summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/ARUBA_me.bin.uu197
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/ARUBA_pfp.bin.uu197
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/ARUBA_rlc.bin.uu140
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/BARTS_mc.bin.uu539
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/BARTS_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/BARTS_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/BTC_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAICOS_mc.bin.uu539
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAICOS_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAICOS_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_mc.bin.uu540
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_me.bin.uu197
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_pfp.bin.uu197
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_rlc.bin.uu95
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CEDAR_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CEDAR_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CEDAR_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_uvd.bin.uu2575
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/HAINAN_ce.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/HAINAN_mc.bin.uu702
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/HAINAN_me.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/HAINAN_pfp.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/HAINAN_rlc.bin.uu186
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/LICENSE.radeon51
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/Makefile8
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/OLAND_ce.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/OLAND_mc.bin.uu702
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/OLAND_me.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/OLAND_pfp.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/OLAND_rlc.bin.uu186
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PALM_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PALM_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_ce.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_mc.bin.uu694
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_me.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_pfp.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_rlc.bin.uu186
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R100_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R200_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R300_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R420_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R520_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R600_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R600_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R600_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/R700_rlc.bin.uu95
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/README4
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RS600_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RS690_cp.bin.uu49
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RS780_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RS780_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV610_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV610_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV620_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV620_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV630_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV630_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV635_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV635_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV670_me.bin.uu481
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV670_pfp.bin.uu55
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV710_me.bin.uu124
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV710_pfp.bin.uu79
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV710_uvd.bin.uu2584
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV730_me.bin.uu124
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV730_pfp.bin.uu79
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV770_me.bin.uu124
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/RV770_pfp.bin.uu79
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO2_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO2_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO_rlc.bin.uu72
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/SUMO_uvd.bin.uu4561
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_ce.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_mc.bin.uu694
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_me.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_pfp.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_rlc.bin.uu186
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TAHITI_uvd.bin.uu4885
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TURKS_mc.bin.uu539
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TURKS_me.bin.uu126
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/TURKS_pfp.bin.uu103
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/VERDE_ce.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/VERDE_mc.bin.uu694
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/VERDE_me.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/VERDE_pfp.bin.uu194
-rw-r--r--sys/contrib/dev/drm2/radeonkmsfw/VERDE_rlc.bin.uu186
-rw-r--r--sys/dev/drm2/ati_pcigart.c210
-rw-r--r--sys/dev/drm2/radeon/ObjectID.h699
-rw-r--r--sys/dev/drm2/radeon/README6
-rw-r--r--sys/dev/drm2/radeon/atom-bits.h51
-rw-r--r--sys/dev/drm2/radeon/atom-names.h103
-rw-r--r--sys/dev/drm2/radeon/atom-types.h45
-rw-r--r--sys/dev/drm2/radeon/atom.c1403
-rw-r--r--sys/dev/drm2/radeon/atom.h161
-rw-r--r--sys/dev/drm2/radeon/atombios.h8013
-rw-r--r--sys/dev/drm2/radeon/atombios_crtc.c1938
-rw-r--r--sys/dev/drm2/radeon/atombios_dp.c893
-rw-r--r--sys/dev/drm2/radeon/atombios_encoders.c2660
-rw-r--r--sys/dev/drm2/radeon/atombios_i2c.c203
-rw-r--r--sys/dev/drm2/radeon/avivod.h65
-rw-r--r--sys/dev/drm2/radeon/cayman_blit_shaders.c375
-rw-r--r--sys/dev/drm2/radeon/cayman_blit_shaders.h38
-rw-r--r--sys/dev/drm2/radeon/cayman_reg_safe.h517
-rw-r--r--sys/dev/drm2/radeon/evergreen.c3759
-rw-r--r--sys/dev/drm2/radeon/evergreen_blit_kms.c733
-rw-r--r--sys/dev/drm2/radeon/evergreen_blit_shaders.c358
-rw-r--r--sys/dev/drm2/radeon/evergreen_blit_shaders.h38
-rw-r--r--sys/dev/drm2/radeon/evergreen_cs.c3727
-rw-r--r--sys/dev/drm2/radeon/evergreen_hdmi.c217
-rw-r--r--sys/dev/drm2/radeon/evergreen_reg.h241
-rw-r--r--sys/dev/drm2/radeon/evergreen_reg_safe.h517
-rw-r--r--sys/dev/drm2/radeon/evergreend.h2046
-rw-r--r--sys/dev/drm2/radeon/ni.c1980
-rw-r--r--sys/dev/drm2/radeon/ni_reg.h89
-rw-r--r--sys/dev/drm2/radeon/nid.h680
-rw-r--r--sys/dev/drm2/radeon/r100.c4201
-rw-r--r--sys/dev/drm2/radeon/r100_reg_safe.h31
-rw-r--r--sys/dev/drm2/radeon/r100_track.h103
-rw-r--r--sys/dev/drm2/radeon/r100d.h883
-rw-r--r--sys/dev/drm2/radeon/r200.c552
-rw-r--r--sys/dev/drm2/radeon/r200_reg_safe.h31
-rw-r--r--sys/dev/drm2/radeon/r300.c1566
-rw-r--r--sys/dev/drm2/radeon/r300_cmdbuf.c1185
-rw-r--r--sys/dev/drm2/radeon/r300_reg.h1792
-rw-r--r--sys/dev/drm2/radeon/r300_reg_safe.h45
-rw-r--r--sys/dev/drm2/radeon/r300d.h357
-rw-r--r--sys/dev/drm2/radeon/r420.c491
-rw-r--r--sys/dev/drm2/radeon/r420_reg_safe.h45
-rw-r--r--sys/dev/drm2/radeon/r420d.h252
-rw-r--r--sys/dev/drm2/radeon/r500_reg.h804
-rw-r--r--sys/dev/drm2/radeon/r520.c330
-rw-r--r--sys/dev/drm2/radeon/r520d.h190
-rw-r--r--sys/dev/drm2/radeon/r600.c4384
-rw-r--r--sys/dev/drm2/radeon/r600_audio.c258
-rw-r--r--sys/dev/drm2/radeon/r600_blit.c876
-rw-r--r--sys/dev/drm2/radeon/r600_blit_kms.c758
-rw-r--r--sys/dev/drm2/radeon/r600_blit_shaders.c720
-rw-r--r--sys/dev/drm2/radeon/r600_blit_shaders.h42
-rw-r--r--sys/dev/drm2/radeon/r600_cp.c2645
-rw-r--r--sys/dev/drm2/radeon/r600_cp.h15
-rw-r--r--sys/dev/drm2/radeon/r600_cs.c2761
-rw-r--r--sys/dev/drm2/radeon/r600_cs.h11
-rw-r--r--sys/dev/drm2/radeon/r600_hdmi.c589
-rw-r--r--sys/dev/drm2/radeon/r600_reg.h177
-rw-r--r--sys/dev/drm2/radeon/r600_reg_safe.h493
-rw-r--r--sys/dev/drm2/radeon/r600d.h1932
-rw-r--r--sys/dev/drm2/radeon/radeon.h2050
-rw-r--r--sys/dev/drm2/radeon/radeon_acpi.c639
-rw-r--r--sys/dev/drm2/radeon/radeon_acpi.h446
-rw-r--r--sys/dev/drm2/radeon/radeon_agp.c289
-rw-r--r--sys/dev/drm2/radeon/radeon_asic.c1961
-rw-r--r--sys/dev/drm2/radeon/radeon_asic.h532
-rw-r--r--sys/dev/drm2/radeon/radeon_atombios.c3190
-rw-r--r--sys/dev/drm2/radeon/radeon_atpx_handler.c506
-rw-r--r--sys/dev/drm2/radeon/radeon_benchmark.c255
-rw-r--r--sys/dev/drm2/radeon/radeon_bios.c728
-rw-r--r--sys/dev/drm2/radeon/radeon_blit_common.h47
-rw-r--r--sys/dev/drm2/radeon/radeon_clocks.c917
-rw-r--r--sys/dev/drm2/radeon/radeon_combios.c3661
-rw-r--r--sys/dev/drm2/radeon/radeon_connectors.c2040
-rw-r--r--sys/dev/drm2/radeon/radeon_cp.c2245
-rw-r--r--sys/dev/drm2/radeon/radeon_cs.c658
-rw-r--r--sys/dev/drm2/radeon/radeon_cursor.c316
-rw-r--r--sys/dev/drm2/radeon/radeon_device.c1551
-rw-r--r--sys/dev/drm2/radeon/radeon_display.c1691
-rw-r--r--sys/dev/drm2/radeon/radeon_drm.h985
-rw-r--r--sys/dev/drm2/radeon/radeon_drv.c514
-rw-r--r--sys/dev/drm2/radeon/radeon_drv.h2165
-rw-r--r--sys/dev/drm2/radeon/radeon_encoders.c381
-rw-r--r--sys/dev/drm2/radeon/radeon_family.h117
-rw-r--r--sys/dev/drm2/radeon/radeon_fb.c433
-rw-r--r--sys/dev/drm2/radeon/radeon_fence.c983
-rw-r--r--sys/dev/drm2/radeon/radeon_gart.c1304
-rw-r--r--sys/dev/drm2/radeon/radeon_gem.c585
-rw-r--r--sys/dev/drm2/radeon/radeon_gem.h17
-rw-r--r--sys/dev/drm2/radeon/radeon_i2c.c1384
-rw-r--r--sys/dev/drm2/radeon/radeon_ioc32.c428
-rw-r--r--sys/dev/drm2/radeon/radeon_irq.c403
-rw-r--r--sys/dev/drm2/radeon/radeon_irq_kms.c468
-rw-r--r--sys/dev/drm2/radeon/radeon_irq_kms.h15
-rw-r--r--sys/dev/drm2/radeon/radeon_kms.c727
-rw-r--r--sys/dev/drm2/radeon/radeon_kms.h30
-rw-r--r--sys/dev/drm2/radeon/radeon_legacy_crtc.c1085
-rw-r--r--sys/dev/drm2/radeon/radeon_legacy_encoders.c1817
-rw-r--r--sys/dev/drm2/radeon/radeon_legacy_tv.c926
-rw-r--r--sys/dev/drm2/radeon/radeon_mem.c304
-rw-r--r--sys/dev/drm2/radeon/radeon_mode.h738
-rw-r--r--sys/dev/drm2/radeon/radeon_object.c651
-rw-r--r--sys/dev/drm2/radeon/radeon_object.h193
-rw-r--r--sys/dev/drm2/radeon/radeon_pm.c918
-rw-r--r--sys/dev/drm2/radeon/radeon_prime.c230
-rw-r--r--sys/dev/drm2/radeon/radeon_reg.h3713
-rw-r--r--sys/dev/drm2/radeon/radeon_ring.c884
-rw-r--r--sys/dev/drm2/radeon/radeon_sa.c428
-rw-r--r--sys/dev/drm2/radeon/radeon_semaphore.c124
-rw-r--r--sys/dev/drm2/radeon/radeon_state.c3262
-rw-r--r--sys/dev/drm2/radeon/radeon_test.c509
-rw-r--r--sys/dev/drm2/radeon/radeon_trace.h85
-rw-r--r--sys/dev/drm2/radeon/radeon_trace_points.c12
-rw-r--r--sys/dev/drm2/radeon/radeon_ttm.c931
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/cayman642
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/evergreen644
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/r100105
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/r200186
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/r300714
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/r420780
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/r600755
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/rn5030
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/rs600780
-rw-r--r--sys/dev/drm2/radeon/reg_srcs/rv515496
-rw-r--r--sys/dev/drm2/radeon/rn50_reg_safe.h31
-rw-r--r--sys/dev/drm2/radeon/rs100d.h43
-rw-r--r--sys/dev/drm2/radeon/rs400.c568
-rw-r--r--sys/dev/drm2/radeon/rs400d.h163
-rw-r--r--sys/dev/drm2/radeon/rs600.c1042
-rw-r--r--sys/dev/drm2/radeon/rs600_reg_safe.h60
-rw-r--r--sys/dev/drm2/radeon/rs600d.h688
-rw-r--r--sys/dev/drm2/radeon/rs690.c788
-rw-r--r--sys/dev/drm2/radeon/rs690d.h313
-rw-r--r--sys/dev/drm2/radeon/rv200d.h39
-rw-r--r--sys/dev/drm2/radeon/rv250d.h126
-rw-r--r--sys/dev/drm2/radeon/rv350d.h55
-rw-r--r--sys/dev/drm2/radeon/rv515.c1201
-rw-r--r--sys/dev/drm2/radeon/rv515_reg_safe.h60
-rw-r--r--sys/dev/drm2/radeon/rv515d.h652
-rw-r--r--sys/dev/drm2/radeon/rv770.c1297
-rw-r--r--sys/dev/drm2/radeon/rv770d.h673
-rw-r--r--sys/dev/drm2/radeon/si.c4424
-rw-r--r--sys/dev/drm2/radeon/si_blit_shaders.c254
-rw-r--r--sys/dev/drm2/radeon/si_blit_shaders.h35
-rw-r--r--sys/dev/drm2/radeon/si_reg.h108
-rw-r--r--sys/dev/drm2/radeon/sid.h1065
-rw-r--r--sys/modules/drm2/Makefile8
-rw-r--r--sys/modules/drm2/drm2/Makefile3
-rw-r--r--sys/modules/drm2/radeonkms/Makefile107
-rw-r--r--sys/modules/drm2/radeonkmsfw/ARUBA_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/ARUBA_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/ARUBA_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/BARTS_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/BARTS_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/BARTS_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/BTC_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAICOS_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAICOS_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAICOS_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAYMAN_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAYMAN_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAYMAN_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CAYMAN_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CEDAR_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CEDAR_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CEDAR_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CYPRESS_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CYPRESS_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CYPRESS_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/CYPRESS_uvd/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/HAINAN_ce/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/HAINAN_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/HAINAN_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/HAINAN_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/HAINAN_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/JUNIPER_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/JUNIPER_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/JUNIPER_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/Makefile85
-rw-r--r--sys/modules/drm2/radeonkmsfw/Makefile.inc18
-rw-r--r--sys/modules/drm2/radeonkmsfw/OLAND_ce/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/OLAND_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/OLAND_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/OLAND_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/OLAND_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PALM_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PALM_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PITCAIRN_ce/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PITCAIRN_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PITCAIRN_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PITCAIRN_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/PITCAIRN_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R100_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R200_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R300_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R420_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R520_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R600_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R600_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R600_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/R700_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/REDWOOD_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/REDWOOD_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/REDWOOD_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RS600_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RS690_cp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RS780_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RS780_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV610_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV610_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV620_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV620_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV630_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV630_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV635_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV635_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV670_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV670_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV710_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV710_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV710_uvd/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV730_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV730_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV770_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/RV770_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO2_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO2_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/SUMO_uvd/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_ce/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_rlc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TAHITI_uvd/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TURKS_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TURKS_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/TURKS_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/VERDE_ce/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/VERDE_mc/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/VERDE_me/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/VERDE_pfp/Makefile6
-rw-r--r--sys/modules/drm2/radeonkmsfw/VERDE_rlc/Makefile6
-rwxr-xr-xsys/modules/drm2/radeonkmsfw/gen-makefiles30
343 files changed, 164152 insertions, 2 deletions
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_me.bin.uu
new file mode 100644
index 0000000..d897ff2
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_me.bin.uu
@@ -0,0 +1,197 @@
+begin 644 ARUBA_me.bin
+MQ`@`,<`.``'`$``'F(``#`04!``$&```V```3=@!H-K8`:#9"1```=@``$W-
+ME:'T!50$``68``&9`/_[?$"``<R``$V(````U$``?X````_80`!=Q!``+"40
+M``*5`/_^)(P``GQ!``'$'``QQ"``+]@``%?-P:#9S@&@VMA``%>8P``/Q!0`
+M"95```+90:*DQ!L`*M@``%;-@`!4P#X`!,P!H?3,/2`$Q#T``\P``$?80`!6
+MV$``7H````_$#``*!#P`(Y3```+/P:*DQ!L`*]@``%;-@`!5P#X`!,P!H?/,
+M/2`$Q#T``\P``$G80`!6V$``7H````\$/``CS\&BI,P``$O8``!5S$``8X``
+M``_,``!&S```2\Q!(F3,02)ES$$B9LQ!HMU\0(`!S(``38@```#,0`!&S```
+M2XP`!:3,02)DS$$B9<Q!(F:,``6HS$&BW7Q`@`',@`!-B````,0@`#%\0,`!
+MQB<#Y,P``&(*9``!SF`#Y)3`_[',``!!@```#WQ`P`'`%@`$)-#__WT5``K,
+M$0``&-@`/A3<`!_$(0`#?$)``97```7,``!-?E:`"LPI``#$)0`#?B8`"7Q"
+MP`&5@``%S```37[7``K,,0``Q"T``WXN``K,``!-)1#__\X1``"````/?$#`
+M`<Q``$"````/?$#``7Q`P`'-02)=S$``1<P``$K-`2)<S$&A_'Q`@`',@`!-
+MB````'Q`P`%\0,`!S4$B7<Q``$7,``!*S0$B7,Q!H?Q\0(`!S(``38@```#,
+M02)7@```#WQ!@`',0`!%S$``2LQ!(ES,0:'\?$"``<R``$V(````S```1<P`
+M`$K,02)<S$&A_'Q`@`',@`!-B````,`.``',``!%S```2LQ!(ES,0:'\U$VA
+M_7Q`@`',@`!-B````,Q!(EV````/S```1<P``$H(3``!?$$``7Q!0`$E6/__
+M&5P#\!5@`!7-@:$"S<$B5LX!(EPI)``@E,``!,Y!H?P(S``!@```LLT!H?S,
+M`:$"?$"``<R``$V(````?$"``7Q`P`'`*@`"?$$``7TI``HDE``!))@`!B2<
+M`P`5W``(?$(``7Q"0`'`+@`$E4``#07P(EA_+P`*S#$``,0I``/,P2%IS0$A
+M:LZ!(6LQM``"S`$A;)=```S$-``-@```\#&T``*70``(P"X`!`7P(EA_+P`*
+MS#$``,0I``/$-``-@```\#&T``"70``$?@*``<0T``V```#P,;0`!)=`_R3.
+M`2%MSD$A;L0J``+$-``-FT```\P``$V,``-[,?0``,`N``270``,SH&BM\PM
+MHK;$+0`#P#``!G[S0!3`,``@?VN`$7^SP!7/@:+$S\&BT8````\Q]``!P"X`
+M!)=```S.@:*[S"VBNL0M``/`,``&?O-`%,`P`"!_:X`1?[/`%<^!HL7/P:+2
+M@```#S'T``+`+@`$ET``#,Z!HK_,+:*^Q"T``\`P``9^\T`4P#``(']K@!%_
+ML\`5SX&BQL_!HM.````/P"X`!,Z!HL/,+:+"Q"T``\`P``9^\T`4P#``(']K
+M@!%_L\`5SX&BQ\_!HM2````/!!@``(```2P$&``!Q"0`,7Q`P`'&:P/D&-``
+M,"34`/\&J``!SJ0#Y)I``!+$.``)V$``7<0\`"PG_``"E\#__LR``$V7@``"
+MV4&BI,0_`"K/P`!4P#X`!,P!H?3,/2`$Q#T``\P``$?80`!>S4&@VL0@`#*6
+M```3V$``4\0X``K80`!=Q#P`+"?\``*7P/_^EX```P0\`"//P:*DQ#\`*\_`
+M`%7`/@`$S`&A\\P](`3$/0`#S```2=A``%[-0:#:F8```LP``$+-0`!A@```
+M#]@``$A\0,`!Q"0`,234`/^:0``#V```5-@``$?$(``RE@``!-A``%/8``!5
+MV```2=A``&3-0`!A@```#WQ`P`$8T`'H&-0`,!C8`#0%*`%T?$(``7Q"0`&5
+M```'AH```(```8Z```6@@``!LH``!:"```&$$50`$'X6``K,@`!-U&$``)6`
+M_I'`.@`$S#DA0,0Y``-\0(`!B````!%4`!!2)``@?B8`&LU``%C48@``E8#^
+MAL0@`!R:`/__?$"``8@```#<.@``F4``&R><``&5P``-"[@``<X!(6G.02%J
+MS$$A:\P!(6R;@``#E8#^=X```:929``@?B8`&D8@``16)``@(F0`,LX!(6G.
+M02%J"[@``LQ!(6O,02%LFX#__96`_FK$,``5EP#__WQ`@`&(````"[@``<X!
+M(6G.02%JS$$A:\P!(6R;@/_[E8#^7X```:86(``"P"H``<X!)<?4:27(E8#^
+M6<`Z``3,.27+Q#D``WQ`@`&(````?$#``7Q!``$9%``]F4``"<0<`!*5P/__
+MS,$A`,T!(0',P2$"S0$A`]D!HJ2````/)1@0`)6```3$'``2,>0`0)9`__[,
+MP2%US0$A=L0@`!.6`/__%B@``9J```/,``!.@```#\P``$[,P2%U@``!SGQ`
+MP`%\00`!S```1<P``$I`U``#S4$B7,T!H?S`'@`!?$(``0C,``$&)``!!B@`
+M`LX=H?W.7:']SIVA_9C`__E\0(`!S(``38@```!\0,`!)-```13,``%\04`!
+M?$&``94```7-02%MS8$A;L0>``*```'YP"(`!'X6``K,(0``Q!T``WQ"0`%\
+M0H`!F,```\WE``"````/SD$A:<Z!(6K-P2%KS`$A;(````]\0,`!?$$``7Q!
+M0`%\08`!?$'``1BD'^@R:``\!"```9:```A\0@`!.C```T(@``*;```"!"``
+M0`0D``&```(4?@)``0ID``&:0/__).P`$,P``$V:P``)P"H`!,0L`!=^DH`*
+MS```0<PI``#.P``7Q#$``X```B3-`2%MS4$A;L0R``)_'P`))/0`!P=X`BB7
+M0``GAX```(```C"```(U@``".H```C^```)$@``"28```DY_&X`/%*0`")>`
+M`!TF9`#_@``"7W\;@`X4I``(EX``&"9D`/^```)??QN`#!2D``B;@``3)F0`
+M_X```E]_&X`-%*0`")N```XF9`#_@``"7W\;@`\4I``(FX``"29D`/^```)?
+M?QN`#A2D``B;@``$)F0`_X```E\4I``()F0`_S)H`#P4[``(FH#]O7Q#0`%\
+M0X`!?$/``<P``$V6P``&ST$A:<^!(6K/P2%KS`$A;(````_/]0``@```#S)H
+M`#R:@/^TU$``?X````]\0,`!?$$``<`>``$5%``2P"(``L`F``250``$P"?_
+M^WTE``G`)@``?=*`"7X2P`E])0`*?$%``7Q!@`',P2%IS0$A:IJ```?-02%K
+MS8$A;);`_9C$,``5EP#__X````_(%``455@`(,U!(6O-@2%LEL#]D(```GA\
+M00`!?$%``<Q``$/,0`!$S``#Y,P``^7,``/FP`Z``'Q"0`%\0H`!%JP`'\`U
+M\`"6P/V"SD`#X"9X``,2?``(?_?`"7_[P`H6>``8S\`#X<^``^(2L``"?S\`
+M`<\``^-\@,`!@``$CWQ`P`$8T`'H!2@"GY4```B&@```@``"J(```K:```*\
+M@``"PH```L>```+-S,&BI(````_`$@@`?$%``7Q"``%]#,`*P!(`!!58``,5
+M7``-?='`"1(@`!-^'D`*?DZ`"LZ!HJ3-@:'^@```#P00(1C$%``0E4#__]11
+M``#,P:*D@```#P00(0;$%``1E4#__]11``#,P:*D@```#]A``!;,P:*DQ!``
+M%ID`__^````/!!`A`,04`!*50/__U%$``,S!HJ2````/)-@``7Q!``%\04`!
+M?$(``96```81F``0Q!P`"L0\`">7P/__@``"VQ&8`!#$'``)Q#P`*)?`__\5
+M:``=?5E`"A'D``J:@``#?B8`"LW``%S-`2%8S4$A6<X!(5K,P:*D@```#WQ`
+MP`$4T``=%-0`')D```:50/TEP"8`!,PE(53$*0`#@```#\U``%>````/)'0`
+M`21X``+$#``?FT```HP``WO$%``A!!``$)N```*,``.5S,&B4,T!H%`$&`0`
+MC``#1,P``%G$/``CQ!``'XP``U3$'``E)=P``<@X`":5P``%Q#P`(T>X!5#,
+M``!8S_H``,0D`!V:0/__!#```<0H`!D^J``$Q"P`&GZN@`J:@/_\SP``45#8
+M``@4W``8*=R``,V!(8#-P2&!42``"!4D`!@3,``>?G)`"LX!(8+.02&#S4$A
+MA'Q`@`',@`!-B````"1T``$D>``"Q`P`()M```*,``-[Q!0`(@00`!";@``"
+MC``#E<S!HF#-`:!@!!@)@(P``T3,``!:Q#P`),00`"",``-4Q!P`)27<``'(
+M.``FE<``!<0\`"1'N`54S```6,_Z``#$)``>FD#__\0H`!D^J``$Q"P`&WZN
+M@`J:@/_\!#```H```Q(%F,``$-P`"!3@`!C-V0``Q!P`&,W9``'$)``8?F)`
+M"LY9``+$'``8Q"``&,0D`!C-V0`#SAD`!,Y9``>0````&_@`\,`V"`#`,`"`
+MEX```I````#8``!=Q#@`+">X``&7@/_^P"H`!,08`"_/02%\SP$A?<V!(7K-
+M`2%^!"0`"`ID``&:0/__S"DA?\0A``,6.``?!"0`",R``$V;@/_YV```7I``
+M``!\00`!Q"0`&II`__^````/?$$``<0D`!N:0/__@```#WQ`P`&,``-[?$"`
+M`<R``$V(````V$``7<0\`"PG_``"E\#__ME!HJ3$/P`JS\``5,`^``3,`:'T
+MS#T@!,0]``/,``!'V$``7I````#$$``Q?$#``94```79P:*DV$``%L00`!:9
+M`/__S(``38P``Y5\0(`!S(``38@````$/``BS\&BI,P``$B0````?$#``8P`
+M`YY\0(`!S(``38@```#80`!=Q#P`+"?\``*7P/_^!#P`(\_!HJ3$/P`KS\``
+M5<`^``3,`:'SS#T@!,0]``/,``!)V$``7I````#`$@`!?%%`"M15``"````/
+MS$``6\0X`"/$/``DP#7@`,`R``1_MX`)?_?`"2NX$``K_!``SX$A5,_!(57,
+M,2%4Q"T``\0<`!N9P/__Q"0`&II`__^````/?$#``7Q!``$9*``PEH``!L0D
+M`!V:0/__Q"0`'II`___,``/W41``('S0P!I5'``_?$%``7Q!@`'0P`$'E<``
+M`\`<@`#-P2`0E8#\.HP`!:3=@P``!5P@`,P``$W470``@``%K'Q`P`%04``@
+M?-#`&GQ!0`%\08`!T,`!")6`_"V,``6DW8,```5<H`#470``@``%K'Q`P`%0
+M4``@?-#`&GQ!0`%\08`!T,`!"96`_"&,``6DW8,```5<Z4#470``@``%K'Q`
+MP`%04``@?-#`&GQ!0`%\08`!T,`!"I6`_!6,``6DW8,```5<Z(#470``@``%
+MK'Q`P`%04``@?-#`&GQ!0`%\08`!T,`!"Y6`_`F,``6DW8,```5<P`#470``
+M@``%K'Q`P`%04``@?-#`&GQ!0`%\08`!T,`!#)6`^_V,``6DW8,```5<\`#4
+M70``@``%K'Q`P`%04``@?-#`&GQ!0`%\08`!T,`!#96`^_&,``6DW8,```5<
+M\_S470``@``%K-1#(`!\0(`!S(``38@```#40Z``?$"``<R``$V(````U$/I
+M0'Q`@`',@`!-B````-1#Z(!\0(`!S(``38@```#40\``?$"``<R``$V(````
+MU$/P`'Q`@`',@`!-B````-1#\_Q\0(`!S(``38@```#,0Z``?$#``8P`!:3,
+M0Z``C``%J'Q`@`',@`!-B````,Q#P`!\0,`!C``%I,Q#P`",``6H?$"``<R`
+M`$V(````?$#``7Q!``%\04`!E,```GQ!@`',`_/\S$/S_,Q#\_Q\0(`!S(``
+M38@```#`'@`0Q`P`'U#0``@05``"?16`$8``!&?`'@`@Q`P`(%#0``@(5`0`
+M$50``GU1@!'-P`!8U%H``'Q`@`',@`!-B````'Q`P`$DT``#$2@``94```H&
+MJ`1Q?$&``8:```!\0<`!@``$?WQ!P`&```2%?$'``8``!(I\08`!?$'``134
+M`!`%5*``S94``(````_`(@`$!9B@`'VA@`K,&0``Q!D``X``!'O`(@`$S8$E
+MPLPA)</$&0`#@``$>\V!(6W-P2%NQ!H``H``!'M\0,`!Q!,#X,07`^/$&P/A
+MQ!\#XLV!(6G-P2%JS,$A:\P!(6P$(``$?:&``7V60`S-@`/AED#[="4H``/`
+M+?``$1@`"'VM@`E]J8`*S8`#X8````\DC/__U$T``'Q`@`',@`!-B````'Q`
+MP`$8U``P&-`!Z!C\`#0DS``/!.@$L7Q!@`%\0<`!E,``,H:```"```2Z@``%
+MH(``!,6```31@``$MU'<`"!]G@`:@``$\\V!(6W-P2%N!9@`!,0B``*50``U
+MS8$A;<W!(6[$)@`"4F0`('XF`!J```3S%9@``L`R``3-@27"S#$EP\0A``.5
+M0``IS(``3<PQ)</$)0`#4F0`('XF`!J```3S,:P(`,0T`!>6P``#S```08``
+M!.@$+```!#```)K```27```#S```08``!.@$+```!#```)K```.7```"S```
+M08``!.@YK`<&/;`'`,0T`!>:P``#EP```LP``$'`.@`$?;F`"LP9```%F``!
+MQ"$``Y5```7,&0``Q"4``U)D`"!^)@`:ST``%\R``$T%*`3X?$&``7Q!P`&5
+M```'AH```(``!2Z```6@@``%.8``!1&```4B.:P'!CVP!P#$-``7FL```Y<`
+M``+,``!!SAD``)5```0%F``!5B0`(,Y9``"7P``$P#H`!,PY(4#$.0`#ST``
+M%WQ`@`',@`!-B````#&L"`#$-``7EL```\P``$&```4$!"P```0P``":P``$
+MEP```\P``$&```4$!"P```0P``":P``#EP```LP``$&```4$49P`('V=@!K8
+M``!8SAH``)5```0%F``$5B0`(,Y:``";P`!@?$"``<R``$V(````E4```B'<
+M`#)6)``@S8$A:<W!(6K.`2%KSD$A;)O`_4-\0(`!S(``38@````5F``"P"H`
+M`<V!)<?.*27(E4``!%8D`"#,@`!-SFDER)?`^L[`.@`$S#DER\0Y``-\0(`!
+MS(``38@```#$%``9/5@`!)F`__[,``!1S$$A@"A,@`#,P2&!%-``'\Q!(8+,
+M02&#S$$AA)4`^KS$%``9F4#__X````_`%@`$Q!``,<Q5(4#$&0`#S!`#]X``
+M``_$(``QV```7<0,`"PDS``!E,#__L8G`^1\0,`!S,$A?,Q!(7W$&``O?$$`
+M`7Q!0`&60``"S8$A>LT!(7[`*@`$)53__SEP``-!7``"FP```@0<`$`)W``!
+MF<#__\PI(7_$)0`#%FP`'T%<``+,@`!-FL#_^13\`!_8``!>F\#ZD\00`#',
+M$`/W@```#WQ`P`%\00`!%1@`'U$4`"`9'``QF8``",T``%A]34`:U%8``)7`
+M^H;$(``<F@#__X````_<.@``P"8`!,S!(6E])0`*S0$A:@NX``+,02%KS$$A
+M;)N`__W,``!_F<#\X8````\D3`#_S$P#`(````_$(``QQ$\#`,SA(46````/
+MP`X!`,P``$',P3!*@``%H]A``#3$/``TE\#__Y````#8```TQ#P`-)O`__^0
+M````V```-,0\`#2;P/__?$"``<R``$V(````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````02C`!``$@`2`!0`%``^`!4`1``6`$T`%P!8`"$`80`D`(``)0"*`"<`
+ME``H`'L`*0"5`"H`D@`K`)4`+`!^`"T`G``N`*,`+P"L`#``K@`R`2L`-`##
+M`#4`E0`W`6P`.`"(`#D!O``Z`=@`.P'K`#P"`P`]`F,`/@%=`#\!*0!`!*@`
+M005(`$(%5P!#!5T`1`*!`$4"`P!&`IL`1P*;`$@"FP!*`N8`3`+Q`$T#(@!.
+M`VX`3P-R`%$#F0!2`W8`4P.)`%<#K0!@`\,`80/<`&(#L0!C`^@`9`/T`&4$
+M``!F!`P`9P08`&@$)`!I!"@`:@1;`&L$+`!L!#``;00T`&X$.`!O!#P`<`0T
+M`'$$80!R!%``<P1``'0$2`!U!&P`>@6``'P$C@!]!9D`?@6<``\%H``/!:``
+M#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/
+M!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%
+MH``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@
+M``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``#P6@``\%H``/!:``
+3#P6@``\%H``/!:``#P6@``\%H```
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_pfp.bin.uu
new file mode 100644
index 0000000..14a086f
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_pfp.bin.uu
@@ -0,0 +1,197 @@
+begin 644 ARUBA_pfp.bin
+M?$"``8@```#,@`!`U$``0'Q`@`&(````$$P``220``)\04`!4%@`('V5P!J8
+MP``#T<``&(````"9```#T<``&8````#1P``:@````"2,``+,@`!`S$``0)C`
+M``/,``!2@``$(<P``%3,``!P@``$(<Q``&6`````S```5\P``''$)``^FD#_
+MX<@,`!I\Q0`1T0``0]C``$/,@`!`S```0,Q``$!\0(`!B````,@,`!E\Q0`1
+MT0``0MD``$)\0,`!Q!L``\0?``/$(P`#Q"<``Y6`_\R5P/_+Q"@`$,P``%::
+M@``$Q#``!<\``$#,``!`Q"@`"2`L`'XB[(Y(&J@`)\[``$#,``!`S8``0,W`
+M`$#.``!`SD``0):```+8@`!;S(``0,P``$#,P`!`?$"``8@```#(#``9?,4`
+M$7Q!0`%\08`!?$#``95`_Z[1``!"V0``0@E4``'$(P`#Q"<``\0K``/$+P`#
+ME@``&99``!C$,``0S```5IL```3$,``%SP``0,P``$#$,``)(#0`?B-TCD@;
+M,``GST``0,P``$#.``!`SD``0,Z``$#.P`!`EP```MB``%O,@`!`S```0,P`
+M`$#,``!`S,``0)5`_XU]&0`1@```4\@,`!E\Q0`1T0``0ME``$)\0,`!Q!L`
+M`\0?``/$(P`#Q"<``\0K``.5@/^`E<#_?\P``&/1``!DQ#``$,P``%:;```$
+MQ#0`!<]``$#,``!`Q"P`"2`P`'XC,*Y(&NP`)\\``$#80`!`S8``0,W``$#.
+M``!`SD``0,Z``$"6P``"V(``6\R``$#,``!`S,``0'Q`@`&(````R`P`&7S%
+M`!%\04`!?$&``7Q`P`&50/]?T0``0ME``$()5``!Q",``\0G``/$*P`#Q"\`
+M`\0S``.6```<ED``&\P``&/1``!DQ#0`$,P``%:;0``$Q#0`!<]``$#,``!`
+MQ#0`"2`X`'XCN*Y(&W0`)\^``$#80`!`S@``0,Y``$#.@`!`SL``0,\``$"7
+M0``"V(``6\R``$#,``!`S```0,P``$#,P`!`E4#_.GT9`!&```"BQ!@`""68
+M``'8```<?$)``7Q"@`&5@`-14JP`('[FP!I\0,`!?$$``1JX`>B7@``$V$`#
+M]\0X`_>;@/__Q!P`$YG`__\<B``0((@`<!#4``)^U4`1T4``0\T``$/,@`!`
+MSD``0,Z``$#,P`!`W#H``,T``$"7@/\:?$#``7Q!``&```#<)(P``IC```K$
+M$``/F0``!<0<``3,``!2S<``0,P``$#$&``()9@``H```,O$$``1F0#__,0<
+M``;,``!4S<``0,P``$"```#R)(P``L04`!*8P``/Q!``$)D```7$'``%S```
+M4\W``$#,``!`Q!@`"!B4`>B4P``"!50`!B@0``%]%0`$?9&`"8```,N90/_X
+MQ!P`!<W``$#,``!`S```58```07,``!?S```8,0D`#Z:0/[LQ!P`!H```1K$
+M'``$S<``0,P``$#,@`!`U$``0'Q`@`&(````Q!P`!8```27$'``&@``!)<0<
+M``3-P`!`S```0,@,`!C,@`!`S$``0!!0``)]#0`1510`(-$``$/80`!#S```
+M0'Q`@`&(````Q!P`!<W``$#,``!`S(``0-1``$!\0(`!B````"2,``+$%``2
+MF,``$<00`!"9```%Q!P`!<P``%/-P`!`S```0,0,`!O,@`!`S$``0,Q``$#,
+M0`!`?,3``<S``$#40`!`?$"``8@```"90/_VQ!P`!<P``%7-P`!`S```0(``
+M`4)\0,`!Q!``)9D```_$%``B(!@`?B&8"<B90``#S8``0,P``$#,@`!`S,``
+M0-1``$!\0(`!B````'Q`P`'$$``EE0#_\\04`",@&`!^(9@)Z)E```/-@`!`
+MS```0!RHX`@BJ`XHSH``0,S``$#40`!`?$"``8@```!\0,`!Q!``)9D`__?,
+M@`!`S,``0-1``$!\0(`!B````,00`"0@*`!^(J@IB,Z``$#-``!`S0``0(P`
+M`9#$#``AQ!0`)I3```L$$``#@``!A<00`"0@*`!^(J@IJ,Z``$#-``!`S0``
+M0(P``9#$%``FS```8<0D`#Z60`*7A4```,0L``DF[``!FL```I````#`+0`!
+MSL``6R`T`'XC="T(P"P!5L]``$#.P`!`S```0)`````DC``"Q!``$93```>9
+M`/YBQ!P`!LP``%3-P`!`S```0(````+$%``/Q!P`!)E`_EK,``!2S<``0,P`
+M`$#$)``^FD#^57Q`P`%04``@?0U`&M%``!?,``!B@````,`W__\@B`!P@``!
+MN'Q#0`'('``7Q!@`%L]#HIY\04`!?5C`!'S<P!%4T``@S(``0(```<I\08`!
+MS(``0,V``$"```''P!G__\R``$#-@Z*>?$#``7Q!``%\04`!S,.A^LT#H?G-
+M0Z*=S,``0,T``$#-0`!`S$``0'Q`@`&(````?$#``230``',PZ*?V$``%I4`
+M``+8@``6S(``0,S``$"`````?$#``<R``$#,PZ*BS,``0(````#$'``<?$#`
+M`3'@```4U``??6%`"<R``$!\00`!E4```LS``%@5&``?S,``0,T``$"5@``"
+MS0``6<P``'^```0A(`@`?B"(!^C$(``4'*@`$,Z@`$1\00`!4%0`('Q!@`$&
+M)``!SD``%!6<`!A]%0`:S>``2<V@`$O1(`!!S:``0544``C-0``;F@``!,0D
+M`"N:0``"(=P`,,W``$"```0AQ"``%,8,``H<J``0E,```\Z@`$:```'WS```
+M2(```A'$#``<E,`"#,0H`"S8``!4V```59J```/8``!2V```4X```@K$(``4
+M?$&``0H@``'&%``-QA@`"GU9@`K.```4E8``!,R@`$;-8`!&@``$(<R@`$3-
+M8`!$@``$(<Q``&&```0AQ`P#]MA``_:8P``)Q!@`(,0<`"'$$``0Q!0`#Q$0
+M``%]%0`*F8#_19G`_U#8``/V?$#``8````!\0,`!?$$``7Q#@`%\0\`!41``
+M(%/\`"!_OX`:?-#`&@0<``C3@`!"V(``0M#``$+-P`!"!!P``@0@``%\`D`!
+MQ!<``\0;``-1F``@?5E`&L0K``/$+P`#Q#,``\0W``,)W``!4NP`('ZN@!I3
+M=``@?S<`&G\K0!)^=D`15J@`/U<P`#]^LH`)?BH`"9G`__&6@/_D4_0`('][
+M0!I]94`155@`(,P``%K-=@``S;8``,0@`!^:`/__@````,0@`"Q\0,`!?$$`
+M`<S@`_W-(`/Z410`('S4P!K0P`!"%10`'QD8`/"90``"!#0``"]<``%]=@`)
+M?5Y`"9F```3,``!"S```38``!"$5F``!%2P`"";L``&9@``S%3``#)8```/,
+M``!"@``$(004``C-0`!")S```2@H``$$.``(!#P``L07``/$&P`#Q!\``\0C
+M``-]74`-?:'`#7U=0`H6$``?%9P`'WT=``E]%T`)?I*`"0NX``0+_``!FT``
+M$IO`__'$(``LQ@\#_<83`_J:@``)S```39L``8-1%``@?-3`&@04``C0P`!"
+MS4``0H```H;,``!-EL`!>\P``$Z```0AS```39K```+,``!.EX#]5`NX``'$
+M/P`#FX#__8````#,``!.ED```\P``$*```0AV@``0L0+``/$#P`#Q!,``\07
+M``/$&P`#Q!\``\0G``/$*P`#%?P`'Q:P`!]_\\`)%/``'W_SP`D5<``??_/`
+M"7V(@`)]S,`"E\``#'Y1``)^E4`"?)"`#'S4P`Q\CT`)FL```BRT``',``!-
+MFT`!4<P``$Z```0AQ"``+,8/`_W&$P/Z410`('S4P!K0P`!"@``"M7Q`P`$4
+MT``>F0``!<R``$#,P`!`U$``0(`````8U``P&-`!Z!C\`#0DS``/!.@"Z7Q!
+M@`%\0<`!E,``%(:```"```+S@``$)8``!"6```0E@``"\(``!"51W``@?9X`
+M&H```P)1W``@?9V`&L6B``"50``,19@`!,6F``!29``@?B8`&H```P+%H0``
+ME4``!068``'%I0``4F0`('XF`!H%*`,&?$&``7Q!P`&5```'AH```(``!"6`
+M``0E@``$)8``!"6```,6V```6LX9``"50``$!9@``58@`"#.&0``E\#\[L0Y
+M(4!\0(`!B````%&<`"!]G8`:V```6LX:``"50``$!9@`!%8@`"#.&@``F\``
+MGGQ`@`&(````?$#``7Q!``$9%``[S```6I5``!#$%``>/5@``IF`__[,``!=
+M*1R``,S!(87-P2&&%10`'\Q!(8?,02&(S$$AB95`_,_$%``>F4#__X````#,
+M@`!`S,``0,T``$#40`!`@````,0H`"S8:`/WS(``0,Q``$#&CP/WF,#__WQ`
+M@`&(````Q"@`+,0L`!'$,``O?O+`"IJ```?$,``/FP``!<0T``3,``!2ST``
+M0,P``$":P``%Q#0`!LP``%3/0`!`S```0'Q`P`'8:`/WS(``0,S``$#40`!`
+M%-``'YD``,F```,^S(``0,Q``$#,0`!`S$``0'Q`P`',P``5S,``0-1``$#8
+M``/V@````'Q`P`$4W``=&-@`/,R``$"9P``%S,``0)F`_);,``!A@``$(<V`
+M`%[,``!AS,``0(``!"%\0,`!4%``((P``X!\T,`:Q"``%,36``!\0X`!F4``
+M!M^#``#/H`!/C``#A-1``'^`````C``#A(````#8```=Q!0`'9E`__^0````
+MV$``'<04`!V50/__D````(P``X#$(``4?$#``<`V_P#$$``5P#`__WSU0`E]
+M48`)?8&`'7SS@`F9@``&WX,``,^@`$^,``.$U$``?X````",``.$@````'Q`
+MP`$4T``>F0``!<R``$#,P`!`U$``0(`````8T`'H&-0`,!C8`#0%*`.H?$(`
+M`7Q"0`&5```'AH```(``!"6```0E@``$)8``!"6```.V$50`$'X6``K-0`!:
+MU&$``)6`_$[$.2%`?$"``8@````15``04B0`('XF`!K-0`!:U&(``)6`_$7$
+M(``?F@#__WQ`@`&(````?$#``13<``B5P``9)-P`$'Q!``%05``@F<```\4=
+M``"```/+?14`&L4>``!\0@`!?$)``7Q!@`%]Y<`)?>*`#T&L``*:@/PO!NP`
+M`PKL``&:P/__)-P`$)G```/%'0``@``#SL4>``"```/.S(``0,S``$#40`!`
+M@````,0<``3-P`!`S```0,R``$#40`!`?$"``8@```#$'``%S<``0,P``$#,
+M@`!`U$``0'Q`@`&(````?$#``230``8Q$``&Q!0`#YD```C,``!2Q"0`/I9`
+M`#&90``$Q!P`!,W``$#,``!`S(``0,S``$#40`!`@````'Q`P`%\00`!%1@`
+M'\T``%I1%``@F8```]1-``"`````?4U`&AD<`#'45@``Q"``'Y7`^_?$(``?
+MF@#__X````!\0,`!%-``'R34`/^5```#S%0#`(````#,@`!`S,``0,Q``$"`
+M````Q"``+'Q`P`'$TP,`S(``0,S``$#,``!:S2$A08````#40`!_@````,0D
+M`#Z60``#?$"``8@```"```0E````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P/?``0#Y@`%`?(`!@$9``<!)``(`3(`"0$@``H!%P`+`2(`#`%2``T!
+M8``.`7@`#P&$`!`$'P`1``8`$@`3`!,`'``4`!X`%@`B`"0`*P`E`'8`)@&N
+M`!<"&P`8`BD`&@(K`"(#<0`C`X@`)P'!`!\".0`@`F@`*`'B`"D!M``J`=0`
+M*P'%`"P`30`O`=T`,@(*`#0#[0`U`;<`-P.:`#@`G``\`\``/@(2`#\!]`!`
+M`MH`00,A`$(#.@!#`T(`1`-:`$H#9`!5`^(`5@/I`&``R0!A`.H`8@$3`&,`
+M_`!D`/P`90#\`&8`_`!G`/P`:0$<`&H!<`!K`34`;`$U`&T!-0!N`34`;P$U
+M`'`!.0!S`2<`=`$G`'4!G0![`_T`?00-`'X$%P````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+3```"`````@````(````"`````@``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_rlc.bin.uu
new file mode 100644
index 0000000..84e2f45
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/ARUBA_rlc.bin.uu
@@ -0,0 +1,140 @@
+begin 644 ARUBA_rlc.bin
+M(#@`$".X``#/@``2S``"!008``'-@``.S8`"`\P``@+-@`(!S```"X0`!/P`
+M````S``"0\P``D+-@`(`R`P`0!S@`(`J(`"`S@`"01SD`0`J9`$`SD`"0,Y`
+M`D*6```&`````)I```0`````A``#E`````"```!``````,^Q``#+.0``(`@`
+M'YB````(B``!S!P`%H@`````````R"@``Y:`!'``````S8``#BJ,`>68P`/J
+M(`@``2J,`>3((`)!?.#`!IC`!!H@"``!S(```X```IH`````B`````````#`
+M"```A``"9P````#(#`!Y',S__\`()-6(`````````,@)/3;(#3TWE,`"L@``
+M``#($3TXR!4].<@=/3K((3T[R"4]-02H`##.@3V"S,$]@\T!/83-03V%S<$]
+MALX!/8<0B``#!(P`&,B6`#R50`*AR-(`*'TE``$)5``!!,P`*)D`__L`````
+MR)(`.`40`$!]"L``R-8`!,`<``3(X@`4R.8`),X*`4S.;@%,",P`!`B(``0*
+M[``$"=P``9G`__@`````S0H!8,P*`63-03U'@``"]`````"(`````````(``
+M!*#`,`'!R"@`!9:``2@`````(`@``<V```[,@``%@``"F@````#,@`)#B```
+M``````#`,`'`B````,^Q``#("`)'R`P`+7R,@`R4@``.`````,@(`BO(#`(I
+MP!`DU<D1``!\T,`'P!`/^,D1``!\T,`'?,#`"WR,P`;,P`)'S,``+H@`````
+M````P`P`!L`0``%\T,`2P!```)3`_]<(S``!S!`"+X```)<%$``!A```V```
+M``#("`(7?)2`#)B```P`````S4`"%\U``BF$``'R?!2`!\S``A_,P`(AR`@`
+M>H0``?(<B/__S,`"-<@(`"W`#``!P!``!GS0P`,(S``!?(S`!L`0`A?`%`(I
+MA``#>P````"(`````````,^<`!;-@``.R?``&7\X@`R4@/_^`````(@`````
+M````R#@"0P>X``'+B```P`PA@<R-``#`#"&#S`T``,`H``0'N``!RXP``!ST
+M``&;0`0M![@``<N0```'N``!RY0``(0``Q(*J``!FH#_]@````"$``2_P`@A
+MH(```,C`*``$P`@B5,B)```4B``0P`PB5<C-```4S``0?(U`!\`,)-?(S0``
+M?,#`"WU-0`>(````?4%`"\C4```$S``!!B```1U8`/]]D8`2?9V``WR9@!&5
+M@``U'5C_`!68``A]D8`2?9V``WR9@`^5@``O`````!54`!"60``#`````!54
+M``@=5`#_B`````````#`,/__R(P``'SQ``:5`/\X!(@``<D5``#-2```%,P`
+M$'SQ``:5`/\R!(@``<D5``#-2```R"P`')K`_RU\+<`'@```_`2(``'("`(!
+ME(``EL@(`"_-@``.R`P"+7R-`!&5```#?(T``8```VC`%?__P!P@1\R=``#`
+M'"!&S1T``,@<`BC`("!%S>$```G<``<)W``$("```#X8`!"5@/_#`````(``
+M`/D@%`!`R"@``9:`_P``````(`@``<V```[(#``AS(```8```IH`````R`@`
+M1%"(``B$``&$`````)G``[P@"```A``%32`,``&$``)L(#@``)>``[8@"```
+MS``"`,P``@'`-`.1(!```"`(``/--0``P#`AC2`,``',\0``P#`ACB#,/__,
+M\0``!1```0B(``&8@/_WP#`AML`*%`#,L0``S#4``,@(`$`<B`(`F(`!]<`P
+M`*'`$`!0S3$``,`P`*++$0``'0P``93``1D`````R`P`')3`__L`````@``$
+M[P````#("`!#F(``!@````"$``3\`````(0``)P`````S``"&\`(!0"$``)G
+MS``"',@(`$;(#`!%?,B``<@<`'L=W`#^%=P``7R<@!*$``-QS``")\U``BB(
+M`````````"`(``',@``#P#``H<`(`%3,L0``P#``HL`(`0#+#0``?,C`!IC`
+M__X`````P#`]-<VQ``"```&D`````,`P___(C@``?/$`!I4``R)$B``$R14`
+M`,U*```4S``0?/$`!I4``QQ$B``$R14``,U*``#(+``<FL`#%WPMP`>```&%
+M1(@`!,P``@.$``!]$;@`'X```:0`````R"@`*I:``RL`````S8``#H0``5X`
+M````@``!I"`8``',```.S```#B`H`<,@'```R`@"!7^+@`?("`(!E(`!10``
+M``"```(\`````,@(`B[(B```?`F`!R`<```@+```P"``!I5``!1\KT`$?.Z`
+M!!]T``%_:T`&?2Z`!!ZH``$JJ```?VM`!I=```<`````(#```7\O``-]L8`(
+M"50``07<``$*(``!!NP``9H`_^X`````R"`"+H@```#-H```P`@#((0``],`
+M````R`@"&WU(@!#,@`(DS4`"&X0``IX`````R`@"''U(@!#,@`(EB````,U`
+M`AS)(0``'BC__Q8@`!!^HH``B`````````#("`(`E(#_Q`````#(*`!`P"X(
+M`'ZN@`:6@/^_(!@``<@H`"R6@/\E`````,@H`'C.@`(L@``!#2`8``&(````
+M`````(@`````````(`P``,`0``8<E``!"1```7S4P`"9`/_]%(@``8@`````
+M````A``$V5.X``C`,*'TP#2@V2,(!``C3`0`R-$``,TU``#,"0``(P@(`"-,
+M"`#(T0``S34``,P)```C"`P`(TP,`,C1``#--0``S`D``",($``C3!``R-$`
+M`,TU``#,"0``(P@4`"-,%`#(T0``S34``,P)```C"!@`(TP8`,C1``#--0``
+MS`D``",('``C3!P`R-$``,TU``#,"0``S8`"`,`,(;;,#0``A```?2`X``"(
+M`````````,@X`D*;@``(R"`"098```;()`)`FD``!`````"$``3/`````,@,
+M`$#`$J``?0S`!GT,P`S,P``IR#@"`YN`_UX`````@``!I`````#(.`!6FX``
+M\R`<``#(.`!7FX``\"`<``'(.`!''[@``9>```/`.``0SX``1\@(`@"4@``/
+MR`@"`92```T`````R`@`"I2```H`````S8``#L@X`&G(-`!JSWD``,NU``#`
+M.`_LSWD``,P```X@'```R`@"`92``>4`````R"@``):``>(@"``!S8``#L@,
+M`"#,@```'!P``"J(`;N4@``R`````(``!$4`````P`PCFLR-``#`#".8B```
+M`,R-``#`,"`#S[$``(@```#+.0``'0P!`)3``-3`,#VORPT``!S,``*4P`#0
+MP#`]-,L-``"8P`)W``````````#("`)$!(@``<R``D3`,#TUS#$``,`P/3'-
+ML0``P#`]-,L-```<R``!F(#^\!S(``*8@``'R`P`')3`__H`````R!`"1040
+M``'-``)%R!`"1@40``'-``)&P#`]-<VQ``"```3O(`@``"J(`;R8@/^3````
+M`(```IH`````A``$U`````"```&D`````,`,)-3`$"36(!P``<W-``"(````
+MR14``,@(`BS`#``&P!```7S0P!+`$```P!P``)3``0U\D4`$'50``9E```S`
+M&```R1@"+P68``'(%`!['53_`!54``A]E4`1E4``!'U10`-]7<`'"9@``<V0
+M`B\%$``!@``"J@C,``&$``"X`````"`X``'`,`.8A```'Q.X`!3,``!7P#`#
+MF,PQ``"(````RPD``(0``)P`````P`@'`(0``F<`````P`@!`(0``],`````
+MS4`"&<`(`1"$``/3`````,U``AK($`(AR`@"&2`,`@<@)```A``!%P````#-
+M0`(=R`@"&B`,`@<@)``!A``!%P````#-0`(>R`P"'<@0`AY\T4`1F4```P``
+M``!]`,`'A``$8LS``B.(`````````"`X``'/@``#S``"`<@(`!R4@/],````
+M`,V```X`````(`P``X0``'T0^``>A```<"`X``+,,0``R`@"`)B```0`````
+MA``$,@````"$``)L(#@``<V``@&$``5-(`P``(0``'T@.```R`@`"I2```?(
+M.`!IR#0`:L]Y``#+M0``P#@/[,]Y``"```&D`````(@`````````P`@A@,S)
+M``#`""&"S0D``,`((82(````S4D``,@(`B[(B```?`F`!R`<``#`+``&E4``
+M#PKL``%\KT`$?.Z`!!]T``%_0T`+?VM`!I=```8@,``!?R\``WVQ@`<)5``!
+M!=P``9K`__,`````R"`"+H@```#-H```F<``"\@P`$`C,``"SP``0(0``X,@
+M.``#R#``0!\P`_W/``!`@``"/,P``%;(,`!`(S``0,\``$"$``*](#@``<@P
+M`$`?,`._SP``0(```CS,``!6(`@``8```:3,@``#R`@`1(0`!*M0B``(R#@`
+M2)>`_M;(.`)"FX``!`````"$``3/`````,@X`$<?N``!EX```\`X`!#/@`!'
+MR#@`1Q^X`!";@/_^`````(0`!+\`````A``";"`X``'()`)`FD#^F\@X`$B$
+M``#`R#@"0X```?T`````?4S``7R-``#('`![%=P`$'T=`!&5`/XY`````(0`
+M`J3,@`(M@``!I"`8``$@%``??)3`!!S,``&8P``%``````E4``&90/_[````
+M`(@`````````?,#`"\E(``!\C,`&R0@``'R,P`;`""35B````,S)``"$``"X
+M`````,`P(`B$```?(#C__\`P(`C,,0``RSD``,`P`YB$```?(#@!`,`P`YC,
+M,0``RPD``,`P(;:(````S#$``,@X`$13N``((`@"2,`P___+C@``?/%`!I5`
+M_.#,R```!(@``<P(```$B``!S`@```2(``&```.81[@`!,`0(`O`%```P!;`
+M`,U1``#)%0``P##__\B,``!\\0`&E0#_902(``'(E```S5$``!3,`!!\\0`&
+ME0#_7P2(``'(E```S5$``(```ZD$B``!A```@,W``BN(`````````,@(`D,$
+MB``!RXX``,S(``!'N``$!(@``<N.``#,R```1[@`!`2(``'+C@``S,@``$>X
+M``0$B``!RXX``,S(``!'N``$!(@``<N.```<T``!E0#_\\S(``"(````S,`"
+M0B`4```@'```P!`CF,R1``#`$".:S)$``,`0(YF$``'9`````'UI0`#`$".;
+MA``!V0````!]:4``F<#^#P2(``&```/5(!P``<@H`"B6@/WY`````,V```Z$
+M``1W`````(```=\@&``!R!P`>QW<``&9P``.R"`"),@D`B5^)<`'R"`"&\@D
+M`B8>:/__?BJ`$'WIP`?((`(<%F@`$'XJ0!!]Y<`'F<``&"`<`$!]S,`!?-G`
+M$A7<``;((`(U?Z(`$)8``!'((`(U?Z(``7WA0!"90``#`````'W"``?`%`(I
+MS4`"+L@,`A?($`!Z'1#__R`4``2$``&N`````,`X``+/@`(AB`````````#(
+M#`(#E,``"P`````@#``!A```?1#X`!Z$``5-(`P``80``FP@.```FX#^S```
+M``"$``!]$;@`'X0``FP@.``!A``%32`,``#`,`'`RSD``"`X``"5P/UYSX``
+M`WW!P`:$``!](#@``(```:3/@``#(`P``X0``'T0^``>A``";"`X``+()`)`
+MFD#_$`````"$``.C(`@"2(```TL`````R"@``I:`_.<@"``!S8``#LR```*`
+M``*:`````,P``"G-@`(#A```?2`X``"```&E`````,G,`@.4P`"C(`@``,`,
+M(;;(T0``P`H4`'T)``:9``"=(`@``"`,``&$``!]$/@`'H0``FP@.``"EX``
+MEB`(``#()`)`FD#\TP````"$``#[(`@"2(```3,`````*-``0)D`_['(.`(A
+M.-P`0)7`_X=_@8`'",P`0'S9P!(5W``&R"`"'WXZ``'(#`(7P!0"*<U``BX@
+M%``$A``#&0````#`.``&SX`"(8``!!0`````R`@"`)2``!X`````R`@"1\@,
+M`"U\C(`,E(``&0````#("``MP`P``<`0``9\T,`#",P``7R,P`;`$`(7P!0"
+M*80``WL`````A``!RP````#("`(G!(@``<R``B?(#`![',P`_A3,``%\C,`.
+MF,``!`````"$``+(T``")X@`````````R"@`!):`^]D`````(`@``<V```[,
+M@``$@``"F@````#/L0``S8``#LLY```?N`3P*[@$$)>`__T`````B```````
+M``"(`````````,`0(`O`%```P!;``,U1``#)%0``P##__\B.``!\\0`&E0#]
+M.T2(``3(E@``S5$``!3,`!!\\0`&E0#]-42(``3(E@``S5$``(``!+%$B``$
+MP`@AH,B-```4S``6',P``9C`__T`````B`````````#(*``KEH#_'0````#-
+M@``.A```.`````"```&D(!@``<@X`$B;@/[K4[@`"(@`````````'J@`_\S`
+M``O.@``,B`````````#+B@``P`PA@<R-``#`#"&#S`T``,`H``1'N``$RXX`
+M`!ST``&;0``61[@`!,N2``!'N``$RY8``(0``Q(*J``!FH#_]@````"$``2_
+MP`@AH(``!-_`*``$A``";"`X``&$``!]$;@`'\R```.$``!](#@``(```:0`
+M````A``$OP````"(`````````,`(WJW,@`!#P`H@(""(!0`@#```S(P"!\`*
+M8&`@B`\%!,P``<R,`@?`"F!@((@>#P3,``',C`('P`I@8""(*!X$S``!S(P"
+M!\`*8&`@B#(H!,P``<R,`@?`"F!@((@\,@3,``',C`('P`IP<""(4#P$S``!
+MS(P"!\`*@(`@B%I0!,P``<R,`@?`"H"`((A?6@3,``',C`('P`J`@""(9%\$
+MS``!S(P"!\`*@(`@B&ED!,P``<R,`@?`"H"`((AN:03,``',C`('P`J`@""(
+M<VX$S``!S(P"!\`*P,`@B'AS!,P``<R,`@?`"L#`((A]>`3,``',C`('P`K_
+M_R"(@'T$S``!S(P"!\`*`$`@B``0S(`")LP``BW`"``"S(`"-<P``"[,``)'
+MS``"+(0``),`````P`@`/\R``BF(````S``"%\`P`Y#+.0``P`O__G^+@`80
+MS``0?X^`!\^Q``"(````RSD`````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+8````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/BARTS_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_mc.bin.uu
new file mode 100644
index 0000000..7962013
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_mc.bin.uu
@@ -0,0 +1,539 @@
+begin 644 BARTS_mc.bin
+M``/HX``"O@$```(4``/_```#_P```J`.``'`'0`#Z````^@0``/H(``#Z#``
+M`V`8``-@'``#8"```V`H``*P_P`"L?\``K+_``*S_P`#83@``TEL``/_```#
+MKPH``K0$``)O]```^CL``K0/``)/%```^A<``T`D``*T0``"M0\``TJF``)$
+M00`#\`(``DF5``-JI@`"+:@``TG4```R0P``(A@``#H5``*U$```FD,``D53
+M``/P"``"H'X``_!&``*@8P`#\$0``/(/``(TOP`#]````<`E``/H````@@\`
+M`T`D``*T0``"M?```TJF``)$00`#\`(``FF5``-JI@`#0````_\```/X`0`#
+MQ$```\11``+&10`"`````T`0``/_```#_P```^@@``/H,``#8!```_@#``(S
+M;``",J@``T@(``*TGP`"0`0``V@(``-((0`"L\$``D=S``-H(0`#:HD``T@E
+M``*SP0`"1W,``V@E``-JC0`#2,```TC&``"",0``BC```,(O``#*+@`#Z!``
+M`^B0``-HP``#:,8``TJD``/H0``#_P```D(D``-JI``#2````T@%``*[/P`"
+MO+\``K_O``"2,P``BC0``((X``"Z-@``JCH``D$;``*[^P`"0BL``D`,``-H
+M```"15\``V@%``-($``#2=T``KOQ``*\`@``BC<``*HY``)!&P`"81P``V@0
+M``)%6P`"95P``VG=``-`#0`#_P```_\```.A3```B@T``K,"``)#-``#HS``
+M`)H,``*S!``"0S0``Z,R``":"P`"L`@``()!``*P"0``@D(``T@I``-)<``"
+MOP<``D`/``.````#``X``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H
+M+0`#P00``\$5``-IZ``#:>P``^@```/HT``",$\``VCD``/!W@`",$\``VD$
+M``-`+``#_P```K0"``)$!```HA8``TG6``*U$``"1%L``Z1&``"B&``"H$X`
+M`_`#``(T:@`#]````<#%``/T```!TW(``T`.``#R0``#Z/```Z"V``-)U0``
+M^A$``K$/``)"%P`"I2```_`!``#Z0``"0QL``J4C``/P`0``\A$``T````-`
+M+@`"MA```K0,```J0``"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!
+M``/HP```XA```T`(``*T````>A$``J`D``/P00`"L@@``J#^``/P00`"L@0`
+M`K0_``)")```DB@``TJ4``/_```#8&P``T````/_```"M$```D0$``/P`P`#
+MZ````((_``(B^@`#0````_\```*T0``"1!0``_`"``#R/P`"(OH``T````/_
+M```"M$```D04``/P`0`"+FX``TJ4``/_```#8'```T````/_```"M`(``D0D
+M``/P`P`#Z````((_``(C,0`#0````_\```*T`@`"1#0``_`"``#R/P`"(S$`
+M`TJ4``/_```#830``C-L``-````#_P```_\```)$#@`#\`,``^@```""/P`"
+M)%H``C-L``-````#_P```_\```)$'@`#\`(``/(_``(D6@`"+JD``TJ4``/_
+M```#8'0``K````""*P`#0````_\```*T`@`"1$```_`#``/H````@C\``B89
+M``-*E``#_P```V!X``-````#_P```K0$``)$0``#\`,``^@```""/P`"*)P`
+M`TJ4``/_```#8'P``T````/_```"M!```D1```/P#``#Z````((_``(I;```
+M`@T``_\```/_```"I`X``_`$``#R#@`"*6P``^@```""#@`#2I0``_\```-@
+MK``#0````_\```*T(``"1$```_`#``/H````@C\``BN$``-*E``#_P```V"P
+M``/H````@C\``K#_``*Q_P`#P2```VA@``-H:``#0````_\```*T$``"1$``
+M`_!"``/T```"`8\``T`-``-`)@`"L4```K(0``*S"``"010``Z$:``)")``#
+MHB0``F(A``)#.``#HS```F(C``"2*P`"I!X``_`)``-)/0`"LH```\`B``)$
+M0@`"*6P``TD]``/_```"LH```F1"```"$``#_P```K0!``)$!``#\`0``^@`
+M``""/P`#P?X``BQ&```"$``#_P```K0"``)$!``#\`0``^@```""/P`#Z/``
+M`BQ&``-````#_P```_\```)$+@`#\`,``^@```""/P`"-7<``T````/_```"
+MM!```D0D``/P`P`#Z````((_``(VJ0`#^`,``TJ4``/_```#8+0``K````""
+M*P`#0````_\```*T`@`"1$$``_`"``#R/P`")AD``TJ4``/_```#8+@``T``
+M``/_```"M`0``D1!``/P`@``\C\``BB<``-*E``#_P```V"\``-````#_P``
+M`K00``)$00`#\`L``/(_``(I;````@T``_\```/_```"I`X``_`$``#R#@`"
+M*6P``^@```""#@`#2I0``_\```-@[``#0````_\```*T(``"1$$``_`"``#R
+M/P`"*X0``TJ4``/_```#8/```/(_``*P_P`"L?\``\$@``-H8``#:&@``T``
+M``/_```"M!```D1!``/P0@`#]````@(.``-`#0`#0"8``K%```*R$``"LP@`
+M`D$4``.A&@`"0B0``Z(D``)B(0`"0S@``Z,P``)B(P``DBL``J0>``/P"0`#
+M23T``K*```/`(@`"1$(``BEL``-)/0`#_P```K*```)D0@```A```_\```*T
+M!``"1`0``_`#``#R/P`#P?X``BQ&```"$``#_P```K0(``)$!``#\`,``/(_
+M``/H\``"+$8``T````/_```#_P```D0^``/P`@``\C\``C5W``-````#_P``
+M`K00``)$-``#\`(``/(_``(VJ0`#2I0``_\```-@]``#^`,```(8``/_```#
+M_P```J`.``/P0@`#]````@)L``-`+``#_P```K0@``)`0``"H`0``_!(``/H
+M````@C\``C((``(R30``\C\``C((``(R30`",N0``T````/_```"M`@``D0$
+M``/P#``#2`@``_\```*T0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#``
+M`\$N``-H,``",O@``^@```/H$``#Z#```K(#``-H,``#0````_\```*U"``"
+M114``_`!``(TUP`#2I0``_\```-@^````D```_\```/_```"H0X``_`"``/H
+M````@A0``BZI``-(```#2`4```HT```".```$C,``"HZ```Z-@`#_P```V@`
+M``-H!0`#2!```TG=```*-P``*CD``_\```-H$``#:=T``TEQ``*R`0`#Z#``
+M`\$&``/!%P`#:#```TEL``*U%@`"H%$``<*?``*PSP`"L04``K(!``*S```#
+M:#```C+X``*PM``#:#```C+X``*PO``#:#```C+X``*PN``#:#```C+X``*P
+MRP`#:#```C+X``*PC``#:#```C+X``*PT0`#:#```C+X``/H```#Z!```K(#
+M``*S```#:#````(8``/_```#_P```J`.``/P0@`#]````<`````!]``#0!(`
+M`T`5```*&P`"H`X``_`"``/T```!PL\``L$>``"*&P`":[H``F5;``+&;@`#
+M\$$``L=^``-@%0`"L@\``D1"``*E%``#\`<``^B@``/HL``#8!(``^@```"!
+M]``#]````<!-``-`+``#_P```K0@``)`0``"H`0``_!"``/T```!PN0``^@`
+M``""/P`",@@``C)-``#R/P`",@@``C)-``(RY``#0!```_\```/_```#H`8`
+M`X`&``/!\``"+GL``\'P``(N>P`#P?```BY[``/!\``"+GL``T`@``/_```#
+M_P```L`.``/P10`"P1X``_!#``+"+@`#\$$``L,^``-@(``",VP``TE(``*T
+M/P`"M8```D,T``)C-0`#:4@``D,T``-I2``#]````<````-`!```:C\``^B`
+M``/HD``#Z*```^BP``*U$``"1!4``_`&``*@W@`#\`,``V2J``/T```#\$$`
+M`V3J``/X`0`"M0@``D0%``(#'```8?@``J#>``/P`P`#Z$```_0```/P00`#
+MA.H``]A```/<P```>?<``_@#``/4G@`#^P```P_^``(#&``#^`$``X7D``)$
+M%0`"`R\``"'Y``*@W@`#\`,``&'Q``/T```#\$$``&'P``*_"``#W$```]C`
+M``/X`P`#U)X``_L```,/_@`"`RL``_@#``/L`````A0```I```!J/P`#_P``
+M`D`!``*@#@`#\`$``^P```-).``"H-X``_!!``-*7``"N/X``D(H``*@W@`#
+M\`,``VDX``/T```#\$$``VI<``-)T``"M`0``F$4``*R`0`"LQ(``J#>``/P
+M00`"LQ$``V@P``-)<0`"N.\``KD$``/!!@`"87D``D,X``-H,``#2`D``KC]
+M``)$2``#:`D``BY_``-)H``"M!$``\$D``*Q#P`#::```TI$``*T_@`"81X`
+M`VI$``)!%``#:D0``J#>``/P`P`#0F$``_0```/P00`#0ET``_\```/_```#
+MZ&```VFE``-H:P`"N@P``KC```/<@0`#V*$``K#X``*Q!P`#Z"```^@P``/^
+M```#U!\``VAK``/H\``"(_\``B/B``(D'``"H?X``_!!``-B>@`#0G@``_\`
+M``/_```"H(```<.3``*@D0`!PY,``J"B``'#DP`"H+,``<.3``+/_@`"O`P`
+M`J'\``/P0@`#]````<-]``#Z!``#Z/```B/B``(C_P`")!P``T)X``/_```#
+M_P```J"```'#J0`"H)$``<.I``*@H@`!PZD``J"S``'#J0`"S_X``KP,``*A
+M_``#\$(``_0```'#E@``8@0``/H#``/_```"I<\``<.Y``*E_``!P[0``^CP
+M``/HP``#]````<.\``,,SP`#K,```^CP``/T```!P[P``P_\``.O\``#Z,``
+M`B/_``/!_``"(^(``TDX``*@W@`#\$$``TI<``/_```"8BX``J#>``/P`P`#
+M:3@``_0```/P00`#:EP``TG0``*T^P`"010``K(!``*S$@`"H-X``_!!``*S
+M$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@``V@P``-("0`"N/T``D1(
+M``-H"0`"L!@``B1```/L```#1+D``J#>``/P00`#1/D``\$/``/!'P`#P2\`
+M`\$_``/!3P`#P5\``J#>``/P!0`#9+```V2T``-DN0`#]````_!#``-D\``#
+M9/0``V3Y``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P```-$
+MN0`"H-X``_!!``-$^0`#P0\``\$?``/!+P`#P3\``\%O``/!?P`"H-X``_`%
+M``-DK``#9+P``V2Y``/T```#\$,``V3L``-D_``#9/D``TC(``*T\P`"M00`
+M`D`$``)@!0`#:,@``D`$``-HR``#[````K`0``(D0``",O@``C+X``(R^``"
+M,O@``C+X``-*'``")$P``\&,``-*(``")$P``XS&``)HC``#2B0``B1,``/!
+MG``#2B@``B1,``.,Q@`":9P``THL``(D3``#P:P``THP``(D3``#C,8``FJL
+M``-*-``")$P``\&\``-*.``")$P``XS&``)KO``#[````VAK``*Y"``"N,``
+M`]R```/8D``#Z!```^@@``/H,``#_@```]0>``-H:P`#[````^C```.'/``#
+MIW8``X8L``.F:``#A1P``Z5:``.$#``#I$P``FS'``)LQ@`";,4``FS$``/L
+M````(@\``T`D``/_```"1$X``Z`&``*A#@`#\`$``(('``-)I``#2:$``&H_
+M``.+Z@`#P*L``D6E``*@W@`#\`,``D.C``/T```#\$$``F.S``-II``#::$`
+M`K+_``*Q_P`"L'\``VA@``/H```#Z"```^@P``*@W@`#\`,```H)``/T```#
+M\$$```H(``*XP``#:&L``]@```/<@``#U!X``K\"``(N>P`#@.```(($``""
+M`P`#Z````(("``""`0``\@```TA4``*@W@`#\`,``X3H``/T```#\$$``X3J
+M``)B)``#:%0``TF8``.(Y0`#P3X``J#>``/P`0`#@S```\$N``)@"``#:#``
+M`TEU``.(Y@`"8&@``\$7``/!+@`#P3X``J#>``/P`0`#@S```V@P``-(5``"
+MH-X``_`#``.$Z``#]````_!!``.$Z@`#P$0``D(D``-H5``"OP(``BY[```"
+M&``#_P```_\```*@#@`#\`(``_0```($UP`",&$``^AP``.$Y@`"1DL``J!D
+M``/P3P`#2=(``^A@``.*L@`#JJH``X2F``)D2@`#P50``J#>``/P`P`#:.4`
+M`_0```/P00`#:04``_0```'%@@`"OP@``D_Y``.O]``#B[(``ZN\``(EI@`#
+M]````@6"``-`#``#_P```K\(``)/\``#\$(``_0```'$]``"OP```KL!``(E
+MI@```A$``_\```/_```"H`X``_!"``/T```!Q8(``K$"``*P$0`"Q$```L50
+M``*@W@`#\`,``VCE``/T```#\$$``VD%``,!'@`"!.D``/("``#R`0`"H-X`
+M`_`#``!Z!@`#]````_!!``!Z!0`#C>(``]S0``/8\``#B>8``FF>``#Q\@``
+M0@<``^C0``./X``#P:@``XSM``#A]@``XCX``B_*``*W`0``0@<``^B@``#1
+M\@`"H'X``_`!``.H@``##]\``\'9``/!J``#C.T``.'V``#B/@`"+\H``C`+
+M``/!!``#P28``V)P``*_`0`#0!$``XC@``*@_@`#\`0``D1(``/P`@`#]```
+M`@5H``*W`0``0@<``_\```*@?@`#\`$``ZB```/HT``#C^```\&H``.,[0``
+MX?8``.(^``(OR@`",`L``T)P``.,ZP`#C.H``^CP``+(0``#J(```"H6``+*
+M8@`#JJ```J9>``(%10``:C\``/(6``/!6``#P7H``V)Q``/T```"!/\``J%>
+M``/P#@``:C\``\&1``/!LP`"H-X``_`#``-A+@`#]````_!!``-A,@`"P($`
+M`Z@```+"HP`#JB```X50``"J%@`#@>```P"$``/P)``"H80``_`!``+$00`#
+M!$X``\%4``,"I@`#\"0``J&F``/P`0`"QF$``P9N``/!=@`#U%X``F`"``(%
+M5P``:C\``K\"``(N>P`#27$``X'D``/!!@`#HFP``J`N``(%@@`"87$``\$N
+M``/!/@`"H-X``_`!``.#,``#AF```_!'``-H,``#C^T``BY[``./[0`"+GL`
+M`X_M``(N>P`#C^T``BY[``-)=0`#P2X``\$&``/!%P`#P3X``J#>``/P`0`#
+M@S```V@P``-)F``#_P```\$^``*@W@`#\`$``X,P``/!+@`#:#````H/```!
+M]``#_P```D$>``/P`0`#[````J4.``/P2``#0!$``J#>``/P`P`"9FX``_0`
+M``/P00`"9WX``V`1``/H````@?0``^P```(R^``#2D```$(```!*!```4@,`
+M`KPS``)$#``"11P``F1%``)&+``"1SP``F9G``)D1@`"H4X``_`!``*T`0`"
+MH(X``_`%``*D20`#\$,``J1+``/P00``\@(``*($``*\S``"1`P``D4<``)&
+M+``"1SP``F1%``)D1@`"9$<``J%.``/P`0`"M`$``J".``/P!0`"I$H``_!#
+M``*D2P`#\$$``/(!``"B`P`#Z$```*(```-#*0`"H-X``_!!``-#:0```@(`
+M`!(!``*Q#P`"LP<``J7^``(%_``"H`X``_`&``*\#P`"I$$``_`!``*\"0`#
+MP4P``\%<``*@+@`#\`8``KP/``*D80`#\`$``KP)``/!;``#P7P``J#>``/P
+M`P`#8RD``_0```/P00`#8VD``DP"``*@S@`#\`8``L_^``*\"0`"I?P``_`"
+M``/T```!Q:8``TCE``*@W@`#\$$``TD%``*X$0`"H`X``_`!``+$2``"24$`
+M`J23``/P`0``\@(``J`N``/P`0`"Q5@``DE1``*DDP`#\`$``/(!``*@W@`#
+M\`,``VCE``/T```#\$$``VD%``)``@`"H`X``@6F``/L````:C\``^@```(P
+M.P`#29@``K@/``*U]0`"LP$``J#>``/P`0`#@S```\$N``)@"``"014``V@P
+M``*_```"+GL``/'_``/H````@?X``T`,``-`+0`"N!```KD(``)*&``#JJ8`
+M`DM)``.KM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*$0`"
+ML$```D!```/P00`#Z#```D$>``/P`0`#Z#```)G]``(N?P`"O`$``J#>``/P
+M"0`#2"$``XS&``.&9@`#IF8``F9L``-H(0`#:HD``_0```/P1P`#2"4``XS&
+M``.&9@`#IF8``F9L``-H)0`#:HT``K`!``/H$``#Z"```^@P``-J8``"OP,`
+M`C'5``-("``#A.H``('U``)@!``#:`@``K]D``(N>P``:C\``_\```/_```"
+MH-X``_`#``*[```#]````_!!``*[0```V>\``\$.``/!'@`#@18``F$>``."
+MY@`#:D0``\$>``.!%@`#Z"```VI$``/H```#P````\$0``*R_0`#:&```TI@
+M``*_]P`"L1,``D`/``)@#@`#:F```#(,```Z"P`"O`@``K_^``.&:@`"8B8`
+M`J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(N>P`#:&L``_\```/^````
+M8CT``%H\``/_```#V,$``]RQ``./XP`"+GL``]`?``.,[P`#C^0``F_^``)`
+M`0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!J(``J#>``/P`P`#2"$``_0`
+M``/P00`#2"4``\#,``(&S@`#C.8``L9L``/P00`"QWX``J#>``/P!``#:"$`
+M`VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!QG$``T`1``*P"```
+M\?0``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T```""(,``X#A``.!
+M!@`"81X``X+G``-J1``#@08``^@@``-J1``"L`$``^@0``/H(``#Z#```VI@
+M``-`+```6BL``K0$``/H\``"1$```_`!``*_`0`"I+X``_`!``*_!``",=4`
+M`/(G``#R)0`"L/\``K&_``/!(``#:&```K`!``/H$``#Z"```^@P``-J8```
+M"CL``!(,```:"P`"L`(``J#>``/P00`"L`0``X(J``*D/@`#\`$``K,$``.!
+M%@`"8`$``K$S``-J8``#0`H``K`!``*Q`@`"L@```K,!``*@*P`#\`(``^@@
+M``/!.P`#:F@``\$.```20@`"0`D``_`!``/H(``"L!,``K$"``.")@`#Z#``
+M`VIP``-`+0``8A$``!(H``*_0``"3T\``_`#``*@S@`#\`$``K((``*P(0`"
+ML0(``K,!``-J=```"BL``K`!``/_```"I!X``_`%``*Q!``"L@```K,"``/T
+M!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q`@`"LP0``VI\
+M```!_@`#_P```_\```+`#@``@?X``C'0```")P`#0`H``T`-``*@#@`#\`4`
+M`K`!``)`!0`#@`8``_0$``/P`P`"L`0``D`)``.``@`"L0,``F@!```"*P`#
+M_P```_\```*D#@`#\`L``!(H``*P(P`"L0,``K,!``-J=``#2GP``_\```*P
+M`0`"L00``K,$``-J?``#2F0``K2````1[P`"0`0``F`(``.B(@`"LP$``VID
+M``(PE0`",*(```'_``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H`
+M`J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(O"P`#Z/```/G_```!_@`#
+M_P```_\```+`#@``@?X``T`E```:$``"L@0``D(@``*@W@`#\$$``Z,R``*Y
+M`@`"29,``F(I``*Y@``"294``F(I``*YA@`#Z(```J`I``/P00`#P8X``,':
+M```)_0`#0"X``_\```*@`0`"!Z(``K`!``)!"``#\`4```)```/_```#_P``
+M`J`.``('H@`#2G0``'HH``/_```#_P```\$O``-J=``",=````(G``-`"@`#
+M0`T``J`.``/P!0`"L`0``D`%``.``@`#]`0``_`"``*P$``"0`D``'G:``*Q
+M0P`#_P```J#^``/P00`"L2,``F@!```"*P`#_P```_\```*@#@`"!]0``!(H
+M``*P0P`"L00``K,!``-J=``#2GP``_\```*P`0`"L04``K,$``-J?``#2F0`
+M`K2````1[P`"0`0``F`(``*X(``"8`@``KB_``)`"``#HB(``\$^``-J9``#
+M]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``/!/@`#:F0``C"5``(P
+MH@``0A```K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```'']0`#0`X``K`0
+M``/_```"00D``J`0``(']0```B<``_\```/_```"P`X``((G``*Q`@`"I`$`
+M`@<U``!![P```?D``_\```/_```#V(```]P```!Z0@`"L`$``]P!``*P```#
+MV`$``$G:``/_```#_P```J">``/P1@`#Z/```K$D``+(@0`#V(```L`!``/8
+M@0`",(P```'^``/_```#_P```L`.``"!_@``>=H``C'0``*@_@`#\$4``K`/
+M``/!$``#P2```\$P``-J@``#0`H``K!```/_```"0`D``Z`"``*Q`P`":`$`
+M``(K``/_```#_P```J0.``/P"P``$B@``K!#``*Q!0`"LP$``VIT``-*?``#
+M_P```K`!``*Q!@`"LP0``VI\``-*9``"M(```!'O``)`!``"8`@``Z(B``*S
+M`0`#:F0``C"5``(PH@`#0"4``$(0``*P(``"0`4``_!(``*P`@`"H-X``_!!
+M``.``@`"0`@``_`"``/T```!R&4``!'^``*P@``"LP,``J`C``/P0P`"0`4`
+M`_`!``(QE@`#0"X``_\```*P"``"00@``J`0``((90`"L(```D$(``/P!0``
+M`D```_\```/_```"H`X``@AE```")0`#_P```_\```/H$```BB4``J0.``('
+M=P```>\``$'Y``/_```#_P```]@```/<@```>D(``K````/8`0`"L`$``]P!
+M``-`#0`"O2```_\```)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\`
+M`K+_``-H8``#:&L``!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#
+MZ#```VI@``-*9``"M(```D`$``-J9```(?4``_\```-("``#_P```\$$``-H
+M"``#[````^@```/H$``"H-X``_`#``-I'``#]`0``_`!``-I-``#[````&H_
+M``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_````V?P`
+M`C*.``/H```",#L``KL"``#:/@`#2`$``K"_``)$0``#:`$``TF8``*T#P`"
+MM?T``F`$``)!%0`#P2X``\$^``*@W@`#\`$``X,P``-H,``#2`@``K1```"!
+M]0`"8`0``V@(``/H```"L6```^@@``/H,``#::```^@```*Q$``#Z"```^@P
+M``-J1``"L`$``^@0``/H(``#Z#```VI@``*_`@`",=4``^@```/````#P1``
+M`K+]``-H8```"CL``!(,```:"P`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+GL``VAK``/_
+M```#_@```C'^``-*8```,@P``#H+``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"````20@`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``"L/\``K&_``/!(``#:&```^AP``-*9``"M(```D`$
+M``/H(``#Z#```VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0`
+M`C"5``-*9``"M`@``D1```)G=``"I7X``@E<``/H```",#L``J#>``/P`P`#
+M2"(``_0```/P00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H
+M(@`#:HH``_0```/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R2$``T`2
+M``#Q]``"OP0``J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R5P`
+M`K`!``/H$``#Z"```^@P``-J8``#2F0``K2```)`!``#:F0``"'U``/_```#
+M2`@``_\```/!!``#:`@``^P```!J/P``\?\``^@```""$P`#0`@``T`M``*X
+M0``"N0@``DH(``.JJ@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!
+M``*S!@`#0"T```H1``*P0``"0$```_!!``/H,``"01X``_`!``/H,```FA(`
+M`"'T``/H4``#_P```*(9``"I]```:C\``_\```/_```"H-X``_`#``!9\0`#
+M]````_!#``!9\``#_P```_\```#9[P`#2````X3J``/`1``#_P```D`$``-H
+M```#2`0``\!^``/_```#_P```D,W``-H!``#0"P``%HK``*T!``#Z/```D1`
+M``/P`0`"OP$``DN^``*@O@`#\`,``C#]``/T```!R;4``K_+``(S00``\B8`
+M`/(E``*P_P`"L;\``\$@``-H8``"L`$``^@0``/H(``#Z#```VI@```*.P``
+M$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B
+M(0`"I#X``_`!``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"
+M``*R```"LP$``J`K``/P`@`#Z"```\$[``-J:``"L`$``!)!``)`"0`#\`$`
+M`^@@``*P$P`"L0(``X(F``/H,``#:G```T`M``!B$0``$B@``K]```)/3P`#
+M\`,``J#.``/P`0`"L@@``K`A``*Q`@`"LP$``VIT```**P`"L`$``_\```)!
+M$``"I!X``_`%``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX
+M``-*?``#_P```K`!``*Q`@`"LP0``VI\```**P`#_P```_\```)!'@`"I!X`
+M`@I4```"$P`#_P```_\```+`#@``@A,``C'0```")@`#0`H``T`-``*@#@`#
+M\`4``K`"``)`!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"
+M*P`#_P```_\```)`#@`"I`X``_`+```2*``"L",``K$#``*S`0`#:G0``TI\
+M``/_```"L`$``K$$``*S!``#:GP``TID``*T@```$>\``D`$``)@"``#HB(`
+M`K,!``-J9``",)4``C"B```!_P`#_P```_\```*@#@`#\$X``T`L``*\!``#
+MW,```K_```*@W@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+PL``^CP``#Y
+M_P```A,``_\```/_```"P`X``((3``!:*P``>B4``K@(``)*O@`"H*X``<IX
+M``.JL``"2JX``_!#``(M:``#]````<IT``-*<``"NH@``KEP``*@^``#\$,`
+M`\$J``/T```!RG(``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C,+``*P_P`"
+ML;\``\$@``-H8```"A(```(3``-`+@`#_P```J`!``(*C``"L`$``D$(``/P
+M!0```D```_\```/_```"H`X``@J,``-*=```>B@``_\```/_```#P2\``VIT
+M``(QT````B8``T`*``-`#0`"H`X``_`%``*P"``"0`4``X````/T!``#\`,`
+M`K`@``)`"0`#H````K%#``)H`0```BL``_\```/_```"0`X``J`.``(*O```
+M$B@``K!#``*Q!``"LP$``VIT``-*?``#_P```K`!``*Q!0`"LP0``VI\``-*
+M9``"M(```!'O``)`!``"8`@``K@@``)@"``"N+\``D`(``.B(@`"L00``\$^
+M``-J9``#]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``*S`0`#:F0`
+M`C"5``(PH@``6BL``KH!``/_```"2[H``J"Z``/P0@`#]````<KE``!"$``"
+ML`$``J#>``/P00`#@`(``D`(``/P`@`#]````<KE``-`"@`#_P```K!```)!
+M"``"H!```@KE```")@`#_P```_\```+`#@``@B8``K$"``*D`0`""A$```'O
+M``!!^0`#_P```_\```/8```#W(```'I!``*P```#V`$``K`!``/<`0`",(P`
+M``(3``/_```#_P```L`.``""$P`",=```T`*``*P@``#_P```D`)``.@!``"
+ML0,``F@!```"*P`#_P```_\```)`#@`"I`X``_`+```2*``"L$,``K$%``*S
+M`0`#:G0``TI\``/_```"L`$``K$&``*S!``#:GP``TID``*T@```$>\``D`$
+M``)@"``#HB(``K,!``*Q```#:F0``C"5``(PH@``6BL``KH#``*Y`0`#_P``
+M`DBZ``*DB0`!RU<``KD$``/_```"2+H``J"*``'+.0```B4``K((``*S```#
+M_P```J0"``'+5P`"H`X``_!#``":)0`#]````<I4``)+N0`"H+D``<M7``"2
+M)0`#]````<I4``/T```!RU<``$(0``*P`0`"H-X``_!!``.``@`"0`@``_`"
+M``/T```!RU<``T`N``/_```"L`@``D$(``*@$``""U<``K"```)!"``#\`4`
+M``)```/_```#_P```J`.``(+5P```B4``_\```/_```#Z!```(HE``*D#@`"
+M"E0``%HK``/_```#2G```_\```)+O@`"H+X``_!"``*R@``#:G```&'Y``!9
+M[P`#_P```]S```/8L```>D$``K````/8`0`"L`$``]P!``-`#0`"O4```_\`
+M``)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\``K+_``-H8``#:&L`
+M`!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#Z#```VI@``(QT``#
+M[````&H_``/_```#_P```J#>``/P`P`"NU,``_0```/P00`"NUL``_\```/_
+M````V?P``T`0``*[#P`#2"D``J#>``/P00`#2"T``K\$``)`"P`#JP(``P_[
+M``.,]@`";,\``X_V``-)Z``"HTP``_`$``,$3``#!5\``_0```/P10`#A.8`
+M`X56``.E5@`"950``F1.``/!!``#P14``J#>``/P!``#:"D``VGH``/T```#
+M\$(``V@M``-I[``#Z````C!/``-(`0`"L+\``D1```-H`0`#Z````K%```/H
+M(``#Z#```VI$``*P`0`#Z!```^@@``/H,``#:F```K\"``(QU0``"CL``!(,
+M```:"P`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$``)B(0`"I#X`
+M`_`!``*S!``"L1@``VI@``-`"@`"L`$``K$"``*R$@`#Z#```VIH``*P@```
+M$D$``D`(``/P`0`#Z"```K`3``*Q`@`#@B8``^@P``-J<``"L"$``K$"``*R
+M`0`"LP$``VIT``*P`0`"L0(``K(/``*S`0`#:G@``TI\``/_```"L`(``K$"
+M``*S!``#:GP``^@```/````"L;\``\$@``-H8``#Z'```TID``*T@``"0`0`
+M`VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0``C"5``-*9``"
+MM`@``D1```)G=``"I7X``@P\``/H```",$\``J#>``/P!``#2"H``TGH``/T
+M```#\$(``T@N``-)[``"O!$``K\0``+)GP`"R(P``\$(``/!&0`"H-X``_`$
+M``-H*@`#:>@``_0```/P0@`#:"X``VGL``*[`0``VCX``^AP``.+Y0`#B[8`
+M`J6+``/P`@`#]````<O\``-`$@``\?0``K\@``*@W@`#\`,``FJO``/T```#
+M\$$``FN_``-@$@`#]````<P\``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID``/L````:C\``^@```"!V0`"L`@``('[``*@W@`#\`,``%GQ
+M``/T```#\$$``%GP``*P?P`"H?X``_!!``)+L```V>\``K#_``*QOP`#P2``
+M`VA@``*P`0`#Z!```^@@``/H,``#:F````H[```2#```&@L``K`"``*@W@`#
+M\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"LP0``T`5``*Q
+M"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J:```$?L``K`3
+M``*Q`@`#@B8``^@P``-J<```$B@``K`A``*Q`@`"LP$``VIT``*P`0`"L0(`
+M`K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP``KP$``/<P```
+M>>\``&'[``*[&``#V/```B\+```!V0`#0"4``K\0``+`#@``@=D``D]?``/P
+M`P`"+6@``_0```',J0`"OP@``J`.``/P`0`#P?X``C,+``-*@``"H/X``_!!
+M``-JA```8>\``K"```/H\``"H<```_!!``/!_@`"+1L``C'0```1[P`#Z!``
+M`K`C``.B(@`"LP$``VID``(PE0``8=D```'O```)^0`#0"8``K(0``/8```#
+MW!```'G[``*P```#V`$``K`!``/<`0`"0BD``_!%``.O\``"H,X``_`"``/[
+M```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E+@`#\`$``_L!
+M``,/_@`"#,L```'9``/_```#_P```L`.``"!V0``8>\``K"```/!_@`"H<``
+M`_!!``/H\``"+1L``C'0```1[P`"L`,``^@0``.B(@`"LP$``VID``(PE0`"
+M,*(``T`E```!V0`"L0,``K((``*S$``"0S4``_`"``)")0`#\`(``J4!``',
+ME@``8?D``%GO``/_```#W,```]BP``*P```#V`$``K`!``/<`0``>?L``T`-
+M``*]0``#_P```DW5``*FW@`#\`,``B\K``/T!``#\`H``K!_``*Q_P`"LO\`
+M`VA@``-H:P``$>4``K/```/HT``#8$P``B]F``*P`0`#Z!```^@@``/H,``#
+M:F```C'0``/L```"O!$``J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(
+M\0`"+5,``J#>``/P!``#:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$
+M``-(U``#2-D``_0```/P0@`#2/0``TCY``(M4P`"H-X``_`$``-HU``#:-D`
+M`_0```/P0@`#:/0``VCY``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#
+M\`0``L`,``+!'``#]````_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P
+M00`#:/P``^P```*@_@`#\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L
+M``+'?``#]````_!(``,`#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP`
+M`^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#H`,``]P```/8$``#
+M0#$``K\#``*\`@`"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X``_!!``/!
+M!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#^P```P_^
+M``(-=0`#0#4``K\#``/_```"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X`
+M`_!!``/!!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#
+M^P```P_^``(-C0`#0#@``T`]``/_```#:H0``VJ!``/L```#85```V%5``-A
+M6@`#85\``TA4``/_```#Z#```Z,S``-H5``#:&L``TA5``/H```#Z'```K+O
+M``*Q_P`"L+\``VA@``-H:P`#27P``K0$``)A%``#:7P``TD\``/_```"81X`
+M`VD\``-*E``#03D``_\```/_```"IC<``_`'``*F)@`#\`4``J85``/P`P`"
+MI00``_`!``-A.``#8/P``_\```/^```#_P```TAD``*T$``"0B0``J`D``/P
+M0P`"+A4``_0```'-T``"L/\``K'_``*R_P`"L_\``VJ0``-)/``#P$X``D$4
+M``-I/``#2%0``K4_``)#4P`#:%0``^@```"!]```@AH``((;``-(9``#C.H`
+M`/(5``),#``#\$@``T@T``/_```#@`@``Z`,``*@#@`#^`$``@WQ``""%0`#
+M^`,``TA5``/H```#AP<``VA5``-)/0`"OQ```D1/``/P!``"O_\``BY[``*_
+M4``"+GL``Z=P``,'?@`"#@<``\`@``/`$``#P````VA@``-H:P`#H!```VA@
+M``-!4``#054``T%:``-!7P`#[````_@#``-)T``"N`@``DDX``*@F``"#F@`
+M`TG4``*T$``"0S0``J`T``(.1``#2`@``K@(``)@"``#:`@``T@H``*X(``"
+M8S@``T@M``-H*``#:>@``F=X``-H+0`#:>T``TC(``*X^P`"0B@``VC(``-(
+MF``"N"```F`(``-(L0`#:)@``F1(``-HL0`#P0X``\$>``/!+@`#P3X``V,P
+M``-C<``#8S0``V-T``-C.``#8W@``_0```'.:``#2`@``KCW``)`"``#:`@`
+M`T@H``*XWP`"0S@``T@M``-H*``#:>@``D=X``-H+0`#:>T``TC(``*X!``"
+M8B@``VC(``-(F``"N-\``D`(``-(L0`#:)@``D1(``-HL0`"L`,``\$0``/!
+M(``#P3```V,P``-C<``#8S0``V-T``/!+@`#P3X``V,X``-C>``#27P``K3[
+M``)!%``#:7P``VAK``/L```#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(`
+M`VC*``)H(0`#:,H``\&"``-HR@`#[````_@#``,/_@`"#GP``^P```/H```#
+MP!```\`@``.@$``#:&```VAK``/!#@`#Z!```^@@``/H,``#I!,``]@0``/<
+M0``#_@```]0>``-H:P`#::0``^@```/^```#U!X``VAK``-II``"H-X``_`#
+M``-"8``#]````_!!``-"7``#0ED``J#>``-II``#\`,``T)H``/T```#\$$`
+M`T)D``-IH0`#_@```]0>``-H:P`#:&L``^P```/H```#P"```\`0``.@$``#
+M:&```VAK``-"5@`#P0X``^@0``/H(``#Z#```Z03``/8$``#W$```]0>``*_
+M`@`"+GL``VAK``-II``#::(``^@```/_```#U!X``K\"``(N>P`#:&L``VFD
+M``/H```#P"```\`0``/````#:&```VAK``/L```#:&L``K!_``*Q_P`"LO\`
+M`VA@``*Q#``#Z````Z`#``/<```#V!```^@```/H$``#Z"```^@P``/^```#
+MU!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>``-H:P`#^P```PB.``(.
+MX``#[````"'Z``/H4``#Z&```^AP``*Y"``"N,```]R!``/8D0`#0E```_@#
+M``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#:&L``K09``/^```#U%\`
+M`VAK``-)I0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#
+M"9X``@\'``-II0`#[````J&^``/P"@`#T!X``P^^``/X`P`#``X``P$>``,"
+M+@`#`SX``]0>``,/_@`"#Q```_L```,,S@`"#PL``^P```*AO@`#\`H``]`>
+M``,/O@`#^`,``L`.``+!'@`"PBX``L,^``/4'@`##_X``@\@``/[```##,X`
+M`@\;``/L```#T)X``]`?``*\/P`"2(P``DF<``)*K``"2[P``D0,``)%'``"
+M1BP``D<\``*\(``"P(0``Z````*C2``#\$$``L`,``+!E0`#H1```J-9``/P
+M00`"P1P``L*F``.B(``"HVH``_!!``+"+``"P[<``Z,P``*C>P`#\$$``L,\
+M``/HT``#C.D``P2```+HC0`#!9$``NF=``,&H@`"ZJT``P>S``+KO0`#8FX`
+M`DB,``))G``"2JP``DN\``/4G@`#0FX``F1%``)D1@`"9$<``@]-``!J/P`#
+M^P```_L!``,/_@`"#RL``^P```/0G@`#T!\``KP_``)(C``"29P``DJL``)+
+MO``"1`P``D4<``)&+``"1SP``KP@``+`A``#H````J-(``/P00`"P`P``L&5
+M``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#\$$``L(L``+#MP`#HS``
+M`J-[``/P00`"PSP``KP'``*CW``#\$X``W!,``-03@`#_P```_\```/^```#
+MU!X``VAK``/[```#<$X``U!,``/_```#_P```_0$``/P"``"O`@``J3<``/P
+M`0`#:H0``KP)``*DW``#\`$``VJ```*P_P`"L;\``K+_``-H8``#^P```_L!
+M``+-W@`"IM\``@]F``-*9``"M(```D`$``-J9``"L````K$```*R```"LP$`
+M`VIT``*P,0`"L08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#
+M:GP``TID``*T@``"0`0``K0#``)@!``#:F0``C"5``-*9``"M(```D`$``-J
+M9```:C\``C-L``/L````6?8``&(^``/_```"H;X``_!"``#Q]``#[````J'.
+M``/P00`#"[X``PS.``#9]@``XCX``TI```!:%@`#_P```_\```*@O@`#\$(`
+M`Z````.B(``#T%X``&(*``!9\@`#H@(``D`)``)"*0`"I8X``@_U``,(C@`"
+MH`T``_`+``!"!P`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$
+M3P`#P50``J6N``(0!0`#"JX``J`M``/P"P``4@<``L9O``/!=@`"H+X``_!&
+M``/47@`"QF\``\%V``/47@`"QF\``\%V``/47@`##,X``A`&``)KB@`"#\H`
+M`^P```-"<```4A8``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"
+MH6@``_!!``+&:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&
+M:``#`B@``P,X``,*K@`"$!D``\%4``/!=@`#U%X``V)P``/L```#P6(``P9N
+M``/<$``#V````]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X`
+M`_L```,&;@`"$"X``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#
+M:1```VD4``-I&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I
+M-``#[````\$0``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<
+M``/T```#\$4``VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4`
+M`D$#``-)T@`#_P```D`*``-)P@`"I1```_`!``-)Q@`#[````K!_``*Q_P`"
+MLO\``VA@``-H:P`#Z````^@0``/!+@`"LS```VFD``/H```"L3```^@@``/H
+M,``#Z$```Z5#``/80``#W%```_X```/4'@`#:&L``_L```/[```"L!(``^@0
+M``/^```#U!X``VAK``,(C@`"$(8``^P```/0G@`#^P```_\```/_```#U)\`
+M`_L!``,/_@`"$(P``^P```/X`0`"OP0``TID``/_```#_P```D$/``(0EP`#
+M^`,``VAK``/_```#_P```_X```/L```#2F0``_\```*_"``"00\``J`?``(0
+MPP`#0!(``K40``*E)0`#\`0``K\"``)JKP`#]````=#```+$50`"I20``_`$
+M``*_`@`":[\``_0```'0P``"Q$4``J4D``/P!``"OQ```FJO``/T```!T,``
+M`K\0``)KOP``\?0``V`2``(PQ``#[````TIP``/_```#P<(``T`N``*P`0`#
+M:J@``_\```/_```#_P```TJL``*T`@`#:JD``\````/`$0`#P"(``\`S``-*
+MK0`"OY```J#/``/P!0`#P$0``K\/``)/3P`#]````_!!``/`]``"H-X``_`+
+M``-`&0`#_P```_\```)D0``"95$``F9B``)G<P`#8!D``FJO``/T```#\$D`
+M`T`=``/_```#_P```F1```)E40`"9F(``F=S``-@'0`":[\``V`N``/L```"
+MQ$8``VJI``/_```#_P```_\```-*K``#[````K!_``*Q_P`"LO\``VA@``-H
+M:P``">4``K#```/<```#V!```J#^``/P!``#Z````^@0``/H(``#Z#```J#^
+M``/P1``"L%4``\$0``/!(``#P3```J#^``/P!``"M/\``\%4``/!9``#P70`
+M`J#^``/P1``"M*H``\%4``/!9``#P70``KP'``*C_@`"$7D``$(-``/_```#
+M_P```J".``(1/P`"H-X``_`#``-`0@`#]`0``_`!``-`1@``ZC\``&H.``*D
+MW@`#\`0``\"(``/`F0`#P*H``\"[``)@"``"81D``F(J``)C.P`"9$@``F59
+M``)F:@`"9WL``&H_``/_```#_P```_X```/4'@`#:&L``_L```,,S@`#_@``
+M`]1>``-H:P`#^P```PS.``(1/P``0@T``&(.``/_```"H(X``A%D``-`2@`"
+MI,X``_`$``/`B``#P)D``\"J``/`NP`"I-X``_`"``/!B@`#P9L``KH/``)*
+MJ``#BZ8``FJK``*[\``"2[@``Z>V``)KMP`#]`0``_`#``/H8``#Z*```^BP
+M``*T\``"8$H``\$0``/!(``#P3```VJ$``*@_@`#\`,``K3P``/T!``#\`$`
+M`K0/``)@2P`#P1```\$@``/!,``#:H```^P```/^```#U!X``VAK``/[```#
+M#,X``KD#``*@^0`#\$0``^A```/H4``#Z&```^AP``/^```#U%X``VAK``/[
+M```##,X``A&%``*P\``"L?\``J#Y``/P0@`#Z````^@0``/!(0`#P3$``VJ$
+M``-J@``#[````K!_``*Q_P`"LO\``VA@``-H:P``">4``K#```/<```#V!``
+M`K3_``/!9``#P70``KP'``/^```"M?\``]1>``-H:P`#^P```PS.``/^```"
+MM>\``]1>``-H:P`#^P```PS.``(1HP`"M?\``VJ%``*P\``#P1```\$@``/!
+M,``#:H```TIB``(QT``#Z/```C'<``-J8@``">4``K#```/<```#V!```K3_
+M``/!5``#P60``\%T``*\!P`#_@```]1>``-H:P`#^P```PS.``(1Q0`"L/\`
+M`K&_``/!(``#:&```^P```-*9``"M(```D`$``-J9``#[````K`$``*@\``#
+M\`,``C#]``/T!``#\`$``BUH``/H```#P````\$0``*R_0`#:&````H[```R
+M#```&@L``K`*``*@W@`#\$$``K`,``.!%@`"8`$``K$6``*D/@`#\`$``K,$
+M``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"L@0``F(F``-J8``#C^$`
+M`BY[``-H:P`#_P```_X```/L```#2F```_\```/H,``"8`X``VI@``-*9``"
+MM/(``D`$``-J9``#[````&H_``-`!``#_P```K@$``)%X``"H%X``_!$``*@
+MW@`#\$(``T`D``/_````8?@``_\```/_```#W,```X_J``*@W@`#\`$``^CP
+M``/8\``#C.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<`
+M`D`(``/P0P`"+PL``_0```/P00`"+QL``D1N``/P"0`#Z,```ZMB``.E8``"
+M15X``_!#``(O"P`#]````_!!``(O&P`#[````TC```-(Q0`#Z!```^A0``*@
+MW@`#\`@``VC````",0``"C```_\```/_```#:,```_0```/P1@`#:,4``"(O
+M```J+@`#_P```_\```-HQ0`#[````&H_``/_```#_P```%'Y``*@W@`#\`,`
+M`%GQ``/T```#\$$``%GP``/_```#W*```]BP``-`!@`#_P```_\```)`Z``#
+M\`,``J#>``/P00`#0"8``_\```/_```#24$``J`.``/P0P`"H-X``_!!``/!
+M10`"14X``_!#``.,Y``#]````_!!``.,XP`#B9@``ZJ<``*@K@`#\`,``B\+
+M``/T```#\$$``B\;``-`!@`#_P```_\```-)00`"0(X``J`.``/P0P`"H-X`
+M`_!!``/!10`#Z,```ZM"``)%3@`#\`<``Z5```)%7@`#\$,``B\+``/T```#
+M\$$``B\;``/L```"H-X``_`#``-((0`#]````_!!``-()0`#_P```KL!``.B
+M9@`#@68``Z$6``.'=@`"8"<``P`+``.G!@`#@@8``F8A``*@W@`#\`0``V@A
+M``-JB0`#]````_!"``-H)0`#:HT``^P```./[0`"+GL``^@P``."X``#Z!``
+M`^@```-H,``#C^T``BY[``/H\``#27```^AP``*V`0`#P5$``\%```-H,0`"
+MN/P``\%3``/!0@`"15@``TET``(R^``#:#$``\%1``/!0``",O@``V@Q``/!
+M4P`#P4(``TF8``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TF<
+M``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TCH``(R^``#:#$`
+M`\%1``/!0``"MQ```C+X``-H,0`#P5,``\%"``(R^``#:#$``^P```-)/0`"
+ML`@``D`$``/P!0`#2J0``_\```/_```"L@,``VJD``*P!``"000``J`0``/P
+M1@`#2,```TC%``*Q`P`"M0,``VC```-HQ0`#[````_\```/_```#_P```^P`
+M``-A2``#84$``V%&``-B?P`#P0X``^@0``/H(``#Z#```VCH``/H```#_P``
+M`VCH``-!2``#_P```^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#
+MH`,``]P```/8$``"O`,``K#W``*@_@`#\$$``K!_``/!$``#P2```\$P``*T
+M_P`#P50``\%D``/!=``#_@```]0>``-H:P`#H`$``Z$1``.B(0`#HS$``_L`
+M``/^```#U%X``VAK``/[```##,X``A,A``*P_P`"O`@``\$0``/!(``#P3``
+M`VJ```*D_@`!TSL``J#\``/P`@`#:H0``^P```*P]P`#H0$``Z(1``.C(0`#
+M:H0``^P```-)/0`#_P```KB```)D2``#:3T``K`!``*Q`@`"LC\``D(O``*S
+M```#:F@``K````*Q```"L@```K,"``-J=``"L0$``K((``*S```#:G@``K`!
+M``*R```#:GP``!'O``*PP``"0`\``Z`"``)@#@`"L0```Z(B``*S`0`#:F0`
+M`K#_``*QOP`#P2```VA@``/_```#_P```C"5``*X?P`"1$@``VD]``/L```#
+MZ````^@0``*R`P`"LP```V@P``/L```#Z````((_``(B^@``\C\``B+Z``(S
+MJ``"+FX``TF8``*T]P`"010``VF8``/!+@`#Z#```V@P```"%P`#@>```^A`
+M``*@`0`#\`$``\%.``(TL@`#2`@``KC^``)!&``#:`@``^@```""/P`")%H`
+M`/(_``(D6@```A<``X'@``/_```"I!```_`"``/!3@`"-+(``C0"``-`+``"
+MN$```KF```*[_P`#2J4``D@8``/P`0`"N\\``DD9``/P`@`"NC\``DNZ``)%
+M6P`#:J4``_0```'";``#2=$``KA```)$>``#A$```TB<``.%X@`"8`0``F`%
+M``-HG``#:*```VBT``-HN``#23@``X7A``/`50`"0B4``VDX``-J7``#H.$`
+M`X'A``/H,``#@N@``X7E``(P*@`#0Z8``X#H``/_```"2(4``FB```/!F``#
+MP:@``\&X``-CI@`#8^8``^@```/HT``",#L``\'>``(P.P`",&$``X3B``/!
+MR0`#Z````X'A``.#Y``"PC$``P(N``+#/@`"1$D``_`!``.#Y0`#Z%```C`J
+M``.`Z@`","H``XCE``.$X``"1$P``_`"``.(Y``"R(X``\&8``/!J``#P;@`
+M`V,J``-C:@`",&$``X'B``.@X0`#HY8``X+D``+"+@`#Z%```C`J``.@XP`"
+M,"H``C!A``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"
+M`@`#@B0``)'C``/L```",&$``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP
+M``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(`
+M`V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"
+M8`4``F$4``/H,``#P2X``V@P``-#I```(>,``K4/``/_```"0`4``F`$``/!
+M$``#P2```\$P``-CI``#8^0``X&$``.@&``#@@8``F`"``/HT``",$\``\'>
+M``(P3P`#2)```Z2Z``.EYP`"014``F$4``-HD``#:*@``VB4``-HK``#H*8`
+M`\$0``/!(``#P3```V0D``-D9``#BK8``T@A``*X`P`"9F@``KD/``*[_@`"
+M1FD``F9J``)'>P`#:"$``VJ)``-H)0`#:HT``T@(``-((0`"81X``V@(``-(
+MR``"N$```KD_``)@"``#:,@``D`)``-HR``"95X``V@A``-JB0`#:"4``VJ-
+M``)%6P`#:"$``VJ)``-H)0`#:HT``^P```-`+``"N$```KF```/HL``#2J4`
+M`D@8``/P`0`"NS```DD9``/P`@`"NL```FNZ``)E6P`#:J4``TB<``-(H0`"
+MO'L``D`,``)$3``#:)P``VBA``-(M``#2+D``D`,``)$3``#:+0``VBY``-(
+MD``#A.(``Z7G``)!%0`"810``VB0``-HJ``#:)0``VBL``-).``#A>$``F(E
+M``-I.``#:EP``Z#A``.!X0`#@^@``X+H``.%Y0`","H``^@```.!X0`#@^0`
+M`L(Q``/H,``#Z%```C`J``.`Z@`","H``T@(``-((0`#J.T``D$8``-H"``#
+MJ.L``D9H``/`/@`"15,``V@A``-JB0`#:"4``VJ-``/H0``"-+(``^P```-)
+M=``#P6X``^AP``.(2``#P%X``X59``)")0`"8B@``VET``/!0@`#P5,``V@Q
+M``/L```#2`@``KC^``)!&``#:`@``TA4``*\8``"8BP``VA4``-)=@`"O!``
+M`F2L``/!6P`#P6X``^AP``-H,0`",O@``TA4``*\GP`"0BP``VA4``/!2@`#
+M:#$``C14``/L````\=X``/'=``/!_0`#P<X``T@$``/`?@`"0S<``V@$``-(
+M"``#_P```X3H``)@!``#:`@``TF8``.%X@`#P%4``D$5``.$Y0`"8`0``^@P
+M``/!+@`#:#```^C0``(NRP`#^`$``T`-``/_```"L`$``D`&``(5"P`"H.T`
+M`_`%``*[/@`"2[8``ZNP``/T!``#\`T``K````*R`@`#HVH``PNN``*@,``#
+M\`<``PN^``*@/@`#\`0``PN^``*@,@`#\`$``PN^``/T!``#\`$``^BP``-(
+M&0`"LN```D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BY_
+M``(NYP`"M`\``TI```/X`0`"I$```_`&``*D00`#\`0``J1"``/P`@`"H$,`
+M`A4W``+*K@`"L"```J"@``/P00`#Z*```J"K``(57P`#2!D``K+@``)&8@`"
+M9FH``V@9``-)Y0`#_P```D9B``)F:@`#:>4``_0$``(5&```T=\``J#>``(5
+M/@``T>```LW>``/T!``"%.\``$'@``/_```#_P```J"H``(590`"H:@``_!(
+M``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%64``T@9``*RX``"1F(`
+M`F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P``)G<P`#
+M:"4``VJ-``/T!``"%64``T`1``/HP```\?0``KB```)G>``#8!$``\'?``-)
+MF``#A>(``\!5``)!%0`#:9@``^@P``/!+@`#:#```T@(``/_```#A,@``F`$
+M``-H"``#^`,``^P```/_```#_P```&H_``/H````@AD``('<``*P`0`"L1$`
+M`K(0``-J1``"L1```^@@``-J1``#0"0``J#>``/P`P`"NU,``_0```/P00`"
+MNUL``-G\``)`#@`#\$L``T`0``*\!``#W,```X_J``*@W@`#\`$``^CP``/8
+M\``"O`D``\&Q``(O"P`#0"0``_\```*\`@`"0`P``_!+``-`$``"O`0``]S`
+M``*_P``"H-X``_`!``*_@``#V/```XSD``/!L0`"+PL``TF8``.(Y0`"M?T`
+M`\$^``*@W@`#\`$``X,P``/!+@`"8`@``D$5``-H,``#2`@``K1```"!]0`"
+M8`0``V@(``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$``-`
+M+@`"L`$``^@0``/H(``#Z#```VI@``(M:``"L`$``K$"``*R!@`#Z#```VIH
+M```200`"L!,``K$"``.")@`#Z#```VIP``*P(0`"L0(``K($``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P```"L0```K,$``-J?``"
+MOQ@``C91``(V?@`"OP```C'5``-*<``#_P```_\```*RD``#:G```K\3``(V
+M40`"-GX``T`D``/_```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>
+M``/P`0`#Z/```]CP``*\"0`#BQ```B\;``-`)``#_P```KP"``)`#``#\$L`
+M`T`0``*\!``#W,```K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(O&P`#
+M2G```_\```/_```"LH```VIP``*_&``"-E$``C9^``*_```",=4``TIP``/_
+M```#_P```K*0``-J<``"OQ,``C91``(V?@`#0"0``_\```/_```"0`X``_!+
+M``-`$``"O`0``]S```./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+PL`
+M`T`D``/_```"O`(``D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"
+MOX```]CP``.,Y``#P;D``B\+``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID```A]0`#_P```T@(``/_```#P00``V@(``/L```#Z````\``
+M``*QOP`#P2```VA@``*P`0`#Z!```^@@``/H,``#:F```TID``*T@``"0`0`
+M`VID```*.P``$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``/!'P`#:F```TID``*T@```$?P``D`$``*T
+M`P`"8`0``K,0``-J9``",)4``K\(``)/\``#\`$``/(9``/L`````AD``_\`
+M``/_```"I0X``_`!``/L```#Z````((9``-`$@`#_P```_\```)$C@`"H$X`
+M`_`!``#Q]``"OT```J#>``/P`P`":J\``_0```/P00`":[\``V`2``(PQ```
+M>=P``_\```-`*``"H/X``_!!``/L```"H-X``_`%``+`#@`#\$$``L$>``/T
+M```#\$,``L(N``/P00`"PSX``V`H``#QW``#[`````(4```*0```:C\``_\`
+M``)``0`"H`X``_`!``/L```#2)P``TBA``-*2@`"H-X``_!#``-(M``#2+D`
+M`TI.``*\$``"8BX``F9N``)HC``":9P``J#>``/P!0`#:)P``VBA``-J2@`#
+M]````_!#``-HM``#:+D``VI.``/HP```X=L``K`0``*Q```"LA```K,```-B
+M=``"L(```]@!``*P```#W`$``K`2``*Q`@`"LA(``K,"``-B=``"L!```K$2
+M``*R$``"LQ(``V)P``-B1``"L0(``K,"``-B3``#8D@``T`L``/_```#_P``
+M`^@@``/H,``#8"P``^@```/H$```8=L``V`8``-@'``#P8P``\&<``/!K``#
+MP;P``C=S``(U=P``8=L``_\```*P```#W````K!```./P@`"P`\``]@```-`
+M&``"H-X``_!!``-`'``#0"T``_\```/4'@`#U%\``K\```/<\``"O\```XC"
+M``+/^``#V/```\0```/$$0`#Q"(``\0S``*U#P`"1&4``Z5F``*@W@`#\$,`
+M`K4/``)$=0`#I78``Z9"``.$2@`#IU(``X5:``/$1``#Q&8``L`!``+`!``"
+MPB,``L(F``/$%0`#Q#<``]0>``-"=0`#0G(``K\0``*A!``#\$8``J4)``/P
+M!``#P8P``\&0``/!K``#P;```J,)``/P0@`#P:P``\&P``-B<@`#0D8``J$F
+M``/P1@`"I2D``_`$``/!C``#P9(``\&L``/!L@`"HRD``_!"``/!K``#P;(`
+M`V)&``-"3@`"H14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#
+M\$(``\&L``/!L0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!
+MK``#P;,``J,Y``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.';
+M``*@P0`!UN(``T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD`
+M`_\```+)`@`#J9```LM&``.KL``"-W,``^P```-(G``#2*$``J#>``/P0@`#
+M2+0``TBY``/!&``#P5H``XF6``.+M@`"81D``F5;``*@W@`#\`0``VB<``-H
+5H0`#]````_!"``-HM``#:+D``^P`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/BARTS_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_me.bin.uu
new file mode 100644
index 0000000..9bf8480
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 BARTS_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*P`X``<P``$7,``!*S$$B7,Q!
+MH?S43:']?$"``*````#,@`!-@````,Q!(EW,``!%S```2@A,``%\00``?$%`
+M`!U8__\97`/P%6``%<V!H0+-P2)6S@$B7)3```4A)``@SD&A_(```'L(S``!
+MS0&A_,P!H0)\0(``H````,R``$U\0(``?$#``,`J``)\00``?2D`!QR4``$<
+MF``&')P#`!7<``A\0@``?$)``)5```_`+@`$!?`B6'\O``?,,0``R"@`!,S!
+M(6G-`2%JSH$A:RFT``+,`2%LET``#BFT``"```"[R#0`#BFT``*70``)*;0`
+M`,`N``0%\")8?R\`!\PQ``#(*``$@```N\@T``Z70``$?@*``(```+O(-``.
+M*;0`!)=`_TL`````S@$A;<Y!(6[(*``#R#0`#IM```3(/``.A``#0\P``$TI
+M]```ET``!P0PHK:$``#=SH&BM\^!HL2`````S\&BT2GT``&70``'!#"BNH0`
+M`-W.@:*[SX&BQ8````#/P:+2*?0``I=```<$,**^A```W<Z!HK_/@:+&@```
+M`,_!HM,$,*+"A```W<Z!HL//@:+'@````,_!HM3`+@`$?R\`!\PQ``#(+``$
+MP#``!G[S0"/`,``@?VN`((@```!_L\`DS```0H````#,0``??$#``'Q!```9
+M%``]F4``$P04`"Z$``2=!!@`*80``F3('``3!!0`*H0`!)T$&``MS4&BI,@<
+M`!.5P```R!P`$\S!(0#-`2$!S,$A`LT!(0.```2:S8&BI!T8$`"5@``%R!P`
+M$RGD`$"60/__R!P`$\S!(77-`2%VR"``%)8```#((``4%B@``9J```3,``!/
+M@``$FLP``'^```$'S,$A=7Q`P`!\00``S```1<P``$I`U``#S4$B7,T!H?S`
+M'@`!?$(```C,``$&)``!!B@``LX=H?W.7:']F,#_^LZ=H?U\0(``H````,R`
+M`$U\0,``'-```13,``%\04``E0``!GQ!@`#-02%MS8$A;H```3/('``#P"(`
+M!'X6``?,(0``R!P`!'Q"0`"8P``$?$*``(````#-Y0``SD$A:<Z!(6K-P2%K
+M@````,P!(6Q\0,``?$$``'Q!0`!\08``?$'``!BD'^@J:``\EH``"GP"``!\
+M0@``.C```\P``%B;```#0B``!00@`$"```%/?`)``'X"0`":0```"F0``1SL
+M`!":P``*S```3<`J``3(+``@?I*`!\P``$',*0``SL``'H```5_(,``$S0$A
+M;<U!(6[(,``#?Q\`!AST``<3>``!ET``*@>X`62?@````````(```71_&X`.
+M@``!>'\;@`^```%\?QN`#(```8!_&X`-@``!A'\;@!&```&(?QN`$(```8T4
+MI``(FX``&12D``B```&='F0`_YN``!44I``(@``!G1YD`/^;@``1%*0`"(``
+M`9T>9`#_FX``#12D``B```&='F0`_YN```D4I``(@``!G1YD`/^;@``%%*0`
+M"(```9T>9`#_%*0`"!YD`/\J:``\FH#^<13L``A\0T``?$.``'Q#P`"6P``'
+MS```3<]!(6G/@2%JS\$A:X````#,`2%L@````,_U``#,``!9A``$G2IH`#R:
+M@``$R"@`%X````#40`!_EH#_JWX"0`"$``*6P`X``LP``$&```&KS,$P2I0`
+M``#(/``<?$#``'Q!``#`'@`!%20`$L`B``*60``%P"8`!,`G__M])0`&P"8`
+M`'W2@`9^$L`&?24`!WQ!0`!\08``S,$A:9J```S-`2%JS4$A:Y;`_D#-@2%L
+MA``$G<P``'_(,``:EP```,@P`!J````!?$"``(0`!)W,``!_R!0`%<@8`!;-
+M02%KEL#^,LV!(6R```'"S```?WQ`P`!\0(``%)0`$!%4``4<B/__$(@`!7Q`
+MP``4T``0',S__\`:``0%F!NDS!D``,@8``0=F`__?1D`$)D`_A]]C0`0F0#^
+M'<P``%C,``!9A``$G<R!(73(#``7E,#__\P``%F````!?$"``,P``^7(+``@
+MP`X@0`00,``@S")K!!0P`<P``$'0$0``S-4``,[``![(#``)F,```,@,``E\
+M00``?$%``,P``^?,``/HS``#Z<Q``$/,0`!$U$``?X````!\@,``?$#``!C0
+M`>@1*``!E0``$`:H`@F>@````````(```B'`$@@`@``"+\@4`!&```(VR!0`
+M$H```CW,P:*D@``"1ASH`#^```)N?,&`"QS0`#\I*``&*2P`%GZN@`?('``3
+MFH``/004`"Z`````S,&BI,`2"`!\04``?0S`!\`2``@56``#%5P`#'Q"``!]
+MT<`&$B``%'X>0`=^3H`'SH&BI(````#-@:'^R!0`$000(1B50```R!0`$=11
+M``"`````S,&BI,@4`!($$"$&E4```,@4`!+440``@````,S!HJ3,P:*D!!``
+M`<T``!F$``2=S```?\@0`!N9````R!``&X````%\0(``*J``!"JD`!1^)@`'
+M!!0`+I8```@$&``IA``"9,@<`!,$%``JA``$G00,`"W-0:*D!!`A`,@<`!.5
+MP```R!P`$]11``"```2:S,&BI(0`!)T$&``IA``"9,@<`!,$%``JA``$G008
+M`"V$``)DR!P`$X````%\0(``E<```,@<`!/-0:*DS`$A`,P!(0'-@2$"S8$A
+M`\V!HJ2(````S```31V8``%\00``?$%``)F```E\0@``R#P`,A&8`!#('``+
+M._P``9?`___(/``R@``"@,@\`#,1F``0R!P`"CO\``&7P/__R#P`,Q5H`!U]
+M64`'FH``!!'D``I^)@`'S<``9LT!(5C-02%9S@$A6LS!HJ2:@`(0!1``!`0L
+M``$2\``=?7%`!Q+@`!`B(``,S0$A6,U!(5G.`2%:@``$FLS!HJ0$/``%S\&B
+MI,`V``*(````ST$@$'Q`P``4T``=F0``"!34`!R50/UAP"8`!")D(53,)0``
+M@````,@H``2```2:S4``880`!)T<=``!''@``IM```/(#``IA``#0L@4`"N;
+M@``#!!``$(0``U+,P:)0S0&@4(0``P\$&`0`A``$G<P``&/(/``MA``#'<@0
+M`"G('``O'=P``<@D`">5P``)R#0`,<@X`##(/``M4W0`('^W@"='N`50S```
+M8L_Z``":0```R"0`)\@H`",ZJ``"FH#__\@H`"/`,``!R"@`))J```#(*``D
+MSP``6U#8``@4W``8P#X0`"'<@`!]_<`'S8$A@,W!(8'`'@`@42``"!4D`!A^
+M?D`'$S``'GYR0`=]74`'S@$A@LY!(8/-02&$?$"``*````#,@`!-A``$G1QT
+M``$<>``"FT```\@,`"J$``-"R!0`+)N```,$$``0A``#4LS!HF#-`:!@A``#
+M#P08"8"$``2=S```9,@\`"Z$``,=R!``*L@<`"\=W``!R"0`*)7```G(-``Q
+MR#@`,,@\`"Y3=``@?[>`)T>X!53,``!BS_H``)I```#()``HR"@`(SJH``*:
+M@/__R"@`(\@H`"6:@```R"@`)8```M#`,``"!9C``!#<``@4X``8S=D``,@<
+M`"+()``B'=P/_\W9``%^8D`'SED``M@840/8&%$$B````-@840<;^`#PP#8(
+M`)>```/`,`"`B````,`J``3/02%\SP$A?<T!(7XBJ"%_!"0`")I````*9``!
+MS"D``,@@``06.``?FX#_^P0D``B(`````````,@D`"1\00``FD```,@D`"2`
+M```!?$"``,@D`"5\00``FD```,@D`"6````!?$"``(0``T)\0,``?$"``*``
+M``#,@`!-R#P`#I?```/3``/FB`````0\``7/P:*DS`&A](0`!)W,``!'B```
+M`,P``'^$``-2?$#``'Q`@`"@````S(``300\`"+/P:*DA``$G<P``$B(````
+MS```?X0``UU\0,``?$"``*````#,@`!-!#P`(\_!HJ3,`:'SA``$G<P``$F(
+M````S```?X````!\0,``@````'Q`P`#`$@`!?%%`!X````#450``S$``9<@X
+M`"W(/``NP#7@`,`R``1_MX`&?_?`!B.X$``C_!``SX$A5,_!(57,,2%5R"P`
+M!,@<`"7()``D?>7`!YG`__[('``E@````7Q`@`!\0,``?$$``!DH`#"6@``(
+MR"@`)\@D`"B:0```R"0`)YI```#()``HS``#X'Q!0`!\08``%1P`'\S``,?-
+M``#(E<```\`<@`#-P2`0X8,```5<(`#,``!-@````-P?00!\0,``?$$``'Q!
+M0`!\08``S,``R<T``,KA@P``!5R@`(````#<'T$`?$#``'Q!``!\04``?$&`
+M`,S``,O-``#,X8,```5<Z4"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#-
+MS0``SN&#```%7.B`@````-P?00!\0,``?$$``'Q!0`!\08``S,``S\T``-#A
+M@P``!5S``(````#<'T$`?$#``'Q!``!\04``?$&``,S``-'-``#2X8,```5<
+M\`"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#3S0``U.&#```%7//\@```
+M`-P?00#40R``?$"``*````#,@`!-U$.@`'Q`@`"@````S(``3=1#Z4!\0(``
+MH````,R``$W40^B`?$"``*````#,@`!-U$/``'Q`@`"@````S(``3=1#\`!\
+M0(``H````,R``$W40_/\?$"``*````#,@`!-!!R@`,Q#H`!\0,``V!_!`'Q`
+M@`"@````S(``300<P`#,0\``?$#``-@?P0!\0(``H````,R``$U\0,``?$$`
+M`)3```-\04``?$&``,P#\_S,0_/\S$/S_'Q`@`"@````S(``3<`>`!#(#``I
+M4-``"!!4``*```05?16`(,`>`"#(#``J4-``"`A4!``15``"?5&`(,W``&+4
+M6@``?$"``*````#,@`!-?$#``!S0``,1*``!E0``"@:H!!^>@```?$&``(``
+M!"U\0<``@``$,WQ!P`"```0Y?$'``'Q!@`!\0<``%-0`$`54H`"`````S94`
+M`,`B``0%F*``?:&`!\P9``"```0IR!@`!,`B``3-@276(B`EU\PA``"```0I
+MR!@`!,V!(6W-P2%N@``$*<@8``-\0,``@````,Q,`^`<C/__U$T``'Q`@`"@
+M````S(``3<@4`",Q6``$E8#__\@4`"/,``!;S$$A@"!,@`#,P2&!%-``'\Q!
+M(8+,02&#E0#[L,Q!(83(%``CF4#__\@4`".````!?$"``,`6``0A5"%`S%4`
+M`,@8``2`````S``#X'Q`P``8T``XP!8`@)4```/`*@`$?-3`!\S!(7S,02%]
+MS$$A?GQ!@``4_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`F<````G<``',
+M(0``R"0`!!9L`!]!G``%FL#_^LR``$V;P/N*`````(````#,``/@?$#``'Q!
+M```5&``?410`()F```L9'``QS0``8GU-0"?45@``E<#[?<@@`"::````R"``
+M)H````%\0(``X#H``,`F``3,P2%I?24`!\T!(6H+N``"S$$A:YN`__[,02%L
+MF<#],,P``'^````!?$"``,`.`0#,``!!S,$P2L@\`'_,``!_@````,P``'_,
+M``!_B````,P``'\`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01``!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=0`P`'<`,@#H`#0`C``U`&(`.0#J`#H!$@`[`24`/`$]
+M`#T!K0`^`=(`/P#G`$$$10!"!%<`0P1=`$0![0!%`3T`1@($`$<"!`!(`@0`
+M2@*;`$L#9`!,`J<`30+E`$X#,0!/`S<`40-8`%(#/0!3`TT`5`-F`%<#:`!@
+M`X``80.8`&(#;`!C`Z(`9`.L`&4#M@!F`\``9P/*`&@#U`!I`]@`:@0)`&L#
+MW`!L`^``;0/D`&X#Z`!O`^P`<`/D`'$$#P!R`_X`<P/P`'0#]P!U!!H`?00]
+M`'H$>@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`
+M#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/
+.!)8`#P26``\$E@`/!)8`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/BARTS_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_pfp.bin.uu
new file mode 100644
index 0000000..a410bd7
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/BARTS_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 BARTS_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-?S$``*ID```4`````S$``*X```U_,0``LS$``+8``
+M`U_,0``N'(P``LR``$"8P``$S$``0(```U_,``!2@``#7\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$+-
+M0`!"T0``0GQ`P`#(&``#R!P``\@@``.5@/_"R"0``Y7`_\#(*``=FH``!,P`
+M`%78``/`S```0,@H`!;`+@`$R#``#1JH`"=^\L`'SL``0,P``$#-@`!`S<``
+M0,X``$"6@``#SD``0-"``%S,@`!`S```0,S``$!\0(``H`````0H``'($``L
+MR`P`*U$0`"!\T,`G?,4`(%44`"#-``!"S4``0M%``$)\0,``R!@``\@<``/(
+M(``#R"0``Y6`_YG(*``#E<#_E\@L`_U^+P`1EP```W[BP`%\`L`&SL.BGLP`
+M`&S-``!MS4``;<@P`!V;```$S```5=@``\#,``!`R"P`%L`R``7(-``-&NP`
+M)W\W``?/``!`T$``0,V``$#-P`!`S@``0,Y``$"6P``#SH``0-"``%S,@`!`
+MS```0,S``$!\0(``H`````0H``'(&``5'9@``7Q"0`"5@`+.?$*``,@<`"#`
+M-\``?$#``'Q!``!\M(`&P#8``QJX`>B7@``'T$`#X(0``V+,``!_R#@#X)N`
+M``#(.`/@F<```,@<`"!\M(`'$-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``
+M0,Z``$#,P`!`X#H``)>`_U3-``!`?$#``(```*)\00``'(P``IC```G($``<
+MF0``!,@<``:$``-ES```4L@8`!6```".'9@``L@0`!Z9`/_\R!P`"(0``V7,
+M``!4R!@`%8```(X=F``"'(P``L@0`!V8P``.R!0`29D```3('``'A``#9<P`
+M`%/(&``5E,```QB4`>@%5``&(!```7T5``.```".?9&`!IE`__C('``'S<``
+M0,P``$"```#+S```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/T
+MS0`#]LT``_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``8```.[8
+M``1`V``#0,P``$#,@`!`U$``0'Q`@`"@````!"@``=@``\"```#[S```0(``
+M`/K8``1`V``#0,P``$#(#``IR!``*LR``$#,0`!`41``('S0P"<04``"?0T`
+M(%44`"#-``!#S4``0]!``$/,``!`?$"``*`````$*``!V``#P,P``$#,@`!`
+MU$``0'Q`@`"@````!"@``1R,``+($``=F,``$<@4`$F9```$R!P`!X0``V7,
+M``!3R`P`+\R``$#,0`!`S$``0,Q``$!\Q,``S,``0-1``$!\0(``H`````0H
+M``&90/_UR!P`!\W``$#,``!`@``!&LP``&Y\0,``R!``1YD```O(%`!$F4``
+M!,@8``G-@`!`S```0(```43,@`!`?$#``,@0`$>5`/_WR!0`19E```3(&``*
+MS8``0,P``$"```%$V``(0'Q`P`#($`!'F0#__`````#,@`!`S,``0-1``$!\
+M0(``H`````0H``'($`!&V``'0,T``$"$``%;S0``0,@,`$.4P``*R!0`2(``
+M`50$$``#R!``1M@`!\#-``!`A``!6\T``$#(%`!(G4```,P``&K(*``6'J@`
+M`9J```/`*0`!B````,`L`5;.@`!<V``(P,[``$"(````S```0!R,``+($``>
+ME,``",@4`!R9```*R!P`"(0``V7,``!4@``!=<R``$"90``$R!P`!H0``V7,
+M``!2S(``0(````#40`!`S$``)\Q``"B```-?S```:\`R``/`-___@``!@'RP
+M@`=\0T``R"``*,@<`"?(&``FST.BGGQ!0`!2(``@?>'`)WU8P`-\W,`@5-``
+M((```97,@`!`?$&``,R``$"```&2S8``0,`9___,@`!`S8.BGGQ`P`!\00``
+M?$%``,S#H?K-`Z'YS4.BG<S``$#-``!`S4``0,Q``$!\0(``H`````0H``%\
+M0,``'-```<S#HI^5```#T$``)M"``";,@`!`@````,S``$!\0,``S(``0,S#
+MHJ*`````S,``0'Q`P``4U``?S(``0)5```-\00``S,``6148`!_,P`!`E8``
+M`\T``$#-``!:@``#7\P``'_((``??$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)
+MS2``0<U@`$'-H`!!%1``"!%4`!A]4\`'S\``+P8@``'.``!8@``#7\P``'_(
+M(``?R@P`%Y3```5\00``V"`"QH```;_.(`!&S```2(```=4`````R"``'WQ!
+M@``*(``!RA0`&LH8`!=]68`'E8``!<X``%C,H`!&@````,U@`$;,H`!$@```
+M`,U@`$2```-?S$``:L@,`_J8P``+T$`#^L@8`$+('`!#R!``'<@4`!P1$``!
+MF8#_6WT5``>9P/]C`````-```_J`````?$#``,R``$"`````U$``0'Q`P`!\
+M00``?$.``'Q#P``$'``"SX``0L_``$+-P`!"!!P`(,S``$+-``!"S<``0@0<
+M``<$(``!?`)``,@4``/(&``#49@`('U90"?(*``#R"P``\@P``/(-``#4NP`
+M('ZN@"=3=``@?S<`)W\K0"%^=D`@5J@`/U<P`#]^LH`&?BH`!IG`__()W``!
+MEH#_X5/T`"!_>T`G?65`(%58`"#,``!;S78``,VV``#((`!!F@```,@@`$&`
+M```!?$"``'Q`P`!\00``S,`#_LT``__,P`!"S0``0A44`!\9&`#P)UP``7UV
+M``:9@``%?5Y`!LP``$*```-?S```3168``$5+``(F8``,1[L``&6```$%3``
+M#(```U_,``!"!!0`(,U``$(?,``!("@``00X`"`$/``'R!0``\@8``/('``#
+MR"```WU=0`U]H<`-?5U`!Q80`!\5G``??1T`!GT70`9^DH`&FT``$@NX``2;
+MP/_R"_P``<@,`_Z:@``)R!`#_YL``0;,``!-!!0`(,S``$+-``!"@``"0\U`
+M`$*6P`#_S```38```U_,``!.FL```\P``$W,``!.EX#]F>.#``"`````W`,!
+M_Y9```3,``!.@``#7\P``$+2``!"R`@``\@,``/($``#R!0``\@8``/('``#
+MR"0``\@H``,5_``?%K``'W_SP`84\``??_/`!A5P`!]_\\`&?8B``9?```U]
+MS,`!?E$``7Z50`%\D(`,?-3`#)K```-\CT`&)+0``9M``-;,``!-@``#7\P`
+M`$[(#`/^R!`#_\S``$*```)OS0``0GQ`P`!\00``?$+``'Q#``#`.P`??$-`
+M`'^W@`;`/A``EX#]9GT]``=_/P`'&10`.\P``%N50``3R!0`0#%8``*5@/__
+MR!0`0,P``&,A'(``S,$AA<W!(885%``?SL$AA\\!(8B50/U5ST$AB<@4`$"9
+M0/__R!0`0(````%\0(``S(``0,S``$#-``!`SL``0,\``$"`````ST``0-"`
+M`^#,@`!`A``#8LQ``$#(#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``"
+MS!30`!^9`/TZT$`#X(0``V+,``!_@``"OL@,`^#,@`!`S,``0(@```#40`!`
+MS(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`-___T``#^]```_S0
+M``/Z@````,]``_U\0,``%-P`'9G```?,@`!`&-P`/)G``'S,P`!`@``#7\P`
+M`&H8V``\S8``9LP``&J```-?S,``0'Q`P`!04``@A``#8LP``%U\T,`GR"``
+M'\C6``"90``(?$.``..#``#/H`!/A``#8LP``%Z`````U$``?X```U_,``!>
+MA``#8LP``%W((``??$#``,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\
+M\X`&XX,``,^@`$^$``-BS```7H````#40`!_@``#7\P``%Z$``-B?$#``!3<
+M``B5P``9'-P`$'Q!``"9P``$4%0`((```QW)'0``?14`)\D>``!\0@``?$)`
+M`'Q!@`!]Y<`&?>*`$9J`_-Y!K``%FL````KL``$<W``0F<``!`````"```,@
+MR1T``(```R#)'@``S(``0,S``$"`````U$``0-@``T#,``!`S(``0-1``$!\
+M0(``H`````0H``'8``/`S```0,R``$#40`!`?$"``*`````$*``!?$#``!S0
+M``8I$``&F0``!L@4`!R90``$S```4H0``V7('``&S(``0,S``$"`````U$``
+M0'Q`P`!\00``%1@`'\T``%N9@``$410`((````#430``?4U`)QD<`#'45@``
+ME<#\J<@@`$&:````R"``08````%\0(``@````-1``'_,``!_@````,P``'_,
+M``!_B````,P``'_-P`!`B````,P``$``````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,Q``0#.``%`;L`!@#M``<`^0`(`0L`"0#T``H`ZP`+`/<`#`$K
+M``T!-0`.`4D`#P%3`!`#70`1``H`$@`8`!,`(``6`"(`)``Q`"4`60`F`7<`
+M%P'7`!@!Y0`:`><`(@+L`","_0`G`8P`'P'Y`"`"*0`H`:X`*0%[`"H!H``K
+M`9``+P&I`#(!S0`T`S\`-0%_`#D!]@`\`Q$`/P&[`$$"D@!"`KD`0P+#`$0"
+MT`!*`MX`50,S`%8#.@!@`(P`80"Q`&(`V0!C`,,`9`##`&4`PP!F`,,`9P##
+M`&@`Y@!I`.\`:@$_`&L!#0!L`0T`;0$-`&X!#0!O`0T`<`$2`',`^P!T`/L`
+M=0%F`'L#3`````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/BTC_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/BTC_rlc.bin.uu
new file mode 100644
index 0000000..6b0c5ef
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/BTC_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 BTC_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X```"``
+M````R"@``Y:``,T`````S8``#BJ,`>68P`!\(`@``<R```.```#B`````,@P
+M`$`C,`!`SP``0(0``+0@.``!R#``0!\P`[_/``!`@``!$,P``%;("3TVR`T]
+M-Y3``%\`````R!$].,@5/3G('3TZR"$].\@E/34$J``PSH$]@LS!/8/-`3V$
+MS4$]A<W!/8;.`3V'$(@``P2,`!C(E@`\E4``3LC2`"A])0`!"50``03,`"B9
+M`/_[`````,B2`#@%$`!`?0K``,C6``3(W@`8R.(`',CF`"#(Z@`DS>X!0,XN
+M`43.;@%(SJX!3,C>``C(X@`,R.8`$,CJ`!3-R@%`S@H!1,Y*`4C.B@%,S0H!
+M4,P*`53-03U'@```@0`````JB`&\F(``MP````"5``",`````,@H``*6@``&
+M(`@``<V```[,@``"@```X@````#(*``!EH#_K``````@"``!S8``#LR```&`
+M``#B`````,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`````````S[$``,V`
+M``[+.0``%[@`!!^X``^7@/_]`````(@`````````(#@``<^```/($`""S```
+M@<@(`!J4@`"3`````,V```X`````A``!*A&X`!^$``$M(#@``LPQ``"$``#F
+M(#@``<V``(&$``#1(`P``(```,4`````R<P`@Y3``%P`````A```T2`,``&$
+M``#F(#@``)>``%8@#``-P#`@"<SQ``#`,"`*P#08&!-T``@C=!@8RPT``'ST
+MP`;("``:F(``2R`<``&4P/_[`````(```'A]P<`&'J@`_\Z```R(````````
+M`,^Q``#+.0``(`@`'YB````(B``!S!P`%LGP`!N7`/__`````(@`````````
+MA```9P`````@.``!P#`#F(0``*D3N``4S```5\`P`YC,,0``B````,L)``#,
+M'`"#A``!*A&X`!^```#%`````,P```[,```.R!``@B`H`<,@'```R!``@L@(
+M`(5_BX`'R`@`@92`_Z\`````@``!$`````#`,`.0RSD``,`+__Y_BX`&$,P`
+M$'^/@`?/L0``B````,LY``#(*``$EH#_Z@`````@"``!S8``#LR```2```#B
+M`````(0``*4`````@```Q0````#`,"`#S[$``(@```#+.0``A``!*A&X`!^$
+M``#F(#@``80``-$@#```P#`!P,LY```@.```E<#_TL^```-]P<`&A``!*B`X
+M``"```#%SX```X0``&<`````P#`@"(0``*D@./__P#`@",PQ``#+.0``P#`#
+MF(0``*D@.`$`P#`#F,PQ``#+"0``P#`AMH@```#,,0``R?@`@YN`_[,`````
+M@```Q0````#(.`!6FX``'B`<``#(.`!7FX``&R`<``$@'```R`@`@92`_T``
+M````R"@``):`_ST@"``!S8``#LR````<'```*H@!NY2`_S(`````@``!)0``
+M``#-G`"#A``!*B`X``"5`/^?`````,`P`<"(````S[$``(```&_`,`'!F<#^
+MY\@P`$`C,``"SP``0(0``/H@.``#R#``0!\P`_W/``!`@``!$,P``%8`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_mc.bin.uu
new file mode 100644
index 0000000..5a56101
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_mc.bin.uu
@@ -0,0 +1,539 @@
+begin 644 CAICOS_mc.bin
+M``/HX``"O@$```(4``/_```#_P```J`.``'`'0`#Z````^@0``/H(``#Z#``
+M`V`8``-@'``#8"```V`H``*P_P`"L?\``K+_``*S_P`#83@``TEL``/_```#
+MKPH``K0$``)O]```^CL``K0/``)/%```^A<``T`D``*T0``"M0\``TJF``)$
+M00`#\`(``DF5``-JI@`"+:@``TG4```R0P``(A@``#H5``*U$```FD,``D53
+M``/P"``"H'X``_!&``*@8P`#\$0``/(/``(TOP`#]````<`E``/H````@@\`
+M`T`D``*T0``"M?```TJF``)$00`#\`(``FF5``-JI@`#0````_\```/X`0`#
+MQ$```\11``+&10`"`````T`0``/_```#_P```^@@``/H,``#8!```_@#``(S
+M;``",J@``T@(``*TGP`"0`0``V@(``-((0`"L\$``D=S``-H(0`#:HD``T@E
+M``*SP0`"1W,``V@E``-JC0`#2,```TC&``"",0``BC```,(O``#*+@`#Z!``
+M`^B0``-HP``#:,8``TJD``/H0``#_P```D(D``-JI``#2````T@%``*[/P`"
+MO+\``K_O``"2,P``BC0``((X``"Z-@``JCH``D$;``*[^P`"0BL``D`,``-H
+M```"15\``V@%``-($``#2=T``KOQ``*\`@``BC<``*HY``)!&P`"81P``V@0
+M``)%6P`"95P``VG=``-`#0`#_P```_\```.A3```B@T``K,"``)#-``#HS``
+M`)H,``*S!``"0S0``Z,R``":"P`"L`@``()!``*P"0``@D(``T@I``-)<``"
+MOP<``D`/``.````#``X``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H
+M+0`#P00``\$5``-IZ``#:>P``^@```/HT``",$\``VCD``/!W@`",$\``VD$
+M``-`+``#_P```K0"``)$!```HA8``TG6``*U$``"1%L``Z1&``"B&``"H$X`
+M`_`#``(T:@`#]````<#%``/T```!TW(``T`.``#R0``#Z/```Z"V``-)U0``
+M^A$``K$/``)"%P`"I2```_`!``#Z0``"0QL``J4C``/P`0``\A$``T````-`
+M+@`"MA```K0,```J0``"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!
+M``/HP```XA```T`(``*T````>A$``J`D``/P00`"L@@``J#^``/P00`"L@0`
+M`K0_``)")```DB@``TJ4``/_```#8&P``T````/_```"M$```D0$``/P`P`#
+MZ````((_``(B^@`#0````_\```*T0``"1!0``_`"``#R/P`"(OH``T````/_
+M```"M$```D04``/P`0`"+FX``TJ4``/_```#8'```T````/_```"M`(``D0D
+M``/P`P`#Z````((_``(C,0`#0````_\```*T`@`"1#0``_`"``#R/P`"(S$`
+M`TJ4``/_```#830``C-L``-````#_P```_\```)$#@`#\`,``^@```""/P`"
+M)%H``C-L``-````#_P```_\```)$'@`#\`(``/(_``(D6@`"+JD``TJ4``/_
+M```#8'0``K````""*P`#0````_\```*T`@`"1$```_`#``/H````@C\``B89
+M``-*E``#_P```V!X``-````#_P```K0$``)$0``#\`,``^@```""/P`"*)P`
+M`TJ4``/_```#8'P``T````/_```"M!```D1```/P#``#Z````((_``(I;```
+M`@T``_\```/_```"I`X``_`$``#R#@`"*6P``^@```""#@`#2I0``_\```-@
+MK``#0````_\```*T(``"1$```_`#``/H````@C\``BN$``-*E``#_P```V"P
+M``/H````@C\``K#_``*Q_P`#P2```VA@``-H:``#0````_\```*T$``"1$``
+M`_!"``/T```"`8\``T`-``-`)@`"L4```K(0``*S"``"010``Z$:``)")``#
+MHB0``F(A``)#.``#HS```F(C``"2*P`"I!X``_`)``-)/0`"LH```\`B``)$
+M0@`"*6P``TD]``/_```"LH```F1"```"$``#_P```K0!``)$!``#\`0``^@`
+M``""/P`#P?X``BQ&```"$``#_P```K0"``)$!``#\`0``^@```""/P`#Z/``
+M`BQ&``-````#_P```_\```)$+@`#\`,``^@```""/P`"-7<``T````/_```"
+MM!```D0D``/P`P`#Z````((_``(VJ0`#^`,``TJ4``/_```#8+0``K````""
+M*P`#0````_\```*T`@`"1$$``_`"``#R/P`")AD``TJ4``/_```#8+@``T``
+M``/_```"M`0``D1!``/P`@``\C\``BB<``-*E``#_P```V"\``-````#_P``
+M`K00``)$00`#\`L``/(_``(I;````@T``_\```/_```"I`X``_`$``#R#@`"
+M*6P``^@```""#@`#2I0``_\```-@[``#0````_\```*T(``"1$$``_`"``#R
+M/P`"*X0``TJ4``/_```#8/```/(_``*P_P`"L?\``\$@``-H8``#:&@``T``
+M``/_```"M!```D1!``/P0@`#]````@(.``-`#0`#0"8``K%```*R$``"LP@`
+M`D$4``.A&@`"0B0``Z(D``)B(0`"0S@``Z,P``)B(P``DBL``J0>``/P"0`#
+M23T``K*```/`(@`"1$(``BEL``-)/0`#_P```K*```)D0@```A```_\```*T
+M!``"1`0``_`#``#R/P`#P?X``BQ&```"$``#_P```K0(``)$!``#\`,``/(_
+M``/H\``"+$8``T````/_```#_P```D0^``/P`@``\C\``C5W``-````#_P``
+M`K00``)$-``#\`(``/(_``(VJ0`#2I0``_\```-@]``#^`,```(8``/_```#
+M_P```J`.``/P0@`#]````@)L``-`+``#_P```K0@``)`0``"H`0``_!(``/H
+M````@C\``C((``(R30``\C\``C((``(R30`",N0``T````/_```"M`@``D0$
+M``/P#``#2`@``_\```*T0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#``
+M`\$N``-H,``",O@``^@```/H$``#Z#```K(#``-H,``#0````_\```*U"``"
+M114``_`!``(TUP`#2I0``_\```-@^````D```_\```/_```"H0X``_`"``/H
+M````@A0``BZI``-(```#2`4```HT```".```$C,``"HZ```Z-@`#_P```V@`
+M``-H!0`#2!```TG=```*-P``*CD``_\```-H$``#:=T``TEQ``*R`0`#Z#``
+M`\$&``/!%P`#:#```TEL``*U%@`"H%$``<*?``*PSP`"L04``K(!``*S```#
+M:#```C+X``*PM``#:#```C+X``*PO``#:#```C+X``*PN``#:#```C+X``*P
+MRP`#:#```C+X``*PC``#:#```C+X``*PT0`#:#```C+X``/H```#Z!```K(#
+M``*S```#:#````(8``/_```#_P```J`.``/P0@`#]````<`````!]``#0!(`
+M`T`5```*&P`"H`X``_`"``/T```!PL\``L$>``"*&P`":[H``F5;``+&;@`#
+M\$$``L=^``-@%0`"L@\``D1"``*E%``#\`<``^B@``/HL``#8!(``^@```"!
+M]``#]````<!-``-`+``#_P```K0@``)`0``"H`0``_!"``/T```!PN0``^@`
+M``""/P`",@@``C)-``#R/P`",@@``C)-``(RY``#0!```_\```/_```#H`8`
+M`X`&``/!\``"+GL``\'P``(N>P`#P?```BY[``/!\``"+GL``T`@``/_```#
+M_P```L`.``/P10`"P1X``_!#``+"+@`#\$$``L,^``-@(``",VP``TE(``*T
+M/P`"M8```D,T``)C-0`#:4@``D,T``-I2``#]````<````-`!```:C\``^B`
+M``/HD``#Z*```^BP``*U$``"1!4``_`&``*@W@`#\`,``V2J``/T```#\$$`
+M`V3J``/X`0`"M0@``D0%``(#'```8?@``J#>``/P`P`#Z$```_0```/P00`#
+MA.H``]A```/<P```>?<``_@#``/4G@`#^P```P_^``(#&``#^`$``X7D``)$
+M%0`"`R\``"'Y``*@W@`#\`,``&'Q``/T```#\$$``&'P``*_"``#W$```]C`
+M``/X`P`#U)X``_L```,/_@`"`RL``_@#``/L`````A0```I```!J/P`#_P``
+M`D`!``*@#@`#\`$``^P```-).``"H-X``_!!``-*7``"N/X``D(H``*@W@`#
+M\`,``VDX``/T```#\$$``VI<``-)T``"M`0``F$4``*R`0`"LQ(``J#>``/P
+M00`"LQ$``V@P``-)<0`"N.\``KD$``/!!@`"87D``D,X``-H,``#2`D``KC]
+M``)$2``#:`D``BY_``-)H``"M!$``\$D``*Q#P`#::```TI$``*T_@`"81X`
+M`VI$``)!%``#:D0``J#>``/P`P`#0F$``_0```/P00`#0ET``_\```/_```#
+MZ&```VFE``-H:P`"N@P``KC```/<@0`#V*$``K#X``*Q!P`#Z"```^@P``/^
+M```#U!\``VAK``/H\``"(_\``B/B``(D'``"H?X``_!!``-B>@`#0G@``_\`
+M``/_```"H(```<.3``*@D0`!PY,``J"B``'#DP`"H+,``<.3``+/_@`"O`P`
+M`J'\``/P0@`#]````<-]``#Z!``#Z/```B/B``(C_P`")!P``T)X``/_```#
+M_P```J"```'#J0`"H)$``<.I``*@H@`!PZD``J"S``'#J0`"S_X``KP,``*A
+M_``#\$(``_0```'#E@``8@0``/H#``/_```"I<\``<.Y``*E_``!P[0``^CP
+M``/HP``#]````<.\``,,SP`#K,```^CP``/T```!P[P``P_\``.O\``#Z,``
+M`B/_``/!_``"(^(``TDX``*@W@`#\$$``TI<``/_```"8BX``J#>``/P`P`#
+M:3@``_0```/P00`#:EP``TG0``*T^P`"010``K(!``*S$@`"H-X``_!!``*S
+M$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@``V@P``-("0`"N/T``D1(
+M``-H"0`"L!@``B1```/L```#1+D``J#>``/P00`#1/D``\$/``/!'P`#P2\`
+M`\$_``/!3P`#P5\``J#>``/P!0`#9+```V2T``-DN0`#]````_!#``-D\``#
+M9/0``V3Y``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P```-$
+MN0`"H-X``_!!``-$^0`#P0\``\$?``/!+P`#P3\``\%O``/!?P`"H-X``_`%
+M``-DK``#9+P``V2Y``/T```#\$,``V3L``-D_``#9/D``TC(``*T\P`"M00`
+M`D`$``)@!0`#:,@``D`$``-HR``#[````K`0``(D0``",O@``C+X``(R^``"
+M,O@``C+X``-*'``")$P``\&,``-*(``")$P``XS&``)HC``#2B0``B1,``/!
+MG``#2B@``B1,``.,Q@`":9P``THL``(D3``#P:P``THP``(D3``#C,8``FJL
+M``-*-``")$P``\&\``-*.``")$P``XS&``)KO``#[````VAK``*Y"``"N,``
+M`]R```/8D``#Z!```^@@``/H,``#_@```]0>``-H:P`#[````^C```.'/``#
+MIW8``X8L``.F:``#A1P``Z5:``.$#``#I$P``FS'``)LQ@`";,4``FS$``/L
+M````(@\``T`D``/_```"1$X``Z`&``*A#@`#\`$``(('``-)I``#2:$``&H_
+M``.+Z@`#P*L``D6E``*@W@`#\`,``D.C``/T```#\$$``F.S``-II``#::$`
+M`K+_``*Q_P`"L'\``VA@``/H```#Z"```^@P``*@W@`#\`,```H)``/T```#
+M\$$```H(``*XP``#:&L``]@```/<@``#U!X``K\"``(N>P`#@.```(($``""
+M`P`#Z````(("``""`0``\@```TA4``*@W@`#\`,``X3H``/T```#\$$``X3J
+M``)B)``#:%0``TF8``.(Y0`#P3X``J#>``/P`0`#@S```\$N``)@"``#:#``
+M`TEU``.(Y@`"8&@``\$7``/!+@`#P3X``J#>``/P`0`#@S```V@P``-(5``"
+MH-X``_`#``.$Z``#]````_!!``.$Z@`#P$0``D(D``-H5``"OP(``BY[```"
+M&``#_P```_\```*@#@`#\`(``_0```($UP`",&$``^AP``.$Y@`"1DL``J!D
+M``/P3P`#2=(``^A@``.*L@`#JJH``X2F``)D2@`#P50``J#>``/P`P`#:.4`
+M`_0```/P00`#:04``_0```'%@@`"OP@``D_Y``.O]``#B[(``ZN\``(EI@`#
+M]````@6"``-`#``#_P```K\(``)/\``#\$(``_0```'$]``"OP```KL!``(E
+MI@```A$``_\```/_```"H`X``_!"``/T```!Q8(``K$"``*P$0`"Q$```L50
+M``*@W@`#\`,``VCE``/T```#\$$``VD%``,!'@`"!.D``/("``#R`0`"H-X`
+M`_`#``!Z!@`#]````_!!``!Z!0`#C>(``]S0``/8\``#B>8``FF>``#Q\@``
+M0@<``^C0``./X``#P:@``XSM``#A]@``XCX``B_*``*W`0``0@<``^B@``#1
+M\@`"H'X``_`!``.H@``##]\``\'9``/!J``#C.T``.'V``#B/@`"+\H``C`+
+M``/!!``#P28``V)P``*_`0`#0!$``XC@``*@_@`#\`0``D1(``/P`@`#]```
+M`@5H``*W`0``0@<``_\```*@?@`#\`$``ZB```/HT``#C^```\&H``.,[0``
+MX?8``.(^``(OR@`",`L``T)P``.,ZP`#C.H``^CP``+(0``#J(```"H6``+*
+M8@`#JJ```J9>``(%10``:C\``/(6``/!6``#P7H``V)Q``/T```"!/\``J%>
+M``/P#@``:C\``\&1``/!LP`"H-X``_`#``-A+@`#]````_!!``-A,@`"P($`
+M`Z@```+"HP`#JB```X50``"J%@`#@>```P"$``/P)``"H80``_`!``+$00`#
+M!$X``\%4``,"I@`#\"0``J&F``/P`0`"QF$``P9N``/!=@`#U%X``F`"``(%
+M5P``:C\``K\"``(N>P`#27$``X'D``/!!@`#HFP``J`N``(%@@`"87$``\$N
+M``/!/@`"H-X``_`!``.#,``#AF```_!'``-H,``#C^T``BY[``./[0`"+GL`
+M`X_M``(N>P`#C^T``BY[``-)=0`#P2X``\$&``/!%P`#P3X``J#>``/P`0`#
+M@S```V@P``-)F``#_P```\$^``*@W@`#\`$``X,P``/!+@`#:#````H/```!
+M]``#_P```D$>``/P`0`#[````J4.``/P2``#0!$``J#>``/P`P`"9FX``_0`
+M``/P00`"9WX``V`1``/H````@?0``^P```(R^``#2D```$(```!*!```4@,`
+M`KPS``)$#``"11P``F1%``)&+``"1SP``F9G``)D1@`"H4X``_`!``*T`0`"
+MH(X``_`%``*D20`#\$,``J1+``/P00``\@(``*($``*\S``"1`P``D4<``)&
+M+``"1SP``F1%``)D1@`"9$<``J%.``/P`0`"M`$``J".``/P!0`"I$H``_!#
+M``*D2P`#\$$``/(!``"B`P`#Z$```*(```-#*0`"H-X``_!!``-#:0```@(`
+M`!(!``*Q#P`"LP<``J7^``(%_``"H`X``_`&``*\#P`"I$$``_`!``*\"0`#
+MP4P``\%<``*@+@`#\`8``KP/``*D80`#\`$``KP)``/!;``#P7P``J#>``/P
+M`P`#8RD``_0```/P00`#8VD``DP"``*@S@`#\`8``L_^``*\"0`"I?P``_`"
+M``/T```!Q:8``TCE``*@W@`#\$$``TD%``*X$0`"H`X``_`!``+$2``"24$`
+M`J23``/P`0``\@(``J`N``/P`0`"Q5@``DE1``*DDP`#\`$``/(!``*@W@`#
+M\`,``VCE``/T```#\$$``VD%``)``@`"H`X``@6F``/L````:C\``^@```(P
+M.P`#29@``K@/``*U]0`"LP$``J#>``/P`0`#@S```\$N``)@"``"014``V@P
+M``*_```"+GL``/'_``/H````@?X``T`,``-`+0`"N!```KD(``)*&``#JJ8`
+M`DM)``.KM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*$0`"
+ML$```D!```/P00`#Z#```D$>``/P`0`#Z#```)G]``(N?P`"O`$``J#>``/P
+M"0`#2"$``XS&``.&9@`#IF8``F9L``-H(0`#:HD``_0```/P1P`#2"4``XS&
+M``.&9@`#IF8``F9L``-H)0`#:HT``K`!``/H$``#Z"```^@P``-J8``"OP,`
+M`C'5``-("``#A.H``('U``)@!``#:`@``K]D``(N>P``:C\``_\```/_```"
+MH-X``_`#``*[```#]````_!!``*[0```V>\``\$.``/!'@`#@18``F$>``."
+MY@`#:D0``\$>``.!%@`#Z"```VI$``/H```#P````\$0``*R_0`#:&```TI@
+M``*_]P`"L1,``D`/``)@#@`#:F```#(,```Z"P`"O`@``K_^``.&:@`"8B8`
+M`J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(N>P`#:&L``_\```/^````
+M8CT``%H\``/_```#V,$``]RQ``./XP`"+GL``]`?``.,[P`#C^0``F_^``)`
+M`0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!J(``J#>``/P`P`#2"$``_0`
+M``/P00`#2"4``\#,``(&S@`#C.8``L9L``/P00`"QWX``J#>``/P!``#:"$`
+M`VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!QG$``T`1``*P"```
+M\?0``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T```""(,``X#A``.!
+M!@`"81X``X+G``-J1``#@08``^@@``-J1``"L`$``^@0``/H(``#Z#```VI@
+M``-`+```6BL``K0$``/H\``"1$```_`!``*_`0`"I+X``_`!``*_!``",=4`
+M`/(G``#R)0`"L/\``K&_``/!(``#:&```K`!``/H$``#Z"```^@P``-J8```
+M"CL``!(,```:"P`"L`(``J#>``/P00`"L`0``X(J``*D/@`#\`$``K,$``.!
+M%@`"8`$``K$S``-J8``#0`H``K`!``*Q`@`"L@```K,!``*@*P`#\`(``^@@
+M``/!.P`#:F@``\$.```20@`"0`D``_`!``/H(``"L!,``K$"``.")@`#Z#``
+M`VIP``-`+0``8A$``!(H``*_0``"3T\``_`#``*@S@`#\`$``K((``*P(0`"
+ML0(``K,!``-J=```"BL``K`!``/_```"I!X``_`%``*Q!``"L@```K,"``/T
+M!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q`@`"LP0``VI\
+M```!_@`#_P```_\```+`#@``@?X``C'0```")P`#0`H``T`-``*@#@`#\`4`
+M`K`!``)`!0`#@`8``_0$``/P`P`"L`0``D`)``.``@`"L0,``F@!```"*P`#
+M_P```_\```*D#@`#\`L``!(H``*P(P`"L0,``K,!``-J=``#2GP``_\```*P
+M`0`"L00``K,$``-J?``#2F0``K2````1[P`"0`0``F`(``.B(@`"LP$``VID
+M``(PE0`",*(```'_``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H`
+M`J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(O"P`#Z/```/G_```!_@`#
+M_P```_\```+`#@``@?X``T`E```:$``"L@0``D(@``*@W@`#\$$``Z,R``*Y
+M`@`"29,``F(I``*Y@``"294``F(I``*YA@`#Z(```J`I``/P00`#P8X``,':
+M```)_0`#0"X``_\```*@`0`"!Z(``K`!``)!"``#\`4```)```/_```#_P``
+M`J`.``('H@`#2G0``'HH``/_```#_P```\$O``-J=``",=````(G``-`"@`#
+M0`T``J`.``/P!0`"L`0``D`%``.``@`#]`0``_`"``*P$``"0`D``'G:``*Q
+M0P`#_P```J#^``/P00`"L2,``F@!```"*P`#_P```_\```*@#@`"!]0``!(H
+M``*P0P`"L00``K,!``-J=``#2GP``_\```*P`0`"L04``K,$``-J?``#2F0`
+M`K2````1[P`"0`0``F`(``*X(``"8`@``KB_``)`"``#HB(``\$^``-J9``#
+M]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``/!/@`#:F0``C"5``(P
+MH@``0A```K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```'']0`#0`X``K`0
+M``/_```"00D``J`0``(']0```B<``_\```/_```"P`X``((G``*Q`@`"I`$`
+M`@<U``!![P```?D``_\```/_```#V(```]P```!Z0@`"L`$``]P!``*P```#
+MV`$``$G:``/_```#_P```J">``/P1@`#Z/```K$D``+(@0`#V(```L`!``/8
+M@0`",(P```'^``/_```#_P```L`.``"!_@``>=H``C'0``*@_@`#\$4``K`/
+M``/!$``#P2```\$P``-J@``#0`H``K!```/_```"0`D``Z`"``*Q`P`":`$`
+M``(K``/_```#_P```J0.``/P"P``$B@``K!#``*Q!0`"LP$``VIT``-*?``#
+M_P```K`!``*Q!@`"LP0``VI\``-*9``"M(```!'O``)`!``"8`@``Z(B``*S
+M`0`#:F0``C"5``(PH@`#0"4``$(0``*P(``"0`4``_!(``*P`@`"H-X``_!!
+M``.``@`"0`@``_`"``/T```!R&4``!'^``*P@``"LP,``J`C``/P0P`"0`4`
+M`_`!``(QE@`#0"X``_\```*P"``"00@``J`0``((90`"L(```D$(``/P!0``
+M`D```_\```/_```"H`X``@AE```")0`#_P```_\```/H$```BB4``J0.``('
+M=P```>\``$'Y``/_```#_P```]@```/<@```>D(``K````/8`0`"L`$``]P!
+M``-`#0`"O2```_\```)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\`
+M`K+_``-H8``#:&L``!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#
+MZ#```VI@``-*9``"M(```D`$``-J9```(?4``_\```-("``#_P```\$$``-H
+M"``#[````^@```/H$``"H-X``_`#``-I'``#]`0``_`!``-I-``#[````&H_
+M``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_````V?P`
+M`C*.``/H```",#L``KL"``#:/@`#2`$``K"_``)$0``#:`$``TF8``*T#P`"
+MM?T``F`$``)!%0`#P2X``\$^``*@W@`#\`$``X,P``-H,``#2`@``K1```"!
+M]0`"8`0``V@(``/H```"L6```^@@``/H,``#::```^@```*Q$``#Z"```^@P
+M``-J1``"L`$``^@0``/H(``#Z#```VI@``*_`@`",=4``^@```/````#P1``
+M`K+]``-H8```"CL``!(,```:"P`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+GL``VAK``/_
+M```#_@```C'^``-*8```,@P``#H+``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"````20@`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``"L/\``K&_``/!(``#:&```^AP``-*9``"M(```D`$
+M``/H(``#Z#```VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0`
+M`C"5``-*9``"M`@``D1```)G=``"I7X``@E<``/H```",#L``J#>``/P`P`#
+M2"(``_0```/P00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H
+M(@`#:HH``_0```/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R2$``T`2
+M``#Q]``"OP0``J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R5P`
+M`K`!``/H$``#Z"```^@P``-J8``#2F0``K2```)`!``#:F0``"'U``/_```#
+M2`@``_\```/!!``#:`@``^P```!J/P``\?\``^@```""$P`#0`@``T`M``*X
+M0``"N0@``DH(``.JJ@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!
+M``*S!@`#0"T```H1``*P0``"0$```_!!``/H,``"01X``_`!``/H,```FA(`
+M`"'T``/H4``#_P```*(9``"I]```:C\``_\```/_```"H-X``_`#``!9\0`#
+M]````_!#``!9\``#_P```_\```#9[P`#2````X3J``/`1``#_P```D`$``-H
+M```#2`0``\!^``/_```#_P```D,W``-H!``#0"P``%HK``*T!``#Z/```D1`
+M``/P`0`"OP$``DN^``*@O@`#\`,``C#]``/T```!R;4``K_+``(S00``\B8`
+M`/(E``*P_P`"L;\``\$@``-H8``"L`$``^@0``/H(``#Z#```VI@```*.P``
+M$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B
+M(0`"I#X``_`!``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"
+M``*R```"LP$``J`K``/P`@`#Z"```\$[``-J:``"L`$``!)!``)`"0`#\`$`
+M`^@@``*P$P`"L0(``X(F``/H,``#:G```T`M``!B$0``$B@``K]```)/3P`#
+M\`,``J#.``/P`0`"L@@``K`A``*Q`@`"LP$``VIT```**P`"L`$``_\```)!
+M$``"I!X``_`%``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX
+M``-*?``#_P```K`!``*Q`@`"LP0``VI\```**P`#_P```_\```)!'@`"I!X`
+M`@I4```"$P`#_P```_\```+`#@``@A,``C'0```")@`#0`H``T`-``*@#@`#
+M\`4``K`"``)`!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"
+M*P`#_P```_\```)`#@`"I`X``_`+```2*``"L",``K$#``*S`0`#:G0``TI\
+M``/_```"L`$``K$$``*S!``#:GP``TID``*T@```$>\``D`$``)@"``#HB(`
+M`K,!``-J9``",)4``C"B```!_P`#_P```_\```*@#@`#\$X``T`L``*\!``#
+MW,```K_```*@W@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+PL``^CP``#Y
+M_P```A,``_\```/_```"P`X``((3``!:*P``>B4``K@(``)*O@`"H*X``<IX
+M``.JL``"2JX``_!#``(M:``#]````<IT``-*<``"NH@``KEP``*@^``#\$,`
+M`\$J``/T```!RG(``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C,+``*P_P`"
+ML;\``\$@``-H8```"A(```(3``-`+@`#_P```J`!``(*C``"L`$``D$(``/P
+M!0```D```_\```/_```"H`X``@J,``-*=```>B@``_\```/_```#P2\``VIT
+M``(QT````B8``T`*``-`#0`"H`X``_`%``*P"``"0`4``X````/T!``#\`,`
+M`K`@``)`"0`#H````K%#``)H`0```BL``_\```/_```"0`X``J`.``(*O```
+M$B@``K!#``*Q!``"LP$``VIT``-*?``#_P```K`!``*Q!0`"LP0``VI\``-*
+M9``"M(```!'O``)`!``"8`@``K@@``)@"``"N+\``D`(``.B(@`"L00``\$^
+M``-J9``#]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``*S`0`#:F0`
+M`C"5``(PH@``6BL``KH!``/_```"2[H``J"Z``/P0@`#]````<KE``!"$``"
+ML`$``J#>``/P00`#@`(``D`(``/P`@`#]````<KE``-`"@`#_P```K!```)!
+M"``"H!```@KE```")@`#_P```_\```+`#@``@B8``K$"``*D`0`""A$```'O
+M``!!^0`#_P```_\```/8```#W(```'I!``*P```#V`$``K`!``/<`0`",(P`
+M``(3``/_```#_P```L`.``""$P`",=```T`*``*P@``#_P```D`)``.@!``"
+ML0,``F@!```"*P`#_P```_\```)`#@`"I`X``_`+```2*``"L$,``K$%``*S
+M`0`#:G0``TI\``/_```"L`$``K$&``*S!``#:GP``TID``*T@```$>\``D`$
+M``)@"``#HB(``K,!``*Q```#:F0``C"5``(PH@``6BL``KH#``*Y`0`#_P``
+M`DBZ``*DB0`!RU<``KD$``/_```"2+H``J"*``'+.0```B4``K((``*S```#
+M_P```J0"``'+5P`"H`X``_!#``":)0`#]````<I4``)+N0`"H+D``<M7``"2
+M)0`#]````<I4``/T```!RU<``$(0``*P`0`"H-X``_!!``.``@`"0`@``_`"
+M``/T```!RU<``T`N``/_```"L`@``D$(``*@$``""U<``K"```)!"``#\`4`
+M``)```/_```#_P```J`.``(+5P```B4``_\```/_```#Z!```(HE``*D#@`"
+M"E0``%HK``/_```#2G```_\```)+O@`"H+X``_!"``*R@``#:G```&'Y``!9
+M[P`#_P```]S```/8L```>D$``K````/8`0`"L`$``]P!``-`#0`"O4```_\`
+M``)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\``K+_``-H8``#:&L`
+M`!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#Z#```VI@``(QT``#
+M[````&H_``/_```#_P```J#>``/P`P`"NU,``_0```/P00`"NUL``_\```/_
+M````V?P``T`0``*[#P`#2"D``J#>``/P00`#2"T``K\$``)`"P`#JP(``P_[
+M``.,]@`";,\``X_V``-)Z``"HTP``_`$``,$3``#!5\``_0```/P10`#A.8`
+M`X56``.E5@`"950``F1.``/!!``#P14``J#>``/P!``#:"D``VGH``/T```#
+M\$(``V@M``-I[``#Z````C!/``-(`0`"L+\``D1```-H`0`#Z````K%```/H
+M(``#Z#```VI$``*P`0`#Z!```^@@``/H,``#:F```K\"``(QU0``"CL``!(,
+M```:"P`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$``)B(0`"I#X`
+M`_`!``*S!``"L1@``VI@``-`"@`"L`$``K$"``*R$@`#Z#```VIH``*P@```
+M$D$``D`(``/P`0`#Z"```K`3``*Q`@`#@B8``^@P``-J<``"L"$``K$"``*R
+M`0`"LP$``VIT``*P`0`"L0(``K(/``*S`0`#:G@``TI\``/_```"L`(``K$"
+M``*S!``#:GP``^@```/````"L;\``\$@``-H8``#Z'```TID``*T@``"0`0`
+M`VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0``C"5``-*9``"
+MM`@``D1```)G=``"I7X``@P\``/H```",$\``J#>``/P!``#2"H``TGH``/T
+M```#\$(``T@N``-)[``"O!$``K\0``+)GP`"R(P``\$(``/!&0`"H-X``_`$
+M``-H*@`#:>@``_0```/P0@`#:"X``VGL``*[`0``VCX``^AP``.+Y0`#B[8`
+M`J6+``/P`@`#]````<O\``-`$@``\?0``K\@``*@W@`#\`,``FJO``/T```#
+M\$$``FN_``-@$@`#]````<P\``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID``/L````:C\``^@```"!V0`"L`@``('[``*@W@`#\`,``%GQ
+M``/T```#\$$``%GP``*P?P`"H?X``_!!``)+L```V>\``K#_``*QOP`#P2``
+M`VA@``*P`0`#Z!```^@@``/H,``#:F````H[```2#```&@L``K`"``*@W@`#
+M\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"LP0``T`5``*Q
+M"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J:```$?L``K`3
+M``*Q`@`#@B8``^@P``-J<```$B@``K`A``*Q`@`"LP$``VIT``*P`0`"L0(`
+M`K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP``KP$``/<P```
+M>>\``&'[``*[&``#V/```B\+```!V0`#0"4``K\0``+`#@``@=D``D]?``/P
+M`P`"+6@``_0```',J0`"OP@``J`.``/P`0`#P?X``C,+``-*@``"H/X``_!!
+M``-JA```8>\``K"```/H\``"H<```_!!``/!_@`"+1L``C'0```1[P`#Z!``
+M`K`C``.B(@`"LP$``VID``(PE0``8=D```'O```)^0`#0"8``K(0``/8```#
+MW!```'G[``*P```#V`$``K`!``/<`0`"0BD``_!%``.O\``"H,X``_`"``/[
+M```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E+@`#\`$``_L!
+M``,/_@`"#,L```'9``/_```#_P```L`.``"!V0``8>\``K"```/!_@`"H<``
+M`_!!``/H\``"+1L``C'0```1[P`"L`,``^@0``.B(@`"LP$``VID``(PE0`"
+M,*(``T`E```!V0`"L0,``K((``*S$``"0S4``_`"``)")0`#\`(``J4!``',
+ME@``8?D``%GO``/_```#W,```]BP``*P```#V`$``K`!``/<`0``>?L``T`-
+M``*]0``#_P```DW5``*FW@`#\`,``B\K``/T!``#\`H``K!_``*Q_P`"LO\`
+M`VA@``-H:P``$>4``K/```/HT``#8$P``B]F``*P`0`#Z!```^@@``/H,``#
+M:F```C'0``/L```"O!$``J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(
+M\0`"+5,``J#>``/P!``#:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$
+M``-(U``#2-D``_0```/P0@`#2/0``TCY``(M4P`"H-X``_`$``-HU``#:-D`
+M`_0```/P0@`#:/0``VCY``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#
+M\`0``L`,``+!'``#]````_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P
+M00`#:/P``^P```*@_@`#\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L
+M``+'?``#]````_!(``,`#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP`
+M`^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#H`,``]P```/8$``#
+M0#$``K\#``*\`@`"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X``_!!``/!
+M!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#^P```P_^
+M``(-=0`#0#4``K\#``/_```"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X`
+M`_!!``/!!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#
+M^P```P_^``(-C0`#0#@``T`]``/_```#:H0``VJ!``/L```#85```V%5``-A
+M6@`#85\``TA4``/_```#Z#```Z,S``-H5``#:&L``TA5``/H```#Z'```K+O
+M``*Q_P`"L+\``VA@``-H:P`#27P``K0$``)A%``#:7P``TD\``/_```"81X`
+M`VD\``-*E``#03D``_\```/_```"IC<``_`'``*F)@`#\`4``J85``/P`P`"
+MI00``_`!``-A.``#8/P``_\```/^```#_P```TAD``*T$``"0B0``J`D``/P
+M0P`"+A4``_0```'-T``"L/\``K'_``*R_P`"L_\``VJ0``-)/``#P$X``D$4
+M``-I/``#2%0``K4_``)#4P`#:%0``^@```"!]```@AH``((;``-(9``#C.H`
+M`/(5``),#``#\$@``T@T``/_```#@`@``Z`,``*@#@`#^`$``@WQ``""%0`#
+M^`,``TA5``/H```#AP<``VA5``-)/0`"OQ```D1/``/P!``"O_\``BY[``*_
+M4``"+GL``Z=P``,'?@`"#@<``\`@``/`$``#P````VA@``-H:P`#H!```VA@
+M``-!4``#054``T%:``-!7P`#[````_@#``-)T``"N`@``DDX``*@F``"#F@`
+M`TG4``*T$``"0S0``J`T``(.1``#2`@``K@(``)@"``#:`@``T@H``*X(``"
+M8S@``T@M``-H*``#:>@``F=X``-H+0`#:>T``TC(``*X^P`"0B@``VC(``-(
+MF``"N"```F`(``-(L0`#:)@``F1(``-HL0`#P0X``\$>``/!+@`#P3X``V,P
+M``-C<``#8S0``V-T``-C.``#8W@``_0```'.:``#2`@``KCW``)`"``#:`@`
+M`T@H``*XWP`"0S@``T@M``-H*``#:>@``D=X``-H+0`#:>T``TC(``*X!``"
+M8B@``VC(``-(F``"N-\``D`(``-(L0`#:)@``D1(``-HL0`"L`,``\$0``/!
+M(``#P3```V,P``-C<``#8S0``V-T``/!+@`#P3X``V,X``-C>``#27P``K3[
+M``)!%``#:7P``VAK``/L```#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(`
+M`VC*``)H(0`#:,H``\&"``-HR@`#[````_@#``,/_@`"#GP``^P```/H```#
+MP!```\`@``.@$``#:&```VAK``/!#@`#Z!```^@@``/H,``#I!,``]@0``/<
+M0``#_@```]0>``-H:P`#::0``^@```/^```#U!X``VAK``-II``"H-X``_`#
+M``-"8``#]````_!!``-"7``#0ED``J#>``-II``#\`,``T)H``/T```#\$$`
+M`T)D``-IH0`#_@```]0>``-H:P`#:&L``^P```/H```#P"```\`0``.@$``#
+M:&```VAK``-"5@`#P0X``^@0``/H(``#Z#```Z03``/8$``#W$```]0>``*_
+M`@`"+GL``VAK``-II``#::(``^@```/_```#U!X``K\"``(N>P`#:&L``VFD
+M``/H```#P"```\`0``/````#:&```VAK``/L```#:&L``K!_``*Q_P`"LO\`
+M`VA@``*Q#``#Z````Z`#``/<```#V!```^@```/H$``#Z"```^@P``/^```#
+MU!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>``-H:P`#^P```PB.``(.
+MX``#[````"'Z``/H4``#Z&```^AP``*Y"``"N,```]R!``/8D0`#0E```_@#
+M``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#:&L``K09``/^```#U%\`
+M`VAK``-)I0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#
+M"9X``@\'``-II0`#[````J&^``/P"@`#T!X``P^^``/X`P`#``X``P$>``,"
+M+@`#`SX``]0>``,/_@`"#Q```_L```,,S@`"#PL``^P```*AO@`#\`H``]`>
+M``,/O@`#^`,``L`.``+!'@`"PBX``L,^``/4'@`##_X``@\@``/[```##,X`
+M`@\;``/L```#T)X``]`?``*\/P`"2(P``DF<``)*K``"2[P``D0,``)%'``"
+M1BP``D<\``*\(``"P(0``Z````*C2``#\$$``L`,``+!E0`#H1```J-9``/P
+M00`"P1P``L*F``.B(``"HVH``_!!``+"+``"P[<``Z,P``*C>P`#\$$``L,\
+M``/HT``#C.D``P2```+HC0`#!9$``NF=``,&H@`"ZJT``P>S``+KO0`#8FX`
+M`DB,``))G``"2JP``DN\``/4G@`#0FX``F1%``)D1@`"9$<``@]-``!J/P`#
+M^P```_L!``,/_@`"#RL``^P```/0G@`#T!\``KP_``)(C``"29P``DJL``)+
+MO``"1`P``D4<``)&+``"1SP``KP@``+`A``#H````J-(``/P00`"P`P``L&5
+M``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#\$$``L(L``+#MP`#HS``
+M`J-[``/P00`"PSP``KP'``*CW``#\$X``W!,``-03@`#_P```_\```/^```#
+MU!X``VAK``/[```#<$X``U!,``/_```#_P```_0$``/P"``"O`@``J3<``/P
+M`0`#:H0``KP)``*DW``#\`$``VJ```*P_P`"L;\``K+_``-H8``#^P```_L!
+M``+-W@`"IM\``@]F``-*9``"M(```D`$``-J9``"L````K$```*R```"LP$`
+M`VIT``*P,0`"L08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#
+M:GP``TID``*T@``"0`0``K0#``)@!``#:F0``C"5``-*9``"M(```D`$``-J
+M9```:C\``C-L``/L````6?8``&(^``/_```"H;X``_!"``#Q]``#[````J'.
+M``/P00`#"[X``PS.``#9]@``XCX``TI```!:%@`#_P```_\```*@O@`#\$(`
+M`Z````.B(``#T%X``&(*``!9\@`#H@(``D`)``)"*0`"I8X``@_U``,(C@`"
+MH`T``_`+``!"!P`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$
+M3P`#P50``J6N``(0!0`#"JX``J`M``/P"P``4@<``L9O``/!=@`"H+X``_!&
+M``/47@`"QF\``\%V``/47@`"QF\``\%V``/47@`##,X``A`&``)KB@`"#\H`
+M`^P```-"<```4A8``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"
+MH6@``_!!``+&:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&
+M:``#`B@``P,X``,*K@`"$!D``\%4``/!=@`#U%X``V)P``/L```#P6(``P9N
+M``/<$``#V````]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X`
+M`_L```,&;@`"$"X``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#
+M:1```VD4``-I&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I
+M-``#[````\$0``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<
+M``/T```#\$4``VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4`
+M`D$#``-)T@`#_P```D`*``-)P@`"I1```_`!``-)Q@`#[````K!_``*Q_P`"
+MLO\``VA@``-H:P`#Z````^@0``/!+@`"LS```VFD``/H```"L3```^@@``/H
+M,``#Z$```Z5#``/80``#W%```_X```/4'@`#:&L``_L```/[```"L!(``^@0
+M``/^```#U!X``VAK``,(C@`"$(8``^P```/0G@`#^P```_\```/_```#U)\`
+M`_L!``,/_@`"$(P``^P```/X`0`"OP0``TID``/_```#_P```D$/``(0EP`#
+M^`,``VAK``/_```#_P```_X```/L```#2F0``_\```*_"``"00\``J`?``(0
+MPP`#0!(``K40``*E)0`#\`0``K\"``)JKP`#]````=#```+$50`"I20``_`$
+M``*_`@`":[\``_0```'0P``"Q$4``J4D``/P!``"OQ```FJO``/T```!T,``
+M`K\0``)KOP``\?0``V`2``(PQ``#[````TIP``/_```#P<(``T`N``*P`0`#
+M:J@``_\```/_```#_P```TJL``*T`@`#:JD``\````/`$0`#P"(``\`S``-*
+MK0`"OY```J#/``/P!0`#P$0``K\/``)/3P`#]````_!!``/`]``"H-X``_`+
+M``-`&0`#_P```_\```)D0``"95$``F9B``)G<P`#8!D``FJO``/T```#\$D`
+M`T`=``/_```#_P```F1```)E40`"9F(``F=S``-@'0`":[\``V`N``/L```"
+MQ$8``VJI``/_```#_P```_\```-*K``#[````K!_``*Q_P`"LO\``VA@``-H
+M:P``">4``K#```/<```#V!```J#^``/P!``#Z````^@0``/H(``#Z#```J#^
+M``/P1``"L%4``\$0``/!(``#P3```J#^``/P!``"M/\``\%4``/!9``#P70`
+M`J#^``/P1``"M*H``\%4``/!9``#P70``KP'``*C_@`"$7D``$(-``/_```#
+M_P```J".``(1/P`"H-X``_`#``-`0@`#]`0``_`!``-`1@``ZC\``&H.``*D
+MW@`#\`0``\"(``/`F0`#P*H``\"[``)@"``"81D``F(J``)C.P`"9$@``F59
+M``)F:@`"9WL``&H_``/_```#_P```_X```/4'@`#:&L``_L```,,S@`#_@``
+M`]1>``-H:P`#^P```PS.``(1/P``0@T``&(.``/_```"H(X``A%D``-`2@`"
+MI,X``_`$``/`B``#P)D``\"J``/`NP`"I-X``_`"``/!B@`#P9L``KH/``)*
+MJ``#BZ8``FJK``*[\``"2[@``Z>V``)KMP`#]`0``_`#``/H8``#Z*```^BP
+M``*T\``"8$H``\$0``/!(``#P3```VJ$``*@_@`#\`,``K3P``/T!``#\`$`
+M`K0/``)@2P`#P1```\$@``/!,``#:H```^P```/^```#U!X``VAK``/[```#
+M#,X``KD#``*@^0`#\$0``^A```/H4``#Z&```^AP``/^```#U%X``VAK``/[
+M```##,X``A&%``*P\``"L?\``J#Y``/P0@`#Z````^@0``/!(0`#P3$``VJ$
+M``-J@``#[````K!_``*Q_P`"LO\``VA@``-H:P``">4``K#```/<```#V!``
+M`K3_``/!9``#P70``KP'``/^```"M?\``]1>``-H:P`#^P```PS.``/^```"
+MM>\``]1>``-H:P`#^P```PS.``(1HP`"M?\``VJ%``*P\``#P1```\$@``/!
+M,``#:H```TIB``(QT``#Z/```C'<``-J8@``">4``K#```/<```#V!```K3_
+M``/!5``#P60``\%T``*\!P`#_@```]1>``-H:P`#^P```PS.``(1Q0`"L/\`
+M`K&_``/!(``#:&```^P```-*9``"M(```D`$``-J9``#[````K`$``*@\``#
+M\`,``C#]``/T!``#\`$``BUH``/H```#P````\$0``*R_0`#:&````H[```R
+M#```&@L``K`*``*@W@`#\$$``K`,``.!%@`"8`$``K$6``*D/@`#\`$``K,$
+M``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"L@0``F(F``-J8``#C^$`
+M`BY[``-H:P`#_P```_X```/L```#2F```_\```/H,``"8`X``VI@``-*9``"
+MM/(``D`$``-J9``#[````&H_``-`!``#_P```K@$``)%X``"H%X``_!$``*@
+MW@`#\$(``T`D``/_````8?@``_\```/_```#W,```X_J``*@W@`#\`$``^CP
+M``/8\``#C.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<`
+M`D`(``/P0P`"+PL``_0```/P00`"+QL``D1N``/P"0`#Z,```ZMB``.E8``"
+M15X``_!#``(O"P`#]````_!!``(O&P`#[````TC```-(Q0`#Z!```^A0``*@
+MW@`#\`@``VC````",0``"C```_\```/_```#:,```_0```/P1@`#:,4``"(O
+M```J+@`#_P```_\```-HQ0`#[````&H_``/_```#_P```%'Y``*@W@`#\`,`
+M`%GQ``/T```#\$$``%GP``/_```#W*```]BP``-`!@`#_P```_\```)`Z``#
+M\`,``J#>``/P00`#0"8``_\```/_```#24$``J`.``/P0P`"H-X``_!!``/!
+M10`"14X``_!#``.,Y``#]````_!!``.,XP`#B9@``ZJ<``*@K@`#\`,``B\+
+M``/T```#\$$``B\;``-`!@`#_P```_\```-)00`"0(X``J`.``/P0P`"H-X`
+M`_!!``/!10`#Z,```ZM"``)%3@`#\`<``Z5```)%7@`#\$,``B\+``/T```#
+M\$$``B\;``/L```"H-X``_`#``-((0`#]````_!!``-()0`#_P```KL!``.B
+M9@`#@68``Z$6``.'=@`"8"<``P`+``.G!@`#@@8``F8A``*@W@`#\`0``V@A
+M``-JB0`#]````_!"``-H)0`#:HT``^P```./[0`"+GL``^@P``."X``#Z!``
+M`^@```-H,``#C^T``BY[``/H\``#27```^AP``*V`0`#P5$``\%```-H,0`"
+MN/P``\%3``/!0@`"15@``TET``(R^``#:#$``\%1``/!0``",O@``V@Q``/!
+M4P`#P4(``TF8``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TF<
+M``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TCH``(R^``#:#$`
+M`\%1``/!0``"MQ```C+X``-H,0`#P5,``\%"``(R^``#:#$``^P```-)/0`"
+ML`@``D`$``/P!0`#2J0``_\```/_```"L@,``VJD``*P!``"000``J`0``/P
+M1@`#2,```TC%``*Q`P`"M0,``VC```-HQ0`#[````_\```/_```#_P```^P`
+M``-A2``#84$``V%&``-B?P`#P0X``^@0``/H(``#Z#```VCH``/H```#_P``
+M`VCH``-!2``#_P```^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#
+MH`,``]P```/8$``"O`,``K#W``*@_@`#\$$``K!_``/!$``#P2```\$P``*T
+M_P`#P50``\%D``/!=``#_@```]0>``-H:P`#H`$``Z$1``.B(0`#HS$``_L`
+M``/^```#U%X``VAK``/[```##,X``A,A``*P_P`"O`@``\$0``/!(``#P3``
+M`VJ```*D_@`!TSL``J#\``/P`@`#:H0``^P```*P]P`#H0$``Z(1``.C(0`#
+M:H0``^P```-)/0`#_P```KB```)D2``#:3T``K`!``*Q`@`"LC\``D(O``*S
+M```#:F@``K````*Q```"L@```K,"``-J=``"L0$``K((``*S```#:G@``K`!
+M``*R```#:GP``!'O``*PP``"0`\``Z`"``)@#@`"L0```Z(B``*S`0`#:F0`
+M`K#_``*QOP`#P2```VA@``/_```#_P```C"5``*X?P`"1$@``VD]``/L```#
+MZ````^@0``*R`P`"LP```V@P``/L```#Z````((_``(B^@``\C\``B+Z``(S
+MJ``"+FX``TF8``*T]P`"010``VF8``/!+@`#Z#```V@P```"%P`#@>```^A`
+M``*@`0`#\`$``\%.``(TL@`#2`@``KC^``)!&``#:`@``^@```""/P`")%H`
+M`/(_``(D6@```A<``X'@``/_```"I!```_`"``/!3@`"-+(``C0"``-`+``"
+MN$```KF```*[_P`#2J4``D@8``/P`0`"N\\``DD9``/P`@`"NC\``DNZ``)%
+M6P`#:J4``_0```'";``#2=$``KA```)$>``#A$```TB<``.%X@`"8`0``F`%
+M``-HG``#:*```VBT``-HN``#23@``X7A``/`50`"0B4``VDX``-J7``#H.$`
+M`X'A``/H,``#@N@``X7E``(P*@`#0Z8``X#H``/_```"2(4``FB```/!F``#
+MP:@``\&X``-CI@`#8^8``^@```/HT``",#L``\'>``(P.P`",&$``X3B``/!
+MR0`#Z````X'A``.#Y``"PC$``P(N``+#/@`"1$D``_`!``.#Y0`#Z%```C`J
+M``.`Z@`","H``XCE``.$X``"1$P``_`"``.(Y``"R(X``\&8``/!J``#P;@`
+M`V,J``-C:@`",&$``X'B``.@X0`#HY8``X+D``+"+@`#Z%```C`J``.@XP`"
+M,"H``C!A``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"
+M`@`#@B0``)'C``/L```",&$``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP
+M``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(`
+M`V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"
+M8`4``F$4``/H,``#P2X``V@P``-#I```(>,``K4/``/_```"0`4``F`$``/!
+M$``#P2```\$P``-CI``#8^0``X&$``.@&``#@@8``F`"``/HT``",$\``\'>
+M``(P3P`#2)```Z2Z``.EYP`"014``F$4``-HD``#:*@``VB4``-HK``#H*8`
+M`\$0``/!(``#P3```V0D``-D9``#BK8``T@A``*X`P`"9F@``KD/``*[_@`"
+M1FD``F9J``)'>P`#:"$``VJ)``-H)0`#:HT``T@(``-((0`"81X``V@(``-(
+MR``"N$```KD_``)@"``#:,@``D`)``-HR``"95X``V@A``-JB0`#:"4``VJ-
+M``)%6P`#:"$``VJ)``-H)0`#:HT``^P```-`+``"N$```KF```/HL``#2J4`
+M`D@8``/P`0`"NS```DD9``/P`@`"NL```FNZ``)E6P`#:J4``TB<``-(H0`"
+MO'L``D`,``)$3``#:)P``VBA``-(M``#2+D``D`,``)$3``#:+0``VBY``-(
+MD``#A.(``Z7G``)!%0`"810``VB0``-HJ``#:)0``VBL``-).``#A>$``F(E
+M``-I.``#:EP``Z#A``.!X0`#@^@``X+H``.%Y0`","H``^@```.!X0`#@^0`
+M`L(Q``/H,``#Z%```C`J``.`Z@`","H``T@(``-((0`#J.T``D$8``-H"``#
+MJ.L``D9H``/`/@`"15,``V@A``-JB0`#:"4``VJ-``/H0``"-+(``^P```-)
+M=``#P6X``^AP``.(2``#P%X``X59``)")0`"8B@``VET``/!0@`#P5,``V@Q
+M``/L```#2`@``KC^``)!&``#:`@``TA4``*\8``"8BP``VA4``-)=@`"O!``
+M`F2L``/!6P`#P6X``^AP``-H,0`",O@``TA4``*\GP`"0BP``VA4``/!2@`#
+M:#$``C14``/L````\=X``/'=``/!_0`#P<X``T@$``/`?@`"0S<``V@$``-(
+M"``#_P```X3H``)@!``#:`@``TF8``.%X@`#P%4``D$5``.$Y0`"8`0``^@P
+M``/!+@`#:#```^C0``(NRP`#^`$``T`-``/_```"L`$``D`&``(5"P`"H.T`
+M`_`%``*[/@`"2[8``ZNP``/T!``#\`T``K````*R`@`#HVH``PNN``*@,``#
+M\`<``PN^``*@/@`#\`0``PN^``*@,@`#\`$``PN^``/T!``#\`$``^BP``-(
+M&0`"LN```D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BY_
+M``(NYP`"M`\``TI```/X`0`"I$```_`&``*D00`#\`0``J1"``/P`@`"H$,`
+M`A4W``+*K@`"L"```J"@``/P00`#Z*```J"K``(57P`#2!D``K+@``)&8@`"
+M9FH``V@9``-)Y0`#_P```D9B``)F:@`#:>4``_0$``(5&```T=\``J#>``(5
+M/@``T>```LW>``/T!``"%.\``$'@``/_```#_P```J"H``(590`"H:@``_!(
+M``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%64``T@9``*RX``"1F(`
+M`F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P``)G<P`#
+M:"4``VJ-``/T!``"%64``T`1``/HP```\?0``KB```)G>``#8!$``\'?``-)
+MF``#A>(``\!5``)!%0`#:9@``^@P``/!+@`#:#```T@(``/_```#A,@``F`$
+M``-H"``#^`,``^P```/_```#_P```&H_``/H````@AD``('<``*P`0`"L1$`
+M`K(0``-J1``"L1```^@@``-J1``#0"0``J#>``/P`P`"NU,``_0```/P00`"
+MNUL``-G\``)`#@`#\$L``T`0``*\!``#W,```X_J``*@W@`#\`$``^CP``/8
+M\``"O`D``\&Q``(O"P`#0"0``_\```*\`@`"0`P``_!+``-`$``"O`0``]S`
+M``*_P``"H-X``_`!``*_@``#V/```XSD``/!L0`"+PL``TF8``.(Y0`"M?T`
+M`\$^``*@W@`#\`$``X,P``/!+@`"8`@``D$5``-H,``#2`@``K1```"!]0`"
+M8`0``V@(``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$``-`
+M+@`"L`$``^@0``/H(``#Z#```VI@``(M:``"L`$``K$"``*R!@`#Z#```VIH
+M```200`"L!,``K$"``.")@`#Z#```VIP``*P(0`"L0(``K($``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P```"L0```K,$``-J?``"
+MOQ@``C91``(V?@`"OP```C'5``-*<``#_P```_\```*RD``#:G```K\3``(V
+M40`"-GX``T`D``/_```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>
+M``/P`0`#Z/```]CP``*\"0`#BQ```B\;``-`)``#_P```KP"``)`#``#\$L`
+M`T`0``*\!``#W,```K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(O&P`#
+M2G```_\```/_```"LH```VIP``*_&``"-E$``C9^``*_```",=4``TIP``/_
+M```#_P```K*0``-J<``"OQ,``C91``(V?@`#0"0``_\```/_```"0`X``_!+
+M``-`$``"O`0``]S```./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+PL`
+M`T`D``/_```"O`(``D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"
+MOX```]CP``.,Y``#P;D``B\+``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID```A]0`#_P```T@(``/_```#P00``V@(``/L```#Z````\``
+M``*QOP`#P2```VA@``*P`0`#Z!```^@@``/H,``#:F```TID``*T@``"0`0`
+M`VID```*.P``$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``/!'P`#:F```TID``*T@```$?P``D`$``*T
+M`P`"8`0``K,0``-J9``",)4``K\(``)/\``#\`$``/(9``/L`````AD``_\`
+M``/_```"I0X``_`!``/L```#Z````((9``-`$@`#_P```_\```)$C@`"H$X`
+M`_`!``#Q]``"OT```J#>``/P`P`":J\``_0```/P00`":[\``V`2``(PQ```
+M>=P``_\```-`*``"H/X``_!!``/L```"H-X``_`%``+`#@`#\$$``L$>``/T
+M```#\$,``L(N``/P00`"PSX``V`H``#QW``#[`````(4```*0```:C\``_\`
+M``)``0`"H`X``_`!``/L```#2)P``TBA``-*2@`"H-X``_!#``-(M``#2+D`
+M`TI.``*\$``"8BX``F9N``)HC``":9P``J#>``/P!0`#:)P``VBA``-J2@`#
+M]````_!#``-HM``#:+D``VI.``/HP```X=L``K`0``*Q```"LA```K,```-B
+M=``"L(```]@!``*P```#W`$``K`2``*Q`@`"LA(``K,"``-B=``"L!```K$2
+M``*R$``"LQ(``V)P``-B1``"L0(``K,"``-B3``#8D@``T`L``/_```#_P``
+M`^@@``/H,``#8"P``^@```/H$```8=L``V`8``-@'``#P8P``\&<``/!K``#
+MP;P``C=S``(U=P``8=L``_\```*P```#W````K!```./P@`"P`\``]@```-`
+M&``"H-X``_!!``-`'``#0"T``_\```/4'@`#U%\``K\```/<\``"O\```XC"
+M``+/^``#V/```\0```/$$0`#Q"(``\0S``*U#P`"1&4``Z5F``*@W@`#\$,`
+M`K4/``)$=0`#I78``Z9"``.$2@`#IU(``X5:``/$1``#Q&8``L`!``+`!``"
+MPB,``L(F``/$%0`#Q#<``]0>``-"=0`#0G(``K\0``*A!``#\$8``J4)``/P
+M!``#P8P``\&0``/!K``#P;```J,)``/P0@`#P:P``\&P``-B<@`#0D8``J$F
+M``/P1@`"I2D``_`$``/!C``#P9(``\&L``/!L@`"HRD``_!"``/!K``#P;(`
+M`V)&``-"3@`"H14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#
+M\$(``\&L``/!L0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!
+MK``#P;,``J,Y``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.';
+M``*@P0`!UN(``T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD`
+M`_\```+)`@`#J9```LM&``.KL``"-W,``^P```-(G``#2*$``J#>``/P0@`#
+M2+0``TBY``/!&``#P5H``XF6``.+M@`"81D``F5;``*@W@`#\`0``VB<``-H
+5H0`#]````_!"``-HM``#:+D``^P`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_me.bin.uu
new file mode 100644
index 0000000..0bf5708
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 CAICOS_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*P`X``<P``$7,``!*S$$B7,Q!
+MH?S43:']?$"``*````#,@`!-@````,Q!(EW,``!%S```2@A,``%\00``?$%`
+M`!U8__\97`/P%6``%<V!H0+-P2)6S@$B7)3```4A)``@SD&A_(```'L(S``!
+MS0&A_,P!H0)\0(``H````,R``$U\0(``?$#``,`J``)\00``?2D`!QR4``$<
+MF``&')P#`!7<``A\0@``?$)``)5```_`+@`$!?`B6'\O``?,,0``R"@`!,S!
+M(6G-`2%JSH$A:RFT``+,`2%LET``#BFT``"```"[R#0`#BFT``*70``)*;0`
+M`,`N``0%\")8?R\`!\PQ``#(*``$@```N\@T``Z70``$?@*``(```+O(-``.
+M*;0`!)=`_TL`````S@$A;<Y!(6[(*``#R#0`#IM```3(/``.A``#0\P``$TI
+M]```ET``!P0PHK:$``#=SH&BM\^!HL2`````S\&BT2GT``&70``'!#"BNH0`
+M`-W.@:*[SX&BQ8````#/P:+2*?0``I=```<$,**^A```W<Z!HK_/@:+&@```
+M`,_!HM,$,*+"A```W<Z!HL//@:+'@````,_!HM3`+@`$?R\`!\PQ``#(+``$
+MP#``!G[S0"/`,``@?VN`((@```!_L\`DS```0H````#,0``??$#``'Q!```9
+M%``]F4``$P04`"Z$``2=!!@`*80``F3('``3!!0`*H0`!)T$&``MS4&BI,@<
+M`!.5P```R!P`$\S!(0#-`2$!S,$A`LT!(0.```2:S8&BI!T8$`"5@``%R!P`
+M$RGD`$"60/__R!P`$\S!(77-`2%VR"``%)8```#((``4%B@``9J```3,``!/
+M@``$FLP``'^```$'S,$A=7Q`P`!\00``S```1<P``$I`U``#S4$B7,T!H?S`
+M'@`!?$(```C,``$&)``!!B@``LX=H?W.7:']F,#_^LZ=H?U\0(``H````,R`
+M`$U\0,``'-```13,``%\04``E0``!GQ!@`#-02%MS8$A;H```3/('``#P"(`
+M!'X6``?,(0``R!P`!'Q"0`"8P``$?$*``(````#-Y0``SD$A:<Z!(6K-P2%K
+M@````,P!(6Q\0,``?$$``'Q!0`!\08``?$'``!BD'^@J:``\EH``"GP"``!\
+M0@``.C```\P``%B;```#0B``!00@`$"```%/?`)``'X"0`":0```"F0``1SL
+M`!":P``*S```3<`J``3(+``@?I*`!\P``$',*0``SL``'H```5_(,``$S0$A
+M;<U!(6[(,``#?Q\`!AST``<3>``!ET``*@>X`62?@````````(```71_&X`.
+M@``!>'\;@`^```%\?QN`#(```8!_&X`-@``!A'\;@!&```&(?QN`$(```8T4
+MI``(FX``&12D``B```&='F0`_YN``!44I``(@``!G1YD`/^;@``1%*0`"(``
+M`9T>9`#_FX``#12D``B```&='F0`_YN```D4I``(@``!G1YD`/^;@``%%*0`
+M"(```9T>9`#_%*0`"!YD`/\J:``\FH#^<13L``A\0T``?$.``'Q#P`"6P``'
+MS```3<]!(6G/@2%JS\$A:X````#,`2%L@````,_U``#,``!9A``$G2IH`#R:
+M@``$R"@`%X````#40`!_EH#_JWX"0`"$``*6P`X``LP``$&```&KS,$P2I0`
+M``#(/``<?$#``'Q!``#`'@`!%20`$L`B``*60``%P"8`!,`G__M])0`&P"8`
+M`'W2@`9^$L`&?24`!WQ!0`!\08``S,$A:9J```S-`2%JS4$A:Y;`_D#-@2%L
+MA``$G<P``'_(,``:EP```,@P`!J````!?$"``(0`!)W,``!_R!0`%<@8`!;-
+M02%KEL#^,LV!(6R```'"S```?WQ`P`!\0(``%)0`$!%4``4<B/__$(@`!7Q`
+MP``4T``0',S__\`:``0%F!NDS!D``,@8``0=F`__?1D`$)D`_A]]C0`0F0#^
+M'<P``%C,``!9A``$G<R!(73(#``7E,#__\P``%F````!?$"``,P``^7(+``@
+MP`X@0`00,``@S")K!!0P`<P``$'0$0``S-4``,[``![(#``)F,```,@,``E\
+M00``?$%``,P``^?,``/HS``#Z<Q``$/,0`!$U$``?X````!\@,``?$#``!C0
+M`>@1*``!E0``$`:H`@F>@````````(```B'`$@@`@``"+\@4`!&```(VR!0`
+M$H```CW,P:*D@``"1ASH`#^```)N?,&`"QS0`#\I*``&*2P`%GZN@`?('``3
+MFH``/004`"Z`````S,&BI,`2"`!\04``?0S`!\`2``@56``#%5P`#'Q"``!]
+MT<`&$B``%'X>0`=^3H`'SH&BI(````#-@:'^R!0`$000(1B50```R!0`$=11
+M``"`````S,&BI,@4`!($$"$&E4```,@4`!+440``@````,S!HJ3,P:*D!!``
+M`<T``!F$``2=S```?\@0`!N9````R!``&X````%\0(``*J``!"JD`!1^)@`'
+M!!0`+I8```@$&``IA``"9,@<`!,$%``JA``$G00,`"W-0:*D!!`A`,@<`!.5
+MP```R!P`$]11``"```2:S,&BI(0`!)T$&``IA``"9,@<`!,$%``JA``$G008
+M`"V$``)DR!P`$X````%\0(``E<```,@<`!/-0:*DS`$A`,P!(0'-@2$"S8$A
+M`\V!HJ2(````S```31V8``%\00``?$%``)F```E\0@``R#P`,A&8`!#('``+
+M._P``9?`___(/``R@``"@,@\`#,1F``0R!P`"CO\``&7P/__R#P`,Q5H`!U]
+M64`'FH``!!'D``I^)@`'S<``9LT!(5C-02%9S@$A6LS!HJ2:@`(0!1``!`0L
+M``$2\``=?7%`!Q+@`!`B(``,S0$A6,U!(5G.`2%:@``$FLS!HJ0$/``%S\&B
+MI,`V``*(````ST$@$'Q`P``4T``=F0``"!34`!R50/UAP"8`!")D(53,)0``
+M@````,@H``2```2:S4``880`!)T<=``!''@``IM```/(#``IA``#0L@4`"N;
+M@``#!!``$(0``U+,P:)0S0&@4(0``P\$&`0`A``$G<P``&/(/``MA``#'<@0
+M`"G('``O'=P``<@D`">5P``)R#0`,<@X`##(/``M4W0`('^W@"='N`50S```
+M8L_Z``":0```R"0`)\@H`",ZJ``"FH#__\@H`"/`,``!R"@`))J```#(*``D
+MSP``6U#8``@4W``8P#X0`"'<@`!]_<`'S8$A@,W!(8'`'@`@42``"!4D`!A^
+M?D`'$S``'GYR0`=]74`'S@$A@LY!(8/-02&$?$"``*````#,@`!-A``$G1QT
+M``$<>``"FT```\@,`"J$``-"R!0`+)N```,$$``0A``#4LS!HF#-`:!@A``#
+M#P08"8"$``2=S```9,@\`"Z$``,=R!``*L@<`"\=W``!R"0`*)7```G(-``Q
+MR#@`,,@\`"Y3=``@?[>`)T>X!53,``!BS_H``)I```#()``HR"@`(SJH``*:
+M@/__R"@`(\@H`"6:@```R"@`)8```M#`,``"!9C``!#<``@4X``8S=D``,@<
+M`"+()``B'=P/_\W9``%^8D`'SED``M@840/8&%$$B````-@840<;^`#PP#8(
+M`)>```/`,`"`B````,`J``3/02%\SP$A?<T!(7XBJ"%_!"0`")I````*9``!
+MS"D``,@@``06.``?FX#_^P0D``B(`````````,@D`"1\00``FD```,@D`"2`
+M```!?$"``,@D`"5\00``FD```,@D`"6````!?$"``(0``T)\0,``?$"``*``
+M``#,@`!-R#P`#I?```/3``/FB`````0\``7/P:*DS`&A](0`!)W,``!'B```
+M`,P``'^$``-2?$#``'Q`@`"@````S(``300\`"+/P:*DA``$G<P``$B(````
+MS```?X0``UU\0,``?$"``*````#,@`!-!#P`(\_!HJ3,`:'SA``$G<P``$F(
+M````S```?X````!\0,``@````'Q`P`#`$@`!?%%`!X````#450``S$``9<@X
+M`"W(/``NP#7@`,`R``1_MX`&?_?`!B.X$``C_!``SX$A5,_!(57,,2%5R"P`
+M!,@<`"7()``D?>7`!YG`__[('``E@````7Q`@`!\0,``?$$``!DH`#"6@``(
+MR"@`)\@D`"B:0```R"0`)YI```#()``HS``#X'Q!0`!\08``%1P`'\S``,?-
+M``#(E<```\`<@`#-P2`0X8,```5<(`#,``!-@````-P?00!\0,``?$$``'Q!
+M0`!\08``S,``R<T``,KA@P``!5R@`(````#<'T$`?$#``'Q!``!\04``?$&`
+M`,S``,O-``#,X8,```5<Z4"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#-
+MS0``SN&#```%7.B`@````-P?00!\0,``?$$``'Q!0`!\08``S,``S\T``-#A
+M@P``!5S``(````#<'T$`?$#``'Q!``!\04``?$&``,S``-'-``#2X8,```5<
+M\`"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#3S0``U.&#```%7//\@```
+M`-P?00#40R``?$"``*````#,@`!-U$.@`'Q`@`"@````S(``3=1#Z4!\0(``
+MH````,R``$W40^B`?$"``*````#,@`!-U$/``'Q`@`"@````S(``3=1#\`!\
+M0(``H````,R``$W40_/\?$"``*````#,@`!-!!R@`,Q#H`!\0,``V!_!`'Q`
+M@`"@````S(``300<P`#,0\``?$#``-@?P0!\0(``H````,R``$U\0,``?$$`
+M`)3```-\04``?$&``,P#\_S,0_/\S$/S_'Q`@`"@````S(``3<`>`!#(#``I
+M4-``"!!4``*```05?16`(,`>`"#(#``J4-``"`A4!``15``"?5&`(,W``&+4
+M6@``?$"``*````#,@`!-?$#``!S0``,1*``!E0``"@:H!!^>@```?$&``(``
+M!"U\0<``@``$,WQ!P`"```0Y?$'``'Q!@`!\0<``%-0`$`54H`"`````S94`
+M`,`B``0%F*``?:&`!\P9``"```0IR!@`!,`B``3-@276(B`EU\PA``"```0I
+MR!@`!,V!(6W-P2%N@``$*<@8``-\0,``@````,Q,`^`<C/__U$T``'Q`@`"@
+M````S(``3<@4`",Q6``$E8#__\@4`"/,``!;S$$A@"!,@`#,P2&!%-``'\Q!
+M(8+,02&#E0#[L,Q!(83(%``CF4#__\@4`".````!?$"``,`6``0A5"%`S%4`
+M`,@8``2`````S``#X'Q`P``8T``XP!8`@)4```/`*@`$?-3`!\S!(7S,02%]
+MS$$A?GQ!@``4_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`F<````G<``',
+M(0``R"0`!!9L`!]!G``%FL#_^LR``$V;P/N*`````(````#,``/@?$#``'Q!
+M```5&``?410`()F```L9'``QS0``8GU-0"?45@``E<#[?<@@`"::````R"``
+M)H````%\0(``X#H``,`F``3,P2%I?24`!\T!(6H+N``"S$$A:YN`__[,02%L
+MF<#],,P``'^````!?$"``,`.`0#,``!!S,$P2L@\`'_,``!_@````,P``'_,
+M``!_B````,P``'\`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01``!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=0`P`'<`,@#H`#0`C``U`&(`.0#J`#H!$@`[`24`/`$]
+M`#T!K0`^`=(`/P#G`$$$10!"!%<`0P1=`$0![0!%`3T`1@($`$<"!`!(`@0`
+M2@*;`$L#9`!,`J<`30+E`$X#,0!/`S<`40-8`%(#/0!3`TT`5`-F`%<#:`!@
+M`X``80.8`&(#;`!C`Z(`9`.L`&4#M@!F`\``9P/*`&@#U`!I`]@`:@0)`&L#
+MW`!L`^``;0/D`&X#Z`!O`^P`<`/D`'$$#P!R`_X`<P/P`'0#]P!U!!H`?00]
+M`'H$>@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`
+M#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/
+.!)8`#P26``\$E@`/!)8`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_pfp.bin.uu
new file mode 100644
index 0000000..004b4fa
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAICOS_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 CAICOS_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-?S$``*ID```4`````S$``*X```U_,0``LS$``+8``
+M`U_,0``N'(P``LR``$"8P``$S$``0(```U_,``!2@``#7\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$+-
+M0`!"T0``0GQ`P`#(&``#R!P``\@@``.5@/_"R"0``Y7`_\#(*``=FH``!,P`
+M`%78``/`S```0,@H`!;`+@`$R#``#1JH`"=^\L`'SL``0,P``$#-@`!`S<``
+M0,X``$"6@``#SD``0-"``%S,@`!`S```0,S``$!\0(``H`````0H``'($``L
+MR`P`*U$0`"!\T,`G?,4`(%44`"#-``!"S4``0M%``$)\0,``R!@``\@<``/(
+M(``#R"0``Y6`_YG(*``#E<#_E\@L`_U^+P`1EP```W[BP`%\`L`&SL.BGLP`
+M`&S-``!MS4``;<@P`!V;```$S```5=@``\#,``!`R"P`%L`R``7(-``-&NP`
+M)W\W``?/``!`T$``0,V``$#-P`!`S@``0,Y``$"6P``#SH``0-"``%S,@`!`
+MS```0,S``$!\0(``H`````0H``'(&``5'9@``7Q"0`"5@`+.?$*``,@<`"#`
+M-\``?$#``'Q!``!\M(`&P#8``QJX`>B7@``'T$`#X(0``V+,``!_R#@#X)N`
+M``#(.`/@F<```,@<`"!\M(`'$-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``
+M0,Z``$#,P`!`X#H``)>`_U3-``!`?$#``(```*)\00``'(P``IC```G($``<
+MF0``!,@<``:$``-ES```4L@8`!6```".'9@``L@0`!Z9`/_\R!P`"(0``V7,
+M``!4R!@`%8```(X=F``"'(P``L@0`!V8P``.R!0`29D```3('``'A``#9<P`
+M`%/(&``5E,```QB4`>@%5``&(!```7T5``.```".?9&`!IE`__C('``'S<``
+M0,P``$"```#+S```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/T
+MS0`#]LT``_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``8```.[8
+M``1`V``#0,P``$#,@`!`U$``0'Q`@`"@````!"@``=@``\"```#[S```0(``
+M`/K8``1`V``#0,P``$#(#``IR!``*LR``$#,0`!`41``('S0P"<04``"?0T`
+M(%44`"#-``!#S4``0]!``$/,``!`?$"``*`````$*``!V``#P,P``$#,@`!`
+MU$``0'Q`@`"@````!"@``1R,``+($``=F,``$<@4`$F9```$R!P`!X0``V7,
+M``!3R`P`+\R``$#,0`!`S$``0,Q``$!\Q,``S,``0-1``$!\0(``H`````0H
+M``&90/_UR!P`!\W``$#,``!`@``!&LP``&Y\0,``R!``1YD```O(%`!$F4``
+M!,@8``G-@`!`S```0(```43,@`!`?$#``,@0`$>5`/_WR!0`19E```3(&``*
+MS8``0,P``$"```%$V``(0'Q`P`#($`!'F0#__`````#,@`!`S,``0-1``$!\
+M0(``H`````0H``'($`!&V``'0,T``$"$``%;S0``0,@,`$.4P``*R!0`2(``
+M`50$$``#R!``1M@`!\#-``!`A``!6\T``$#(%`!(G4```,P``&K(*``6'J@`
+M`9J```/`*0`!B````,`L`5;.@`!<V``(P,[``$"(````S```0!R,``+($``>
+ME,``",@4`!R9```*R!P`"(0``V7,``!4@``!=<R``$"90``$R!P`!H0``V7,
+M``!2S(``0(````#40`!`S$``)\Q``"B```-?S```:\`R``/`-___@``!@'RP
+M@`=\0T``R"``*,@<`"?(&``FST.BGGQ!0`!2(``@?>'`)WU8P`-\W,`@5-``
+M((```97,@`!`?$&``,R``$"```&2S8``0,`9___,@`!`S8.BGGQ`P`!\00``
+M?$%``,S#H?K-`Z'YS4.BG<S``$#-``!`S4``0,Q``$!\0(``H`````0H``%\
+M0,``'-```<S#HI^5```#T$``)M"``";,@`!`@````,S``$!\0,``S(``0,S#
+MHJ*`````S,``0'Q`P``4U``?S(``0)5```-\00``S,``6148`!_,P`!`E8``
+M`\T``$#-``!:@``#7\P``'_((``??$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)
+MS2``0<U@`$'-H`!!%1``"!%4`!A]4\`'S\``+P8@``'.``!8@``#7\P``'_(
+M(``?R@P`%Y3```5\00``V"`"QH```;_.(`!&S```2(```=4`````R"``'WQ!
+M@``*(``!RA0`&LH8`!=]68`'E8``!<X``%C,H`!&@````,U@`$;,H`!$@```
+M`,U@`$2```-?S$``:L@,`_J8P``+T$`#^L@8`$+('`!#R!``'<@4`!P1$``!
+MF8#_6WT5``>9P/]C`````-```_J`````?$#``,R``$"`````U$``0'Q`P`!\
+M00``?$.``'Q#P``$'``"SX``0L_``$+-P`!"!!P`!,S``$+-``!"S<``0@0<
+M```$(``!?`)``,@4``/(&``#49@`('U90"?(*``#R"P``\@P``/(-``#4NP`
+M('ZN@"=3=``@?S<`)W\K0"%^=D`@5J@`/U<P`#]^LH`&?BH`!IG`__()W``!
+MEH#_X5/T`"!_>T`G?65`(%58`"#,``!;S78``,VV``#((`!!F@```,@@`$&`
+M```!?$"``'Q`P`!\00``S,`#_LT``__,P`!"S0``0A44`!\9&`#P)UP``7UV
+M``:9@``%?5Y`!LP``$*```-?S```3168``$5+``(F8``,1[L``&6```$%3``
+M#(```U_,``!"!!0`!,U``$(?,``!("@``00X``0$/```R!0``\@8``/('``#
+MR"```WU=0`U]H<`-?5U`!Q80`!\5G``??1T`!GT70`9^DH`&FT``$@NX``2;
+MP/_R"_P``<@,`_Z:@``)R!`#_YL``0;,``!-!!0`!,S``$+-``!"@``"0\U`
+M`$*6P`#_S```38```U_,``!.FL```\P``$W,``!.EX#]F>.#``"`````W`,!
+M_Y9```3,``!.@``#7\P``$+2``!"R`@``\@,``/($``#R!0``\@8``/('``#
+MR"0``\@H``,5_``?%K``'W_SP`84\``??_/`!A5P`!]_\\`&?8B``9?```U]
+MS,`!?E$``7Z50`%\D(`,?-3`#)K```-\CT`&)+0``9M``-;,``!-@``#7\P`
+M`$[(#`/^R!`#_\S``$*```)OS0``0GQ`P`!\00``?$+``'Q#``#`.P`??$-`
+M`'^W@`;`/A``EX#]9GT]``=_/P`'&10`.\P``%N50``3R!0`0#%8``*5@/__
+MR!0`0,P``&,A'(``S,$AA<W!(885%``?SL$AA\\!(8B50/U5ST$AB<@4`$"9
+M0/__R!0`0(````%\0(``S(``0,S``$#-``!`SL``0,\``$"`````ST``0-"`
+M`^#,@`!`A``#8LQ``$#(#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``"
+MS!30`!^9`/TZT$`#X(0``V+,``!_@``"OL@,`^#,@`!`S,``0(@```#40`!`
+MS(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`-___T``#^]```_S0
+M``/Z@````,]``_U\0,``%-P`'9G```?,@`!`&-P`/)G``'S,P`!`@``#7\P`
+M`&H8V``\S8``9LP``&J```-?S,``0'Q`P`!04``@A``#8LP``%U\T,`GR"``
+M'\C6``"90``(?$.``..#``#/H`!/A``#8LP``%Z`````U$``?X```U_,``!>
+MA``#8LP``%W((``??$#``,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\
+M\X`&XX,``,^@`$^$``-BS```7H````#40`!_@``#7\P``%Z$``-B?$#``!3<
+M``B5P``9'-P`$'Q!``"9P``$4%0`((```QW)'0``?14`)\D>``!\0@``?$)`
+M`'Q!@`!]Y<`&?>*`$9J`_-Y!K``%FL````KL``$<W``0F<``!`````"```,@
+MR1T``(```R#)'@``S(``0,S``$"`````U$``0-@``T#,``!`S(``0-1``$!\
+M0(``H`````0H``'8``/`S```0,R``$#40`!`?$"``*`````$*``!?$#``!S0
+M``8I$``&F0``!L@4`!R90``$S```4H0``V7('``&S(``0,S``$"`````U$``
+M0'Q`P`!\00``%1@`'\T``%N9@``$410`((````#430``?4U`)QD<`#'45@``
+ME<#\J<@@`$&:````R"``08````%\0(``@````-1``'_,``!_@````,P``'_,
+M``!_B````,P``'_-P`!`B````,P``$``````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,Q``0#.``%`;L`!@#M``<`^0`(`0L`"0#T``H`ZP`+`/<`#`$K
+M``T!-0`.`4D`#P%3`!`#70`1``H`$@`8`!,`(``6`"(`)``Q`"4`60`F`7<`
+M%P'7`!@!Y0`:`><`(@+L`","_0`G`8P`'P'Y`"`"*0`H`:X`*0%[`"H!H``K
+M`9``+P&I`#(!S0`T`S\`-0%_`#D!]@`\`Q$`/P&[`$$"D@!"`KD`0P+#`$0"
+MT`!*`MX`50,S`%8#.@!@`(P`80"Q`&(`V0!C`,,`9`##`&4`PP!F`,,`9P##
+M`&@`Y@!I`.\`:@$_`&L!#0!L`0T`;0$-`&X!#0!O`0T`<`$2`',`^P!T`/L`
+M=0%F`'L#3`````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_mc.bin.uu
new file mode 100644
index 0000000..e2caf01
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_mc.bin.uu
@@ -0,0 +1,540 @@
+begin 644 CAYMAN_mc.bin
+M``/HX``"O@$```(4``/_```#_P```J`.``'`'``#Z````^@0``/H(``#Z#``
+M`V`@``-@*``",SX``K#_``*Q_P`"LO\``K/_``-A.``#26P``_\```.O"@`"
+MM`0``F_T``#Z.P`"M`\``D\4``#Z%P`#0"0``K1```*U#P`#2J8``D1!``/P
+M`@`"294``VJF``(M;@`#2$(``TG4```R0P``(A@``#H5``*U$```FD,``D53
+M``/P"``"H'X``_!&``*@8P`#\$0``/(/``(TL``#]````<`D``/H````@@\`
+M`T`D``*T0``"M?```TJF``)$00`#\`(``FF5``-JI@`#0````_\```/X`0`#
+MQ$```\11``+&10`"`````T`0``/_```#_P```^@@``/H,``#8!```_@#``(S
+M.``",G0``T@(``*TGP`"0`0``V@(``-((0`"L\$``D=S``-H(0`#:HD``T@E
+M``*SP0`"1W,``V@E``-JC0`#2,```TC&``"",0``BC```,(O``#*+@`#Z!``
+M`^B0``-HP``#:,8``TJD``/H0``#_P```D(D``-JI``#2````T@%``*[/P`"
+MO+\``K_O``"2,P``BC0``((X``"Z-@``JCH``D$;``*[^P`"0BL``D`,``-H
+M```"15\``V@%``-($``#2=T``KOQ``*\`@``BC<``*HY``)!&P`"81P``V@0
+M``)%6P`"95P``VG=``-`#0`#_P```_\```.A3```B@T``K,"``)#-``#HS``
+M`)H,``*S!``"0S0``Z,R``":"P`"L`@``()!``*P"0``@D(``T@I``-)<``"
+MOP<``D`/``.````#``X``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H
+M+0`#P00``\$5``-IZ``#:>P``^@```/HT``",!4``VCD``/!W@`",!4``VD$
+M``-`+``#_P```K0"``)$!```HA8``TG6``*U$``"1%L``Z1&``"B&``"H$X`
+M`_`#``(T6P`#]````<#%``/T```!TTD``T`.``#R0``#Z/```Z"V``-)U0``
+M^A$``K$/``)"%P`"I2```_`!``#Z0``"0QL``J4C``/P`0``\A$``T````-`
+M+@`"MA```K0,```J0``"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!
+M``/HP```XA```T`(``*T````>A$``J`D``/P00`"L@@``J#^``/P00`"L@0`
+M`K0_``)")```DB@``TJ4``/_```#8&P``T````/_```"M$```D0$``/P`P`#
+MZ````((_``(B^@`#0````_\```*T0``"1!0``_`"``#R/P`"(OH``T````/_
+M```"M$```D04``/P`0`"+C0``TJ4``/_```#8'```T````/_```"M`(``D0D
+M``/P`P`#Z````((_``(C,0`#0````_\```*T`@`"1#0``_`"``#R/P`"(S$`
+M`TJ4``/_```#830``C,X``-````#_P```_\```)$#@`#\`,``^@```""/P`"
+M)%H``C,X``-````#_P```_\```)$'@`#\`(``/(_``(D6@`"+F\``TJ4``/_
+M```#8'0``K````""*P`#0````_\```*T`@`"1$```_`#``/H````@C\``B88
+M``-*E``#_P```V!X``-````#_P```K0$``)$0``#\`,``^@```""/P`"*(P`
+M`TJ4``/_```#8'P``T````/_```"M!```D1```/P#``#Z````((_``(I4```
+M`@T``_\```/_```"I`X``_`$``#R#@`"*5```^@```""#@`#2I0``_\```-@
+MK``#0````_\```*T(``"1$```_`#``/H````@C\``BM@``-*E``#_P```V"P
+M``/H````@C\``K#_``*Q_P`#P2```VA@``-H:``#0````_\```*T$``"1$``
+M`_!"``/T```"`8\``T`-``-`)@`"L4```K(0``*S"``"010``Z$:``)")``#
+MHB0``F(A``)#.``#HS```F(C``"2*P`"I!X``_`)``-)/0`"LH```\`B``)$
+M0@`"*5```TD]``/_```"LH```F1"```"$``#_P```K0!``)$!``#\`0``^@`
+M``""/P`#P?X``BP4```"$``#_P```K0"``)$!``#\`0``^@```""/P`#Z/``
+M`BP4``-````#_P```_\```)$+@`#\`,``^@```""/P`"-9X``T````/_```"
+MM!```D0D``/P`P`#Z````((_``(VOP`#^`,``TJ4``/_```#8+0``K````""
+M*P`#0````_\```*T`@`"1$$``_`"``#R/P`")A@``TJ4``/_```#8+@``T``
+M``/_```"M`0``D1!``/P`@``\C\``BB,``-*E``#_P```V"\``-````#_P``
+M`K00``)$00`#\`L``/(_``(I4````@T``_\```/_```"I`X``_`$``#R#@`"
+M*5```^@```""#@`#2I0``_\```-@[``#0````_\```*T(``"1$$``_`"``#R
+M/P`"*V```TJ4``/_```#8/```/(_``*P_P`"L?\``\$@``-H8``#:&@``T``
+M``/_```"M!```D1!``/P0@`#]````@(.``-`#0`#0"8``K%```*R$``"LP@`
+M`D$4``.A&@`"0B0``Z(D``)B(0`"0S@``Z,P``)B(P``DBL``J0>``/P"0`#
+M23T``K*```/`(@`"1$(``BE0``-)/0`#_P```K*```)D0@```A```_\```*T
+M!``"1`0``_`#``#R/P`#P?X``BP4```"$``#_P```K0(``)$!``#\`,``/(_
+M``/H\``"+!0``T````/_```#_P```D0^``/P`@``\C\``C6>``-````#_P``
+M`K00``)$-``#\`(``/(_``(VOP`#2I0``_\```-@]``#^`,```(8``/_```#
+M_P```J`.``/P0@`#]````@)L``-`+``#_P```K0@``)`0``"H`0``_!(``/H
+M````@C\``C'4``(R&0``\C\``C'4``(R&0`",K```T````/_```"M`@``D0$
+M``/P#``#2`@``_\```*T0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#``
+M`\$N``-H,``",L0``^@```/H$``#Z#```K(#``-H,``#0````_\```*U"``"
+M114``_`!``(T_@`#2I0``_\```-@^````D```_\```/_```"H0X``_`"``/H
+M````@A0``BYO``-(```#2`4```HT```".```$C,``"HZ```Z-@`#_P```V@`
+M``-H!0`#2!```TG=```*-P``*CD``_\```-H$``#:=T``TEQ``*R`0`#Z#``
+M`\$&``/!%P`#:#```TEL``*U%@`"H%$``<*?``*PSP`"L04``K(!``*S```#
+M:#```C+$``*PM``#:#```C+$``*PO``#:#```C+$``*PN``#:#```C+$``*P
+MRP`#:#```C+$``*PC``#:#```C+$``*PT0`#:#```C+$``/H```#Z!```K(#
+M``*S```#:#````(8``/_```#_P```J`.``/P0@`#]````<`````!]``#0!(`
+M`T`5```*&P`"H`X``_`"``/T```!PL\``L$>``"*&P`":[H``F5;``+&;@`#
+M\$$``L=^``-@%0`"L@\``D1"``*E%``#\`<``^B@``/HL``#8!(``^@```"!
+M]``#]````<!-``-`+``#_P```K0@``)`0``"H`0``_!"``/T```!PN0``^@`
+M``""/P`",=0``C(9``#R/P`",=0``C(9``(RL``#0!```_\```/_```#H`8`
+M`X`&``/!\``"+D$``\'P``(N00`#P?```BY!``/!\``"+D$``T`@``/_```#
+M_P```L`.``/P10`"P1X``_!#``+"+@`#\$$``L,^``-@(``",S@``TE(``*T
+M/P`"M8```D,T``)C-0`#:4@``D,T``-I2``#]````<````-`!```:C\``^B`
+M``/HD``#Z*```^BP``*U$``"1!4``_`&``*@W@`#\`,``V2J``/T```#\$$`
+M`V3J``/X`0`"M0@``D0%``(#'```8?@``J#>``/P`P`#Z$```_0```/P00`#
+MA.H``]A```/<P```>?<``_@#``/4G@`#^P```P_^``(#&``#^`$``X7D``)$
+M%0`"`R\``"'Y``*@W@`#\`,``&'Q``/T```#\$$``&'P``*_"``#W$```]C`
+M``/X`P`#U)X``_L```,/_@`"`RL``_@#``/L`````A0```I```!J/P`#_P``
+M`D`!``*@#@`#\`$``^P```-).``"H-X``_!!``-*7``"N/X``D(H``*@W@`#
+M\`,``VDX``/T```#\$$``VI<``-)T``"M`0``F$4``*R`0`"LQ(``J#>``/P
+M00`"LQ$``V@P``-)<0`"N.\``KD$``/!!@`"87D``D,X``-H,``#2`D``KC]
+M``)$2``#:`D``BY%``-)H``"M!$``\$D``*Q#P`#::```TI$``*T_@`"81X`
+M`VI$``)!%``#:D0``J#>``/P`P`#0F$``_0```/P00`#0ET``_\```/_```#
+MZ&```VFE``-H:P`"N@P``KC```/<@0`#V*$``K#X``*Q!P`#Z"```^@P``/^
+M```#U!\``VAK``/H\``"(_\``B/B``(D'``"H?X``_!!``-B>@`#0G@``_\`
+M``/_```"H(```<.3``*@D0`!PY,``J"B``'#DP`"H+,``<.3``+/_@`"O`P`
+M`J'\``/P0@`#]````<-]``#Z!``#Z/```B/B``(C_P`")!P``T)X``/_```#
+M_P```J"```'#J0`"H)$``<.I``*@H@`!PZD``J"S``'#J0`"S_X``KP,``*A
+M_``#\$(``_0```'#E@``8@0``/H#``/_```"I<\``<.Y``*E_``!P[0``^CP
+M``/HP``#]````<.\``,,SP`#K,```^CP``/T```!P[P``P_\``.O\``#Z,``
+M`B/_``/!_``"(^(``TDX``*@W@`#\$$``TI<``/_```"8BX``J#>``/P`P`#
+M:3@``_0```/P00`#:EP``TG0``*T^P`"010``K(!``*S$@`"H-X``_!!``*S
+M$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@``V@P``-("0`"N/T``D1(
+M``-H"0`"L!@``B1```/L```#1+D``J#>``/P00`#1/D``\$/``/!'P`#P2\`
+M`\$_``/!3P`#P5\``J#>``/P!0`#9+```V2T``-DN0`#]````_!#``-D\``#
+M9/0``V3Y``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P```-$
+MN0`"H-X``_!!``-$^0`#P0\``\$?``/!+P`#P3\``\%O``/!?P`"H-X``_`%
+M``-DK``#9+P``V2Y``/T```#\$,``V3L``-D_``#9/D``TC(``*T\P`"M00`
+M`D`$``)@!0`#:,@``D`$``-HR``#[````K`0``(D0``",L0``C+$``(RQ``"
+M,L0``C+$``-*'``")$P``\&,``-*(``")$P``XS&``)HC``#2B0``B1,``/!
+MG``#2B@``B1,``.,Q@`":9P``THL``(D3``#P:P``THP``(D3``#C,8``FJL
+M``-*-``")$P``\&\``-*.``")$P``XS&``)KO``#[````VAK``*Y"``"N,``
+M`]R```/8D``#Z!```^@@``/H,``#_@```]0>``-H:P`#[````^C```.'/``#
+MIW8``X8L``.F:``#A1P``Z5:``.$#``#I$P``FS'``)LQ@`";,4``FS$``/L
+M```#0"0``_\```/_```#H`8``J$.``/P`0``@@<``TFD``-)H0``:C\``XOJ
+M``/`JP`"1:4``J#>``/P`P`"0Z,``_0```/P00`"8[,``VFD``-IH0`"LO\`
+M`K'_``*P?P`#:&```^@```/H(``#Z#```J#>``/P`P``"@D``_0```/P00``
+M"@@``KC```-H:P`#V````]R```/4'@`"OP(``BY!``.`X```@@0``((#``/H
+M````@@(``((!``#R```#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``F(D
+M``-H5``#29@``XCE``/!/@`"H-X``_`!``.#,``#P2X``F`(``-H,``#274`
+M`XCF``)@:``#P1<``\$N``/!/@`"H-X``_`!``.#,``#:#```TA4``*@W@`#
+M\`,``X3H``/T```#\$$``X3J``/`1``"0B0``VA4``*_`@`"+D$```(8``/_
+M```#_P```J`.``/P`@`#]````@36``(P)P`#Z'```X3F``)&2P`"H&0``_!/
+M``-)T@`#Z&```XJR``.JJ@`#A*8``F1*``/!5``"H-X``_`#``-HY0`#]```
+M`_!!``-I!0`#]````<6!``*_"``"3_D``Z_T``.+L@`#J[P``B6E``/T```"
+M!8$``T`,``/_```"OP@``D_P``/P0@`#]````<3S``*_```"NP$``B6E```"
+M$0`#_P```_\```*@#@`#\$(``_0```'%@0`"L0(``K`1``+$0``"Q5```J#>
+M``/P`P`#:.4``_0```/P00`#:04``P$>``($Z```\@(``/(!``*@W@`#\`,`
+M`'H&``/T```#\$$``'H%``.-X@`#W-```]CP``.)Y@`":9X``/'R``!"!P`#
+MZ-```X_@``/!J``#C.T``.'V``#B/@`"+Y```K<!``!"!P`#Z*```-'R``*@
+M?@`#\`$``ZB```,/WP`#P=D``\&H``.,[0``X?8``.(^``(OD``"+]$``\$$
+M``/!)@`#8G```K\!``-`$0`#B.```J#^``/P!``"1$@``_`"``/T```"!6<`
+M`K<!``!"!P`#_P```J!^``/P`0`#J(```^C0``./X``#P:@``XSM``#A]@``
+MXCX``B^0``(OT0`#0G```XSK``.,Z@`#Z/```LA```.H@```*A8``LIB``.J
+MH``"IEX``@5$``!J/P``\A8``\%8``/!>@`#8G$``_0```($_@`"H5X``_`.
+M``!J/P`#P9$``\&S``*@W@`#\`,``V$N``/T```#\$$``V$R``+`@0`#J```
+M`L*C``.J(``#A5```*H6``.!X``#`(0``_`D``*AA``#\`$``L1!``,$3@`#
+MP50``P*F``/P)``"H:8``_`!``+&80`#!FX``\%V``/47@`"8`(``@56``!J
+M/P`"OP(``BY!``-)<0`#@>0``\$&``.B;``"H"X``@6!``)A<0`#P2X``\$^
+M``*@W@`#\`$``X,P``.&8``#\$<``V@P``./[0`"+D$``X_M``(N00`#C^T`
+M`BY!``./[0`"+D$``TEU``/!+@`#P08``\$7``/!/@`"H-X``_`!``.#,``#
+M:#```TF8``/_```#P3X``J#>``/P`0`#@S```\$N``-H,```"@\```'T``/_
+M```"01X``_`!``/L```"I0X``_!(``-`$0`"H-X``_`#``)F;@`#]````_!!
+M``)G?@`#8!$``^@```"!]``#[````C+$``-*0```0@```$H$``!2`P`"O#,`
+M`D0,``)%'``"9$4``D8L``)'/``"9F<``F1&``*A3@`#\`$``K0!``*@C@`#
+M\`4``J1)``/P0P`"I$L``_!!``#R`@``H@0``KS,``)$#``"11P``D8L``)'
+M/``"9$4``F1&``)D1P`"H4X``_`!``*T`0`"H(X``_`%``*D2@`#\$,``J1+
+M``/P00``\@$``*(#``/H0```H@```T,I``*@W@`#\$$``T-I```"`@``$@$`
+M`K$/``*S!P`"I?X``@7[``*@#@`#\`8``KP/``*D00`#\`$``KP)``/!3``#
+MP5P``J`N``/P!@`"O`\``J1A``/P`0`"O`D``\%L``/!?``"H-X``_`#``-C
+M*0`#]````_!!``-C:0`"3`(``J#.``/P!@`"S_X``KP)``*E_``#\`(``_0`
+M``'%I0`#2.4``J#>``/P00`#204``K@1``*@#@`#\`$``L1(``))00`"I),`
+M`_`!``#R`@`"H"X``_`!``+%6``"25$``J23``/P`0``\@$``J#>``/P`P`#
+M:.4``_0```/P00`#:04``D`"``*@#@`"!:4``^P```!J/P`#Z````C`!``-)
+MF``"N`\``K7U``*S`0`"H-X``_`!``.#,``#P2X``F`(``)!%0`#:#```K\`
+M``(N00``\?\``^@```"!_@`#0`P``T`M``*X$``"N0@``DH8``.JI@`"2TD`
+M`ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!``*S!@`#0"T```H1``*P0``"
+M0$```_!!``/H,``"01X``_`!``/H,```F?T``BY%``*\`0`"H-X``_`)``-(
+M(0`#C,8``X9F``.F9@`"9FP``V@A``-JB0`#]````_!'``-()0`#C,8``X9F
+M``.F9@`"9FP``V@E``-JC0`",9L``K\#``(QH0`#2`@``X3J``"!]0`"8`0`
+M`V@(``*_9``"+D$``&H_``/_```#_P```J#>``/P`P`"NP```_0```/P00`"
+MNT```-GO``/!#@`#P1X``X$6``)A'@`#@N8``VI$``/!'@`#@18``^@@``-J
+M1``#Z````\````/!$``"LOT``VA@``-*8``"O_<``K$3``)`#P`"8`X``VI@
+M```R#```.@L``KP(``*__@`#AFH``F(F``*D?@`#\`$``K,$``)`#P`"8`P`
+M`VI@``./X0`"+D$``VAK``/_```#_@```&(]``!:/``#_P```]C!``/<L0`#
+MC^,``BY!``/0'P`#C.\``X_D``)O_@`"0`$``D(C``)``@`"3,```_L!``/0
+M'P`##_X``@:=``*@W@`#\`,``T@A``/T```#\$$``T@E``/`S``"!LD``XSF
+M``+&;``#\$$``L=^``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`J5^``/P`@`#]````<9L``-`$0`"L`@``/'T``*@W@`#\`,``F9@``/T```#
+M\$$``F=P``-@$0`#]````@AZ``.`X0`#@08``F$>``."YP`#:D0``X$&``/H
+M(``#:D0``C&;``-`+```6BL``K0$``/H\``"1$```_`!``*_`0`"I+X``_`!
+M``*_!``",:$``/(G``#R)0`"L/\``K&_``/!(``#:&```K`!``/H$``#Z"``
+M`^@P``-J8```"CL``!(,```:"P`"L`(``J#>``/P00`"L`0``X(J``*D/@`#
+M\`$``K,$``.!%@`"8`$``K$S``-J8``#0`H``K`!``*Q`@`"L@```K,!``*@
+M*P`#\`(``^@@``/!.P`#:F@``\$.```20@`"0`D``_`!``/H(``"L!,``K$"
+M``.")@`#Z#```VIP``-`+0``8A$``!(H``*_0``"3T\``_`#``*@S@`#\`$`
+M`K((``*P(0`"L0(``K,!``-J=```"BL``K`!``/_```"I!X``_`%``*Q!``"
+ML@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q
+M`@`"LP0``VI\```!_@`#_P```_\```+`#@``@?X``C&6```")P`#0`H``T`-
+M``*@#@`#\`4``K`!``)`!0`#@`8``_0$``/P`P`"L`0``D`)``.``@`"L0,`
+M`F@!```"*P`#_P```_\```*D#@`#\`L``!(H``*P(P`"L0,``K,!``-J=``#
+M2GP``_\```*P`0`"L00``K,$``-J?``#2F0``K2````1[P`"0`0``F`(``.B
+M(@`"LP$``VID``(P6P`",&@```'_``/_```#_P```J`.``/P3@`#0"P``KP$
+M``/<P``#C^H``J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(NT0`#Z/``
+M`/G_```!_@`#_P```_\```+`#@``@?X``T`E```:$``"L@0``D(@``*@W@`#
+M\$$``Z,R``*Y`@`"29,``F(I``*Y@``"294``F(I``*YA@`#Z(```J`I``/P
+M00`#P8X``,':```)_0`#0"X``_\```*@`0`"!YD``K`!``)!"``#\`4```)`
+M``/_```#_P```J`.``('F0`#2G0``'HH``/_```#_P```\$O``-J=``",98`
+M``(G``-`"@`#0`T``J`.``/P!0`"L`0``D`%``.``@`#]`0``_`"``*P$``"
+M0`D``'G:``*Q0P`#_P```J#^``/P00`"L2,``F@!```"*P`#_P```_\```*@
+M#@`"!\L``!(H``*P0P`"L00``K,!``-J=``#2GP``_\```*P`0`"L04``K,$
+M``-J?``#2F0``K2````1[P`"0`0``F`(``*X(``"8`@``KB_``)`"``#HB(`
+M`\$^``-J9``#]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``/!/@`#
+M:F0``C!;``(P:```0A```K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''
+M[``#0`X``K`0``/_```"00D``J`0``('[````B<``_\```/_```"P`X``((G
+M``*Q`@`"I`$``@<L``!![P```?D``_\```/_```#V(```]P```!Z0@`"L`$`
+M`]P!``*P```#V`$``$G:``/_```#_P```J">``/P1@`#Z/```K$D``+(@0`#
+MV(```L`!``/8@0`",%(```'^``/_```#_P```L`.``"!_@``>=H``C&6``*@
+M_@`#\$4``K`/``/!$``#P2```\$P``-J@``#0`H``K!```/_```"0`D``Z`"
+M``*Q`P`":`$```(K``/_```#_P```J0.``/P"P``$B@``K!#``*Q!0`"LP$`
+M`VIT``-*?``#_P```K`!``*Q!@`"LP0``VI\``-*9``"M(```!'O``)`!``"
+M8`@``Z(B``*S`0`#:F0``C!;``(P:``#0"4``$(0``*P(``"0`4``_!(``*P
+M`@`"H-X``_!!``.``@`"0`@``_`"``/T```!R%P``!'^``*P@``"LP,``J`C
+M``/P0P`"0`4``_`!``(Q7``#0"X``_\```*P"``"00@``J`0``((7``"L(``
+M`D$(``/P!0```D```_\```/_```"H`X``@A<```")0`#_P```_\```/H$```
+MBB4``J0.``(';@```>\``$'Y``/_```#_P```]@```/<@```>D(``K````/8
+M`0`"L`$``]P!``-`#0`"O2```_\```)-U0`"IMX``_`#``(N\0`#]`0``_`*
+M``*P?P`"L?\``K+_``-H8``#:&L``!'E``*SP``#Z-```V!,``(O+``",9L`
+M`C&6```A]0`#_P```T@(``/_```#P00``V@(``/L```#Z````^@0``*@W@`#
+M\`,``VD<``/T!``#\`$``VDT``/L````:C\``_\```/_```"H-X``_`#``*[
+M8@`#]````_!!``*[:``#_P```_\```#9_``",EH``^@```(P`0`"NP(``-H^
+M``-(`0`"L+\``D1```-H`0`#29@``K0/``*U_0`"8`0``D$5``/!+@`#P3X`
+M`J#>``/P`0`#@S```V@P``-("``"M$```('U``)@!``#:`@``^@```*Q8``#
+MZ"```^@P``-IH``#Z````K$0``/H(``#Z#```VI$``*P`0`#Z!```^@@``/H
+M,``#:F```K\"``(QH0`#Z````\````/!$``"LOT``VA@```*.P``$@P``!H+
+M``*P"@`"H-X``_!!``*P#``#@18``F`!``."*@`"L0P``F(A``*D/@`#\`$`
+M`K,$``*Q%@`#:F```X_A``(N00`#:&L``_\```/^```",<H``TI@```R#```
+M.@L``K3V``*U`P`#AFH``F(F``*D?@`#\`$``K<$``)C-P`#`14``D`$``-J
+M8``#0`H``K`!``*Q`@`"LA(``^@P``-J:``"L(```!)"``)`"``#\`$``^@@
+M``*P$P`"L0(``X(F``/H,``#:G```K`A``*Q`@`"L@$``K,!``-J=``"L`$`
+M`K$"``*R#P`"LP$``VIX``-*?``#_P```K`"``*Q`@`"LP0``VI\``*P_P`"
+ML;\``\$@``-H8``#Z'```C&6``-*9``"M(```!'\``)`!``"M`,``F`$``*S
+M$``#:F0``C!;``-*9``"M`@``D1```)G=``"I7X``@E'``/H```",`$``J#>
+M``/P`P`#2"(``_0```/P00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X`
+M`_`$``-H(@`#:HH``_0```/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!
+MR1$``T`2``#Q]``"OP0``J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T
+M```!R4<``C&;``(QE@``(?4``_\```-("``#_P```\$$``-H"``#[````&H_
+M``#Q_P`#Z````((3``-`"``#0"T``KA```*Y"``"2@@``ZJJ``)+20`#J[0`
+M`K,$``)OJP`#\$$``K,"``)/JP`#\`$``K,&``-`+0``"A$``K!```)`0``#
+M\$$``^@P``)!'@`#\`$``^@P``":$@``(?0``^A0``/_````HAD``*GT``!J
+M/P`#_P```_\```*@W@`#\`,``%GQ``/T```#\$,``%GP``/_```#_P```-GO
+M``-(```#A.H``\!$``/_```"0`0``V@```-(!``#P'X``_\```/_```"0S<`
+M`V@$``-`+```6BL``K0$``/H\``"1$```_`!``*_`0`"2[X``J"^``/P`P`"
+M,,,``_0```')F0`"O\L``C,-``#R)@``\B4``K#_``*QOP`#P2```VA@``(Q
+MFP``"CL``!(,```:"P`"L`(``J#>``/P00`"L`0``X$6``)@`0`#0!4``X(J
+M``*Q@``"8B$``J0^``/P`0`"LP0``K;P``)$1@`"L0@``F$4``-J8``#0`H`
+M`K`!``*Q`@`"L@```K,!``*@*P`#\`(``^@@``/!.P`#:F@``K`!```200`"
+M0`D``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``-`+0``8A$``!(H``*_
+M0``"3T\``_`#``*@S@`#\`$``K((``*P(0`"L0(``K,!``-J=```"BL``K`!
+M``/_```"01```J0>``/P!0`"L00``K(```*S`@`#]`0``_`#``*Q`@`"L@\`
+M`K,!``-J>``#2GP``_\```*P`0`"L0(``K,$``-J?```"BL``_\```/_```"
+M01X``J0>``(*-````A,``_\```/_```"P`X``((3``(QE@```B8``T`*``-`
+M#0`"H`X``_`%``*P`@`"0`4``X`$``/T!``#\`,``K`(``)`"0`#@````K$#
+M``)H`0```BL``_\```/_```"0`X``J0.``/P"P``$B@``K`C``*Q`P`"LP$`
+M`VIT``-*?``#_P```K`!``*Q!``"LP0``VI\``-*9``"M(```!'O``)`!``"
+M8`@``Z(B``*S`0`#:F0``C!;``(P:````?\``_\```/_```"H`X``_!.``-`
+M+``"O`0``]S```*_P``"H-X``_`!``*_@``#V/```XSD``*_/P`"2Q\``B[1
+M``/H\```^?\```(3``/_```#_P```L`.``""$P``6BL``'HE``*X"``"2KX`
+M`J"N``'*6``#JK```DJN``/P0P`"+2X``_0```'*5``#2G```KJ(``*Y<``"
+MH/@``_!#``/!*@`#]````<I2``.KL@`"2[X``J"^``/P00`#P2D``VIP``(R
+MUP`"L/\``K&_``/!(``#:&````H2```"$P`#0"X``_\```*@`0`""FP``K`!
+M``)!"``#\`4```)```/_```#_P```J`.``(*;``#2G0``'HH``/_```#_P``
+M`\$O``-J=``",98```(F``-`"@`#0`T``J`.``/P!0`"L`@``D`%``.````#
+M]`0``_`#``*P(``"0`D``Z````*Q0P`":`$```(K``/_```#_P```D`.``*@
+M#@`""IP``!(H``*P0P`"L00``K,!``-J=``#2GP``_\```*P`0`"L04``K,$
+M``-J?``#2F0``K2````1[P`"0`0``F`(``*X(``"8`@``KB_``)`"``#HB(`
+M`K$$``/!/@`#:F0``_0$``/P"``#2F0``K2````1[P`"0`0``F`(``.B(@`"
+MLP$``VID``(P6P`",&@``%HK``*Z`0`#_P```DNZ``*@N@`#\$(``_0```'*
+MQ0``0A```K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```'*Q0`#0`H``_\`
+M``*P0``"00@``J`0``(*Q0```B8``_\```/_```"P`X``((F``*Q`@`"I`$`
+M`@GQ```![P``0?D``_\```/_```#V````]R```!Z00`"L````]@!``*P`0`#
+MW`$``C!2```"$P`#_P```_\```+`#@``@A,``C&6``-`"@`"L(```_\```)`
+M"0`#H`0``K$#``)H`0```BL``_\```/_```"0`X``J0.``/P"P``$B@``K!#
+M``*Q!0`"LP$``VIT``-*?``#_P```K`!``*Q!@`"LP0``VI\``-*9``"M(``
+M`!'O``)`!``"8`@``Z(B``*S`0`"L0```VID``(P6P`",&@``%HK``*Z`P`"
+MN0$``_\```)(N@`"I(D``<LW``*Y!``#_P```DBZ``*@B@`!RQD```(E``*R
+M"``"LP```_\```*D`@`!RS<``J`.``/P0P``FB4``_0```'*-``"2[D``J"Y
+M``'+-P``DB4``_0```'*-``#]````<LW``!"$``"L`$``J#>``/P00`#@`(`
+M`D`(``/P`@`#]````<LW``-`+@`#_P```K`(``)!"``"H!```@LW``*P@``"
+M00@``_`%```"0``#_P```_\```*@#@`""S<```(E``/_```#_P```^@0``"*
+M)0`"I`X``@HT``!:*P`#_P```TIP``/_```"2[X``J"^``/P0@`"LH```VIP
+M``!A^0``6>\``_\```/<P``#V+```'I!``*P```#V`$``K`!``/<`0`#0`T`
+M`KU```/_```"3=4``J;>``/P`P`"+O$``_0$``/P"@`"L'\``K'_``*R_P`#
+M:&```VAK```1Y0`"L\```^C0``-@3``"+RP``C&;``(QE@`#[````&H_``/_
+M```#_P```J#>``/P`P`"NU,``_0```/P00`"NUL``_\```/_````V?P``T`0
+M``*[#P`#2"D``J#>``/P00`#2"T``K\$``)`"P`#JP(``P_[``.,]@`";,\`
+M`X_V``-)Z``"HTP``_`$``,$3``#!5\``_0```/P10`#A.8``X56``.E5@`"
+M950``F1.``/!!``#P14``J#>``/P!``#:"D``VGH``/T```#\$(``V@M``-I
+M[``#Z````C`5``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$
+M``(QFP`"OP(``C&A```*.P``$@P``!H+``*P`@`"H-X``_!!``*P!``#@18`
+M`F`!``."*@`"L80``F(A``*D/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"
+ML0(``K(2``/H,``#:F@``K"````200`"0`@``_`!``/H(``"L!,``K$"``."
+M)@`#Z#```VIP``*P(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!
+M``-J>``#2GP``_\```*P`@`"L0(``K,$``-J?``#Z````\````*QOP`#P2``
+M`VA@``/H<``",98``TID``*T@```$?P``D`$``*T`P`"8`0``K,0``-J9``"
+M,%L``TID``*T"``"1$```F=T``*E?@`"#!$``^@```(P%0`"H-X``_`$``-(
+M*@`#2>@``_0```/P0@`#2"X``TGL``*\$0`"OQ```LF?``+(C``#P0@``\$9
+M``*@W@`#\`0``V@J``-IZ``#]````_!"``-H+@`#:>P``KL!``#:/@`#Z'``
+M`XOE``.+M@`"I8L``_`"``/T```!R]0``T`2``#Q]``"OR```J#>``/P`P`"
+M:J\``_0```/P00`":[\``V`2``/T```!S!$``C&;``(QE@`#[````&H_``/H
+M````@=D``K`(``"!^P`"H-X``_`#``!9\0`#]````_!!``!9\``"L'\``J'^
+M``/P00`"2[```-GO``*P_P`"L;\``\$@``-H8``",9L```H[```2#```&@L`
+M`K`"``*@W@`#\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"
+MLP0``T`5``*Q"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J
+M:```$?L``K`3``*Q`@`#@B8``^@P``-J<```$B@``K`A``*Q`@`"LP$``VIT
+M``*P`0`"L0(``K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP`
+M`KP$``/<P```>>\``&'[``*[&``#V/```B[1```!V0`#0"4``K\0``+`#@``
+M@=D``D]?``/P`P`"+2X``_0```',<P`"OP@``J`.``/P`0`#P?X``C+7``-*
+M@``"H/X``_!!``-JA```8>\``K"```/H\``"H<```_!!``/!_@`"+.$``C&6
+M```1[P`#Z!```K`C``.B(@`"LP$``VID``(P6P``8=D```'O```)^0`#0"8`
+M`K(0``/8```#W!```'G[``*P```#V`$``K`!``/<`0`"0BD``_!%``.O\``"
+MH,X``_`"``/[```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E
+M+@`#\`$``_L!``,/_@`"#)4```'9``/_```#_P```L`.``"!V0``8>\``K"`
+M``/!_@`"H<```_!!``/H\``"+.$``C&6```1[P`"L`,``^@0``.B(@`"LP$`
+M`VID``(P6P`",&@``T`E```!V0`"L0,``K((``*S$``"0S4``_`"``)")0`#
+M\`(``J4!``',8```8?D``%GO``/_```#W,```]BP``*P```#V`$``K`!``/<
+M`0``>?L``T`-``*]0``#_P```DW5``*FW@`#\`,``B[Q``/T!``#\`H``K!_
+M``*Q_P`"LO\``VA@``-H:P``$>4``K/```/HT``#8$P``B\L``(QFP`",98`
+M`^P```*\$0`"H-X``_`$``-(S``#2-$``_0```/P0@`#2.P``TCQ``(M&0`"
+MH-X``_`$``-HS``#:-$``_0```/P0@`#:.P``VCQ``*@W@`#\`0``TC4``-(
+MV0`#]````_!"``-(]``#2/D``BT9``*@W@`#\`0``VC4``-HV0`#]````_!"
+M``-H]``#:/D``J#>``/P`P`#2-P``_0```/P00`#2/P``J#^``/P!``"P`P`
+M`L$<``/T```#\$(``P`,``,!'``"H-X``_`#``-HW``#]````_!!``-H_``#
+M[````J#^``/P"@`"P`P``L$<``+"+``"PSP``L1,``+%7``"QFP``L=\``/T
+M```#\$@``P`,``,!'``#`BP``P,\``,$3``#!5P``P9L``,'?``#[````K!_
+M``*Q_P`"LO\``VA@``-H:P``">4``^@```.@`P`#W````]@0``-`,0`"OP,`
+M`KP"``*F_``#\$$``\$'``*@_``#\$$``\$&``*@_@`#\$$``\$%``*A_@`#
+M\$$``\$$``/!$``#P2```\$P``/^```#U!X``VAK``/[```##_X``@T[``-`
+M-0`"OP,``_\```*F_``#\$$``\$'``*@_``#\$$``\$&``*@_@`#\$$``\$%
+M``*A_@`#\$$``\$$``/!$``#P2```\$P``/^```#U!X``VAK``/[```##_X`
+M`@U3``-`.``#0#T``_\```-JA``#:H$``^P```-A4``#854``V%:``-A7P`#
+M2%0``_\```/H,``#HS,``VA4``-H:P`#2%4``^@```/H<``"LN\``K'_``*P
+MOP`#:&```VAK``-)?``"M`0``F$4``-I?``#23P``_\```)A'@`#:3P``TJ4
+M``-!.0`#_P```_\```*F-P`#\`<``J8F``/P!0`"IA4``_`#``*E!``#\`$`
+M`V$X``-@_``#_P```_X```/_```#2&0``K00``)")``"H"0``_!#``(MVP`#
+M]````<V6``*P_P`"L?\``K+_``*S_P`#:I```TD\``/`3@`"010``VD\``-(
+M5``"M3\``D-3``-H5``#Z````('T``""&@``@AL``TAD``.,Z@``\A4``DP,
+M``/P2``#2#0``_\```.`"``#H`P``J`.``/X`0`"#;<``((5``/X`P`#2%4`
+M`^@```.'!P`#:%4``TD]``*_$``"1$\``_`$``*__P`"+D$``K]0``(N00`#
+MIW```P=^``(-S0`#P"```\`0``/````#:&```VAK``.@$``#:&```T%0``-!
+M50`#05H``T%?``/L```#^`,``TG0``*X"``"23@``J"8``(.+@`#2=0``K00
+M``)#-``"H#0``@X*``-("``"N`@``F`(``-H"``#2"@``K@@``)C.``#2"T`
+M`V@H``-IZ``"9W@``V@M``-I[0`#2,@``KC[``)"*``#:,@``TB8``*X(``"
+M8`@``TBQ``-HF``"9$@``VBQ``/!#@`#P1X``\$N``/!/@`#8S```V-P``-C
+M-``#8W0``V,X``-C>``#]````<XN``-("``"N/<``D`(``-H"``#2"@``KC?
+M``)#.``#2"T``V@H``-IZ``"1W@``V@M``-I[0`#2,@``K@$``)B*``#:,@`
+M`TB8``*XWP`"0`@``TBQ``-HF``"1$@``VBQ``*P`P`#P1```\$@``/!,``#
+M8S```V-P``-C-``#8W0``\$N``/!/@`#8S@``V-X``-)?``"M/L``D$4``-I
+M?``#:&L``^P```-(R@`"L`0``K%```/!*``":"```VC*``/!@@`#:,H``F@A
+M``-HR@`#P8(``VC*``/L```#^`,``P_^``(.0@`#[````^@```/`$``#P"``
+M`Z`0``-H8``#:&L``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/^```#
+MU!X``VAK``-II``#Z````_X```/4'@`#:&L``VFD``*@W@`#\`,``T)@``/T
+M```#\$$``T)<``-"60`"H-X``VFD``/P`P`#0F@``_0```/P00`#0F0``VFA
+M``/^```#U!X``VAK``-H:P`#[````^@```/`(``#P!```Z`0``-H8``#:&L`
+M`T)6``/!#@`#Z!```^@@``/H,``#I!,``]@0``/<0``#U!X``K\"``(N00`#
+M:&L``VFD``-IH@`#Z````_\```/4'@`"OP(``BY!``-H:P`#::0``^@```/`
+M(``#P!```\````-H8``#:&L``^P```-H:P`"L'\``K'_``*R_P`#:&```K$,
+M``/H```#H`,``]P```/8$``#Z````^@0``/H(``#Z#```_X```/4'@`#:&L`
+M`_L```/[```#B.,``_@#``/^```#U!X``VAK``/[```#"(X``@ZF``/L````
+M(?H``^A0``/H8``#Z'```KD(``*XP``#W($``]B1``-"4``#^`,``_\```-J
+M1``#Z"```P$>``-J1``#_@```]1?``-H:P`"M!D``_X```/47P`#:&L``TFE
+M``/_```#_P```\$$``/!%0`#@N```F(F``/!-P`#::0``KD(``,)G@`"#LT`
+M`VFE``/L```"H;X``_`*``/0'@`##[X``_@#``,`#@`#`1X``P(N``,#/@`#
+MU!X``P_^``(.U@`#^P```PS.``(.T0`#[````J&^``/P"@`#T!X``P^^``/X
+M`P`"P`X``L$>``+"+@`"PSX``]0>``,/_@`"#N8``_L```,,S@`"#N$``^P`
+M``/0G@`#T!\``KP_``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP`
+M`KP@``+`A``#H````J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"
+MPJ8``Z(@``*C:@`#\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``^C0``.,
+MZ0`#!(```NB-``,%D0`"Z9T``P:B``+JK0`#![,``NN]``-B;@`"2(P``DF<
+M``)*K``"2[P``]2>``-";@`"9$4``F1&``)D1P`"#Q,``&H_``/[```#^P$`
+M`P_^``(.\0`#[````]">``/0'P`"O#\``DB,``))G``"2JP``DN\``)$#``"
+M11P``D8L``)'/``"O"```L"$``.@```"HT@``_!!``+`#``"P94``Z$0``*C
+M60`#\$$``L$<``+"I@`#HB```J-J``/P00`"PBP``L.W``.C,``"HWL``_!!
+M``+#/``"O`<``J/<``/P3@`#<$P``U!.``/_```#_P```_X```/4'@`#:&L`
+M`_L```-P3@`#4$P``_\```/_```#]`0``_`(``*\"``"I-P``_`!``-JA``"
+MO`D``J3<``/P`0`#:H```K#_``*QOP`"LO\``VA@``/[```#^P$``LW>``*F
+MWP`"#RP``TID``*T@``"0`0``VID``*P```"L0```K(```*S`0`#:G0``K`Q
+M``*Q!@`"L@0``K,```-J>``#2GP``_\```*P`0`"L0$``K,```-J?``#2F0`
+M`K2```)`!``"M`,``F`$``-J9``",%L``TID``*T@``"0`0``VID``!J/P`"
+M,S@``^P```!9]@``8CX``_\```*AO@`#\$(``/'T``/L```"H<X``_!!``,+
+MO@`##,X``-GV``#B/@`#2D```%H6``/_```#_P```J"^``/P0@`#H````Z(@
+M``/07@``8@H``%GR``.B`@`"0`D``D(I``*EC@`"#[L``PB.``*@#0`#\`L`
+M`$('``+$3P`#P50``J"^``/P1@`#U%X``L1/``/!5``#U%X``L1/``/!5``"
+MI:X``@_+``,*K@`"H"T``_`+``!2!P`"QF\``\%V``*@O@`#\$8``]1>``+&
+M;P`#P78``]1>``+&;P`#P78``]1>``,,S@`"#\P``FN*``(/D``#[````T)P
+M``!2%@`#C^P``XCJ``.JH``"I*X``_`&``*A2``#\$$``L1(``*A:``#\$$`
+M`L9H``.*X``"ID\``_!#``,$2``#``@``P$8``*F;P`#\$,``P9H``,"*``#
+M`S@``PJN``(/WP`#P50``\%V``/47@`#8G```^P```/!8@`#!FX``]P0``/8
+M```#T)X``_\```/_```"2(4``FB#``/!F``#P:@``\&X``/4G@`#^P```P9N
+M``(/]``#[````\$0``/!(``#P3```J#>``/P"``#:0@``VD,``-I$``#:10`
+M`VD8``-I'``#]````_!&``-I(``#:20``VDH``-I+``#:3```VDT``/L```#
+MP1```\$@``/!,``"H-X``_`'``-HS``#:-```VC4``-HV``#:-P``_0```/P
+M10`#:.P``VCP``-H]``#:/@``VC\``/L```#2=0``_\```.`Y0`"00,``TG2
+M``/_```"0`H``TG"``*E$``#\`$``TG&``/L```"L'\``K'_``*R_P`#:&``
+M`VAK``/H```#Z!```\$N``*S,``#::0``^@```*Q,``#Z"```^@P``/H0``#
+MI4,``]A```/<4``#_@```]0>``-H:P`#^P```_L```*P$@`#Z!```_X```/4
+M'@`#:&L``PB.``(03``#[````]">``/[```#_P```_\```/4GP`#^P$``P_^
+M``(04@`#[````_@!``*_!``#2F0``_\```/_```"00\``A!=``/X`P`#:&L`
+M`_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\``A")``-`$@`"
+MM1```J4E``/P!``"OP(``FJO``/T```!T(8``L15``*E)``#\`0``K\"``)K
+MOP`#]````="&``+$10`"I20``_`$``*_$``":J\``_0```'0A@`"OQ```FN_
+M``#Q]``#8!(``C"*``/L```#2G```_\```/!P@`#0"X``K`!``-JJ``#_P``
+M`_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,``TJM``*_D``"
+MH,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#\`L``T`9``/_
+M```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P20`#0!T``_\`
+M``/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P```+$1@`#:JD`
+M`_\```/_```#_P```TJL``/L```"L'\``K'_``*R_P`#:&```VAK```)Y0`"
+ML,```]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P
+M50`#P1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$
+M``*TJ@`#P50``\%D``/!=``"O`<``J/^``(1/P``0@T``_\```/_```"H(X`
+M`A$%``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J/P``:@X``J3>``/P!``#
+MP(@``\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G
+M>P``:C\``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK
+M``/[```##,X``A$%``!"#0``8@X``_\```*@C@`"$2H``T!*``*DS@`#\`0`
+M`\"(``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`"
+M:JL``KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@
+M2@`#P1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+
+M``/!$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,`
+M`J#Y``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"
+M$4L``K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L
+M```"L'\``K'_``*R_P`#:&```VAK```)Y0`"L,```]P```/8$``"M/\``\%D
+M``/!=``"O`<``_X```*U_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X`
+M`VAK``/[```##,X``A%I``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#
+M2F(``C&6``/H\``",:@``VIB```)Y0`"L,```]P```/8$``"M/\``\%4``/!
+M9``#P70``KP'``/^```#U%X``VAK``/[```##,X``A&+``*P_P`"L;\``\$@
+M``-H8``#[````TID``*T@``"0`0``VID``/L```"L`$``^@0``/H(``#Z#``
+M`VI@``/L```"L`0``J#P``/P`P`",,,``_0$``/P`0`"+2X``^@```/````#
+MP1```K+]``-H8```"CL``#(,```:"P`"L`H``J#>``/P00`"L`P``X$6``)@
+M`0`"L18``J0^``/P`0`"LP0``X9J``*R`@`"M`0``J/^``/P`P`"H/0``_`!
+M``*R!``"8B8``VI@``./X0`"+D$``VAK``/_```#_@```^P```-*8``#_P``
+M`^@P``)@#@`#:F```TID``*T\@`"0`0``VID``/L````:C\``T`$``/_```"
+MN`0``D7@``*@7@`#\$0``J#>``/P0@`#0"0``_\```!A^``#_P```_\```/<
+MP``#C^H``J#>``/P`0`#Z/```]CP``.,Y``#P;(``TD]``*@W@`#\$$``TE!
+M``/_```"1&X``_`!``*\!P`"0`@``_!#``(NT0`#]````_!!``(NX0`"1&X`
+M`_`)``/HP``#JV(``Z5@``)%7@`#\$,``B[1``/T```#\$$``B[A``/L```#
+M2,```TC%``/H$``#Z%```J#>``/P"``#:,````(Q```*,``#_P```_\```-H
+MP``#]````_!&``-HQ0``(B\``"HN``/_```#_P```VC%``/L````:C\``_\`
+M``/_````4?D``J#>``/P`P``6?$``_0```/P00``6?```_\```/<H``#V+``
+M`T`&``/_```#_P```D#H``/P`P`"H-X``_!!``-`)@`#_P```_\```-)00`"
+MH`X``_!#``*@W@`#\$$``\%%``)%3@`#\$,``XSD``/T```#\$$``XSC``.)
+MF``#JIP``J"N``/P`P`"+M$``_0```/P00`"+N$``T`&``/_```#_P```TE!
+M``)`C@`"H`X``_!#``*@W@`#\$$``\%%``/HP``#JT(``D5.``/P!P`#I4``
+M`D5>``/P0P`"+M$``_0```/P00`"+N$``^P```*@W@`#\`,``T@A``/T```#
+M\$$``T@E``/_```"NP$``Z)F``.!9@`#H18``X=V``)@)P`#``L``Z<&``."
+M!@`"9B$``J#>``/P!``#:"$``VJ)``/T```#\$(``V@E``-JC0`#[````X_M
+M``(N00`#Z#```X+@``/H$``#Z````V@P``./[0`"+D$``^CP``-)<``#Z'``
+M`K8!``/!40`#P4```V@Q``*X_``#P5,``\%"``)%6``#270``C+$``-H,0`#
+MP5$``\%```(RQ``#:#$``\%3``/!0@`#29@``C+$``-H,0`#P5$``\%```(R
+MQ``#:#$``\%3``/!0@`#29P``C+$``-H,0`#P5$``\%```(RQ``#:#$``\%3
+M``/!0@`#2.@``C+$``-H,0`#P5$``\%```*W$``",L0``V@Q``/!4P`#P4(`
+M`C+$``-H,0`#[````TD]``*P"``"0`0``_`%``-*I``#_P```_\```*R`P`#
+M:J0``K`$``)!!``"H!```_!&``-(P``#2,4``K$#``*U`P`#:,```VC%``/L
+M```#_P```_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@
+M``/H,``#:.@``^@```/_```#:.@``T%(``/_```#[````K!_``*Q_P`"LO\`
+M`VA@``-H:P``">4``^@```.@`P`#W````]@0``*\`P`"L/<``J#^``/P00`"
+ML'\``\$0``/!(``#P3```K3_``/!5``#P60``\%T``/^```#U!X``VAK``.@
+M`0`#H1$``Z(A``.C,0`#^P```_X```/47@`#:&L``_L```,,S@`"$NT``K#_
+M``*\"``#P1```\$@``/!,``#:H```J3^``'3!P`"H/P``_`"``-JA``#[```
+M`K#W``.A`0`#HA$``Z,A``-JA``#[````TD]``/_```"N(```F1(``-I/0`"
+ML`$``K$"``*R/P`"0B\``K,```-J:``"L````K$```*R```"LP(``VIT``*Q
+M`0`"L@@``K,```-J>``"L`$``K(```-J?```$>\``K#```)`#P`#H`(``F`.
+M``*Q```#HB(``K,!``-J9``"L/\``K&_``/!(``#:&```_\```/_```",%L`
+M`KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S```#:#```^P```-`+``#
+M_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8``-@'``#[````^@```""
+M/P`"(OH``/(_``(B^@`",X\``BXT``-)F``"M/<``K4/``)!%``"8`4``VF8
+M``/!+@`#Z#```V@P```"%P`#@>```^A```*@`0`#\`$``\%.``(THP`#2`@`
+M`KC^``)!&``#:`@``^@```""/P`")%H``/(_``(D6@```A<``X'@``/_```"
+MI!```_`"``/!3@`"-*,``C/S``-````"O"```_\```)"+``#\`(``KT```(T
+MR``#0````KP@``/_```"0SP``_`"``*]`0`"-,@``T`L``*X0``"N8```KO_
+M``-*I0`"2!@``_`!``*[SP`"21D``_`"``*Z/P`"2[H``D5;``-JI0`#]```
+M`<)L``-)T0`"N$```D1X``.$0``#2)P``TBB``.%X@`"8`0``F`%``)HA``"
+M:(4``VB<``-HH@`#2+0``TBZ``.%X@`"8`0``F`%``)HA``":(4``VBT``-H
+MN@`#23@``X7A``/`50`"0B4``VDX``-J7``#H.$``X'A``/H,``#@N@``X7E
+M``(O\``#0Z8``X#H``/_```"2(4``FB```/!F``#P:@``\&X``-CI@`#8^8`
+M`^@```/HT``",`$``\'>``(P`0`","<``X3B``/!R0`#Z````X'A``.#Y``"
+MPC$``P(N``+#/@`"1$D``_`!``.#Y0`#Z%```B_P``.`Z@`"+_```XCE``.$
+MX``"1$P``_`"``.(Y``"R(X``\&8``/!J``#P;@``V,J``-C:@`","<``X'B
+M``.@X0`#HY8``X+D``+"+@`#Z%```B_P``.@XP`"+_```C`G``.`Y0`"0*``
+M`\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"`@`#@B0``)'C``/L```"
+M,"<``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP``/!;@`#P5,``\%"``-H
+M,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(``V@Q``)$C@`#\$T``TF<
+M``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"8`4``F$4``/H,``#P2X`
+M`V@P``-#I```(>,``K4/``/_```"0`4``F`$``/!$``#P2```\$P``-CI``#
+M8^0``X&$``.@&``#@@8``F`"``/HT``",!4``\'>``(P%0`#2)```Z2Z``.E
+MYP`"014``F$4``-HD``#:*@``VB4``-HK``#H*8``\$0``/!(``#P3```V0D
+M``-D9``#BK8``T@A``*X`P`"9F@``KD/``*[_@`"1FD``F9J``)'>P`#:"$`
+M`VJ)``-H)0`#:HT``T@(``-((0`"81X``V@(``-(R``"N$```KD_``)@"``#
+M:,@``D`)``-HR``"95X``V@A``-JB0`#:"4``VJ-``)%6P`#:"$``VJ)``-H
+M)0`#:HT``^P```-`+``"N$```KF```/HL``#2J4``D@8``/P`0`"NS```DD9
+M``/P`@`"NL```FNZ``)E6P`#:J4``TB<``-(H0`"O'L``D`,``)$3``#:)P`
+M`VBA``-(M``#2+D``D`,``)$3``#:+0``VBY``-(D``#A.(``Z7G``)!%0`"
+M810``VB0``-HJ``#:)0``VBL``-).``#A>$``F(E``-I.``#:EP``Z#A``.!
+MX0`#@^@``X+H``.%Y0`"+_```^@```.!X0`#@^0``L(Q``/H,``#Z%```B_P
+M``.`Z@`"+_```T@(``-((0`#J.T``D$8``-H"``#J.L``D9H``/`/@`"15,`
+M`V@A``-JB0`#:"4``VJ-``/H0``"-*,``^P```-)=``#P6X``^AP``.(2``#
+MP%X``X59``)")0`"8B@``VET``/!0@`#P5,``V@Q``/L```#2`@``KC^``)!
+M&``#:`@``TA4``*_8``"8B\``VA4``-)=@`"OQ```F2O``/!6P`#P6X``^AP
+M``-H,0`",L0``TA4``*_GP`"0B\``VA4``/!2@`#:#$``C1%``/L```"+D4`
+M`C&;``(M+@`"-I\``^C```#B$``#P3P``C3U``(S/@`"+C0``C2P``*_&``"
+M-D<``C"*``!B$``"L````]P```*P```#W`$``X_"``*P0``"P`\``]@```*P
+M@``"P`\``]@!``-`&``"H-X``_!!``-`'``#0"T``_\```/4'@`#U%\``K`0
+M``+,S@``XA```J7```(4S@`","<``Z.6``(T]0`",9L``C&6``/L```"L00`
+M`K"```*@W@`#\$$``K#```*R"0`#Z%```B_P``/L````\=X``/'=``/!_0`#
+MP<X``T@$``/`?@`"0S<``V@$``-("``#_P```X3H``)@!``#:`@``TF8``.%
+MX@`#P%4``D$5``.$Y0`"8`0``^@P``/!+@`#:#```^C0``(ND0`#^`$``T`-
+M``/_```"L`$``D`&``(5,@`"H.T``_`%``*[/@`"2[8``ZNP``/T!``#\`T`
+M`K````*R`@`#HVH``PNN``*@,``#\`<``PN^``*@/@`#\`0``PN^``*@,@`#
+M\`$``PN^``/T!``#\`$``^BP``-(&0`"LN```D9B``)F:P`#:!D``TGE``/_
+M```"1F(``F9K``-IY0`#P:L``BY%``(NK0`"M`\``TI```/X`0`"I$```_`&
+M``*D00`#\`0``J1"``/P`@`"H$,``A5>``+*K@`"L"```J"@``/P00`#Z*``
+M`J"K``(5A@`#2!D``K+@``)&8@`"9FH``V@9``-)Y0`#_P```D9B``)F:@`#
+M:>4``_0$``(5/P``T=\``J#>``(590``T>```LW>``/T!``"%18``$'@``/_
+M```#_P```J"H``(5C``"H:@``_!(``-((0`#`XH``X,P``)G<P`#:"$``VJ)
+M``/T!``"%8P``T@9``*RX``"1F(``F9H``-H&0`#2>4``_\```)&8@`"9F@`
+M`VGE``-()0`#`Z@``X,P``)G<P`#:"4``VJ-``/T!``"%8P``T`1``/HP```
+M\?0``KB```)G>``#8!$``\'?``-)F``#A>(``\!5``)!%0`#:9@``^@P``/!
+M+@`#:#```T@(``/_```#A,@``F`$``-H"``#^`,``^P```/_```#_P```&H_
+M``/H````@AD``('<``*P`0`"L1$``K(0``-J1``"L1```^@@``-J1``#0"0`
+M`J#>``/P`P`"NU,``_0```/P00`"NUL``-G\``)`#@`#\$L``T`0``*\!``#
+MW,```X_J``*@W@`#\`$``^CP``/8\``"O`D``\&Q``(NT0`#0"0``_\```*\
+M`@`"0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/```XSD
+M``/!L0`"+M$``T@(``*T0```@?4``F`$``-H"``#2`$``K"_``)$0``#:`$`
+M`^@```*Q0``#Z"```^@P``-J1``",9L``BTN``(VGP`"OQ@``C9'``(V=``"
+MOP```C&A``-*<``#_P```_\```*RD``#:G```K\3``(V1P`"-G0``T`D``/_
+M```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP
+M``*\"0`#BQ```B[A``-`)``#_P```KP"``)`#``#\$L``T`0``*\!``#W,``
+M`K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(NX0`#2G```_\```/_```"
+MLH```VIP``*_&``"-D<``C9T``*_```",:$``TIP``/_```#_P```K*0``-J
+M<``"OQ,``C9'``(V=``#0"0``_\```/_```"0`X``_!+``-`$``"O`0``]S`
+M``./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+M$``T`D``/_```"O`(`
+M`D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"OX```]CP``.,Y``#
+MP;D``B[1``(QFP`",98``"'U``/_```#2`@``_\```/!!``#:`@``^P```/H
+M```#P````K&_``/!(``#:&```K`!``/H$``#Z"```^@P``-J8``#2F0``K2`
+M``)`!``#:F0```H[```2#```&@L``K`"``*@W@`#\$$``K`$``.!%@`"8`$`
+M`X(J``*QA``"8B$``J0^``/P`0`"LP0``\$?``-J8``#2F0``K2````1_``"
+M0`0``K0#``)@!``"LQ```VID``(P6P`"OP@``D_P``/P`0``\AD``^P````"
+M&0`#_P```_\```*E#@`#\`$``^P```/H````@AD``T`2``/_```#_P```D2.
+M``*@3@`#\`$``/'T``*_0``"H-X``_`#``)JKP`#]````_!!``)KOP`#8!(`
+M`C"*``!YW``#_P```T`H``*@_@`#\$$``^P```*@W@`#\`4``L`.``/P00`"
+MP1X``_0```/P0P`"PBX``_!!``+#/@`#8"@``/'<``/L```"L`$``K$"``*R
+M!@`#Z#```VIH```200`"L!,``K$"``.")@`#Z#```VIP``-`!0`"L"$``K$"
+M``*R!``"M`,``D54``,")0`"LP$``VIT``*P`0`"L0(``K(/``*S`0`#:G@`
+M`TI\``/_```"L````K$```*S!``#:GP``^P````"%```"D```&H_``/_```"
+M0`$``J`.``/P`0`#[````TB<``-(H0`#2DH``J#>``/P0P`#2+0``TBY``-*
+M3@`"O!```F(N``)F;@`":(P``FF<``*@W@`#\`4``VB<``-HH0`#:DH``_0`
+M``/P0P`#:+0``VBY``-J3@`#Z,```.';``*P$``"L0```K(0``*S```#8G0`
+M`K"```/8`0`"L````]P!``*P$@`"L0(``K(2``*S`@`#8G0``K`0``*Q$@`"
+MLA```K,2``-B<``#8D0``K$"``*S`@`#8DP``V)(``(S/@``8=L``\&,``/!
+MG``#P:P``\&\``(W@``"-9X``&';``/_```"L````]P```*P0``#C\(``L`/
+M``/8```#0!@``J#>``/P00`#0!P``T`M``/_```#U!X``]1?``*_```#W/``
+M`K_```.(P@`"S_@``]CP``/$```#Q!$``\0B``/$,P`"M0\``D1E``.E9@`"
+MH-X``_!#``*U#P`"1'4``Z5V``.F0@`#A$H``Z=2``.%6@`#Q$0``\1F``+`
+M`0`"P`0``L(C``+")@`#Q!4``\0W``/4'@`#0G4``T)R``*_$``"H00``_!&
+M``*E"0`#\`0``\&,``/!D``#P:P``\&P``*C"0`#\$(``\&L``/!L``#8G(`
+M`T)&``*A)@`#\$8``J4I``/P!``#P8P``\&2``/!K``#P;(``J,I``/P0@`#
+MP:P``\&R``-B1@`#0DX``J$5``/P1@`"I1D``_`$``/!C``#P9$``\&L``/!
+ML0`"HQD``_!"``/!K``#P;$``V).``-"2@`"H3<``_!&``*E.0`#\`0``\&,
+M``/!DP`#P:P``\&S``*C.0`#\$(``\&L``/!LP`#8DH``V)T``/[`0`"L1``
+M`LS.``#AVP`"H,$``=;X``-"<``#0D4``_\```+(`@`#J(```LI&``.JH``#
+M0DP``T))``/_```"R0(``ZF0``++1@`#J[```C>```/L```#2)P``TBA``*@
+MW@`#\$(``TBT``-(N0`#P1@``\%:``.)E@`#B[8``F$9``)E6P`"H-X``_`$
+<``-HG``#:*$``_0```/P0@`#:+0``VBY``/L````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_me.bin.uu
new file mode 100644
index 0000000..82b8244
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_me.bin.uu
@@ -0,0 +1,197 @@
+begin 644 CAYMAN_me.bin
+M?$"``<R``$V(````U$``?X````#80`!=Q!``+"40``*5`/_^)(P``GQ!``'$
+M'``QQ"``+]@``%?-P:#9S@&@VMA``%>8P``/Q!0`"95```+90:*DQ!L`*M@`
+M`%;-@`!4P#X`!,P!H?3,/2`$Q#T``\P``$?80`!6V$``7H````#$#``*!#P`
+M(Y3```+/P:*DQ!L`*]@``%;-@`!5P#X`!,P!H?/,/2`$Q#T``\P``$G80`!6
+MV$``7H`````$/``CS\&BI,P``$O8``!5S$``8X````#,``!&S```2\Q!(F3,
+M02)ES$$B9LQ!HMU\0(`!S(``38@```#,0`!&S```2XP`!4;,02)DS$$B9<Q!
+M(F:,``5*S$&BW7Q`@`',@`!-B````'Q`P`',``!BE,#_M<P``$&`````?$#`
+M`<`6``0DT/__?14`"LP1```8V``^%-P`'\0A``-\0D`!E<``!<P``$U^5H`*
+MS"D``,0E``-^)@`)?$+``96```7,``!-?M<`"LPQ``#$+0`#?BX`"LP``$TE
+M$/__SA$``(````!\0,`!S$``0(````#-02)=S$``1<P``$K-`2)<S$&A_'Q`
+M@`',@`!-B````,U!(EW,0`!%S```2LT!(ES,0:'\?$"``<R``$V(````S$$B
+M5X````!\08`!S$``1<Q``$K,02)<S$&A_'Q`@`',@`!-B````,P``$7,``!*
+MS$$B7,Q!H?Q\0(`!S(``38@```#`#@`!S```1<P``$K,02)<S$&A_-1-H?U\
+M0(`!S(``38@```#,02)=@````,P``$7,``!*"$P``7Q!``%\04`!)5C__QE<
+M`_`58``5S8&A`LW!(E;.`2)<*20`()3```3.0:'\",P``8```)O-`:'\S`&A
+M`GQ`@`',@`!-B````'Q`@`%\0,`!P"H``GQ!``%]*0`*))0``228``8DG`,`
+M%=P`"'Q"``%\0D`!P"X`!)5```T%\")8?R\`"LPQ``#$*0`#S,$A:<T!(6K.
+M@2%K,;0``LP!(6R70``,Q#0`#8```-DQM``"ET``",`N``0%\")8?R\`"LPQ
+M``#$*0`#Q#0`#8```-DQM```ET``!'X"@`'$-``-@```V3&T``270/\LS@$A
+M;<Y!(6[$*@`"Q#0`#9M```/,``!-C``#0C'T``#`+@`$ET``#,Z!HK?,+:*V
+MQ"T``\`P``9^\T`4P#``(']K@!%_L\`5SX&BQ,_!HM&`````,?0``<`N``27
+M0``,SH&BN\PMHKK$+0`#P#``!G[S0!3`,``@?VN`$7^SP!7/@:+%S\&BTH``
+M```Q]``"P"X`!)=```S.@:*_S"VBOL0M``/`,``&?O-`%,`P`"!_:X`1?[/`
+M%<^!HL;/P:+3@````,`N``3.@:+#S"VBPL0M``/`,``&?O-`%,`P`"!_:X`1
+M?[/`%<^!HL?/P:+4@`````08``"```$5!!@``7Q`P`'$)``Q&-``,"34`/^5
+M```)FD```XP``T+-0:#:Q"``,I8```380`!3C``#9<U!H-J9@``"S```0LU`
+M`&&`````V```2'Q`P`'$)``Q)-0`_YI```/8``!4V```1\0@`#*6```$V$``
+M4]@``%78``!)V$``9,U``&&`````?$#``1C0`>@8U``P&-@`-`4H`3U\0@`!
+M?$)``94```>&@```@``!5X``!4*```%[@``%0H```4T15``0?A8`"LR``$W4
+M80``E8#^N<`Z``3,.2%`Q#D``WQ`@`&(````$50`$%(D`"!^)@`:S4``6-1B
+M``"5@/ZNQ"``')H`__]\0(`!B````-PZ``"90``;)YP``97```T+N``!S@$A
+M:<Y!(6K,02%KS`$A;)N```.5@/Z?@``!;U)D`"!^)@`:1B``!%8D`"`B9``R
+MS@$A:<Y!(6H+N``"S$$A:\Q!(6R;@/_]E8#^DL0P`!67`/__?$"``8@````+
+MN``!S@$A:<Y!(6K,02%KS`$A;)N`__N5@/Z'@``!;Q8@``+`*@`!S@$EQ]1I
+M)<B5@/Z!P#H`!,PY)<O$.0`#?$"``8@```!\0,`!?$$``1D4`#V90``)Q!P`
+M$I7`___,P2$`S0$A`<S!(0+-`2$#V0&BI(`````E&!``E8``!,0<`!(QY`!`
+MED#__LS!(77-`2%VQ"``$Y8`__\6*``!FH```\P``$Z`````S```3LS!(76`
+M``&7?$#``7Q!``',``!%S```2D#4``/-02)<S0&A_,`>``%\0@`!",P``08D
+M``$&*``"SAVA_<Y=H?W.G:']F,#_^7Q`@`',@`!-B````'Q`P`$DT``!%,P`
+M`7Q!0`%\08`!E0``!<U!(6W-@2%NQ!X``H```<+`(@`$?A8`"LPA``#$'0`#
+M?$)``7Q"@`&8P``#S>4``(````#.02%ISH$A:LW!(6O,`2%L@````'Q`P`%\
+M00`!?$%``7Q!@`%\0<`!&*0?Z#)H`#P$(``!EH``"'Q"``$Z,``#0B```IL`
+M``($(`!`!"0``8```=U^`D`!"F0``9I`__\D[``0S```39K```G`*@`$Q"P`
+M%WZ2@`K,``!!S"D``,[``!?$,0`#@``![<T!(6W-02%NQ#(``G\?``DD]``'
+M!W@!\9=``">'@```@``!^8```?Z```(#@``""(```@V```(2@``"%W\;@`\4
+MI``(EX``'29D`/^```(H?QN`#A2D``B7@``8)F0`_X```BA_&X`,%*0`")N`
+M`!,F9`#_@``"*'\;@`T4I``(FX``#B9D`/^```(H?QN`#Q2D``B;@``))F0`
+M_X```BA_&X`.%*0`")N```0F9`#_@``"*!2D``@F9`#_,F@`/!3L``B:@/WE
+M?$-``7Q#@`%\0\`!S```39;```;/02%ISX$A:L_!(6O,`2%L@````,_U``"`
+M````,F@`/)J`_[340`!_@````'Q`P`%\00`!P!X``144`!+`(@`"P"8`!)5`
+M``3`)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!(6G-`2%JFH``
+M!\U!(6O-@2%LEL#]P,0P`!67`/__@````,04`!156``@S4$A:\V!(6R6P/VX
+M@``"07Q!``%\04`!S$``0\Q``$3`#H``?$)``7Q"@`$6K``?P#7P`);`_:W.
+M0`/@)G@``Q)\``A_]\`)?_O`"A9X`!C/P`/ASX`#XA*P``)_/P`!SP`#XWR`
+MP`&```16?$#``1C0`>@%*`)EE0``"(:```"```)N@``"?(```H*```*(@``"
+MC8```I/,P:*D@````,`2"`!\04`!?$(``7T,P`K`$@`$%5@``Q5<``U]T<`)
+M$B``$WX>0`I^3H`*SH&BI,V!H?Z`````!!`A&,04`!"50/__U%$``,S!HJ2`
+M````!!`A!L04`!&50/__U%$``,S!HJ2`````V$``%LS!HJ3$$``6F0#__X``
+M```$$"$`Q!0`$I5`___440``S,&BI(`````DV``!?$$``7Q!0`%\0@`!E8``
+M!A&8`!#$'``*Q#P`)Y?`__^```*A$9@`$,0<``G$/``HE\#__Q5H`!U]64`*
+M$>0`"IJ```-^)@`*S<``7,T!(5C-02%9S@$A6LS!HJ2`````?$#``130`!T4
+MU``<F0``!I5`_5#`)@`$S"4A5,0I``.`````S4``5X`````D=``!)'@``L0,
+M`!^;0``"C``#0L04`"$$$``0FX```HP``US,P:)0S0&@4`08!`",``,+S```
+M6<0\`"/$$``?C``#&\0<`"4EW``!R#@`)I7```7$/``C1[@%4,P``%C/^@``
+MQ"0`'9I`__\$,``!Q"@`&3ZH``3$+``:?JZ`"IJ`__S/``!14-@`"!3<`!@I
+MW(``S8$A@,W!(8%1(``(%20`&!,P`!Y^<D`*(50`-<X!(8+.02&#S4$AA'Q`
+M@`',@`!-B````"1T``$D>``"Q`P`()M```*,``-"Q!0`(@00`!";@``"C``#
+M7,S!HF#-`:!@!!@)@(P``PO,``!:Q#P`),00`"",``,;Q!P`)27<``'(.``F
+ME<``!<0\`"1'N`54S```6,_Z``#$)``>FD#__\0H`!D^J``$Q"P`&WZN@`J:
+M@/_\!#```H```M@%F,``$-P`"!3@`!C-V0``Q!P`&,W9``'$)``8?F)`"LY9
+M``+$'``8Q"``&,0D`!C-V0`#SAD`!,Y9``>0````&_@`\,`V"`#`,`"`EX``
+M`I````#8``!=Q#@`+">X``&7@/_^P"H`!,08`"_/02%\SP$A?<V!(7K-`2%^
+M!"0`"`ID``&:0/__S"DA?\0A``,6.``?!"0`",R``$V;@/_YV```7I````!\
+M00`!Q"0`&II`__^`````?$$``<0D`!N:0/__@````'Q`P`&,``-"?$"``<R`
+M`$V(````V$``7<0\`"PG_``"E\#__ME!HJ3$/P`JS\``5,`^``3,`:'TS#T@
+M!,0]``/,``!'V$``7I````#$$``Q?$#``94```79P:*DV$``%L00`!:9`/__
+MS(``38P``UQ\0(`!S(``38@````$/``BS\&BI,P``$B0````?$#``8P``V5\
+M0(`!S(``38@```#80`!=Q#P`+"?\``*7P/_^!#P`(\_!HJ3$/P`KS\``5<`^
+M``3,`:'SS#T@!,0]``/,``!)V$``7I````#`$@`!?%%`"M15``"`````S$``
+M6\0X`"/$/``DP#7@`,`R``1_MX`)?_?`"2NX$``K_!``SX$A5,_!(57,,2%4
+MQ"T``\0<`!N9P/__Q"0`&II`__^`````?$#``7Q!``$9*``PEH``!L0D`!V:
+M0/__Q"0`'II`___,``/W41``('S0P!I5'``_?$%``7Q!@`'0P`$'E<```\`<
+M@`#-P2`0E8#\9(P`!4;=@P``!5P@`,P``$W470``@``%3GQ`P`%04``@?-#`
+M&GQ!0`%\08`!T,`!")6`_%>,``5&W8,```5<H`#470``@``%3GQ`P`%04``@
+M?-#`&GQ!0`%\08`!T,`!"96`_$N,``5&W8,```5<Z4#470``@``%3GQ`P`%0
+M4``@?-#`&GQ!0`%\08`!T,`!"I6`_#^,``5&W8,```5<Z(#470``@``%3GQ`
+MP`%04``@?-#`&GQ!0`%\08`!T,`!"Y6`_#.,``5&W8,```5<P`#470``@``%
+M3GQ`P`%04``@?-#`&GQ!0`%\08`!T,`!#)6`_">,``5&W8,```5<\`#470``
+M@``%3GQ`P`%04``@?-#`&GQ!0`%\08`!T,`!#96`_!N,``5&W8,```5<\_S4
+M70``@``%3M1#(`!\0(`!S(``38@```#40Z``?$"``<R``$V(````U$/I0'Q`
+M@`',@`!-B````-1#Z(!\0(`!S(``38@```#40\``?$"``<R``$V(````U$/P
+M`'Q`@`',@`!-B````-1#\_Q\0(`!S(``38@```#,0Z``?$#``8P`!4;,0Z``
+MC``%2GQ`@`',@`!-B````,Q#P`!\0,`!C``%1LQ#P`",``5*?$"``<R``$V(
+M````?$#``7Q!``%\04`!E,```GQ!@`',`_/\S$/S_,Q#\_Q\0(`!S(``38@`
+M``#`'@`0Q`P`'U#0``@05``"?16`$8``!"[`'@`@Q`P`(%#0``@(5`0`$50`
+M`GU1@!'-P`!8U%H``'Q`@`',@`!-B````'Q`P`$DT``#$2@``94```H&J`0X
+M?$&``8:```!\0<`!@``$1GQ!P`&```1,?$'``8``!%%\08`!?$'``134`!`%
+M5*``S94``(````#`(@`$!9B@`'VA@`K,&0``Q!D``X``!$+`(@`$S8$EPLPA
+M)</$&0`#@``$0LV!(6W-P2%NQ!H``H``!$)\0,`!Q!,#X,07`^/$&P/AQ!\#
+MXLV!(6G-P2%JS,$A:\P!(6P$(``$?:&``7V60`S-@`/AED#[GB4H``/`+?``
+M$1@`"'VM@`E]J8`*S8`#X8`````DC/__U$T``'Q`@`',@`!-B````'Q`P`$8
+MU``P&-`!Z!C\`#0DS``/!.@$>'Q!@`%\0<`!E,``(8:```"```2!@``%0H``
+M!(R```5"@``$?E'<`"!]G@`:@``$J<V!(6W-P2%N!9@`!,0B``*50``DS8$A
+M;<W!(6[$)@`"4F0`('XF`!J```2I%9@``L`R``3-@27"S#$EP\0A``.50``8
+MS(``3<PQ)</$)0`#4F0`('XF`!J```2I.:P'!CVP!P#$-``7FL```Y<```+,
+M``!!P#H`!'VY@`K,&0``!9@``<0A``.50``%S!D``,0E``-29``@?B8`&L]`
+M`!?,@`!-!2@$KGQ!@`%\0<`!E0``!X:```"```33@``%0H``!-Z```5"@``$
+MQSFL!P8]L`<`Q#0`%YK```.7```"S```0<X9``"50``$!9@``58D`"#.60``
+ME\``!,`Z``3,.2%`Q#D``\_``!=\0(`!S(``38@```!1G``@?9V`&M@``%C.
+M&@``E4``!`68``16)``@SEH``)O``%U\0(`!S(``38@```"50``"(=P`,E8D
+M`"#-@2%IS<$A:LX!(6O.02%LF\#]9WQ`@`',@`!-B````!68``+`*@`!S8$E
+MQ\XI)<B50``$5B0`(,R``$W.:27(E\#[&L`Z``3,.27+Q#D``WQ`@`',@`!-
+MB````,04`!D]6``$F8#__LP``%',02&`*$R``,S!(8$4T``?S$$A@LQ!(8/,
+M02&$E0#[",04`!F90/__@````,`6``3$$``QS%4A0,09``/,$`/W@````-@`
+M`%W$#``L),P``93`__Y\0,`!S,$A?,Q!(7W$&``O?$$``7Q!0`'-@2%ZS0$A
+M?L`J``0E5/__.7```T%<``*;```"!!P`0`G<``&9P/__S"DA?\0E``,6;``?
+M05P``LR``$V:P/_Y%/P`']@``%Z;P/KBQ!``,<P0`_>`````?$#``7Q!``$5
+M&``?410`(!D<`#&9@``(S0``6'U-0!K45@``E<#ZU<0@`!R:`/__@````-PZ
+M``#`)@`$S,$A:7TE``K-`2%J"[@``LQ!(6O,02%LFX#__<P``'^9P/T(@```
+M`"1,`/_,3`,`@````,0@`#'$3P,`S.$A18````#`#@$`S```0<S!,$J```5%
+MV$``-,0\`#27P/__D````-@``#3$/``TF\#__Y````#8```TQ#P`-)O`__]\
+M0(`!S(``38@`````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````01J`!```P`2``4`%``O`!4`-0`6`#X`%P!)`"$`3@`D`&L`)0!S`"<`
+M?0`H`&@`*0!^`"H`>P`K`'X`+0"%`"X`C``O`)4`,`"7`#(!%``T`*P`-0!^
+M`#<!-0`Y`84`.@&A`#L!M``\`<P`/0(L`#X!)@`_`1(`0`1O`$$$[0!"!/P`
+M0P4"`$0"2@!%`<P`1@)A`$<"80!(`F$`2@*L`$P"MP!-`ND`3@,U`$\#.0!1
+M`V``4@,]`%,#4`!7`W0`8`.*`&$#HP!B`W@`8P.O`&0#NP!E`\<`9@/3`&<#
+MWP!H`^L`:0/O`&H$(@!K`_,`;`/W`&T#^P!N`_\`;P0#`'`#^P!Q!"@`<@07
+M`',$!P!T!`\`=00S`'H%(@!\!%4`?04[`'X%/@`/!4(`#P5"``\%0@`/!4(`
+M#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/
+M!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%
+M0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"
+M``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`#P5"``\%0@`/!4(`
+3#P5"``\%0@`/!4(`#P5"``\%0@``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_pfp.bin.uu
new file mode 100644
index 0000000..cdc964b
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_pfp.bin.uu
@@ -0,0 +1,197 @@
+begin 644 CAYMAN_pfp.bin
+M?$"``8@```#,@`!`U$``0'Q`@`&(````$$P``220``)\04`!4%@`('V5P!J8
+MP``#T<``&(````"9```#T<``&8````#1P``:@````"2,``+,@`!`S$``0)C`
+M``/,``!2@``#OLP``%3,``!P@``#OLQ``&6`````S```5\P``''$)``^FD#_
+MX<@,`!I\Q0`1T0``0]C``$/,@`!`S```0,Q``$!\0(`!B````,@,`!E\Q0`1
+MT0``0MD``$)\0,`!Q!L``\0?``/$(P`#Q"<``Y6`_\R5P/_+Q"@`$,P``%::
+M@``$Q#``!<\``$#,``!`Q"@`"2`L`'XB[(Y(&J@`)\[``$#,``!`S8``0,W`
+M`$#.``!`SD``0):```+8@`!;S(``0,P``$#,P`!`?$"``8@```#(#``9?,4`
+M$=$``$+90`!"?$#``<0;``/$'P`#Q",``\0G``/$*P`#E8#_J97`_ZC,``!C
+MT0``9,0P`!#,``!6FP``!,0T``7/0`!`S```0,0L``D@,`!^(S"N2!KL`"?/
+M``!`V$``0,V``$#-P`!`S@``0,Y``$#.@`!`EL```MB``%O,@`!`S```0,S`
+M`$!\0(`!B````,08``@EF``!?$)``7Q"@`&5@`-%4JP`('[FP!I\0,`!?$$`
+M`1JX`>B7@``$V$`#]\0X`_>;@/__Q!P`$YG`__\<B``0((@`<!#4``)^U4`1
+MT4``0\T``$/,@`!`SD``0,Z``$#,P`!`W#H``,T``$"7@/]Q?$#``7Q!``&`
+M``"%)(P``IC```K$$``/F0``!<0<``3,``!2S<``0,P``$#$&``()9@``H``
+M`'7$$``1F0#__,0<``;,``!4S<``0,P``$"```";)(P``L04`!*8P``/Q!``
+M$)D```7$'``%S```4\W``$#,``!`Q!@`"!B4`>B4P``"!50`!B@0``%]%0`$
+M?9&`"8```'690/_XQ!P`!<W``$#,``!`S```58```*[,``!?S```8,0D`#Z:
+M0/]#Q!P`!H```,/$'``$S<``0,P``$#,@`!`U$``0'Q`@`&(````Q!P`!8``
+M`,[$'``&@```SL0<``3-P`!`S```0,@,`!C,@`!`S$``0!!0``)]#0`1510`
+M(-$``$/80`!#S```0'Q`@`&(````Q!P`!<W``$#,``!`S(``0-1``$!\0(`!
+MB````"2,``+$%``2F,``$<00`!"9```%Q!P`!<P``%/-P`!`S```0,0,`!O,
+M@`!`S$``0,Q``$#,0`!`?,3``<S``$#40`!`?$"``8@```"90/_VQ!P`!<P`
+M`%7-P`!`S```0(```.M\0,`!Q!``)9D```_$%``B(!@`?B&8"<B90``#S8``
+M0,P``$#,@`!`S,``0-1``$!\0(`!B````'Q`P`'$$``EE0#_\\04`",@&`!^
+M(9@)Z)E```/-@`!`S```0!RHX`@BJ`XHSH``0,S``$#40`!`?$"``8@```!\
+M0,`!Q!``)9D`__?,@`!`S,``0-1``$!\0(`!B````,00`"0@*`!^(J@IB,Z`
+M`$#-``!`S0``0(P``3G$#``AQ!0`)I3```L$$``#@``!+L00`"0@*`!^(J@I
+MJ,Z``$#-``!`S0``0(P``3G$%``FS```8<0D`#Z60`*+A4```,0L``DF[``!
+MFL```I````#`+0`!SL``6R`T`'XC="T(P"P!5L]``$#.P`!`S```0)`````D
+MC``"Q!``$93```>9`/ZYQ!P`!LP``%3-P`!`S```0(````+$%``/Q!P`!)E`
+M_K',``!2S<``0,P``$#$)``^FD#^K'Q`P`%04``@?0U`&M%``!?,``!B@```
+M`,`W__\@B`!P@``!87Q#0`'('``7Q!@`%L]#HIY\04`!?5C`!'S<P!%4T``@
+MS(``0(```7-\08`!S(``0,V``$"```%PP!G__\R``$#-@Z*>?$#``7Q!``%\
+M04`!S,.A^LT#H?G-0Z*=S,``0,T``$#-0`!`S$``0'Q`@`&(````?$#``230
+M``',PZ*?V$``%I4```+8@``6S(``0,S``$"`````?$#``<R``$#,PZ*BS,``
+M0(````!\0,`!%-0`'\R``$!\00`!E4```LS``%@5&``?S,``0,T``$"5@``"
+MS0``6<P``'^```.^(`@`?B"(!^C$(``4'*@`$,Z@`$1\00`!4%0`('Q!@`$&
+M)``!SD``%!6<`!A]%0`:S>``2<V@`$O1(`!!S:``0544``C-0``;F@``!,0D
+M`"N:0``"(=P`,,W``$"```.^Q"``%,8,``H<J``0E,```\Z@`$:```&=S```
+M2(```;?$(``4?$&``0H@``'&%``-QA@`"GU9@`K.```4E8``!,R@`$;-8`!&
+M@``#OLR@`$3-8`!$@``#OLQ``&&```.^Q`P#]MA``_:8P``)Q!@`(,0<`"'$
+M$``0Q!0`#Q$0``%]%0`*F8#_49G`_US8``/V?$#``8````!\0,`!?$$``7Q#
+M@`%\0\`!41``(%/\`"!_OX`:?-#`&@0<`"#3@`!"V(``0M#``$+-P`!"!!P`
+M"`0@``%\`D`!Q!<``\0;``-1F``@?5E`&L0K``/$+P`#Q#,``\0W``,)W``!
+M4NP`('ZN@!I3=``@?S<`&G\K0!)^=D`15J@`/U<P`#]^LH`)?BH`"9G`__&6
+M@/_D4_0`('][0!I]94`155@`(,P``%K-=@``S;8``,0@`!^:`/__@````,0@
+M`"Q\0,`!?$$``<S@`_W-(`/Z410`('S4P!K0P`!"%10`'QD8`/"90``"!#0`
+M`"]<``%]=@`)?5Y`"9F```3,``!"S```38```[X5F``!%2P`"";L``&9@``S
+M%3``#)8```/,``!"@``#O@04`"#-0`!")S```2@H``$$.``@!#P`",07``/$
+M&P`#Q!\``\0C``-]74`-?:'`#7U=0`H6$``?%9P`'WT=``E]%T`)?I*`"0NX
+M``0+_``!FT``$IO`__'$(``LQ@\#_<83`_J:@``)S```39L``8-1%``@?-3`
+M&@04`"#0P`!"S4``0H```B/,``!-EL`!>\P``$Z```.^S```39K```+,``!.
+MEX#]MPNX``'$/P`#FX#__8````#,``!.ED```\P``$*```.^V@``0L0+``/$
+M#P`#Q!,``\07``/$&P`#Q!\``\0G``/$*P`#%?P`'Q:P`!]_\\`)%/``'W_S
+MP`D5<``??_/`"7V(@`)]S,`"E\``#'Y1``)^E4`"?)"`#'S4P`Q\CT`)FL``
+M`BRT``',``!-FT`!4<P``$Z```.^Q"``+,8/`_W&$P/Z410`('S4P!K0P`!"
+M@``"4GQ`P`$4T``>F0``!<R``$#,P`!`U$``0(`````8U``P&-`!Z!C\`#0D
+MS``/!.@"AGQ!@`%\0<`!E,``%(:```"```*0@``#PH```\*```/"@``"C8``
+M`\)1W``@?9X`&H```I]1W``@?9V`&L6B``"50``,19@`!,6F``!29``@?B8`
+M&H```I_%H0``E4``!068``'%I0``4F0`('XF`!H%*`*C?$&``7Q!P`&5```'
+MAH```(```\*```/"@``#PH```\*```*SV```6LX9``"50``$!9@``58@`"#.
+M&0``E\#]4<0Y(4!\0(`!B````%&<`"!]G8`:V```6LX:``"50``$!9@`!%8@
+M`"#.&@``F\``GGQ`@`&(````?$#``7Q!``$9%``[S```6I5``!#$%``>/5@`
+M`IF`__[,``!=*1R``,S!(87-P2&&%10`'\Q!(8?,02&(S$$AB95`_3+$%``>
+MF4#__X````#,@`!`S,``0,T``$#40`!`@````,0H`"S8:`/WS(``0,Q``$#&
+MCP/WF,#__WQ`@`&(````Q"@`+,0L`!'$,``O?O+`"IJ```?$,``/FP``!<0T
+M``3,``!2ST``0,P``$":P``%Q#0`!LP``%3/0`!`S```0'Q`P`'8:`/WS(``
+M0,S``$#40`!`%-``'YD``,F```+;S(``0,Q``$#,0`!`S$``0'Q`P`',P``5
+MS,``0-1``$#8``/V@````'Q`P`$4W``=&-@`/,R``$"9P``%S,``0)F`_/G,
+M``!A@``#OLV``%[,``!AS,``0(```[Y\0,`!4%``((P``QU\T,`:Q"``%,36
+M``!\0X`!F4``!M^#``#/H`!/C``#(=1``'^`````C``#(8````#8```=Q!0`
+M'9E`__^0````V$``'<04`!V50/__D````(P``QW$(``4?$#``<`V_P#$$``5
+MP#`__WSU0`E]48`)?8&`'7SS@`F9@``&WX,``,^@`$^,``,AU$``?X````",
+M``,A@````'Q`P`$4T``>F0``!<R``$#,P`!`U$``0(`````8T`'H&-0`,!C8
+M`#0%*`-%?$(``7Q"0`&5```'AH```(```\*```/"@``#PH```\*```-3$50`
+M$'X6``K-0`!:U&$``)6`_+'$.2%`?$"``8@````15``04B0`('XF`!K-0`!:
+MU&(``)6`_*C$(``?F@#__WQ`@`&(````?$#``13<``B5P``9)-P`$'Q!``%0
+M5``@F<```\4=``"```-H?14`&L4>``!\0@`!?$)``7Q!@`%]Y<`)?>*`#T&L
+M``*:@/R2!NP``PKL``&:P/__)-P`$)G```/%'0``@``#:\4>``"```-KS(``
+M0,S``$#40`!`@````,0<``3-P`!`S```0,R``$#40`!`?$"``8@```#$'``%
+MS<``0,P``$#,@`!`U$``0'Q`@`&(````?$#``230``8Q$``&Q!0`#YD```C,
+M``!2Q"0`/I9``#&90``$Q!P`!,W``$#,``!`S(``0,S``$#40`!`@````'Q`
+MP`%\00`!%1@`'\T``%I1%``@F8```]1-``"`````?4U`&AD<`#'45@``Q"``
+M'Y7`_%K$(``?F@#__X````!\0,`!%-``'R34`/^5```#S%0#`(````#,@`!`
+MS,``0,Q``$"`````Q"``+'Q`P`'$TP,`S(``0,S``$#,``!:S2$A08````#4
+M0`!_@````,0D`#Z60``#?$"``8@```"```/"````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P-\``0#@P`%`9@`!@#"``<`S0`(`-L`"0#)``H`P``+`,L`#`#[``T!
+M"0`.`2$`#P$M`!`#O``1``8`$@`3`!,`'``4`!X`%@`B`"0`*P`E`$T`)@%7
+M`!<!N``8`<8`&@'(`"(##@`C`R4`)P%J`!\!U@`@`@4`*`&+`"D!70`J`7T`
+M*P%N`"\!A@`R`;``-`.*`#4!8``W`S<`/`-=`#X#O``_`9H`0`)W`$$"O@!"
+M`M<`0P+?`$0"]P!*`P$`50-_`%8#A@!@`',`80"3`&(`O`!C`*4`9`"E`&4`
+MI0!F`*4`9P"E`&D`Q0!J`1D`:P#>`&P`W@!M`-X`;@#>`&\`W@!P`.(`<P#0
+M`'0`T`!U`48`>P.:`'T#J@!^`[0````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+3```"`````@````(````"`````@``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_rlc.bin.uu
new file mode 100644
index 0000000..33c1510
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CAYMAN_rlc.bin.uu
@@ -0,0 +1,95 @@
+begin 644 CAYMAN_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X0``;T`
+M````@```F0`````@#```P!``#!R4``$)$``!?-3``)D`__T4B``!B```````
+M```@'```F<``#L@@`*3()`"E?B7`!\@@`)O()`"F'FC__WXJ@!!]Z<`'R"``
+MG!9H`!!^*D`0?>7`!YG``",@'`!`?<S``7S9P!(5W``&.Z```98```,`````
+M"Z```3OD``&60``#``````OD``&$``+7`````,`((`O`#D``S,D``,@,`)<@
+M$``!?"%`!X0``',`````?Y^``<^``*'`""`+P`Y``<S)``#(#`"8(!```7PE
+M0`>$``!S`````'_?P`'/P`"BP`P@"\`2P`"(````S0T``,^Q``#-@``.RSD`
+M`!>X``0?N``/EX#__0````"(`````````,`(`Y'`#``#S,D``(0``&4`````
+MR`@`IP2(``',@`"G,(P`!)C```0`````A``#)-```*?`"`.1B````,P)``#`
+M"`,@A```QP````#("`";?4B`$,R``*3-0`";A``!&P````#("`"<?4B`$,R`
+M`*6(````S4``G,`()-7(B0``?`F`!R`<```@+```P"``#)5``!1\KT`$?.Z`
+M!!]T``%_:T`&?2Z`!!ZH``$JJ```?VM`!I=```<`````(#```7\O``-]L8`(
+M"50``07<``$*(``!!NP``9H`_^X`````P`@DU8@```#-B0``R"@``9:``.(`
+M````(`@``<V```[(#``AS(```8```/L`````R`D]-L@-/3>4P`(P`````,@1
+M/3C(%3TYR!T].L@A/3O()3TU!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]
+MAQ"(``,$C``8R)8`/)5``A_(T@`H?24``0E4``$$S``HF0#_^P````#(D@`X
+M!1``0'T*P`#(U@`$P!P`!,CB`!3(Y@`DS@H!3,YN`4P(S``$"(@`!`KL``0)
+MW``!F<#_^`````#-"@%@S`H!9,U!/4>```++`````"`4```@'```P`P@"\`2
+MP`#-#0``P!`CF,R1``#`$".:S)$``,`0(YS,D0``(!@``,`20`#-#0``P!`C
+MF80``EP`````?6E``,`0(YN$``)<`````'UI0`#`$".=A``"7`````!]:4``
+MF8`!5R`8``&```#4P!)``<@H`"N6@`(H`````,V```Z$``,8`````,@@`*G(
+M)`"J@``!LR`8``&$``(B`````,`((E3(B0``%(@`$,`,(E7(S0``%,P`$'R-
+M0`=]44`'B````"54__^$``%]`````(```;,`````A``"NP````#`,"`(A``!
+M4"`X___`,"`(S#$``,LY``#`,`.8A``!4"`X`0#`,`.8S#$``,L)``#`,"&V
+MB````,PQ``!^HL`/EL```P````!\*@`'?>*``7ZFP`^6P``#`````'PJ0`>(
+M`````````,`,)-3`$"36P`@@"\`:P`#-B0``(!P``<W-``#`&D``S8D``,B9
+M``#)%0``P!I``<V)``#(F0``R1T``'U=0`#`(L``B````,X)```HT`!`F0#_
+M&<@X`*'(/`"B.-P`0)7`_N1_O8``",P`0'S9P!(5W``&R"``GWXZ``'()`"@
+M?GY``80``M?`""`+P`Y``,S)``#(#`"7?"%`!X0``H$`````?Y^``,^``*'`
+M""`+P`Y``<S)``#(#`"8?"5`!X0``H$`````?]_``(```$C/P`"BS[$``,LY
+M```@"``?F(````B(``','``6B`````````#`,`'`B````,^Q``#(#`"#E,``
+MX`````"$``-R(`P``80``AX@.```EX``VB`,``W`,"`)S/$``,`P(`K`-!@8
+M$W0`""-T&!C+#0``?/3`!L@(`!R8@`#/(!P``93`__L`````@``"PWW!P`;(
+M*``#EH`!A@````#-@``.*HP!Y9C`_^,@"``!S(```X```/L`````'J@`_\S`
+M``O.@``,B``````````@%``??)3`!!S,``&8P``%``````E4``&90/_[````
+M`(@`````````P`@@"\`.0`#,R0``A```[P````#("`"7?)2`#)B```G`""35
+MS4``E\U)``!\%(`'A```#@````#,P`"?S,``H<`((`O`#D`!S,D``(0``.\`
+M````R`@`F'R4@`R8@``-P`@DU<U``)C-20``?!2`!X0```X`````S,``H,S`
+M`*+`#"`+P!+``,T-``#(T0``B`````````#,```.S```#B`H`<,@'```R`@`
+MA7^+@`?("`"!E(`!#0````"```+D`````,`(!0`@#```S(P`A\`*("`@B`\%
+M!,P``<R,`(?`"C`P((@>#P3,``',C`"'P`I`0""(*!X$S``!S(P`A\`*0$`@
+MB#(H!,P``<R,`(?`"F!@((@\,@3,``',C`"'P`IP<""(4#P$S``!S(P`A\`*
+M@(`@B%I0!,P``<R,`(?`"H"`((A?6@3,``',C`"'P`J`@""(9%\$S``!S(P`
+MA\`*@(`@B&ED!,P``<R,`(?`"H"`((AN:03,``',C`"'P`J`@""(<VX$S``!
+MS(P`A\`*P,`@B'AS!,P``<R,`(?`"L#`((A]>`3,``',C`"'P`K__R"(@'T$
+MS``!S(P`A\`*`(`@B``@S(``ILP``)B(````S```EYG``!+(,`!`(S```L\`
+M`$"$``#_(#@``\@P`$`?,`/]SP``0(```N3,``!6R"@``I:`_H(@"``!S8``
+M#LR```*```#[`````,@P`$`C,`!`SP``0(0``IH@.``!R#``0!\P`[_/``!`
+M@``"Y,P``%;`,"`#S[$``(@```#+.0``P`@CB,B)``#`#".)R,T``'R,@`;`
+M#"-FR,T``'R,@`;`#".*R,T``,`0(V?)$0``?-#`!L`1``!\T,`'?(R`!A2,
+M`!`<S/__'(C__WR,@`:(````))#__YG``-0$B``!@```RB`<``&$``%8$;@`
+M'X0``AX@.``!A``#<B`,``#`,`'`RSD``"`X``"5P/]NSX```WW!P`:$``%8
+M(#@``(```;//@``#P"`#D<`D``/.80``P`@%`(0``TK,``";S```G,@(`$;(
+M#`!%?,B``4"(``2$``&"S```I\U``*B(````S"$``,DA```>*/__%B``$'ZB
+M@`"(`````````,@(`(90B``((`P`AR`4`!#(D@``S0P```E4``&90/_]!,P`
+M`8@`````````S```*<V``(.$``%8(#@``(```;0`````R!P`J`G<``<)W``$
+M("```#X8`!"5@`#A`````(```W`@%`!`*H@!O)B``#0`````@```^P````#`
+M""35R(D``'P)@`<@'```("P``,`@``R50``0?*]`!'SN@`0?=``!*W0``']K
+M0`:70``&(#```7\O``-]L8`'"50``07<``$*(``!!NP``9H`__(`````P`@D
+MU8@```#-B0``A``"NP`````@.``!P#`#F(0``5`3N``4S```5\`P`YC,,0``
+MB````,L)``#.``"ISD``JL@H`"J6@/X]`````,V```Z$``),`````,@@`*G(
+M)`"J@``!LR`8``'(#`!`P!*@`'T,P`9]#,`,S,``*<@X`(.;@`"=`````(``
+M`;,`````SYP`%LV```[)\``9?SB`#)2`__X`````B``````````@.``!SX``
+M`\P``('("``<E(``'0````#-@``.`````(0``5@1N``?A``#`B`X``+,,0``
+MA``"'B`X``'-@`"!A``#<B`,``"```&S`````!7H``%^)L`0EL#^-WZFP`^6
+MP``#`````'PJ0`=]YH`!?J+`#Y;`_CD`````@``!&7PJ``?(.`!6FX#_'2`<
+M``#(.`!7FX#_&B`<``$@'```R`@`@92`_R$`````R"@``):`_QX@"``!S8``
+M#L@,`"#,@```'!P``"J(`;N4@/^&`````(```FT`````R"@`!):```D`````
+M(`@``<V```[,@``$@```^P````"```!,P#`!P<@H``66@/^@`````"`(``'-
+M@``.S(``!8```/L`````B`````````#(*``HEH#^I`````#-@``.A```50``
+M``#((`"IR"0`JH```;,@&``!P`@#D<`,``/,R0``P`@``(0``TH`````P`P/
+M_\`()-;,R0``P`@#D8@```#,"0``A``!C`````#`"`<`A``#2@````#`"`$`
+MA```QP````#-0`"9P`@!$(0``,<`````S4``FL@0`*'(+`"B?2T``,@(`)D@
+M#`"'("0``(0``G,`````S4``G<@(`)H@#`"'("0``80``G,`````S4``GL@,
+M`)W($`">?-%`$9E```,`````?0#`!X0``2[,P`"CB`````````#`#"`+P!+`
+M`,T-``#`#".:S(T``,`,(YS,C0``P`PCF(@```#,C0``S```@X0``5@1N``?
+M@``!LP````#(U```!,P``08@``$@&`#_?96`!GV1@!)]G8`#?)F`$96`_Q8@
+M&/\`?96`!A68``A]D8`2?9V``WR9@`^5@/\/`````!54`!"60``#`````!54
+M``@@&`#_?95`!H@`````````P#`#D,LY``#`"__^?XN`!A#,`!!_CX`'S[$`
+M`(@```#+.0``````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+!````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_me.bin.uu
new file mode 100644
index 0000000..4c73530
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 CEDAR_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*!`RA_<`2``',``!%S```2GS0
+MP`?,02)<S$&A_-1-``!\0(``H````,R``$V`````S$$B7<P``$7,``!*"$P`
+M`7Q!``!\04``'5C__QE<`_`58``5S8&A`LW!(E;.`2)<E,``!2$D`"#.0:'\
+M@```?0C,``'-`:'\S`&A`GQ`@`"@````S(``37Q`@`!\0,``P"H``GQ!``!]
+M*0`'')0``1R8``8<G`,`%=P`"'Q"``!\0D``E4``#\`N``0%\")8?R\`!\PQ
+M``#(*``$S,$A:<T!(6K.@2%K*;0``LP!(6R70``.*;0``(```+W(-``.*;0`
+M`I=```DIM```P"X`!`7P(EA_+P`'S#$``,@H``2```"]R#0`#I=```1^`H``
+M@```O<@T``XIM``$ET#_20````#.`2%MSD$A;L@H``/(-``.FT``!,@\``Z$
+M``-.S```32GT``"70``'!#"BMH0``-_.@:*WSX&BQ(````#/P:+1*?0``9=`
+M``<$,**ZA```W\Z!HKO/@:+%@````,_!HM(I]``"ET``!P0PHKZ$``#?SH&B
+MO\^!HL:`````S\&BTP0PHL*$``#?SH&BP\^!HL>`````S\&BU,`N``1_+P`'
+MS#$``,@L``3`,``&?O-`(\`P`"!_:X`@B````'^SP"3,``!"@````,Q``!]\
+M0,``?$$``!D4`#V90``3!!0`+H0`!,4$&``IA``"6L@<`!,$%``JA``$Q008
+M`"W-0:*DR!P`$Y7```#('``3S,$A`,T!(0',P2$"S0$A`X``!,+-@:*D'1@0
+M`)6```7('``3*>0`0)9`___('``3S,$A=<T!(7;((``4E@```,@@`!06*``!
+MFH``!,P``$^```3"S```?X```0G,P2%U?$#``'Q!``#,``!%S```2D#4``/-
+M02)<S0&A_,`:``$$'*']?=G`!WQ"```(S``!!B0``08H``+.'0``SET``)C`
+M__K.G0``?$"``*````#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A
+M;<V!(6Z```$WR!P``\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````
+MS>4``,Y!(6G.@2%JS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8
+MI!_H*F@`/):```I\`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4WP"
+M0`!^`D``FD````ID``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D`
+M`,[``!Z```%CR#``!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%H
+MGX````````"```%X?QN`#H```7Q_&X`/@``!@'\;@`R```&$?QN`#8```8A_
+M&X`1@``!C'\;@!"```&1%*0`")N``!D4I``(@``!H1YD`/^;@``5%*0`"(``
+M`:$>9`#_FX``$12D``B```&A'F0`_YN```T4I``(@``!H1YD`/^;@``)%*0`
+M"(```:$>9`#_FX``!12D``B```&A'F0`_Q2D``@>9`#_*F@`/)J`_FT4[``(
+M?$-``'Q#@`!\0\``EL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/
+M]0``S```680`!,4J:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"C,`.
+M``+,``!!@``!K\S!,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``
+M!<`F``3`)__[?24`!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,
+MS0$A:LU!(6N6P/X\S8$A;(0`!,7,``!_R#``&I<```#(,``:@````7Q`@`"$
+M``3%S```?\@4`!7(&``6S4$A:Y;`_B[-@2%L@``!QLP``'_,``/ER"P`(,`.
+M("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(#``)?$$`
+M`'Q!0`#,0`!#S$``1,`.@`!\0D``?$*``!:L`!^6P/X5P#7P`,Y``^$>>``#
+M$GP`"'_WP`9_^\`'%G@`&,_``^+/@`/C$K```G\_``#/``/D@``$47R`P`!\
+M0,``&-`!Z!$H``&5```0!J@!_YZ`````````@``"%\`2"`"```(ER!0`$8``
+M`BS(%``2@``",\S!HJ2```(\'.@`/X```F1\P8`+'-``/RDH``8I+``6?JZ`
+M!\@<`!.:@``]!!0`+H````#,P:*DP!((`'Q!0`!]#,`'P!(`"!58``,57``,
+M?$(``'W1P`82(``4?AY`!WY.@`?.@:*D@````,V!H?[(%``1!!`A&)5```#(
+M%``1U%$``(````#,P:*DR!0`$@00(0:50```R!0`$M11``"`````S,&BI,S!
+MHJ0$$``!S0``&80`!,7,``!_R!``&YD```#($``;@````7Q`@``JH``$*J0`
+M%'XF``<$%``NE@``"`08`"F$``):R!P`$P04`"J$``3%!`P`+<U!HJ0$$"$`
+MR!P`$Y7```#('``3U%$``(``!,+,P:*DA``$Q008`"F$``):R!P`$P04`"J$
+M``3%!!@`+80``EK('``3@````7Q`@`"5P```R!P`$\U!HJ3,`2$`S`$A`<V!
+M(0+-@2$#S8&BI(@```#,``!-'9@``7Q!``!\04``F8``"7Q"``#(/``R$9@`
+M$,@<``L[_``!E\#__\@\`#*```)VR#P`,Q&8`!#('``*._P``9?`___(/``S
+M%6@`'7U90`>:@``$$>0`"GXF``?-P`!FS0$A6,U!(5G.`2%:S,&BI)J``D(%
+M$``$!"P``1+P`!U]<4`'$N``$"(@``S-`2%8S4$A6<X!(5J```3"S,&BI`0\
+M``7/P:*DP#8``H@```#/02`0?$#``!30`!V9```(%-0`')5`_6O`)@`$(F0A
+M5,PE``"`````R"@`!(``!,+-0`!AA``$Q1QT``$<>``"FT```\@,`"F$``--
+MR!0`*YN```,$$``0A``#9,S!HE#-`:!0A``"_@08!`"$``3%S```8\@\`"V$
+M``,,R!``*<@<`"\=W``!R"0`)Y7```G(-``QR#@`,,@\`"U3=``@?[>`)T>X
+M!5#,``!BS_H``)I```#()``GR"@`(SJH``*:@/__R"@`(\`P``'(*``DFH``
+M`,@H`"3/``!;4-@`"!3<`!@AW(``S8$A@,W!(8%1(``(%20`&,X!(8+.02&#
+MS4$AA'Q`@`"@````S(``380`!,4<=``!''@``IM```/(#``JA``#3<@4`"R;
+M@``#!!``$(0``V3,P:)@S0&@8(0``OX$&`F`A``$Q<P``&3(/``NA``##,@0
+M`"K('``O'=P``<@D`"B5P``)R#0`,<@X`##(/``N4W0`('^W@"='N`54S```
+M8L_Z``":0```R"0`*,@H`"7(*``C.J@``IJ`___(*``CFH```,@H`"6```+&
+MP#```@68P``0W``(%.``&,W9``#('``BR"0`(AW<#__-V0`!?F)`!\Y9``+8
+M&%$#V!A1!(@```#8&%$'&_@`\,`V"`"7@``#P#``@(@```#`*@`$ST$A?,\!
+M(7W-`2%^(J@A?P0D``B:0```"F0``<PI``#((``$%C@`'YN`__L$)``(B```
+M``````#(#``DE,``)#C4``&90/_]R!``(WT-``&9`/_[R`P`)(```S'(#``E
+ME,``&SC4``&90/_]R!``(WT-``&9`/_[R`P`)80`!,7,``!_R#P#^YO```#(
+M/`/[T$`#_,`^``32`2'X(_PA^80`!,7,/0``R#@`!!NT`#X?L``$?P+`"Q[H
+M``1^MD`'FD#_]L`^``30``/\?$$``(````%\0(``A``#37Q`P`!\0(``H```
+M`,R``$W(/``.E\```],``^:(````!#P`)L_!HJ3(/`/F"_P``<_``^:;P/_[
+MS```300\``7/P:*DS`&A](0`!,7,``!'B````,P``'^$``-D?$#``'Q`@`"@
+M````S(``300\`"+/P:*DA``$Q<P``$B(````S```?X0``V]\0,``?$"``*``
+M``#,@`!-!#P`(\_!HJ3,`:'SA``$Q<P``$F(````S```?X````!\0,``@```
+M`'Q`P`#`$@`!?%%`!X````#450``S$``9<@X`"W(/``NP#7@`,`R``1_MX`&
+M?_?`!B.X$``C_!``SX$A5,_!(57,,2%5R"P`!,@<`"7()``D?>7`!YG`__[(
+M'``E@````7Q`@`!\0,``?$$``!DH`#"6@``(R"@`)\@D`"B:0```R"0`)YI`
+M``#()``HS``#X'Q!0`!\08``%1P`'\S``,?-``#(E<```\`<@`#-P2`0X8,`
+M``5<(`#,``!-@````-P?00!\0,``?$$``'Q!0`!\08``S,``R<T``,KA@P``
+M!5R@`(````#<'T$`?$#``'Q!``!\04``?$&``,S``,O-``#,X8,```5<Z4"`
+M````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#-S0``SN&#```%7.B`@````-P?
+M00!\0,``?$$``'Q!0`!\08``S,``S\T``-#A@P``!5S``(````#<'T$`?$#`
+M`'Q!``!\04``?$&``,S``-'-``#2X8,```5<\`"`````W!]!`'Q`P`!\00``
+M?$%``'Q!@`#,P`#3S0``U.&#```%7//\@````-P?00#40R``?$"``*````#,
+M@`!-U$.@`'Q`@`"@````S(``3=1#Z4!\0(``H````,R``$W40^B`?$"``*``
+M``#,@`!-U$/``'Q`@`"@````S(``3=1#\`!\0(``H````,R``$W40_/\?$"`
+M`*````#,@`!-!!R@`,Q#H`!\0,``V!_!`'Q`@`"@````S(``300<P`#,0\``
+M?$#``-@?P0!\0(``H````,R``$U\0,``R!,``I3```/(%P`"R!L``@0<\_S,
+M`_/\V!_!`-@?P0!\0(``H````,R``$W`'@`0R`P`*5#0``@05``"@``$*'T5
+M@"#`'@`@R`P`*E#0``@(5`0`$50``GU1@"#-P`!BU%H``'Q`@`"@````S(``
+M37Q`P``<T``#$2@``94```H&J`0RGH```'Q!@`"```1`?$'``(``!$9\0<``
+M@``$3'Q!P`!\08``?$'``!34`!`%5*``@````,V5``#`(@`$!9B@`'VA@`?,
+M&0``@``$/,@8``3`(@`$S8$EUB(@)=?,(0``@``$/,@8``3-@2%MS<$A;H``
+M!#S(&``#?$#``,@0`^'(%`/DR!@#XL@<`^/-@2%IS<$A:LS!(6O,`2%L!"``
+M!'VA@`!]ED`,ED#[I,V``^(=*``#P"WP`!$8``A]K8`&?:F`!X````#-@`/B
+M?$#``(````#,3`/@'(S__]1-``!\0(``H````,R``$W(%``C,5@`!)6`___(
+M%``CS```6\Q!(8`@3(``S,$A@130`!_,02&"S$$A@Y4`^XC,02&$R!0`(YE`
+M___(%``C@````7Q`@`#`%@`$(50A0,Q5``#(&``$@````,P``^!\0,``&-``
+M.,`6`("5```#P"H`!'S4P`?,P2%\S$$A?<Q!(7Y\08``%/P`'QV8__\YL``#
+M(J`A?YL```-!G``%!!P`0)G````)W``!S"$``,@D``06;``?09P`!9K`__K,
+M@`!-F\#[8@````"`````S``#X'Q`P`!\00``%1@`'U$4`""9@``+&1P`,<T`
+M`&)]34`GU%8``)7`^U7((``FF@```,@@`":````!?$"``.`Z``#`)@`$S,$A
+M:7TE``?-`2%J"[@``LQ!(6N;@/_^S$$A;)G`_0S,``!_@````7Q`@`#`#@$`
+MS```0<S!,$K(/`!_S```?X````#,``!_S```?X@```#,``!_````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01H`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=P`P`'D`,@#J`#0`C@`U`&(`.0#L`#H!%``[`2D`/`%!
+M`#T!L0`_`.D`001M`$($?P!#!(4`1`'6`$4!00!&`?H`1P'Z`$@!^@!*`I$`
+M2P-V`$P"G0!-`M0`3@,@`$\#*0!1`VH`4@-(`%,#7P!4`W@`5P-Z`&`#D@!A
+M`ZH`8@-^`&,#M`!D`[X`90/(`&8#T@!G`]P`:`/F`&D#Z@!J!!P`:P/N`&P#
+M\@!M`_8`;@/Z`&\#_@!P`_8`<00B`'($$`!S!`(`=`0)`'4$+0!Z!*(`?`10
+M`'T$90`/!+X`#P2^``\$O@`/!+X`#P2^``\$O@`/!+X`#P2^``\$O@`/!+X`
+M#P2^``\$O@`/!+X`#P2^``\$O@`/!+X`#P2^``\$O@`/!+X`#P2^``\$O@`/
+.!+X`#P2^``\$O@`/!+X`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_pfp.bin.uu
new file mode 100644
index 0000000..c0e0e21
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 CEDAR_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```,WS$``*ID```4`````S$``*X```S?,0``LS$``+8``
+M`S?,0``N'(P``LR``$"8P``$S$``0(```S?,``!2@``#-\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$/-
+M0`!#R!P`'=$``$.9P``%S```5<@@`!_8``/`S```0,@H`!;8``;`&J@`)Y:`
+M``/,``!`T(``7,R``$#,``!`S$``0'Q`@`"@````!"@``<@0`"S(#``K41``
+M('S0P"=\Q0`@11@`",F>``#()`/]?>:`$9:```-^7L`!?`+`!L[#HIY5%``@
+MS```;,T``&W-0`!MS0``0\U``$/('``=T4``0YG```7,``!5R"``']@``\#,
+M``!`R"@`%M@`!L`:J``GEH```\R``$#0@`!<S(``0,P``$#,0`!`?$"``*``
+M```$*``!R!@`%1V8``%\0D``E8`"P'Q"@`#('``@P#?``'Q`P`!\00``?+2`
+M!L`V``,:N`'HEX``!]!``^"$``,ZS```?\@X`^";@```R#@#X)G```#('``@
+M?+2`!Q#4``)]94``S4``0\Z``$/-``!#S(``0,Y``$#.@`!`S,``0.`Z``"7
+M@/]NS0``0'Q`P`"```"(?$$``!R,``+($``<F,``"<@@`!^9```$R!P`!H0`
+M`SW,``!2R!@`%8```'0=F``"R!``'ID`__S('``(A``#/<P``%3(&``5@```
+M=!V8``(<C``"R!``'9C```_(%`!)F0``!<@@`!_('``'A``#/<P``%/(&``5
+ME,```QB4`>@%5``&(!```7T5``.```!T?9&`!IE`__C((``?A``#/<@<``>`
+M``"SS```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/TS0`#]LT`
+M`_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``<@@`!^```#8V``$
+M0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!R"``']@``\"```#H
+MS```0,@@`!^```#GV``$0,@@`!_8``-`S```0,@,`"G($``JS(``0,Q``$!1
+M$``@?-#`)Q!0``)]#0`@510`(,T``$/-0`!#T$``0\P``$!\0(``H`````0H
+M``'((``?V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=F,``
+M$L@4`$F9```%R"``'\@<``>$``,]S```4\@,`"_,@`!`S$``0,Q``$#,0`!`
+M?,3``,S``$#40`!`?$"``*`````$*``!F4#_]<@@`!^$``,]R!P`!X```0G,
+M``!N?$#``,@0`$>9```+R!0`1)E```3(&``)S8``0,P``$"```$SS(``0'Q`
+MP`#($`!'E0#_]\@4`$690``$R!@`"LV``$#,``!`@``!,]@`"$!\0,``R!``
+M1YD`__P`````S(``0,S``$#40`!`?$"``*`````$*``!R!``1M@`!T#-``!`
+MA``!2LT``$#(#`!#E,``"L@4`$B```%#!!```\@0`$;8``?`S0``0(0``4K-
+M``!`R!0`2)U```#,``!JR"@`%AZH``&:@``#P"D``8@```#`+`%6SH``7-@`
+M",#.P`!`B````,P``$`<C``"R!``'L@@`!^4P``(R!0`')D```K('``(A``#
+M/<P``%2```%ES(``0)E```3('``&A``#/<P``%+,@`!`@````-1``$#,0``G
+MS$``*(```S?,``!KP#(``\`W__^```%P?+"`!WQ#0`#((``HR!P`)\@8`";/
+M0Z*>?$%``%(@`"!]X<`G?5C``WS<P"!4T``@@``!A<R``$!\08``S(``0(``
+M`8+-@`!`P!G__\R``$#-@Z*>?$#``'Q!``!\04``S,.A^LT#H?G-0Z*=S,``
+M0,T``$#-0`!`S$``0'Q`@`"@````!"@``7Q`P``<T``!S,.BGY4```/00``F
+MT(``)LR``$"`````S,``0'Q`P`#,@`!`S,.BHH````#,P`!`?$#``!34`!_,
+M@`!`E4```WQ!``#,P`!9%1@`'\S``$"5@``#S0``0,T``%J```,WS```?\@@
+M`!]\00``V"`"1,X@`$1\04``?$&``,V@`$G-(`!!S6``0<V@`$$5$``($50`
+M&'U3P`?/P``O!B```<X``%B```,WS```?\@@`!_*#``7E,``!7Q!``#8(`+&
+M@``!K\X@`$;,``!(@``!Q0````#((``??$&```H@``'*%``:RA@`%WU9@`>5
+M@``%S@``6,R@`$:`````S6``1LR@`$2`````S6``1(```S?,0`!JS(``0(``
+M``#40`!`?$#``'Q!``!\0X``?$/```0<``+/@`!"S\``0LW``$($'``@S,``
+M0LT``$+-P`!"!!P`!P0@``%\`D``R!0``\@8``-1F``@?5E`)\@H``/(+``#
+MR#```\@T``-2[``@?JZ`)U-T`"!_-P`G?RM`(7YV0"!6J``_5S``/WZR@`9^
+M*@`&F<#_\@G<``&6@/_A4_0`('][0"=]94`@55@`(,P``%O-=@``S;8``,@@
+M`$&:````R"``08````%\0(``?$#``'Q!``#,P`/^S0`#_\S``$+-``!"%10`
+M'QD8`/`G7``!?78`!IF```5]7D`&S```0H```S?,``!-%9@``14L``B9@``Q
+M'NP``98```05,``,@``#-\P``$($%``@S4``0A\P``$@*``!!#@`(`0\``?(
+M%``#R!@``\@<``/((``#?5U`#7VAP`U]74`'%A``'Q6<`!]]'0`&?1=`!GZ2
+M@`:;0``2"[@`!)O`__(+_``!R`P#_IJ```G($`/_FP``_<P``$T$%``@S,``
+M0LT``$*```(DS4``0I;``/;,``!-@``#-\P``$Z:P``#S```3<P``$Z7@/VX
+MXX,``(````#<`P'_ED``!,P``$Z```,WS```0M(``$+("``#R`P``\@0``/(
+M%``#R!@``\@<``/()``#R"@``Q7\`!\6L``??_/`!A3P`!]_\\`&%7``'W_S
+MP`9]B(`!E\``#7W,P`%^40`!?I5``7R0@`Q\U,`,FL```WR/0`8DM``!FT``
+MS<P``$V```,WS```3L@,`_[($`/_S,``0H```E#-``!"?$#``'Q!```9%``[
+MS```6Y5``!/(%`!`,5@``I6`___(%`!`S```8R$<@`#,P2&%S<$AAA44`!_,
+M02&'S$$AB)5`_7W,02&)R!0`0)E`___(%`!`@````7Q`@`#,@`!`S,``0,T`
+M`$"`````U$``0-"``^#,@`!`A``#.LQ``$#(#`/@F,```,@,`^!\0(``H```
+M`'Z"@`9\0,``A``"HA30`!^9`/UDT$`#X(0``SK,``!_@``"E,@,`^#,@`!`
+MS,``0(@```#40`!`S(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`
+M-___T``#^]```_R`````ST`#_7Q`P``4W``=F<``!\R``$`8W``\F<``?\S`
+M`$"```,WS```:AC8`#S-@`!FS```:H```S?,P`!`?$#``%!0`""$``,ZS```
+M77S0P"?((``?R-8``)E```A\0X``XX,``,^@`$^$``,ZS```7H````#40`!_
+M@``#-\P``%Z$``,ZS```7<@@`!]\0,``P#;_`,@0`"'`,#__?/5`!GU1@`9]
+M@8`*F8``"'SS@`;C@P``SZ``3X0``SK,``!>@````-1``'^```,WS```7H0`
+M`SI\0,``%-P`")7``!D<W``0?$$``)G```105``@@``"\LD=``!]%0`GR1X`
+M`'Q"``!\0D``?$&``'WEP`9]XH`1FH#]"4&L``6:P```"NP``1S<`!"9P``$
+M`````(```O7)'0``@``"]<D>``#,@`!`S,``0(````#40`!`R"``']@``T#,
+M``!`S(``0-1``$!\0(``H`````0H``'((``?V``#P,P``$#,@`!`U$``0'Q`
+M@`"@````!"@``7Q`P``<T``&*1``!ID```?(%``<F4``!<P``%+('``&A``#
+M/<@@`!_,@`!`S,``0(````#40`!`?$#``'Q!```5&``?S0``6YF```11%``@
+M@````-1-``!]34`G&1P`,=16``"5P/S1R"``09H```#((`!!@````7Q`@`"`
+M````U$``?\P``'^`````S```?\P``'^(````S```?\W``$"(````S```0```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,&``0##@`%`:L`!@#6``<`Y0`(`/@`"0#>``H`TP`+`.(`#`$:
+M``T!)``.`3@`#P%"`!`#-0`1``H`$@`8`!,`(``6`"(`)``Q`"4`3``F`6<`
+M%P''`!@!U0`B`L$`(P+2`"<!?``?`=H`(`(*`"@!G@`I`6L`*@&0`"L!@``O
+M`9D`,@&]`#0#%@`U`6\`.0'7`#P"Y@`^`S4`/P&K`$$"<P!"`H\`0P*9`$0"
+MI@!*`K,`50,)`%8#$0!@`'(`80"7`&(`P0!C`*H`9`"J`&4`J@!F`*H`9P"J
+M`&@`S@!I`-D`:@$N`&L`^P!L`/L`;0#[`&X`^P!O`/L`<`$``',`Z`!T`.@`
+M=0%5`'L#)`````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_rlc.bin.uu
new file mode 100644
index 0000000..5b69bab
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CEDAR_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 CEDAR_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X```/P`
+M````P#`@`\^Q``"(````RSD``,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`
+M````````A```?`````"```#%`````,GX`(.;@``$`````(```,4`````S!P`
+M@X0``-@1N``?@```Q0````#(*``#EH``M`````#-@``.*HP!Y9C``"0@"``!
+MS(```X```!@`````(#@``<^```/($`""S```@<@(`!J4@``R`````,V```X`
+M````A```T2`X``+,,0``A```#"`X``'-@`"!A```\R`,``"```#%`````"J(
+M`;R8@/_8`````)4`_](`````R"@``I:``.$@"``!S8``#LR```*````8````
+M`,G,`(.4P`"3`````(0``/,@#``!A```#"`X``"7@`"-(`P`#<`P(`G,\0``
+MP#`@"L`T&!@3=``((W08&,L-``!\],`&R`@`&IB``((@'``!E,#_^P````"`
+M```P?<'`!L@X`%:;@``S(!P``,@X`%>;@``P(!P``2`<``#("`"!E(#_V0``
+M``#(*```EH#_UB`(``'-@``.S(```!P<```JB`&[E(#_RP````"```#3````
+M`!ZH`/_.@``,B`````````#(,`!`(S``0,\``$"$``"F(#@``<@P`$`?,`._
+MSP``0(```&?,``!6A```$`````#`,"`(A```N2`X___`,"`(S#$``,LY``#`
+M,`.8A```N2`X`0#`,`.8S#$``,L)``#`,"&VB````,PQ``"9P/_ER#``0",P
+M``+/``!`A```BB`X``/(,`!`'S`#_<\``$"```!GS```5H0``!``````(#@`
+M`<`P`YB$``"Y$[@`%,P``%?`,`.8S#$``(@```#+"0``S[$``,V```[+.0``
+M%[@`!)>`__X`````B`````````#/L0``RSD``"`(`!^8@```"(@``<P<`!;)
+M\``;EP#__P````"(`````````,P```[,```.R!``@B`H`<,@'```R!``@L@(
+M`(5_BX`'R`@`@92`_V<`````@```9P````"```"QP#`!P<V<`(.$``#8(#@`
+M`)4`__$`````P#`!P(@```#/L0``R"@`!):`_^D`````(`@``<V```[,@``$
+M@```&`````"$``#8$;@`'X0```P@.``!A```\R`,``#`,`'`RSD``"`X``"5
+MP/_9SX```WW!P`:$``#8(#@``(```,7/@``#P#`#D,LY``#`"__^?XN`!A#,
+M`!!_CX`'S[$``(@```#+.0``R`D]-L@-/3>4P/\[`````,@1/3C(%3TYR!T]
+M.L@A/3O()3TU!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8
+MR)8`/)5`_RK(T@`H?24``0E4``$$S``HF0#_^P````#(D@`X!1``0'T*P`#(
+MU@`$P!P`!,CB`!3(Y@`DS@H!3,YN`4P(S``$"(@`!`KL``0)W``!F<#_^```
+M``#-"@%@S`H!9,U!/4>````Y`````,@H``&6@/[[`````"`(``'-@``.S(``
+M`8```!@`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_me.bin.uu
new file mode 100644
index 0000000..ac9b3cf
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 CYPRESS_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*!`RA_<`2``',``!%S```2GS0
+MP`?,02)<S$&A_-1-``!\0(``H````,R``$V`````S$$B7<P``$7,``!*"$P`
+M`7Q!``!\04``'5C__QE<`_`58``5S8&A`LW!(E;.`2)<E,``!2$D`"#.0:'\
+M@```?0C,``'-`:'\S`&A`GQ`@`"@````S(``37Q`@`!\0,``P"H``GQ!``!]
+M*0`'')0``1R8``8<G`,`%=P`"'Q"``!\0D``E4``#\`N``0%\")8?R\`!\PQ
+M``#(*``$S,$A:<T!(6K.@2%K*;0``LP!(6R70``.*;0``(```+W(-``.*;0`
+M`I=```DIM```P"X`!`7P(EA_+P`'S#$``,@H``2```"]R#0`#I=```1^`H``
+M@```O<@T``XIM``$ET#_20````#.`2%MSD$A;L@H``/(-``.FT``!,@\``Z$
+M``-.S```32GT``"70``'!#"BMH0``-_.@:*WSX&BQ(````#/P:+1*?0``9=`
+M``<$,**ZA```W\Z!HKO/@:+%@````,_!HM(I]``"ET``!P0PHKZ$``#?SH&B
+MO\^!HL:`````S\&BTP0PHL*$``#?SH&BP\^!HL>`````S\&BU,`N``1_+P`'
+MS#$``,@L``3`,``&?O-`(\`P`"!_:X`@B````'^SP"3,``!"@````,Q``!]\
+M0,``?$$``!D4`#V90``3!!0`+H0`!-H$&``IA``"6L@<`!,$%``JA``$V@08
+M`"W-0:*DR!P`$Y7```#('``3S,$A`,T!(0',P2$"S0$A`X``!-?-@:*D'1@0
+M`)6```7('``3*>0`0)9`___('``3S,$A=<T!(7;((``4E@```,@@`!06*``!
+MFH``!,P``$^```37S```?X```0G,P2%U?$#``'Q!``#,``!%S```2D#4``/-
+M02)<S0&A_,`:``$$'*']?=G`!WQ"```(S``!!B0``08H``+.'0``SET``)C`
+M__K.G0``?$"``*````#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A
+M;<V!(6Z```$WR!P``\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````
+MS>4``,Y!(6G.@2%JS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8
+MI!_H*F@`/):```I\`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4WP"
+M0`!^`D``FD````ID``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D`
+M`,[``!Z```%CR#``!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%H
+MGX````````"```%X?QN`#H```7Q_&X`/@``!@'\;@`R```&$?QN`#8```8A_
+M&X`1@``!C'\;@!"```&1%*0`")N``!D4I``(@``!H1YD`/^;@``5%*0`"(``
+M`:$>9`#_FX``$12D``B```&A'F0`_YN```T4I``(@``!H1YD`/^;@``)%*0`
+M"(```:$>9`#_FX``!12D``B```&A'F0`_Q2D``@>9`#_*F@`/)J`_FT4[``(
+M?$-``'Q#@`!\0\``EL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/
+M]0``S```680`!-HJ:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"C,`.
+M``+,``!!@``!K\S!,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``
+M!<`F``3`)__[?24`!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,
+MS0$A:LU!(6N6P/X\S8$A;(0`!-K,``!_R#``&I<```#(,``:@````7Q`@`"$
+M``3:S```?\@4`!7(&``6S4$A:Y;`_B[-@2%L@``!QLP``'_,``/ER"P`(,`.
+M("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(#``)?$$`
+M`'Q!0`#,0`!#S$``1,`.@`!\0D``?$*``!:L`!^6P/X5P#7P`,Y``^$>>``#
+M$GP`"'_WP`9_^\`'%G@`&,_``^+/@`/C$K```G\_``#/``/D@``$8WR`P`!\
+M0,``&-`!Z!$H``&5```0!J@!_YZ`````````@``"%\`2"`"```(ER!0`$8``
+M`BS(%``2@``",\S!HJ2```(\'.@`/X```F1\P8`+'-``/RDH``8I+``6?JZ`
+M!\@<`!.:@``]!!0`+H````#,P:*DP!((`'Q!0`!]#,`'P!(`"!58``,57``,
+M?$(``'W1P`82(``4?AY`!WY.@`?.@:*D@````,V!H?[(%``1!!`A&)5```#(
+M%``1U%$``(````#,P:*DR!0`$@00(0:50```R!0`$M11``"`````S,&BI,S!
+MHJ0$$``!S0``&80`!-K,``!_R!``&YD```#($``;@````7Q`@``JH``$*J0`
+M%'XF``<$%``NE@``"`08`"F$``):R!P`$P04`"J$``3:!`P`+<U!HJ0$$"$`
+MR!P`$Y7```#('``3U%$``(``!-?,P:*DA``$V@08`"F$``):R!P`$P04`"J$
+M``3:!!@`+80``EK('``3@````7Q`@`"5P```R!P`$\U!HJ3,`2$`S`$A`<V!
+M(0+-@2$#S8&BI(@```#,``!-'9@``7Q!``!\04``F8``"7Q"``#(/``R$9@`
+M$,@<``L[_``!E\#__\@\`#*```)VR#P`,Q&8`!#('``*._P``9?`___(/``S
+M%6@`'7U90`>:@``$$>0`"GXF``?-P`!FS0$A6,U!(5G.`2%:S,&BI)J``E<%
+M$``$!"P``1+P`!U]<4`'$N``$"(@``S-`2%8S4$A6<X!(5J```37S,&BI`0\
+M``7/P:*DP#8``H@```#/02`0?$#``!30`!V9```(%-0`')5`_6O`)@`$(F0A
+M5,PE``"`````R"@`!(``!-?-0`!AA``$VGQ!0``==``!''@``IM```/(#``I
+MA``#3154`!";@``#!!``$(0``W',P:)0S0&@4(0``OX$&`0`A``$VLP``&/(
+M/``MA``##,@0`"G('``O'=P``<@D`">5P``,R#0`,<@X`##(/``M%_P`$!/\
+M`!!_U\`'4W0`('^W@"='N`50S```8L_Z``":0```R"0`)\`P``'(*``DFH``
+M`,@H`"3/``!;4-@`"!3<`!@AW(``S8$A@,W!(8%1(``(%20`&,X!(8+.02&#
+MS4$AA'Q`@`"@````S(``380`!-I\04``'70``1QX``*;0``#R`P`*H0``TT5
+M5``0FX```P00`!"$``-QS,&B8,T!H&"$``+^!!@)@(0`!-K,``!DR#P`+H0`
+M`PS($``JR!P`+QW<``'()``HE<``#,@T`#'(.``PR#P`+A?\`!`3_``0?]?`
+M!U-T`"!_MX`G1[@%5,P``&+/^@``FD```,@D`"C(*``EFH```,@H`"6```+&
+MP#```@68P``0W``(%.``&,W9``#('``BR"0`(AW<#__-V0`!?F)`!\Y9``+8
+M&%$#V!A1!(@```#8&%$'&_@`\,`V"`"7@``#P#``@(@```#`*@`$ST$A?,\!
+M(7W-`2%^(J@A?P0D``B:0```"F0``<PI``#((``$%C@`'YN`__L$)``(B```
+M``````#(#``DE,``)#C4``&90/_]R!``(WT-``&9`/_[R`P`)(```S'(#``E
+ME,``&SC4``&90/_]R!``(WT-``&9`/_[R`P`)80`!-K,``!_R#P#^YO```#(
+M/`/[T$`#_,`^``32`2'X(_PA^80`!-K,/0``R#@`!!NT`#X?L``$?P+`"Q[H
+M``1^MD`'FD#_]L`^``30``/\?$$``(````%\0(``A``#37Q`P`!\0(``H```
+M`,R``$W(/``.E\```],``^:(````!#P`)L_!HJ3(/`/F"_P``<_``^:;P/_[
+MS```3<@\`^67P``,R#P`$Y?```#(/``3!#PA`,P]``#,/0``S#T``,P]```$
+M/``IS\&BI,R``$T$/``%S\&BI,P!H?2$``3:S```1X@```#,``!_A``#<7Q`
+MP`!\0(``H````,R``$T$/``BS\&BI(0`!-K,``!(B````,P``'^$``-\?$#`
+M`'Q`@`"@````S(``3<@\`^67P``,R#P`$Y?```#(/``3!#PA`,P]``#,/0``
+MS#T``,P]```$/``IS\&BI,R``$T$/``CS\&BI,P!H?.$``3:S```28@```#,
+M``!_@````'Q`P`"`````?$#``,`2``%\44`'@````-15``"$``3:S$``9<@<
+M`"7()``D?>7`!YG`__[('``E@````7Q`@`!\0,``?$$``'Q!0`!\08``%1P`
+M'\S``,?-``#(E<```\`<@`#-P2`0X8,```5<(`#,``!-@````-P?00!\0,``
+M?$$``'Q!0`!\08``S,``R<T``,KA@P``!5R@`(````#<'T$`?$#``'Q!``!\
+M04``?$&``,S``,O-``#,X8,```5<Z4"`````W!]!`'Q`P`!\00``?$%``'Q!
+M@`#,P`#-S0``SN&#```%7.B`@````-P?00!\0,``?$$``'Q!0`!\08``S,``
+MS\T``-#A@P``!5S``(````#<'T$`?$#``'Q!``!\04``?$&``,S``-'-``#2
+MX8,```5<\`"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#3S0``U.&#```%
+M7//\@````-P?00#40R``?$"``*````#,@`!-U$.@`'Q`@`"@````S(``3=1#
+MZ4!\0(``H````,R``$W40^B`?$"``*````#,@`!-U$/``'Q`@`"@````S(``
+M3=1#\`!\0(``H````,R``$W40_/\?$"``*````#,@`!-!!R@`,Q#H`!\0,``
+MV!_!`'Q`@`"@````S(``300<P`#,0\``?$#``-@?P0!\0(``H````,R``$U\
+M0,``R!,``I3```/(%P`"R!L``@0<\_S,`_/\V!_!`-@?P0!\0(``H````,R`
+M`$W(*``FR"P`*"JP`/\J]`#_?W.`!YN`__O`'@`0R`P`*5#0``@05``"@``$
+M.GT5@"#(*``FR"P`)RJP`/\J]`#_?W.`!YN`__O`'@`@R`P`*E#0``@(5`0`
+M$50``GU1@"#-P`!BU%H``'Q`@`"@````S(``37Q`P``<T``#$2@``94```H&
+MJ`1$GH```'Q!@`"```12?$'``(``!%A\0<``@``$7GQ!P`!\08``?$'``!34
+M`!`%5*``@````,V5``#`(@`$!9B@`'VA@`?,&0``@``$3L@8``3`(@`$S8$E
+MUB(@)=?,(0``@``$3L@8``3-@2%MS<$A;H``!$[(&``#?$#``,@0`^'(%`/D
+MR!@#XL@<`^/-@2%IS<$A:LS!(6O,`2%L!"``!'VA@`!]ED`,ED#[DLV``^(=
+M*``#P"WP`!$8``A]K8`&?:F`!X````#-@`/B?$#``(````#,3`/@'(S__]1-
+M``!\0(``H````,R``$W(%``C,5@`!)6`___(%``CS```6\Q!(8`@3(``S,$A
+M@130`!_,02&"S$$A@Y4`^W;,02&$R!0`(YE`___(%``C@````7Q`@`#`%@`$
+M(50A0,Q5``#(&``$@````,P``^#`*@`$?$#``,S!(7S,02%]S$$A?GQ!@``4
+M_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`F<````G<``',(0``R"0`!!9L
+M`!]!G``%FL#_^LR``$V;P/M4`````(````#,``/@?$#``'Q!```5&``?410`
+M()F``!(9'``QR"@`)\@L`"@JL`#_*O0`_W]S@`>;@/_\R"@`)\T``&)]34`G
+MU%8``)7`^T#((``FF@```,@@`":````!?$"``.`Z``#`)@`$S,$A:7TE``?-
+M`2%J"[@``LQ!(6N;@/_^S$$A;)G`_/?,``!_@````7Q`@`#`#@$`S```0<S!
+M,$K(/`!_S```?X````#,``!_S```?X@```#,``!_````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01Z`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=P`P`'D`,@#J`#0`C@`U`&(`.0#L`#H!%``[`2D`/`%!
+M`#T!L0`_`.D`001_`$($D0!#!)<`1`'6`$4!00!&`?H`1P'Z`$@!^@!*`I$`
+M2P.0`$P"G0!-`M0`3@,@`$\#*0!1`W<`4@-(`%,#;`!4`Y(`5P.4`&`#H0!A
+M`[``8@.8`&,#N@!D`\0`90/.`&8#V`!G`^(`:`/L`&D#\`!J!"(`:P/T`&P#
+M^`!M`_P`;@0``&\$!`!P`_P`<00N`'($%@!S!`@`=`0/`'4$/P!Z!+``?`1B
+M`'T$=P`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`
+M#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/
+.!-,`#P33``\$TP`/!-,`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_pfp.bin.uu
new file mode 100644
index 0000000..d45dccb
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 CYPRESS_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```.MS$``*ID```4`````S$``*X```ZW,0``LS$``+8``
+M`ZW,0``N'(P``LR``$"8P``$S$``0(```ZW,``!2@``#K<P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$/-
+M0`!#R!P`'=$``$.9P``%S```5<@@`!_8``/`S```0,@H`!;8``;`&J@`)Y:`
+M``/,``!`T(``7,R``$#,``!`S$``0'Q`@`"@````!"@``<@0`"S(#``K41``
+M('S0P"=\Q0`@11@`",F>``#()`/]?>:`$9:```-^7L`!?`+`!L[#HIY5%``@
+MS```;,T``&W-0`!MS0``0\U``$/('``=T4``0YG```7,``!5R"``']@``\#,
+M``!`R"@`%M@`!L`:J``GEH```\R``$#0@`!<S(``0,P``$#,0`!`R#4AHQMX
+M!_`KM``(ET#__<@X`_R;@```R#@#_(0``[#00`/[R#@#_)N`__L$/``;S```
+M6X0``[#/P2'XR#DA^1NT`'B;0/_\S```6]```_M\0(``H`````0H``'(&``5
+M'9@``7Q"0`"5@`,B?$*``,@<`"#`-\``?$#``'Q!``!\M(`&P#8``YG```#(
+M'``@?+2`!Q#4``)]94``S4``0\Z``$/-``!#S(``0,Y``$#.@`!`S,``0.`Z
+M``"7@/]BS0``0'Q`P`"```"4?$$``!R,``+($``<F,``"<@@`!^9```$R!P`
+M!H0``[/,``!2R!@`%8```(@=F``"R!``'ID`__S('``(A``#L\P``%3(&``5
+M@```B!V8``(<C``"R!``'9C```_(%`!)F0``!<@@`!_('``'A``#L\P``%/(
+M&``5E,```QB4`>@%5``&(!```7T5``.```"(?9&`!IE`__C((``?A``#L\@<
+M``>```"_S```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/TS0`#
+M]LT``_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``<@@`!^```#D
+MV``$0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!R"``']@``\"`
+M``#TS```0,@@`!^```#SV``$0,@@`!_8``-`S```0,@,`"G($``JS(``0,Q`
+M`$!1$``@?-#`)Q!0``)]#0`@510`(,T``$/-0`!#T$``0\P``$!\0(``H```
+M``0H``'((``?V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=
+MF,``$L@4`$F9```%R"``'\@<``>$``.SS```4\@,`"_,@`!`S$``0,Q``$#,
+M0`!`?,3``,S``$#40`!`?$"``*`````$*``!F4#_]<@@`!^$``.SR!P`!X``
+M`17,``!N?$#``,@0`$<<W`/_&)3_\)D```]]74``R!@`1)F```3(&``)S8``
+M0,P``$"```%=R!@#\'Q`P`#($`!''-P#_QB4__"5`/_U?5U``,@8`$69@``$
+MR!@`"LV``$#,``!`R!@#]1V<``,5F``"R:0#]A'<``-^7H`$'J@`_P54``<5
+M5``#?6K`$);```@$+`#_?M[``W["P`M^;D`&?5U``WY60`?.6`/VV``(0,S`
+M`$#40`!`?$"``*`````$*``!?$#``,@0`$<<W`/_&)3_\)D`_^1]74``R!@#
+M\!V<``,5F``"R:0#\1'<``-^7H`$'J@`_P54``<55``#?6K`$);```@$+`#_
+M?M[``W["P`M^;D`&?5U``WY60`?.6`/QS(``0,S``$#40`!`?$"``*`````$
+M*``!R!``1L@8`_`%F``!'9@`#\V``_`=G``#&9@`8LFD`_$1W``#!"P`_W[>
+MP`-^PL`+?FY`!LY8`_$$&```!!P``(0``<')Y`/QA``!P<GD`_&$``'!R>0#
+M\80``<')Y`/Q?2$`!]@`!T#-``!`A``!MLT``$#(#`!#E,``(L@4`$B```&7
+M!!```\@0`$;(&`/U!9@``1V8``_-@`/U'9P``QF8`&+)I`/V$=P``P0L`/]^
+MWL`#?L+`"WYN0`;.6`/V!!@```0<``"$``'!R>0#]H0``<')Y`/VA``!P<GD
+M`_:$``'!R>0#]GTA``?8``?`S0``0(0``;;-``!`R!0`2)U```#,``!JR"@`
+M%AZH``&:@``#P"D``8@```#`+`%6SH``7-@`",#.P`!`B````,P``$`>:`#_
+M?IO`$)?```,:;!_H?H&``'[;P!"7P``#&G`?\'[!@`!_&\`0E\```QIT'_A_
+M`8``?UO`$)?```,%W``!?T&``!&@``6(````$B``$!R,``+($``>R"``'Y3`
+M``C(%``<F0``"L@<``B$``.SS```5(```>7,@`!`F4``!,@<``:$``.SS```
+M4LR``$"`````U$``0,Q``"?,0``H@``#K<P``&O`,@`#P#?__X```?!\L(`'
+M?$-``,@@`"C('``GR!@`)L]#HIY\04``4B``('WAP"=]6,`#?-S`(%30`""`
+M``(%S(``0'Q!@`#,@`!`@``"`LV``$#`&?__S(``0,V#HIY\0,``?$$``'Q!
+M0`#,PZ'ZS0.A^<U#HIW,P`!`S0``0,U``$#,0`!`?$"``*`````$*``!?$#`
+M`!S0``',PZ*?E0```]!``";0@``FS(``0(````#,P`!`?$#``,R``$#,PZ*B
+M@````,S``$!\0,``%-0`'\R``$"50``#?$$``,S``%D5&``?S,``0)6```/-
+M``!`S0``6H```ZW,``!_R"``'WQ!``#8(`)$SB``1'Q!0`!\08``S:``2<T@
+M`$'-8`!!S:``0140``@15``8?5/`!\_``"\&(``!S@``6(```ZW,``!_R"``
+M'\H,`!>4P``%?$$``-@@`L:```(OSB``1LP``$B```)%`````,@@`!]\08``
+M"B```<H4`!K*&``7?5F`!Y6```7.``!8S*``1H````#-8`!&S*``1(````#-
+M8`!$@``#K<Q``&K,@`!`@````-1``$!\0,``?$$``,S``_[-``/_S,``0LT`
+M`$(5%``?&1@`\"=<``%]=@`&F8``!7U>0`;,``!"@``#K<P``$T5F``!%2P`
+M")F``$T>[``!E@``!!4P``R```.MS```0@04`"#-0`!"'S```2`H``&$``*L
+MR!0``YM``"L$.``<A``"K,@4``.;0``G!#@`&(0``JS(%``#FT``(P0X`!2$
+M``*LR!0``YM``!\$.``0A``"K,@4``.;0``;!#@`#(0``JS(%``#FT``%P0X
+M``B$``*LR!0``YM``!,$.``$A``"K,@4``.;0``5R`P#_IJ```G($`/_FP`!
+M%LP``$T$%``@S,``0LT``$*```)TS4``0I;``0_,``!-@``#K<P``$Z:P``#
+MS```3<P``$[C@P``@````-P#`?^:P`$%S```38```ZW,``!.R!@``\@<``/(
+M(``#?5U`#7VAP`U]74`'%A``'Q6<`!]]'0`&?1=`!H@```!^DH`&ED``!,P`
+M`$Z```.MS```0M(``$+("``#R`P``\@0``/(%``#R!@``\@<``/()``#R"@`
+M`Q7\`!\6L``??_/`!A3P`!]_\\`&%7``'W_SP`9]B(`!E\``#7W,P`%^40`!
+M?I5``7R0@`Q\U,`,FL```WR/0`8DM``!FT``U\P``$V```.MS```3L@,`_[(
+M$`/_S,``0H```KS-``!"?$#``'Q!```9%``[S```6Y5``!/(%`!`,5@``I6`
+M___(%`!`S```8R$<@`#,P2&%S<$AAA44`!_,02&'S$$AB)5`_1',02&)R!0`
+M0)E`___(%`!`@````7Q`@`#,@`!`S,``0,T``$"`````U$``0-"``^#,@`!`
+MA``#L,Q``$#(#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``##A30`!^9
+M`/SXT$`#X(0``[#,``!_@``#`,@,`^#,@`!`S,``0(@```#40`!`S(``0,Q`
+M`$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#,``/PS``#\<P``_+,``/SS``#
+M],P``_7,``/VS``#]\P``_C,``/YP#?__]```_O0``/\@````,]``_U\0,``
+M%-P`'9G```?,@`!`&-P`/)G``'_,P`!`@``#K<P``&H8V``\S8``9LP``&J`
+M``.MS,``0'Q`P`!04``@A``#L,P``%U\T,`GR"``'\C6``"90``(?$.``..#
+M``#/H`!/A``#L,P``%Z`````U$``?X```ZW,``!>A``#L,P``%W((``??$#`
+M`,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\\X`&XX,``,^@`$^$``.P
+MS```7H````#40`!_@``#K<P``%Z$``.P?$#``!3<``B5P``9'-P`$'Q!``"9
+MP``$4%0`((```VC)'0``?14`)\D>``!\0@``?$)``'Q!@`!]Y<`&?>*`$9J`
+M_)-!K``%FL````KL``$<W``0F<``!`````"```-KR1T``(```VO)'@``S(``
+M0,S``$"`````U$``0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!
+MR"``']@``\#,``!`S(``0-1``$!\0(``H`````0H``%\0,``'-``!BD0``:9
+M```'R!0`')E```7,``!2R!P`!H0``[/((``?S(``0,S``$"`````U$``0'Q`
+MP`!\00``%1@`'\T``%N9@``$410`((````#430``?4U`)QD<`#'45@``E<#\
+M6\@@`$&:````R"``08````%\0(``@````-1``'_,``!_@````,P``'_,``!_
+MB````,P``'_-P`!`B````,P``$``````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P-\``0#A``%`BL`!@#B``<`\0`(`00`"0#J``H`WP`+`.X`#`$F
+M``T!,P`.`70`#P&6`!`#JP`1``H`$@`8`!,`(``6`"(`)``Q`"4`3``F`><`
+M%P)'`!@"50`B`S<`(P-(`"<!_``@`EH`*`(>`"D!ZP`J`A``*P(``"\"&0`R
+M`CT`-`.,`#4![P`Y`E<`/`-<`#X#JP`_`BL`00+?`$("^P!#`P4`1`,2`$H#
+M*0!5`W\`5@.'`&``A@!A`*,`8@#-`&,`M@!D`+8`90"V`&8`M@!G`+8`:`#:
+M`&D`Y0!J`58`:P$'`&P!!P!M`0<`;@$'`&\!!P!P`0P`<P#T`'0`]`!U`=4`
+M>P.:````!0````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_rlc.bin.uu
new file mode 100644
index 0000000..a5c3e20
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 CYPRESS_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X```/P`
+M````P#`@`\^Q``"(````RSD``,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`
+M````````A```?`````"```#%`````,GX`(.;@``$`````(```,4`````S!P`
+M@X0``-@1N``?@```Q0````#(*``#EH``M`````#-@``.*HP!Y9C``"0@"``!
+MS(```X```!@`````(#@``<^```/($`""S```@<@(`!J4@``R`````,V```X`
+M````A```T2`X``+,,0``A```#"`X``'-@`"!A```\R`,``"```#%`````"J(
+M`;R8@/_8`````)4`_](`````R"@``I:``.$@"``!S8``#LR```*````8````
+M`,G,`(.4P`"3`````(0``/,@#``!A```#"`X``"7@`"-(`P`#<`P(`G,\0``
+MP#`@"L`T&!@3=``((W08&,L-``!\],`&R`@`&IB``((@'``!E,#_^P````"`
+M```P?<'`!L@X`%:;@``S(!P``,@X`%>;@``P(!P``2`<``#("`"!E(#_V0``
+M``#(*```EH#_UB`(``'-@``.S(```!P<```JB`&[E(#_RP````"```#3````
+M`!ZH`/_.@``,B`````````#(,`!`(S``0,\``$"$``"F(#@``<@P`$`?,`._
+MSP``0(```&?,``!6A```$`````#`,"`(A```N2`X___`,"`(S#$``,LY``#`
+M,`.8A```N2`X`0#`,`.8S#$``,L)``#`,"&VB````,PQ``"9P/_ER#``0",P
+M``+/``!`A```BB`X``/(,`!`'S`#_<\``$"```!GS```5H0``!``````(#@`
+M`<`P`YB$``"Y$[@`%,P``%?`,`.8S#$``(@```#+"0``S[$``,V```[+.0``
+M%[@`!)>`__X`````B`````````#/L0``RSD``"`(`!^8@```"(@``<P<`!;)
+M\``;EP#__P````"(`````````,P```[,```.R!``@B`H`<,@'```R!``@L@(
+M`(5_BX`'R`@`@92`_V<`````@```9P````"```"QP#`!P<V<`(.$``#8(#@`
+M`)4`__$`````P#`!P(@```#/L0``R"@`!):`_^D`````(`@``<V```[,@``$
+M@```&`````"$``#8$;@`'X0```P@.``!A```\R`,``#`,`'`RSD``"`X``"5
+MP/_9SX```WW!P`:$``#8(#@``(```,7/@``#P#`#D,LY``#`"__^?XN`!A#,
+M`!!_CX`'S[$``(@```#+.0``R`D]-L@-/3>4P/\[`````,@1/3C(%3TYR!T]
+M.L@A/3O()3TU!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8
+MR)8`/)5`_RK(T@`H?24``0E4``$$S``HF0#_^P````#(D@`X!1``0'T*P`#(
+MU@`$P!P`!,CB`!3(Y@`DS@H!3,YN`4P(S``$"(@`!`KL``0)W``!F<#_^```
+M``#-"@%@S`H!9,U!/4>````Y`````,@H``&6@/[[`````"`(``'-@``.S(``
+M`8```!@`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_uvd.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_uvd.bin.uu
new file mode 100644
index 0000000..5de4827
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/CYPRESS_uvd.bin.uu
@@ -0,0 +1,2575 @@
+begin 644 CYPRESS_uvd.bin
+M0O6*8M!!U)"E$$SW91/,Z?E1+LSP8-,\=S+YH&JT,]A'V"RYW\6L-6]*JKKE
+M/6:`'G93]@````"`P0$`!`````@```'FU#H=(5XCD!7/QQ-TKX:Y+*_^@?@^
+MTZ>'PO:`MNK<<#UG_)0)```!S(88]CE^DV9B^?L(V<61^O':T!<C&U7EK--@
+M*@H_!:M1JD83"@```3O9#$?(CM]'<9H*E`T?WTWX&GS5=E'_YWMNUWZ@3NK@
+MNO"SAPL```%3(\5+3*\4<._::89:=S;A3[C]%VM86((#M-U&7M@KFG)=I=@`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````,5)$-5)(.5),/5)`#0``-S_`&'0
+M_P!A$``!82\`!`"Y#`1@``````````````````````````````````````#%
+M"1#5"2#E"3#U"0`U````````````````````````````````````````````
+M````````````````````````R4D`T0D0V4D@Z4DP^4E`@$E0D$E@H$EPL$D`
+M-````````````````````````````````````````````````,D)$-D)(.D)
+M<-$),/D)0(<)4)<)8*<)<+<)`#4`````````````````````````````````
+M``````````````#-20#1"1#=22#M23#]24!`25!026!@27!P28"`29"02:"@
+M2;"P20`T````````````````````````````````S0D0W0D@[0FPT0DP_0E`
+M2PE06PE@:PEP>PF`BPF0FPF@JPFPNPD`-0``````````````````````````
+M````#```Y!,``!,``1,``A,``Q,`!!,`!1,0(```21,`2!,0(```:!,`@!,`
+M@1,`D!,`D1,`H!,`H1,P(```L1,`LA,`LQ,`PA,`PQ,`T1,`TA,`TQ,`Z!,`
+MZA,`\!,`\1,`\A,,\B#F$Q`@`$P"#`-V@@[2<P/2<T/2<X/2<\,RTP$`(``B
+MH$`RH`!V@@[R<P#R<Q#R<R#R<S`RTP$`(`!,`@P#=H(.@G,#@G-#@G.#@G/#
+M,M,!,"``(J`@,J``=H(.<G,`<G,0<G,@<G,P,M,!,"``#"5`50$,`PST0&-0
+M6C-`8U!:,T!C4%HS#$0&````0&-0`"``\"``\"``6C,,]$!C4%HS0&-06C-`
+M8U!:,T!C4``@``P##/1`XU!:,T#C4%HS0.-06C,,1$#C4%HS#"1`XU!:,PST
+M0.-06C,,)$#C4%HS#/1`XU`P(``\`B#C$P*@!`N`#``,`0P"#`,,!`P%#`8,
+M!R"`0%9P_@P1#``021,`2!,`(``0(``11?\A1?\Q1?\Y`C%%_S#F$Q`@`"!@
+M`"%#_R`%$^7Y`"T*,2X#*0,,$C$O`RD#AI3_````.1%)(5DQ:4%Y48EAF7&I
+M@;F1R:'9L>G!^=$@``,P`0,IX3GQ(`(#,`,#(F$0,F$1(.8#,+$#(F$2,F$3
+M;`,P(A`K(B#F$Q+1`1+!@!`@`!`1(!4%`!+!@#(A$2(A$#`#$R`"$SCQ*.$P
+M`1,@`!,B(1(R(1,@YA,PL1,0(`#XT>C!V+'(H;B1J(&8<8AA>%%H05@Q2"$X
+M$2@!$M$!$L&``#`````V`0$@80!`X@-0Y`,A,`-01!`@1!!61``@;P`=\##T
+M0!SR,#+``!-`03$#0$.PG&,,$@`BH2#C$R(D`&(D`19"_-`"`(;O_P`@\`,@
+M\!,H!&@4%@+[T`(`ANK_`#8A`##J`RHS,/`3'?`````V(0#VP@E1,0-0(K`Y
+M`DD2'?``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````"*L#L9E_P``
+M````````````````````````````````(JP8QEW_````````````````````
+M```````````````0-````````````````````````````````````````!+!
+M@"D!(.@#9D("1E#_*`$2T0$2P8`BK!=&2/\`````(JP6QD7_```V(0!`;P`P
+MY`,@,R`PY!-`YA,0(``=\``V(0!`;P`PY`,@,R`@,S`PY!-`YA,0(``=\```
+M`````"*L%<8U_P``-B$`(.H#'?`V(0`@\!,`(``=\``V(0`@\`,=\```````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``"`P0%@````````````````T0$``!$!``#1`0``T0$``-$!```1`0``=P$`
+M`-$!``#1`0``=P$``-$!``#1`0``T0$``!$"``#_`0``T0$``-$!``#1`0``
+MT0$``-$!``#=`0``````````````````7````"\````_`@``!P(``-D!``!5
+M`0``TP`````````&#10<#10<(!0<("4<("4J"@X4&`X4&!L4&!L>&!L>(@`!
+M!`@%`@,&"0P-"@<+#@\``0@0"0(#"A$8(!D2"P0%#!,:(2@P*2(;%`T&!PX5
+M'",J,3@Y,BLD'18/%QXE+#,Z.S0M)A\G+C4\/38O-SX_-`D``#0)``#4"0``
+MQ`D``,0)``#5!@``U08``-4&``#5!@``U08``-4&``#$"0``M`D``*0)``#5
+M!@``U08``-4&``#5!@``U08``-4&``#5!@``I`D``)0)``"$"0``U08``-4&
+M``#5!@``U08``-4&``#5!@``U08``'0)``!T"0``9`D``-4&``#5!@``U08`
+M`-4&``#5!@``U08``-4&``!4"0``1`D```````#$````JP(``(\"``!S`@``
+M5P(``#L"```P`@``%`(``/@!``#<`0``P`$``*0!``"(`0``;`$``%`!```T
+M`0``&`$``/P```#@```````````!`@,$!08'"`D*"PP-#@\0$1(3%!46%Q@9
+M&AL<'1T>'R`@(2(B(R,D)"4E)28F)B<G)R<````````````````/```!!P(+
+M!`T(#@,#!04*"@P,#P$'`@L$#0@.!@8)"0``````````````````````````
+M```````````````````````````````````````````````````````````O
+M`!\0#P$``A<$&P@=(!X#!P4+"@T,#@\G+RL'+0LN#1`.`P8%"0H?#",3)14J
+M&BP<(2,B)20J*"PG`2L"+00N"!$1$A(4%!@8$P85"1H6'!D7(!LA'2(>)!8H
+M&28F*2D`````$````"`````/````'P```"\```````````````(!`P,$!P4/
+M"!\"`@,&!`X%'@<^````````````````'T`?01]"'T,?6Q]<'UT?7@!`@`%!
+M@0)"@@-#@P1$A`5%A09&A@='APA(B`E)B0I*B@M+BPQ,C`U-C0Y.C@]/CQ!0
+MD!%1D1)2DA-3DQ14E!55E196EA=7EQA8F!E9F1I:FAM;FQQ<G!U=G1Y>GA]?
+MGR!@H"%AH2)BHB-CHR1DI"5EI29FIB=GIRAHJ"EIJ2IJJ@``````````````
+M``````("`@```@```0$!`P,!`P.`5:I`P#-FF<PKUR5*;Y2YWB!@H.``````
+M`````````!\X'SD?.A\['SP?/1\^'S\?2!])'TH?2Q],'TT?3A]/'QL?'!\=
+M'QX?)Q\H'RD?*A]$'T4?1A]'```````````?7Q]@'V$?8A]C'V0?91]F'Q\?
+M(!\A'R(?(Q\D'R4?)A\7'Q@?&1\:'PT?#A\/'Q``"`$%"0T#"P``````````
+M#1T)!14F-C($!Q<#)S<S`(!5JD#`,V:9S"O7)4IOE+G>(&"@X````-SQ_)\4
+M)_V?T?\'`)#!`6"T"````/+\GX;W`P``]OR?````"/__'P`````!%"``8```
+M`@`X(`!@U!\`8(@3`````&````@``````@+___\_`````@#N_)^`EI@``"[\
+MG_T)_/\``#`#`/[[GP```("'$P``____`0```,#__U\`>_C]_^0-``````!B
+M`O8#`(0'`@#____]`!\```!```#_?_#_`(`)`/^___\```B`__#__P```X``
+M``*````&@````8````,````,````,````,``/0``0#R=`6````2````-@```
+M#(````6``!@``/_G__\-``!``/K\GP#^_)\@3@``````X````/````"@.&L`
+M`!1K``!L#```@`P``*`G`&`8*@!@W!$``````$#___^_____`-1H``#4#P``
+M`#__`("I`P#DJ@!@W`\``.QH````_P#_^!T``/#_``!`"```(#__``(@```W
+MS4+]9KCTC(OQ3P=D:@``L`D``!`(`&",,`!@Z&@``#`*`````"0`+5T``*@,
+M``#4#```6!$``!0)``#`"@``@`H``/___W_<$P``E%H``-0(``#P:```2`H`
+M`.`Z```X.P``2#D``-@8```P&0``H`H``'`(`&"43`!@4`H``,`(``!4"0``
+ME`D``.P/``#___^```#P#ZP)```7```("`T``&`-``!H$```Q#@``+0/```"
+M"```:&H```````3,"0``V`\``#QH``#`#P``-`P``+1;```46P``N`\``/QJ
+M````"0!@R&L`8#$,````4@(````X!`#@A@(``,P```!X``!X:0``=B\``-@;
+M``#L#0``1@4`>E\``'Q?```Z8```/&```)@*``#D$0``\`\``/QH``!,"@``
+MT`\``(`8```L70``__^__ZQ;`````$``N`@``$D*``"07```'%T``-A:``#<
+M6@``;`H``&QJ```L"@``_*(`8!2C`&"4:```__\#^/\!_/\``/P'`/X#`.`/
+M``"(.@``Q&@````__P$#"```L`D`8%2K`&#\VP!@9,\`8"3W`&#$`@%@P,4`
+M8)BX`&`LT`!@\,<`8&#@`&#`Z@!@>`,!8"C[`&"(N0!@Q*\`8)CK`&"0X@!@
+M``H`8`"``````!#X``!`^``+`&````#X```P^`B``````.`!```@^!,``0`;
+M``"`&P``0!L``!`;``"0&P``4!L``"`;``"@&P``8!L``#`;``"P&P``<!L`
+M`/`;``#`&P``T!L``.`9```0&0``(!D``#`:```0&@``(!H``#`<``#`'```
+M@!P``$`<```@'```$$`*`&#@:```____!Z0(``"L)P%@%"4!8`$__P`!`/`/
+M00#P#T3^'P!(10%@``X``/[_```""0``.`@````@`P"`?X!_@0#P#SQ^`6#4
+M4P%@O'D!8(17`6`@"P!@*@L`8(!_`6`(@@%@Q(`!8-QZ`6`<?0%@_'L!8,!4
+M`6!\6`%@F%8!8&Q:`6"L50%@=%D!8`L``@!0"P!@0`L`8```40```%````!P
+M````<0```!$````0`!\R```?,0````#1````D0```-````"0``(1```"$P``
+M`A8```(8```"#P```A0``/X/``#^'P``'S4``!\S```?-```'U@``.`+`&`?
+M4```\`L`8`(2```"#@``'U<``!]9```?6@``8`P`8!]4```?4@``(`P`8!]1
+M``!0#`!@`@P``'@,`&`?5@``$`P`8$`,`&`X#`!@`@L``#`,`&`?4P``&&X!
+M8,!)`6"H;@%@4$L!8%AO`6`@=@%@D$\!8(1Q`6",=P%@'RL``)`,`&```"``
+M``#@`(`,`&`?,`````"P`!"*`6"@#`!@'U4```#>_)\```$`P/\```#B_)\?
+MH0<`B)(!8!"5`6````"$``"`````"`````0`___S_____/__`/__````@P``
+M`!@````,````$````(8`\/____]___\/`/\````*````#@````8````<````
+M%#;!$K$R`^+1"0P"HM$)#`D,"(D!F7J1,P,IFB$T`_(IJOD1R!&)#HNA(,P@
+MPFFJ@FG$I=<:)3,!30IE"Q$]"B6@&"$U`^$S`X$V`S"4<Y":<YE!@F[:,B[E
+MTM$(H3<#,#`T,FTO\BTOPBTOLBTO@/\1P,P1\,P@P+L@LF[EHF(5HF(7DB[W
+MDFTO\BTO@J_''`.`_Q`P_R#R;O?"+K_";2^B+2\,&X$X`["J(*)M+Y(M+Y)N
+MO_(NWH#_(/)M+\(M+\)NWI(NHK$Y`Z*G`*"9())M+X(M+X)NHO(NW?)M+_$Z
+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
+M\````````````````````````````````````````(#!`6"`P0%@@,$!8(#!
+M`6``````_____P````#_____`````/____\`````_____P````#_____````
+M`/____\`````_____P````#_____`````/____\`````_____P````#_____
+M`````/____\`````_____P````#_____`````/____\`````_____P````#_
+M____`````/____\`````_____P````#_____`````/____\`````_____P``
+M``#_____`````/____\`````_____P````#_____`````/____\`````____
+I_P````#_____`````/____\`````_____P````#_____@,$!``8L@`(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_ce.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_ce.bin.uu
new file mode 100644
index 0000000..0cd84a0
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_ce.bin.uu
@@ -0,0 +1,194 @@
+begin 644 HAINAN_ce.bin
+M?$"``8@```#40`!_?$"``8@```#$(``+Q@P`!93``"0D4``/,10``I5```3,
+M0``DS$``)8`````Q%``#E4`!.\Q``";,0``G@````,0@``O,(``%?$$``5!4
+M`"!\08`!!B0``<Y````5G``8?14`&LW@``K-H``,T2```\V@``.:```$Q"0`
+M$II```(AW``P@``!3,0@``O&#``%'*@`$)3```/.H``'@```%<P```G$)`!_
+MQ"``"WQ!@`$*(``!QA0`",88``5]68`*S@```)6```/,(``'@````,P@``6`
+M````?$#``130`!XQ%``"E4`!#AC0`>@8U``P&-@`-`4H`$1\0@`!?$)``94`
+M``>&@```@``!4(```5"```%0@``!4(```%(15``0?A8`"LU``!'480``E8#_
+MLL0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``!'48@``E8#_J<0@``Z:`/__
+M?$"``8@```!\0,`!%-``'C$4``*50`#K&-0`,!C0`>@8_``T),P`#P3H`&A\
+M08`!?$'``93``!*&@```@```<H```5"```%0@``!4(```&^```%04=P`('V>
+M`!J```!_4=P`('V=@!J90``#Q:(``(```'_)H@``@```?\6A``"50``%!9@`
+M`<6E``!29``@?B8`&@4H`(-\08`!?$'``94```>&@```@``!4(```5"```%0
+M@``!4(```)/8```1SAD``)5```0%F``!5B``(,X9``"7P/]QQ#DA0'Q`@`&(
+M````4=P`('V=@!K8```1SAH``)5```0%F``$5B``(,X:``";P/^]?$"``8@`
+M``#8``/VV``#]=@``_38``/SV``#\M@``_'8``/PV``#[]@``^[,0`!_S$``
+M?\Q``']\0,`!S,```=1``'^`````?$#``5!0`"",``#+?-#`&L0@``O$U@``
+M?$.``<0D`!.:```)V&0#],9K`_&:@/__QFL#[@:H``'.I`/NS60#Z]@D`_29
+M0``)WX,``,^@``Z,``#/U$``?YH`_SS&<P/NFP#__X````",``#/?$"``8@`
+M``#8```"Q#P`#9O``(.0````V$```L0\``V7P`!_D````-@``!)\0,`!4%``
+M(,0\`!`G_``!E\#__GS0P!K0P``4S$``%<00`"%\4,`!S,``%M@``!.`````
+MQ!``(7Q0P`',P``7U$``&(````#$$``A?%#``<S``!?$$``@?%#``<S``!F`
+M````Q!``(7Q0P`',P``:S$``&WQ`P`%04``@?-#`&M#``!R`````S$``(=@`
+M`"*`````?$#``5!0`"!]#4`:V$``*<@8`!U]E<`/E<#__M@``"F`````?$#`
+M`<@0`!W(%``>?16`#IF```_80``IR!``'7U1@!)]C<`/F<#__=@``"E0X``!
+M?A9`#II```1]8H`2TH``(X````#0```C@````-B``"G$/`!_S```(-A``"C$
+M#``<F,#__]@``"A\00`!4%0`('T6`!K2```>V$``'8````#,```@V$``*,0,
+M`!R8P/__V```*-```![0```?V$``'7Q!``&`````?$#``7Q!``$5&``?S0``
+M$5$4`""9@``#U$T``(````!]34`:&1P`,=16``#$(``.E<#^R,0@``Z:`/__
+M@````'Q`P`%\08`!%-``'C$0``(DU`#_E0#^O\V4`P"`````Q"``$WQ`P`'$
+MTP,`S```$<TA(4&`````U$``?X````#$)`!^ED```WQ`@`&(````@``!4```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0`"`!`!2@`1``4`&0`M`#$`)0`S`!,`@`#3`($`X0""`.8`@P#M`#<`
+M.0!``%P`1`">`(0`]@"'`/D`B`$"`(D!%P!]`3P`?@%$`'\!+``B`*X`BP$B
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_mc.bin.uu
new file mode 100644
index 0000000..5e43a2c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_mc.bin.uu
@@ -0,0 +1,702 @@
+begin 644 HAINAN_mc.bin
+M``/HX``"O@$```('``/_```#_P```J`.``'`&0`#Z````^@0``/H(``#Z#``
+M`V`@``-A2``",A(``TEL``-("@`#KPH``K0$``)O]```^BT``K0/``)/%```
+M^@H``ZB,``#"`0`#0"0``K1```*U#P`#2J8``D1!``/P`@`"294``VJF``-*
+M40`#0"0``K@"``*Y_@`"1)0``DB!``.H@``"9$@``VI1``-`)@`"OX```KP$
+M``))^0`#\$(``_0```'`00`"OX```TA4``*X#P`"N?```D$8``)"*0`#:%0`
+M`TMI``/`C``"9$P``VMI``)$2``#:VD``F$?``)B+``#:%0``BQE``-+3``#
+M_P```V%$``-+'``#0"H``K3\``-A0``"0S0``F$>``-K'``"2JX``_!&``-)
+MU0`"O!```DS'``/P0@`"O"T``_\```-`)``"M$```K7P``-*I@`"1$$``_`"
+M``)IE0`#:J8``T````/_```#^`$``\1```/$40`"QD4``@````-`$``#_P``
+M`_\```/H(``#Z#```V`0``"1Y0``D@T``_@#``(Q&0`",@P``T@(``*TGP`"
+M0`0``V@(``-(P``#2,8``K3\``*U#P`"010``DF4``)")0`"2J4``D,U``)+
+MM0`#:,```VC&``-(```#2`4``KL_``*\OP`"O^\``)(E``"*)@``@BH``+HH
+M``"J+``"01L``KO[``)`#``#:````KS^``)%7P`"1WP``V@%``-($``#2=T`
+M`KOQ``*\`@``BBD``*HK``)!&P`"81P``V@0``)%6P`"95P``VG=``-`#0`#
+M_P```_\```.A3```B?\``K,"``)#-``#HS```)G^``*S!``"0S0``Z,R``"9
+M_0`#0"D``T````*\(```N<<``D(L``/P!P`"L````((Q``(ZG0`#Z````('E
+M``/T```!PF```T````*\(```\C$``D,\``/P!0`".IT``^@```"!Y0`#]```
+M`<)@``-((0`"L\$``D=S``-H(0`#:HD``T@E``*SP0`"1W,``V@E``-JC0`#
+M2"D``TEP``-`$@`"OP<``D`/``.````#``X``Z^(``-)U@`"O!```DS+``/P
+M00`"P`\``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H+0`#P00``\$5
+M``-IZ``#:>P``TK"``*_P``"2(\``VK"``-JQ@`#Z````^C0``(N\``#:.0`
+M`\'>``(N\``#:00``^A```*]```",EP``KT!``(R7``#0"P``_\```*T`@`"
+M1`0``*()``-)U@`"M1```D1;``.D1@``H@L``J!.``/P`P`"-!<``_0```'!
+M!0`#]````=+=``-+8``#_P```F`.``-K8``"O````C*7``-`#@``\C(``^CP
+M``.@M@`#2=4``/H$``*Q#P`"0A<``J4@``/P`0``^C(``D,;``*E(P`#\`$`
+M`/($``-````#0"X``K80``*T#```*C(``D(D``.B(@`"0S0``FPC``)&:``#
+M\`,``J!>``/P`0`#Z,```.(#``-`"``"M````'H$``*@)``#\$$``K((``*@
+M_@`#\$$``K($``*T/P`"0B0``)(:``-*E``#_P```V&```-````#_P```K1`
+M``)$!``#\`,``^@```"",0`"(O,``T````/_```"M$```D04``/P`@``\C$`
+M`B+S``-````#_P```K1```)A$``"1!0``_`!``(M40`#2I0``_\```-AA``#
+M0````_\```*T`@`"1"0``_`#``/H````@C$``B,?``-````#_P```K0"``)$
+M-``#\`(``/(Q``(C'P`#2I0``_\```-AB``",@P``T````/_```#_P```D0.
+M``/P`P`#Z````((Q``(D2``",@P``T````/_```#_P```D0>``/P`@``\C$`
+M`B1(``(MB``#2I0``_\```-AC``#0````_\```*T`@`"1$```_`+``/H````
+M@C$``B8[``-`+``#_P```K0@``)$0``#\`,``^@```"",0`",8,``TJ4``/_
+M```#89```T````/_```"M`0``D1```/P`P`#Z````((Q``(H#``#2I0``_\`
+M``-AE``#0````_\```*T$``"1$```_`,``/H````@C$``BBS```!_P`#_P``
+M`_\```*D#@`#\`0``/(```(HLP`#Z````((```-*E``#_P```V&8``-````#
+M_P```K0@``)$0``#\`,``^@```"",0`"*D```TJ4``/_```#89P```(#``/_
+M```"M`$``D0$``/P!``#Z````((Q``/!_@`"*O(```(#``/_```"M`(``D0$
+M``/P!``#Z````((Q``/H\``"*O(``T````/_```#_P```D0N``/P`P`#Z```
+M`((Q``(X.P`#0````_\```*T$``"1"0``_`#``/H````@C$``CE?``/X`P`#
+M2I0``_\```-A8``#0````_\```*T`@`"1$$``_`*``#R,0`")CL``T`L``/_
+M```"M"```D1```/P`@``\C$``C&#``-*E``#_P```V%D``-````#_P```K0$
+M``)$00`#\`(``/(Q``(H#``#2I0``_\```-A:``#0````_\```*T$``"1$$`
+M`_`+``#R,0`"*+,```'_``/_```#_P```J0.``/P!```\@```BBS``/H````
+M@@```TJ4``/_```#86P``T````/_```"M"```D1!``/P`@``\C$``BI```-*
+ME``#_P```V%P```"`P`#_P```K0$``)$!``#\`,``/(Q``/!_@`"*O(```(#
+M``/_```"M`@``D0$``/P`P``\C$``^CP``(J\@`#0````_\```/_```"1#X`
+M`_`"``#R,0`".#L``T````/_```"M!```D0T``/P`@``\C$``CE?``-*E``#
+M_P```V%T``/X`P`#0````_\```*T"``"8`$``D0$``/P#``#2`@``_\```*T
+M0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#```\$N``-H,``",9X``^@`
+M``/H$``#Z#```K(#``-H,``#0````_\```*U@``"81```D45``/P`0`"-YH`
+M`TJ4``/_```#87@``KP!``(REP```C(``_\```/_```"H0X``_`"``/H````
+M@@<``BV(``-(```#2`4```HF```"*@``$B4``"HL```Z*``#_P```V@```-H
+M!0`#2!```TG=```**0``*BL``_\```-H$``#:=T``TEQ``*R`0`#Z#```\$&
+M``/!%P`#:#```C&>``/H```#Z!```K(#``*S```#:#````(+``/_```#_P``
+M`J`.``("A@`"(N<``_0```'``````>4``T`2``-`%0``"@T``J`.``/P`@`#
+M]````<*A``+!'@``B@T``FNZ``)E6P`"QFX``_!!``,&;@`#8!4``K(/``)$
+M0@`"I10``_`'``/HH``#Z+```V`2``/H````@>4``_0```'`:P`#0"P``_\`
+M``*T(``"0$```_`"``/T```!PK4``T@(``*TOP`"0`0``V@(``/H````@C$`
+M`C&#``#R,0`",8,``T@(``*T0``"8`0``V@(``/H````@C$``C"X``#R,0`"
+M,+@``TD]``-(P``"M@@``D9D``/P`@`"M3```F(E``-HP``#:,0``B+G``-`
+M(``#_P```_\```+"+@`#\$0``L,^``/P0@`"LO\``K/_``-@(``",@P``TM@
+M``/`C@`"0`@``VM@``-)2``#0"H``K0_``*U@``"MD```D9H``/P10`"0S0`
+M`F,U``-I2``"0S0``VE(``/H```#Z!```^@@``/H,``#9*0``V3D``/T```!
+MP````TL=``-`*``"O!```K\$``),P``#\`4``F=^``-K'0`",9X``F=_``-K
+M'0`#[````T`$``!J,0`#Z(```^B0``/HH``#Z+```J#>``/P`P`#9*H``_0`
+M``/P00`#9.H``&'I``*@W@`#\`,``^A```/T```#\$$``X3J``/80``#W,``
+M`'GH``/X`P`#U)X``_L```,/_@`"`PH``"'#``*@W@`#\`,``&'"``/T```#
+M\$$``&'!``*_"``#W$```]C```/X`P`#U)X``_L```,/_@`"`QD``_@#``/L
+M`````C(``&HQ``/_```"H`X``_`!``/L```#23@``J#>``/P00`#23@``KC^
+M``)"*``#:3@``TG0``*T!``"810``K(!``*S$@`"H-X``_!!``*S$0`#:#``
+M`TEQ``*X[P`"N00``\$&``)A>0`"0S@``V@P``-("0`"N/T``D1(``-H"0`"
+MM`$``B/J``(M8@`#2:```K01``/!)``"L0\``VF@``*@W@`#\`,``T)A``/T
+M```#\$$``T)=``/_```#_P```^A@``-II0`#:&L``KH,``*XP``#W($``]BA
+M``*P^``"L0<``^@@``/H,``#_@```]0?``-H:P`#Z/```B/3``(CPP`")`4`
+M`J'^``/P00`#8GH``T)X``/_```#_P```J"```'#=@`"H)$``<-V``*@H@`!
+MPW8``J"S``'#=@`"S_X``KP,``*A_``#\$(``_0```'#8```^<X``^CP``(C
+MPP`"(],``B0%``-">``#_P```_\```*@@``!PXP``J"1``'#C``"H*(``<.,
+M``*@LP`!PXP``L_^``*\#``"H?P``_!"``/T```!PWD``&'.``#YQ0`#_P``
+M`J7/``'#G``"I?P``<.7``/H\``#Z,```_0```'#GP`##,\``ZS```/H\``#
+M]````<.?``,/_``#K_```^C```(CTP`#P?P``B/#``*P&``")"0``K0```(C
+MZ@`#23@``J#>``/P00`#23@``_\```)B+@`#:3@``TG0``*T^P`"010``K(!
+M``*S$@`"H-X``_!!``*S$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@`
+M`V@P``-("0`"N`(``F1(``-H"0`"+8@``^P```/!#P`#P1\``\$O``/!/P`"
+MH-X``_`%``-DL``#9+0``V2X``/T```#\$,``V3P``-D]``#9/@``B/A``/L
+M```#P0\``\$?``/!+P`#P3\``J#>``/P!``#9*P``V2\``/T```#\$(``V3L
+M``-D_``"(^$``^P```-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@`
+M`^P```)-W@`#\$,``T<T``/T```#\$$``T=T```IQP`"MO@``D1.``/P0P`#
+MP04``_0```/P0@``@<<``D`&``/!$``#P2```\$P``)-W@`#\$0``V<T``-G
+M.``#]````_!"``-G=``#9W@``^P```*P$``")"0``TH<``(D.@`#P8P``TH@
+M``(D.@`#C,8``FB,``-*)``")#H``\&<``-**``")#H``XS&``)IG``#2BP`
+M`B0Z``/!K``#2C```B0Z``.,Q@`":JP``THT``(D.@`#P;P``THX``(D.@`#
+MC,8``FN\``/L```#2D8``K3^``)IG@`#:D8``DF4``-J1@`#:&L``KD(``*X
+MP``#W(```]B0``/H$``#Z"```^@P``/^```#U!X``VAK``/!CP`"OQ```BU>
+M``/!^``#[````^C```.'/``#IW8``X8L``.F:``#A1P``Z5:``.$#``#I$P`
+M`FS'``)LQ@`";,4``FS$``/L```#0"0``&HQ``/_```#H`8``J$.``/P`0``
+M@?D``TFA``-)I``"NT```KJ_``)%I0`"H-X``_`#``)#HP`#]````_!!``)C
+MLP`#::0``VFA``(RN@`#Z````^@@``/H,``"H-X``_`#```)^P`#]````_!!
+M```)^@`"N,```VAK``/8```#W(```]0>``*_"``"+5X``X#@``"!]@``@?4`
+M`^@```"!]```@?,``/'R``-(5``"H-X``_`#``.$Z``#]````_!!``.$Z@`"
+M8B0``VA4``-)=0`#B.8``F!H``/!%P`#P2X``\$^``*@W@`#\`$``X,P``-H
+M,``#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``\!$``)")``#:%0``&(+
+M``*_`@`"+5X``J#.``/P`@`#]````@2P``(O`@`#Z'```X3F``)&2P`"H&0`
+M`_!*``-)T@`#Z&```XJR``.JJ@`"H:X``_`"``,!K@`")BL``_0```'%5@`"
+MOP@``D_Y``.O]``#B[(``ZN\``(E;P`#]````<56``-`$``#_P```K\"``)/
+M\``#\`(``_0```'%5@`#0`P``_\```*_"``"3_```_!"``/T```!Q,@``K\`
+M``*[`0`")6\```($``/_```#_P```J`.``/P0@`#]````<56``#Q]```\?,`
+M`J#>``/P`P``>?@``_0```/P00``>?<``XWB``/<T``#V/```XGF``)IG@``
+M\>,``$'Y``/HT``#C^```\&H``.,[0``X><``.(P``(N:P`"MP$``$'Y``/H
+MH```T>,``J!^``/P`0`#J(```P_?``/!V0`#P:@``XSM``#AYP``XC```BYK
+M``(NK``#P00``\$F``-B<``"OP$``T`1``.(X``"H/X``_`$``)$2``#\`(`
+M`_0```(%/``"MP$``$'Y``/_```"H'X``_`!``.H@``#Z-```X_@``/!J``#
+MC.T``.'G``#B,``"+FL``BZL``-"<``#C.L``XSJ``/H\``"R$```ZB````J
+M"0`"RF(``ZJ@``*F7@`"!1D``&HQ``#R"0`#P5@``\%Z``-B<0`#]````@33
+M``*A7@`#\`X``&HQ``/!D0`#P;,``J#>``/P`P`#82X``_0```/P00`#83(`
+M`L"!``.H```"PJ,``ZH@``.%4```J@D``X'@``,`A``#\"0``J&$``/P`0`"
+MQ$$``P1.``/!5``#`J8``_`D``*AI@`#\`$``L9A``,&;@`#P78``]1>``)@
+M`@`"!2L``&HQ``*_`@`"+5X``TEQ``.!Y``#P08``Z)L``*@+@`"!58``F%Q
+M``/!+@`#P3X``J#>``/P`0`#@S```X9@``/P1P`#:#```X_M``(M7@`#C^T`
+M`BU>``./[0`"+5X``X_M``(M7@`#274``\$N``/!!@`#P1<``\$^``*@W@`#
+M\`$``X,P``-H,````>4``_\```/_```"I0X``_!(``-`$0`"H-X``_`#``)F
+M;@`#]````_!!``)G?@`#8!$``^@```"!Y0`#[````J#^``'%>P`"L`\``K$/
+M``*R#P`"LP\``J#>``/P`P`#8R@``_0```/P00`#8V@``C&>``-*0```0?(`
+M`$GV``!1]0`"O#,``D0,``)%'``"9$4``D8L``)'/``"9F<``F1&``*A3@`#
+M\`$``K0!``*@C@`#\`4``J1)``/P0P`"I$L``_!!``#Q]```H?8``KS,``)$
+M#``"11P``D8L``)'/``"9$4``F1&``)D1P`"H4X``_`!``*T`0`"H(X``_`%
+M``*D2@`#\$,``J1+``/P00``\?,``*'U``/H0```H?(```'T```1\P`"L0\`
+M`K,%``*E_@`"!=$``J#^``/P00`#Z/```J`.``/P`0`"S_X``K$0``*@+@`#
+M\`$``L_Q``*SD``"IO,``_!"``#QY0`#[````D,"``/P0P`")A$``_0```'%
+M>P`"M!$``P_T``*@W@`#\`,``/GQ``/T!``#\`$``/GP``-#*0`"H-X``_!!
+M``-#:0`"OW<``B7P``/L```#2.4``J#>``/P00`#204``K@1``*@#@`#\`$`
+M`L1(``))00`"I),``_`!``#Q]``"H"X``_`!``+%6``"25$``J23``/P`0``
+M\?,``J#>``/P`P`#:.4``_0```/P00`#:04``D`"``*@#@`"!7L``K$"``(F
+M*P`#[````J'^``/P00`#[````Z'V``./]@`#H/8``J$.``/P!P`"O`D``J!,
+M``/P00`"O`\``\%,``/!7``#``X``J$>``/P!P`"O`D``J!L``/P00`"O`\`
+M`\%L``/!?``#`1X``J#>``/P`P`#8RD``_0```/P00`#8VD``F(!``(%]@`#
+M[````T,I``*@W@`#\$$``T-I``*@#@`#\`4``K0/``),_@`#\`$``K0)``/!
+M5``"H"X``_`&``*V#P`#K/8``DS.``/P`0`"M@D``\%V``*@W@`#\`,``V,I
+M``/T```#\$$``V-I``/L```#2.4``J#>``/P00`#204``K`1``+$0``"Q5``
+M`J#>``/P`P`#:.4``_0```/P00`#:04``P$>``(&+P`#[````&HQ``/H```"
+M+MP``/'O``/H````@>X``T`,``-`+0`"N!```KD(``)*&``#JJ8``DM)``.K
+MM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!`
+M``/P00`#Z#```D$>``/P`0`#Z#```)GM``(M8@`"N!```KG^``*@W@`#\`D`
+M`T@A``*Z#P`"1FH``D=Y``)F:``#:"$``VJ)``/T```#\$<``T@E``*Z#P`"
+M1FH``D=Y``)F:``#:"4``VJ-``(P@@`"OP,``C!.``*_9``"+5X``&HQ``/_
+M```#_P```J#>``/P`P`"NP```_0```/P00`"NT```-G@``/!#@`"L1$``K(0
+M``-J1``"L1```^@@``-J1``"L/\``K'_``*R_0`"L_\``VA@``-*8``"O_<`
+M`K$3``)`#P`"8`X``VI@```Q_@``.?T``KP(``*__@`#AFH``F(F``*D?@`#
+M\`$``K,$``)`#P`"8`P``VI@``./X0`"+5X``VAK``/_```#_@```&(O``!:
+M+@`#_P```]C!``/<L0`#C^,``BU>``/0'P`#C.\``X_D``)O_@`"0`$``D(C
+M``)``@`"3,```_L!``/0'P`##_X``@:L``*@W@`#\`,``T@A``/T```#\$$`
+M`T@E``/`S``"!M@``XSF``+&;``#\$$``L=^``*@W@`#\`0``V@A``-JB0`#
+M]````_!"``-H)0`#:HT``J5^``/P`@`#]````<9^``-`$0`"L`@``/'E``*@
+MW@`#\`,``F9@``/T```#\$$``F=P``-@$0`#]````@@*``.`X0`#@08``F$>
+M``."YP`#:D0``X$&``/H(``#:D0``C""``-`+```6AT``K0$``/H\``"1$``
+M`_`!``*_`0`"I+X``_`!``*_!``",$X``/(9``#R%P`",K0``C""```*+0``
+M$?X``!G]``*P`@`"H-X``_!!``*P!``#@BH``J0^``/P`0`"LP0``X$6``)@
+M`0`"L3,``VI@``-`"@`"L`$``K$"``*R```"LP$``J`K``/P`@`#Z"```\$[
+M``-J:``#P0X``K()``)`"0`#\`$``^@@``*P$P`"L0(``X(F``/H,``#:G``
+M`&($```2&@`"H,X``_!!``*R!``"L"$``K$"``*S`0`#:G0```H=``*P`0`#
+M_P```J0>``/P!0`"L00``K(```*S`@`#]`0``_`#``*Q`@`"L@\``K,!``-J
+M>``#2GP``_\```*P`0`"L0(``K,$``-J?````>X``_\```/_```"P`X``('N
+M``(P20```AD``T`*``-`#0`"H`X``_`%``*P`0`"0`4``X`&``/T!``#\`,`
+M`K`$``)`"0`#@`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"
+MLP$``VID``(O%P`"+R0```'O``/_```#_P```J`.``/P3@`#0"P``KP$``/<
+MP``#C^H``J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(MY0`#Z/```/GO
+M```![@`#_P```_\```+`#@``@>X```GM``-`+@`#_P```J`!``('@P`"L`$`
+M`D$(``/P!0```C(``_\```/_```"H`X``@>#``-*=``#23T``_\```.B5``#
+M@B```T`)``*E+@`#\`$``K((``)%7@`#\`$``!(:``/_```#_P```VIT``(P
+M20```AD``T`*``-`#0`"H`X``_`%``*P!``"0`4``X`"``/T!``#\`(``K`0
+M``)`"0`"L4,``F@!``-*9``"M(```!'@``)`!``"8`@``Z(B``/!/@`#:F0`
+M`B\7``(O)```0@,``K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''LP`#
+M0`X``K`0``/_```"00D``J`0``('LP```AD``_\```/_```"P`X``((9``*Q
+M`@`"I`$``@<P``!!X````<,``_\```/_```#V(```]P```*_"0`"L````]P!
+M``*PP``#V`$``B\.```![@`#_P```_\```+`#@``@>X``C!)``-`"@`"L$``
+M`_\```)`"0`#H`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"
+MLP$``VID``(O%P`"+R0``T`E``!"`P`"L"```D`%``/P2``"L`(``J#>``/P
+M00`#@`(``D`(``/P`@`#]````<?X``-`+@`#_P```K`(``)!"``"H!```@?X
+M``*P@``"00@``_`%```",@`#_P```_\```*@#@`"!_@```(7``/_```#_P``
+M`^@0``"*%P`"I`X``@=B```!X```0<,``_\```/_```#V````]R```*_"0`"
+ML,```]@!``*P```#W`$``C*Z``-H:P``$=8``K/```/HT``#8G0``BX-``(P
+M>``#[````&HQ``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\`
+M``/_````V>P``C#_``/H```"+MP``KL"``#:,``#Z````K%@``/H(``#Z#``
+M`VF@``/H```"L1```^@@``/H,``#:D0``C""``*_`@`",$X``K#_``*Q_P`"
+MLOT``K/_``-H8```"BT``!'^```9_0`"L`H``J#>``/P00`"L`P``X$6``)@
+M`0`#@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+5X``VAK
+M``/_```#_@```C!X``-*8```,?X``#G]``*T]@`"M0,``X9J``)B)@`"I'X`
+M`_`!``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#
+M:F@``K"```*R"0`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P
+M(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\`
+M``*P`@`"L0(``K,$``-J?``",K0``^AP``-*9``"M(```D`$``/H(``#Z#``
+M`VID``-*9``"M(```!'L``)`!``"M`,``F`$``*S$``#:F0``B\7``-*9``"
+MM`@``D1```)G=``"I7X``@BQ``/H```"+MP``J#>``/P`P`#2"(``_0```/P
+M00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H(@`#:HH``_0`
+M``/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R'8``T`2``#QY0`"OP0`
+M`J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R+$``C!X``/L````
+M:C$``/'O``/H````@@8``T`(``-`+0`"N$```KD(``)*"``#JJH``DM)``.K
+MM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!`
+M``/P00`#Z#```D$>``/P`0`#Z#```)H%```AY0`#Z%```_\```"B#```J>4`
+M`&HQ``/_```#_P```J#>``/P`P``6<(``_0```/P0P``6<$``_\```/_````
+MV>```T`L``!:'0`"M`0``^CP``)$0``#\`$``K\!``)+O@`"H+X``_`#``(O
+M?P`#]````<CP``*_RP`",>0``/(8``#R%P`",K0``C""```*+0``$?X``!G]
+M``*P`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B(0`"I#X`
+M`_`!``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"``*R```"
+MLP$``J`K``/P`@`#Z"```\$[``-J:``"L`$``K((``)`"0`#\`$``^@@``*P
+M$P`"L0(``X(F``/H,``#:G```&($```2&@`#_P```J#.``/P00`"L@0``K`A
+M``*Q`@`"LP$``VIT```*'0`"L`$``_\```)!$``"I!X``_`%``*Q!``"L@``
+M`K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q`@`"
+MLP0``VI\```*'0`#_P```_\```)!'@`"I!X``@F%```"!@`#_P```_\```+`
+M#@``@@8``C!)```"&``#0`H``T`-``*@#@`#\`4``K`"``)`!0`#@`0``_0$
+M``/P`P`"L`@``D`)``.````"L0,``F@!```"'0`#_P```_\```)`#@`"I`X`
+M`_`+```2&@`"L",``K$#``*S`0`#:G0``TI\``/_```"L`$``K$$``*S!``#
+M:GP``TID``*T@```$>```D`$``)@"``#HB(``K,!``-J9``"+Q<``B\D```!
+M[P`#_P```_\```*@#@`#\$X``T`L``*\!``#W,```K_```*@W@`#\`$``K^`
+M``/8\``#C.0``K\_``)+'P`"+>4``^CP``#Y[P```@8``_\```/_```"P`X`
+M`((&``!:'0``>A<``K@(``)*O@`"H*X``<FF``.JL``"2JX``_!#``(L)``#
+M]````<FE``-*<``"NH@``KEP``*@^``#\$,``\$J``/T```!R:,``ZNR``)+
+MO@`"H+X``_!!``/!*0`#:G```C&Q``(RM```"@4```(&``-`+@`#_P```J`!
+M``()N@`"L`$``D$(``/P!0```C(``_\```/_```"H`X``@FZ``-*=```>AH`
+M`_\```/_```#P2\``VIT``(P20```A@``T`*``-`#0`"H`X``_`%``*P"``"
+M0`4``X````/T!``#\`,``K`@``)`"0`#H````K%#``)H`0`#2F0``K2````1
+MX``"0`0``F`(``.B(@`"LP$``VID``(O%P`"+R0``$(#``*P`0`"H-X``_!!
+M``.``@`"0`@``_`"``/T```!R>L``T`*``/_```"L$```D$(``*@$``"">L`
+M``(8``/_```#_P```L`.``""&``"L0(``J0!``()0@```>```$'#``/_```#
+M_P```]@```/<@``"OP@``K#```/8`0`"L````]P!``(O#@```@8``_\```/_
+M```"P`X``((&``(P20`#0`H``K"```/_```"0`D``Z`$``*Q`P`":`$``TID
+M``*T@```$>```D`$``)@"``#HB(``K,!``*Q```#:F0``B\7``(O)```0@,`
+M`K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```'*+0`#0"X``_\```*P"``"
+M00@``J`0``(*+0`"L(```D$(``/P!0```C(``_\```/_```"H`X``@HM```"
+M%P`#_P```_\```/H$```BA<``J0.``()A0``8<,``%G@``/_```#W,```]BP
+M``*_"``"L,```]@!``*P```#W`$``C*Z``-H:P``$=8``K/```/HT``#8G0`
+M`BX-``(P>``#[````&HQ``/_```#_P```J#>``/P`P`"NU,``_0```/P00`"
+MNUL``_\```/_````V>P``T`0``*['P`#2"D``J#>``/P00`#2"T``D`+``.O
+M`@`#C/8``FS/``./]@`#2>@``J-,``/P!``#!$P``P5?``/T```#\$(``P3$
+M``,%]0`#P00``\$5``*@W@`#\`0``V@I``-IZ``#]````_!"``-H+0`#:>P`
+M`^@```(N\``#Z````K%```/H(``#Z#```VI$``(P@@`"OP(``B]_```*+0``
+M$?X``!G]``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"L80``F(A``*D
+M/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"L0(``K(*``/H,``#:F@``K"`
+M``*R"``"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"L0(`
+M`K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P`@`"
+ML0(``K,$``-J?``",K0``^AP``(P20`#2F0``K2````1[``"0`0``K0#``)@
+M!``"LQ```VID``(O%P`#2F0``K0(``)$0``"9W0``J5^``(*[P`#Z````B[P
+M``*@W@`#\`0``T@J``-)Z``#]````_!"``-(+@`#2>P``KP1``*_$``"R9\`
+M`LB,``/P00`#Z(```\$(``/!&0`"H-X``_`$``-H*@`#:>@``_0```/P0@`#
+M:"X``VGL``-*P``"OP<``DW>``/P`0`"OS@``J&.``/P0P`"8`\``VK```-J
+MQ``"NP$``-HP``/H<``"3_```_`#``*[_P`"H(L``_`"``/T```!RJ<``T`2
+M``#QY0`"OR```J#>``/P`P`":J\``_0```/P00`":[\``V`2``(P@@`",$D`
+M`^P```!J,0`#Z````(',``""#``"H-X``_`#``!9P@`#]````_!!``!9P0`"
+ML'\``J'^``/P00`"2[```-G@``(RM``",((```HM```1_@``&?T``K`"``*@
+MW@`#\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"LP0``T`5
+M``*Q"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J:``"L@@`
+M`K`3``*Q`@`#@B8``^@P``-J<```$AH``K`A``*Q`@`"LP$``VIT``*P`0`"
+ML0(``K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP``KP$``/<
+MP```>>```KP(``*[&``#V/```BWE```!S``#0"4``K\0``+`#@``@<P``D]?
+M``/P`P`"+"0``_0```'+30`"OP@``J`.``/P`0`#P?X``C&Q``-*@``"H/X`
+M`_!!``-JA```8>```K"```/H\``"H<```_!!``/!_@`"*[8``C!)```1X``#
+MZ!```K`C``.B(@`"LP$``VID``(O%P``8<P```'@```)PP`#0"8``K(0``/8
+M```#W!```K\(``*PP``#V`$``K````/<`0`"0BD``_!%``.O\``"H,X``_`"
+M``/[```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E+@`#\`$`
+M`_L!``,/_@`""V\```',``/_```#_P```L`.``"!S```8>```K"```/!_@`"
+MH<```_!!``/H\``"*[8``C!)```1X``"L`,``^@0``.B(@`"LP$``VID``(O
+M%P`"+R0``T`E```!S``"L0,``K((``*S$``"0S4``_`"``)")0`#\`(``J4!
+M``'+.@``8<,``%G@``/_```#W,```]BP``*PP``#V`$``K````/<`0`"OP@`
+M`C*Z``-H:P``$=8``K/```/HT``#8G0``BX-```"#``#0!$``K&```)`#@`#
+M\`,``F9A``-@$0``@>4``C!X``/L```"O!$``J#>``/P!``#2,P``TC1``/T
+M```#\$(``TCL``-(\0`"*^X``J#>``/P!``#:,P``VC1``/T```#\$(``VCL
+M``-H\0`"H-X``_`$``-(U``#2-D``_0```/P0@`#2/0``TCY``(K[@`"H-X`
+M`_`$``-HU``#:-D``_0```/P0@`#:/0``VCY``*@W@`#\`,``TC<``/T```#
+M\$$``TC\``*@_@`#\`0``L`,``+!'``#]````_!"``,`#``#`1P``J#>``/P
+M`P`#:-P``_0```/P00`#:/P``^P```*@_@`#\`D``L`,``+!'``"PBP``L,\
+M``+$3``"Q5P``L9L``+'?``#[````P`,``,!'``#`BP``P,\``,$3``#!5P`
+M`P9L``,'?``#[````K@/``*Y\``"2@@``DL)``(L'0`"2A@``DL9``(L'0`"
+M2B@``DLI``(L'0`"2C@``DLY``(L'0`"2D@``DM)``(L'0`"2E@``DM9``(L
+M'0`"2F@``DMI``(L'0`"2G@``DMY``(L'0`#[````J&N``/P00``\@P``J&^
+M``/P00``\@P``^P```*P?P`"L?\``K+_``*S_P`#:&```VAK```)U@`#Z```
+M`Z`#``/<```#V!```T`Q``*_`P`"O`(``J;\``/P00`#P0<``J#\``/P00`#
+MP08``J#^``/P00`#P04``J'^``/P00`#P00``\$0``/!(``#P3```_X```/4
+M'@`#:&L``_L```,/_@`"##(``T`U``*_`P`#_P```J;\``/P00`#P0<``J#\
+M``/P00`#P08``J#^``/P00`#P04``J'^``/P00`#P00``\$0``/!(``#P3``
+M`_X```/4'@`#:&L``_L```,/_@`"#$H``T`X``-`/0`#_P```VJ$``-J@0`#
+M[````TA5``/_```"M\```VA5``-H:P`#2`H``K]_``)H^``"LN\``Z"!``*_
+MPP`"0`\``T`E``*S_P`"L?\``D]>``/P`@`"N?,``D(I``*\`@`"3%P``_`!
+M``*S^P`#:&```TA```./\@`"O/L``D$<``)A'P`#:$```VAK``-)?``"M`0`
+M`F$4``-I?``#2I0``_\```-A?``#:&L``C&>``/_```#_@```_\```-!20`#
+MZ/```]SP``-(9``#B$0``ZB```*\0``"S,@``]C```/4'@`",L```V%)``-(
+M9``"M!```D8D``/P`@`#]````<SS``-(9``#2#8``K1```*U!``"1$```D58
+M``)D10`!S+<``K0\``)$0``#\$,``CLG``/T```!S(L``T`4``/_```#_P``
+M`L,^``/P00`#`SX``V`4``(RUP`#^`,``TAD``.,Z@``\@@``DP,``',SP`#
+M2#0``KP$``),P``"#+X``.((``-)/0`"OQ```D1/``/P!``"O_\``BU>``*_
+M4``"+5X``K\(``(M7@`#]````<S@``-(0@`#2=0``#(S``*U$```FC,``KQ`
+M``)%4P`#\`D``DS)``/P!P`"H&,``_!%``#R`@`"-,<``VAK``/T```!P$$`
+M`TA4``*U/P`"0U,``K</``)C-P`#:%0``C*Z``/H````@@(``T)Q``(RP``#
+M8G$``T@(``*T@``"1$```_`"``/T```!UU4``^P```/X`P`#2`@``K2```)$
+M0``#\`(``_0```'750`#2=```K@(``)).``"H)@``@U*``-)U``"M!```D,T
+M``*@-``"#2@``T@(``*X"``"8`@``V@(``-(*``"N"```F,X``-(+0`#:"@`
+M`VGH``)G>``#:"T``VGM``-(R``"N/L``D(H``-HR``#2)@``K@@``)@"``#
+M2+$``VB8``)D2``#:+$``\$.``/!'@`#P2X``\$^``-C,``#8W```V,T``-C
+M=``#8S@``V-X``/T```!S4H``T@(``*X]P`"0`@``V@(``-(*``"N-\``D,X
+M``-(+0`#:"@``VGH``)'>``#:"T``VGM``-(R``"N`0``F(H``-HR``#2)@`
+M`KC?``)`"``#2+$``VB8``)$2``#:+$``K`#``/!$``#P2```\$P``-C,``#
+M8W```V,T``-C=``#8S@``V-X``-)?``"M/L``D$4``-I?``#:&L``_0```',
+MBP`#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(``VC*``)H(0`#:,H``\&"
+M``-HR@`#[````_@#``,/_@`"#5\``^P```(RN@`#:&L``\$.``/H$``#Z"``
+M`^@P``.D$P`#V!```]Q```/^```#U!X``VAK``-II``#Z````_X```/4'@`#
+M:&L``VFD``*@W@`#\`,``T)@``/T```#\$$``T)<``-"60`"H-X``VFD``/P
+M`P`#0F@``_0```/P00`#0F0``VFA``/^```#U!X``VAK``-H:P`#[````C*Z
+M``-H:P`#0E8``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/4'@`"OP(`
+M`BU>``-H:P`#::0``VFB``/H```#_P```]0>``*_`@`"+5X``VAK``-II``"
+M,KH``VAK``/L```#:&L``C*Z``*Q#``#Z````Z`#``/<```#V!```^@```/H
+M$``#Z"```^@P``/^```#U!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>
+M``-H:P`#^P```PB.``(-M``#[````"'K``/H4``#Z&```^AP``*Y"``"N,``
+M`]R!``/8D0`#0E```_@#``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#
+M:&L``\&/``*_$``"+5X``K09``/^```#U%\``VAK``*_$``"+5X``\'X``-)
+MI0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#"9X``@WA
+M``-II0`#[````J&^``/P#@`#T!X``P^^``*Z/P`#``X``D`*``,!'@`"01H`
+M`P(N``)"*@`#`SX``D,Z``/4'@`##_X``@WJ``/[```##,X``@WE``/L```"
+MH;X``_`.``/0'@`##[X``KH_``+`#@`"0`H``L$>``)!&@`"PBX``D(J``+#
+M/@`"0SH``]0>``,/_@`"#?X``_L```,,S@`"#?D``^P```/0G@`#T!\``KP_
+M``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP``KP@``+`A``#H```
+M`J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#
+M\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``KP'``*CW``#\$X``W)T``-2
+M=@`#_P```_\```/^```#U!X``VAK``/[```#<G8``U)T``/_```#_P```_0$
+M``/P"``"O`@``J3<``/P`0`#:H0``KP)``*DW``#\`$``VJ```(RM``#^P``
+M`_L!``+-W@`"IM\``@X-``(P20`"L````K$```*R```"LP$``VIT``*P,0`"
+ML08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#:GP``TID``*T
+M@``"0`0``K0#``)@!``#:F0``B\7``-*9``"M(```D`$``-J9```:C$``C(,
+M``/L````6><``&(P``/_```"H;X``_!"``#QY0`#[````J'.``/P00`#"[X`
+M`PS.``#9YP``XC```TI```!:"0`#_P```_\```*@O@`#\$(``Z````.B(``#
+MT%X``&'\``!9XP`#H@(``D`)``)"*0`"I8X``@Z6``,(C@`"H`T``_`+``!!
+M^0`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$3P`#P50``J6N
+M``(.I@`#"JX``J`M``/P"P``4?D``L9O``/!=@`"H+X``_!&``/47@`"QF\`
+M`\%V``/47@`"QF\``\%V``/47@`##,X``@ZG``)KB@`"#FL``^P```-"<```
+M4@D``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"H6@``_!!``+&
+M:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&:``#`B@``P,X
+M``,*K@`"#KH``\%4``/!=@`#U%X``V)P``/L```#P6(``P9N``/<$``#V```
+M`]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X``_L```,&;@`"
+M#L\``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#:1```VD4``-I
+M&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I-``#[````\$0
+M``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<``/T```#\$4`
+M`VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4``D$#``-)T@`#
+M_P```D`*``-)P@`"I1```_`!``-)Q@`#[````]">``/[```#_P```_\```/4
+MGP`#^P$``P_^``(/#@`#[````_@!``*_!``#2F0``_\```/_```"00\``@\9
+M``/X`P`#:&L``_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\`
+M`@]%``-`$@`"M1```J4E``/P!``"OP(``FJO``/T```!ST(``L15``*E)``#
+M\`0``K\"``)KOP`#]````<]"``+$10`"I20``_`$``*_$``":J\``_0```'/
+M0@`"OQ```FN_``#QY0`#8!(``B]&``/L```#2G```_\```/!P@`#0"X``K`!
+M``-JJ``#_P```_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,`
+M`TJM``*_D``"H,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#
+M\`L``T`9``/_```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P
+M20`#0!T``_\```/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P`
+M``+$1@`#:JD``_\```/_```#_P```TJL``/L```",KH``VAK```)U@`"L,``
+M`]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P50`#
+MP1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$``*T
+MJ@`#P50``\%D``/!=``"O`<``J/^``(/^```0?\``_\```/_```"H(X``@^^
+M``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J,0``:@```J3>``/P!``#P(@`
+M`\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G>P``
+M:C$``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK``/[
+M```##,X``@^^``!!_P``8@```_\```*@C@`"#^,``T!*``*DS@`#\`0``\"(
+M``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`":JL`
+M`KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@2@`#
+MP1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+``/!
+M$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,``J#Y
+M``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"$`0`
+M`K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L```"
+M,KH``VAK```)U@`"L,```]P```/8$``"M/\``\%D``/!=``"O`<``_X```*U
+M_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X``VAK``/[```##,X``A`?
+M``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#2F(``C!)``/H\``",%4`
+M`VIB```)U@`"L,```]P```/8$``"M/\``\%4``/!9``#P70``KP'``/^```#
+MU%X``VAK``/[```##,X``A!!``(RM``#[````TID``*T@``"0`0``VID``/L
+M```"L`0``J#P``/P`P`"+W\``_0$``/P`0`"+"0``^@```/````#P1```K+]
+M``*S_P`#:&````HM```Q_@``&?T``K`*``*@W@`#\$$``K`,``.!%@`"8`$`
+M`K$6``*D/@`#\`$``K,$``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"
+ML@0``F(F``-J8``#C^$``BU>``-H:P`#_P```_X```/L```#2F```_\```/H
+M,``"8`X``VI@``-*9``"M/(``D`$``-J9``#[````K`!``/H$``#Z"```^@P
+M``-J8``#[````&HQ``-`!``#_P```K@$``)%X``"H%X``_!$``*@W@`#\$(`
+M`T`D``/_````8>D``_\```/_```#W,```X_J``*@W@`#\`$``^CP``/8\``#
+MC.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<``D`(``/P
+M0P`"+>4``_0```/P00`"+?D``D1N``/P"0`#Z,```ZMB``.E8``"15X``_!#
+M``(MY0`#]````_!!``(M^0`#[````&HQ``-`*``#0"$``KA```)(@``#\`,`
+M`D9N``/P`0`#[````%'#``*@W@`#\`,``%G"``/T```#\$$``%G!``/_```#
+MW*```]BP``-`!@`#_P```_\```)`Z``#\`,``J#>``/P00`#0"8``_\```/_
+M```#24$``J`.``/P0P`"H-X``_!!``/!10`"14X``_!#``.,Y``#]````_!!
+M``.,XP`#B9@``ZJ<``*@K@`#\`,``BWE``/T```#\$$``BWY``-`!@`#_P``
+M`_\```-)00`"0(X``J`.``/P0P`"H-X``_!!``/!10`#Z,```ZM"``)%3@`#
+M\`<``Z5```)%7@`#\$,``BWE``/T```#\$$``BWY``/L```"H-X``_`#``-(
+M(0`#]````_!!``-()0`#_P```KL!``.B9@`#@68``Z$6``.'=@`"8"<``P`+
+M``.G!@`#@@8``F8A``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`^P```./[0`"+5X``^@P``."X``#Z!```^@```-H,``#C^T``BU>``-)G``#
+M2=4``T`J``*T$``"1$<``K4"``)%6@`#A50``D1%``.D0``"MO<``D(F``)B
+M)``#:9P``^CP``-)<``#Z'```K8!``/!40`#P4```V@Q``*X_``#P5,``\%"
+M``)%6``#270``C&>``-H,0`#P5$``\%```(QG@`#:#$``\%3``/!0@`#29@`
+M`C&>``-H,0`#P5$``\%```(QG@`#:#$``\%3``/!0@`#29P``C&>``-H,0`#
+MP5$``\%```(QG@`#:#$``\%3``/!0@`#2.@``C&>``-H,0`#P5$``\%```*W
+M$``",9X``V@Q``/!4P`#P4(``C&>``-H,0`#[````KP#``-)/0`#2,```J#>
+M``/P00`#2,0``K8$``)&9``#\`0``X;*``/!?``"8B8``F$7``*@W@`#\`,`
+M`VC```/T```#\$$``VC$``-`*@`"M@@``X?&``)&:``#\`$``F,W``*@W@`#
+M\`,``VC```/T```#\$$``VC$``/L```",(@``TD]``-`*``"OP@``KP$``)/
+M#P`"3$P``F#\``/P00`#[````K0!``(R7``",6,``J'^``/P"0`",AT``C""
+M``-`*``"O`@``_\```)"+``#\$(``_0```/P0@`#Z$```C)<``/L```#_P``
+M`_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@``/H,``#
+M:.@``^@```/_```#:.@``T%(``/_```#[````C*Z``-H:P``"=8``^@```.@
+M`P`#W````]@0``*\`P`"L/<``J#^``/P00`"L'\``\$0``/!(``#P3```K3_
+M``/!5``#P60``\%T``/^```#U!X``VAK``.@`0`#H1$``Z(A``.C,0`#^P``
+M`_X```/47@`#:&L``_L```,,S@`"$<0``K#_``*\"``#P1```\$@``/!,``#
+M:H```J3^``'1W@`"H/P``_`"``-JA``#[````K#W``.A`0`#HA$``Z,A``-J
+MA``#[````TD]``/_```"N(```F1(``-I/0`"L`$``K$"``*R/P`"0B\``K,`
+M``-J:``"L````K$```*R```"LP(``VIT``*Q`0`"L@@``K,```-J>``"L`$`
+M`K(```-J?```$>```K#```)`#P`#H`(``F`.``*Q```#HB(``K,!``-J9``"
+M,K0``_\```/_```"+Q<``KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S
+M```#:#```^P```-`+``#_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8
+M``-@'``#[````&HQ``*P`0`#Z!```^@@``/H,``#:F```K\!``(P3@`"OQ``
+M`BU>``*\%``#2F```K_W``*Q$P`"0`\``F`.``-J8```,?X``#G]``*\B``"
+MM?X``X9J``)B)@`"I'X``_`!``*S!``"0`4``F`,``-J8``#2I8``T`I``*\
+M!P`#_P```D1,``.%1``"Q5X``\'%``/H0``#Z&```^AP``-JD0`"M/\``K5_
+M``*V_P`"M_\``VAA``-H:P`#_P```_X```,)G``#\$4``\"9``,*K@`#\$(`
+M`\"J``,+O@`#:I(``X````.@```#:F```K\0``(M7@`#[````T`J``-'+``"
+MH-X``_!!``-';``"MG\``X5,``)`!@`"29X``_`!``)@!0`#P1```\$@``/!
+M,``"H-X``_!$``-G+``#9S```_0```/P0@`#9VP``V=P``-'-``"H-X``_!!
+M``-'=``"MM\``X5(``)`!@`"8`4``\$0``/!(``#P3```J#>``/P1``#9S0`
+M`V<X``/T```#\$(``V=T``-G>``#2,```J#>``/P00`#2,0``K8_``)")@`"
+MML```J!.``/P`0`#Z&```F(F``*@W@`#\`,``VC```/T```#\$$``VC$``/L
+M```#29@``K@/``*Y]0`#Z#```\$N``*@S@`#\`(``F`(``)!&0`#:#```T@(
+M``*X0``"H,X``_`"``)@"``#:`@``^P```-A4``#854``V%:``-A7P`"+&4`
+M`T%0``-!50`#05H``T%?``/_```#_P```^P```*P_P`"L;\``K+_``*S_P`#
+M:&```^P```*P?P`"L?\``K+_``*S_P`#:&```^P```+$3@`#\$H``L5>``/P
+M2``"QFX``_!&``+'?@`#\$0``K3_``*U_P`"MO\``K?_``/L```"H<X``_`'
+M``,,S@`"OWP``BU>``/_```#_P```PS.``(2T``#[````K#_``*Q_P`"LO\`
+M`K/_``-JD``#[````^@```"",0`"(O,``/(Q``(B\P`",U@``BU1``-)F``"
+MM/,``K4/``)!%``"8`4``VF8``/!+@`#Z#```V@P```""@`#@>```^A```*@
+M`0`#\`$``\%.``(TN@`#2`@``KC^``)!&``#:`@``KP```(T90`"-)8``T`!
+M``/H````@C$``D1.``/P`0`")$@``T`!``/_````\C$``D5>``/P`0`")$@`
+M``(*``.!X``#_P```J00``/P`@`#P4X``C2Z``*\`0`"-&4``C26``*_`P`"
+M-T```C.E``(O`@`"OQ```D_[``'30```><L``_\```/_```"H/X``_`&``*]
+M```"-OH``KT!``(V^@`#]````=-(``-````"O````.(Q``*A#@`#\`$``C3L
+M``-````#_P```/(Q``*A'@`#\`$``C3L``-`!``#0`$``KP(``),P0`#\`H`
+M`KT```)$3@`#\`$``C<@``*]`0`"15X``_`!``(W(``"OP```/G+``/T```!
+MTT@``TG0``*\@``"3,,``_`$``*]```"-MH``KT!``(VV@`#0"P``KA```*Y
+M@``"N_\``TJE``)(&``#\`$``KO/``))&0`#\`(``KH_``)+N@`"15L``VJE
+M``/T```!PF```TG1``(O`@`#Z(```J40``/P`0`"N$```D1X``.$0``#2)P`
+M`K4$``)D10`"MG\``D`&``)@!``#:)P``VB@``-HM``#:+@``TDX``*U_``"
+M0B4``K4,``)B)0`#:3@``^@```/HT``"+MP``\'>``(NW``"+P(``X3B``/!
+MR0`#Z````K$#``*R"@`"LRT``D1)``/P`0`"LR\``^A0``(NRP`#@.H``B[+
+M``*X+P`"M`(``D1,``/P`0`"N"T``\&8``/!J``#P;@``V,J``-C:@`"+P(`
+M`X'B``.@X0`#HY8``X+D``+"+@`#Z%```B[+``.@XP`"+LL``B\"``.`Y0`"
+M0*```\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"`@`#@B0``)'4``/L
+M```"+P(``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP``/!;@`#P5,``\%"
+M``-H,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(``V@Q``)$C@`#\$T`
+M`TF<``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"8`4``F$4``/H,``#
+MP2X``V@P``-#I```(=0``K7/``)`!0`"8`0``\$0``/!(``#P3```V.D``-C
+MY``"1$0``_`!``(W.P`#@80``Z`8``."!@`"8`(``^C0``(N\``#P=X``B[P
+M``-)T0`"+P(``^A@``*E$``#\`$``K9```)&=@`#IFH``TB0``.DN@`"H$X`
+M`_!!``*T!``"M0,``J!%``/P00`"M`$``K7P``)!%0`"810``K?^``)`!P`"
+M8`8``VB0``-HJ``#:)0``VBL``.@I@`#P1```\$@``/!,``#9"0``V1D``.*
+MM@`#2"$``K@#``)F:``"N0\``KO^``)&:0`"9FH``D=[``-H(0`#:HD``V@E
+M``-JC0`#2`@``T@A``)A'@`#:`@``TC(``*X0``"N3\``F`(``-HR``"0`D`
+M`VC(``/L```#0"P``KA```*Y@``#Z+```TJE``)(&``#\`$``KLP``))&0`#
+M\`(``KK```)KN@`"95L``VJE``-(G``"O'L``D`,``-HG``#:*```VBT``-H
+MN``#2)```X3B``.EYP`"014``F$4``*U_@`"0`4``VB0``-HJ``#:)0``VBL
+M``-).``"M0,``F(E``*U\P`"0B4``VDX``/HP``"-&4``C26``/H```"L0,`
+M`K()``/H,``#Z%```B[+``.`Z@`"+LL``K`$``/!$``#P2```\$P``-C)``#
+M8V0``K`@``/!$``#P2```\$P``-C*``#8V@``C<[``-("``#2"$``ZCM``)!
+M&``#:`@``ZCK``)&:``#P#X``D53``-H(0`#:HD``V@E``-JC0`#Z$```C2Z
+M``/L```#0"D``_\```*X*@`"0EX``_`!``*X9``"H,X``_!!``*X$``#P9@`
+M`\&H``/!N``#9RX``V<R``-G;@`#9W(``K@J``)"7@`#\`$``KCD``*@S@`#
+M\$$``K@0``/!F``#P:@``\&X``-CK@`#8^X``TB>``/`%``#H1P``X$4``*P
+M]P`"2(```FB!``-HG@`#:*(``VBV``-HN@`#2NH``K#[``.!(@`"2J```FJA
+M``-JZ@`#:NX``VKR``-J]@`#[````T`I``-'-@`"L`<``K$(``)"7@`#\`$`
+M`K$8``*@S@`#\$$``K$```)(@``":($``\&8``/!J``#P;@``V<V``-G.@`#
+M9W8``V=Z``-#L@`"L`<``K$H``)"7@`#\`$``K$X``*@S@`#\$$``K$```)(
+M@``":($``\&8``/!J``#P;@``V.R``-C\@`#[````TET``/!;@`#Z'```XA(
+M``/`7@`#A5D``D(E``)B*``#:70``\%"``/!4P`#:#$``^P```*_`P`"-TT`
+M`T@(``*X_@`"01@``V@(``-`*``"O`0``K\#``),P@`#\`,``CX6``/T```!
+MU.<``TA4``*\8``"8BP``VA4``-)=@`"O!```F2L``/!6P`#P6X``^AP``-H
+M,0`",9X``TA4``*\GP`"0BP``VA4``/!2@`#:#$``C0+``-"10`",L```V)%
+M``/L````:C$``BUB``#QY0`",((``BPD``-`!``#0`H``KP#``*_!``"01P`
+M`P;Q``)`#P`#\`$``\%J``+$;@`"M0@``CD8``-`!``#Z/```/H&``*R0``"
+M0B```=5-``./!``#K_@``/H#``-)P0`"O`\``DC/``.H@``#B8(``KKC``)$
+M2@`"9$D``DG^``.)D@`"NOL``D5:``)E60`#:<$``X&&``)@@0`"+O```^@`
+M``*@W@`#\$$``K!```*Q`P`"L@D``K,)``)$[P`#\`$``K,/``/H4``"+LL`
+M`J/\``'530`#Z,```.'.``#A[@`"-K,``T`8``*@W@`#\$$``T`<``!![@``
+M8<X``F`!``)@`@`"8`,``J$.``/P0@`"R(X``,'N``*Z`@`"NQ\``LS*``#A
+MS@`"I<L``=4H``!*!@``>@,``_\```*AB0`!U4@``P_^``*P$``"S_```^@`
+M``"!Y0`#]````=4&``+/_@``^@,``,(&``/T```!U08``^C```#B`P`#Z#``
+M`C;'``/<X``"OP@``]CP``*P(``#P1```\$@``/!,``"OQ$``]0>``/_```#
+M^P```P_^``(560`"-K,``&(#``*P```#W````]P!``./P@`"L$```L`/``/8
+M```"L#\``D$/``*PP``"P`$``]@!``/47@`#T!\``K\0``*ASP`!U7H``J#>
+M``/P`P`#P0H``_0$``/P`0`#P0L``]0?``/T```!U8$``J#>``/P`P`#P2H`
+M`_0$``/P`0`#P2L``]0?``(V:P`#0`8``K`?``*Q(``#P2X``D$8``/P`0`"
+MPBX``LS"``#B`P`"I<```A5>``-*E``#_P```V"\``-`!``#W.```K\(``/8
+M\``#W.$``K\L``/8\0`"OP@``ZP6``*ESP`#\$,``\#,``)LSP`"S,X``K\(
+M``/0'@`#T%\``\&)``/!F@`#P:L``L1```.@0``"P`P``\&P``+%40`#H5``
+M`L$<``*F&P`#\`$``\&Q``+&8@`#HF```L(L``*F*P`#\`$``\&R``+'<P`#
+MHW```L,\``*F.P`#\`$``\&S``/4'@`#U)\``_L```/[`0`##_X``A6?``-!
+M.``#04D``T$J``*\#@`"HP$``_`!``/!`0`"HP(``_`!``/!`@`"HP,``_`!
+M``/!`P`"HP@``_`!``/!"``"HPD``_`!``/!"0`#Z!```J8,``/P`P`#P```
+M`X`&``.A!@`#P0$``J-%``/P`0`#P44``J-&``/P`0`#P48``J-'``/P`0`#
+MP4<``J-*``/P`0`#P4H``J-+``/P`0`#P4L``^@@``*F3``#\`,``\!$``.$
+M1@`#HD8``\$R``*@W@`#\`,``V2H``/T!``#\`$``V3H``/<X``"OP@``]CP
+M``/07@`"OP0``]SQ``*_@``"H-X``_!!``*_P``#V/$``KP0``*X`0`"N0,`
+M`KH/``*A3``#\$4``\!$``)$2@`#!`0``_0$``/P`@`#!$H``L1```*A7``#
+M\$4``\!5``)%6@`#!04``_0$``/P`@`#!5H``L50``*A;``#\$4``\!F``)&
+M:@`#!@8``_0$``/P`@`#!FH``L9@``*A?``#\$4``\!W``)'>@`#!P<``_0$
+M``/P`@`#!WH``L=P``/47P`#^P```_L!``/07@`#"(X``A8%``*X`0`#P0$`
+M`\$2``/!(P`#"9X``A8%``-$J``"H-X``_!!``-$Z``"H4P``_!%``/`1``"
+M1$H``P0$``/T!``#\`(``P1*``+$0``"H5P``_!%``/`50`"15H``P45``/T
+M!``#\`(``P5:``+%40`"H6P``_!%``/`9@`"1FH``P8F``/T!``#\`(``P9J
+M``+&8@`"H7P``_!%``/`=P`"1WH``P<W``/T!``#\`(``P=Z``+'<P`#U%\`
+M`BU1``(TQP`",((``C!)``/L```"+P(``Z.6``(VQP`#@.4``D.@``(VT``#
+M]````=9>``/!D``"H<\``_`!``/!D@`#8G4``,G.``/<X``"OP@``]CP``/<
+MX0`"ORP``]CQ``*_`0`#P00``C:-``-"=0`"OP$``_\```/!!0`"-HT``T)U
+M``*_`0`#_P```\$&``(VC0`#0G4``K\!``/_```#P0<``C:-```!S@`"OP``
+M`C:-``/L```"LB```]!>``/0GP`"00X``_!$``*@0@`#\$$``\%,``/!C``#
+MH````D$.``/P1``"H%(``_!!``/!7``#P9P``Z````)!#@`#\$0``J!B``/P
+M00`#P6P``\&L``.@```"00X``_!$``*@<@`#\$$``\%\``/!O``#U%X``]2?
+M``/[```#^P$``Z````,/_@`"%HX``^P```*S$``"I<,``_`&``/`/``#@S8`
+M`Z,V``(VT``#]````=;```*S#P`"S,X``D,\``(VQP`",A(``BU1``(TQP`"
+MOQ@``CC&``(O1@`#[````K$$``*P@``"H-X``_!!``*PP``"L@D``^A0``(N
+MRP`#[````\$#``/!$P`#P2,``J#>``/P`P`#9*@``_0$``/P`0`#9.@``^P`
+M``-`!``"O(```_\```),P``!UOH``T$!``*@W@`#\$$``T$%``*Q!``"L(``
+M`J#>``/P00`"L,```]P0``/8```#P80``C<7``/!A0`"-Q<``\&&``(W%P`#
+MP8<``C<7``*@W@`#\`,``V2A``/T!``#\`$``V3A``/T```!UQ0``K$$``*P
+M@``"H-X``_!!``*PP``#W!$``]@!``*Q`0`"L`@``J#>``/P00`"L"P``]P0
+M``/8```"OP@``B\.``-!`0`"H-X``_!!``-!!0`"H-X``_`#``-DJ0`#]`0`
+M`_`!``-DZ0`"+5$``C3'``/L```#P9@``\&H``/!N``"L@$``]2>``/[```#
+M`BX``A<;``/L```"L00``K"```*@W@`#\$$``K#```/<$``#V````K$!``*P
+M"``"H-X``_!!``*P+``#W!$``]@!``*_"``"+PX``T2H``*@W@`#\$$``T3H
+M``*@W@`#\`,``V$```/T!``#\`$``V$$``/L```#2PP``K7\``)!%0`#:PP`
+M`^P```-+#@`#P,\``FJO``-K#@`"2JP``TG5``*\"``#CW8``Z_T``+/_``"
+M+5X``VL.``/L```#2PX``\#/``)JKP`#:PX``C&>``)*K``#:PX``^P```*_
+M`P`"-T```TG```-)U0`"3`X``_!"``/T```!UY(``TG```.'=@`"IG```_!"
+M``/!$@`#Z````Z(6``.!%@`#H18``TB1``*\\``"15P``F52``*\!``"0PP`
+M`Z,R``*\_@`"1$P``F1#``-HD0`#:)4``VBI``-HK0`#P4$``\%1``/!80`#
+MP7$``V0A``-D)0`#9&$``V1E``*\`@`"0@P``X(J``-(G0`"LW\``D1#``)D
+M0@`#:)T``VBA``-HM0`#:+D``J$.``/P`@`"-SL``K`0``/!$``#P2```\$P
+M``-CH``#8Z0``V/@``-CY``"+5$``TE\``*T^P`"010``VE\``-H:P`#]```
+M`<QE``(P@@`",$D``T````/_```#_P```Z`,``.A'``#@1```F$0``,/'@`#
+MZ-```J#^``/P00`"O0$``\'.``-("``#_P```X3H``)@!``#:`@``TF8``*U
+M^P`"014``VF8``*T#P`"8`0``^@P``/!+@`#:#```TEQ``.!X0`#P08``F%Q
+M``/!+@`#Z#```V@P``(MH@`#^`$``T`-``/_```"L`$``D`&``(7TP`"H/X`
+M`_`"``*@[0`#\`4``KL^``)+M@`#J[```_0$``/P!@`#IFH``L9N``,+I@`#
+M]`0``_`!``/HL``#2!D``K+@``)&8@`"9FL``V@9``-)Y0`#_P```D9B``)F
+M:P`#:>4``\&K``(M8@`"+;L``K0/``(QG@`#2D```_@!``*D0``#\`8``J1!
+M``/P!``"I$(``_`"``*@0P`"&````LJN``*P(``"H*```_!!``/HH``"H*L`
+M`A@J``-(&0`"LN```D9B``)F:@`#:!D``TGE``/_```"1F(``F9J``-IY0`#
+M]`0``A?@``*C_@`"&#0``-'0``*@W@`"&`D``-'1``+-W@`#]`0``A>_``!!
+MT0`#_P```_\```*@J``"&#0``J&H``/P2``#2"$``P.*``.#,``"9W,``V@A
+M``-JB0`#]`0``A@T``-(&0`"LN```D9B``)F:``#:!D``TGE``/_```"1F(`
+M`F9H``-IY0`#2"4``P.H``.#,``"9W,``V@E``-JC0`#]`0``A@T``-`$0`#
+MZ,```/'E``*X@``"9W@``V`1``-)F``"M00``F$5``-IF``#2`@``_\```.$
+MR``"8`0``V@(``/X`P`#[````&HQ``/H````@@P``('/``(Y-``#0"0``_\`
+M``/_```"0`X``_!+``-`$``"O`0``]S```./Z@`"H-X``_`!``/H\``#V/``
+M`KP)``/!L0`"+>4``T`D``/_```"O`(``D`,``/P2P`#0!```KP$``/<P``"
+MO\```J#>``/P`0`"OX```]CP``.,Y``#P;$``BWE``(L)``"M`8``K4(``*V
+M!``".1@``K\8``(XQ@`"..T``K\```(P3@`#2G```_\```/_```"LI```VIP
+M``*_$P`".,8``CCM``-`)``#_P```_\```)`#@`#\$L``T`0``*\!``#W,``
+M`X_J``*@W@`#\`$``^CP``/8\``"O`D``XL0``(M^0`#0"0``_\```*\`@`"
+M0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/```XSD``.+
+M$``"+?D``TIP``/_```#_P```K*```-J<``"OQ@``CC&``(X[0`"OP```C!.
+M``-*<``#_P```_\```*RD``#:G```K\3``(XQ@`"..T``T`D``/_```#_P``
+M`D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP``*\"0`#
+MP;$``BWE``-`)``#_P```KP"``)`#``#\$L``T`2``*\!``#W,```K_```*@
+MW@`#\`$``K^```/8\``#C.0``\&Y``(MY0`".58``^P```/H```#P````K&_
+M``/!(``"L_\``VA@``(P@@`",$D```HM```1_@``&?T``K`"``*@W@`#\$$`
+M`K`$``.!%@`"8`$``X(J``*QA``"8B$``J0^``/P`0`"LP0``\$?``-J8``#
+M2F0``K2````1[``"0`0``K0#``)@!``"LQ```VID``(O%P`"OP@``D_P``/P
+M`0``\@P``^P````"#``#_P```_\```*E#@`#\`$``^P```/H````@@P``T`2
+M``/_```#_P```D2.``*@3@`#\`$``/'E``*_0``"H-X``_`#``)JKP`#]```
+M`_!!``)KOP`#8!(``B]&``!YSP`#_P```T`@``*@_@`#\$$``^P```*@W@`#
+M\`4``L`.``/P00`"L/\``_0```/P0P`"P1X``_!!``*Q_P`#8"```/'/``/L
+M```"L`$``K$"``/!)``#Z#```VIH``/!)0`"L!,``K$"``.")@`#Z#```VIP
+M``*P(0`"L0(``\$F``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP`
+M`_\```*P```"L0```K,$``-J?``#[````K`!``*Q$0`"LA```VI$``*Q$``#
+MZ"```VI$``*@W@`#\`,``KM3``/T```#\$$``KM;``#9[``#2`@``K1```"!
+MY@`"8`0``V@(``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$
+M``*P`0`#Z!```^@@``/H,``#:F```^P```(P@@`",$D``"'F``/_```#2`@`
+M`_\```/!!``#:`@``^P````*,@``:C$``_\```)`'@`#\$$``^P```(Y-``"
+MOP```C!.```R&@`#_P```K4)``.F8@`"QFX``L1N``(Y&``#0"@``^CP``*@
+MW@`#\$$``K]```#YX``#H`P``('%``-`&``#0!T``T`N``!AY0`#_P```_\`
+M``-A4``#854``V%:``#AQP`#0!```'G@``*\!``#W,```]CP``*\"0`#P;$`
+M`BWE``/HP```X<X``K`0``*Q```"LA```K,```-B=``"L(```]@!``*P```#
+MW`$``K`2``*Q`@`"LA(``K,"``-B=``"L!```K$2``*R$``"LQ(``V)P``-B
+M1``#8DP``V)(``/!C``#P9P``\&L``/!O``".D4``C(2``*_$P`".,8``B]&
+M``!AS@`#_P```K````/<```"L$```X_"``+`#P`#V````T`8``*@W@`#\$$`
+M`T`<``-`+0`#_P```]0>``/47P`"OP$``]SP``*_```#B,(``L_X``/8\``#
+MQ````\01``/$(@`#Q#,``J#>``/P00`#P6<``K41``)$90`#Q$0``L`$``*U
+M(@`"1&4``\1$``+!%``"M40``D1E``/$1``"PB0``K6(``)$90`#Q$0``L,T
+M``/4'@``><4``T)U``-"<@`"3_X``_!"``+``0`"PB,``J$$``/P1@`"I0D`
+M`_`$``/!C``#P9```\&L``/!L``"HPD``_!"``/!K``#P;```V)R``-"1@`"
+MH28``_!&``*E*0`#\`0``\&,``/!D@`#P:P``\&R``*C*0`#\$(``\&L``/!
+ML@`#8D8``J#^``':&``#0DX``J$5``/P1@`"I1D``_`$``/!C``#P9$``\&L
+M``/!L0`"HQD``_!"``/!K``#P;$``V).``-"2@`"H3<``_!&``*E.0`#\`0`
+M`\&,``/!DP`#P:P``\&S``*C.0`#\$(``\&L``/!LP`#8DH``V)T``/[`0`"
+ML1```LS.``#AS@`"H,$``=FA``-"<``#0D4``_\```+(`@`#J(```LI&``.J
+MH``#0DP``T))``/_```"R0(``ZF0``++1@`#J[```CI%``-`$```>>```KP$
+M``/<P``#V/```KP)``/!L0`"+?D``C""``(P20`#05```T%5``-!6@``8<<`
+M`_\```/_```#8!@``V`=``-@+@``X>4``^P```*[(0`"NQ````'%``/_```#
+M_P```D`.``':?0`#J80``ZND``*\#P`#B(```DB,``.*H``"2JP``TB<``-(
+MH0`"H-X``_!"``-(M``#2+D``\$8``/!6@`#C!8``X]6``)A'``"95\``J#>
+M``/P!``#:)P``VBA``/T```#\$(``VBT``-HN0`#2N@``TKM``*@W@`#\$(`
+M`TKP``-*]0`"O.X``D`,``)$3``#B)8``FR8``)@#``#BK8``FRZ``)D3``"
+MH-X``_`$``-JZ``#:NT``_0```/P0@`#:O```VKU``/L```"OP4``KP```*@
+MW@`#\$$``KQ```/<\``#V,```KR```)HC``":9P``FJL``)KO``#P0@``CJ5
+M``/!"0`".I4``\$*``(ZE0`#P0L``CJ5``/4G@`#^P```]2>``/L```#P1``
+M`\$@``/!,``#U!X``_L```/4'@`#^P```^P```!J,0`"+6(``^@```*Q8``#
+MZ"```^@P``-IH``#29@``K@/``*U]0`"LP```\$N``)@"``"014``V@P``*_
+M`0`"+5X``CDT``(P@@`#0"P``K\$``/_```"3_```Z_R``/H\``",$X``#(:
+M``/_```"M0D``L1N``(Y&``#Z/```J#>``/P00`"OT```/G@``!9QP``>>``
+M`KP$``/<P``#V/```KP)``(MY0`#Z,```.'.``#AQ@`#Z(```^B@``(Z10`"
+MOT```KP```/<P0`#V/$``K]```/<X``#V/```C(2``*_$P`".,8``B]&``*@
+MW@`#\$$``\&K``!AS@``><8``]1?``/[`0`#T%X``KL"``*A_@`#\$$``\%*
+M``*@_@`#\$$``\%:``*@^P`#\$$``\%J``*F^P`#\$$``\%Z``/47@`#^P``
+M`K`0``+,S@`"I<```_`&``#AS@`#P8P``\&L``(Z10`#]````=K5``*Q!``"
+MS_X``/G&``*A\0`!VQ```^BP``#9S@`#P8L``\&K``(Z10``>>```KP$``/<
+MP``#V/```KP)``/!O@`"+>4``]S@``*[0``#V+```_0```':U0`".58``K@(
+M``*Z"``".D4``%G'``!YX``"O`0``]S```/8\``"O`,``LN\``*\"0`"+?D`
+M`T@(``*T8``"8`0``V@(``-)F``#_P```K(!``/H,``#:#```^P```*T!``"
+M1C0``J!D``';,@`"OP,``CX_``-H:P`#0DD``C+```-B20`#[````T)-``(R
+MP``#8DT``TAD``/X`0`"O0P``DG2``*@V0`#\$8``K\#``([D0`"OP,``KT`
+M``([<@`#[````KT$``))T@`#\`8``K\!``([D0`"OP$``KT```([<@`#[```
+M`KT(``))T@`#\`8``K\"``([D0`"OP(``KT```([<@`#[````KU@``))T@`"
+MH-D``_!'``*_`P`"/!```K\#``*]`0`"O`$``CMR``/L```"O2```DG2``/P
+M!P`"OP$``CP0``*_`0`"O0$``KP!``([<@`#[````KU```))T@`#\`<``K\"
+M``(\$``"OP(``KT!``*\`0`".W(``^P```-(8@`"3,X``AN$``.`\@`#P```
+M`X'X``/`$0`"3=X``_!%``/````":J```DJA``/T!``#\`,``\`1``)*H``"
+M:J$``VAB``*P\@`":J```J`*``/P1P`#2$```K0(``*U]P`"810``VA```)!
+M%0`#:$```VAK``/L```#2%0``^B```*Y`P`"2_X``_`!``)HB0`"N@(``KD,
+M``)+^@`#\`$``FB)``)C.``#:%0``^B0``*T!``"2_X``_`!``)IF@`"2_H`
+M`_`!``)IE``#26```VAK``/_```#_P```TAE``/_```"2]8``J"]``'<"@`"
+M2Y,``=NF``-`*``#A/```*("``.B)@`",9X``P(N``';M0`#2`0``K3O``"*
+M+``"010``V@$``(^,P`"M@0``V@Q``-"20`#Z(```]R```-*E``#B$8``ZB"
+M``*\P``"S,@``]C```/4'@`#0"D``C+7``)%6@`"&_,``$H!``/_```"N(``
+M`\"9``.)G``"3/X``_`&``-)/``#2)D``F,X``)D20`#:3P``VB9``),^@`#
+M\`8``TE```-(L0`"8S@``F1)``-I0``#:+$``DS^``/P!@`#2)```TB5``)@
+M"``"9$@``VB0``-HE0`"3/H``_`&``-(J``#2*T``F`(``)D2``#:*@``VBM
+M``-`*``#_P```K@$``)!&``#\`$``CS)``-`*``#_P```K@(``)!&``#\`$`
+M`CV#``-(0``"N(```DO^``/P`0`"81@``DOZ``/P`0`"8B@``VA```*\`0`#
+M[````TA4``/`B``"0S@``VA4``*\```#[````T`H``#YNP`"N`@``D$8``/P
+M`0`"/9H``T`H``/_```"N`0``D$8``/P`0`"/1@``T`H``/_```"N`(``D$8
+M``(<1P`"2_X``APJ``-)/``#2)D``KA_``)#.``"1$@``VD\``-HF0`"O`(`
+M`DO\``(<-``#24```TBQ``*X?P`"0S@``D1(``-I0``#:+$``DO^``(</0`#
+M2)```TB5``*X?P`"0`@``D1(``-HD``#:)4``KP"``)+_``"'$<``TBH``-(
+MK0`"N'\``D`(``)$2``#:*@``VBM``-`*``#_P```K@,``)!&``"'%0``K5$
+M``(];``#2`@``K@0``)!&``!W%0``CW0``(W30`"2_X``AQ;``-(F``"M,``
+M`F,T``)#-``#:)@``KP"``)+_``"'&,``TBP``*TP``"8S0``D,T``-HL``#
+M0DD``K@!``/<@``#2I0``XA&``.H@@`#Z,```LS(``/8P``#U!X``C+7``-(
+M0``"N'\``DO^``/P`0`"01@``KP"``)+_``#\`$``D(H``-H0``#2`@``K@0
+M``)!&``!W(<``T`H``*\!``#_P```DS"``/P0P`"/;$``_0```/P00`"/A8`
+M`D[N``'<B0`"O`@``CWG``!YNP`#_P```_\```)+_@`#\`0``TB8``*T/P`"
+M0S0``VB8``*\`@`"2_P``_`$``-(L``"M#\``D,T``-HL``#2$```K@@``)(
+M@0`"'*```CXS``*V`@`#:#$``TA```*X`@`"2(```ARG``-(/0`"/C,``V@Q
+M``-("``"N!```D$8``/P!``#2$```KP@``/DPP`"/><``T@$```B+``#_P``
+M`_\```/!%``#:`0``'F[``*X```"O`(``TA4``)+_@`#\`$``K@#``)+_``#
+M\`(``KP,``)HC``#P(@``D,X``-H5``#@/@``(("``-"20`",L```V))``/L
+M```#2`@``K@0``)!&``!W-H``DO^``/P!``#2E0``K0/``)@!``#:E0``KL"
+M``)+^P`#\`0``TI8``*T#P`"8`0``VI8``)+_@`#\`0``TI4``*T\``"8`0`
+M`VI4``*[`@`"2_L``_`$``-*6``"M/```F`$``-J6``#2`@``K@0``)!&``!
+MW/@``DO^``/P!``#2E0``K0/``)A%``#:E0``KL"``)+^P`#\`0``TI8``*T
+M#P`"810``VI8``)+_@`#\`0``TI4``*T\``"810``VI4``*[`@`"2_L``_`$
+M``-*6``"M/```F$4``-J6``#2`@``K@0``)!&``#\`$``^P```)+_@`#\`0`
+M`TI4``*T`0`"8B0``VI4``*[`@`"2_L``_`$``-*6``"M`$``F(D``-J6``#
+M[````T@(``*X$``"01@``=TI``)+_@`#\`0``TI4``*T_@`"0B0``VI4``*\
+M`@`"2_P``ATI``-*6``"M/X``D(D``-J6``"2_X``_`$``-*5``"M`\``D$4
+M``-J5``"O`(``DO\``(=-@`#2E@``K0/``)!%``#:E@``T@(``*X$``#_P``
+M`D$8``'=2``"2_X``_`$``-*5``"M/```D$4``-J5``"O`(``DO\``(=2``#
+M2E@``K3P``)!%``#:E@``DO^``/P!``#2E0``K0/``)`!``#:E0``KP"``)+
+M_``"'54``TI8``*T#P`"0`0``VI8``-("``"N!```D$8``'=9@`"2_X``_`$
+M``-*5``"M/```D`$``-J5``"O`(``DO\``/P!``#2E@``K3P``)`!``#:E@`
+M`KP(``(]YP`"M40``CUL``(^/P`#[````K?\``*V,P`"M````TC(``*@_@`#
+M\$$``K0"``*\`@`"H/P``_!!``*T`0`"810``VC(``)@!0`#:,@``_\```)`
+M!@`#:,@``KP"``(]YP`"01<``VC(``/L```#2`@``K@0``)!&``!W90``DO^
+M``/P!``#2)@``K1_``)")``#:)@``KL"``)+OP`#\`0``TBP``*T?P`"0B0`
+M`VBP``-).``#A/(``\!$``)")``#:3@``^P```-).``#A/(``F(D``-I.``#
+M2`@``K@0``)!&``#\`$``^P```)+_@`#\`0``TB8``*T@``"8B0``VB8``*[
+M`@`"2[\``_`$``-(L``"M(```F(D``-HL``#[````CWJ``-(5``#C/@``F(L
+M``-H5``#270``KS?``)$+``#P5,``CXS``-H,0`",9X``KP0``)D3``#:#$`
+M`C&>``-(5``"O)\``D(L``-H5``#270``_\```/!0@`#P5,``CXS``-H,0`"
+M/@```K5```(];``"/=```^P```*[_``"2OX``_`(``-((0`#_P```F5>``-H
+M(0`#:HD``D5;``-H(0`#:HD``KH"``)*KP`#\`@``T@E``/_```"95X``V@E
+M``-JC0`"15L``V@E``-JC0`#[````PS.``'=YP`#[````D'^``(=]``#0ZX`
+M`K#O``/_```"2[```DJP``))L``"2+```V.N``*Q`@`"0?$``AVR``-#[@`"
+ML.\``_\```)+L``"2K```DFP``)(L``#8^X``^P```)!_@`"'@H``T.N``*P
+M$``#_P```FNP``)JL``":;```FBP``-CK@`"L0(``D'Q``(>%0`#0^X``K`0
+M``/_```":[```FJP``)IL``":+```V/N``/L```"/C,``K8"``-H,0`"M@$`
+M`TF>``*\$``"9*P``\%;``-H,0`#29H``KP"``)DK``#P5L``V@Q``/_```#
+M270``KP0``)D+``#P5,``V@Q``(QG@`#P,P``D1,``-H,0`",9X``\%*``/!
+M6P`#:#$``^P```/!;@`"MP,``DW^``/P`@`"O0(``D=]``*]`@`"3?T``_`"
+M``*]`0`"1WT``^P```*X```"N0```KH```*[```#2L$``KR```/!;P`#Z'``
+M`VK!``-B@@`#0P```F9L``*WZ``#:L$``V,```-#*``"M_<``VK!``-C*``#
+M0RP``KQ_``)&;``"MQ\``VK!``-C+``#Z&```^AP``-JP0`"L@(``K$#``*P
+MK``"0_X``_`!``(^J``"L.P``D/R``/P`0`"/J@``K(/``*Q!``"L````D/^
+M``/P`0`"/J@``K,"``*P0``"0_,``_`!``(^J``"L@\``K$$``*P@``"0_X`
+M`_`!``(^J``"LP(``K#```)#\P`#\`$``CZH``)/_@`#\`4``T<T``-'.0`#
+M_P```V<T``-G.0`"LP(``D/S``/P!0`#1W0``T=Y``/_```#9W0``V=Y``/H
+M@``#Z)```^B@``/HL``"3_X``_`%``-E+@`#93(``V4V``-E.@`#93X``K,"
+M``)#\P`#\`4``V5N``-E<@`#978``V5Z``-E?@`#2L$``_\```/!;P`#Z'``
+M`VK!``-F`@`#9H(``^A@``/H<``#:L$``^P```/<$``#V````]!>``/!P@`#
+J_P```]1>``/[```#T%X``PS.``'>K0`#[````_\```/_```#_P```_\`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_me.bin.uu
new file mode 100644
index 0000000..330ab5f
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_me.bin.uu
@@ -0,0 +1,194 @@
+begin 644 HAINAN_me.bin
+M?$"``8@```#40`!_?$"``8@```!\0,`!S$``*,Q``"E\0(`!B````-A``![$
+M$``A)1```I4`__Y\00`!Q!P`)L0@`"38```<S(``"\W!H-G.`:#:V$``',04
+M``>50``"V4&BI,0;``+8```;S8``&L`^``3,`:'TS#T@!,0]``',```%V$``
+M&]A``!]\0(`!B````,Q!+@',02X"S$$N`\Q!+@!\0(`!B````'Q`P`&,``5Y
+MS$$N`<Q!+@+,02X#C``%?<Q!+@!\0(`!B````'Q`P`'$&``PQ!P`,7W90`)\
+MU@`.Q"0`%9I`__^:```#S,``%(````#`*(``SH$P2L0\`'\DD``"P"H``7Q`
+MP`&5```#Q!0`,'S4P`$4S``"S,$EQ]1I)<A\0(`!B````'Q`P`$8T`'H),P`
+M?WQ!0`%06``@?5E`&GQ!@`%07``@?9V`&GQ!P`%08``@?>'`&GQ"``$E)``!
+MS,``(]%``"31@``ET<``)MA``">60``,Q"@`+)J`___()``M?EZ`#)J`_YP2
+M+``&!NP``0KL``&:P/__V$``)X```&#$*``LFH#__WQ`@`&(````?$#``<00
+M`##,027,?04``<Q!)<_-`27.?$%``230`'\56``0)50`_\T!)=/-@271S4$E
+MT,Q!)=)\04`!?$&``1C<`#`8X``Q&.0`,ACH`#,8[``TS$$EULQ!)=?-@275
+MS4$EU,`R``260``AEL```LPQ)=G,,278EH``!);```+,,27;S#$EVGP#`!&6
+MP``#Q#$``5,P`"#$-0`!?S<`&M,``!:6@``(?`.`$9;```/$.0`!4[@`(,0]
+M``%_OX`:TX``%Y7`_V":P``$?7<`#)<`_^2`````4;@`('^7@!I_.X`,EX#_
+MWX````"6`/]6S#$ES<R```O$-0`!ET#__'Q`@`&(````Q"``)GQ!0`'&)P/D
+ME4```LP```',```)"F0``<Y@`^1\0(`!B````'Q`P`'`%@`$)-#__WT5``K,
+M@``+S!$``!C8`#X4W``?Q"$``7Q"0`&5P``%?E:`"LP```O,*0``Q"4``7XF
+M``E\0L`!E8``!7[7``K,```+S#$``,0M``%^+@`*)1#__\P```O.$0``@```
+M`'Q`P`',0```@````,R```O-02)=S0$B7,Q!H?Q\0(`!B````,R```O,02)7
+M?$"``8@```#,02)<S$&A_'Q`@`&(````P`X``<Q!(ES,0:'\U$VA_7Q`@`&(
+M````S(``"\Q!(EU\0(`!B`````A,``%\00`!S(``"WQ!0`$E6/__&5P#\!5@
+M`!7-@:$"S<$B5LX!(ER4P``$S0&A_`C,``&```#TS0&A_,P!H0)\0(`!B```
+M`'Q`@`'`*@`"?$#``7Q!``%]*0`*))0``228``8DG`,`%=P`"'Q"``%\0D`!
+MP"X`!,R```N50``.!?`B6'\O``K,,0``Q"D``<S!(6G-`2%JSH$A:S&T``+,
+M`2%LQ#``&9<`__^70``*@``!,#&T``*70``'P"X`!`7P(EA_+P`*S#$``,0I
+M``&```$P,;0``)=```-^`H`!@``!,#&T``270/[5(F0`,,X!(6W.02%NQ"H`
+M`,0L``DQ\```,?0``3'X``*:P``"C``#7-J!HJ27```#SH&BMX````"70``#
+MSH&BNX````"7@``#SH&BOX````#.@:+#@`````08``"```%%!!@``<0D`"9\
+M0,`!QFL#Y!C0`#`DU`#_!J@``<ZD`^2:0``2Q#@`!]A``![$/``A)_P``I?`
+M__[,@``+EX```ME!HJ3$/P`"S\``&L`^``3,`:'TS#T@!,0Y``',```%V$``
+M'\U!H-K,@``+S4$N%)F```+,```"S4``"'Q`@`&(````?$#``1C0`>@8U``P
+M&-@`-`4H`6U\0@`!?$)``94```>&@```@``!AX```:N```'!@``%=8```7T1
+M5``0?A8`"LR```O480``E8#^B<`Z``3,.2%`Q#D``7Q`@`&(````$50`$%)D
+M`"!^)@`:S4``'=1B``"5@/Y^Q"``'9H`__]\0(`!B````-PZ``"90``;)YP`
+M`97```T+N``!S@$A:<Y!(6K,02%KS`$A;)N```.5@/YO@``!GU)D`"!^)@`:
+M1B``!%8D`"`B9``RS@$A:<Y!(6H+N``"S$$A:\Q!(6R;@/_]E8#^8L0P`!F7
+M`/__?$"``8@````+N``!S@$A:<Y!(6K,02%KS`$A;)N`__N5@/Y7@``!GU)D
+M`"!^)@`:F4``"M(``"O40``LV$``+8P`!8:5@/Y.Q#@`+YN`__]\0(`!B```
+M`-PV```+=``!T@``*\Q``"S80``MC``%AIM`__N9@/_U?$"``8@```#$'``P
+MP"H``7X>``$6(``"S@$EQ]1I)<B5@/XYP#H`!,PY)<O$.0`!?$"``8@```!\
+M0,`!?$$``1D4`#V90``*Q!P`#97`___,P2$`S0$A`<S!(0+-`2$#V0&BI'Q`
+M@`&(````S,$A=<T!(7;$(``.E@#__S(H``(R+``#FH``!)K```7,```,@```
+M`,P```R```':P#X`!,P],'[$/0`!,^@``9?`_A::@`.-!#A``,P```'/@3!*
+M@``%>'Q`P`%\00`!0-0``\U!(ES-`:'\P!X``7Q"``$(S``!!B0``08H``+.
+M':']SEVA_<Z=H?V8P/_Y?$"``8@```!\0,`!)-```13,``%\04`!?$&``<R`
+M``N5```&(9@`,,U!(6W-@2%NQ!X``(```A#`(@`$?A8`"LPA``#$'0`!?$)`
+M`7Q"@`&8P``#S>4``(````#.02%ISH$A:LW!(6O,`2%L?$"``8@```!\0,`!
+M?$$``7Q!0`%\08`!?$'``1BD'^@R:``\!"```9:```A\0@`!.C```T(@``*;
+M```"!"``0`0D``&```(L?@)``0ID``',``!_FD#__B3L`!#,@``+FL``"<`J
+M``3$+``0?I*`"LP```',*0``SL``$,0Q``&```(^(50`,,T!(6W-02%NQ#(`
+M`'\?``DD]``'!W@"0I=``">'@```@``"2H```D^```)4@``"68```EZ```)C
+M@``":'\;@`\4I``(EX``'29D`/^```)Y?QN`#A2D``B7@``8)F0`_X```GE_
+M&X`,%*0`")N``!,F9`#_@``">7\;@`T4I``(FX``#B9D`/^```)Y?QN`#Q2D
+M``B;@``))F0`_X```GE_&X`.%*0`")N```0F9`#_@``">12D``@F9`#_,F@`
+M/!3L``B:@/V4?$-``7Q#@`%\0\`!S```"Y;```;/02%ISX$A:L_!(6O,`2%L
+M@````,_U``"`````,F@`/)J`_['40`!_@````'Q`P`%\00`!P!X``144`!+`
+M(@`"P"8`!)5```3`)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!
+M(6G-`2%JFH``!\U!(6O-@2%LEL#];\0P`!F7`/__@````,@4`!A56``@S4$A
+M:\V!(6R6P/UG@``"DGQ`P`%\0(`!%)0`$!%4``4DB/__$(@`!7Q`P`$4T``0
+M),S__\R!(73`&@`$*9@;I,P9``#$&``!)9@?_WT9``Z9`/U5?8T`#ID`_5/$
+M'`/GR"``&'V=``Z5```)Q"0#Z,0(`^E0B``@?*9`&GY60!%^8D`25F0`/Y9`
+M_4?-@`/GS@`#Z%8@`"#.``/IE,```(````!\00`!?$%``<Q```/,0``$S``#
+MY,P``^7,``/FP`Z``'Q"0`%\0H`!@````'Q`P`$8T`'H!2@"T1S,_@C,@``+
+ME0``"8:```"```+<@``"ZX```O*```+Y@``"_X```R&```,_S,&BI'Q`@`&(
+M````P!((`'Q!0`%\0@`!?0S`"L`2``056``#%5P`#7W1P`D2(``3?AY`"GY.
+M@`K.@:*DS8&A_GQ`@`&(````!!`A&,04``N50/__U%$``,S!HJ1\0(`!B```
+M``00(0;$%``,E4#__]11``#,P:*D?$"``8@```#80``/S,&BI,00``^9`/__
+M?$"``8@````8T``T$10`%'Q!@`%]1<`*?$(``1GH`/@RJ``"?$)``<0L``V6
+MP/__FH``",V!(0#-P2$!S@$A`LY!(0/,P:*D?$"``8@````=_/\8S8$A`,_!
+M(0'.`2$"SD$A`\S!HJ3$+``-EL#__\V!(0#/P2$!S@$A`LY!(0/,P:*DQ"P`
+M#9;`__^```,*)-@``7Q!``%\04`!$9P`$'Q"``%]74`*%60`'29D``*5@``)
+MQ#P`'Y?`__^:0``-Q"@`,!:H``)^*@`!S```%8```SG$/``@E\#__YI```7$
+M*``P%J@``GXJ``',```5S0$A6,U!(5G.`2%:S,&BI'Q`@`&(````&-``-!$4
+M`!0DV``_E0#_E\0D``V60/__-9P`!LP!(0#-02$!S`$A`LP!(0.9P``#V0&B
+MI(`````$(``4S@&BI'Q`@`&(````?$#``130`!T8U``\F0```H````#-0``<
+M@````'Q`P`&,``-<?$"``8@```#80``>Q#P`(2?\``*7P/_^S(``"]E!HJ3$
+M/P`"S\``&L`^``3,`:'TS#T@!,0]``',```%V$``'Y````!\0,`!!#P`(LR`
+M``O/P:*DS```!GQ`@`&(````P!(``7Q10`K,@``+U%4``'Q`@`&(````?$#`
+M`5!0`"!\T,`:51P`/WQ!0`%\08`!S(``"]#``(.5P``=Q#P`"9O```*,``-<
+MV```'L0@`"$F(``!E@#__L`F`"@J9'_#S(``"\Y!(7S`)___SD$A?<0H`"3.
+M@2%ZS`$A?L`J``0$+``(?L,``0LP``&;`/__S(``"\PI(7_$-0`!%W@`'W[#
+M``&;@/_YV```'Y6`_&.,``5YW8,```5<(`#,```+U%T``(``!8%\0,`!4%``
+M('S0P!I\04`!?$&``<R```O0P`"$E8#\58P`!7G=@P``!5R@`-1=``"```6!
+M?$#``5!0`"!\T,`:?$%``7Q!@`',@``+T,``A96`_$B,``5YW8,```5<+`#4
+M70``@``%@<R```O40R``?$"``8@```#,@``+U$.@`'Q`@`&(````S(``"]1#
+M+`!\0(`!B````'Q`P`%\00`!?$%``93```)\08`!?$'``7Q"``&5```*E4``
+M"<R```O,0RP`S<,L`,R```O,0RP`S@,L`'Q`@`&(````Q"0`'LQ``'_,0`!_
+M&F@`,'Q`@`%\0,`!EH#\']B``"Y\0(`!B````,R```O,0Z``?$#``008``'=
+M@P``C``%>=1#H`"```6!)(S__\R```O430``?$"``<R```N(````?$#``1C4
+M`#`8T`'H&/P`-"3,``\$Z`/\?$&``7Q!P`&4P`!*AH```(``!!2```0<@``$
+M)8``!#2```0'@``$"H``!`R```0.@``$$(``!!)1W``@?9X`&H``!%/((``M
+M@``$4\@@`!:```13R"``%X``!%/((``8@``$4\@@`#*```13F4```R'<`#"`
+M``08(=P`4,V!(6W-P2%NR"(``(``!%-1W``@?9V`&M@``"/1@``DV$``)\0H
+M`"R:@/__R"``+H``!%/$'``PP#(`!'V=@`$5F``"S8$EPLPQ)<.50``#S(``
+M"\PQ)</$(0`!E4``),0E``%29``@?B8`&H``!%,QK`@`Q#0`$);```/,```!
+M@``$1CFL"GP]L`IWFL``!)<```/,```!@``$1CFL"MP]L`K9FL```Y<```+,
+M```!@``$1L0T`!#,@``+P#H`!'VY@`K,&0``E4```P68``',&0``Q"$``95`
+M``7$)0`!4F0`('XF`!K/0``0!2@$5WQ!@`%\0<`!E0``!X:```"```2(@``$
+MDH``!*"```1K@``$?<0T`!#,@``+SAD``)5```0%F``!5B``(,X9``"7P/N<
+MP#H`!,PY(4#$.0`!ST``$'Q`@`&(````,:P(`,0T`!"6P``#S````8``!%XY
+MK`I\/;`*=\0T`!":P``$EP```\P```&```1>.:P*W#VP"MF:P``#EP```LP`
+M``&```1>4=P`('V=@!K8```=SAH``)5```0%F``$5B``(,X:``";P`"0?$"`
+M`8@```"50``"(=P`,E8D`"#-@2%IS<$A:LX!(6O.02%LF\#^`WQ`@`&(````
+M4=P`('V=@!K1@``KS@``+)5```-6)``@SD``+-A``"V,``6&E\#[9<0X`"^;
+M@/__?$"``8@```#$'``PP"H``7V=@`$5F``"S8$EQ\XI)<B50``#5B0`(,YI
+M)<B7P/M7P#H`!,PY)<O$.0`!?$"``8@```#$%``</5@`!)F`__[,```-?$#`
+M`2A0@``5%``?&1@`?1D<`'3$(``P,9@``3'<``&5@``"?.#``7Q"0`&5P``"
+M?F)``<S!(8#-`2&!SD$A@LQ!(8/,02&$E4#[.\04`!R90/__?$"``8@```#`
+M%@`$Q!``)LR```O,52%`Q!D``<P0`_=\0(`!B````,0@`";8```>Q`P`(23,
+M``&4P/_^QB<#Y'Q`P`',@``+S,$A?,Q!(7W$&``D?$$``7Q!0`&60``"S8$A
+M>LT!(7[`-@#`P"H`!']/0`D17``!!=P``9=``!3,*2%_Q"4``1IL`#Z6P``'
+M$5P``07<``$)W``!F<#__\R```N```3H%W0`%R@L`&";0``"*"P`0,[``"/8
+M0``GQ#0`+)M`__^```4`"=P``9G`___,@``+S"DA?\0E``$6;``?$5P``07<
+M``&:P/_X%/P`']@``!^;P/KZQ!``)LP0`_=\0(`!B````'Q`P`%\00`!%1@`
+M'U$4`"`9'``QF8``",T``!U]34`:U%8``)7`^NS$(``=F@#__X````#<.@``
+MP"8`!,S!(6E])0`*S0$A:@NX``+,02%KS$$A;)N`__V9P/UQ?$"``8@````D
+M3`#_S$P#`'Q`@`&(````Q"``)L1/`P#,@``+S.$A18````#,@``+VL&BI'Q`
+MP`%\0(`!B````,0,`!J8P``#V$``+X``!3+80``P?$$``7T!0`$55``!)50`
+M`9E```DE$``!E0#ZP\@4`#250``%R!@`&Y6```-]E<`.E<#ZO<@@`#/2```R
+MV```'L0@`"$F(``!E@#__L`F"$#,@``+SD$A?,P!(7W$*``DSH$A>LP!(7[`
+M*@`$!!0`"'U!P`$H+`!`SL``(]A``"<)W``!F<#__\R```O,*2%_Q"4``19L
+M`!]]0<`!FL#_^<0T`"R;0/__V```'WQ`@`&(````Q`P`$S#0``&5```#S(``
+M"]L!HJ3,0``.Q`P`$L00`!,PU```/1@``7U9P`K80``QF<#_^MA``!/0```R
+M?$"``8@```#`#@$`S````<S!,$J```5XV$``$<0\`!&7P/_]D````-@``!'$
+M/``1F\#_^9````#8```1Q#P`$9O`__5\0(`!B````-B``![$/``A)_P`!)?`
+M__[`.``OP#X`!,^!(?C,/2'YQ#@`)@0\``5_^X`"Q#T``7_[P`4G_``!F\#_
+M]MB``!^0````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0/M`!```@`1``4`$@`*`!4`)0`6`"L`%P"Q`!L`-``<`$$`'0!O`!X`
+M3``A`+L`)`#9`"4`V0`G`.,`*`#6`"H`WP`L`-D`+0#C`"X`YP`O`.T`,`#Q
+M`#(!1``T`0,`-0#C`#<!90`X`-D`.0'-`#H!\``[`@``/`(;`#T"?0`^`IL`
+M/P%"`$`#\P!!!*\`0@3*`$,$T@!$`L``10(;`$8"RP!'`LL`2`++`$H#40!2
+M`U@`4P-K`%<#<@!?`[$`8`-X`&$#I`!H`[X`:0/"`'(#R@!S`^4`=@/&`'<#
+MQ@!Z!0L`?04D`'X%*`"%!2T`A@4R`(H%9`"+!60`#P5U``\%=0`/!74`#P5U
+M``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`
+M#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/
+:!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_pfp.bin.uu
new file mode 100644
index 0000000..478c7da
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_pfp.bin.uu
@@ -0,0 +1,194 @@
+begin 644 HAINAN_pfp.bin
+M?$"``8@```#,@```U$```'Q`@`&(````S(```,S```#40```?$"``8@````D
+M3``/,.@``B20``*:@``,?$%``5!8`"!]E<`:F,```]'``!F`````F0```]'`
+M`!J`````T<``&X````#$(``5QB0`"I9``:U\00`!?$%``<R```#,P```S0``
+M`,U```#-```MS4``+GQ`@`&(````S(```,Q```#,```2@``#\<Q``"A\0(`!
+MB````,@,`!M\Q0`1T0```]C```/,@```S````,Q```!\0(`!B````,@,`!I\
+MQ0`1T0```MD```)\0,`!?$$``7Q!0`'$&P`#Q!\``\0C``/$)P`#E8#_OI7`
+M_[W$*``0S```%)J```3$,``%SP```,P```#$*``)("P`?B+LSD@:J``PSL``
+M`-@```#-@```S<```,X```#.0```S,```,T````<B``0EH```MB``"+,@```
+MS4```'Q`@`&(````R`P`&GS%`!%\04`!?$&``7Q!P`%\0@`!?$)``97`_YS1
+M```"V0```@G<``'$*P`#Q"\``\0S``/$-P`#EH``&9;``!C$#``0S```%)C`
+M``3$#``%S,```,P```#$#``)(#@`?B.XSD@8S``PSX```-@```#.@```SL``
+M`,\```#/0```S4```,V````<B``0E,```MB``"+,@```SD```)7`_WM](0`1
+M@```94'H``31```"SH```@G<``'$*P`#Q"\``\0S``/$-P`#EH``&9;``!C$
+M#``0S```%)C```3$#``%S,```,P```#$#``)(#@`?B.XSD@8S``PSX```-@`
+M``#.@```SL```,\```#/0```S4```,V````<B``0E,```MB``"+,@```SD``
+M`)7`_U=](0`1@```B\@,`!I\QL`1TL```ME```)\0,`!?$$``7Q!0`'$&P`#
+MQ!\``\0C``/$)P`#Q"L``Y6`_TB5P/]'S```)M+``"?$+``0S```%)K```3$
+M+``%SL```,P```#$+``)&NP`,"`P`'XC,.Y(SP```-A```#-@```S<```,X`
+M``#.0```SH```,S```#-````'(@`$);```+8@``BS(```,U```!\0(`!B```
+M`,@,`!I\Q0`1?$%``7Q!@`%\0<`!?$(``7Q"0`&5P/\CT0```ME```()W``!
+MQ"L``\0O``/$,P`#Q#<``\0[``.6@``<EL``&\P``";1```GQ`P`$,P``!28
+MP``$Q`P`!<S```#,````Q`P`"2`\`'XC_.Y(&,P`,,_```#80```SH```,[`
+M``#/````ST```,^```#-0```S8```!R(`!"4P``"V(``(LR```#.0```E<#^
+M_GTA`!&```#>Q!@`""68``%\0D`!?$*``96``N52K``@?N;`&GQ`P`%\00`!
+MQ!P`$9G`__\<B``0((@`<!#4``)^U4`1T4```\T```/,@```SD```,Z```#,
+MP```W#H``,T```"7@/[D?$#``7Q!``&```$2Q!``#\0<``29```$S```$LW`
+M``#,````Q!@`""68``*```$')(P``L00`!#$&``(F,``")D```7$'``%S```
+M$\W```#,````&9@`,(```0<9F``X@``!!\0<``3-P```S````,R```#40```
+M?$"``8@```#$'``$S<```,P```#(#``9S(```,Q````04``"?0T`$544`"#1
+M```#V$```\P```!\0(`!B````,0<``7-P```S````,R```#40```?$"``8@`
+M``#$'``%S<```,P```#$)``DR`P`',93`^C,@```S$```%$0`"!\T,`:?,4`
+M$544`"!]18`*S0```,V```!\0(`!B````'Q`P`%04``@?0U`&M%``!C,```E
+M?$"``8@```!\0T`!R!P`&,08`!<<B``0((@`,'Q!0`%]6,`$?-S`$530`"!\
+M04`!S(```,]#HI[,PZ'ZS0.A^<U#HIW-0```S$```'Q`@`&(````?$-``1R(
+M`!`@B``P?$#``7Q!``%\04`!S(```,]#HI[,PZ'ZS0.A^<U#HIW-0```S$``
+M`'Q`@`&(````?$#``230``',PZ*?V$``%Y4```+8@``7S(```,S```!\0(`!
+MB````'Q`P`',@```S,.BHLS```!\0(`!B````'Q`P`$4U``?S(```'Q!``&5
+M0``"S,``'Q48`!_,P```S0```)6```+-```@S```?X```_$@"`!^((@'Z,0@
+M`!4<J``0SJ``!'Q!``%05``@?$&``08D``'.0``5%9P`&'T5`!K-X``)S:``
+M"]$@``'-H``!Q"P`)%4P`"#1```<SRP#Z)H```3$)``CFD```B'<`##-P```
+M@``#\<0@`!7&#``*'*@`$)3```/.H``&@``!KLP```B```'*Q"``%7Q!@`$*
+M(``!QA0`#<88``I]68`*S@``%96```3,H``&S6``!H```_',H``$S6``!(``
+M`_%\0,`!%-``'C$4``&5`/XJE4`"$1C0`>@8U``P&-@`-`4H`>5\0@`!?$)`
+M`94```>&@```@``#]8```_6```/U@``#]8```?,15``0?A8`"LU``"'480``
+ME8#^$<0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``"'48@``E8#^",0@`!.:
+M`/__?$"``8@```!\0,`!?$$``7Q#@`%\0\`!41``(%/\`"!_OX`:?-#`&@0<
+M``33@``"V(```M#```+-P``"!!P``00@``%\`D`!Q!<``\0;``-1F``@?5E`
+M&L0K``/$+P`#Q#,``\0W``,)W``!4NP`('ZN@!I3=``@?S<`&G\K0!)^=D`1
+M5J@`/U<P`#]^LH`)?BH`"9G`__&6@/_D4_0`('][0!I]94`155@`(,P``"'-
+M=@``S;8``,0@`!.:`/__?$"``8@```#$(``D?$#``7Q!``',X`/]S2`#^E$4
+M`"!\U,`:T,```A44`!\9&`#PF4```@0T```O7``!?78`"7U>0`F9@``$S```
+M`LP```V```/Q%9@``14L``@F[``!F8``,Q4P``R6```#S````H```_$$%``$
+MS4```B<P``$H*``!!#@`!`0\``'$%P`#Q!L``\0?``/$(P`#?5U`#7VAP`U]
+M74`*%A``'Q6<`!]]'0`)?1=`"7Z2@`D+N``$"_P``9M``!*;P/_QQ"``),8/
+M`_W&$P/ZFH``"<P```V;``&.410`('S4P!H$%``$T,```LU```*```)+S```
+M#9;``8;,```.@``#\<P```V:P``"S```#I>`_8\+N``!Q#\``YN`__V`````
+MS```#I9```/,```"@``#\=H```+$"P`#Q`\``\03``/$%P`#Q!L``\0?``/$
+M)P`#Q"L``Q7\`!\6L``??_/`"13P`!]_\\`)%7``'W_SP`E]B(`"?<S``I?`
+M``Q^40`"?I5``GR0@`Q\U,`,?(]`"9K```(LM``!S```#9M``5S,```.@``#
+M\<0@`"3&#P/]QA,#^E$4`"!\U,`:T,```H```GI\0,`!%-``'C$4``&5`/UD
+ME4`!2QC4`#`8T`'H&/P`-"3,``\$Z`*L?$&``7Q!P`&4P``2AH```(```K:`
+M``/U@``#]8```_6```*S@``#]5'<`"!]G@`:@``"PU'<`"!]G8`:F4```\6B
+M``"```+#R:(``(```L/%H0``E4``!068``'%I0``4F0`('XF`!H%*`+'?$&`
+M`7Q!P`&5```'AH```(```_6```/U@``#]8```_6```+7V```(<X9``"50``$
+M!9@``58@`"#.&0``E\#]+<0Y(4!\0(`!B````%'<`"!]G8`:V```(<X:``"5
+M0``$!9@`!%8@`"#.&@``F\#_&GQ`@`&(````?$#``7Q!``$9%``[E4``&\04
+M`!(]6``"F8#__AD<`'T9(`!TQ!0`)3'<``$R(``!S```(<P``",I$(``E<``
+M`GS4P`%\0D`!E@```GY60`',P2&%S0$AAA44`!_.02&'S$$AB,Q!(8F50/T$
+MQ!0`$IE`__^`````S(```,S```#-````U$```'Q`@`&(````Q"@`)-AH`_?,
+M@```S$```,0D`'Z60`#JQH\#]YC`__U\0(`!B````,0H`"3$,``/Q#0`!)J`
+M``6;```$S```$L]```#,````?$#``=AH`_?,@```S,```-1````4T``?F0``
+MTX```PK,@```S$```,Q```#,0```?$#``<S``!;,P```U$```'Q`@`&(````
+M?$#``13<`!T8V``\S(```,S```"9P``#F8#\T(```_'-@``D@``#\7Q`P`%0
+M4``@C``#67S0P!K$)``5Q!0`)'Q#@`&60``(Q-8``)E``!G?@P``SZ0`#XP`
+M`UW40`!_@````,5?`^Z5P/__V%0#\<5;`_25@``#V!0#\9F`__S%7P/N/>``
+M`IH```?%8P/KF@``!=^#``#/I``/C``#7=1``'\)W``!S=0#[M@4`_&,``-=
+M?$"``8@```#8```>Q#P`'IO``)J0````V$``'L0\`!Z7P`"6D````(P``UG$
+M(``5?$#``<`V_P#$$``6P#`__WSU0`E]48`)?8&`'7SS@`F9@``&WX,``,^@
+M``^,``-=U$``?X````",``-=?$"``8@```!\0,`!%-P`")G```7,@```S,``
+M`-1```"`````?$$``5!4`"!\08`!?$'``7Q"``$Z,``#$B```IL```($(``(
+M!"0``8```X=^`D`!"F0``<P``'^:0/_^).P`$)K```/%,0``@``#D'T5`!K%
+M,@``)/0`!P=X`Y1_'P`)AX```(````"```.<@``#GX```Z*```.E@``#J(``
+M`ZN`````?QN`#Y>`_&.```.M?QN`#I>`_&"```.M?QN`#)N`_%V```.M?QN`
+M#9N`_%J```.M?QN`#YN`_%>```.M?QN`#IN`_%1^`D`!@``#A\0<``3-P```
+MS````,R```#40```?$"``8@```!\0,`!)-``!C$0``;$%``/F0``",P``!+$
+M)`!^ED``.)E```3$'``$S<```,P```#,@```S,```-1```!\0(`!B````'Q`
+MP`%\00`!%1@`'\T``"%1%``@F8```]1-``"`````?4U`&AD<`#'45@``E<#\
+M+L0@`!.:`/__?$"``8@```!\0,`!?$$``134`!XQ6``")-P`_Y5```29@/PC
+MS1P#`(````#,@```S,```,T```!\0(`!B````,0@`"1\0,`!Q-,#`,R```#,
+MP```S```(<TA(4%\0(`!B````-1``']\0(`!B````,0D`'Z60``#?$"``8@`
+M``"```/U````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P.O``4!J0`&`38`!P$]``@!2P`)`5(`$`/N`!$`"P`2`"<`$P`K`!8`
+M+@`D`#<`)0"L`"8!8P`7`<L`(@,T`",#80`G`7T`'P']`"`"+0`H`9P`*@&,
+M`"P`70`O`98`,0/N`#(!PP`S`^X`-`.V`#4!:@`X`-8`-P'9`#P#=``_`:L`
+M0`*?`$$"X@!"`P8`0P,0`$0#(`!*`RH`50.R`%\!*0!@`04`80$@`&D!.0!S
+M`4``=@%.`'<!50![`\<`?0/7`'X#Y0!_`^X````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_rlc.bin.uu
new file mode 100644
index 0000000..a51aedd
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/HAINAN_rlc.bin.uu
@@ -0,0 +1,186 @@
+begin 644 HAINAN_rlc.bin
+MQ`@`)S",``*8P`+O,(P``9C``9`PC``#F,`"[(````@$&``!S8``#LV``"V,
+M``#^S````LP```O,```CP#`PXB@L``/.\0``P`@Q`,2)```DC``$F,``!L`^
+M`-`K_`#_P#O__\`W__^,``$U)(P`")C```;`/@"P*_P`_\`[___`-___C``!
+M-22,`!"8P``&P#X`<"O\`/_`.___P#?__XP``37,`P`(S`,`!LP#`"W,`P`N
+MQ`P`UR3@``'.`P`)).0``C)D``+.0P`*SD,`!\P#``#,`P`BS`,`(\P#`!W,
+M`P`DS`,`',P#``O`#``?S,,``L`<(F^,``%<SH,`(GZ"P`K`'")PC``!7,Z#
+M`"-^KH`*SH,``<`,,0S$S0``S,,`!<0/``+`$#$#S-$``,S#``_,`P`-P!``
+M`,P3`!#,$P`4S!,`&`40``$Q#``$E,#_^\0-,0/$#``ZS```+<0(``.8@/__
+MS8``$,V``!',```2S```#L0(`#;$"``OQ"@``9:```;-@``.*`@``<0,`"',
+M@``!@```@<0(`!"4@`"HQ`@`$92``*;$*```EH``#<V```XH"``!Q`P`(,R`
+M```RB`&[E(```\P#``"```"),H@!O)2```O,`P``@```L,0G``"60``#S`,`
+M`(```(G$*P`.EH#_WXP``4J```!=)J@`_Q3D``029``()-P`#WY<P`K,P``C
+MSH``#(```%W,```MS8``#LP#``#`,#!)QPD``,`R`!!\L<`)E<#_S<`P,0''
+M"0``))P``97``!L4K``()NP`_\`D``'`(```C``!=)8```/-@P``@```78P`
+M`,V7@``#Q`P`$)3```/-@P``@```7<0,`!R4P``#S8,``(```+#`,#$!QPD`
+M`"2<``*5P``%C```Z98```/-@P``@```L(```%W-@``.S8``+<0(`!*4@``"
+MC```N\0(`!"8@``"C```_L0G``":0`!;@```7<0K``*,``&(P`Z``'^/@`K`
+M#@``?T]`"B@\`*`3_``0*_P`_XP``37`'#$%Q>T``!+L`!@F[`#_P"0``(P`
+M`6?,```2D````"@,``&,``$<*#@``8P``2DH.```C``!)9>```[`.#$!Q[D`
+M`!>X`!`GK`?_EL```\`D``",``%GS8```L00``.5`/__S```$,`X``&0````
+MQ`P`$93```4H.```C``!*2@,``",``$<P#@``)````#$"``/E(#__\0K``*,
+M``&(P`Z``'^/@`K`#@``?T]`"B@\`)`3_``0*_P`_XP``37`'#$%Q>T``!+L
+M`!@F[`#_P"0``<`@``",``%GS8``$I````#$"``3E(#__\P```+$"``/Q!``
+M`YD`___`+#$>QNT``,`D``",``%G*#@``(P``2DH.``!C``!)2@,``",``$<
+MS8``$)````#$"``<E(#_3,V#``"```"P*#@``(P``2DH.``!C``!)2@,``",
+M``$<S```+8```%W`,`.0QSD``,`+__Y_BX`)$,P`$'^/@`K/L0``QSD``)``
+M``#`,"`#S[$``,<Y``"0````P#`P>,^Q``"0````EX``!,`0,1G%'0``F<#_
+M_I=```3`$#$:Q1T``)G`__Z0````C``!+,`4,17/E0``P!0Q%L]5``#`%#$8
+MSQ4``,`0,1W%$0``)1```9D```3`%#$7S]4``)`````GT`#_,1``_YD```3`
+M%#$7S]4``)````"0````S8``#L03`![`#"35C``!4,P#``Z0````)10`_\`*
+MB`!\C(`*S4D``)````#`$```P`J(`'R,@`K$E0``)50`'WT5``J0````P`P`
+M'\`*B`!]R0`*Q14``!54`!!]04`>?4Z`"7Z"@![$%P`"?I:`"9````"6P``,
+M*NP``<[``#"60``%Q"``')8```/,```PD````,0<`#.5P/_ZS```,,`@``"0
+M````EL``$W[!``K`'##0S9T``,`<,,[%U0``%2P`!);```2,``%GE@```I``
+M``#`'##0S9T``,`<,,[%W0``?=7``GW1P`^5P/_V?0+`"I`````FN``?%IP`
+M""7<`!\1W``%?Y^`"A:<`!`E]``?%=P`""7<`!\1W``%?U]`"I````",``&H
+MS```#L0(`#?$"``SE(```\V```Z,``)5Q`@`*I2```/-@``.C``!],0(`"N4
+M@``"S8``#L0(`"B4@/_RS8``#HP``F:,``+I@``!E<`8``',`P`.P`W__\S#
+M`![,PP!AP`@%`"@,``#,CP!!P`H@("B(#P4$S``!S(\`0<`*,#`HB!X/!,P`
+M`<R/`$'`"D!`*(@H'@3,``',CP!!P`I`0"B(,B@$S``!S(\`0<`*8&`HB#PR
+M!,P``<R/`$'`"G!P*(A0/`3,``',CP!!P`J`@"B(6E`$S``!S(\`0<`*@(`H
+MB%]:!,P``<R/`$'`"H"`*(AD7P3,``',CP!!P`J`@"B(:60$S``!S(\`0<`*
+M@(`HB&YI!,P``<R/`$'`"H"`*(AS;@3,``',CP!!P`K`P"B(>',$S``!S(\`
+M0<`*P,`HB'UX!,P``<R/`$'`"O__*(B`?03,``',CP!!P`@`@,R#`%[`"`/_
+MS(``,,P#`%7,`P!=S`,`7Y````#,`P!5S`,`7\`(,,;$B0``P`PPQ<3-``!\
+MR(`"C``"2,U#`&"0````*`P``,`0``4DE``!"1```7S4P`$4B``!F0#__)``
+M``#`&"35Q9D``"@<```H$```P"``!95```PDR``!E(``!7R0@`1]B8`*"50`
+M`07<``$*(``!%,P``040``&:`/_V)9@`'Y````#`&"35Q9D``'T!`!Y]D,`)
+M*!P``"@D``#`(``%E4``#"3(``&4@``%?*2`!'V)@`L)5``!!=P``0H@``$4
+MS``!!F0``9H`__8EF``?D````,0?`&`)W``'*"``$)H```,H%`!`@``"1\37
+M```$S``!"B```2@8`/]]E8`)?9&`$'V=@`1\F8`/E8#_]2@8_P!]E8`)%9@`
+M"'V1@!!]G8`$?)F`#IF`_^X55``0ED```A54``@H&`#_?95`"9`````H%``?
+M?)3`!23,``&8P``#"50``9E`__R0````P`@DU\`.B`!\C,`*Q-4``"54`/^0
+M````P`@Q"<2-```DT``!F0``#230`/[$%P!?!50``<U#`%]]44`/E4``!XP`
+M`GW$"P!5?0B`#LR#`%W-`P!5S`,`7Y````",``*4C``"AL`(`!1\L(`0P`P`
+M07PM``K`)```C``"+,U#`%;`"``%?+2`$,`,`$%\+0`*P"0``8P``BS-0P!7
+MQ`L`5GR4P`^8P``"?!2`"HP``JW`&``!D````,`*G``HB"34P`P``<S)``#`
+M"HP`*(@DUL2-```DT/__D````,`*G``HC".8P!``!\T-``#`"HP`*(PCF<3Q
+M```HC".:Q/4``"B,(YO$^0``*(PCG,3]``"0````P!Z(`(P``IQ\%(`*?!:`
+M"HP``?Y\#L`*SH,`6I````",``*E*<PDU<3-``!]34`)D````,`>B`",``*E
+M?!<`"I`````IR")OQ(D``"G,(G#$S0``?(U`"GU!0!X55``0D````#",`$"8
+MP``G.(P`0)3```X(B`!`?*W`$!7<``:,``*A?H*`'GZR@`F,``+6)HP`_W\!
+M0`J,``(&?!I`"LY#`&&```+5P`PQ"<3-```DT``!F0``!\0/`%W$$P!>Q!<`
+M57U1``Y\T0`*F0``#L`<`$!]R(`"?*W`$!7<``9]PL`*C``"UL`L,0O&[0``
+M)M``_W\!0`J,``(8?!J`"LZ#`&&0````P#```":(`/^,``'^?,&`"I;```J,
+M``+EE4``"#%(``&4@``$!S```0F8``&```+B"NP``8```MJ0````?8#`"L`4
+M``!]@4`-D````,0+`![$#P!A?(T`#)D```3,PP`>P!@``<V#``Z0````@``"
+M\8```O(`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+"````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_me.bin.uu
new file mode 100644
index 0000000..1581361
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 JUNIPER_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*!`RA_<`2``',``!%S```2GS0
+MP`?,02)<S$&A_-1-``!\0(``H````,R``$V`````S$$B7<P``$7,``!*"$P`
+M`7Q!``!\04``'5C__QE<`_`58``5S8&A`LW!(E;.`2)<E,``!2$D`"#.0:'\
+M@```?0C,``'-`:'\S`&A`GQ`@`"@````S(``37Q`@`!\0,``P"H``GQ!``!]
+M*0`'')0``1R8``8<G`,`%=P`"'Q"``!\0D``E4``#\`N``0%\")8?R\`!\PQ
+M``#(*``$S,$A:<T!(6K.@2%K*;0``LP!(6R70``.*;0``(```+W(-``.*;0`
+M`I=```DIM```P"X`!`7P(EA_+P`'S#$``,@H``2```"]R#0`#I=```1^`H``
+M@```O<@T``XIM``$ET#_20````#.`2%MSD$A;L@H``/(-``.FT``!,@\``Z$
+M``-.S```32GT``"70``'!#"BMH0``-_.@:*WSX&BQ(````#/P:+1*?0``9=`
+M``<$,**ZA```W\Z!HKO/@:+%@````,_!HM(I]``"ET``!P0PHKZ$``#?SH&B
+MO\^!HL:`````S\&BTP0PHL*$``#?SH&BP\^!HL>`````S\&BU,`N``1_+P`'
+MS#$``,@L``3`,``&?O-`(\`P`"!_:X`@B````'^SP"3,``!"@````,Q``!]\
+M0,``?$$``!D4`#V90``3!!0`+H0`!-H$&``IA``"6L@<`!,$%``JA``$V@08
+M`"W-0:*DR!P`$Y7```#('``3S,$A`,T!(0',P2$"S0$A`X``!-?-@:*D'1@0
+M`)6```7('``3*>0`0)9`___('``3S,$A=<T!(7;((``4E@```,@@`!06*``!
+MFH``!,P``$^```37S```?X```0G,P2%U?$#``'Q!``#,``!%S```2D#4``/-
+M02)<S0&A_,`:``$$'*']?=G`!WQ"```(S``!!B0``08H``+.'0``SET``)C`
+M__K.G0``?$"``*````#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A
+M;<V!(6Z```$WR!P``\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````
+MS>4``,Y!(6G.@2%JS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8
+MI!_H*F@`/):```I\`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4WP"
+M0`!^`D``FD````ID``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D`
+M`,[``!Z```%CR#``!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%H
+MGX````````"```%X?QN`#H```7Q_&X`/@``!@'\;@`R```&$?QN`#8```8A_
+M&X`1@``!C'\;@!"```&1%*0`")N``!D4I``(@``!H1YD`/^;@``5%*0`"(``
+M`:$>9`#_FX``$12D``B```&A'F0`_YN```T4I``(@``!H1YD`/^;@``)%*0`
+M"(```:$>9`#_FX``!12D``B```&A'F0`_Q2D``@>9`#_*F@`/)J`_FT4[``(
+M?$-``'Q#@`!\0\``EL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/
+M]0``S```680`!-HJ:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"C,`.
+M``+,``!!@``!K\S!,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``
+M!<`F``3`)__[?24`!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,
+MS0$A:LU!(6N6P/X\S8$A;(0`!-K,``!_R#``&I<```#(,``:@````7Q`@`"$
+M``3:S```?\@4`!7(&``6S4$A:Y;`_B[-@2%L@``!QLP``'_,``/ER"P`(,`.
+M("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(#``)?$$`
+M`'Q!0`#,0`!#S$``1,`.@`!\0D``?$*``!:L`!^6P/X5P#7P`,Y``^$>>``#
+M$GP`"'_WP`9_^\`'%G@`&,_``^+/@`/C$K```G\_``#/``/D@``$8WR`P`!\
+M0,``&-`!Z!$H``&5```0!J@!_YZ`````````@``"%\`2"`"```(ER!0`$8``
+M`BS(%``2@``",\S!HJ2```(\'.@`/X```F1\P8`+'-``/RDH``8I+``6?JZ`
+M!\@<`!.:@``]!!0`+H````#,P:*DP!((`'Q!0`!]#,`'P!(`"!58``,57``,
+M?$(``'W1P`82(``4?AY`!WY.@`?.@:*D@````,V!H?[(%``1!!`A&)5```#(
+M%``1U%$``(````#,P:*DR!0`$@00(0:50```R!0`$M11``"`````S,&BI,S!
+MHJ0$$``!S0``&80`!-K,``!_R!``&YD```#($``;@````7Q`@``JH``$*J0`
+M%'XF``<$%``NE@``"`08`"F$``):R!P`$P04`"J$``3:!`P`+<U!HJ0$$"$`
+MR!P`$Y7```#('``3U%$``(``!-?,P:*DA``$V@08`"F$``):R!P`$P04`"J$
+M``3:!!@`+80``EK('``3@````7Q`@`"5P```R!P`$\U!HJ3,`2$`S`$A`<V!
+M(0+-@2$#S8&BI(@```#,``!-'9@``7Q!``!\04``F8``"7Q"``#(/``R$9@`
+M$,@<``L[_``!E\#__\@\`#*```)VR#P`,Q&8`!#('``*._P``9?`___(/``S
+M%6@`'7U90`>:@``$$>0`"GXF``?-P`!FS0$A6,U!(5G.`2%:S,&BI)J``E<%
+M$``$!"P``1+P`!U]<4`'$N``$"(@``S-`2%8S4$A6<X!(5J```37S,&BI`0\
+M``7/P:*DP#8``H@```#/02`0?$#``!30`!V9```(%-0`')5`_6O`)@`$(F0A
+M5,PE``"`````R"@`!(``!-?-0`!AA``$VGQ!0``==``!''@``IM```/(#``I
+MA``#3154`!";@``#!!``$(0``W',P:)0S0&@4(0``OX$&`0`A``$VLP``&/(
+M/``MA``##,@0`"G('``O'=P``<@D`">5P``,R#0`,<@X`##(/``M%_P`$!/\
+M`!!_U\`'4W0`('^W@"='N`50S```8L_Z``":0```R"0`)\`P``'(*``DFH``
+M`,@H`"3/``!;4-@`"!3<`!@AW(``S8$A@,W!(8%1(``(%20`&,X!(8+.02&#
+MS4$AA'Q`@`"@````S(``380`!-I\04``'70``1QX``*;0``#R`P`*H0``TT5
+M5``0FX```P00`!"$``-QS,&B8,T!H&"$``+^!!@)@(0`!-K,``!DR#P`+H0`
+M`PS($``JR!P`+QW<``'()``HE<``#,@T`#'(.``PR#P`+A?\`!`3_``0?]?`
+M!U-T`"!_MX`G1[@%5,P``&+/^@``FD```,@D`"C(*``EFH```,@H`"6```+&
+MP#```@68P``0W``(%.``&,W9``#('``BR"0`(AW<#__-V0`!?F)`!\Y9``+8
+M&%$#V!A1!(@```#8&%$'&_@`\,`V"`"7@``#P#``@(@```#`*@`$ST$A?,\!
+M(7W-`2%^(J@A?P0D``B:0```"F0``<PI``#((``$%C@`'YN`__L$)``(B```
+M``````#(#``DE,``)#C4``&90/_]R!``(WT-``&9`/_[R`P`)(```S'(#``E
+ME,``&SC4``&90/_]R!``(WT-``&9`/_[R`P`)80`!-K,``!_R#P#^YO```#(
+M/`/[T$`#_,`^``32`2'X(_PA^80`!-K,/0``R#@`!!NT`#X?L``$?P+`"Q[H
+M``1^MD`'FD#_]L`^``30``/\?$$``(````%\0(``A``#37Q`P`!\0(``H```
+M`,R``$W(/``.E\```],``^:(````!#P`)L_!HJ3(/`/F"_P``<_``^:;P/_[
+MS```3<@\`^67P``,R#P`$Y?```#(/``3!#PA`,P]``#,/0``S#T``,P]```$
+M/``IS\&BI,R``$T$/``%S\&BI,P!H?2$``3:S```1X@```#,``!_A``#<7Q`
+MP`!\0(``H````,R``$T$/``BS\&BI(0`!-K,``!(B````,P``'^$``-\?$#`
+M`'Q`@`"@````S(``3<@\`^67P``,R#P`$Y?```#(/``3!#PA`,P]``#,/0``
+MS#T``,P]```$/``IS\&BI,R``$T$/``CS\&BI,P!H?.$``3:S```28@```#,
+M``!_@````'Q`P`"`````?$#``,`2``%\44`'@````-15``"$``3:S$``9<@<
+M`"7()``D?>7`!YG`__[('``E@````7Q`@`!\0,``?$$``'Q!0`!\08``%1P`
+M'\S``,?-``#(E<```\`<@`#-P2`0X8,```5<(`#,``!-@````-P?00!\0,``
+M?$$``'Q!0`!\08``S,``R<T``,KA@P``!5R@`(````#<'T$`?$#``'Q!``!\
+M04``?$&``,S``,O-``#,X8,```5<Z4"`````W!]!`'Q`P`!\00``?$%``'Q!
+M@`#,P`#-S0``SN&#```%7.B`@````-P?00!\0,``?$$``'Q!0`!\08``S,``
+MS\T``-#A@P``!5S``(````#<'T$`?$#``'Q!``!\04``?$&``,S``-'-``#2
+MX8,```5<\`"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#3S0``U.&#```%
+M7//\@````-P?00#40R``?$"``*````#,@`!-U$.@`'Q`@`"@````S(``3=1#
+MZ4!\0(``H````,R``$W40^B`?$"``*````#,@`!-U$/``'Q`@`"@````S(``
+M3=1#\`!\0(``H````,R``$W40_/\?$"``*````#,@`!-!!R@`,Q#H`!\0,``
+MV!_!`'Q`@`"@````S(``300<P`#,0\``?$#``-@?P0!\0(``H````,R``$U\
+M0,``R!,``I3```/(%P`"R!L``@0<\_S,`_/\V!_!`-@?P0!\0(``H````,R`
+M`$W(*``FR"P`*"JP`/\J]`#_?W.`!YN`__O`'@`0R`P`*5#0``@05``"@``$
+M.GT5@"#(*``FR"P`)RJP`/\J]`#_?W.`!YN`__O`'@`@R`P`*E#0``@(5`0`
+M$50``GU1@"#-P`!BU%H``'Q`@`"@````S(``37Q`P``<T``#$2@``94```H&
+MJ`1$GH```'Q!@`"```12?$'``(``!%A\0<``@``$7GQ!P`!\08``?$'``!34
+M`!`%5*``@````,V5``#`(@`$!9B@`'VA@`?,&0``@``$3L@8``3`(@`$S8$E
+MUB(@)=?,(0``@``$3L@8``3-@2%MS<$A;H``!$[(&``#?$#``,@0`^'(%`/D
+MR!@#XL@<`^/-@2%IS<$A:LS!(6O,`2%L!"``!'VA@`!]ED`,ED#[DLV``^(=
+M*``#P"WP`!$8``A]K8`&?:F`!X````#-@`/B?$#``(````#,3`/@'(S__]1-
+M``!\0(``H````,R``$W(%``C,5@`!)6`___(%``CS```6\Q!(8`@3(``S,$A
+M@130`!_,02&"S$$A@Y4`^W;,02&$R!0`(YE`___(%``C@````7Q`@`#`%@`$
+M(50A0,Q5``#(&``$@````,P``^#`*@`$?$#``,S!(7S,02%]S$$A?GQ!@``4
+M_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`F<````G<``',(0``R"0`!!9L
+M`!]!G``%FL#_^LR``$V;P/M4`````(````#,``/@?$#``'Q!```5&``?410`
+M()F``!(9'``QR"@`)\@L`"@JL`#_*O0`_W]S@`>;@/_\R"@`)\T``&)]34`G
+MU%8``)7`^T#((``FF@```,@@`":````!?$"``.`Z``#`)@`$S,$A:7TE``?-
+M`2%J"[@``LQ!(6N;@/_^S$$A;)G`_/?,``!_@````7Q`@`#`#@$`S```0<S!
+M,$K(/`!_S```?X````#,``!_S```?X@```#,``!_````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01Z`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=P`P`'D`,@#J`#0`C@`U`&(`.0#L`#H!%``[`2D`/`%!
+M`#T!L0`_`.D`001_`$($D0!#!)<`1`'6`$4!00!&`?H`1P'Z`$@!^@!*`I$`
+M2P.0`$P"G0!-`M0`3@,@`$\#*0!1`W<`4@-(`%,#;`!4`Y(`5P.4`&`#H0!A
+M`[``8@.8`&,#N@!D`\0`90/.`&8#V`!G`^(`:`/L`&D#\`!J!"(`:P/T`&P#
+M^`!M`_P`;@0``&\$!`!P`_P`<00N`'($%@!S!`@`=`0/`'4$/P!Z!+``?`1B
+M`'T$=P`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`
+M#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/!-,`#P33``\$TP`/
+.!-,`#P33``\$TP`/!-,`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_pfp.bin.uu
new file mode 100644
index 0000000..fa1f6bc
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 JUNIPER_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```.MS$``*ID```4`````S$``*X```ZW,0``LS$``+8``
+M`ZW,0``N'(P``LR``$"8P``$S$``0(```ZW,``!2@``#K<P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$/-
+M0`!#R!P`'=$``$.9P``%S```5<@@`!_8``/`S```0,@H`!;8``;`&J@`)Y:`
+M``/,``!`T(``7,R``$#,``!`S$``0'Q`@`"@````!"@``<@0`"S(#``K41``
+M('S0P"=\Q0`@11@`",F>``#()`/]?>:`$9:```-^7L`!?`+`!L[#HIY5%``@
+MS```;,T``&W-0`!MS0``0\U``$/('``=T4``0YG```7,``!5R"``']@``\#,
+M``!`R"@`%M@`!L`:J``GEH```\R``$#0@`!<S(``0,P``$#,0`!`R#4AHQMX
+M!_`KM``(ET#__<@X`_R;@```R#@#_(0``[#00`/[R#@#_)N`__L$/``;S```
+M6X0``[#/P2'XR#DA^1NT`'B;0/_\S```6]```_M\0(``H`````0H``'(&``5
+M'9@``7Q"0`"5@`,B?$*``,@<`"#`-\``?$#``'Q!``!\M(`&P#8``YG```#(
+M'``@?+2`!Q#4``)]94``S4``0\Z``$/-``!#S(``0,Y``$#.@`!`S,``0.`Z
+M``"7@/]BS0``0'Q`P`"```"4?$$``!R,``+($``<F,``"<@@`!^9```$R!P`
+M!H0``[/,``!2R!@`%8```(@=F``"R!``'ID`__S('``(A``#L\P``%3(&``5
+M@```B!V8``(<C``"R!``'9C```_(%`!)F0``!<@@`!_('``'A``#L\P``%/(
+M&``5E,```QB4`>@%5``&(!```7T5``.```"(?9&`!IE`__C((``?A``#L\@<
+M``>```"_S```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/TS0`#
+M]LT``_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``<@@`!^```#D
+MV``$0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!R"``']@``\"`
+M``#TS```0,@@`!^```#SV``$0,@@`!_8``-`S```0,@,`"G($``JS(``0,Q`
+M`$!1$``@?-#`)Q!0``)]#0`@510`(,T``$/-0`!#T$``0\P``$!\0(``H```
+M``0H``'((``?V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=
+MF,``$L@4`$F9```%R"``'\@<``>$``.SS```4\@,`"_,@`!`S$``0,Q``$#,
+M0`!`?,3``,S``$#40`!`?$"``*`````$*``!F4#_]<@@`!^$``.SR!P`!X``
+M`17,``!N?$#``,@0`$<<W`/_&)3_\)D```]]74``R!@`1)F```3(&``)S8``
+M0,P``$"```%=R!@#\'Q`P`#($`!''-P#_QB4__"5`/_U?5U``,@8`$69@``$
+MR!@`"LV``$#,``!`R!@#]1V<``,5F``"R:0#]A'<``-^7H`$'J@`_P54``<5
+M5``#?6K`$);```@$+`#_?M[``W["P`M^;D`&?5U``WY60`?.6`/VV``(0,S`
+M`$#40`!`?$"``*`````$*``!?$#``,@0`$<<W`/_&)3_\)D`_^1]74``R!@#
+M\!V<``,5F``"R:0#\1'<``-^7H`$'J@`_P54``<55``#?6K`$);```@$+`#_
+M?M[``W["P`M^;D`&?5U``WY60`?.6`/QS(``0,S``$#40`!`?$"``*`````$
+M*``!R!``1L@8`_`%F``!'9@`#\V``_`=G``#&9@`8LFD`_$1W``#!"P`_W[>
+MP`-^PL`+?FY`!LY8`_$$&```!!P``(0``<')Y`/QA``!P<GD`_&$``'!R>0#
+M\80``<')Y`/Q?2$`!]@`!T#-``!`A``!MLT``$#(#`!#E,``(L@4`$B```&7
+M!!```\@0`$;(&`/U!9@``1V8``_-@`/U'9P``QF8`&+)I`/V$=P``P0L`/]^
+MWL`#?L+`"WYN0`;.6`/V!!@```0<``"$``'!R>0#]H0``<')Y`/VA``!P<GD
+M`_:$``'!R>0#]GTA``?8``?`S0``0(0``;;-``!`R!0`2)U```#,``!JR"@`
+M%AZH``&:@``#P"D``8@```#`+`%6SH``7-@`",#.P`!`B````,P``$`>:`#_
+M?IO`$)?```,:;!_H?H&``'[;P!"7P``#&G`?\'[!@`!_&\`0E\```QIT'_A_
+M`8``?UO`$)?```,%W``!?T&``!&@``6(````$B``$!R,``+($``>R"``'Y3`
+M``C(%``<F0``"L@<``B$``.SS```5(```>7,@`!`F4``!,@<``:$``.SS```
+M4LR``$"`````U$``0,Q``"?,0``H@``#K<P``&O`,@`#P#?__X```?!\L(`'
+M?$-``,@@`"C('``GR!@`)L]#HIY\04``4B``('WAP"=]6,`#?-S`(%30`""`
+M``(%S(``0'Q!@`#,@`!`@``"`LV``$#`&?__S(``0,V#HIY\0,``?$$``'Q!
+M0`#,PZ'ZS0.A^<U#HIW,P`!`S0``0,U``$#,0`!`?$"``*`````$*``!?$#`
+M`!S0``',PZ*?E0```]!``";0@``FS(``0(````#,P`!`?$#``,R``$#,PZ*B
+M@````,S``$!\0,``%-0`'\R``$"50``#?$$``,S``%D5&``?S,``0)6```/-
+M``!`S0``6H```ZW,``!_R"``'WQ!``#8(`)$SB``1'Q!0`!\08``S:``2<T@
+M`$'-8`!!S:``0140``@15``8?5/`!\_``"\&(``!S@``6(```ZW,``!_R"``
+M'\H,`!>4P``%?$$``-@@`L:```(OSB``1LP``$B```)%`````,@@`!]\08``
+M"B```<H4`!K*&``7?5F`!Y6```7.``!8S*``1H````#-8`!&S*``1(````#-
+M8`!$@``#K<Q``&K,@`!`@````-1``$!\0,``?$$``,S``_[-``/_S,``0LT`
+M`$(5%``?&1@`\"=<``%]=@`&F8``!7U>0`;,``!"@``#K<P``$T5F``!%2P`
+M")F``$T>[``!E@``!!4P``R```.MS```0@04`"#-0`!"'S```2`H``&$``*L
+MR!0``YM``"L$.``<A``"K,@4``.;0``G!#@`&(0``JS(%``#FT``(P0X`!2$
+M``*LR!0``YM``!\$.``0A``"K,@4``.;0``;!#@`#(0``JS(%``#FT``%P0X
+M``B$``*LR!0``YM``!,$.``$A``"K,@4``.;0``5R`P#_IJ```G($`/_FP`!
+M%LP``$T$%``@S,``0LT``$*```)TS4``0I;``0_,``!-@``#K<P``$Z:P``#
+MS```3<P``$[C@P``@````-P#`?^:P`$%S```38```ZW,``!.R!@``\@<``/(
+M(``#?5U`#7VAP`U]74`'%A``'Q6<`!]]'0`&?1=`!H@```!^DH`&ED``!,P`
+M`$Z```.MS```0M(``$+("``#R`P``\@0``/(%``#R!@``\@<``/()``#R"@`
+M`Q7\`!\6L``??_/`!A3P`!]_\\`&%7``'W_SP`9]B(`!E\``#7W,P`%^40`!
+M?I5``7R0@`Q\U,`,FL```WR/0`8DM``!FT``U\P``$V```.MS```3L@,`_[(
+M$`/_S,``0H```KS-``!"?$#``'Q!```9%``[S```6Y5``!/(%`!`,5@``I6`
+M___(%`!`S```8R$<@`#,P2&%S<$AAA44`!_,02&'S$$AB)5`_1',02&)R!0`
+M0)E`___(%`!`@````7Q`@`#,@`!`S,``0,T``$"`````U$``0-"``^#,@`!`
+MA``#L,Q``$#(#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``##A30`!^9
+M`/SXT$`#X(0``[#,``!_@``#`,@,`^#,@`!`S,``0(@```#40`!`S(``0,Q`
+M`$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#,``/PS``#\<P``_+,``/SS``#
+M],P``_7,``/VS``#]\P``_C,``/YP#?__]```_O0``/\@````,]``_U\0,``
+M%-P`'9G```?,@`!`&-P`/)G``'_,P`!`@``#K<P``&H8V``\S8``9LP``&J`
+M``.MS,``0'Q`P`!04``@A``#L,P``%U\T,`GR"``'\C6``"90``(?$.``..#
+M``#/H`!/A``#L,P``%Z`````U$``?X```ZW,``!>A``#L,P``%W((``??$#`
+M`,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\\X`&XX,``,^@`$^$``.P
+MS```7H````#40`!_@``#K<P``%Z$``.P?$#``!3<``B5P``9'-P`$'Q!``"9
+MP``$4%0`((```VC)'0``?14`)\D>``!\0@``?$)``'Q!@`!]Y<`&?>*`$9J`
+M_)-!K``%FL````KL``$<W``0F<``!`````"```-KR1T``(```VO)'@``S(``
+M0,S``$"`````U$``0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!
+MR"``']@``\#,``!`S(``0-1``$!\0(``H`````0H``%\0,``'-``!BD0``:9
+M```'R!0`')E```7,``!2R!P`!H0``[/((``?S(``0,S``$"`````U$``0'Q`
+MP`!\00``%1@`'\T``%N9@``$410`((````#430``?4U`)QD<`#'45@``E<#\
+M6\@@`$&:````R"``08````%\0(``@````-1``'_,``!_@````,P``'_,``!_
+MB````,P``'_-P`!`B````,P``$``````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P-\``0#A``%`BL`!@#B``<`\0`(`00`"0#J``H`WP`+`.X`#`$F
+M``T!,P`.`70`#P&6`!`#JP`1``H`$@`8`!,`(``6`"(`)``Q`"4`3``F`><`
+M%P)'`!@"50`B`S<`(P-(`"<!_``@`EH`*`(>`"D!ZP`J`A``*P(``"\"&0`R
+M`CT`-`.,`#4![P`Y`E<`/`-<`#X#JP`_`BL`00+?`$("^P!#`P4`1`,2`$H#
+M*0!5`W\`5@.'`&``A@!A`*,`8@#-`&,`M@!D`+8`90"V`&8`M@!G`+8`:`#:
+M`&D`Y0!J`58`:P$'`&P!!P!M`0<`;@$'`&\!!P!P`0P`<P#T`'0`]`!U`=4`
+M>P.:````!0````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_rlc.bin.uu
new file mode 100644
index 0000000..7aef7d3
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/JUNIPER_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 JUNIPER_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X```/P`
+M````P#`@`\^Q``"(````RSD``,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`
+M````````A```?`````"```#%`````,GX`(.;@``$`````(```,4`````S!P`
+M@X0``-@1N``?@```Q0````#(*``#EH``M`````#-@``.*HP!Y9C``"0@"``!
+MS(```X```!@`````(#@``<^```/($`""S```@<@(`!J4@``R`````,V```X`
+M````A```T2`X``+,,0``A```#"`X``'-@`"!A```\R`,``"```#%`````"J(
+M`;R8@/_8`````)4`_](`````R"@``I:``.$@"``!S8``#LR```*````8````
+M`,G,`(.4P`"3`````(0``/,@#``!A```#"`X``"7@`"-(`P`#<`P(`G,\0``
+MP#`@"L`T&!@3=``((W08&,L-``!\],`&R`@`&IB``((@'``!E,#_^P````"`
+M```P?<'`!L@X`%:;@``S(!P``,@X`%>;@``P(!P``2`<``#("`"!E(#_V0``
+M``#(*```EH#_UB`(``'-@``.S(```!P<```JB`&[E(#_RP````"```#3````
+M`!ZH`/_.@``,B`````````#(,`!`(S``0,\``$"$``"F(#@``<@P`$`?,`._
+MSP``0(```&?,``!6A```$`````#`,"`(A```N2`X___`,"`(S#$``,LY``#`
+M,`.8A```N2`X`0#`,`.8S#$``,L)``#`,"&VB````,PQ``"9P/_ER#``0",P
+M``+/``!`A```BB`X``/(,`!`'S`#_<\``$"```!GS```5H0``!``````(#@`
+M`<`P`YB$``"Y$[@`%,P``%?`,`.8S#$``(@```#+"0``S[$``,V```[+.0``
+M%[@`!)>`__X`````B`````````#/L0``RSD``"`(`!^8@```"(@``<P<`!;)
+M\``;EP#__P````"(`````````,P```[,```.R!``@B`H`<,@'```R!``@L@(
+M`(5_BX`'R`@`@92`_V<`````@```9P````"```"QP#`!P<V<`(.$``#8(#@`
+M`)4`__$`````P#`!P(@```#/L0``R"@`!):`_^D`````(`@``<V```[,@``$
+M@```&`````"$``#8$;@`'X0```P@.``!A```\R`,``#`,`'`RSD``"`X``"5
+MP/_9SX```WW!P`:$``#8(#@``(```,7/@``#P#`#D,LY``#`"__^?XN`!A#,
+M`!!_CX`'S[$``(@```#+.0``R`D]-L@-/3>4P/\[`````,@1/3C(%3TYR!T]
+M.L@A/3O()3TU!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8
+MR)8`/)5`_RK(T@`H?24``0E4``$$S``HF0#_^P````#(D@`X!1``0'T*P`#(
+MU@`$P!P`!,CB`!3(Y@`DS@H!3,YN`4P(S``$"(@`!`KL``0)W``!F<#_^```
+M``#-"@%@S`H!9,U!/4>````Y`````,@H``&6@/[[`````"`(``'-@``.S(``
+M`8```!@`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/LICENSE.radeon b/sys/contrib/dev/drm2/radeonkmsfw/LICENSE.radeon
new file mode 100644
index 0000000..0d1894f
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/LICENSE.radeon
@@ -0,0 +1,51 @@
+Copyright (C) 2009-2013 Advanced Micro Devices, Inc. All rights reserved.
+
+REDISTRIBUTION: Permission is hereby granted, free of any license fees,
+to any person obtaining a copy of this microcode (the "Software"), to
+install, reproduce, copy and distribute copies, in binary form only, of
+the Software and to permit persons to whom the Software is provided to
+do the same, provided that the following conditions are met:
+
+No reverse engineering, decompilation, or disassembly of this Software
+is permitted.
+
+Redistributions must reproduce the above copyright notice, this
+permission notice, and the following disclaimers and notices in the
+Software documentation and/or other materials provided with the
+Software.
+
+DISCLAIMER: THE USE OF THE SOFTWARE IS AT YOUR SOLE RISK. THE SOFTWARE
+IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND AND COPYRIGHT
+HOLDER AND ITS LICENSORS EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS AND
+IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+COPYRIGHT HOLDER AND ITS LICENSORS DO NOT WARRANT THAT THE SOFTWARE WILL
+MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF THE SOFTWARE WILL BE
+UNINTERRUPTED OR ERROR-FREE. THE ENTIRE RISK ASSOCIATED WITH THE USE OF
+THE SOFTWARE IS ASSUMED BY YOU. FURTHERMORE, COPYRIGHT HOLDER AND ITS
+LICENSORS DO NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE
+OR THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
+ACCURACY, RELIABILITY, CURRENTNESS, OR OTHERWISE.
+
+DISCLAIMER: UNDER NO CIRCUMSTANCES INCLUDING NEGLIGENCE, SHALL COPYRIGHT
+HOLDER AND ITS LICENSORS OR ITS DIRECTORS, OFFICERS, EMPLOYEES OR AGENTS
+("AUTHORIZED REPRESENTATIVES") BE LIABLE FOR ANY INCIDENTAL, INDIRECT,
+SPECIAL OR CONSEQUENTIAL DAMAGES (INCLUDING DAMAGES FOR LOSS OF BUSINESS
+PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, AND THE
+LIKE) ARISING OUT OF THE USE, MISUSE OR INABILITY TO USE THE SOFTWARE,
+BREACH OR DEFAULT, INCLUDING THOSE ARISING FROM INFRINGEMENT OR ALLEGED
+INFRINGEMENT OF ANY PATENT, TRADEMARK, COPYRIGHT OR OTHER INTELLECTUAL
+PROPERTY RIGHT EVEN IF COPYRIGHT HOLDER AND ITS AUTHORIZED
+REPRESENTATIVES HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN
+NO EVENT SHALL COPYRIGHT HOLDER OR ITS AUTHORIZED REPRESENTATIVES TOTAL
+LIABILITY FOR ALL DAMAGES, LOSSES, AND CAUSES OF ACTION (WHETHER IN
+CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE) EXCEED THE AMOUNT OF
+US$10.
+
+Notice: The Software is subject to United States export laws and
+regulations. You agree to comply with all domestic and international
+export laws and regulations that apply to the Software, including but
+not limited to the Export Administration Regulations administered by the
+U.S. Department of Commerce and International Traffic in Arm Regulations
+administered by the U.S. Department of State. These laws include
+restrictions on destinations, end users and end use.
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/Makefile b/sys/contrib/dev/drm2/radeonkmsfw/Makefile
new file mode 100644
index 0000000..44fbf9e
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+all:
+ rm -f *.uu
+ for file in *.bin; do \
+ uuencode -o $$file.uu $$file $$file; \
+ rm $$file; \
+ done
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/OLAND_ce.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_ce.bin.uu
new file mode 100644
index 0000000..6af378ba
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_ce.bin.uu
@@ -0,0 +1,194 @@
+begin 644 OLAND_ce.bin
+M?$"``8@```#40`!_?$"``8@```#$(``+Q@P`!93``"0D4``/,10``I5```3,
+M0``DS$``)8`````Q%``#E4`!.\Q``";,0``G@````,0@``O,(``%?$$``5!4
+M`"!\08`!!B0``<Y````5G``8?14`&LW@``K-H``,T2```\V@``.:```$Q"0`
+M$II```(AW``P@``!3,0@``O&#``%'*@`$)3```/.H``'@```%<P```G$)`!_
+MQ"``"WQ!@`$*(``!QA0`",88``5]68`*S@```)6```/,(``'@````,P@``6`
+M````?$#``130`!XQ%``"E4`!#AC0`>@8U``P&-@`-`4H`$1\0@`!?$)``94`
+M``>&@```@``!4(```5"```%0@``!4(```%(15``0?A8`"LU``!'480``E8#_
+MLL0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``!'48@``E8#_J<0@``Z:`/__
+M?$"``8@```!\0,`!%-``'C$4``*50`#K&-0`,!C0`>@8_``T),P`#P3H`&A\
+M08`!?$'``93``!*&@```@```<H```5"```%0@``!4(```&^```%04=P`('V>
+M`!J```!_4=P`('V=@!J90``#Q:(``(```'_)H@``@```?\6A``"50``%!9@`
+M`<6E``!29``@?B8`&@4H`(-\08`!?$'``94```>&@```@``!4(```5"```%0
+M@``!4(```)/8```1SAD``)5```0%F``!5B``(,X9``"7P/]QQ#DA0'Q`@`&(
+M````4=P`('V=@!K8```1SAH``)5```0%F``$5B``(,X:``";P/^]?$"``8@`
+M``#8``/VV``#]=@``_38``/SV``#\M@``_'8``/PV``#[]@``^[,0`!_S$``
+M?\Q``']\0,`!S,```=1``'^`````?$#``5!0`"",``#+?-#`&L0@``O$U@``
+M?$.``<0D`!.:```)V&0#],9K`_&:@/__QFL#[@:H``'.I`/NS60#Z]@D`_29
+M0``)WX,``,^@``Z,``#/U$``?YH`_SS&<P/NFP#__X````",``#/?$"``8@`
+M``#8```"Q#P`#9O``(.0````V$```L0\``V7P`!_D````-@``!)\0,`!4%``
+M(,0\`!`G_``!E\#__GS0P!K0P``4S$``%<00`"%\4,`!S,``%M@``!.`````
+MQ!``(7Q0P`',P``7U$``&(````#$$``A?%#``<S``!?$$``@?%#``<S``!F`
+M````Q!``(7Q0P`',P``:S$``&WQ`P`%04``@?-#`&M#``!R`````S$``(=@`
+M`"*`````?$#``5!0`"!]#4`:V$``*<@8`!U]E<`/E<#__M@``"F`````?$#`
+M`<@0`!W(%``>?16`#IF```_80``IR!``'7U1@!)]C<`/F<#__=@``"E0X``!
+M?A9`#II```1]8H`2TH``(X````#0```C@````-B``"G$/`!_S```(-A``"C$
+M#``<F,#__]@``"A\00`!4%0`('T6`!K2```>V$``'8````#,```@V$``*,0,
+M`!R8P/__V```*-```![0```?V$``'7Q!``&`````?$#``7Q!``$5&``?S0``
+M$5$4`""9@``#U$T``(````!]34`:&1P`,=16``#$(``.E<#^R,0@``Z:`/__
+M@````'Q`P`%\08`!%-``'C$0``(DU`#_E0#^O\V4`P"`````Q"``$WQ`P`'$
+MTP,`S```$<TA(4&`````U$``?X````#$)`!^ED```WQ`@`&(````@``!4```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0`"`!`!2@`1``4`&0`M`#$`)0`S`!,`@`#3`($`X0""`.8`@P#M`#<`
+M.0!``%P`1`">`(0`]@"'`/D`B`$"`(D!%P!]`3P`?@%$`'\!+``B`*X`BP$B
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/OLAND_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_mc.bin.uu
new file mode 100644
index 0000000..5964aec
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_mc.bin.uu
@@ -0,0 +1,702 @@
+begin 644 OLAND_mc.bin
+M``/HX``"O@$```('``/_```#_P```J`.``'`&0`#Z````^@0``/H(``#Z#``
+M`V`@``-A2``",A(``TEL``-("@`#KPH``K0$``)O]```^BT``K0/``)/%```
+M^@H``ZB,``#"`0`#0"0``K1```*U#P`#2J8``D1!``/P`@`"294``VJF``-*
+M40`#0"0``K@"``*Y_@`"1)0``DB!``.H@``"9$@``VI1``-`)@`"OX```KP$
+M``))^0`#\$(``_0```'`00`"OX```TA4``*X#P`"N?```D$8``)"*0`#:%0`
+M`TMI``/`C``"9$P``VMI``)$2``#:VD``F$?``)B+``#:%0``BQE``-+3``#
+M_P```V%$``-+'``#0"H``K3\``-A0``"0S0``F$>``-K'``"2JX``_!&``-)
+MU0`"O!```DS'``/P0@`"O"T``_\```-`)``"M$```K7P``-*I@`"1$$``_`"
+M``)IE0`#:J8``T````/_```#^`$``\1```/$40`"QD4``@````-`$``#_P``
+M`_\```/H(``#Z#```V`0``"1Y0``D@T``_@#``(Q&0`",@P``T@(``*TGP`"
+M0`0``V@(``-(P``#2,8``K3\``*U#P`"010``DF4``)")0`"2J4``D,U``)+
+MM0`#:,```VC&``-(```#2`4``KL_``*\OP`"O^\``)(E``"*)@``@BH``+HH
+M``"J+``"01L``KO[``)`#``#:````KS^``)%7P`"1WP``V@%``-($``#2=T`
+M`KOQ``*\`@``BBD``*HK``)!&P`"81P``V@0``)%6P`"95P``VG=``-`#0`#
+M_P```_\```.A3```B?\``K,"``)#-``#HS```)G^``*S!``"0S0``Z,R``"9
+M_0`#0"D``T````*\(```N<<``D(L``/P!P`"L````((Q``(ZG0`#Z````('E
+M``/T```!PF```T````*\(```\C$``D,\``/P!0`".IT``^@```"!Y0`#]```
+M`<)@``-((0`"L\$``D=S``-H(0`#:HD``T@E``*SP0`"1W,``V@E``-JC0`#
+M2"D``TEP``-`$@`"OP<``D`/``.````#``X``Z^(``-)U@`"O!```DS+``/P
+M00`"P`\``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H+0`#P00``\$5
+M``-IZ``#:>P``TK"``*_P``"2(\``VK"``-JQ@`#Z````^C0``(N\``#:.0`
+M`\'>``(N\``#:00``^A```*]```",EP``KT!``(R7``#0"P``_\```*T`@`"
+M1`0``*()``-)U@`"M1```D1;``.D1@``H@L``J!.``/P`P`"-!<``_0```'!
+M!0`#]````=+=``-+8``#_P```F`.``-K8``"O````C*7``-`#@``\C(``^CP
+M``.@M@`#2=4``/H$``*Q#P`"0A<``J4@``/P`0``^C(``D,;``*E(P`#\`$`
+M`/($``-````#0"X``K80``*T#```*C(``D(D``.B(@`"0S0``FPC``)&:``#
+M\`,``J!>``/P`0`#Z,```.(#``-`"``"M````'H$``*@)``#\$$``K((``*@
+M_@`#\$$``K($``*T/P`"0B0``)(:``-*E``#_P```V&```-````#_P```K1`
+M``)$!``#\`,``^@```"",0`"(O,``T````/_```"M$```D04``/P`@``\C$`
+M`B+S``-````#_P```K1```)A$``"1!0``_`!``(M40`#2I0``_\```-AA``#
+M0````_\```*T`@`"1"0``_`#``/H````@C$``B,?``-````#_P```K0"``)$
+M-``#\`(``/(Q``(C'P`#2I0``_\```-AB``",@P``T````/_```#_P```D0.
+M``/P`P`#Z````((Q``(D2``",@P``T````/_```#_P```D0>``/P`@``\C$`
+M`B1(``(MB``#2I0``_\```-AC``#0````_\```*T`@`"1$```_`+``/H````
+M@C$``B8[``-`+``#_P```K0@``)$0``#\`,``^@```"",0`",8,``TJ4``/_
+M```#89```T````/_```"M`0``D1```/P`P`#Z````((Q``(H#``#2I0``_\`
+M``-AE``#0````_\```*T$``"1$```_`,``/H````@C$``BBS```!_P`#_P``
+M`_\```*D#@`#\`0``/(```(HLP`#Z````((```-*E``#_P```V&8``-````#
+M_P```K0@``)$0``#\`,``^@```"",0`"*D```TJ4``/_```#89P```(#``/_
+M```"M`$``D0$``/P!``#Z````((Q``/!_@`"*O(```(#``/_```"M`(``D0$
+M``/P!``#Z````((Q``/H\``"*O(``T````/_```#_P```D0N``/P`P`#Z```
+M`((Q``(X.P`#0````_\```*T$``"1"0``_`#``/H````@C$``CE?``/X`P`#
+M2I0``_\```-A8``#0````_\```*T`@`"1$$``_`*``#R,0`")CL``T`L``/_
+M```"M"```D1```/P`@``\C$``C&#``-*E``#_P```V%D``-````#_P```K0$
+M``)$00`#\`(``/(Q``(H#``#2I0``_\```-A:``#0````_\```*T$``"1$$`
+M`_`+``#R,0`"*+,```'_``/_```#_P```J0.``/P!```\@```BBS``/H````
+M@@```TJ4``/_```#86P``T````/_```"M"```D1!``/P`@``\C$``BI```-*
+ME``#_P```V%P```"`P`#_P```K0$``)$!``#\`,``/(Q``/!_@`"*O(```(#
+M``/_```"M`@``D0$``/P`P``\C$``^CP``(J\@`#0````_\```/_```"1#X`
+M`_`"``#R,0`".#L``T````/_```"M!```D0T``/P`@``\C$``CE?``-*E``#
+M_P```V%T``/X`P`#0````_\```*T"``"8`$``D0$``/P#``#2`@``_\```*T
+M0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#```\$N``-H,``",9X``^@`
+M``/H$``#Z#```K(#``-H,``#0````_\```*U@``"81```D45``/P`0`"-YH`
+M`TJ4``/_```#87@``KP!``(REP```C(``_\```/_```"H0X``_`"``/H````
+M@@<``BV(``-(```#2`4```HF```"*@``$B4``"HL```Z*``#_P```V@```-H
+M!0`#2!```TG=```**0``*BL``_\```-H$``#:=T``TEQ``*R`0`#Z#```\$&
+M``/!%P`#:#```C&>``/H```#Z!```K(#``*S```#:#````(+``/_```#_P``
+M`J`.``("A@`"(N<``_0```'``````>4``T`2``-`%0``"@T``J`.``/P`@`#
+M]````<*A``+!'@``B@T``FNZ``)E6P`"QFX``_!!``,&;@`#8!4``K(/``)$
+M0@`"I10``_`'``/HH``#Z+```V`2``/H````@>4``_0```'`:P`#0"P``_\`
+M``*T(``"0$```_`"``/T```!PK4``T@(``*TOP`"0`0``V@(``/H````@C$`
+M`C&#``#R,0`",8,``T@(``*T0``"8`0``V@(``/H````@C$``C"X``#R,0`"
+M,+@``TD]``-(P``"M@@``D9D``/P`@`"M3```F(E``-HP``#:,0``B+G``-`
+M(``#_P```_\```+"+@`#\$0``L,^``/P0@`"LO\``K/_``-@(``",@P``TM@
+M``/`C@`"0`@``VM@``-)2``#0"H``K0_``*U@``"MD```D9H``/P10`"0S0`
+M`F,U``-I2``"0S0``VE(``/H```#Z!```^@@``/H,``#9*0``V3D``/T```!
+MP````TL=``-`*``"O!```K\$``),P``#\`4``F=^``-K'0`",9X``F=_``-K
+M'0`#[````T`$``!J,0`#Z(```^B0``/HH``#Z+```J#>``/P`P`#9*H``_0`
+M``/P00`#9.H``&'I``*@W@`#\`,``^A```/T```#\$$``X3J``/80``#W,``
+M`'GH``/X`P`#U)X``_L```,/_@`"`PH``"'#``*@W@`#\`,``&'"``/T```#
+M\$$``&'!``*_"``#W$```]C```/X`P`#U)X``_L```,/_@`"`QD``_@#``/L
+M`````C(``&HQ``/_```"H`X``_`!``/L```#23@``J#>``/P00`#23@``KC^
+M``)"*``#:3@``TG0``*T!``"810``K(!``*S$@`"H-X``_!!``*S$0`#:#``
+M`TEQ``*X[P`"N00``\$&``)A>0`"0S@``V@P``-("0`"N/T``D1(``-H"0`"
+MM`$``B/J``(M8@`#2:```K01``/!)``"L0\``VF@``*@W@`#\`,``T)A``/T
+M```#\$$``T)=``/_```#_P```^A@``-II0`#:&L``KH,``*XP``#W($``]BA
+M``*P^``"L0<``^@@``/H,``#_@```]0?``-H:P`#Z/```B/3``(CPP`")`4`
+M`J'^``/P00`#8GH``T)X``/_```#_P```J"```'#=@`"H)$``<-V``*@H@`!
+MPW8``J"S``'#=@`"S_X``KP,``*A_``#\$(``_0```'#8```^<X``^CP``(C
+MPP`"(],``B0%``-">``#_P```_\```*@@``!PXP``J"1``'#C``"H*(``<.,
+M``*@LP`!PXP``L_^``*\#``"H?P``_!"``/T```!PWD``&'.``#YQ0`#_P``
+M`J7/``'#G``"I?P``<.7``/H\``#Z,```_0```'#GP`##,\``ZS```/H\``#
+M]````<.?``,/_``#K_```^C```(CTP`#P?P``B/#``*P&``")"0``K0```(C
+MZ@`#23@``J#>``/P00`#23@``_\```)B+@`#:3@``TG0``*T^P`"010``K(!
+M``*S$@`"H-X``_!!``*S$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@`
+M`V@P``-("0`"N`(``F1(``-H"0`"+8@``^P```/!#P`#P1\``\$O``/!/P`"
+MH-X``_`%``-DL``#9+0``V2X``/T```#\$,``V3P``-D]``#9/@``B/A``/L
+M```#P0\``\$?``/!+P`#P3\``J#>``/P!``#9*P``V2\``/T```#\$(``V3L
+M``-D_``"(^$``^P```-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@`
+M`^P```)-W@`#\$,``T<T``/T```#\$$``T=T```IQP`"MO@``D1.``/P0P`#
+MP04``_0```/P0@``@<<``D`&``/!$``#P2```\$P``)-W@`#\$0``V<T``-G
+M.``#]````_!"``-G=``#9W@``^P```*P$``")"0``TH<``(D.@`#P8P``TH@
+M``(D.@`#C,8``FB,``-*)``")#H``\&<``-**``")#H``XS&``)IG``#2BP`
+M`B0Z``/!K``#2C```B0Z``.,Q@`":JP``THT``(D.@`#P;P``THX``(D.@`#
+MC,8``FN\``/L```#2D8``K3^``)IG@`#:D8``DF4``-J1@`#:&L``KD(``*X
+MP``#W(```]B0``/H$``#Z"```^@P``/^```#U!X``VAK``/!CP`"OQ```BU>
+M``/!^``#[````^C```.'/``#IW8``X8L``.F:``#A1P``Z5:``.$#``#I$P`
+M`FS'``)LQ@`";,4``FS$``/L```#0"0``&HQ``/_```#H`8``J$.``/P`0``
+M@?D``TFA``-)I``"NT```KJ_``)%I0`"H-X``_`#``)#HP`#]````_!!``)C
+MLP`#::0``VFA``(RN@`#Z````^@@``/H,``"H-X``_`#```)^P`#]````_!!
+M```)^@`"N,```VAK``/8```#W(```]0>``*_"``"+5X``X#@``"!]@``@?4`
+M`^@```"!]```@?,``/'R``-(5``"H-X``_`#``.$Z``#]````_!!``.$Z@`"
+M8B0``VA4``-)=0`#B.8``F!H``/!%P`#P2X``\$^``*@W@`#\`$``X,P``-H
+M,``#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``\!$``)")``#:%0``&(+
+M``*_`@`"+5X``J#.``/P`@`#]````@2P``(O`@`#Z'```X3F``)&2P`"H&0`
+M`_!*``-)T@`#Z&```XJR``.JJ@`"H:X``_`"``,!K@`")BL``_0```'%5@`"
+MOP@``D_Y``.O]``#B[(``ZN\``(E;P`#]````<56``-`$``#_P```K\"``)/
+M\``#\`(``_0```'%5@`#0`P``_\```*_"``"3_```_!"``/T```!Q,@``K\`
+M``*[`0`")6\```($``/_```#_P```J`.``/P0@`#]````<56``#Q]```\?,`
+M`J#>``/P`P``>?@``_0```/P00``>?<``XWB``/<T``#V/```XGF``)IG@``
+M\>,``$'Y``/HT``#C^```\&H``.,[0``X><``.(P``(N:P`"MP$``$'Y``/H
+MH```T>,``J!^``/P`0`#J(```P_?``/!V0`#P:@``XSM``#AYP``XC```BYK
+M``(NK``#P00``\$F``-B<``"OP$``T`1``.(X``"H/X``_`$``)$2``#\`(`
+M`_0```(%/``"MP$``$'Y``/_```"H'X``_`!``.H@``#Z-```X_@``/!J``#
+MC.T``.'G``#B,``"+FL``BZL``-"<``#C.L``XSJ``/H\``"R$```ZB````J
+M"0`"RF(``ZJ@``*F7@`"!1D``&HQ``#R"0`#P5@``\%Z``-B<0`#]````@33
+M``*A7@`#\`X``&HQ``/!D0`#P;,``J#>``/P`P`#82X``_0```/P00`#83(`
+M`L"!``.H```"PJ,``ZH@``.%4```J@D``X'@``,`A``#\"0``J&$``/P`0`"
+MQ$$``P1.``/!5``#`J8``_`D``*AI@`#\`$``L9A``,&;@`#P78``]1>``)@
+M`@`"!2L``&HQ``*_`@`"+5X``TEQ``.!Y``#P08``Z)L``*@+@`"!58``F%Q
+M``/!+@`#P3X``J#>``/P`0`#@S```X9@``/P1P`#:#```X_M``(M7@`#C^T`
+M`BU>``./[0`"+5X``X_M``(M7@`#274``\$N``/!!@`#P1<``\$^``*@W@`#
+M\`$``X,P``-H,````>4``_\```/_```"I0X``_!(``-`$0`"H-X``_`#``)F
+M;@`#]````_!!``)G?@`#8!$``^@```"!Y0`#[````J#^``'%>P`"L`\``K$/
+M``*R#P`"LP\``J#>``/P`P`#8R@``_0```/P00`#8V@``C&>``-*0```0?(`
+M`$GV``!1]0`"O#,``D0,``)%'``"9$4``D8L``)'/``"9F<``F1&``*A3@`#
+M\`$``K0!``*@C@`#\`4``J1)``/P0P`"I$L``_!!``#Q]```H?8``KS,``)$
+M#``"11P``D8L``)'/``"9$4``F1&``)D1P`"H4X``_`!``*T`0`"H(X``_`%
+M``*D2@`#\$,``J1+``/P00``\?,``*'U``/H0```H?(```'T```1\P`"L0\`
+M`K,%``*E_@`"!=$``J#^``/P00`#Z/```J`.``/P`0`"S_X``K$0``*@+@`#
+M\`$``L_Q``*SD``"IO,``_!"``#QY0`#[````D,"``/P0P`")A$``_0```'%
+M>P`"M!$``P_T``*@W@`#\`,``/GQ``/T!``#\`$``/GP``-#*0`"H-X``_!!
+M``-#:0`"OW<``B7P``/L```#2.4``J#>``/P00`#204``K@1``*@#@`#\`$`
+M`L1(``))00`"I),``_`!``#Q]``"H"X``_`!``+%6``"25$``J23``/P`0``
+M\?,``J#>``/P`P`#:.4``_0```/P00`#:04``D`"``*@#@`"!7L``K$"``(F
+M*P`#[````J'^``/P00`#[````Z'V``./]@`#H/8``J$.``/P!P`"O`D``J!,
+M``/P00`"O`\``\%,``/!7``#``X``J$>``/P!P`"O`D``J!L``/P00`"O`\`
+M`\%L``/!?``#`1X``J#>``/P`P`#8RD``_0```/P00`#8VD``F(!``(%]@`#
+M[````T,I``*@W@`#\$$``T-I``*@#@`#\`4``K0/``),_@`#\`$``K0)``/!
+M5``"H"X``_`&``*V#P`#K/8``DS.``/P`0`"M@D``\%V``*@W@`#\`,``V,I
+M``/T```#\$$``V-I``/L```#2.4``J#>``/P00`#204``K`1``+$0``"Q5``
+M`J#>``/P`P`#:.4``_0```/P00`#:04``P$>``(&+P`#[````&HQ``/H```"
+M+MP``/'O``/H````@>X``T`,``-`+0`"N!```KD(``)*&``#JJ8``DM)``.K
+MM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!`
+M``/P00`#Z#```D$>``/P`0`#Z#```)GM``(M8@`"N!```KG^``*@W@`#\`D`
+M`T@A``*Z#P`"1FH``D=Y``)F:``#:"$``VJ)``/T```#\$<``T@E``*Z#P`"
+M1FH``D=Y``)F:``#:"4``VJ-``(P@@`"OP,``C!.``*_9``"+5X``&HQ``/_
+M```#_P```J#>``/P`P`"NP```_0```/P00`"NT```-G@``/!#@`"L1$``K(0
+M``-J1``"L1```^@@``-J1``"L/\``K'_``*R_0`"L_\``VA@``-*8``"O_<`
+M`K$3``)`#P`"8`X``VI@```Q_@``.?T``KP(``*__@`#AFH``F(F``*D?@`#
+M\`$``K,$``)`#P`"8`P``VI@``./X0`"+5X``VAK``/_```#_@```&(O``!:
+M+@`#_P```]C!``/<L0`#C^,``BU>``/0'P`#C.\``X_D``)O_@`"0`$``D(C
+M``)``@`"3,```_L!``/0'P`##_X``@:L``*@W@`#\`,``T@A``/T```#\$$`
+M`T@E``/`S``"!M@``XSF``+&;``#\$$``L=^``*@W@`#\`0``V@A``-JB0`#
+M]````_!"``-H)0`#:HT``J5^``/P`@`#]````<9^``-`$0`"L`@``/'E``*@
+MW@`#\`,``F9@``/T```#\$$``F=P``-@$0`#]````@@*``.`X0`#@08``F$>
+M``."YP`#:D0``X$&``/H(``#:D0``C""``-`+```6AT``K0$``/H\``"1$``
+M`_`!``*_`0`"I+X``_`!``*_!``",$X``/(9``#R%P`",K0``C""```*+0``
+M$?X``!G]``*P`@`"H-X``_!!``*P!``#@BH``J0^``/P`0`"LP0``X$6``)@
+M`0`"L3,``VI@``-`"@`"L`$``K$"``*R```"LP$``J`K``/P`@`#Z"```\$[
+M``-J:``#P0X``K()``)`"0`#\`$``^@@``*P$P`"L0(``X(F``/H,``#:G``
+M`&($```2&@`"H,X``_!!``*R!``"L"$``K$"``*S`0`#:G0```H=``*P`0`#
+M_P```J0>``/P!0`"L00``K(```*S`@`#]`0``_`#``*Q`@`"L@\``K,!``-J
+M>``#2GP``_\```*P`0`"L0(``K,$``-J?````>X``_\```/_```"P`X``('N
+M``(P20```AD``T`*``-`#0`"H`X``_`%``*P`0`"0`4``X`&``/T!``#\`,`
+M`K`$``)`"0`#@`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"
+MLP$``VID``(O%P`"+R0```'O``/_```#_P```J`.``/P3@`#0"P``KP$``/<
+MP``#C^H``J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(MY0`#Z/```/GO
+M```![@`#_P```_\```+`#@``@>X```GM``-`+@`#_P```J`!``('@P`"L`$`
+M`D$(``/P!0```C(``_\```/_```"H`X``@>#``-*=``#23T``_\```.B5``#
+M@B```T`)``*E+@`#\`$``K((``)%7@`#\`$``!(:``/_```#_P```VIT``(P
+M20```AD``T`*``-`#0`"H`X``_`%``*P!``"0`4``X`"``/T!``#\`(``K`0
+M``)`"0`"L4,``F@!``-*9``"M(```!'@``)`!``"8`@``Z(B``/!/@`#:F0`
+M`B\7``(O)```0@,``K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''LP`#
+M0`X``K`0``/_```"00D``J`0``('LP```AD``_\```/_```"P`X``((9``*Q
+M`@`"I`$``@<P``!!X````<,``_\```/_```#V(```]P```*_"0`"L````]P!
+M``*PP``#V`$``B\.```![@`#_P```_\```+`#@``@>X``C!)``-`"@`"L$``
+M`_\```)`"0`#H`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"
+MLP$``VID``(O%P`"+R0``T`E``!"`P`"L"```D`%``/P2``"L`(``J#>``/P
+M00`#@`(``D`(``/P`@`#]````<?X``-`+@`#_P```K`(``)!"``"H!```@?X
+M``*P@``"00@``_`%```",@`#_P```_\```*@#@`"!_@```(7``/_```#_P``
+M`^@0``"*%P`"I`X``@=B```!X```0<,``_\```/_```#V````]R```*_"0`"
+ML,```]@!``*P```#W`$``C*Z``-H:P``$=8``K/```/HT``#8G0``BX-``(P
+M>``#[````&HQ``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\`
+M``/_````V>P``C#_``/H```"+MP``KL"``#:,``#Z````K%@``/H(``#Z#``
+M`VF@``/H```"L1```^@@``/H,``#:D0``C""``*_`@`",$X``K#_``*Q_P`"
+MLOT``K/_``-H8```"BT``!'^```9_0`"L`H``J#>``/P00`"L`P``X$6``)@
+M`0`#@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+5X``VAK
+M``/_```#_@```C!X``-*8```,?X``#G]``*T]@`"M0,``X9J``)B)@`"I'X`
+M`_`!``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#
+M:F@``K"```*R"0`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P
+M(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\`
+M``*P`@`"L0(``K,$``-J?``",K0``^AP``-*9``"M(```D`$``/H(``#Z#``
+M`VID``-*9``"M(```!'L``)`!``"M`,``F`$``*S$``#:F0``B\7``-*9``"
+MM`@``D1```)G=``"I7X``@BQ``/H```"+MP``J#>``/P`P`#2"(``_0```/P
+M00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H(@`#:HH``_0`
+M``/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R'8``T`2``#QY0`"OP0`
+M`J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R+$``C!X``/L````
+M:C$``/'O``/H````@@8``T`(``-`+0`"N$```KD(``)*"``#JJH``DM)``.K
+MM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!`
+M``/P00`#Z#```D$>``/P`0`#Z#```)H%```AY0`#Z%```_\```"B#```J>4`
+M`&HQ``/_```#_P```J#>``/P`P``6<(``_0```/P0P``6<$``_\```/_````
+MV>```T`L``!:'0`"M`0``^CP``)$0``#\`$``K\!``)+O@`"H+X``_`#``(O
+M?P`#]````<CP``*_RP`",>0``/(8``#R%P`",K0``C""```*+0``$?X``!G]
+M``*P`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B(0`"I#X`
+M`_`!``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"``*R```"
+MLP$``J`K``/P`@`#Z"```\$[``-J:``"L`$``K((``)`"0`#\`$``^@@``*P
+M$P`"L0(``X(F``/H,``#:G```&($```2&@`#_P```J#.``/P00`"L@0``K`A
+M``*Q`@`"LP$``VIT```*'0`"L`$``_\```)!$``"I!X``_`%``*Q!``"L@``
+M`K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q`@`"
+MLP0``VI\```*'0`#_P```_\```)!'@`"I!X``@F%```"!@`#_P```_\```+`
+M#@``@@8``C!)```"&``#0`H``T`-``*@#@`#\`4``K`"``)`!0`#@`0``_0$
+M``/P`P`"L`@``D`)``.````"L0,``F@!```"'0`#_P```_\```)`#@`"I`X`
+M`_`+```2&@`"L",``K$#``*S`0`#:G0``TI\``/_```"L`$``K$$``*S!``#
+M:GP``TID``*T@```$>```D`$``)@"``#HB(``K,!``-J9``"+Q<``B\D```!
+M[P`#_P```_\```*@#@`#\$X``T`L``*\!``#W,```K_```*@W@`#\`$``K^`
+M``/8\``#C.0``K\_``)+'P`"+>4``^CP``#Y[P```@8``_\```/_```"P`X`
+M`((&``!:'0``>A<``K@(``)*O@`"H*X``<FF``.JL``"2JX``_!#``(L)``#
+M]````<FE``-*<``"NH@``KEP``*@^``#\$,``\$J``/T```!R:,``ZNR``)+
+MO@`"H+X``_!!``/!*0`#:G```C&Q``(RM```"@4```(&``-`+@`#_P```J`!
+M``()N@`"L`$``D$(``/P!0```C(``_\```/_```"H`X``@FZ``-*=```>AH`
+M`_\```/_```#P2\``VIT``(P20```A@``T`*``-`#0`"H`X``_`%``*P"``"
+M0`4``X````/T!``#\`,``K`@``)`"0`#H````K%#``)H`0`#2F0``K2````1
+MX``"0`0``F`(``.B(@`"LP$``VID``(O%P`"+R0``$(#``*P`0`"H-X``_!!
+M``.``@`"0`@``_`"``/T```!R>L``T`*``/_```"L$```D$(``*@$``"">L`
+M``(8``/_```#_P```L`.``""&``"L0(``J0!``()0@```>```$'#``/_```#
+M_P```]@```/<@``"OP@``K#```/8`0`"L````]P!``(O#@```@8``_\```/_
+M```"P`X``((&``(P20`#0`H``K"```/_```"0`D``Z`$``*Q`P`":`$``TID
+M``*T@```$>```D`$``)@"``#HB(``K,!``*Q```#:F0``B\7``(O)```0@,`
+M`K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```'*+0`#0"X``_\```*P"``"
+M00@``J`0``(*+0`"L(```D$(``/P!0```C(``_\```/_```"H`X``@HM```"
+M%P`#_P```_\```/H$```BA<``J0.``()A0``8<,``%G@``/_```#W,```]BP
+M``*_"``"L,```]@!``*P```#W`$``C*Z``-H:P``$=8``K/```/HT``#8G0`
+M`BX-``(P>``#[````&HQ``/_```#_P```J#>``/P`P`"NU,``_0```/P00`"
+MNUL``_\```/_````V>P``T`0``*['P`#2"D``J#>``/P00`#2"T``D`+``.O
+M`@`#C/8``FS/``./]@`#2>@``J-,``/P!``#!$P``P5?``/T```#\$(``P3$
+M``,%]0`#P00``\$5``*@W@`#\`0``V@I``-IZ``#]````_!"``-H+0`#:>P`
+M`^@```(N\``#Z````K%```/H(``#Z#```VI$``(P@@`"OP(``B]_```*+0``
+M$?X``!G]``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"L80``F(A``*D
+M/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"L0(``K(*``/H,``#:F@``K"`
+M``*R"``"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"L0(`
+M`K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P`@`"
+ML0(``K,$``-J?``",K0``^AP``(P20`#2F0``K2````1[``"0`0``K0#``)@
+M!``"LQ```VID``(O%P`#2F0``K0(``)$0``"9W0``J5^``(*[P`#Z````B[P
+M``*@W@`#\`0``T@J``-)Z``#]````_!"``-(+@`#2>P``KP1``*_$``"R9\`
+M`LB,``/P00`#Z(```\$(``/!&0`"H-X``_`$``-H*@`#:>@``_0```/P0@`#
+M:"X``VGL``-*P``"OP<``DW>``/P`0`"OS@``J&.``/P0P`"8`\``VK```-J
+MQ``"NP$``-HP``/H<``"3_```_`#``*[_P`"H(L``_`"``/T```!RJ<``T`2
+M``#QY0`"OR```J#>``/P`P`":J\``_0```/P00`":[\``V`2``(P@@`",$D`
+M`^P```!J,0`#Z````(',``""#``"H-X``_`#``!9P@`#]````_!!``!9P0`"
+ML'\``J'^``/P00`"2[```-G@``(RM``",((```HM```1_@``&?T``K`"``*@
+MW@`#\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"LP0``T`5
+M``*Q"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J:``"L@@`
+M`K`3``*Q`@`#@B8``^@P``-J<```$AH``K`A``*Q`@`"LP$``VIT``*P`0`"
+ML0(``K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP``KP$``/<
+MP```>>```KP(``*[&``#V/```BWE```!S``#0"4``K\0``+`#@``@<P``D]?
+M``/P`P`"+"0``_0```'+30`"OP@``J`.``/P`0`#P?X``C&Q``-*@``"H/X`
+M`_!!``-JA```8>```K"```/H\``"H<```_!!``/!_@`"*[8``C!)```1X``#
+MZ!```K`C``.B(@`"LP$``VID``(O%P``8<P```'@```)PP`#0"8``K(0``/8
+M```#W!```K\(``*PP``#V`$``K````/<`0`"0BD``_!%``.O\``"H,X``_`"
+M``/[```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E+@`#\`$`
+M`_L!``,/_@`""V\```',``/_```#_P```L`.``"!S```8>```K"```/!_@`"
+MH<```_!!``/H\``"*[8``C!)```1X``"L`,``^@0``.B(@`"LP$``VID``(O
+M%P`"+R0``T`E```!S``"L0,``K((``*S$``"0S4``_`"``)")0`#\`(``J4!
+M``'+.@``8<,``%G@``/_```#W,```]BP``*PP``#V`$``K````/<`0`"OP@`
+M`C*Z``-H:P``$=8``K/```/HT``#8G0``BX-```"#``#0!$``K&```)`#@`#
+M\`,``F9A``-@$0``@>4``C!X``/L```"O!$``J#>``/P!``#2,P``TC1``/T
+M```#\$(``TCL``-(\0`"*^X``J#>``/P!``#:,P``VC1``/T```#\$(``VCL
+M``-H\0`"H-X``_`$``-(U``#2-D``_0```/P0@`#2/0``TCY``(K[@`"H-X`
+M`_`$``-HU``#:-D``_0```/P0@`#:/0``VCY``*@W@`#\`,``TC<``/T```#
+M\$$``TC\``*@_@`#\`0``L`,``+!'``#]````_!"``,`#``#`1P``J#>``/P
+M`P`#:-P``_0```/P00`#:/P``^P```*@_@`#\`D``L`,``+!'``"PBP``L,\
+M``+$3``"Q5P``L9L``+'?``#[````P`,``,!'``#`BP``P,\``,$3``#!5P`
+M`P9L``,'?``#[````K@/``*Y\``"2@@``DL)``(L'0`"2A@``DL9``(L'0`"
+M2B@``DLI``(L'0`"2C@``DLY``(L'0`"2D@``DM)``(L'0`"2E@``DM9``(L
+M'0`"2F@``DMI``(L'0`"2G@``DMY``(L'0`#[````J&N``/P00``\@P``J&^
+M``/P00``\@P``^P```*P?P`"L?\``K+_``*S_P`#:&```VAK```)U@`#Z```
+M`Z`#``/<```#V!```T`Q``*_`P`"O`(``J;\``/P00`#P0<``J#\``/P00`#
+MP08``J#^``/P00`#P04``J'^``/P00`#P00``\$0``/!(``#P3```_X```/4
+M'@`#:&L``_L```,/_@`"##(``T`U``*_`P`#_P```J;\``/P00`#P0<``J#\
+M``/P00`#P08``J#^``/P00`#P04``J'^``/P00`#P00``\$0``/!(``#P3``
+M`_X```/4'@`#:&L``_L```,/_@`"#$H``T`X``-`/0`#_P```VJ$``-J@0`#
+M[````TA5``/_```"M\```VA5``-H:P`#2`H``K]_``)H^``"LN\``Z"!``*_
+MPP`"0`\``T`E``*S_P`"L?\``D]>``/P`@`"N?,``D(I``*\`@`"3%P``_`!
+M``*S^P`#:&```TA```./\@`"O/L``D$<``)A'P`#:$```VAK``-)?``"M`0`
+M`F$4``-I?``#2I0``_\```-A?``#:&L``C&>``/_```#_@```_\```-!20`#
+MZ/```]SP``-(9``#B$0``ZB```*\0``"S,@``]C```/4'@`",L```V%)``-(
+M9``"M!```D8D``/P`@`#]````<SS``-(9``#2#8``K1```*U!``"1$```D58
+M``)D10`!S+<``K0\``)$0``#\$,``CLG``/T```!S(L``T`4``/_```#_P``
+M`L,^``/P00`#`SX``V`4``(RUP`#^`,``TAD``.,Z@``\@@``DP,``',SP`#
+M2#0``KP$``),P``"#+X``.((``-)/0`"OQ```D1/``/P!``"O_\``BU>``*_
+M4``"+5X``K\(``(M7@`#]````<S@``-(0@`#2=0``#(S``*U$```FC,``KQ`
+M``)%4P`#\`D``DS)``/P!P`"H&,``_!%``#R`@`"-,<``VAK``/T```!P$$`
+M`TA4``*U/P`"0U,``K</``)C-P`#:%0``C*Z``/H````@@(``T)Q``(RP``#
+M8G$``T@(``*T@``"1$```_`"``/T```!UU4``^P```/X`P`#2`@``K2```)$
+M0``#\`(``_0```'750`#2=```K@(``)).``"H)@``@U*``-)U``"M!```D,T
+M``*@-``"#2@``T@(``*X"``"8`@``V@(``-(*``"N"```F,X``-(+0`#:"@`
+M`VGH``)G>``#:"T``VGM``-(R``"N/L``D(H``-HR``#2)@``K@@``)@"``#
+M2+$``VB8``)D2``#:+$``\$.``/!'@`#P2X``\$^``-C,``#8W```V,T``-C
+M=``#8S@``V-X``/T```!S4H``T@(``*X]P`"0`@``V@(``-(*``"N-\``D,X
+M``-(+0`#:"@``VGH``)'>``#:"T``VGM``-(R``"N`0``F(H``-HR``#2)@`
+M`KC?``)`"``#2+$``VB8``)$2``#:+$``K`#``/!$``#P2```\$P``-C,``#
+M8W```V,T``-C=``#8S@``V-X``-)?``"M/L``D$4``-I?``#:&L``_0```',
+MBP`#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(``VC*``)H(0`#:,H``\&"
+M``-HR@`#[````_@#``,/_@`"#5\``^P```(RN@`#:&L``\$.``/H$``#Z"``
+M`^@P``.D$P`#V!```]Q```/^```#U!X``VAK``-II``#Z````_X```/4'@`#
+M:&L``VFD``*@W@`#\`,``T)@``/T```#\$$``T)<``-"60`"H-X``VFD``/P
+M`P`#0F@``_0```/P00`#0F0``VFA``/^```#U!X``VAK``-H:P`#[````C*Z
+M``-H:P`#0E8``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/4'@`"OP(`
+M`BU>``-H:P`#::0``VFB``/H```#_P```]0>``*_`@`"+5X``VAK``-II``"
+M,KH``VAK``/L```#:&L``C*Z``*Q#``#Z````Z`#``/<```#V!```^@```/H
+M$``#Z"```^@P``/^```#U!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>
+M``-H:P`#^P```PB.``(-M``#[````"'K``/H4``#Z&```^AP``*Y"``"N,``
+M`]R!``/8D0`#0E```_@#``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#
+M:&L``\&/``*_$``"+5X``K09``/^```#U%\``VAK``*_$``"+5X``\'X``-)
+MI0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#"9X``@WA
+M``-II0`#[````J&^``/P#@`#T!X``P^^``*Z/P`#``X``D`*``,!'@`"01H`
+M`P(N``)"*@`#`SX``D,Z``/4'@`##_X``@WJ``/[```##,X``@WE``/L```"
+MH;X``_`.``/0'@`##[X``KH_``+`#@`"0`H``L$>``)!&@`"PBX``D(J``+#
+M/@`"0SH``]0>``,/_@`"#?X``_L```,,S@`"#?D``^P```/0G@`#T!\``KP_
+M``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP``KP@``+`A``#H```
+M`J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#
+M\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``KP'``*CW``#\$X``W)T``-2
+M=@`#_P```_\```/^```#U!X``VAK``/[```#<G8``U)T``/_```#_P```_0$
+M``/P"``"O`@``J3<``/P`0`#:H0``KP)``*DW``#\`$``VJ```(RM``#^P``
+M`_L!``+-W@`"IM\``@X-``(P20`"L````K$```*R```"LP$``VIT``*P,0`"
+ML08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#:GP``TID``*T
+M@``"0`0``K0#``)@!``#:F0``B\7``-*9``"M(```D`$``-J9```:C$``C(,
+M``/L````6><``&(P``/_```"H;X``_!"``#QY0`#[````J'.``/P00`#"[X`
+M`PS.``#9YP``XC```TI```!:"0`#_P```_\```*@O@`#\$(``Z````.B(``#
+MT%X``&'\``!9XP`#H@(``D`)``)"*0`"I8X``@Z6``,(C@`"H`T``_`+``!!
+M^0`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$3P`#P50``J6N
+M``(.I@`#"JX``J`M``/P"P``4?D``L9O``/!=@`"H+X``_!&``/47@`"QF\`
+M`\%V``/47@`"QF\``\%V``/47@`##,X``@ZG``)KB@`"#FL``^P```-"<```
+M4@D``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"H6@``_!!``+&
+M:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&:``#`B@``P,X
+M``,*K@`"#KH``\%4``/!=@`#U%X``V)P``/L```#P6(``P9N``/<$``#V```
+M`]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X``_L```,&;@`"
+M#L\``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#:1```VD4``-I
+M&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I-``#[````\$0
+M``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<``/T```#\$4`
+M`VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4``D$#``-)T@`#
+M_P```D`*``-)P@`"I1```_`!``-)Q@`#[````]">``/[```#_P```_\```/4
+MGP`#^P$``P_^``(/#@`#[````_@!``*_!``#2F0``_\```/_```"00\``@\9
+M``/X`P`#:&L``_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\`
+M`@]%``-`$@`"M1```J4E``/P!``"OP(``FJO``/T```!ST(``L15``*E)``#
+M\`0``K\"``)KOP`#]````<]"``+$10`"I20``_`$``*_$``":J\``_0```'/
+M0@`"OQ```FN_``#QY0`#8!(``B]&``/L```#2G```_\```/!P@`#0"X``K`!
+M``-JJ``#_P```_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,`
+M`TJM``*_D``"H,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#
+M\`L``T`9``/_```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P
+M20`#0!T``_\```/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P`
+M``+$1@`#:JD``_\```/_```#_P```TJL``/L```",KH``VAK```)U@`"L,``
+M`]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P50`#
+MP1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$``*T
+MJ@`#P50``\%D``/!=``"O`<``J/^``(/^```0?\``_\```/_```"H(X``@^^
+M``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J,0``:@```J3>``/P!``#P(@`
+M`\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G>P``
+M:C$``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK``/[
+M```##,X``@^^``!!_P``8@```_\```*@C@`"#^,``T!*``*DS@`#\`0``\"(
+M``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`":JL`
+M`KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@2@`#
+MP1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+``/!
+M$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,``J#Y
+M``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"$`0`
+M`K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L```"
+M,KH``VAK```)U@`"L,```]P```/8$``"M/\``\%D``/!=``"O`<``_X```*U
+M_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X``VAK``/[```##,X``A`?
+M``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#2F(``C!)``/H\``",%4`
+M`VIB```)U@`"L,```]P```/8$``"M/\``\%4``/!9``#P70``KP'``/^```#
+MU%X``VAK``/[```##,X``A!!``(RM``#[````TID``*T@``"0`0``VID``/L
+M```"L`0``J#P``/P`P`"+W\``_0$``/P`0`"+"0``^@```/````#P1```K+]
+M``*S_P`#:&````HM```Q_@``&?T``K`*``*@W@`#\$$``K`,``.!%@`"8`$`
+M`K$6``*D/@`#\`$``K,$``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"
+ML@0``F(F``-J8``#C^$``BU>``-H:P`#_P```_X```/L```#2F```_\```/H
+M,``"8`X``VI@``-*9``"M/(``D`$``-J9``#[````K`!``/H$``#Z"```^@P
+M``-J8``#[````&HQ``-`!``#_P```K@$``)%X``"H%X``_!$``*@W@`#\$(`
+M`T`D``/_````8>D``_\```/_```#W,```X_J``*@W@`#\`$``^CP``/8\``#
+MC.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<``D`(``/P
+M0P`"+>4``_0```/P00`"+?D``D1N``/P"0`#Z,```ZMB``.E8``"15X``_!#
+M``(MY0`#]````_!!``(M^0`#[````&HQ``-`*``#0"$``KA```)(@``#\`,`
+M`D9N``/P`0`#[````%'#``*@W@`#\`,``%G"``/T```#\$$``%G!``/_```#
+MW*```]BP``-`!@`#_P```_\```)`Z``#\`,``J#>``/P00`#0"8``_\```/_
+M```#24$``J`.``/P0P`"H-X``_!!``/!10`"14X``_!#``.,Y``#]````_!!
+M``.,XP`#B9@``ZJ<``*@K@`#\`,``BWE``/T```#\$$``BWY``-`!@`#_P``
+M`_\```-)00`"0(X``J`.``/P0P`"H-X``_!!``/!10`#Z,```ZM"``)%3@`#
+M\`<``Z5```)%7@`#\$,``BWE``/T```#\$$``BWY``/L```"H-X``_`#``-(
+M(0`#]````_!!``-()0`#_P```KL!``.B9@`#@68``Z$6``.'=@`"8"<``P`+
+M``.G!@`#@@8``F8A``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`^P```./[0`"+5X``^@P``."X``#Z!```^@```-H,``#C^T``BU>``-)G``#
+M2=4``T`J``*T$``"1$<``K4"``)%6@`#A50``D1%``.D0``"MO<``D(F``)B
+M)``#:9P``^CP``-)<``#Z'```K8!``/!40`#P4```V@Q``*X_``#P5,``\%"
+M``)%6``#270``C&>``-H,0`#P5$``\%```(QG@`#:#$``\%3``/!0@`#29@`
+M`C&>``-H,0`#P5$``\%```(QG@`#:#$``\%3``/!0@`#29P``C&>``-H,0`#
+MP5$``\%```(QG@`#:#$``\%3``/!0@`#2.@``C&>``-H,0`#P5$``\%```*W
+M$``",9X``V@Q``/!4P`#P4(``C&>``-H,0`#[````KP#``-)/0`#2,```J#>
+M``/P00`#2,0``K8$``)&9``#\`0``X;*``/!?``"8B8``F$7``*@W@`#\`,`
+M`VC```/T```#\$$``VC$``-`*@`"M@@``X?&``)&:``#\`$``F,W``*@W@`#
+M\`,``VC```/T```#\$$``VC$``/L```",(@``TD]``-`*``"OP@``KP$``)/
+M#P`"3$P``F#\``/P00`#[````K0!``(R7``",6,``J'^``/P"0`",AT``C""
+M``-`*``"O`@``_\```)"+``#\$(``_0```/P0@`#Z$```C)<``/L```#_P``
+M`_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@``/H,``#
+M:.@``^@```/_```#:.@``T%(``/_```#[````C*Z``-H:P``"=8``^@```.@
+M`P`#W````]@0``*\`P`"L/<``J#^``/P00`"L'\``\$0``/!(``#P3```K3_
+M``/!5``#P60``\%T``/^```#U!X``VAK``.@`0`#H1$``Z(A``.C,0`#^P``
+M`_X```/47@`#:&L``_L```,,S@`"$<0``K#_``*\"``#P1```\$@``/!,``#
+M:H```J3^``'1W@`"H/P``_`"``-JA``#[````K#W``.A`0`#HA$``Z,A``-J
+MA``#[````TD]``/_```"N(```F1(``-I/0`"L`$``K$"``*R/P`"0B\``K,`
+M``-J:``"L````K$```*R```"LP(``VIT``*Q`0`"L@@``K,```-J>``"L`$`
+M`K(```-J?```$>```K#```)`#P`#H`(``F`.``*Q```#HB(``K,!``-J9``"
+M,K0``_\```/_```"+Q<``KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S
+M```#:#```^P```-`+``#_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8
+M``-@'``#[````&HQ``*P`0`#Z!```^@@``/H,``#:F```K\!``(P3@`"OQ``
+M`BU>``*\%``#2F```K_W``*Q$P`"0`\``F`.``-J8```,?X``#G]``*\B``"
+MM?X``X9J``)B)@`"I'X``_`!``*S!``"0`4``F`,``-J8``#2I8``T`I``*\
+M!P`#_P```D1,``.%1``"Q5X``\'%``/H0``#Z&```^AP``-JD0`"M/\``K5_
+M``*V_P`"M_\``VAA``-H:P`#_P```_X```,)G``#\$4``\"9``,*K@`#\$(`
+M`\"J``,+O@`#:I(``X````.@```#:F```K\0``(M7@`#[````T`J``-'+``"
+MH-X``_!!``-';``"MG\``X5,``)`!@`"29X``_`!``)@!0`#P1```\$@``/!
+M,``"H-X``_!$``-G+``#9S```_0```/P0@`#9VP``V=P``-'-``"H-X``_!!
+M``-'=``"MM\``X5(``)`!@`"8`4``\$0``/!(``#P3```J#>``/P1``#9S0`
+M`V<X``/T```#\$(``V=T``-G>``#2,```J#>``/P00`#2,0``K8_``)")@`"
+MML```J!.``/P`0`#Z&```F(F``*@W@`#\`,``VC```/T```#\$$``VC$``/L
+M```#29@``K@/``*Y]0`#Z#```\$N``*@S@`#\`(``F`(``)!&0`#:#```T@(
+M``*X0``"H,X``_`"``)@"``#:`@``^P```-A4``#854``V%:``-A7P`"+&4`
+M`T%0``-!50`#05H``T%?``/_```#_P```^P```*P_P`"L;\``K+_``*S_P`#
+M:&```^P```*P?P`"L?\``K+_``*S_P`#:&```^P```+$3@`#\$H``L5>``/P
+M2``"QFX``_!&``+'?@`#\$0``K3_``*U_P`"MO\``K?_``/L```"H<X``_`'
+M``,,S@`"OWP``BU>``/_```#_P```PS.``(2T``#[````K#_``*Q_P`"LO\`
+M`K/_``-JD``#[````^@```"",0`"(O,``/(Q``(B\P`",U@``BU1``-)F``"
+MM/,``K4/``)!%``"8`4``VF8``/!+@`#Z#```V@P```""@`#@>```^A```*@
+M`0`#\`$``\%.``(TN@`#2`@``KC^``)!&``#:`@``KP```(T90`"-)8``T`!
+M``/H````@C$``D1.``/P`0`")$@``T`!``/_````\C$``D5>``/P`0`")$@`
+M``(*``.!X``#_P```J00``/P`@`#P4X``C2Z``*\`0`"-&4``C26``*_`P`"
+M-T```C.E``(O`@`"OQ```D_[``'30```><L``_\```/_```"H/X``_`&``*]
+M```"-OH``KT!``(V^@`#]````=-(``-````"O````.(Q``*A#@`#\`$``C3L
+M``-````#_P```/(Q``*A'@`#\`$``C3L``-`!``#0`$``KP(``),P0`#\`H`
+M`KT```)$3@`#\`$``C<@``*]`0`"15X``_`!``(W(``"OP```/G+``/T```!
+MTT@``TG0``*\@``"3,,``_`$``*]```"-MH``KT!``(VV@`#0"P``KA```*Y
+M@``"N_\``TJE``)(&``#\`$``KO/``))&0`#\`(``KH_``)+N@`"15L``VJE
+M``/T```!PF```TG1``(O`@`#Z(```J40``/P`0`"N$```D1X``.$0``#2)P`
+M`K4$``)D10`"MG\``D`&``)@!``#:)P``VB@``-HM``#:+@``TDX``*U_``"
+M0B4``K4,``)B)0`#:3@``^@```/HT``"+MP``\'>``(NW``"+P(``X3B``/!
+MR0`#Z````K$#``*R"@`"LRT``D1)``/P`0`"LR\``^A0``(NRP`#@.H``B[+
+M``*X+P`"M`(``D1,``/P`0`"N"T``\&8``/!J``#P;@``V,J``-C:@`"+P(`
+M`X'B``.@X0`#HY8``X+D``+"+@`#Z%```B[+``.@XP`"+LL``B\"``.`Y0`"
+M0*```\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"`@`#@B0``)'4``/L
+M```"+P(``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP``/!;@`#P5,``\%"
+M``-H,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(``V@Q``)$C@`#\$T`
+M`TF<``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"8`4``F$4``/H,``#
+MP2X``V@P``-#I```(=0``K7/``)`!0`"8`0``\$0``/!(``#P3```V.D``-C
+MY``"1$0``_`!``(W.P`#@80``Z`8``."!@`"8`(``^C0``(N\``#P=X``B[P
+M``-)T0`"+P(``^A@``*E$``#\`$``K9```)&=@`#IFH``TB0``.DN@`"H$X`
+M`_!!``*T!``"M0,``J!%``/P00`"M`$``K7P``)!%0`"810``K?^``)`!P`"
+M8`8``VB0``-HJ``#:)0``VBL``.@I@`#P1```\$@``/!,``#9"0``V1D``.*
+MM@`#2"$``K@#``)F:``"N0\``KO^``)&:0`"9FH``D=[``-H(0`#:HD``V@E
+M``-JC0`#2`@``T@A``)A'@`#:`@``TC(``*X0``"N3\``F`(``-HR``"0`D`
+M`VC(``/L```#0"P``KA```*Y@``#Z+```TJE``)(&``#\`$``KLP``))&0`#
+M\`(``KK```)KN@`"95L``VJE``-(G``"O'L``D`,``-HG``#:*```VBT``-H
+MN``#2)```X3B``.EYP`"014``F$4``*U_@`"0`4``VB0``-HJ``#:)0``VBL
+M``-).``"M0,``F(E``*U\P`"0B4``VDX``/HP``"-&4``C26``/H```"L0,`
+M`K()``/H,``#Z%```B[+``.`Z@`"+LL``K`$``/!$``#P2```\$P``-C)``#
+M8V0``K`@``/!$``#P2```\$P``-C*``#8V@``C<[``-("``#2"$``ZCM``)!
+M&``#:`@``ZCK``)&:``#P#X``D53``-H(0`#:HD``V@E``-JC0`#Z$```C2Z
+M``/L```#0"D``_\```*X*@`"0EX``_`!``*X9``"H,X``_!!``*X$``#P9@`
+M`\&H``/!N``#9RX``V<R``-G;@`#9W(``K@J``)"7@`#\`$``KCD``*@S@`#
+M\$$``K@0``/!F``#P:@``\&X``-CK@`#8^X``TB>``/`%``#H1P``X$4``*P
+M]P`"2(```FB!``-HG@`#:*(``VBV``-HN@`#2NH``K#[``.!(@`"2J```FJA
+M``-JZ@`#:NX``VKR``-J]@`#[````T`I``-'-@`"L`<``K$(``)"7@`#\`$`
+M`K$8``*@S@`#\$$``K$```)(@``":($``\&8``/!J``#P;@``V<V``-G.@`#
+M9W8``V=Z``-#L@`"L`<``K$H``)"7@`#\`$``K$X``*@S@`#\$$``K$```)(
+M@``":($``\&8``/!J``#P;@``V.R``-C\@`#[````TET``/!;@`#Z'```XA(
+M``/`7@`#A5D``D(E``)B*``#:70``\%"``/!4P`#:#$``^P```*_`P`"-TT`
+M`T@(``*X_@`"01@``V@(``-`*``"O`0``K\#``),P@`#\`,``CX6``/T```!
+MU.<``TA4``*\8``"8BP``VA4``-)=@`"O!```F2L``/!6P`#P6X``^AP``-H
+M,0`",9X``TA4``*\GP`"0BP``VA4``/!2@`#:#$``C0+``-"10`",L```V)%
+M``/L````:C$``BUB``#QY0`",((``BPD``-`!``#0`H``KP#``*_!``"01P`
+M`P;Q``)`#P`#\`$``\%J``+$;@`"M0@``CD8``-`!``#Z/```/H&``*R0``"
+M0B```=5-``./!``#K_@``/H#``-)P0`"O`\``DC/``.H@``#B8(``KKC``)$
+M2@`"9$D``DG^``.)D@`"NOL``D5:``)E60`#:<$``X&&``)@@0`"+O```^@`
+M``*@W@`#\$$``K!```*Q`P`"L@D``K,)``)$[P`#\`$``K,/``/H4``"+LL`
+M`J/\``'530`#Z,```.'.``#A[@`"-K,``T`8``*@W@`#\$$``T`<``!![@``
+M8<X``F`!``)@`@`"8`,``J$.``/P0@`"R(X``,'N``*Z`@`"NQ\``LS*``#A
+MS@`"I<L``=4H``!*!@``>@,``_\```*AB0`!U4@``P_^``*P$``"S_```^@`
+M``"!Y0`#]````=4&``+/_@``^@,``,(&``/T```!U08``^C```#B`P`#Z#``
+M`C;'``/<X``"OP@``]CP``*P(``#P1```\$@``/!,``"OQ$``]0>``/_```#
+M^P```P_^``(560`"-K,``&(#``*P```#W````]P!``./P@`"L$```L`/``/8
+M```"L#\``D$/``*PP``"P`$``]@!``/47@`#T!\``K\0``*ASP`!U7H``J#>
+M``/P`P`#P0H``_0$``/P`0`#P0L``]0?``/T```!U8$``J#>``/P`P`#P2H`
+M`_0$``/P`0`#P2L``]0?``(V:P`#0`8``K`?``*Q(``#P2X``D$8``/P`0`"
+MPBX``LS"``#B`P`"I<```A5>``-*E``#_P```V"\``-`!``#W.```K\(``/8
+M\``#W.$``K\L``/8\0`"OP@``ZP6``*ESP`#\$,``\#,``)LSP`"S,X``K\(
+M``/0'@`#T%\``\&)``/!F@`#P:L``L1```.@0``"P`P``\&P``+%40`#H5``
+M`L$<``*F&P`#\`$``\&Q``+&8@`#HF```L(L``*F*P`#\`$``\&R``+'<P`#
+MHW```L,\``*F.P`#\`$``\&S``/4'@`#U)\``_L```/[`0`##_X``A6?``-!
+M.``#04D``T$J``*\#@`"HP$``_`!``/!`0`"HP(``_`!``/!`@`"HP,``_`!
+M``/!`P`"HP@``_`!``/!"``"HPD``_`!``/!"0`#Z!```J8,``/P`P`#P```
+M`X`&``.A!@`#P0$``J-%``/P`0`#P44``J-&``/P`0`#P48``J-'``/P`0`#
+MP4<``J-*``/P`0`#P4H``J-+``/P`0`#P4L``^@@``*F3``#\`,``\!$``.$
+M1@`#HD8``\$R``*@W@`#\`,``V2H``/T!``#\`$``V3H``/<X``"OP@``]CP
+M``/07@`"OP0``]SQ``*_@``"H-X``_!!``*_P``#V/$``KP0``*X`0`"N0,`
+M`KH/``*A3``#\$4``\!$``)$2@`#!`0``_0$``/P`@`#!$H``L1```*A7``#
+M\$4``\!5``)%6@`#!04``_0$``/P`@`#!5H``L50``*A;``#\$4``\!F``)&
+M:@`#!@8``_0$``/P`@`#!FH``L9@``*A?``#\$4``\!W``)'>@`#!P<``_0$
+M``/P`@`#!WH``L=P``/47P`#^P```_L!``/07@`#"(X``A8%``*X`0`#P0$`
+M`\$2``/!(P`#"9X``A8%``-$J``"H-X``_!!``-$Z``"H4P``_!%``/`1``"
+M1$H``P0$``/T!``#\`(``P1*``+$0``"H5P``_!%``/`50`"15H``P45``/T
+M!``#\`(``P5:``+%40`"H6P``_!%``/`9@`"1FH``P8F``/T!``#\`(``P9J
+M``+&8@`"H7P``_!%``/`=P`"1WH``P<W``/T!``#\`(``P=Z``+'<P`#U%\`
+M`BU1``(TQP`",((``C!)``/L```"+P(``Z.6``(VQP`#@.4``D.@``(VT``#
+M]````=9>``/!D``"H<\``_`!``/!D@`#8G4``,G.``/<X``"OP@``]CP``/<
+MX0`"ORP``]CQ``*_`0`#P00``C:-``-"=0`"OP$``_\```/!!0`"-HT``T)U
+M``*_`0`#_P```\$&``(VC0`#0G4``K\!``/_```#P0<``C:-```!S@`"OP``
+M`C:-``/L```"LB```]!>``/0GP`"00X``_!$``*@0@`#\$$``\%,``/!C``#
+MH````D$.``/P1``"H%(``_!!``/!7``#P9P``Z````)!#@`#\$0``J!B``/P
+M00`#P6P``\&L``.@```"00X``_!$``*@<@`#\$$``\%\``/!O``#U%X``]2?
+M``/[```#^P$``Z````,/_@`"%HX``^P```*S$``"I<,``_`&``/`/``#@S8`
+M`Z,V``(VT``#]````=;```*S#P`"S,X``D,\``(VQP`",A(``BU1``(TQP`"
+MOQ@``CC&``(O1@`#[````K$$``*P@``"H-X``_!!``*PP``"L@D``^A0``(N
+MRP`#[````\$#``/!$P`#P2,``J#>``/P`P`#9*@``_0$``/P`0`#9.@``^P`
+M``-`!``"O(```_\```),P``!UOH``T$!``*@W@`#\$$``T$%``*Q!``"L(``
+M`J#>``/P00`"L,```]P0``/8```#P80``C<7``/!A0`"-Q<``\&&``(W%P`#
+MP8<``C<7``*@W@`#\`,``V2A``/T!``#\`$``V3A``/T```!UQ0``K$$``*P
+M@``"H-X``_!!``*PP``#W!$``]@!``*Q`0`"L`@``J#>``/P00`"L"P``]P0
+M``/8```"OP@``B\.``-!`0`"H-X``_!!``-!!0`"H-X``_`#``-DJ0`#]`0`
+M`_`!``-DZ0`"+5$``C3'``/L```#P9@``\&H``/!N``"L@$``]2>``/[```#
+M`BX``A<;``/L```"L00``K"```*@W@`#\$$``K#```/<$``#V````K$!``*P
+M"``"H-X``_!!``*P+``#W!$``]@!``*_"``"+PX``T2H``*@W@`#\$$``T3H
+M``*@W@`#\`,``V$```/T!``#\`$``V$$``/L```#2PP``K7\``)!%0`#:PP`
+M`^P```-+#@`#P,\``FJO``-K#@`"2JP``TG5``*\"``#CW8``Z_T``+/_``"
+M+5X``VL.``/L```#2PX``\#/``)JKP`#:PX``C&>``)*K``#:PX``^P```*_
+M`P`"-T```TG```-)U0`"3`X``_!"``/T```!UY(``TG```.'=@`"IG```_!"
+M``/!$@`#Z````Z(6``.!%@`#H18``TB1``*\\``"15P``F52``*\!``"0PP`
+M`Z,R``*\_@`"1$P``F1#``-HD0`#:)4``VBI``-HK0`#P4$``\%1``/!80`#
+MP7$``V0A``-D)0`#9&$``V1E``*\`@`"0@P``X(J``-(G0`"LW\``D1#``)D
+M0@`#:)T``VBA``-HM0`#:+D``J$.``/P`@`"-SL``K`0``/!$``#P2```\$P
+M``-CH``#8Z0``V/@``-CY``"+5$``TE\``*T^P`"010``VE\``-H:P`#]```
+M`<QE``(P@@`",$D``T````/_```#_P```Z`,``.A'``#@1```F$0``,/'@`#
+MZ-```J#^``/P00`"O0$``\'.``-("``#_P```X3H``)@!``#:`@``TF8``*U
+M^P`"014``VF8``*T#P`"8`0``^@P``/!+@`#:#```TEQ``.!X0`#P08``F%Q
+M``/!+@`#Z#```V@P``(MH@`#^`$``T`-``/_```"L`$``D`&``(7TP`"H/X`
+M`_`"``*@[0`#\`4``KL^``)+M@`#J[```_0$``/P!@`#IFH``L9N``,+I@`#
+M]`0``_`!``/HL``#2!D``K+@``)&8@`"9FL``V@9``-)Y0`#_P```D9B``)F
+M:P`#:>4``\&K``(M8@`"+;L``K0/``(QG@`#2D```_@!``*D0``#\`8``J1!
+M``/P!``"I$(``_`"``*@0P`"&````LJN``*P(``"H*```_!!``/HH``"H*L`
+M`A@J``-(&0`"LN```D9B``)F:@`#:!D``TGE``/_```"1F(``F9J``-IY0`#
+M]`0``A?@``*C_@`"&#0``-'0``*@W@`"&`D``-'1``+-W@`#]`0``A>_``!!
+MT0`#_P```_\```*@J``"&#0``J&H``/P2``#2"$``P.*``.#,``"9W,``V@A
+M``-JB0`#]`0``A@T``-(&0`"LN```D9B``)F:``#:!D``TGE``/_```"1F(`
+M`F9H``-IY0`#2"4``P.H``.#,``"9W,``V@E``-JC0`#]`0``A@T``-`$0`#
+MZ,```/'E``*X@``"9W@``V`1``-)F``"M00``F$5``-IF``#2`@``_\```.$
+MR``"8`0``V@(``/X`P`#[````&HQ``/H````@@P``('/``(Y-``#0"0``_\`
+M``/_```"0`X``_!+``-`$``"O`0``]S```./Z@`"H-X``_`!``/H\``#V/``
+M`KP)``/!L0`"+>4``T`D``/_```"O`(``D`,``/P2P`#0!```KP$``/<P``"
+MO\```J#>``/P`0`"OX```]CP``.,Y``#P;$``BWE``(L)``"M`8``K4(``*V
+M!``".1@``K\8``(XQ@`"..T``K\```(P3@`#2G```_\```/_```"LI```VIP
+M``*_$P`".,8``CCM``-`)``#_P```_\```)`#@`#\$L``T`0``*\!``#W,``
+M`X_J``*@W@`#\`$``^CP``/8\``"O`D``XL0``(M^0`#0"0``_\```*\`@`"
+M0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/```XSD``.+
+M$``"+?D``TIP``/_```#_P```K*```-J<``"OQ@``CC&``(X[0`"OP```C!.
+M``-*<``#_P```_\```*RD``#:G```K\3``(XQ@`"..T``T`D``/_```#_P``
+M`D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP``*\"0`#
+MP;$``BWE``-`)``#_P```KP"``)`#``#\$L``T`2``*\!``#W,```K_```*@
+MW@`#\`$``K^```/8\``#C.0``\&Y``(MY0`".58``^P```/H```#P````K&_
+M``/!(``"L_\``VA@``(P@@`",$D```HM```1_@``&?T``K`"``*@W@`#\$$`
+M`K`$``.!%@`"8`$``X(J``*QA``"8B$``J0^``/P`0`"LP0``\$?``-J8``#
+M2F0``K2````1[``"0`0``K0#``)@!``"LQ```VID``(O%P`"OP@``D_P``/P
+M`0``\@P``^P````"#``#_P```_\```*E#@`#\`$``^P```/H````@@P``T`2
+M``/_```#_P```D2.``*@3@`#\`$``/'E``*_0``"H-X``_`#``)JKP`#]```
+M`_!!``)KOP`#8!(``B]&``!YSP`#_P```T`@``*@_@`#\$$``^P```*@W@`#
+M\`4``L`.``/P00`"L/\``_0```/P0P`"P1X``_!!``*Q_P`#8"```/'/``/L
+M```"L`$``K$"``/!)``#Z#```VIH``/!)0`"L!,``K$"``.")@`#Z#```VIP
+M``*P(0`"L0(``\$F``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP`
+M`_\```*P```"L0```K,$``-J?``#[````K`!``*Q$0`"LA```VI$``*Q$``#
+MZ"```VI$``*@W@`#\`,``KM3``/T```#\$$``KM;``#9[``#2`@``K1```"!
+MY@`"8`0``V@(``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$
+M``*P`0`#Z!```^@@``/H,``#:F```^P```(P@@`",$D``"'F``/_```#2`@`
+M`_\```/!!``#:`@``^P````*,@``:C$``_\```)`'@`#\$$``^P```(Y-``"
+MOP```C!.```R&@`#_P```K4)``.F8@`"QFX``L1N``(Y&``#0"@``^CP``*@
+MW@`#\$$``K]```#YX``#H`P``('%``-`&``#0!T``T`N``!AY0`#_P```_\`
+M``-A4``#854``V%:``#AQP`#0!```'G@``*\!``#W,```]CP``*\"0`#P;$`
+M`BWE``/HP```X<X``K`0``*Q```"LA```K,```-B=``"L(```]@!``*P```#
+MW`$``K`2``*Q`@`"LA(``K,"``-B=``"L!```K$2``*R$``"LQ(``V)P``-B
+M1``#8DP``V)(``/!C``#P9P``\&L``/!O``".D4``C(2``*_$P`".,8``B]&
+M``!AS@`#_P```K````/<```"L$```X_"``+`#P`#V````T`8``*@W@`#\$$`
+M`T`<``-`+0`#_P```]0>``/47P`"OP$``]SP``*_```#B,(``L_X``/8\``#
+MQ````\01``/$(@`#Q#,``J#>``/P00`#P6<``K41``)$90`#Q$0``L`$``*U
+M(@`"1&4``\1$``+!%``"M40``D1E``/$1``"PB0``K6(``)$90`#Q$0``L,T
+M``/4'@``><4``T)U``-"<@`"3_X``_!"``+``0`"PB,``J$$``/P1@`"I0D`
+M`_`$``/!C``#P9```\&L``/!L``"HPD``_!"``/!K``#P;```V)R``-"1@`"
+MH28``_!&``*E*0`#\`0``\&,``/!D@`#P:P``\&R``*C*0`#\$(``\&L``/!
+ML@`#8D8``J#^``':&``#0DX``J$5``/P1@`"I1D``_`$``/!C``#P9$``\&L
+M``/!L0`"HQD``_!"``/!K``#P;$``V).``-"2@`"H3<``_!&``*E.0`#\`0`
+M`\&,``/!DP`#P:P``\&S``*C.0`#\$(``\&L``/!LP`#8DH``V)T``/[`0`"
+ML1```LS.``#AS@`"H,$``=FA``-"<``#0D4``_\```+(`@`#J(```LI&``.J
+MH``#0DP``T))``/_```"R0(``ZF0``++1@`#J[```CI%``-`$```>>```KP$
+M``/<P``#V/```KP)``/!L0`"+?D``C""``(P20`#05```T%5``-!6@``8<<`
+M`_\```/_```#8!@``V`=``-@+@``X>4``^P```*[(0`"NQ````'%``/_```#
+M_P```D`.``':?0`#J80``ZND``*\#P`#B(```DB,``.*H``"2JP``TB<``-(
+MH0`"H-X``_!"``-(M``#2+D``\$8``/!6@`#C!8``X]6``)A'``"95\``J#>
+M``/P!``#:)P``VBA``/T```#\$(``VBT``-HN0`#2N@``TKM``*@W@`#\$(`
+M`TKP``-*]0`"O.X``D`,``)$3``#B)8``FR8``)@#``#BK8``FRZ``)D3``"
+MH-X``_`$``-JZ``#:NT``_0```/P0@`#:O```VKU``/L```"OP4``KP```*@
+MW@`#\$$``KQ```/<\``#V,```KR```)HC``":9P``FJL``)KO``#P0@``CJ5
+M``/!"0`".I4``\$*``(ZE0`#P0L``CJ5``/4G@`#^P```]2>``/L```#P1``
+M`\$@``/!,``#U!X``_L```/4'@`#^P```^P```!J,0`"+6(``^@```*Q8``#
+MZ"```^@P``-IH``#29@``K@/``*U]0`"LP```\$N``)@"``"014``V@P``*_
+M`0`"+5X``CDT``(P@@`#0"P``K\$``/_```"3_```Z_R``/H\``",$X``#(:
+M``/_```"M0D``L1N``(Y&``#Z/```J#>``/P00`"OT```/G@``!9QP``>>``
+M`KP$``/<P``#V/```KP)``(MY0`#Z,```.'.``#AQ@`#Z(```^B@``(Z10`"
+MOT```KP```/<P0`#V/$``K]```/<X``#V/```C(2``*_$P`".,8``B]&``*@
+MW@`#\$$``\&K``!AS@``><8``]1?``/[`0`#T%X``KL"``*A_@`#\$$``\%*
+M``*@_@`#\$$``\%:``*@^P`#\$$``\%J``*F^P`#\$$``\%Z``/47@`#^P``
+M`K`0``+,S@`"I<```_`&``#AS@`#P8P``\&L``(Z10`#]````=K5``*Q!``"
+MS_X``/G&``*A\0`!VQ```^BP``#9S@`#P8L``\&K``(Z10``>>```KP$``/<
+MP``#V/```KP)``/!O@`"+>4``]S@``*[0``#V+```_0```':U0`".58``K@(
+M``*Z"``".D4``%G'``!YX``"O`0``]S```/8\``"O`,``LN\``*\"0`"+?D`
+M`T@(``*T8``"8`0``V@(``-)F``#_P```K(!``/H,``#:#```^P```*T!``"
+M1C0``J!D``';,@`"OP,``CX_``-H:P`#0DD``C+```-B20`#[````T)-``(R
+MP``#8DT``TAD``/X`0`"O0P``DG2``*@V0`#\$8``K\#``([D0`"OP,``KT`
+M``([<@`#[````KT$``))T@`#\`8``K\!``([D0`"OP$``KT```([<@`#[```
+M`KT(``))T@`#\`8``K\"``([D0`"OP(``KT```([<@`#[````KU@``))T@`"
+MH-D``_!'``*_`P`"/!```K\#``*]`0`"O`$``CMR``/L```"O2```DG2``/P
+M!P`"OP$``CP0``*_`0`"O0$``KP!``([<@`#[````KU```))T@`#\`<``K\"
+M``(\$``"OP(``KT!``*\`0`".W(``^P```-(8@`"3,X``AN$``.`\@`#P```
+M`X'X``/`$0`"3=X``_!%``/````":J```DJA``/T!``#\`,``\`1``)*H``"
+M:J$``VAB``*P\@`":J```J`*``/P1P`#2$```K0(``*U]P`"810``VA```)!
+M%0`#:$```VAK``/L```#2%0``^B```*Y`P`"2_X``_`!``)HB0`"N@(``KD,
+M``)+^@`#\`$``FB)``)C.``#:%0``^B0``*T!``"2_X``_`!``)IF@`"2_H`
+M`_`!``)IE``#26```VAK``/_```#_P```TAE``/_```"2]8``J"]``'<"@`"
+M2Y,``=NF``-`*``#A/```*("``.B)@`",9X``P(N``';M0`#2`0``K3O``"*
+M+``"010``V@$``(^,P`"M@0``V@Q``-"20`#Z(```]R```-*E``#B$8``ZB"
+M``*\P``"S,@``]C```/4'@`#0"D``C+7``)%6@`"&_,``$H!``/_```"N(``
+M`\"9``.)G``"3/X``_`&``-)/``#2)D``F,X``)D20`#:3P``VB9``),^@`#
+M\`8``TE```-(L0`"8S@``F1)``-I0``#:+$``DS^``/P!@`#2)```TB5``)@
+M"``"9$@``VB0``-HE0`"3/H``_`&``-(J``#2*T``F`(``)D2``#:*@``VBM
+M``-`*``#_P```K@$``)!&``#\`$``CS)``-`*``#_P```K@(``)!&``#\`$`
+M`CV#``-(0``"N(```DO^``/P`0`"81@``DOZ``/P`0`"8B@``VA```*\`0`#
+M[````TA4``/`B``"0S@``VA4``*\```#[````T`H``#YNP`"N`@``D$8``/P
+M`0`"/9H``T`H``/_```"N`0``D$8``/P`0`"/1@``T`H``/_```"N`(``D$8
+M``(<1P`"2_X``APJ``-)/``#2)D``KA_``)#.``"1$@``VD\``-HF0`"O`(`
+M`DO\``(<-``#24```TBQ``*X?P`"0S@``D1(``-I0``#:+$``DO^``(</0`#
+M2)```TB5``*X?P`"0`@``D1(``-HD``#:)4``KP"``)+_``"'$<``TBH``-(
+MK0`"N'\``D`(``)$2``#:*@``VBM``-`*``#_P```K@,``)!&``"'%0``K5$
+M``(];``#2`@``K@0``)!&``!W%0``CW0``(W30`"2_X``AQ;``-(F``"M,``
+M`F,T``)#-``#:)@``KP"``)+_``"'&,``TBP``*TP``"8S0``D,T``-HL``#
+M0DD``K@!``/<@``#2I0``XA&``.H@@`#Z,```LS(``/8P``#U!X``C+7``-(
+M0``"N'\``DO^``/P`0`"01@``KP"``)+_``#\`$``D(H``-H0``#2`@``K@0
+M``)!&``!W(<``T`H``*\!``#_P```DS"``/P0P`"/;$``_0```/P00`"/A8`
+M`D[N``'<B0`"O`@``CWG``!YNP`#_P```_\```)+_@`#\`0``TB8``*T/P`"
+M0S0``VB8``*\`@`"2_P``_`$``-(L``"M#\``D,T``-HL``#2$```K@@``)(
+M@0`"'*```CXS``*V`@`#:#$``TA```*X`@`"2(```ARG``-(/0`"/C,``V@Q
+M``-("``"N!```D$8``/P!``#2$```KP@``/DPP`"/><``T@$```B+``#_P``
+M`_\```/!%``#:`0``'F[``*X```"O`(``TA4``)+_@`#\`$``K@#``)+_``#
+M\`(``KP,``)HC``#P(@``D,X``-H5``#@/@``(("``-"20`",L```V))``/L
+M```#2`@``K@0``)!&``!W-H``DO^``/P!``#2E0``K0/``)@!``#:E0``KL"
+M``)+^P`#\`0``TI8``*T#P`"8`0``VI8``)+_@`#\`0``TI4``*T\``"8`0`
+M`VI4``*[`@`"2_L``_`$``-*6``"M/```F`$``-J6``#2`@``K@0``)!&``!
+MW/@``DO^``/P!``#2E0``K0/``)A%``#:E0``KL"``)+^P`#\`0``TI8``*T
+M#P`"810``VI8``)+_@`#\`0``TI4``*T\``"810``VI4``*[`@`"2_L``_`$
+M``-*6``"M/```F$4``-J6``#2`@``K@0``)!&``#\`$``^P```)+_@`#\`0`
+M`TI4``*T`0`"8B0``VI4``*[`@`"2_L``_`$``-*6``"M`$``F(D``-J6``#
+M[````T@(``*X$``"01@``=TI``)+_@`#\`0``TI4``*T_@`"0B0``VI4``*\
+M`@`"2_P``ATI``-*6``"M/X``D(D``-J6``"2_X``_`$``-*5``"M`\``D$4
+M``-J5``"O`(``DO\``(=-@`#2E@``K0/``)!%``#:E@``T@(``*X$``#_P``
+M`D$8``'=2``"2_X``_`$``-*5``"M/```D$4``-J5``"O`(``DO\``(=2``#
+M2E@``K3P``)!%``#:E@``DO^``/P!``#2E0``K0/``)`!``#:E0``KP"``)+
+M_``"'54``TI8``*T#P`"0`0``VI8``-("``"N!```D$8``'=9@`"2_X``_`$
+M``-*5``"M/```D`$``-J5``"O`(``DO\``/P!``#2E@``K3P``)`!``#:E@`
+M`KP(``(]YP`"M40``CUL``(^/P`#[````K?\``*V,P`"M````TC(``*@_@`#
+M\$$``K0"``*\`@`"H/P``_!!``*T`0`"810``VC(``)@!0`#:,@``_\```)`
+M!@`#:,@``KP"``(]YP`"01<``VC(``/L```#2`@``K@0``)!&``!W90``DO^
+M``/P!``#2)@``K1_``)")``#:)@``KL"``)+OP`#\`0``TBP``*T?P`"0B0`
+M`VBP``-).``#A/(``\!$``)")``#:3@``^P```-).``#A/(``F(D``-I.``#
+M2`@``K@0``)!&``#\`$``^P```)+_@`#\`0``TB8``*T@``"8B0``VB8``*[
+M`@`"2[\``_`$``-(L``"M(```F(D``-HL``#[````CWJ``-(5``#C/@``F(L
+M``-H5``#270``KS?``)$+``#P5,``CXS``-H,0`",9X``KP0``)D3``#:#$`
+M`C&>``-(5``"O)\``D(L``-H5``#270``_\```/!0@`#P5,``CXS``-H,0`"
+M/@```K5```(];``"/=```^P```*[_``"2OX``_`(``-((0`#_P```F5>``-H
+M(0`#:HD``D5;``-H(0`#:HD``KH"``)*KP`#\`@``T@E``/_```"95X``V@E
+M``-JC0`"15L``V@E``-JC0`#[````PS.``'=YP`#[````D'^``(=]``#0ZX`
+M`K#O``/_```"2[```DJP``))L``"2+```V.N``*Q`@`"0?$``AVR``-#[@`"
+ML.\``_\```)+L``"2K```DFP``)(L``#8^X``^P```)!_@`"'@H``T.N``*P
+M$``#_P```FNP``)JL``":;```FBP``-CK@`"L0(``D'Q``(>%0`#0^X``K`0
+M``/_```":[```FJP``)IL``":+```V/N``/L```"/C,``K8"``-H,0`"M@$`
+M`TF>``*\$``"9*P``\%;``-H,0`#29H``KP"``)DK``#P5L``V@Q``/_```#
+M270``KP0``)D+``#P5,``V@Q``(QG@`#P,P``D1,``-H,0`",9X``\%*``/!
+M6P`#:#$``^P```/!;@`"MP,``DW^``/P`@`"O0(``D=]``*]`@`"3?T``_`"
+M``*]`0`"1WT``^P```*X```"N0```KH```*[```#2L$``KR```/!;P`#Z'``
+M`VK!``-B@@`#0P```F9L``*WZ``#:L$``V,```-#*``"M_<``VK!``-C*``#
+M0RP``KQ_``)&;``"MQ\``VK!``-C+``#Z&```^AP``-JP0`"L@(``K$#``*P
+MK``"0_X``_`!``(^J``"L.P``D/R``/P`0`"/J@``K(/``*Q!``"L````D/^
+M``/P`0`"/J@``K,"``*P0``"0_,``_`!``(^J``"L@\``K$$``*P@``"0_X`
+M`_`!``(^J``"LP(``K#```)#\P`#\`$``CZH``)/_@`#\`4``T<T``-'.0`#
+M_P```V<T``-G.0`"LP(``D/S``/P!0`#1W0``T=Y``/_```#9W0``V=Y``/H
+M@``#Z)```^B@``/HL``"3_X``_`%``-E+@`#93(``V4V``-E.@`#93X``K,"
+M``)#\P`#\`4``V5N``-E<@`#978``V5Z``-E?@`#2L$``_\```/!;P`#Z'``
+M`VK!``-F`@`#9H(``^A@``/H<``#:L$``^P```/<$``#V````]!>``/!P@`#
+J_P```]1>``/[```#T%X``PS.``'>K0`#[````_\```/_```#_P```_\`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/OLAND_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_me.bin.uu
new file mode 100644
index 0000000..13f177c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_me.bin.uu
@@ -0,0 +1,194 @@
+begin 644 OLAND_me.bin
+M?$"``8@```#40`!_?$"``8@```!\0,`!S$``*,Q``"E\0(`!B````-A``![$
+M$``A)1```I4`__Y\00`!Q!P`)L0@`"38```<S(``"\W!H-G.`:#:V$``',04
+M``>50``"V4&BI,0;``+8```;S8``&L`^``3,`:'TS#T@!,0]``',```%V$``
+M&]A``!]\0(`!B````,Q!+@',02X"S$$N`\Q!+@!\0(`!B````'Q`P`&,``5Y
+MS$$N`<Q!+@+,02X#C``%?<Q!+@!\0(`!B````'Q`P`'$&``PQ!P`,7W90`)\
+MU@`.Q"0`%9I`__^:```#S,``%(````#`*(``SH$P2L0\`'\DD``"P"H``7Q`
+MP`&5```#Q!0`,'S4P`$4S``"S,$EQ]1I)<A\0(`!B````'Q`P`$8T`'H),P`
+M?WQ!0`%06``@?5E`&GQ!@`%07``@?9V`&GQ!P`%08``@?>'`&GQ"``$E)``!
+MS,``(]%``"31@``ET<``)MA``">60``,Q"@`+)J`___()``M?EZ`#)J`_YP2
+M+``&!NP``0KL``&:P/__V$``)X```&#$*``LFH#__WQ`@`&(````?$#``<00
+M`##,027,?04``<Q!)<_-`27.?$%``230`'\56``0)50`_\T!)=/-@271S4$E
+MT,Q!)=)\04`!?$&``1C<`#`8X``Q&.0`,ACH`#,8[``TS$$EULQ!)=?-@275
+MS4$EU,`R``260``AEL```LPQ)=G,,278EH``!);```+,,27;S#$EVGP#`!&6
+MP``#Q#$``5,P`"#$-0`!?S<`&M,``!:6@``(?`.`$9;```/$.0`!4[@`(,0]
+M``%_OX`:TX``%Y7`_V":P``$?7<`#)<`_^2`````4;@`('^7@!I_.X`,EX#_
+MWX````"6`/]6S#$ES<R```O$-0`!ET#__'Q`@`&(````Q"``)GQ!0`'&)P/D
+ME4```LP```',```)"F0``<Y@`^1\0(`!B````'Q`P`'`%@`$)-#__WT5``K,
+M@``+S!$``!C8`#X4W``?Q"$``7Q"0`&5P``%?E:`"LP```O,*0``Q"4``7XF
+M``E\0L`!E8``!7[7``K,```+S#$``,0M``%^+@`*)1#__\P```O.$0``@```
+M`'Q`P`',0```@````,R```O-02)=S0$B7,Q!H?Q\0(`!B````,R```O,02)7
+M?$"``8@```#,02)<S$&A_'Q`@`&(````P`X``<Q!(ES,0:'\U$VA_7Q`@`&(
+M````S(``"\Q!(EU\0(`!B`````A,``%\00`!S(``"WQ!0`$E6/__&5P#\!5@
+M`!7-@:$"S<$B5LX!(ER4P``$S0&A_`C,``&```#TS0&A_,P!H0)\0(`!B```
+M`'Q`@`'`*@`"?$#``7Q!``%]*0`*))0``228``8DG`,`%=P`"'Q"``%\0D`!
+MP"X`!,R```N50``.!?`B6'\O``K,,0``Q"D``<S!(6G-`2%JSH$A:S&T``+,
+M`2%LQ#``&9<`__^70``*@``!,#&T``*70``'P"X`!`7P(EA_+P`*S#$``,0I
+M``&```$P,;0``)=```-^`H`!@``!,#&T``270/[5(F0`,,X!(6W.02%NQ"H`
+M`,0L``DQ\```,?0``3'X``*:P``"C``#7-J!HJ27```#SH&BMX````"70``#
+MSH&BNX````"7@``#SH&BOX````#.@:+#@`````08``"```%%!!@``<0D`"9\
+M0,`!QFL#Y!C0`#`DU`#_!J@``<ZD`^2:0``2Q#@`!]A``![$/``A)_P``I?`
+M__[,@``+EX```ME!HJ3$/P`"S\``&L`^``3,`:'TS#T@!,0Y``',```%V$``
+M'\U!H-K,@``+S4$N%)F```+,```"S4``"'Q`@`&(````?$#``1C0`>@8U``P
+M&-@`-`4H`6U\0@`!?$)``94```>&@```@``!AX```:N```'!@``%=8```7T1
+M5``0?A8`"LR```O480``E8#^B<`Z``3,.2%`Q#D``7Q`@`&(````$50`$%)D
+M`"!^)@`:S4``'=1B``"5@/Y^Q"``'9H`__]\0(`!B````-PZ``"90``;)YP`
+M`97```T+N``!S@$A:<Y!(6K,02%KS`$A;)N```.5@/YO@``!GU)D`"!^)@`:
+M1B``!%8D`"`B9``RS@$A:<Y!(6H+N``"S$$A:\Q!(6R;@/_]E8#^8L0P`!F7
+M`/__?$"``8@````+N``!S@$A:<Y!(6K,02%KS`$A;)N`__N5@/Y7@``!GU)D
+M`"!^)@`:F4``"M(``"O40``LV$``+8P`!8:5@/Y.Q#@`+YN`__]\0(`!B```
+M`-PV```+=``!T@``*\Q``"S80``MC``%AIM`__N9@/_U?$"``8@```#$'``P
+MP"H``7X>``$6(``"S@$EQ]1I)<B5@/XYP#H`!,PY)<O$.0`!?$"``8@```!\
+M0,`!?$$``1D4`#V90``*Q!P`#97`___,P2$`S0$A`<S!(0+-`2$#V0&BI'Q`
+M@`&(````S,$A=<T!(7;$(``.E@#__S(H``(R+``#FH``!)K```7,```,@```
+M`,P```R```':P#X`!,P],'[$/0`!,^@``9?`_A::@`.-!#A``,P```'/@3!*
+M@``%>'Q`P`%\00`!0-0``\U!(ES-`:'\P!X``7Q"``$(S``!!B0``08H``+.
+M':']SEVA_<Z=H?V8P/_Y?$"``8@```!\0,`!)-```13,``%\04`!?$&``<R`
+M``N5```&(9@`,,U!(6W-@2%NQ!X``(```A#`(@`$?A8`"LPA``#$'0`!?$)`
+M`7Q"@`&8P``#S>4``(````#.02%ISH$A:LW!(6O,`2%L?$"``8@```!\0,`!
+M?$$``7Q!0`%\08`!?$'``1BD'^@R:``\!"```9:```A\0@`!.C```T(@``*;
+M```"!"``0`0D``&```(L?@)``0ID``',``!_FD#__B3L`!#,@``+FL``"<`J
+M``3$+``0?I*`"LP```',*0``SL``$,0Q``&```(^(50`,,T!(6W-02%NQ#(`
+M`'\?``DD]``'!W@"0I=``">'@```@``"2H```D^```)4@``"68```EZ```)C
+M@``":'\;@`\4I``(EX``'29D`/^```)Y?QN`#A2D``B7@``8)F0`_X```GE_
+M&X`,%*0`")N``!,F9`#_@``">7\;@`T4I``(FX``#B9D`/^```)Y?QN`#Q2D
+M``B;@``))F0`_X```GE_&X`.%*0`")N```0F9`#_@``">12D``@F9`#_,F@`
+M/!3L``B:@/V4?$-``7Q#@`%\0\`!S```"Y;```;/02%ISX$A:L_!(6O,`2%L
+M@````,_U``"`````,F@`/)J`_['40`!_@````'Q`P`%\00`!P!X``144`!+`
+M(@`"P"8`!)5```3`)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!
+M(6G-`2%JFH``!\U!(6O-@2%LEL#];\0P`!F7`/__@````,@4`!A56``@S4$A
+M:\V!(6R6P/UG@``"DGQ`P`%\0(`!%)0`$!%4``4DB/__$(@`!7Q`P`$4T``0
+M),S__\R!(73`&@`$*9@;I,P9``#$&``!)9@?_WT9``Z9`/U5?8T`#ID`_5/$
+M'`/GR"``&'V=``Z5```)Q"0#Z,0(`^E0B``@?*9`&GY60!%^8D`25F0`/Y9`
+M_4?-@`/GS@`#Z%8@`"#.``/IE,```(````!\00`!?$%``<Q```/,0``$S``#
+MY,P``^7,``/FP`Z``'Q"0`%\0H`!@````'Q`P`$8T`'H!2@"T1S,_@C,@``+
+ME0``"8:```"```+<@``"ZX```O*```+Y@``"_X```R&```,_S,&BI'Q`@`&(
+M````P!((`'Q!0`%\0@`!?0S`"L`2``056``#%5P`#7W1P`D2(``3?AY`"GY.
+M@`K.@:*DS8&A_GQ`@`&(````!!`A&,04``N50/__U%$``,S!HJ1\0(`!B```
+M``00(0;$%``,E4#__]11``#,P:*D?$"``8@```#80``/S,&BI,00``^9`/__
+M?$"``8@````8T``T$10`%'Q!@`%]1<`*?$(``1GH`/@RJ``"?$)``<0L``V6
+MP/__FH``",V!(0#-P2$!S@$A`LY!(0/,P:*D?$"``8@````=_/\8S8$A`,_!
+M(0'.`2$"SD$A`\S!HJ3$+``-EL#__\V!(0#/P2$!S@$A`LY!(0/,P:*DQ"P`
+M#9;`__^```,*)-@``7Q!``%\04`!$9P`$'Q"``%]74`*%60`'29D``*5@``)
+MQ#P`'Y?`__^:0``-Q"@`,!:H``)^*@`!S```%8```SG$/``@E\#__YI```7$
+M*``P%J@``GXJ``',```5S0$A6,U!(5G.`2%:S,&BI'Q`@`&(````&-``-!$4
+M`!0DV``_E0#_E\0D``V60/__-9P`!LP!(0#-02$!S`$A`LP!(0.9P``#V0&B
+MI(`````$(``4S@&BI'Q`@`&(````?$#``130`!T8U``\F0```H````#-0``<
+M@````'Q`P`&,``-<?$"``8@```#80``>Q#P`(2?\``*7P/_^S(``"]E!HJ3$
+M/P`"S\``&L`^``3,`:'TS#T@!,0]``',```%V$``'Y````!\0,`!!#P`(LR`
+M``O/P:*DS```!GQ`@`&(````P!(``7Q10`K,@``+U%4``'Q`@`&(````?$#`
+M`5!0`"!\T,`:51P`/WQ!0`%\08`!S(``"]#``(.5P``=Q#P`"9O```*,``-<
+MV```'L0@`"$F(``!E@#__L`F`"@J9'_#S(``"\Y!(7S`)___SD$A?<0H`"3.
+M@2%ZS`$A?L`J``0$+``(?L,``0LP``&;`/__S(``"\PI(7_$-0`!%W@`'W[#
+M``&;@/_YV```'Y6`_&.,``5YW8,```5<(`#,```+U%T``(``!8%\0,`!4%``
+M('S0P!I\04`!?$&``<R```O0P`"$E8#\58P`!7G=@P``!5R@`-1=``"```6!
+M?$#``5!0`"!\T,`:?$%``7Q!@`',@``+T,``A96`_$B,``5YW8,```5<+`#4
+M70``@``%@<R```O40R``?$"``8@```#,@``+U$.@`'Q`@`&(````S(``"]1#
+M+`!\0(`!B````'Q`P`%\00`!?$%``93```)\08`!?$'``7Q"``&5```*E4``
+M"<R```O,0RP`S<,L`,R```O,0RP`S@,L`'Q`@`&(````Q"0`'LQ``'_,0`!_
+M&F@`,'Q`@`%\0,`!EH#\']B``"Y\0(`!B````,R```O,0Z``?$#``008``'=
+M@P``C``%>=1#H`"```6!)(S__\R```O430``?$"``<R```N(````?$#``1C4
+M`#`8T`'H&/P`-"3,``\$Z`/\?$&``7Q!P`&4P`!*AH```(``!!2```0<@``$
+M)8``!#2```0'@``$"H``!`R```0.@``$$(``!!)1W``@?9X`&H``!%/((``M
+M@``$4\@@`!:```13R"``%X``!%/((``8@``$4\@@`#*```13F4```R'<`#"`
+M``08(=P`4,V!(6W-P2%NR"(``(``!%-1W``@?9V`&M@``"/1@``DV$``)\0H
+M`"R:@/__R"``+H``!%/$'``PP#(`!'V=@`$5F``"S8$EPLPQ)<.50``#S(``
+M"\PQ)</$(0`!E4``),0E``%29``@?B8`&H``!%,QK`@`Q#0`$);```/,```!
+M@``$1CFL"GP]L`IWFL``!)<```/,```!@``$1CFL"MP]L`K9FL```Y<```+,
+M```!@``$1L0T`!#,@``+P#H`!'VY@`K,&0``E4```P68``',&0``Q"$``95`
+M``7$)0`!4F0`('XF`!K/0``0!2@$5WQ!@`%\0<`!E0``!X:```"```2(@``$
+MDH``!*"```1K@``$?<0T`!#,@``+SAD``)5```0%F``!5B``(,X9``"7P/N<
+MP#H`!,PY(4#$.0`!ST``$'Q`@`&(````,:P(`,0T`!"6P``#S````8``!%XY
+MK`I\/;`*=\0T`!":P``$EP```\P```&```1>.:P*W#VP"MF:P``#EP```LP`
+M``&```1>4=P`('V=@!K8```=SAH``)5```0%F``$5B``(,X:``";P`"0?$"`
+M`8@```"50``"(=P`,E8D`"#-@2%IS<$A:LX!(6O.02%LF\#^`WQ`@`&(````
+M4=P`('V=@!K1@``KS@``+)5```-6)``@SD``+-A``"V,``6&E\#[9<0X`"^;
+M@/__?$"``8@```#$'``PP"H``7V=@`$5F``"S8$EQ\XI)<B50``#5B0`(,YI
+M)<B7P/M7P#H`!,PY)<O$.0`!?$"``8@```#$%``</5@`!)F`__[,```-?$#`
+M`2A0@``5%``?&1@`?1D<`'3$(``P,9@``3'<``&5@``"?.#``7Q"0`&5P``"
+M?F)``<S!(8#-`2&!SD$A@LQ!(8/,02&$E4#[.\04`!R90/__?$"``8@```#`
+M%@`$Q!``)LR```O,52%`Q!D``<P0`_=\0(`!B````,0@`";8```>Q`P`(23,
+M``&4P/_^QB<#Y'Q`P`',@``+S,$A?,Q!(7W$&``D?$$``7Q!0`&60``"S8$A
+M>LT!(7[`-@#`P"H`!']/0`D17``!!=P``9=``!3,*2%_Q"4``1IL`#Z6P``'
+M$5P``07<``$)W``!F<#__\R```N```3H%W0`%R@L`&";0``"*"P`0,[``"/8
+M0``GQ#0`+)M`__^```4`"=P``9G`___,@``+S"DA?\0E``$6;``?$5P``07<
+M``&:P/_X%/P`']@``!^;P/KZQ!``)LP0`_=\0(`!B````'Q`P`%\00`!%1@`
+M'U$4`"`9'``QF8``",T``!U]34`:U%8``)7`^NS$(``=F@#__X````#<.@``
+MP"8`!,S!(6E])0`*S0$A:@NX``+,02%KS$$A;)N`__V9P/UQ?$"``8@````D
+M3`#_S$P#`'Q`@`&(````Q"``)L1/`P#,@``+S.$A18````#,@``+VL&BI'Q`
+MP`%\0(`!B````,0,`!J8P``#V$``+X``!3+80``P?$$``7T!0`$55``!)50`
+M`9E```DE$``!E0#ZP\@4`#250``%R!@`&Y6```-]E<`.E<#ZO<@@`#/2```R
+MV```'L0@`"$F(``!E@#__L`F"$#,@``+SD$A?,P!(7W$*``DSH$A>LP!(7[`
+M*@`$!!0`"'U!P`$H+`!`SL``(]A``"<)W``!F<#__\R```O,*2%_Q"4``19L
+M`!]]0<`!FL#_^<0T`"R;0/__V```'WQ`@`&(````Q`P`$S#0``&5```#S(``
+M"]L!HJ3,0``.Q`P`$L00`!,PU```/1@``7U9P`K80``QF<#_^MA``!/0```R
+M?$"``8@```#`#@$`S````<S!,$J```5XV$``$<0\`!&7P/_]D````-@``!'$
+M/``1F\#_^9````#8```1Q#P`$9O`__5\0(`!B````-B``![$/``A)_P`!)?`
+M__[`.``OP#X`!,^!(?C,/2'YQ#@`)@0\``5_^X`"Q#T``7_[P`4G_``!F\#_
+M]MB``!^0````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0/M`!```@`1``4`$@`*`!4`)0`6`"L`%P"Q`!L`-``<`$$`'0!O`!X`
+M3``A`+L`)`#9`"4`V0`G`.,`*`#6`"H`WP`L`-D`+0#C`"X`YP`O`.T`,`#Q
+M`#(!1``T`0,`-0#C`#<!90`X`-D`.0'-`#H!\``[`@``/`(;`#T"?0`^`IL`
+M/P%"`$`#\P!!!*\`0@3*`$,$T@!$`L``10(;`$8"RP!'`LL`2`++`$H#40!2
+M`U@`4P-K`%<#<@!?`[$`8`-X`&$#I`!H`[X`:0/"`'(#R@!S`^4`=@/&`'<#
+MQ@!Z!0L`?04D`'X%*`"%!2T`A@4R`(H%9`"+!60`#P5U``\%=0`/!74`#P5U
+M``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`
+M#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`#P5U``\%=0`/
+:!74`#P5U``\%=0`/!74`#P5U``\%=0`/!74`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/OLAND_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_pfp.bin.uu
new file mode 100644
index 0000000..6ad4abe
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_pfp.bin.uu
@@ -0,0 +1,194 @@
+begin 644 OLAND_pfp.bin
+M?$"``8@```#,@```U$```'Q`@`&(````S(```,S```#40```?$"``8@````D
+M3``/,.@``B20``*:@``,?$%``5!8`"!]E<`:F,```]'``!F`````F0```]'`
+M`!J`````T<``&X````#$(``5QB0`"I9``:U\00`!?$%``<R```#,P```S0``
+M`,U```#-```MS4``+GQ`@`&(````S(```,Q```#,```2@``#\<Q``"A\0(`!
+MB````,@,`!M\Q0`1T0```]C```/,@```S````,Q```!\0(`!B````,@,`!I\
+MQ0`1T0```MD```)\0,`!?$$``7Q!0`'$&P`#Q!\``\0C``/$)P`#E8#_OI7`
+M_[W$*``0S```%)J```3$,``%SP```,P```#$*``)("P`?B+LSD@:J``PSL``
+M`-@```#-@```S<```,X```#.0```S,```,T````<B``0EH```MB``"+,@```
+MS4```'Q`@`&(````R`P`&GS%`!%\04`!?$&``7Q!P`%\0@`!?$)``97`_YS1
+M```"V0```@G<``'$*P`#Q"\``\0S``/$-P`#EH``&9;``!C$#``0S```%)C`
+M``3$#``%S,```,P```#$#``)(#@`?B.XSD@8S``PSX```-@```#.@```SL``
+M`,\```#/0```S4```,V````<B``0E,```MB``"+,@```SD```)7`_WM](0`1
+M@```94'H``31```"SH```@G<``'$*P`#Q"\``\0S``/$-P`#EH``&9;``!C$
+M#``0S```%)C```3$#``%S,```,P```#$#``)(#@`?B.XSD@8S``PSX```-@`
+M``#.@```SL```,\```#/0```S4```,V````<B``0E,```MB``"+,@```SD``
+M`)7`_U=](0`1@```B\@,`!I\QL`1TL```ME```)\0,`!?$$``7Q!0`'$&P`#
+MQ!\``\0C``/$)P`#Q"L``Y6`_TB5P/]'S```)M+``"?$+``0S```%)K```3$
+M+``%SL```,P```#$+``)&NP`,"`P`'XC,.Y(SP```-A```#-@```S<```,X`
+M``#.0```SH```,S```#-````'(@`$);```+8@``BS(```,U```!\0(`!B```
+M`,@,`!I\Q0`1?$%``7Q!@`%\0<`!?$(``7Q"0`&5P/\CT0```ME```()W``!
+MQ"L``\0O``/$,P`#Q#<``\0[``.6@``<EL``&\P``";1```GQ`P`$,P``!28
+MP``$Q`P`!<S```#,````Q`P`"2`\`'XC_.Y(&,P`,,_```#80```SH```,[`
+M``#/````ST```,^```#-0```S8```!R(`!"4P``"V(``(LR```#.0```E<#^
+M_GTA`!&```#>Q!@`""68``%\0D`!?$*``96``N52K``@?N;`&GQ`P`%\00`!
+MQ!P`$9G`__\<B``0((@`<!#4``)^U4`1T4```\T```/,@```SD```,Z```#,
+MP```W#H``,T```"7@/[D?$#``7Q!``&```$2Q!``#\0<``29```$S```$LW`
+M``#,````Q!@`""68``*```$')(P``L00`!#$&``(F,``")D```7$'``%S```
+M$\W```#,````&9@`,(```0<9F``X@``!!\0<``3-P```S````,R```#40```
+M?$"``8@```#$'``$S<```,P```#(#``9S(```,Q````04``"?0T`$544`"#1
+M```#V$```\P```!\0(`!B````,0<``7-P```S````,R```#40```?$"``8@`
+M``#$'``%S<```,P```#$)``DR`P`',93`^C,@```S$```%$0`"!\T,`:?,4`
+M$544`"!]18`*S0```,V```!\0(`!B````'Q`P`%04``@?0U`&M%``!C,```E
+M?$"``8@```!\0T`!R!P`&,08`!<<B``0((@`,'Q!0`%]6,`$?-S`$530`"!\
+M04`!S(```,]#HI[,PZ'ZS0.A^<U#HIW-0```S$```'Q`@`&(````?$-``1R(
+M`!`@B``P?$#``7Q!``%\04`!S(```,]#HI[,PZ'ZS0.A^<U#HIW-0```S$``
+M`'Q`@`&(````?$#``230``',PZ*?V$``%Y4```+8@``7S(```,S```!\0(`!
+MB````'Q`P`',@```S,.BHLS```!\0(`!B````'Q`P`$4U``?S(```'Q!``&5
+M0``"S,``'Q48`!_,P```S0```)6```+-```@S```?X```_$@"`!^((@'Z,0@
+M`!4<J``0SJ``!'Q!``%05``@?$&``08D``'.0``5%9P`&'T5`!K-X``)S:``
+M"]$@``'-H``!Q"P`)%4P`"#1```<SRP#Z)H```3$)``CFD```B'<`##-P```
+M@``#\<0@`!7&#``*'*@`$)3```/.H``&@``!KLP```B```'*Q"``%7Q!@`$*
+M(``!QA0`#<88``I]68`*S@``%96```3,H``&S6``!H```_',H``$S6``!(``
+M`_%\0,`!%-``'C$4``&5`/XJE4`"$1C0`>@8U``P&-@`-`4H`>5\0@`!?$)`
+M`94```>&@```@``#]8```_6```/U@``#]8```?,15``0?A8`"LU``"'480``
+ME8#^$<0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``"'48@``E8#^",0@`!.:
+M`/__?$"``8@```!\0,`!?$$``7Q#@`%\0\`!41``(%/\`"!_OX`:?-#`&@0<
+M``C3@``"V(```M#```+-P``"!!P``@0@``%\`D`!Q!<``\0;``-1F``@?5E`
+M&L0K``/$+P`#Q#,``\0W``,)W``!4NP`('ZN@!I3=``@?S<`&G\K0!)^=D`1
+M5J@`/U<P`#]^LH`)?BH`"9G`__&6@/_D4_0`('][0!I]94`155@`(,P``"'-
+M=@``S;8``,0@`!.:`/__?$"``8@```#$(``D?$#``7Q!``',X`/]S2`#^E$4
+M`"!\U,`:T,```A44`!\9&`#PF4```@0T```O7``!?78`"7U>0`F9@``$S```
+M`LP```V```/Q%9@``14L``@F[``!F8``,Q4P``R6```#S````H```_$$%``(
+MS4```B<P``$H*``!!#@`"`0\``+$%P`#Q!L``\0?``/$(P`#?5U`#7VAP`U]
+M74`*%A``'Q6<`!]]'0`)?1=`"7Z2@`D+N``$"_P``9M``!*;P/_QQ"``),8/
+M`_W&$P/ZFH``"<P```V;``&.410`('S4P!H$%``(T,```LU```*```)+S```
+M#9;``8;,```.@``#\<P```V:P``"S```#I>`_8\+N``!Q#\``YN`__V`````
+MS```#I9```/,```"@``#\=H```+$"P`#Q`\``\03``/$%P`#Q!L``\0?``/$
+M)P`#Q"L``Q7\`!\6L``??_/`"13P`!]_\\`)%7``'W_SP`E]B(`"?<S``I?`
+M``Q^40`"?I5``GR0@`Q\U,`,?(]`"9K```(LM``!S```#9M``5S,```.@``#
+M\<0@`"3&#P/]QA,#^E$4`"!\U,`:T,```H```GI\0,`!%-``'C$4``&5`/UD
+ME4`!2QC4`#`8T`'H&/P`-"3,``\$Z`*L?$&``7Q!P`&4P``2AH```(```K:`
+M``/U@``#]8```_6```*S@``#]5'<`"!]G@`:@``"PU'<`"!]G8`:F4```\6B
+M``"```+#R:(``(```L/%H0``E4``!068``'%I0``4F0`('XF`!H%*`+'?$&`
+M`7Q!P`&5```'AH```(```_6```/U@``#]8```_6```+7V```(<X9``"50``$
+M!9@``58@`"#.&0``E\#]+<0Y(4!\0(`!B````%'<`"!]G8`:V```(<X:``"5
+M0``$!9@`!%8@`"#.&@``F\#_&GQ`@`&(````?$#``7Q!``$9%``[E4``&\04
+M`!(]6``"F8#__AD<`'T9(`!TQ!0`)3'<``$R(``!S```(<P``",I$(``E<``
+M`GS4P`%\0D`!E@```GY60`',P2&%S0$AAA44`!_.02&'S$$AB,Q!(8F50/T$
+MQ!0`$IE`__^`````S(```,S```#-````U$```'Q`@`&(````Q"@`)-AH`_?,
+M@```S$```,0D`'Z60`#JQH\#]YC`__U\0(`!B````,0H`"3$,``/Q#0`!)J`
+M``6;```$S```$L]```#,````?$#``=AH`_?,@```S,```-1````4T``?F0``
+MTX```PK,@```S$```,Q```#,0```?$#``<S``!;,P```U$```'Q`@`&(````
+M?$#``13<`!T8V``\S(```,S```"9P``#F8#\T(```_'-@``D@``#\7Q`P`%0
+M4``@C``#67S0P!K$)``5Q!0`)'Q#@`&60``(Q-8``)E``!G?@P``SZ0`#XP`
+M`UW40`!_@````,5?`^Z5P/__V%0#\<5;`_25@``#V!0#\9F`__S%7P/N/>``
+M`IH```?%8P/KF@``!=^#``#/I``/C``#7=1``'\)W``!S=0#[M@4`_&,``-=
+M?$"``8@```#8```>Q#P`'IO``)J0````V$``'L0\`!Z7P`"6D````(P``UG$
+M(``5?$#``<`V_P#$$``6P#`__WSU0`E]48`)?8&`'7SS@`F9@``&WX,``,^@
+M``^,``-=U$``?X````",``-=?$"``8@```!\0,`!%-P`")G```7,@```S,``
+M`-1```"`````?$$``5!4`"!\08`!?$'``7Q"``$Z,``#$B```IL```($(``(
+M!"0``8```X=^`D`!"F0``<P``'^:0/_^).P`$)K```/%,0``@``#D'T5`!K%
+M,@``)/0`!P=X`Y1_'P`)AX```(````"```.<@``#GX```Z*```.E@``#J(``
+M`ZN`````?QN`#Y>`_&.```.M?QN`#I>`_&"```.M?QN`#)N`_%V```.M?QN`
+M#9N`_%J```.M?QN`#YN`_%>```.M?QN`#IN`_%1^`D`!@``#A\0<``3-P```
+MS````,R```#40```?$"``8@```!\0,`!)-``!C$0``;$%``/F0``",P``!+$
+M)`!^ED``.)E```3$'``$S<```,P```#,@```S,```-1```!\0(`!B````'Q`
+MP`%\00`!%1@`'\T``"%1%``@F8```]1-``"`````?4U`&AD<`#'45@``E<#\
+M+L0@`!.:`/__?$"``8@```!\0,`!?$$``134`!XQ6``")-P`_Y5```29@/PC
+MS1P#`(````#,@```S,```,T```!\0(`!B````,0@`"1\0,`!Q-,#`,R```#,
+MP```S```(<TA(4%\0(`!B````-1``']\0(`!B````,0D`'Z60``#?$"``8@`
+M``"```/U````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P.O``4!J0`&`38`!P$]``@!2P`)`5(`$`/N`!$`"P`2`"<`$P`K`!8`
+M+@`D`#<`)0"L`"8!8P`7`<L`(@,T`",#80`G`7T`'P']`"`"+0`H`9P`*@&,
+M`"P`70`O`98`,0/N`#(!PP`S`^X`-`.V`#4!:@`X`-8`-P'9`#P#=``_`:L`
+M0`*?`$$"X@!"`P8`0P,0`$0#(`!*`RH`50.R`%\!*0!@`04`80$@`&D!.0!S
+M`4``=@%.`'<!50![`\<`?0/7`'X#Y0!_`^X````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/OLAND_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_rlc.bin.uu
new file mode 100644
index 0000000..ea570ab
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/OLAND_rlc.bin.uu
@@ -0,0 +1,186 @@
+begin 644 OLAND_rlc.bin
+MQ`@`)S",``*8P`%[,(P``9C``7HPC``#F,`"'8```:XPC`!`F,`"!3B,`$"4
+MP`'L"(@`0'RMP!`5W``&C```&7Z"@!Y^LH`)C``!V":,`/]_`4`*C``"47P:
+M0`K.0P!A@``"#L`>B`",``!(?!<`"I````#`'H@`C``"8WP4@`I\%H`*C``"
+M^7P.P`K.@P!:D````"@X``",``!Z*#@``8P``QDH#```C``#$,P``"V```+-
+MC```<<`4,17/E0``P!0Q%L]5``#`%#$8SQ4``,`0,1W%$0``)1```9D``+K`
+M%#$7S]4``)`````FJ`#_%.0`!!)D``@DW``/?ES`"LS``"/.@``,@``"S244
+M`/_`"H@`?(R`"LU)``"0````*<@B;\2)```IS")PQ,T``'R-0`I]04`>%50`
+M$)````#`"IP`*(@DU,`,``',R0``P`J,`"B()-;$C0``)-#__Y````#`'##0
+MS9T``,`<,,[%W0``?=7``GW1P`^5P`*I?0+`"I````#$*P`.EH`":HP``:B`
+M``+-S`,`5<P#`%_`"##&Q(D``,`,,,7$S0``?,B``HP``63-0P!@D````)``
+M``"7@``$P!`Q&<4=``"9P/_^ET``!,`0,1K%'0``F<#__I````#`,#!XS[$`
+M`)````!]@,`*P!0``'V!0`V0````"NP``8```=R6P`'T*NP``<[``#"60`'M
+MQ"``')8``>O,```PD````,0(`!R4@`)!S8,``(```FC$"``/E(#__\0K``*,
+M``$=P`Z``'^/@`K`#@``?T]`"B@\`)`3_``0*_P`_XP``"W`'#$%Q>T``!+L
+M`!@F[`#_P"0``<`@``",``"#S8``$I````#`&``!S`,`#L`-___,PP`>S,,`
+M8<`(!0`H#```S(\`0<`*("`HB`\%!,P``<R/`$'`"C`P*(@>#P3,``',CP!!
+MP`I`0"B(*!X$S``!S(\`0<`*0$`HB#(H!,P``<R/`$'`"F!@*(@\,@3,``',
+MCP!!P`IP<"B(4#P$S``!S(\`0<`*@(`HB%I0!,P``<R/`$'`"H"`*(A?6@3,
+M``',CP!!P`J`@"B(9%\$S``!S(\`0<`*@(`HB&ED!,P``<R/`$'`"H"`*(AN
+M:03,``',CP!!P`J`@"B(<VX$S``!S(\`0<`*P,`HB'AS!,P``<R/`$'`"L#`
+M*(A]>`3,``',CP!!P`K__RB(@'T$S``!S(\`0<`(`(#,@P!>P`@#_\R``##,
+M`P!5S`,`7<P#`%^0````D````"?0`/\Q$`#_F0#_?<`4,1?/U0``D````(P`
+M`!V,``&2P`@`&'RP@!#`#`!!?"T`"L`D``",``%)S4,`5L`(``9\M(`0P`P`
+M07PM``K`)``!C``!2<U#`%?$"P!6?)3`#YC```)\%(`*C```",`8``&0````
+MP`P`/\`*B`!]R0`*Q14``!54`!!]04`>?4Z`"7Z"@![$%P`"?I:`"9````#$
+M#``<E,``RLV#``"```)H)K@`/Q:<``@EW``_$=P`!G^?@`H6G``0)?0`/Q7<
+M``@EW``_$=P`!G]?0`J0````Q`@`$)2`_V'$"``1E(#_7\0H``"6@`#%S8``
+M#B@(``'$#``@S(```#*(`;N4@`'8S`,``(```M?$"``3E(#__\P```+$"``/
+MQ!```YD`___`+#$>QNT``,`D``",``"#*#@``(P``'HH.``!C``#&2@,``",
+M``,0S8``$)````#$'P!@"=P`!R@@`!":``#>*!0`0(```C_`&"35Q9D``'T!
+M`!Y]D,`)*!P``"@D``#`(``&E4``#"3(``&4@``%?*2`!'V)@`L)5``!!=P`
+M`0H@``$4S``!!F0``9H`__8EF``_D````(```LTH%``??)3`!23,``&8P``#
+M"50``9E`__R0````Q"L``HP``1W`#H``?X^`"L`.``!_3T`**#P`H!/\`!`K
+M_`#_C```+<`<,07%[0``$NP`&";L`/_`)```C```@\P``!*0````@``!?8P`
+M`*3,```.Q`@`-\0(`#.4@``#S8``#HP``D#$"``JE(```\V```Z,``!FQ`@`
+M*Y2```+-@``.Q`@`*)2`__+-@``.C```]XP``O&```%_P`J<`"B,(YC`$``'
+MS0T``,`*C``HC".9Q/$``"B,(YK$]0``*(PCF\3Y```HC".<Q/T``)````#$
+M#``1E,``!2@X``",``!Z*`P``(P``Q#`.```D````,V```[$$P`>P`PDU8P`
+M`$/,`P`.D````,@)/3;(#3TWE,``R,@1/3C(%3TYR!T].L@A/3O()3TU!*@`
+M,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8R)8`/)5``+C(T@`H
+M?24``@E4``$$S``HF0#_^\B2`#@%$`!`?0K``<C6``3`'``$R.(`%,CF`"3.
+M"@%,SFX!3`C,``0(B``$"NP`!`G<``&9P/_XS0H!8,P*`63-03U'@``">,`P
+M```FB`#_C``"^7S!@`J6P/\4C```?95`_Q(Q2``!E(#^H0<P``$)F``!@```
+M@<`P,0''"0``))P``I7`_WR,``"/E@#_>LV#``"```)HP!```,`*B`!\C(`*
+MQ)4``"54`#]]%0`*D````,0G``"60/YNS`,``(```M?`##$)Q,T``"30``&9
+M```'Q`\`7<03`%[$%P!5?5$`#GS1``J9```.P!P`0'W(@`)\K<`0%=P`!GW"
+MP`J,``'8P"PQ"\;M```FT`#_?P%`"HP``4]\&H`*SH,`89`````H#``!C``#
+M$"@X``&,``!Z*#@``(P``QF7@/^+P#@Q`<>Y```7N``0)ZP'_Y;```/`)```
+MC```@\V```+$$``#E0#__\P``!#`.``!D````(```B.,``(/EX```\0,`!"4
+MP/[RS8,``(```LW$UP``!,P``0H@``$H&`#_?96`"7V1@!!]G8`$?)F`#Y6`
+M_QHH&/\`?96`"168``A]D8`0?9V`!'R9@`Z9@/\3%50`$)9```(55``(*!@`
+M_WV50`F0````P`@Q"<2-```DT``!F0``#230`/[$%P!?!50``<U#`%]]44`/
+ME4``!XP``%#$"P!5?0B`#LR#`%W-`P!5S`,`7Y````#`&"35Q9D``"@<```H
+M$```P"``!I5```PDR``!E(``!7R0@`1]B8`*"50``07<``$*(``!%,P``040
+M``&:`/_V)9@`/Y````",``!(*<PDU<3-``!]34`)D````,V```[-@``MQ`@`
+M$I2```*,``%KQ`@`$)B```*,``$WQ"<``)I`_;2```+-Q!P`,Y7`_A+,```P
+MP"```)`````$&``!S8``#LV``"V,``$WS````LP```O,```CP#`PXB@L``/.
+M\0``P`@Q`,2)```DC``$F,``!L`^`-`K_`#_P#O__\`W__^,```M)(P`")C`
+M``;`/@"P*_P`_\`[___`-___C```+22,`!"8P``&P#X`<"O\`/_`.___P#?_
+M_XP``"W,`P`(S`,`!LP#`"W,`P`NQ`P`UR3@``'.`P`)).0``C)D``+.0P`*
+MSD,`!\P#``#,`P`BS`,`(\P#`!W,`P`DS`,`',P#``O`#``_S,,``L`<(F^,
+M``$.SH,`(GZ"P`K`'")PC``!#LZ#`"-^KH`*SH,``<`,,0S$S0``S,,`!<0/
+M``+`$#$#S-$``,S#``_,`P`-P!```,P3`!#,$P`4S!,`&`40``$Q#``$E,#_
+M^\0-,0/$#``ZS```+<0(``.8@/__S8``$,V``!',```2S```#L0(`#;$"``O
+MQ"@``9:`_EC-@``.*`@``<0,`"',@``!@```.\P``"W-@``.S`,``,`P,$G'
+M"0``P#(`$'RQP`F5P/_OP#`Q`<<)```DG``!E<#^@12L``@F[`#_P"0``<`@
+M``",``,!E@#_/,V#``"```+-P`@DU\`.B`!\C,`*Q-4``"54`/^0````Q`L`
+M'L0/`&%\C0`,F0``!,S#`![`&``!S8,`#I`````H#```P!``!B24``$)$``!
+M?-3``12(``&9`/_\D````);`_6!^P0`*P!PPT,V=``#`'##.Q=4``!4L``26
+MP/U1C```@Y8`_4^0````,H@!O)2`_2[,`P``@``":,`P`Y#'.0``P`O__G^+
+M@`D0S``0?X^`"L^Q``#'.0``D````,`P(`//L0``QSD``)``````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+"````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PALM_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PALM_me.bin.uu
new file mode 100644
index 0000000..8589564
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PALM_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 PALM_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*P`X``<P``$7,``!*S$$B7,Q!
+MH?S43:']?$"``*````#,@`!-@````,Q!(EW,``!%S```2@A,``%\00``?$%`
+M`!U8__\97`/P%6``%<V!H0+-P2)6S@$B7)3```4A)``@SD&A_(```'L(S``!
+MS0&A_,P!H0)\0(``H````,R``$U\0(``?$#``,`J``)\00``?2D`!QR4``$<
+MF``&')P#`!7<``A\0@``?$)``)5```_`+@`$!?`B6'\O``?,,0``R"@`!,S!
+M(6G-`2%JSH$A:RFT``+,`2%LET``#BFT``"```"[R#0`#BFT``*70``)*;0`
+M`,`N``0%\")8?R\`!\PQ``#(*``$@```N\@T``Z70``$?@*``(```+O(-``.
+M*;0`!)=`_TL`````S@$A;<Y!(6[(*``#R#0`#IM```3(/``.A``#3<P``$TI
+M]```ET``!P0PHK:$``#=SH&BM\^!HL2`````S\&BT2GT``&70``'!#"BNH0`
+M`-W.@:*[SX&BQ8````#/P:+2*?0``I=```<$,**^A```W<Z!HK_/@:+&@```
+M`,_!HM,$,*+"A```W<Z!HL//@:+'@````,_!HM3`+@`$?R\`!\PQ``#(+``$
+MP#``!G[S0"/`,``@?VN`((@```!_L\`DS```0H````#,0``??$#``'Q!```9
+M%``]F4``$P04`"Z$``3#!!@`*80``E;('``3!!0`*H0`!,,$&``MS4&BI,@<
+M`!.5P```R!P`$\S!(0#-`2$!S,$A`LT!(0.```3`S8&BI!T8$`"5@``%R!P`
+M$RGD`$"60/__R!P`$\S!(77-`2%VR"``%)8```#((``4%B@``9J```3,``!/
+M@``$P,P``'^```$'S,$A=7Q`P`!\00``S```1<P``$I`U``#S4$B7,T!H?S`
+M'@`!?$(```C,``$&)``!!B@``LX=H?W.7:']F,#_^LZ=H?U\0(``H````,R`
+M`$U\0,``'-```13,``%\04``E0``!GQ!@`#-02%MS8$A;H```3/('``#P"(`
+M!'X6``?,(0``R!P`!'Q"0`"8P``$?$*``(````#-Y0``SD$A:<Z!(6K-P2%K
+M@````,P!(6Q\0,``?$$``'Q!0`!\08``?$'``!BD'^@J:``\EH``"GP"``!\
+M0@``.C```\P``%B;```#0B``!00@`$"```%/?`)``'X"0`":0```"F0``1SL
+M`!":P``*S```3<`J``3(+``@?I*`!\P``$',*0``SL``'H```5_(,``$S0$A
+M;<U!(6[(,``#?Q\`!AST``<3>``!ET``*@>X`62?@````````(```71_&X`.
+M@``!>'\;@`^```%\?QN`#(```8!_&X`-@``!A'\;@!&```&(?QN`$(```8T4
+MI``(FX``&12D``B```&='F0`_YN``!44I``(@``!G1YD`/^;@``1%*0`"(``
+M`9T>9`#_FX``#12D``B```&='F0`_YN```D4I``(@``!G1YD`/^;@``%%*0`
+M"(```9T>9`#_%*0`"!YD`/\J:``\FH#^<13L``A\0T``?$.``'Q#P`"6P``'
+MS```3<]!(6G/@2%JS\$A:X````#,`2%L@````,_U``#,``!9A``$PRIH`#R:
+M@``$R"@`%X````#40`!_EH#_JWX"0`"$``*(P`X``LP``$&```&KS,$P2I0`
+M``#(/``<?$#``'Q!``#`'@`!%20`$L`B``*60``%P"8`!,`G__M])0`&P"8`
+M`'W2@`9^$L`&?24`!WQ!0`!\08``S,$A:9J```S-`2%JS4$A:Y;`_D#-@2%L
+MA``$P\P``'_(,``:EP```,@P`!J````!?$"``(0`!,/,``!_R!0`%<@8`!;-
+M02%KEL#^,LV!(6R```'"S```?\P``^7(+``@P`X@)`00,``@S")K!!0P`<P`
+M`$'0$0``S-4``,[``![(#``)F,```,@,``E\00``?$%``,Q``$/,0`!$P`Z`
+M`'Q"0`!\0H``%JP`'Y;`_AG`-?``SD`#X1YX``,2?``(?_?`!G_[P`<6>``8
+MS\`#XL^``^,2L``"?S\``,\``^2```1/?(#``'Q`P``8T`'H$2@``94``!`&
+MJ`'[GH````````"```(3P!((`(```B'(%``1@``"*,@4`!*```(OS,&BI(``
+M`C@<Z``_@``"8'S!@`L<T``_*2@`!BDL`!9^KH`'R!P`$YJ``#T$%``N@```
+M`,S!HJ3`$@@`?$%``'T,P`?`$@`(%5@``Q5<``Q\0@``?='`!A(@`!1^'D`'
+M?DZ`!\Z!HJ2`````S8&A_L@4`!$$$"$8E4```,@4`!'440``@````,S!HJ3(
+M%``2!!`A!I5```#(%``2U%$``(````#,P:*DS,&BI`00``'-```9A``$P\P`
+M`'_($``;F0```,@0`!N````!?$"``"J@``0JI``4?B8`!P04`"Z6```(!!@`
+M*80``E;('``3!!0`*H0`!,,$#``MS4&BI`00(0#('``3E<```,@<`!/440``
+M@``$P,S!HJ2$``3#!!@`*80``E;('``3!!0`*H0`!,,$&``MA``"5L@<`!.`
+M```!?$"``)7```#('``3S4&BI,P!(0#,`2$!S8$A`LV!(0/-@:*DB````,P`
+M`$T=F``!?$$``'Q!0`"9@``)?$(``,@\`#(1F``0R!P`"SO\``&7P/__R#P`
+M,H```G+(/``S$9@`$,@<``H[_``!E\#__\@\`#,5:``=?5E`!YJ```01Y``*
+M?B8`!\W``&;-`2%8S4$A6<X!(5K,P:*DFH`"1`40``0$+``!$O``'7UQ0`<2
+MX``0(B``#,T!(5C-02%9S@$A6H``!,#,P:*D!#P`!<_!HJ3`-@`"B````,]!
+M(!!\0,``%-``'9D```@4U``<E4#];\`F``0B9"%4S"4``(````#(*``$@``$
+MP,U``&&$``3#''0``1QX``*;0``#R`P`*80``TS(%``KFX```P00`!"$``-C
+MS,&B4,T!H%"$``+]!!@$`(0`!,/,``!CR#P`+80``PO($``IR!P`+QW<``'(
+M)``GE<``"<@T`#'(.``PR#P`+5-T`"!_MX`G1[@%4,P``&+/^@``FD```,@D
+M`"?(*``C.J@``IJ`___(*``CP#```<@H`"2:@```R"@`),\``%M0V``(%-P`
+M&,`^$``AW(``??W`!\V!(8#-P2&!42``"!4D`!A^?D`'S@$A@LY!(8/-02&$
+M?$"``*````#,@`!-A``$PQQT``$<>``"FT```\@,`"J$``-,R!0`+)N```,$
+M$``0A``#8\S!HF#-`:!@A``"_008"8"$``3#S```9,@\`"Z$``,+R!``*L@<
+M`"\=W``!R"0`*)7```G(-``QR#@`,,@\`"Y3=``@?[>`)T>X!53,``!BS_H`
+M`)I```#()``HR"@`(SJH``*:@/__R"@`(\@H`"6:@```R"@`)8```L+`,``"
+M!9C``!#<``@4X``8S=D``,@<`"+()``B'=P/_\W9``%^8D`'SED``M@840/8
+M&%$$B````-@840<;^`#PP#8(`)>```/`,`"`B````,`J``3/02%\SP$A?<T!
+M(7XBJ"%_!"0`")I````*9``!S"D``,@@``06.``?FX#_^P0D``B(````````
+M`,@,`"24P``D.-0``9E`__W($``C?0T``9D`__O(#``D@``#,,@,`"64P``;
+M.-0``9E`__W($``C?0T``9D`__O(#``EA``$P\P``'_(/`/[F\```,@\`_O0
+M0`/\P#X`!-(!(?@C_"'YA``$P\P]``#(.``$&[0`/A^P``1_`L`+'N@`!'ZV
+M0`>:0/_VP#X`!-```_Q\00``@````7Q`@`"$``-,?$#``'Q`@`"@````S(``
+M3<@\``Z7P``#TP`#YH@````$/``FS\&BI,@\`^8+_``!S\`#YIO`__O,``!-
+M!#P`!<_!HJ3,`:'TA``$P\P``$>(````S```?X0``V-\0,``?$"``*````#,
+M@`!-!#P`(L_!HJ2$``3#S```2(@```#,``!_A``#;GQ`P`!\0(``H````,R`
+M`$T$/``CS\&BI,P!H?.$``3#S```28@```#,``!_@````'Q`P`"`````?$#`
+M`,`2``%\44`'@````-15``#,0`!ER#@`+<@\`"[`->``P#(`!'^W@`9_]\`&
+M([@0`"/\$`#/@2%4S\$A5<PQ(57(+``$R!P`)<@D`"1]Y<`'F<#__L@<`"6`
+M```!?$"``'Q`P`!\00``&2@`,):```C(*``GR"0`*)I```#()``GFD```,@D
+M`"C,``/@?$%``'Q!@``5'``?S,``Q\T``,B5P``#P!R``,W!(!#A@P``!5P@
+M`,P``$V`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#)S0``RN&#```%7*``
+M@````-P?00!\0,``?$$``'Q!0`!\08``S,``R\T``,SA@P``!5SI0(````#<
+M'T$`?$#``'Q!``!\04``?$&``,S``,W-``#.X8,```5<Z("`````W!]!`'Q`
+MP`!\00``?$%``'Q!@`#,P`#/S0``T.&#```%7,``@````-P?00!\0,``?$$`
+M`'Q!0`!\08``S,``T<T``-+A@P``!5SP`(````#<'T$`?$#``'Q!``!\04``
+M?$&``,S``-/-``#4X8,```5<\_R`````W!]!`-1#(`!\0(``H````,R``$W4
+M0Z``?$"``*````#,@`!-U$/I0'Q`@`"@````S(``3=1#Z(!\0(``H````,R`
+M`$W40\``?$"``*````#,@`!-U$/P`'Q`@`"@````S(``3=1#\_Q\0(``H```
+M`,R``$T$'*``S$.@`'Q`P`#8'\$`?$"``*````#,@`!-!!S``,Q#P`!\0,``
+MV!_!`'Q`@`"@````S(``37Q`P`!\00``E,```WQ!0`!\08``S`/S_,Q#\_S,
+M0_/\?$"``*````#,@`!-P!X`$,@,`"E0T``($%0``H``!"9]%8`@P!X`(,@,
+M`"I0T``("%0$`!%4``)]48`@S<``8M1:``!\0(``H````,R``$U\0,``'-``
+M`Q$H``&5```*!J@$,)Z```!\08``@``$/GQ!P`"```1$?$'``(``!$I\0<``
+M?$&``'Q!P``4U``0!52@`(````#-E0``P"(`!`68H`!]H8`'S!D``(``!#K(
+M&``$P"(`!,V!)=8B("77S"$``(``!#K(&``$S8$A;<W!(6Z```0ZR!@``WQ`
+MP`#($`/AR!0#Y,@8`^+('`/CS8$A:<W!(6K,P2%KS`$A;`0@``1]H8``?99`
+M#)9`^Z;-@`/B'2@``\`M\``1&``(?:V`!GVI@`>`````S8`#XGQ`P`"`````
+MS$P#X!R,___430``?$"``*````#,@`!-R!0`(S%8``25@/__R!0`(\P``%O,
+M02&`($R``,S!(8$4T``?S$$A@LQ!(8.5`/N*S$$AA,@4`".90/__R!0`(X``
+M``%\0(``P!8`!"%4(4#,50``R!@`!(````#,``/@?$#``!C0`#C`%@"`E0``
+M`\`J``1\U,`'S,$A?,Q!(7W,02%^?$&``!3\`!\=F/__.;```R*@(7^;```#
+M09P`!00<`$"9P```"=P``<PA``#()``$%FP`'T&<``6:P/_ZS(``39O`^V0`
+M````@````,P``^!\0,``?$$``!48`!]1%``@F8``"QD<`#'-``!B?4U`)]16
+M``"5P/M7R"``)IH```#((``F@````7Q`@`#@.@``P"8`!,S!(6E])0`'S0$A
+M:@NX``+,02%KFX#__LQ!(6R9P/T*S```?X````%\0(``P`X!`,P``$',P3!*
+MR#P`?\P``'^`````S```?\P``'^(````S```?P``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01F`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=0`P`'<`,@#H`#0`C``U`&(`.0#J`#H!$@`[`24`/`$]
+M`#T!K0`_`.<`001K`$($?0!#!(,`1`'2`$4!/0!&`?8`1P'V`$@!]@!*`HT`
+M2P-U`$P"F0!-`M,`3@,?`$\#*`!1`VD`4@-'`%,#7@!4`W<`5P-Y`&`#D0!A
+M`ZD`8@-]`&,#LP!D`[T`90/'`&8#T0!G`]L`:`/E`&D#Z0!J!!H`:P/M`&P#
+M\0!M`_4`;@/Y`&\#_0!P`_4`<00@`'($#P!S!`$`=`0(`'4$*P!Z!*``?`1.
+M`'T$8P`/!+P`#P2\``\$O``/!+P`#P2\``\$O``/!+P`#P2\``\$O``/!+P`
+M#P2\``\$O``/!+P`#P2\``\$O``/!+P`#P2\``\$O``/!+P`#P2\``\$O``/
+.!+P`#P2\``\$O``/!+P`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PALM_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PALM_pfp.bin.uu
new file mode 100644
index 0000000..40624ad
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PALM_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 PALM_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-ES$``*ID```4`````S$``*X```V7,0``LS$``+8``
+M`V7,0``N'(P``LR``$"8P``$S$``0(```V7,``!2@``#9<P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$+-
+M0`!"T0``0GQ`P`#(&``#R!P``\@@``.5@/_"R"0``Y7`_\#(*``=FH``!,P`
+M`%78``/`S```0,@H`!;`+@`$R#``#1JH`"=^\L`'SL``0,P``$#-@`!`S<``
+M0,X``$"6@``#SD``0-"``%S,@`!`S```0,S``$!\0(``H`````0H``'($``L
+MR`P`*U$0`"!\T,`G?,4`(%44`"#-``!"S4``0M%``$)\0,``R!@``\@<``/(
+M(``#R"0``Y6`_YG(*``#E<#_E\@L`_U^+P`1EP```W[BP`%\`L`&SL.BGLP`
+M`&S-``!MS4``;<@P`!V;```$S```5=@``\#,``!`R"P`%L`R``7(-``-&NP`
+M)W\W``?/``!`T$``0,V``$#-P`!`S@``0,Y``$"6P``#SH``0-"``%S,@`!`
+MS```0,S``$!\0(``H`````0H``'(&``5'9@``=```&]\0D``E8`"TWQ"@`#(
+M'``@P#?``'Q`P`!\00``?+2`!L`V``,:N`'HEX``!]!``^"$``-HS```?\@X
+M`^";@```R#@#X)G```#('``@?+2`!Q#4``)]94``S4``0\Z``$/-``!#S(``
+M0,Y``$#.@`!`S,``0.`Z``"7@/]3S0``0'Q`P`"```"C?$$``!R,``*8P``)
+MR!``')D```3('``&A``#:\P``%+(&``5@```CAV8``+($``>F0#__,@<``B$
+M``-KS```5,@8`!6```".'9@``AR,``+($``=F,``#L@4`$F9```$R!P`!X0`
+M`VO,``!3R!@`%93```,8E`'H!50`!B`0``%]%0`#@```CGV1@`:90/_XR!P`
+M!\W``$#,``!`@```S,P``&[`#H"`S```9P30@(#,``!HS0`#\<T``_+-``/S
+MS0`#],T``_;-``/WS0`#^(````7-``/YS(``0-1``$!\0(``H`````0H``&`
+M``#OV``$0-@``T#,``!`S(``0-1``$!\0(``H`````0H``'8``/`@```_,P`
+M`$"```#[V``$0-@``T#,``!`R`P`*<@0`"K,@`!`S$``0%$0`"!\T,`G$%``
+M`GT-`"!5%``@S0``0\U``$/00`!#S```0'Q`@`"@````!"@``=@``\#,``!`
+MS(``0-1``$!\0(``H`````0H``$<C``"R!``'9C``!'(%`!)F0``!,@<``>$
+M``-KS```4\@,`"_,@`!`S$``0,Q``$#,0`!`?,3``,S``$#40`!`?$"``*``
+M```$*``!F4#_]<@<``?-P`!`S```0(```1O,``!N?$#``,@0`$>9```+R!0`
+M1)E```3(&``)S8``0,P``$"```%%S(``0'Q`P`#($`!'E0#_]\@4`$690``$
+MR!@`"LV``$#,``!`@``!1=@`"$!\0,``R!``1YD`__P`````S(``0,S``$#4
+M0`!`?$"``*`````$*``!R!``1M@`!T#-``!`A``!7,T``$#(#`!#E,``"L@4
+M`$B```%5!!```\@0`$;8``?`S0``0(0``5S-``!`R!0`2)U```#,``!JR"@`
+M%AZH``&:@``#P"D``8@```#`+`%6SH``7-@`",#.P`!`B````,P``$`<C``"
+MR!``'I3```C(%``<F0``"L@<``B$``-KS```5(```7;,@`!`F4``!,@<``:$
+M``-KS```4LR``$"`````U$``0,Q``"?,0``H@``#9<P``&O`,@`#P#?__X``
+M`8%\L(`'?$-``,@@`"C('``GR!@`)L]#HIY\04``4B``('WAP"=]6,`#?-S`
+M(%30`""```&6S(``0'Q!@`#,@`!`@``!D\V``$#`&?__S(``0,V#HIY\0,``
+M?$$``'Q!0`#,PZ'ZS0.A^<U#HIW,P`!`S0``0,U``$#,0`!`?$"``*`````$
+M*``!?$#``!S0``',PZ*?E0```]!``";0@``FS(``0(````#,P`!`?$#``,R`
+M`$#,PZ*B@````,S``$#('`!,?$#``"G@```4U``??6%`!LR``$"50``#?$$`
+M`,S``%D5&``?S,``0)6```/-``!`S0``6H```V7,``!_R`P`3)3``:/((``?
+M?$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)S2``0<U@`$'-H`!!%1``"!%4`!A]
+M4\`'S\``+P8@``'.``!8@``#9<P``'_((``?R@P`%Y3```5\00``V"`"QH``
+M`<7.(`!&S```2(```=L`````R"``'WQ!@``*(``!RA0`&LH8`!=]68`'E8``
+M!<X``%C,H`!&@````,U@`$;,H`!$@````,U@`$2```-ES$``:L@,`_J8P``+
+MT$`#^L@8`$+('`!#R!``'<@4`!P1$``!F8#_5GT5``>9P/]>`````-```_J`
+M````?$#``,R``$"`````U$``0'Q`P`!\00``?$.``'Q#P``$'``"SX``0L_`
+M`$+-P`!"!!P`!,S``$+-``!"S<``0@0<```$(``!?`)``,@4``/(&``#49@`
+M('U90"?(*``#R"P``\@P``/(-``#4NP`('ZN@"=3=``@?S<`)W\K0"%^=D`@
+M5J@`/U<P`#]^LH`&?BH`!IG`__()W``!EH#_X5/T`"!_>T`G?65`(%58`"#,
+M``!;S78``,VV``#((`!!F@```,@@`$&````!?$"``'Q`P`!\00``S,`#_LT`
+M`__,P`!"S0``0A44`!\9&`#P)UP``7UV``:9@``%?5Y`!LP``$*```-ES```
+M3168``$5+``(F8``,1[L``&6```$%3``#(```V7,``!"!!0`!,U``$(?,``!
+M("@``00X``0$/```R!0``\@8``/('``#R"```WU=0`U]H<`-?5U`!Q80`!\5
+MG``??1T`!GT70`9^DH`&FT``$@NX``2;P/_R"_P``<@,`_Z:@``)R!`#_YL`
+M`0;,``!-!!0`!,S``$+-``!"@``"2<U``$*6P`#_S```38```V7,``!.FL``
+M`\P``$W,``!.EX#]D^.#``"`````W`,!_Y9```3,``!.@``#9<P``$+2``!"
+MR`@``\@,``/($``#R!0``\@8``/('``#R"0``\@H``,5_``?%K``'W_SP`84
+M\``??_/`!A5P`!]_\\`&?8B``9?```U]S,`!?E$``7Z50`%\D(`,?-3`#)K`
+M``-\CT`&)+0``9M``-;,``!-@``#9<P``$[(#`/^R!`#_\S``$*```)US0``
+M0GQ`P`!\00``?$+``'Q#``#`.P`??$-``'^W@`;`/A``EX#]8'T]``=_/P`'
+M&10`.\P``%N50``3R!0`0#%8``*5@/__R!0`0,P``&,A'(``S,$AA<W!(885
+M%``?SL$AA\\!(8B50/U/ST$AB<@4`$"90/__R!0`0(````%\0(``S(``0,S`
+M`$#-``!`SL``0,\``$"`````ST``0-"``^#,@`!`A``#:,Q``$#(#`/@F,``
+M`,@,`^!\0(``H````'Z"@`9\0,``A``"TA30`!^9`/TTT$`#X(0``VC,``!_
+M@``"Q,@,`^#,@`!`S,``0(@```#40`!`S(``0,Q``$#,0`!`S$``0'Q`P`#,
+MP``AS,``0-1``$#`-___T``#^]```_S0``/Z@````,]``_U\0,``%-P`'9G`
+M``?,@`!`&-P`/)G``'S,P`!`@``#9<P``&H8V``\S8``9LP``&J```-ES,``
+M0'Q`P`!04``@A``#:,P``%U\T,`GR"``'\C6``"90``(?$.``..#``#/H`!/
+MA``#:,P``%Z`````U$``?X```V7,``!>A``#:,P``%W((``??$#``,`V_P#(
+M$``AP#`__WSU0`9]48`&?8&`"IF```A\\X`&XX,``,^@`$^$``-HS```7H``
+M``#40`!_@``#9<P``%Z$``-H?$#``!3<``B5P``9'-P`$'Q!``"9P``$4%0`
+M((```R/)'0``?14`)\D>``!\0@``?$)``'Q!@`!]Y<`&?>*`$9J`_-A!K``%
+MFL````KL``$<W``0F<``!`````"```,FR1T``(```R;)'@``S(``0,S``$"`
+M````U$``0-@``T#,``!`S(``0-1``$!\0(``H`````0H``'8``/`S```0,R`
+M`$#40`!`?$"``*`````$*``!?$#``!S0``8I$``&F0``!L@4`!R90``$S```
+M4H0``VO('``&S(``0,S``$"`````U$``0'Q`P`!\00``%1@`'\T``%N9@``$
+M410`((````#430``?4U`)QD<`#'45@``E<#\H\@@`$&:````R"``08````%\
+M0(``@````-1``'_,``!_@````,P``'_,``!_B````,P``'_-P`!`B````,P`
+M`$``````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,W``0#/@`%`<$`!@#N``<`^@`(`0P`"0#U``H`[``+`/@`#`$L
+M``T!-@`.`4H`#P%4`!`#8P`1``H`$@`8`!,`(``6`"(`)``Q`"4`60`F`7@`
+M%P'=`!@!ZP`:`>T`(@+R`",#`P`G`8T`'P'_`"`"+P`H`:\`*0%\`"H!H0`K
+M`9$`+P&J`#(!TP`T`T4`-0&``#D!_``\`Q<`/@&_`#\!P0!!`I@`0@*_`$,"
+MR0!$`M8`2@+D`%4#.0!6`T``8`",`&$`L@!B`-H`8P#$`&0`Q`!E`,0`9@#$
+M`&<`Q`!H`.<`:0#P`&H!0`!K`0X`;`$.`&T!#@!N`0X`;P$.`'`!$P!S`/P`
+M=`#\`'4!9P![`U(````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_ce.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_ce.bin.uu
new file mode 100644
index 0000000..42fe429
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_ce.bin.uu
@@ -0,0 +1,194 @@
+begin 644 PITCAIRN_ce.bin
+M?$"``8@```#40`!_?$"``8@```#$(``+Q@P`!93``"0D4``/,10``I5```3,
+M0``DS$``)8`````Q%``#E4`!.\Q``";,0``G@````,0@``O,(``%?$$``5!4
+M`"!\08`!!B0``<Y````5G``8?14`&LW@``K-H``,T2```\V@``.:```$Q"0`
+M$II```(AW``P@``!3,0@``O&#``%'*@`$)3```/.H``'@```%<P```G$)`!_
+MQ"``"WQ!@`$*(``!QA0`",88``5]68`*S@```)6```/,(``'@````,P@``6`
+M````?$#``130`!XQ%``"E4`!#AC0`>@8U``P&-@`-`4H`$1\0@`!?$)``94`
+M``>&@```@``!4(```5"```%0@``!4(```%(15``0?A8`"LU``!'480``E8#_
+MLL0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``!'48@``E8#_J<0@``Z:`/__
+M?$"``8@```!\0,`!%-``'C$4``*50`#K&-0`,!C0`>@8_``T),P`#P3H`&A\
+M08`!?$'``93``!*&@```@```<H```5"```%0@``!4(```&^```%04=P`('V>
+M`!J```!_4=P`('V=@!J90``#Q:(``(```'_)H@``@```?\6A``"50``%!9@`
+M`<6E``!29``@?B8`&@4H`(-\08`!?$'``94```>&@```@``!4(```5"```%0
+M@``!4(```)/8```1SAD``)5```0%F``!5B``(,X9``"7P/]QQ#DA0'Q`@`&(
+M````4=P`('V=@!K8```1SAH``)5```0%F``$5B``(,X:``";P/^]?$"``8@`
+M``#8``/VV``#]=@``_38``/SV``#\M@``_'8``/PV``#[]@``^[,0`!_S$``
+M?\Q``']\0,`!S,```=1``'^`````?$#``5!0`"",``#+?-#`&L0@``O$U@``
+M?$.``<0D`!.:```)V&0#],9K`_&:@/__QFL#[@:H``'.I`/NS60#Z]@D`_29
+M0``)WX,``,^@``Z,``#/U$``?YH`_SS&<P/NFP#__X````",``#/?$"``8@`
+M``#8```"Q#P`#9O``(.0````V$```L0\``V7P`!_D````-@``!)\0,`!4%``
+M(,0\`!`G_``!E\#__GS0P!K0P``4S$``%<00`"%\4,`!S,``%M@``!.`````
+MQ!``(7Q0P`',P``7U$``&(````#$$``A?%#``<S``!?$$``@?%#``<S``!F`
+M````Q!``(7Q0P`',P``:S$``&WQ`P`%04``@?-#`&M#``!R`````S$``(=@`
+M`"*`````?$#``5!0`"!]#4`:V$``*<@8`!U]E<`/E<#__M@``"F`````?$#`
+M`<@0`!W(%``>?16`#IF```_80``IR!``'7U1@!)]C<`/F<#__=@``"E0X``!
+M?A9`#II```1]8H`2TH``(X````#0```C@````-B``"G$/`!_S```(-A``"C$
+M#``<F,#__]@``"A\00`!4%0`('T6`!K2```>V$``'8````#,```@V$``*,0,
+M`!R8P/__V```*-```![0```?V$``'7Q!``&`````?$#``7Q!``$5&``?S0``
+M$5$4`""9@``#U$T``(````!]34`:&1P`,=16``#$(``.E<#^R,0@``Z:`/__
+M@````'Q`P`%\08`!%-``'C$0``(DU`#_E0#^O\V4`P"`````Q"``$WQ`P`'$
+MTP,`S```$<TA(4&`````U$``?X````#$)`!^ED```WQ`@`&(````@``!4```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0`"`!`!2@`1``4`&0`M`#$`)0`S`!,`@`#3`($`X0""`.8`@P#M`#<`
+M.0!``%P`1`">`(0`]@"'`/D`B`$"`(D!%P!]`3P`?@%$`'\!+``B`*X`BP$B
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_mc.bin.uu
new file mode 100644
index 0000000..2eaedb6
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_mc.bin.uu
@@ -0,0 +1,694 @@
+begin 644 PITCAIRN_mc.bin
+M``/HX``"O@$```('``/_```#_P```J`.``'`&0`#Z````^@0``/H(``#Z#``
+M`V`@``-A2``",;@``TEL``-("@`#KPH``K0$``)O]```^BT``K0/``)/%```
+M^@H``ZB,``#"`0`#0"0``K1```*U#P`#2J8``D1!``/P`@`"294``VJF``-*
+M40`#0"0``K@"``*Y_@`"1)0``DB!``.H@``"9$@``VI1``-`)@`"OX```KP$
+M``))^0`#\$(``_0```'`00`"OX```TA4``*X#P`"N?```D$8``)"*0`#:%0`
+M`TMI``/`C``"9$P``VMI``)$2``#:VD``F$?``)B+``#:%0``BP%``-+3``#
+M_P```V%$``-+'``#0"H``K3\``-A0``"0S0``F$>``-K'``"2JX``_!&``-)
+MU0`"O!```DS'``/P0@`"O"T``C)S``-`)``"M$```K7P``-*I@`"1$$``_`"
+M``)IE0`#:J8``T````/_```#^`$``\1```/$40`"QD4``@````-`$``#_P``
+M`_\```/H(``#Z#```V`0``"1Y0``D@T``_@#``(POP`",;(``T@(``*TGP`"
+M0`0``V@(``-(P``#2,8``K3\``*U#P`"010``DF4``)")0`"2J4``D,U``)+
+MM0`#:,```VC&``-(```#2`4``KL_``*\OP`"O^\``)(E``"*)@``@BH``+HH
+M``"J+``"01L``KO[``)`#``#:````KS^``)%7P`"1WP``V@%``-($``#2=T`
+M`KOQ``*\`@``BBD``*HK``)!&P`"81P``V@0``)%6P`"95P``VG=``-`#0`#
+M_P```_\```.A3```B?\``K,"``)#-``#HS```)G^``*S!``"0S0``Z,R``"9
+M_0`#0"D``T````*\(```N<<``D(L``/P!P`"L````((Q``(Z,P`#Z````('E
+M``/T```!PEP``T````*\(```\C$``D,\``/P!0`".C,``^@```"!Y0`#]```
+M`<)<``-((0`"L\$``D=S``-H(0`#:HD``T@E``*SP0`"1W,``V@E``-JC0`#
+M2"D``TEP``-`$@`"OP<``D`/``.````#``X``Z^(``-)U@`"O!```DS+``/P
+M00`"P`\``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H+0`#P00``\$5
+M``-IZ``#:>P``TK"``*_P``"2(\``VK"``-JQ@`#Z````^C0``(NE@`#:.0`
+M`\'>``(NE@`#:00``^A```*]```",@(``KT!``(R`@`#0"P``_\```*T`@`"
+M1`0``*()``-)U@`"M1```D1;``.D1@``H@L``J!.``/P`P`",[<``_0```'!
+M!0`#]````=)]``*\```",CT``T`.``#R,@`#Z/```Z"V``-)U0``^@0``K$/
+M``)"%P`"I2```_`!``#Z,@`"0QL``J4C``/P`0``\@0``T````-`+@`"MA``
+M`K0,```J,@`"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!``/HP```
+MX@,``T`(``*T````>@0``J`D``/P00`"L@@``J#^``/P00`"L@0``K0_``)"
+M)```DAH``TJ4``/_```#88```T````/_```"M$```D0$``/P`P`#Z````((Q
+M``(BX``#0````_\```*T0``"1!0``_`"``#R,0`"(N```T````/_```"M$``
+M`F$0``)$%``#\`$``BSW``-*E``#_P```V&$``-````#_P```K0"``)$)``#
+M\`,``^@```"",0`"(PP``T````/_```"M`(``D0T``/P`@``\C$``B,,``-*
+ME``#_P```V&(``(QL@`#0````_\```/_```"1`X``_`#``/H````@C$``B0;
+M``(QL@`#0````_\```/_```"1!X``_`"``#R,0`")!L``BTN``-*E``#_P``
+M`V&,``-````#_P```K0"``)$0``#\`L``^@```"",0`")@<``T`L``/_```"
+MM"```D1```/P`P`#Z````((Q``(Q*0`#2I0``_\```-AD``#0````_\```*T
+M!``"1$```_`#``/H````@C$``B?3``-*E``#_P```V&4``-````#_P```K00
+M``)$0``#\`P``^@```"",0`"*'H```'_``/_```#_P```J0.``/P!```\@``
+M`BAZ``/H````@@```TJ4``/_```#89@``T````/_```"M"```D1```/P`P`#
+MZ````((Q``(J"@`#2I0``_\```-AG````@,``_\```*T`0`"1`0``_`$``/H
+M````@C$``\'^``(JO````@,``_\```*T`@`"1`0``_`$``/H````@C$``^CP
+M``(JO``#0````_\```/_```"1"X``_`#``/H````@C$``C?1``-````#_P``
+M`K00``)$)``#\`,``^@```"",0`"./4``_@#``-*E``#_P```V%@``-````#
+M_P```K0"``)$00`#\`H``/(Q``(F!P`#0"P``_\```*T(``"1$```_`"``#R
+M,0`",2D``TJ4``/_```#860``T````/_```"M`0``D1!``/P`@``\C$``B?3
+M``-*E``#_P```V%H``-````#_P```K00``)$00`#\`L``/(Q``(H>@```?\`
+M`_\```/_```"I`X``_`$``#R```"*'H``^@```""```#2I0``_\```-A;``#
+M0````_\```*T(``"1$$``_`"``#R,0`"*@H``TJ4``/_```#87````(#``/_
+M```"M`0``D0$``/P`P``\C$``\'^``(JO````@,``_\```*T"``"1`0``_`#
+M``#R,0`#Z/```BJ\``-````#_P```_\```)$/@`#\`(``/(Q``(WT0`#0```
+M`_\```*T$``"1#0``_`"``#R,0`"./4``TJ4``/_```#870``_@#``-````#
+M_P```K0(``)@`0`"1`0``_`,``-("``#_P```K1```)@!``#:`@``TF8``*T
+M_0`"010``VF8``/H,``#P2X``V@P``(Q1``#Z````^@0``/H,``"L@,``V@P
+M``-````#_P```K6```)A$``"114``_`!``(W,``#2I0``_\```-A>``"O`$`
+M`C(]```",@`#_P```_\```*A#@`#\`(``^@```""!P`"+2X``T@```-(!0``
+M"B8```(J```2)0``*BP``#HH``/_```#:````V@%``-($``#2=T```HI```J
+M*P`#_P```V@0``-IW0`#27$``K(!``/H,``#P08``\$7``-H,``",40``^@`
+M``/H$``"L@,``K,```-H,````@L``_\```/_```"H`X``@*!``/T```!P```
+M``'E``-`$@`#0!4```H-``*@#@`#\`(``_0```'"G``"P1X``(H-``)KN@`"
+M95L``L9N``/P00`#!FX``V`5``*R#P`"1$(``J44``/P!P`#Z*```^BP``-@
+M$@`#Z````('E``/T```!P&L``T`L``/_```"M"```D!```/P`@`#]````<*H
+M``/H````@C$``C$I``#R,0`",2D``^@```"",0`",%X``/(Q``(P7@`#23T`
+M`TC```*V"``"1F0``_`"``*U,``"8B4``VC```-HQ``#2QT``T`H``*\$``"
+MOP0``DS```/P!0`"9W\``VL=``(Q1``"9WX``VL=``-`(``#_P```_\```+"
+M+@`#\$0``L,^``/P0@`"LO\``K/_``-@(``",;(``TE(``-`*@`"M#\``K6`
+M``*V0``"1F@``_!%``)#-``"8S4``VE(``)#-``#:4@``^@```/H$``#Z"``
+M`^@P``-DI``#9.0``_0```'````#0`0``&HQ``/H@``#Z)```^B@``/HL``"
+MH-X``_`#``-DJ@`#]````_!!``-DZ@``8>D``J#>``/P`P`#Z$```_0```/P
+M00`#A.H``]A```/<P```>>@``_@#``/4G@`#^P```P_^``("]P``(<,``J#>
+M``/P`P``8<(``_0```/P00``8<$``K\(``/<0``#V,```_@#``/4G@`#^P``
+M`P_^``(#!@`#^`,``^P````",@``:C$``_\```*@#@`#\`$``^P```-).``"
+MH-X``_!!``-).``"N/X``D(H``-I.``#2=```K0$``)A%``"L@$``K,2``*@
+MW@`#\$$``K,1``-H,``#27$``KCO``*Y!``#P08``F%Y``)#.``#:#```T@)
+M``*X_0`"1$@``V@)``(M"``#2:```K01``/!)``"L0\``VF@``-*1``"M/X`
+M`F$>``-J1``"010``VI$``*@W@`#\`,``T)A``/T```#\$$``T)=``/_```#
+M_P```^A@``-II0`#:&L``KH,``*XP``#W($``]BA``*P^``"L0<``^@@``/H
+M,``#_@```]0?``-H:P`#Z/```B/)``(CL@`"(]X``J'^``/P00`#8GH``T)X
+M``/_```#_P```J"```'#9P`"H)$``<-G``*@H@`!PV<``J"S``'#9P`"S_X`
+M`KP,``*A_``#\$(``_0```'#40``^<X``^CP``(CL@`"(\D``B/>``-">``#
+M_P```_\```*@@``!PWT``J"1``'#?0`"H*(``<-]``*@LP`!PWT``L_^``*\
+M#``"H?P``_!"``/T```!PVH``&'.``#YQ0`#_P```J7/``'#C0`"I?P``<.(
+M``/H\``#Z,```_0```'#D``##,\``ZS```/H\``#]````<.0``,/_``#K_``
+M`^C```(CR0`#P?P``B.R``-).``"H-X``_!!``-).``#_P```F(N``-I.``#
+M2=```K3[``)!%``"L@$``K,2``*@W@`#\$$``K,1``-H,``#27$``KCO``*Y
+M^P`#P08``D%Y``)#.``#:#```T@)``*X_0`"1$@``V@)``*P&``"(_T``BTN
+M``/L```#P0\``\$?``/!+P`#P3\``J#>``/P!0`#9+```V2T``-DN``#]```
+M`_!#``-D\``#9/0``V3X``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#
+M:,@``^P```/!#P`#P1\``\$O``/!/P`"H-X``_`$``-DK``#9+P``_0```/P
+M0@`#9.P``V3\``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P`
+M``*P$``"(_T``TH<``(D#0`#P8P``TH@``(D#0`#C,8``FB,``-*)``")`T`
+M`\&<``-**``")`T``XS&``)IG``#2BP``B0-``/!K``#2C```B0-``.,Q@`"
+M:JP``THT``(D#0`#P;P``THX``(D#0`#C,8``FN\``/L```#:&L``KD(``*X
+MP``#W(```]B0``/H$``#Z"```^@P``/^```#U!X``VAK``/!CP`"OQ```BT$
+M``/!^``#[````^C```.'/``#IW8``X8L``.F:``#A1P``Z5:``.$#``#I$P`
+M`FS'``)LQ@`";,4``FS$``/L```#0"0``&HQ``/_```#H`8``J$.``/P`0``
+M@?D``TFA``-)I``"NT```KJ_``)%I0`"H-X``_`#``)#HP`#]````_!!``)C
+MLP`#::0``VFA``(R8``#Z````^@@``/H,``"H-X``_`#```)^P`#]````_!!
+M```)^@`"N,```VAK``/8```#W(```]0>``*_"``"+00``X#@``"!]@``@?4`
+M`^@```"!]```@?,``/'R``-(5``"H-X``_`#``.$Z``#]````_!!``.$Z@`"
+M8B0``VA4``-)=0`#B.8``F!H``/!%P`#P2X``\$^``*@W@`#\`$``X,P``-H
+M,``#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``\!$``)")``#:%0``&(+
+M``*_`@`"+00``J#.``/P`@`#]````@2#``(NJ``#Z'```X3F``)&2P`"H&0`
+M`_!*``-)T@`#Z&```XJR``.JJ@`"H:X``_`"``,!K@`")?<``_0```'%(@`"
+MOP@``D_Y``.O]``#B[(``ZN\``(E.P`#]````<4B``-`#``#_P```K\(``)/
+M\``#\$(``_0```'$E``"OP```KL!``(E.P```@0``_\```/_```"H`X``_!"
+M``/T```!Q2(``/'T``#Q\P`"H-X``_`#``!Y^``#]````_!!``!Y]P`#C>(`
+M`]S0``/8\``#B>8``FF>``#QXP``0?D``^C0``./X``#P:@``XSM``#AYP``
+MXC```BX1``*W`0``0?D``^B@``#1XP`"H'X``_`!``.H@``##]\``\'9``/!
+MJ``#C.T``.'G``#B,``"+A$``BY2``/!!``#P28``V)P``*_`0`#0!$``XC@
+M``*@_@`#\`0``D1(``/P`@`#]````@4(``*W`0``0?D``_\```*@?@`#\`$`
+M`ZB```/HT``#C^```\&H``.,[0``X><``.(P``(N$0`"+E(``T)P``.,ZP`#
+MC.H``^CP``+(0``#J(```"H)``+*8@`#JJ```J9>``($Y0``:C$``/()``/!
+M6``#P7H``V)Q``/T```"!)\``J%>``/P#@``:C$``\&1``/!LP`"H-X``_`#
+M``-A+@`#]````_!!``-A,@`"P($``Z@```+"HP`#JB```X50``"J"0`#@>``
+M`P"$``/P)``"H80``_`!``+$00`#!$X``\%4``,"I@`#\"0``J&F``/P`0`"
+MQF$``P9N``/!=@`#U%X``F`"``($]P``:C$``K\"``(M!``#27$``X'D``/!
+M!@`#HFP``J`N``(%(@`"87$``\$N``/!/@`"H-X``_`!``.#,``#AF```_!'
+M``-H,``#C^T``BT$``./[0`"+00``X_M``(M!``#C^T``BT$``-)=0`#P2X`
+M`\$&``/!%P`#P3X``J#>``/P`0`#@S```V@P```!Y0`#_P```_\```*E#@`#
+M\$@``T`1``*@W@`#\`,``F9N``/T```#\$$``F=^``-@$0`#Z````('E``/L
+M```"H/X``<5'``*P#P`"L0\``K(/``*S#P`"H-X``_`#``-C*``#]````_!!
+M``-C:``",40``TI```!!\@``2?8``%'U``*\,P`"1`P``D4<``)D10`"1BP`
+M`D<\``)F9P`"9$8``J%.``/P`0`"M`$``J".``/P!0`"I$D``_!#``*D2P`#
+M\$$``/'T``"A]@`"O,P``D0,``)%'``"1BP``D<\``)D10`"9$8``F1'``*A
+M3@`#\`$``K0!``*@C@`#\`4``J1*``/P0P`"I$L``_!!``#Q\P``H?4``^A`
+M``"A\@```?0``!'S``*Q#P`"LP4``J7^``(%G0`"H/X``_!!``/H\``"H`X`
+M`_`!``+/_@`"L1```J`N``/P`0`"S_$``K.0``*F\P`#\$(``/'E``/L```"
+M0P(``_!#``(EW0`#]````<5'``*T$0`##_0``J#>``/P`P``^?$``_0$``/P
+M`0``^?```T,I``*@W@`#\$$``T-I``*_=P`");P``^P```-(Y0`"H-X``_!!
+M``-)!0`"N!$``J`.``/P`0`"Q$@``DE!``*DDP`#\`$``/'T``*@+@`#\`$`
+M`L58``))40`"I),``_`!``#Q\P`"H-X``_`#``-HY0`#]````_!!``-I!0`"
+M0`(``J`.``(%1P`"L0(``B7W``/L```"H?X``_!!``/L```#H?8``X_V``.@
+M]@`"H0X``_`'``*\"0`"H$P``_!!``*\#P`#P4P``\%<``,`#@`"H1X``_`'
+M``*\"0`"H&P``_!!``*\#P`#P6P``\%\``,!'@`"H-X``_`#``-C*0`#]```
+M`_!!``-C:0`"8@$``@7"``/L```#0RD``J#>``/P00`#0VD``J`.``/P!0`"
+MM`\``DS^``/P`0`"M`D``\%4``*@+@`#\`8``K8/``.L]@`"3,X``_`!``*V
+M"0`#P78``J#>``/P`P`#8RD``_0```/P00`#8VD``^P```-(Y0`"H-X``_!!
+M``-)!0`"L!$``L1```+%4``"H-X``_`#``-HY0`#]````_!!``-I!0`#`1X`
+M`@7[``/L````:C$``^@```(N@@``\>\``^@```"![@`#0`P``T`M``*X$``"
+MN0@``DH8``.JI@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!``*S
+M!@`#0"T```H$``*P0``"0$```_!!``/H,``"01X``_`!``/H,```F>T``BT(
+M``*X$``"N?X``J#>``/P"0`#2"$``KH/``)&:@`"1WD``F9H``-H(0`#:HD`
+M`_0```/P1P`#2"4``KH/``)&:@`"1WD``F9H``-H)0`#:HT``C`H``*_`P`"
+M+_0``K]D``(M!```:C$``_\```/_```"H-X``_`#``*[```#]````_!!``*[
+M0```V>```\$.``*Q$0`"LA```VI$``*Q$``#Z"```VI$``*P_P`"L?\``K+]
+M``*S_P`#:&```TI@``*_]P`"L1,``D`/``)@#@`#:F```#'^```Y_0`"O`@`
+M`K_^``.&:@`"8B8``J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(M!``#
+M:&L``_\```/^````8B\``%HN``/_```#V,$``]RQ``./XP`"+00``]`?``.,
+M[P`#C^0``F_^``)``0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!G@``J#>
+M``/P`P`#2"$``_0```/P00`#2"4``\#,``(&I``#C.8``L9L``/P00`"QWX`
+M`J#>``/P!``#:"$``VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!
+MQDH``T`1``*P"```\>4``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T
+M```"!]$``X#A``.!!@`"81X``X+G``-J1``#@08``^@@``-J1``","@``T`L
+M``!:'0`"M`0``^CP``)$0``#\`$``K\!``*DO@`#\`$``K\$``(O]```\AD`
+M`/(7``(R6@`","@```HM```1_@``&?T``K`"``*@W@`#\$$``K`$``."*@`"
+MI#X``_`!``*S!``#@18``F`!``*Q,P`#:F```T`*``*P`0`"L0(``K(```*S
+M`0`"H"L``_`"``/H(``#P3L``VIH``/!#@`"L@D``D`)``/P`0`#Z"```K`3
+M``*Q`@`#@B8``^@P``-J<``#0"T``&($```2&@`"OT```D]/``/P`P`"H,X`
+M`_`!``*R"``"L"$``K$"``*S`0`#:G0```H=``*P`0`#_P```J0>``/P!0`"
+ML00``K(```*S`@`#]`0``_`#``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`0`"L0(``K,$``-J?````>X``_\```/_```"P`X``('N``(O[P```AD``T`*
+M``-`#0`"H`X``_`%``*P`0`"0`4``X`&``/T!``#\`,``K`$``)`"0`#@`(`
+M`K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"
+M+LH```'O``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H``J#>``/P
+M`0`#Z/```]CP``*\"0`"OS\``DL?``(MBP`#Z/```/GO```![@`#_P```_\`
+M``+`#@``@>X```GM``-`+@`#_P```J`!``('2@`"L`$``D$(``/P!0```C(`
+M`_\```/_```"H`X``@=*``-*=```>AH``_\```/_```#P2\``VIT``(O[P``
+M`AD``T`*``-`#0`"H`X``_`%``*P!``"0`4``X`"``/T!``#\`(``K`0``)`
+M"0`"L4,``F@!``-*9``"M(```!'@``)`!``"8`@``Z(B``/!/@`#:F0``BZ]
+M``(NR@``0@,``K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''>@`#0`X`
+M`K`0``/_```"00D``J`0``('>@```AD``_\```/_```"P`X``((9``*Q`@`"
+MI`$``@<```!!X````<,``_\```/_```#V(```]P```*_"0`"L````]P!``*P
+MP``#V`$``BZT```![@`#_P```_\```+`#@``@>X``B_O``-`"@`"L$```_\`
+M``)`"0`#H`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$`
+M`VID``(NO0`"+LH``T`E``!"`P`"L"```D`%``/P2``"L`(``J#>``/P00`#
+M@`(``D`(``/P`@`#]````<>_``-`+@`#_P```K`(``)!"``"H!```@>_``*P
+M@``"00@``_`%```",@`#_P```_\```*@#@`"![\```(7``/_```#_P```^@0
+M``"*%P`"I`X``@<R```!X```0<,``_\```/_```#V````]R```*_"0`"L,``
+M`]@!``*P```#W`$``C)@``-H:P``$=8``K/```/HT``#8G0``BVS``(P'@`#
+M[````&HQ``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_
+M````V>P``C"E``/H```"+H(``KL"``#:,``#Z````K%@``/H(``#Z#```VF@
+M``/H```"L1```^@@``/H,``#:D0``C`H``*_`@`"+_0``K#_``*Q_P`"LOT`
+M`K/_``-H8```"BT``!'^```9_0`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+00``VAK``/_
+M```#_@```C`>``-*8```,?X``#G]``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"```*R"0`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``",EH``^AP``-*9``"M(```D`$``/H(``#Z#```VID
+M``-*9``"M(```!'L``)`!``"M`,``F`$``*S$``#:F0``BZ]``-*9``"M`@`
+M`D1```)G=``"I7X``@AX``/H```"+H(``J#>``/P`P`#2"(``_0```/P00`#
+M2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H(@`#:HH``_0```/P
+M0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R#T``T`2``#QY0`"OP0``J#>
+M``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R'@``C`>``/L````:C$`
+M`/'O``/H````@@8``T`(``-`+0`"N$```KD(``)*"``#JJH``DM)``.KM``"
+MLP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!```/P
+M00`#Z#```D$>``/P`0`#Z#```)H%```AY0`#Z%```_\```"B#```J>4``&HQ
+M``/_```#_P```J#>``/P`P``6<(``_0```/P0P``6<$``_\```/_````V>``
+M`T`L``!:'0`"M`0``^CP``)$0``#\`$``K\!``)+O@`"H+X``_`#``(O)0`#
+M]````<BW``*_RP`",8H``/(8``#R%P`",EH``C`H```*+0``$?X``!G]``*P
+M`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B(0`"I#X``_`!
+M``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"``*R```"LP$`
+M`J`K``/P`@`#Z"```\$[``-J:``"L`$``K((``)`"0`#\`$``^@@``*P$P`"
+ML0(``X(F``/H,``#:G```T`M``!B!```$AH``K]```)/3P`#\`,``J#.``/P
+M`0`"L@@``K`A``*Q`@`"LP$``VIT```*'0`"L`$``_\```)!$``"I!X``_`%
+M``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P``
+M`K`!``*Q`@`"LP0``VI\```*'0`#_P```_\```)!'@`"I!X``@E/```"!@`#
+M_P```_\```+`#@``@@8``B_O```"&``#0`H``T`-``*@#@`#\`4``K`"``)`
+M!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"'0`#_P```_\`
+M``)`#@`"I`X``_`+```2&@`"L",``K$#``*S`0`#:G0``TI\``/_```"L`$`
+M`K$$``*S!``#:GP``TID``*T@```$>```D`$``)@"``#HB(``K,!``-J9``"
+M+KT``B[*```![P`#_P```_\```*@#@`#\$X``T`L``*\!``#W,```K_```*@
+MW@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+8L``^CP``#Y[P```@8``_\`
+M``/_```"P`X``((&``!:'0``>A<``K@(``)*O@`"H*X``<EP``.JL``"2JX`
+M`_!#``(KQ``#]````<EO``-*<``"NH@``KEP``*@^``#\$,``\$J``/T```!
+MR6T``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C%7``(R6@``"@4```(&``-`
+M+@`#_P```J`!``()A``"L`$``D$(``/P!0```C(``_\```/_```"H`X``@F$
+M``-*=```>AH``_\```/_```#P2\``VIT``(O[P```A@``T`*``-`#0`"H`X`
+M`_`%``*P"``"0`4``X````/T!``#\`,``K`@``)`"0`#H````K%#``)H`0`#
+M2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"+LH``$(#``*P
+M`0`"H-X``_!!``.``@`"0`@``_`"``/T```!R;4``T`*``/_```"L$```D$(
+M``*@$``"";4```(8``/_```#_P```L`.``""&``"L0(``J0!``()#````>``
+M`$'#``/_```#_P```]@```/<@``"OP@``K#```/8`0`"L````]P!``(NM```
+M`@8``_\```/_```"P`X``((&``(O[P`#0`H``K"```/_```"0`D``Z`$``*Q
+M`P`":`$``TID``*T@```$>```D`$``)@"``#HB(``K,!``*Q```#:F0``BZ]
+M``(NR@``0@,``K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```')]P`#0"X`
+M`_\```*P"``"00@``J`0``()]P`"L(```D$(``/P!0```C(``_\```/_```"
+MH`X``@GW```"%P`#_P```_\```/H$```BA<``J0.``()3P``8<,``%G@``/_
+M```#W,```]BP``*_"``"L,```]@!``*P```#W`$``C)@``-H:P``$=8``K/`
+M``/HT``#8G0``BVS``(P'@`#[````&HQ``/_```#_P```J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``_\```/_````V>P``T`0``*['P`#2"D``J#>``/P00`#
+M2"T``D`+``.O`@`#C/8``FS/``./]@`#2>@``J-,``/P!``#!$P``P5?``/T
+M```#\$(``P3$``,%]0`#P00``\$5``*@W@`#\`0``V@I``-IZ``#]````_!"
+M``-H+0`#:>P``^@```(NE@`#Z````K%```/H(``#Z#```VI$``(P*``"OP(`
+M`B\E```*+0``$?X``!G]``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"L0(``K(*``/H
+M,``#:F@``K"```*R"``"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP
+M``*P(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP`
+M`_\```*P`@`"L0(``K,$``-J?``",EH``^AP``(O[P`#2F0``K2````1[``"
+M0`0``K0#``)@!``"LQ```VID``(NO0`#2F0``K0(``)$0``"9W0``J5^``(*
+MN0`#Z````BZ6``*@W@`#\`0``T@J``-)Z``#]````_!"``-(+@`#2>P``KP1
+M``*_$``"R9\``LB,``/P00`#Z(```\$(``/!&0`"H-X``_`$``-H*@`#:>@`
+M`_0```/P0@`#:"X``VGL``-*P``"OP<``DW>``/P`0`"OS@``J&.``/P0P`"
+M8`\``VK```-JQ``"NP$``-HP``/H<``"3_```_`#``*[_P`"H(L``_`"``/T
+M```!RG$``T`2``#QY0`"OR```J#>``/P`P`":J\``_0```/P00`":[\``V`2
+M``(P*``"+^\``^P```!J,0`#Z````(',``*@W@`#\`,``%G"``/T```#\$$`
+M`%G!``*P?P`"H?X``_!!``)+L```V>```C):``(P*```"BT``!'^```9_0`"
+ML`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&```)B(0`"I#X``_`!``*S
+M!``#0!4``K$(``*V\``"1$8``F$4``-J8``"L`$``K$"``*R```"LP(``VIH
+M``*R"``"L!,``K$"``.")@`#Z#```VIP```2&@`"L"$``K$"``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P`0`"L0(``K,$``-J?``"
+MO`0``]S```!YX``"O`@``KL8``/8\``"+8L```',``-`)0`"OQ```L`.``"!
+MS``"3U\``_`#``(KQ``#]````<L6``*_"``"H`X``_`!``/!_@`",5<``TJ`
+M``*@_@`#\$$``VJ$``!AX``"L(```^CP``*AP``#\$$``\'^``(K=P`"+^\`
+M`!'@``/H$``"L",``Z(B``*S`0`#:F0``BZ]``!AS````>````G#``-`)@`"
+MLA```]@```/<$``"OP@``K#```/8`0`"L````]P!``)"*0`#\$4``Z_P``*@
+MS@`#\`(``_L```/[`0`#T)X``_L```*E+@`#\`$``_L```/4GP`#^P$``J4N
+M``/P`0`#^P$``P_^``(+.````<P``_\```/_```"P`X``(',``!AX``"L(``
+M`\'^``*AP``#\$$``^CP``(K=P`"+^\``!'@``*P`P`#Z!```Z(B``*S`0`#
+M:F0``BZ]``(NR@`#0"4```',``*Q`P`"L@@``K,0``)#-0`#\`(``D(E``/P
+M`@`"I0$``<L#``!APP``6>```_\```/<P``#V+```K#```/8`0`"L````]P!
+M``*_"``",F```VAK```1U@`"L\```^C0``-B=``"+;,``C`>``/L```"O!$`
+M`J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(\0`"*Z\``J#>``/P!``#
+M:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$``-(U``#2-D``_0```/P
+M0@`#2/0``TCY``(KKP`"H-X``_`$``-HU``#:-D``_0```/P0@`#:/0``VCY
+M``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#\`0``L`,``+!'``#]```
+M`_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P00`#:/P``^P```*@_@`#
+M\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L``+'?``#]````_!(``,`
+M#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP``^P```*P?P`"L?\``K+_
+M``*S_P`#:&```VAK```)U@`#Z````Z`#``/<```#V!```T`Q``*_`P`"O`(`
+M`J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^``/P00`#
+MP00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""](``T`U``*_
+M`P`#_P```J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^
+M``/P00`#P00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""^H`
+M`T`X``-`/0`#_P```VJ$``-J@0`#[````TA5``/_```"M\```VA5``-H:P`#
+M2`H``K]_``)H^``"LN\``Z"!``*_PP`"0`\``T`E``*S_P`"L?\``D]>``/P
+M`@`"N?,``D(I``*\`@`"3%P``_`!``*S^P`#:&```TA```./\@`"O/L``D$<
+M``)A'P`#:$```VAK``-)?``"M`0``F$4``-I?``#2I0``_\```-A?``#:&L`
+M`C%$``/_```#_@```_\```-!20`#_P```_\```-(9``#B$0``ZB```/H\``#
+MW/```KQ```+,R``#V,```]0>``(R9@`#84D``TAD``*T$``"1B0``_`"``/T
+M```!S)D``TAD``-(-@`"M$```K4$``)$0``"15@``F1%``',60`"M#P``D1`
+M``/P0P`".KT``_0```',*P`#0!0``_\```/_```"PSX``_!!``,#/@`#8!0`
+M`K#_``*Q_P`"LO\``K/_``-JD``#^`,``TAD``.,Z@``\@@``DP,``',=0`#
+M2#0``KP$``),P``"#&0``.((``-)/0`"OQ```D1/``/P!``"O_\``BT$``*_
+M4``"+00``K\(``(M!``#]````<R&``-(0@`#2=0``#(S``*U$```FC,``KQ`
+M``)%4P`#\`D``DS)``/P!P`"H&,``_!%``#R`@`"-&L``VAK``/T```!P$$`
+M`TA4``*U/P`"0U,``K</``)C-P`#:%0``C)@``/H````@@(``T)Q``(R9@`#
+M8G$``T@(``*T@``"1$```_`"``/T```!UNP``^P```/X`P`#2`@``K2```)$
+M0``#\`(``_0```'6[``#2=```K@(``)).``"H)@``@SP``-)U``"M!```D,T
+M``*@-``"#,X``T@(``*X"``"8`@``V@(``-(*``"N"```F,X``-(+0`#:"@`
+M`VGH``)G>``#:"T``VGM``-(R``"N/L``D(H``-HR``#2)@``K@@``)@"``#
+M2+$``VB8``)D2``#:+$``\$.``/!'@`#P2X``\$^``-C,``#8W```V,T``-C
+M=``#8S@``V-X``/T```!S/```T@(``*X]P`"0`@``V@(``-(*``"N-\``D,X
+M``-(+0`#:"@``VGH``)'>``#:"T``VGM``-(R``"N`0``F(H``-HR``#2)@`
+M`KC?``)`"``#2+$``VB8``)$2``#:+$``K`#``/!$``#P2```\$P``-C,``#
+M8W```V,T``-C=``#8S@``V-X``-)?``"M/L``D$4``-I?``#:&L``_0```',
+M*P`#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(``VC*``)H(0`#:,H``\&"
+M``-HR@`#[````_@#``,/_@`"#04``^P```(R8``#:&L``\$.``/H$``#Z"``
+M`^@P``.D$P`#V!```]Q```/^```#U!X``VAK``-II``#Z````_X```/4'@`#
+M:&L``VFD``*@W@`#\`,``T)@``/T```#\$$``T)<``-"60`"H-X``VFD``/P
+M`P`#0F@``_0```/P00`#0F0``VFA``/^```#U!X``VAK``-H:P`#[````C)@
+M``-H:P`#0E8``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/4'@`"OP(`
+M`BT$``-H:P`#::0``VFB``/H```#_P```]0>``*_`@`"+00``VAK``-II``"
+M,F```VAK``/L```#:&L``C)@``*Q#``#Z````Z`#``/<```#V!```^@```/H
+M$``#Z"```^@P``/^```#U!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>
+M``-H:P`#^P```PB.``(-6@`#[````"'K``/H4``#Z&```^AP``*Y"``"N,``
+M`]R!``/8D0`#0E```_@#``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#
+M:&L``\&/``*_$``"+00``K09``/^```#U%\``VAK``*_$``"+00``\'X``-)
+MI0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#"9X``@V'
+M``-II0`#[````J&^``/P#@`#T!X``P^^``*Z/P`#``X``D`*``,!'@`"01H`
+M`P(N``)"*@`#`SX``D,Z``/4'@`##_X``@V0``/[```##,X``@V+``/L```"
+MH;X``_`.``/0'@`##[X``KH_``+`#@`"0`H``L$>``)!&@`"PBX``D(J``+#
+M/@`"0SH``]0>``,/_@`"#:0``_L```,,S@`"#9\``^P```/0G@`#T!\``KP_
+M``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP``KP@``+`A``#H```
+M`J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#
+M\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``KP'``*CW``#\$X``W)T``-2
+M=@`#_P```_\```/^```#U!X``VAK``/[```#<G8``U)T``/_```#_P```_0$
+M``/P"``"O`@``J3<``/P`0`#:H0``KP)``*DW``#\`$``VJ```(R6@`#^P``
+M`_L!``+-W@`"IM\``@VS``(O[P`"L````K$```*R```"LP$``VIT``*P,0`"
+ML08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#:GP``TID``*T
+M@``"0`0``K0#``)@!``#:F0``BZ]``-*9``"M(```D`$``-J9```:C$``C&R
+M``/L````6><``&(P``/_```"H;X``_!"``#QY0`#[````J'.``/P00`#"[X`
+M`PS.``#9YP``XC```TI```!:"0`#_P```_\```*@O@`#\$(``Z````.B(``#
+MT%X``&'\``!9XP`#H@(``D`)``)"*0`"I8X``@X\``,(C@`"H`T``_`+``!!
+M^0`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$3P`#P50``J6N
+M``(.3``#"JX``J`M``/P"P``4?D``L9O``/!=@`"H+X``_!&``/47@`"QF\`
+M`\%V``/47@`"QF\``\%V``/47@`##,X``@Y-``)KB@`"#A$``^P```-"<```
+M4@D``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"H6@``_!!``+&
+M:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&:``#`B@``P,X
+M``,*K@`"#F```\%4``/!=@`#U%X``V)P``/L```#P6(``P9N``/<$``#V```
+M`]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X``_L```,&;@`"
+M#G4``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#:1```VD4``-I
+M&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I-``#[````\$0
+M``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<``/T```#\$4`
+M`VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4``D$#``-)T@`#
+M_P```D`*``-)P@`"I1```_`!``-)Q@`#[````]">``/[```#_P```_\```/4
+MGP`#^P$``P_^``(.M``#[````_@!``*_!``#2F0``_\```/_```"00\``@Z_
+M``/X`P`#:&L``_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\`
+M`@[K``-`$@`"M1```J4E``/P!``"OP(``FJO``/T```!SN@``L15``*E)``#
+M\`0``K\"``)KOP`#]````<[H``+$10`"I20``_`$``*_$``":J\``_0```'.
+MZ``"OQ```FN_``#QY0`#8!(``B[L``/L```#2G```_\```/!P@`#0"X``K`!
+M``-JJ``#_P```_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,`
+M`TJM``*_D``"H,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#
+M\`L``T`9``/_```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P
+M20`#0!T``_\```/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P`
+M``+$1@`#:JD``_\```/_```#_P```TJL``/L```",F```VAK```)U@`"L,``
+M`]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P50`#
+MP1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$``*T
+MJ@`#P50``\%D``/!=``"O`<``J/^``(/G@``0?\``_\```/_```"H(X``@]D
+M``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J,0``:@```J3>``/P!``#P(@`
+M`\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G>P``
+M:C$``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK``/[
+M```##,X``@]D``!!_P``8@```_\```*@C@`"#XD``T!*``*DS@`#\`0``\"(
+M``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`":JL`
+M`KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@2@`#
+MP1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+``/!
+M$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,``J#Y
+M``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"#ZH`
+M`K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L```"
+M,F```VAK```)U@`"L,```]P```/8$``"M/\``\%D``/!=``"O`<``_X```*U
+M_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X``VAK``/[```##,X``@_%
+M``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#2F(``B_O``/H\``"+_L`
+M`VIB```)U@`"L,```]P```/8$``"M/\``\%4``/!9``#P70``KP'``/^```#
+MU%X``VAK``/[```##,X``@_G``(R6@`#[````TID``*T@``"0`0``VID``/L
+M```"L`0``J#P``/P`P`"+R4``_0$``/P`0`"*\0``^@```/````#P1```K+]
+M``*S_P`#:&````HM```Q_@``&?T``K`*``*@W@`#\$$``K`,``.!%@`"8`$`
+M`K$6``*D/@`#\`$``K,$``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"
+ML@0``F(F``-J8``#C^$``BT$``-H:P`#_P```_X```/L```#2F```_\```/H
+M,``"8`X``VI@``-*9``"M/(``D`$``-J9``#[````K`!``/H$``#Z"```^@P
+M``-J8``#[````&HQ``-`!``#_P```K@$``)%X``"H%X``_!$``*@W@`#\$(`
+M`T`D``/_````8>D``_\```/_```#W,```X_J``*@W@`#\`$``^CP``/8\``#
+MC.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<``D`(``/P
+M0P`"+8L``_0```/P00`"+9\``D1N``/P"0`#Z,```ZMB``.E8``"15X``_!#
+M``(MBP`#]````_!!``(MGP`#[````&HQ``-`*``#0"$``KA```)(@``#\`,`
+M`D9N``/P`0`#[````%'#``*@W@`#\`,``%G"``/T```#\$$``%G!``/_```#
+MW*```]BP``-`!@`#_P```_\```)`Z``#\`,``J#>``/P00`#0"8``_\```/_
+M```#24$``J`.``/P0P`"H-X``_!!``/!10`"14X``_!#``.,Y``#]````_!!
+M``.,XP`#B9@``ZJ<``*@K@`#\`,``BV+``/T```#\$$``BV?``-`!@`#_P``
+M`_\```-)00`"0(X``J`.``/P0P`"H-X``_!!``/!10`#Z,```ZM"``)%3@`#
+M\`<``Z5```)%7@`#\$,``BV+``/T```#\$$``BV?``/L```"H-X``_`#``-(
+M(0`#]````_!!``-()0`#_P```KL!``.B9@`#@68``Z$6``.'=@`"8"<``P`+
+M``.G!@`#@@8``F8A``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`^P```./[0`"+00``^@P``."X``#Z!```^@```-H,``#C^T``BT$``-)G``#
+M2=4``T`J``*T$``"1$<``K4"``)%6@`#A50``D1%``.D0``"MO<``D(F``)B
+M)``#:9P``^CP``-)<``#Z'```K8!``/!40`#P4```V@Q``*X_``#P5,``\%"
+M``)%6``#270``C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29@`
+M`C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29P``C%$``-H,0`#
+MP5$``\%```(Q1``#:#$``\%3``/!0@`#2.@``C%$``-H,0`#P5$``\%```*W
+M$``",40``V@Q``/!4P`#P4(``C%$``-H,0`#[````KP#``-)/0`#2,```J#>
+M``/P00`#2,0``K8$``)&9``#\`0``X;*``/!?``"8B8``F$7``*@W@`#\`,`
+M`VC```/T```#\$$``VC$``-`*@`"M@@``X?&``)&:``#\`$``F,W``*@W@`#
+M\`,``VC```/T```#\$$``VC$``/L```","X``TD]``-`*``"OP@``KP$``)/
+M#P`"3$P``F#\``/P00`#[````K0!``(R`@`",0D``J'^``/P"0`",<,``C`H
+M``-`*``"O`@``_\```)"+``#\$(``_0```/P0@`#Z$```C("``/L```#_P``
+M`_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@``/H,``#
+M:.@``^@```/_```#:.@``T%(``/_```#[````C)@``-H:P``"=8``^@```.@
+M`P`#W````]@0``*\`P`"L/<``J#^``/P00`"L'\``\$0``/!(``#P3```K3_
+M``/!5``#P60``\%T``/^```#U!X``VAK``.@`0`#H1$``Z(A``.C,0`#^P``
+M`_X```/47@`#:&L``_L```,,S@`"$6H``K#_``*\"``#P1```\$@``/!,``#
+M:H```J3^``'1A``"H/P``_`"``-JA``#[````K#W``.A`0`#HA$``Z,A``-J
+MA``#[````TD]``/_```"N(```F1(``-I/0`"L`$``K$"``*R/P`"0B\``K,`
+M``-J:``"L````K$```*R```"LP(``VIT``*Q`0`"L@@``K,```-J>``"L`$`
+M`K(```-J?```$>```K#```)`#P`#H`(``F`.``*Q```#HB(``K,!``-J9``"
+M,EH``_\```/_```"+KT``KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S
+M```#:#```^P```-`+``#_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8
+M``-@'``#[````&HQ``*P`0`#Z!```^@@``/H,``#:F```K\!``(O]``"OQ``
+M`BT$``*\%``#2F```K_W``*Q$P`"0`\``F`.``-J8```,?X``#G]``*\B``"
+MM?X``X9J``)B)@`"I'X``_`!``*S!``"0`4``F`,``-J8``#2I8``T`I``*\
+M!P`#_P```D1,``.%1``"Q5X``\'%``/H0``#Z&```^AP``-JD0`"M/\``K5_
+M``*V_P`"M_\``VAA``-H:P`#_P```_X```,)G``#\$4``\"9``,*K@`#\$(`
+M`\"J``,+O@`#:I(``X````.@```#:F```K\0``(M!``#[````T`J``-'+``"
+MH-X``_!!``-';``"MG\``X5,``)`!@`"29X``_`!``)@!0`#P1```\$@``/!
+M,``"H-X``_!$``-G+``#9S```_0```/P0@`#9VP``V=P``-'-``"H-X``_!!
+M``-'=``"MM\``X5(``)`!@`"8`4``\$0``/!(``#P3```J#>``/P1``#9S0`
+M`V<X``/T```#\$(``V=T``-G>``#2,```J#>``/P00`#2,0``K8_``)")@`"
+MML```J!.``/P`0`#Z&```F(F``*@W@`#\`,``VC```/T```#\$$``VC$``/L
+M```#29@``K@/``*Y]0`#Z#```\$N``*@S@`#\`(``F`(``)!&0`#:#```T@(
+M``*X0``"H,X``_`"``)@"``#:`@``^P```-A4``#854``V%:``-A7P`"+`4`
+M`T%0``-!50`#05H``T%?``/_```#_P```^P```*P_P`"L;\``K+_``*S_P`#
+M:&```^P```*P?P`"L?\``K+_``*S_P`#:&```^P```+$3@`#\$H``L5>``/P
+M2``"QFX``_!&``+'?@`#\$0``K3_``*U_P`"MO\``K?_``/L```"H<X``_`'
+M``,,S@`"OWP``BT$``/_```#_P```PS.``(2=@`#[````^@```"",0`"(N``
+M`/(Q``(BX``",O@``BSW``-)F``"M/<``K4/``)!%``"8`4``VF8``/!+@`#
+MZ#```V@P```""@`#@>```^A```*@`0`#\`$``\%.``(T7@`#2`@``KC^``)!
+M&``#:`@``KP```(T"0`"-#H``T`!``/H````@C$``D1.``/P`0`")!L``T`!
+M``/_````\C$``D5>``/P`0`")!L```(*``.!X``#_P```J00``/P`@`#P4X`
+M`C1>``*\`0`"-`D``C0Z``*_`P`"-N0``C-%``(NJ``"OQ```D_[``'2X```
+M><L``_\```/_```"H/X``_`&``*]```"-IX``KT!``(VG@`#]````=+H``-`
+M```"O````.(Q``*A#@`#\`$``C20``-````#_P```/(Q``*A'@`#\`$``C20
+M``-`!``#0`$``KP(``),P0`#\`H``KT```)$3@`#\`$``C;$``*]`0`"15X`
+M`_`!``(VQ``"OP```/G+``/T```!TN@``TG0``*\@``"3,,``_`$``*]```"
+M-GX``KT!``(V?@`#0"P``KA```*Y@``"N_\``TJE``)(&``#\`$``KO/``))
+M&0`#\`(``KH_``)+N@`"15L``VJE``/T```!PEP``TG1``(NJ``#Z(```J40
+M``/P`0`"N$```D1X``.$0``#2)P``K4$``)D10`"MG\``D`&``)@!``#:)P`
+M`VB@``-HM``#:+@``TDX``*U_``"0B4``K4,``)B)0`#:3@``^@```/HT``"
+M+H(``\'>``(N@@`"+J@``X3B``/!R0`#Z````K$#``*R"@`"LRT``D1)``/P
+M`0`"LR\``^A0``(N<0`#@.H``BYQ``*X+P`"M`(``D1,``/P`0`"N"T``\&8
+M``/!J``#P;@``V,J``-C:@`"+J@``X'B``.@X0`#HY8``X+D``+"+@`#Z%``
+M`BYQ``.@XP`"+G$``BZH``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#
+M@.```H((``)"`@`#@B0``)'4``/L```"+J@``TEP``)$C@`#\$,``K7S``)"
+M)0`#:7```^AP``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D
+M``/!4P`#P4(``V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@`
+M`X1```.%1@`"8`4``F$4``/H,``#P2X``V@P``-#I```(=0``K7/``)`!0`"
+M8`0``\$0``/!(``#P3```V.D``-CY``"1$0``_`!``(VWP`#@80``Z`8``."
+M!@`"8`(``^C0``(NE@`#P=X``BZ6``-)T0`"+J@``^A@``*E$``#\`$``K9`
+M``)&=@`#IFH``TB0``.DN@`"H$X``_!!``*T!``"M0,``J!%``/P00`"M`$`
+M`K7P``)!%0`"810``K?^``)`!P`"8`8``VB0``-HJ``#:)0``VBL``.@I@`#
+MP1```\$@``/!,``#9"0``V1D``.*M@`#2"$``K@#``)F:``"N0\``KO^``)&
+M:0`"9FH``D=[``-H(0`#:HD``V@E``-JC0`#2`@``T@A``)A'@`#:`@``TC(
+M``*X0``"N3\``F`(``-HR``"0`D``VC(``/L```#0"P``KA```*Y@``#Z+``
+M`TJE``)(&``#\`$``KLP``))&0`#\`(``KK```)KN@`"95L``VJE``-(G``"
+MO'L``D`,``-HG``#:*```VBT``-HN``#2)```X3B``.EYP`"014``F$4``*U
+M_@`"0`4``VB0``-HJ``#:)0``VBL``-).``"M0,``F(E``*U\P`"0B4``VDX
+M``/HP``"-`D``C0Z``/H```"L0,``K()``/H,``#Z%```BYQ``.`Z@`"+G$`
+M`K`$``/!$``#P2```\$P``-C)``#8V0``K`@``/!$``#P2```\$P``-C*``#
+M8V@``C;?``-("``#2"$``ZCM``)!&``#:`@``ZCK``)&:``#P#X``D53``-H
+M(0`#:HD``V@E``-JC0`#Z$```C1>``/H\``"/B(``K\!``(^(@`#[````T`I
+M``/_```"N"H``D)>``/P`0`"N&0``J#.``/P00`"N!```\&8``/!J``#P;@`
+M`V<N``-G,@`#9VX``V=R``*X*@`"0EX``_`!``*XY``"H,X``_!!``*X$``#
+MP9@``\&H``/!N``#8ZX``V/N``-(G@`#P!0``Z$<``.!%``"L/<``DB```)H
+M@0`#:)X``VBB``-HM@`#:+H``TKJ``*P^P`#@2(``DJ@``)JH0`#:NH``VKN
+M``-J\@`#:O8``^P```-`*0`#1S8``K`'``*Q"``"0EX``_`!``*Q&``"H,X`
+M`_!!``*Q```"2(```FB!``/!F``#P:@``\&X``-G-@`#9SH``V=V``-G>@`#
+M0[(``K`'``*Q*``"0EX``_`!``*Q.``"H,X``_!!``*Q```"2(```FB!``/!
+MF``#P:@``\&X``-CL@`#8_(``^P```-)=``#P6X``^AP``.(2``#P%X``X59
+M``)")0`"8B@``VET``/!0@`#P5,``V@Q``/L```"OP,``C;D``-("``"N/X`
+M`D$8``-H"``#0"@``KP$``*_`P`"3,(``_`#``(]RP`#]````=2+``-(5``"
+MO&```F(L``-H5``#278``KP0``)DK``#P5L``\%N``/H<``#:#$``C%$``-(
+M5``"O)\``D(L``-H5``#P4H``V@Q``(SJP`#0D4``C)F``-B10`#[````&HQ
+M``(M"```\>4``C`H``(KQ``#0`0``T`*``*\`P`"OP0``D$<``,&\0`"0`\`
+M`_`!``/!:@`"Q&X``K4(``(XK@`#0`0``^CP``#Z!@`"LD```D(@``'4\0`#
+MCP0``Z_X``#Z`P`#2<$``KP/``)(SP`#J(```XF"``*ZXP`"1$H``F1)``))
+M_@`#B9(``KK[``)%6@`"95D``VG!``.!A@`"8($``BZ6``/H```"H-X``_!!
+M``*P0``"L0,``K()``*S"0`"1.\``_`!``*S#P`#Z%```BYQ``*C_``!U/$`
+M`^C```#AS@``X>X``C97``-`&``"H-X``_!!``-`'```0>X``&'.``)@`0`"
+M8`(``F`#``*A#@`#\$(``LB.``#![@`"N@(``KL?``+,R@``X<X``J7+``'4
+MS```2@8``'H#``/_```"H8D``=3L``,/_@`"L!```L_P``/H````@>4``_0`
+M``'4J@`"S_X``/H#``#"!@`#]````=2J``/HP```X@,``^@P``(V:P`#W.``
+M`K\(``/8\``"L"```\$0``/!(``#P3```K\1``/4'@`#_P```_L```,/_@`"
+M%/T``C97``!B`P`"L````]P```/<`0`#C\(``K!```+`#P`#V````K`_``)!
+M#P`"L,```L`!``/8`0`#U%X``]`?``*_$``"H<\``=4>``*@W@`#\`,``\$*
+M``/T!``#\`$``\$+``/4'P`#]````=4E``*@W@`#\`,``\$J``/T!``#\`$`
+M`\$K``/4'P`"-@\``T`&``*P'P`"L2```\$N``)!&``#\`$``L(N``+,P@``
+MX@,``J7```(5`@`#2I0``_\```-@O``#0`0``]S@``*_"``#V/```]SA``*_
+M+``#V/$``K\(``.L%@`"I<\``_!#``/`S``";,\``LS.``*_"``#T!X``]!?
+M``/!B0`#P9H``\&K``+$0``#H$```L`,``/!L``"Q5$``Z%0``+!'``"IAL`
+M`_`!``/!L0`"QF(``Z)@``+"+``"IBL``_`!``/!L@`"QW,``Z-P``+#/``"
+MICL``_`!``/!LP`#U!X``]2?``/[```#^P$``P_^``(50P`#03@``T%)``-!
+M*@`"O`X``J,!``/P`0`#P0$``J,"``/P`0`#P0(``J,#``/P`0`#P0,``J,(
+M``/P`0`#P0@``J,)``/P`0`#P0D``^@0``*F#``#\`,``\````.`!@`#H08`
+M`\$!``*C10`#\`$``\%%``*C1@`#\`$``\%&``*C1P`#\`$``\%'``*C2@`#
+M\`$``\%*``*C2P`#\`$``\%+``/H(``"IDP``_`#``/`1``#A$8``Z)&``/!
+M,@`"H-X``_`#``-DJ``#]`0``_`!``-DZ``#W.```K\(``/8\``#T%X``K\$
+M``/<\0`"OX```J#>``/P00`"O\```]CQ``*\$``"N`$``KD#``*Z#P`"H4P`
+M`_!%``/`1``"1$H``P0$``/T!``#\`(``P1*``+$0``"H5P``_!%``/`50`"
+M15H``P4%``/T!``#\`(``P5:``+%4``"H6P``_!%``/`9@`"1FH``P8&``/T
+M!``#\`(``P9J``+&8``"H7P``_!%``/`=P`"1WH``P<'``/T!``#\`(``P=Z
+M``+'<``#U%\``_L```/[`0`#T%X``PB.``(5J0`"N`$``\$!``/!$@`#P2,`
+M`PF>``(5J0`#1*@``J#>``/P00`#1.@``J%,``/P10`#P$0``D1*``,$!``#
+M]`0``_`"``,$2@`"Q$```J%<``/P10`#P%4``D5:``,%%0`#]`0``_`"``,%
+M6@`"Q5$``J%L``/P10`#P&8``D9J``,&)@`#]`0``_`"``,&:@`"QF(``J%\
+M``/P10`#P'<``D=Z``,'-P`#]`0``_`"``,'>@`"QW,``]1?``(L]P`"-&L`
+M`C`H``(O[P`#[````BZH``.CE@`"-FL``X#E``)#H``"-G0``_0```'6`@`#
+MP9```J'/``/P`0`#P9(``V)U``#)S@`#W.```K\(``/8\``#W.$``K\L``/8
+M\0`"OP$``\$$``(V,0`#0G4``K\!``/_```#P04``C8Q``-"=0`"OP$``_\`
+M``/!!@`"-C$``T)U``*_`0`#_P```\$'``(V,0```<X``K\```(V,0`#[```
+M`K(@``/07@`#T)\``D$.``/P1``"H$(``_!!``/!3``#P8P``Z````)!#@`#
+M\$0``J!2``/P00`#P5P``\&<``.@```"00X``_!$``*@8@`#\$$``\%L``/!
+MK``#H````D$.``/P1``"H'(``_!!``/!?``#P;P``]1>``/4GP`#^P```_L!
+M``.@```##_X``A8R``/L```"LQ```J7#``/P!@`#P#P``X,V``.C-@`"-G0`
+M`_0```'69``"LP\``LS.``)#/``"-FL``C&X``(L]P`"-&L``K\8``(X7``"
+M+NP``^P```*Q!``"L(```J#>``/P00`"L,```K()``/H4``"+G$``^P```/!
+M`P`#P1,``\$C``*@W@`#\`,``V2H``/T!``#\`$``V3H``/L```#0`0``KR`
+M``/_```"3,```=:>``-!`0`"H-X``_!!``-!!0`"L00``K"```*@W@`#\$$`
+M`K#```/<$``#V````\&$``(VNP`#P84``C:[``/!A@`"-KL``\&'``(VNP`"
+MH-X``_`#``-DH0`#]`0``_`!``-DX0`#]````=:X``*Q!``"L(```J#>``/P
+M00`"L,```]P1``/8`0`"L0$``K`(``*@W@`#\$$``K`L``/<$``#V````K\(
+M``(NM``#00$``J#>``/P00`#004``J#>``/P`P`#9*D``_0$``/P`0`#9.D`
+M`BSW``(T:P`#[````\&8``/!J``#P;@``K(!``/4G@`#^P```P(N``(6OP`#
+M[````K$$``*P@``"H-X``_!!``*PP``#W!```]@```*Q`0`"L`@``J#>``/P
+M00`"L"P``]P1``/8`0`"OP@``BZT``-$J``"H-X``_!!``-$Z``"H-X``_`#
+M``-A```#]`0``_`!``-A!``#[````TL,``*U_``"014``VL,``/L```#2PX`
+M`\#/``)JKP`#:PX``C%$``)*K``#:PX``^P```*_`P`"-N0``TG```-)U0`"
+M3`X``_!"``/T```!URD``TG```.'=@`"IG```_!"``/!$@`#Z````Z(6``.!
+M%@`#H18``TB1``*\\``"15P``F52``*\!``"0PP``Z,R``*\_@`"1$P``F1#
+M``-HD0`#:)4``VBI``-HK0`#P4$``\%1``/!80`#P7$``V0A``-D)0`#9&$`
+M`V1E``*\`@`"0@P``X(J``-(G0`"LW\``D1#``)D0@`#:)T``VBA``-HM0`#
+M:+D``J$.``/P`@`"-M\``K`0``/!$``#P2```\$P``-CH``#8Z0``V/@``-C
+MY``#27P``K3[``)!%``#:7P``VAK``/T```!S`4``C`H``(O[P`#0````_\`
+M``/_```#H`P``Z$<``.!$``"81```P\>``/HT``"H/X``_!!``*]`0`#P<X`
+M`T@(``/_```#A.@``F`$``-H"``#29@``K7[``)!%0`#:9@``K0/``)@!``#
+MZ#```\$N``-H,``#27$``X'A``/!!@`"87$``\$N``/H,``#:#```BU(``/X
+M`0`#0`T``_\```*P`0`"0`8``A=I``*@_@`#\`(``J#M``/P!0`"NSX``DNV
+M``.KL``#]`0``_`&``.F:@`"QFX``PNF``/T!``#\`$``^BP``-(&0`"LN``
+M`D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BT(``(M80`"
+MM`\``C%$``-*0``#^`$``J1```/P!@`"I$$``_`$``*D0@`#\`(``J!#``(7
+ME@`"RJX``K`@``*@H``#\$$``^B@``*@JP`"%\```T@9``*RX``"1F(``F9J
+M``-H&0`#2>4``_\```)&8@`"9FH``VGE``/T!``"%W8``J/^``(7R@``T=``
+M`J#>``(7GP``T=$``LW>``/T!``"%U4``$'1``/_```#_P```J"H``(7R@`"
+MH:@``_!(``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%\H``T@9``*R
+MX``"1F(``F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P
+M``)G<P`#:"4``VJ-``/T!``"%\H``T`1``/HP```\>4``KB```)G>``#8!$`
+M`TF8``*U!``"814``VF8``-("``#_P```X3(``)@!``#:`@``_@#``/L````
+M:C$``^@```""#```@<\``CC*``-`)``#_P```_\```)`#@`#\$L``T`0``*\
+M!``#W,```X_J``*@W@`#\`$``^CP``/8\``"O`D``\&Q``(MBP`#0"0``_\`
+M``*\`@`"0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/``
+M`XSD``/!L0`"+8L``BO$``*T!@`"M0@``K8$``(XK@`"OQ@``CA<``(X@P`"
+MOP```B_T``-*<``#_P```_\```*RD``#:G```K\3``(X7``".(,``T`D``/_
+M```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP
+M``*\"0`#BQ```BV?``-`)``#_P```KP"``)`#``#\$L``T`0``*\!``#W,``
+M`K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(MGP`#2G```_\```/_```"
+MLH```VIP``*_&``".%P``CB#``*_```"+_0``TIP``/_```#_P```K*0``-J
+M<``"OQ,``CA<``(X@P`#0"0``_\```/_```"0`X``_!+``-`$``"O`0``]S`
+M``./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+8L``T`D``/_```"O`(`
+M`D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"OX```]CP``.,Y``#
+MP;D``BV+``(X[``#[````^@```/````"L;\``\$@``*S_P`#:&```C`H``(O
+M[P``"BT``!'^```9_0`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$
+M``)B(0`"I#X``_`!``*S!``#P1\``VI@``-*9``"M(```!'L``)`!``"M`,`
+M`F`$``*S$``#:F0``BZ]``*_"``"3_```_`!``#R#``#[`````(,``/_```#
+M_P```J4.``/P`0`#[````^@```""#``#0!(``_\```/_```"1(X``J!.``/P
+M`0``\>4``K]```*@W@`#\`,``FJO``/T```#\$$``FN_``-@$@`"+NP``'G/
+M``/_```#0"```J#^``/P00`#[````J#>``/P!0`"P`X``_!!``*P_P`#]```
+M`_!#``+!'@`#\$$``K'_``-@(```\<\``^P```*P`0`"L0(``\$D``/H,``#
+M:F@``\$E``*P$P`"L0(``X(F``/H,``#:G```K`A``*Q`@`#P28``K,!``-J
+M=``"L`$``K$"``*R#P`"LP$``VIX``-*?``#_P```K````*Q```"LP0``VI\
+M``/L```"L`$``K$1``*R$``#:D0``K$0``/H(``#:D0``J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``-GL``-("``"M$```('F``)@!``#:`@``T@!``*POP`"
+M1$```V@!``/H```"L4```^@@``/H,``#:D0``K`!``/H$``#Z"```^@P``-J
+M8``#[````C`H``(O[P``(>8``_\```-("``#_P```\$$``-H"``#[`````HR
+M``!J,0`#_P```D`>``/P00`#[````CC*``*_```"+_0``#(:``/_```"M0D`
+M`Z9B``+&;@`"Q&X``CBN``-`*``#Z/```J#>``/P00`"OT```/G@``.@#```
+M@<4``T`8``-`'0`#0"X``&'E``/_```#_P```V%0``-A50`#85H``.''``-`
+M$```>>```KP$``/<P``#V/```KP)``/!L0`"+8L``^C```#AS@`"L!```K$`
+M``*R$``"LP```V)T``*P@``#V`$``K````/<`0`"L!(``K$"``*R$@`"LP(`
+M`V)T``*P$``"L1(``K(0``*S$@`#8G```V)$``-B3``#8D@``\&,``/!G``#
+MP:P``\&\``(YVP`",;@``K\3``(X7``"+NP``&'.``/_```"L````]P```*P
+M0``#C\(``L`/``/8```#0!@``J#>``/P00`#0!P``T`M``/_```#U!X``]1?
+M``*_`0`#W/```K\```.(P@`"S_@``]CP``/$```#Q!$``\0B``/$,P`"H-X`
+M`_!!``/!9P`"M1$``D1E``/$1``"P`0``K4B``)$90`#Q$0``L$4``*U1``"
+M1&4``\1$``+")``"M8@``D1E``/$1``"PS0``]0>``!YQ0`#0G4``T)R``)/
+M_@`#\$(``L`!``+"(P`"H00``_!&``*E"0`#\`0``\&,``/!D``#P:P``\&P
+M``*C"0`#\$(``\&L``/!L``#8G(``T)&``*A)@`#\$8``J4I``/P!``#P8P`
+M`\&2``/!K``#P;(``J,I``/P0@`#P:P``\&R``-B1@`"H/X``=FN``-"3@`"
+MH14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#\$(``\&L``/!
+ML0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!K``#P;,``J,Y
+M``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.'.``*@P0`!V3<`
+M`T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD``_\```+)`@`#
+MJ9```LM&``.KL``".=L``T`0``!YX``"O`0``]S```/8\``"O`D``\&Q``(M
+MGP`","@``B_O``-!4``#054``T%:``!AQP`#_P```_\```-@&``#8!T``V`N
+M``#AY0`#[````KLA``*[$````<4``_\```/_```"0`X``=H3``.IA``#JZ0`
+M`KP/``.(@``"2(P``XJ@``)*K``#2)P``TBA``*@W@`#\$(``TBT``-(N0`#
+MP1@``\%:``.,%@`#CU8``F$<``)E7P`"H-X``_`$``-HG``#:*$``_0```/P
+M0@`#:+0``VBY``-*Z``#2NT``J#>``/P0@`#2O```TKU``*\[@`"0`P``D1,
+M``.(E@`";)@``F`,``.*M@`";+H``F1,``*@W@`#\`0``VKH``-J[0`#]```
+M`_!"``-J\``#:O4``^P```*_!0`"O````J#>``/P00`"O$```]SP``/8P``"
+MO(```FB,``)IG``":JP``FN\``/!"``".BL``\$)``(Z*P`#P0H``CHK``/!
+M"P`".BL``]2>``/[```#U)X``^P```/!$``#P2```\$P``/4'@`#^P```]0>
+M``/[```#[````&HQ``(M"``#Z````K%@``/H(``#Z#```VF@``-)F``"N`\`
+M`K7U``*S```#P2X``F`(``)!%0`#:#```K\!``(M!``".,H``C`H``-`+``"
+MOP0``_\```)/\``#K_(``^CP``(O]```,AH``_\```*U"0`"Q&X``CBN``/H
+M\``"H-X``_!!``*_0```^>```%G'``!YX``"O`0``]S```/8\``"O`D``BV+
+M``/HP```X<X``.'&``/H@``#Z*```CG;``*_0``"O````]S!``/8\0`"OT``
+M`]S@``/8\``",;@``K\3``(X7``"+NP``J#>``/P00`#P:L``&'.``!YQ@`#
+MU%\``_L!``/07@`"NP(``J'^``/P00`#P4H``J#^``/P00`#P5H``J#[``/P
+M00`#P6H``J;[``/P00`#P7H``]1>``/[```"L!```LS.``*EP``#\`8``.'.
+M``/!C``#P:P``CG;``/T```!VFL``K$$``+/_@``^<8``J'Q``':I@`#Z+``
+M`-G.``/!BP`#P:L``CG;``!YX``"O`0``]S```/8\``"O`D``\&^``(MBP`#
+MW.```KM```/8L``#]````=IK``(X[``"N`@``KH(``(YVP``6<<``'G@``*\
+M!``#W,```]CP``*\`P`"R[P``KP)``(MGP`#2`@``K1@``)@!``#:`@``TF8
+M``/_```"L@$``^@P``-H,``#[````K0$``)&-``"H&0``=K*``/H\``"/?0`
+M`K\!``(]]``#:&L``T))``(R9@`#8DD``^P```-"30`",F8``V)-``-(9``#
+M^`$``KT,``))T@`"H-D``_!&``*_`P`".RD``K\#``*]```".PH``^P```*]
+M!``"2=(``_`&``*_`0`".RD``K\!``*]```".PH``^P```*]"``"2=(``_`&
+M``*_`@`".RD``K\"``*]```".PH``^P```*]8``"2=(``J#9``/P1P`"OP,`
+M`CNP``*_`P`"O0$``KP!``(["@`#[````KT@``))T@`#\`<``K\!``([L``"
+MOP$``KT!``*\`0`".PH``^P```*]0``"2=(``_`'``*_`@`".[```K\"``*]
+M`0`"O`$``CL*``/L```#2&(``DS.``(;'``#@/(``\````.!^``#P!$``DW>
+M``/P10`#P````FJ@``)*H0`#]`0``_`#``/`$0`"2J```FJA``-H8@`"L/(`
+M`FJ@``*@"@`#\$<``TA```*T"``"M?<``F$4``-H0``"014``VA```-H:P`#
+M[````TA4``/H@``"N0,``DO^``/P`0`":(D``KH"``*Y#``"2_H``_`!``)H
+MB0`"8S@``VA4``/HD``"M`0``DO^``/P`0`":9H``DOZ``/P`0`":90``TE@
+M``-H:P`#_P```_\```-(90`#_P```DO6``*@O0`!VZ<``DN3``';/@`#0"@`
+M`X3P``"B`@`#HB8``C%$``,"+@`!VTT``T@$``*T[P``BBP``D$4``-H!``"
+MM8```DO^``/P!0`#2)@``K2_``)#-``"8S4``VB8``)+^@`#\`4``TBP``*T
+MOP`"0S0``F,U``-HL``"/>@``K8$``-H,0`#0"@``C%$``)!&@`"&Y```$H!
+M``/_```"N(```\"9``.)G``"2_X``_`&``-)/``#2)D``F,X``)D20`#:3P`
+M`VB9``)+^@`#\`8``TE```-(L0`"8S@``F1)``-I0``#:+$``DO^``/P!@`#
+M2)```TB5``)@"``"9$@``VB0``-HE0`"2_H``_`&``-(J``#2*T``F`(``)D
+M2``#:*@``VBM``-`*``#_P```K@$``)!&``#\`$``CQH``-`*``#_P```K@(
+M``)!&``#\`$``CTJ``-(0``"N(```DO^``/P`0`"81@``DOZ``/P`0`"8B@`
+M`VA```*\`0`#[````TA4``/`B``"0S@``VA4``-"20`",F8``V))``*\```#
+M[````T`H``#YNP`"N`@``D$8``/P`0`"/4$``T`H``/_```"N`0``D$8``/P
+M`0`"/+<``T`H``/_```"N`(``D$8``(;YP`"2_X``AO*``-)/``#2)D``KA_
+M``)#.``"1$@``VD\``-HF0`"O`(``DO\``(;U``#24```TBQ``*X?P`"0S@`
+M`D1(``-I0``#:+$``DO^``(;W0`#2)```TB5``*X?P`"0`@``D1(``-HD``#
+M:)4``KP"``)+_``"&^<``TBH``-(K0`"N'\``D`(``)$2``#:*@``VBM``-`
+M*``#_P```K@.``)!&``"'`<``CT4``)!%P`#:,@``T@(``*X$``"01@``=P'
+M``)+_@`"&_P``T@@``*T`0`"M?P``F$4``-H(``"014``V@@``*\`@`"2_P`
+M`AP&``-()``"M`$``K7\``)A%``#:"0``D$5``-H)``"-N0``DO^``(<#@`#
+M2)@``K3```)C-``"0S0``VB8``*\`@`"2_P``AP6``-(L``"M,```F,T``)#
+M-``#:+```KP#``(]R``#2$```KA_``)+_@`#\`$``D(H``*\`@`"2_P``_`!
+M``)!&``#:$```T@(``*X$``"01@``=PQ``-`*``"O`0``_\```),P@`#\`,`
+M`CU8``/T```#\$$``CW+``).[@`!W#,``KP(``(]R```>;L``_\```/_```"
+M2_X``_`$``-(F``"M#\``D,T``-HF``"O`(``DO\``/P!``#2+```K0_``)#
+M-``#:+```TA```*X(``"2($``AQ*``(]Z``"M@(``V@Q``-)?``"N`(``DB`
+M``(<40`#27$``CWH``-H,0`#2`0``"(L``/_```#_P```\$4``-H!```>;L`
+M`K@```*\`@`#2%0``DO^``/P`0`"N`,``DO\``/P`@`"O`P``FB,``/`B``"
+M0S@``VA4``.`^```@@(``^P```-("``"N!```D$8``'<>0`"2_X``_`$``-*
+M5``"M`\``F`$``-J5``"NP(``DO[``/P!``#2E@``K0/``)@!``#:E@``DO^
+M``/P!``#2E0``K3P``)@!``#:E0``KL"``)+^P`#\`0``TI8``*T\``"8`0`
+M`VI8``-("``"N!```D$8``'<EP`"2_X``_`$``-*5``"M`\``F$4``-J5``"
+MNP(``DO[``/P!``#2E@``K0/``)A%``#:E@``DO^``/P!``#2E0``K3P``)A
+M%``#:E0``KL"``)+^P`#\`0``TI8``*T\``"810``VI8``-("``"N!```D$8
+M``/P`0`#[````DO^``/P!``#2E0``K0!``)B)``#:E0``KL"``)+^P`#\`0`
+M`TI8``*T`0`"8B0``VI8``/L```#2`@``K@0``)!&``!W,@``DO^``/P!``#
+M2E0``K3^``)")``#:E0``KP"``)+_``"',@``TI8``*T_@`"0B0``VI8``)+
+M_@`#\`0``TI4``*T#P`"010``VI4``*\`@`"2_P``AS5``-*6``"M`\``D$4
+M``-J6``#2`@``K@0``/_```"01@``=SG``)+_@`#\`0``TI4``*T\``"010`
+M`VI4``*\`@`"2_P``ASG``-*6``"M/```D$4``-J6``"2_X``_`$``-*5``"
+MM`\``D`$``-J5``"O`(``DO\``(<]``#2E@``K0/``)`!``#:E@``T@(``*X
+M$``"01@``=T%``)+_@`#\`0``TI4``*T\``"0`0``VI4``*\`@`"2_P``_`$
+M``-*6``"M/```D`$``-J6``"O`@``CW(``(]%``#P=\``DO>``/P`@`"OP``
+M`CWT``*\`@`"2]P``_`"``*_`0`"/?0``\']``/L```"M_P``K8S``*U1``"
+MM````TC(``*@_@`#\$$``K0!``*\`@`"H/P``_!!``*T`@`"810``VC(``)@
+M!0`#:,@``_\```)`!@`#:,@``KP"``(]R``#[````T@(``*X$``"01@``=T[
+M``)+_@`#\`0``TB8``*T?P`"0B0``VB8``*[`@`"2[\``_`$``-(L``"M'\`
+M`D(D``-HL``#23@``X3R``/`1``"0B0``VDX``/L```#23@``X3R``)B)``#
+M:3@``T@(``*X$``"01@``_`!``/L```"2_X``_`$``-(F``"M(```F(D``-H
+MF``"NP(``DN_``/P!``#2+```K2```)B)``#:+```^P```-"20`",F8``V))
+M``)!_@`"'64``T.N``*P[P`#_P```DNP``)*L``"2;```DBP``-CK@`"L0(`
+M`D'Q``(=<``#0^X``K#O``/_```"2[```DJP``))L``"2+```V/N``-(5``#
+MC/@``F(L``-H5``#270``KS?``)$+``#P5,``CWH``-H,0`",40``KP0``)D
+M3``#:#$``C%$``-(5``"O)\``D(L``-H5``#270``_\```/!0@`#P5,``CWH
+M``-H,0`"0?X``AV3``-#K@`"L!```_\```)KL``":K```FFP``)HL``#8ZX`
+M`K$"``)!\0`"'9X``T/N``*P$``#_P```FNP``)JL``":;```FBP``-C[@`"
+MO`(``D?^``),_``";,<``K<#``*@?P`#\$$``^C```-(R``"N$```KD_``)@
+M"``"81P``VC(``)`"0`#:,@``\#,``)!'``#:,@``KO\``)*_@`#\`@``T@A
+M``/_```"95X``V@A``-JB0`"15L``V@A``-JB0`"N@(``DJO``/P"``#2"4`
+M`_\```)E7@`#:"4``VJ-``)%6P`#:"4``VJ-``/L```##,X``=W(``/L```"
+M/>@``K8"``-H,0`"M@$``TF>``*\$``"9*P``\%;``-H,0`#29H``KP"``)D
+MK``#P5L``V@Q``/_```#270``KP0``)D+``#P5,``V@Q``(Q1``#P,P``D1,
+M``-H,0`",40``\%*``/!6P`#:#$``^P```/!;@`"MP,``DW^``/P`@`"O0(`
+M`D=]``*]`@`"3?T``_`"``*]`0`"1WT``^P```*X!``"L0(``K"```)/_@`#
+M\`$``K#```(^0@`"L0,``K````)/_@`#\`$``K!```(^0@`"L0,``K"```)/
+M_@`#\`$``K#```(^0@`"L00``K````)/_@`#\`$``K!```(^0@`"L00``K"`
+M``)/_@`#\`$``K#```(^0@`"3_X``_!'``-'-``#1SD``_\```-G-``#9SD`
+M`_0$``/P!0`#1W0``T=Y``/_```#9W0``V=Y``/L```"N`0``^@```/H$``#
+MZ"```^@P``)/_@`"'C```V4L``-E,``#930``V4X``-E/``#]````=XU``-E
+M;``#97```V5T``-E>``#97P``K$&``*P```"3_X``_`!``*P0``"/D(``K$&
+M``*P@``"3_X``_`!``*PP``"/D(``^P```+""``#W!```]@```/<$0`#V"$`
+M`]`>``/07P`"O`<``]0>``/47P`#^P```_L```/[`0`#^P$``]`>``/07P`#
+:#,X``=Y*``/L```#_P```_\```/_```#_P``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_me.bin.uu
new file mode 100644
index 0000000..37f1355
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_me.bin.uu
@@ -0,0 +1,194 @@
+begin 644 PITCAIRN_me.bin
+M?$"``8@```#40`!_?$"``8@```!\0,`!S$``*,Q``"E\0(`!B````-A``![$
+M$``A)1```I4`__Y\00`!Q!P`)L0@`"38```<S(``"\W!H-G.`:#:V$``',04
+M``>50``"V4&BI,0;``+8```;S8``&L`^``3,`:'TS#T@!,0]``',```%V$``
+M&]A``!]\0(`!B````,Q!+@',02X"S$$N`\Q!+@!\0(`!B````'Q`P`&,``4B
+MS$$N`<Q!+@+,02X#C``%)LQ!+@!\0(`!B````'Q`P`'$&``PQ!P`,7W90`)\
+MU@`.Q"0`%9I`__^:```#S,``%(````#`*(``SH$P2L0\`'\DD``"P"H``7Q`
+MP`&5```#Q!0`,'S4P`$4S``"S,$EQ]1I)<A\0(`!B````'Q`P`$8T`'H),P`
+M?WQ!0`%06``@?5E`&GQ!@`%07``@?9V`&GQ!P`%08``@?>'`&GQ"``$E)``!
+MS,``(]%``"31@``ET<``)MA``">60``,Q"@`+)J`___()``M?EZ`#)J`_YP2
+M+``&!NP``0KL``&:P/__V$``)X```&#$*``LFH#__WQ`@`&(````?$#``<00
+M`##,027,?04``<Q!)<_-`27.?$%``230`'\56``0)50`_\T!)=/-@271S4$E
+MT,Q!)=)\04`!?$&``1C<`#`8X``Q&.0`,ACH`#,8[``TS$$EULQ!)=?-@275
+MS4$EU,`R``260``AEL```LPQ)=G,,278EH``!);```+,,27;S#$EVGP#`!&6
+MP``#Q#$``5,P`"#$-0`!?S<`&M,``!:6@``(?`.`$9;```/$.0`!4[@`(,0]
+M``%_OX`:TX``%Y7`_V":P``$?7<`#)<`_^2`````4;@`('^7@!I_.X`,EX#_
+MWX````"6`/]6S#$ES<R```O$-0`!ET#__'Q`@`&(````Q"``)GQ!0`'&)P/D
+ME4```LP```',```)"F0``<Y@`^1\0(`!B````'Q`P`'`%@`$)-#__WT5``K,
+M@``+S!$``!C8`#X4W``?Q"$``7Q"0`&5P``%?E:`"LP```O,*0``Q"4``7XF
+M``E\0L`!E8``!7[7``K,```+S#$``,0M``%^+@`*)1#__\P```O.$0``@```
+M`'Q`P`',0```@````,R```O-02)=S0$B7,Q!H?Q\0(`!B````,R```O,02)7
+M?$"``8@```#,02)<S$&A_'Q`@`&(````P`X``<Q!(ES,0:'\U$VA_7Q`@`&(
+M````S(``"\Q!(EU\0(`!B`````A,``%\00`!S(``"WQ!0`$E6/__&5P#\!5@
+M`!7-@:$"S<$B5LX!(ER4P``$S0&A_`C,``&```#TS0&A_,P!H0)\0(`!B```
+M`'Q`@`'`*@`"?$#``7Q!``%]*0`*))0``228``8DG`,`%=P`"'Q"``%\0D`!
+MP"X`!,R```N50``,!?`B6'\O``K,,0``Q"D``<S!(6G-`2%JSH$A:S&T``+,
+M`2%LET``"H```2XQM``"ET``!\`N``0%\")8?R\`"LPQ``#$*0`!@``!+C&T
+M``"70``#?@*``8```2XQM``$ET#^UR)D`##.`2%MSD$A;L0J``#$+``),?``
+M`#'T``$Q^``"FL```HP``Q[:@:*DEP```\Z!HK>`````ET```\Z!HKN`````
+MEX```\Z!HK^`````SH&BPX`````$&```@``!0P08``'$)``F?$#``<9K`^08
+MT``P)-0`_P:H``'.I`/DFD``$L0X``?80``>Q#P`(2?\``*7P/_^S(``"Y>`
+M``+90:*DQ#\``L_``!K`/@`$S`&A],P](`3$.0`!S```!=A``!_-0:#:S(``
+M"\U!+A29@``"S````LU```A\0(`!B````'Q`P`$8T`'H&-0`,!C8`#0%*`%K
+M?$(``7Q"0`&5```'AH```(```86```&I@``!OX``!1Z```%[$50`$'X6``K,
+M@``+U&$``)6`_HO`.@`$S#DA0,0Y``%\0(`!B````!%4`!!29``@?B8`&LU`
+M`!W48@``E8#^@,0@`!V:`/__?$"``8@```#<.@``F4``&R><``&5P``-"[@`
+M`<X!(6G.02%JS$$A:\P!(6R;@``#E8#^<8```9U29``@?B8`&D8@``16)``@
+M(F0`,LX!(6G.02%J"[@``LQ!(6O,02%LFX#__96`_F3$,``9EP#__WQ`@`&(
+M````"[@``<X!(6G.02%JS$$A:\P!(6R;@/_[E8#^68```9U29``@?B8`&IE`
+M``K2```KU$``+-A``"V,``4OE8#^4,0X`"^;@/__?$"``8@```#<-@``"W0`
+M`=(``"O,0``LV$``+8P`!2^;0/_[F8#_]7Q`@`&(````Q!P`,,`J``%^'@`!
+M%B```LX!)<?4:27(E8#^.\`Z``3,.27+Q#D``7Q`@`&(````?$#``7Q!``$9
+M%``]F4``"L0<``V5P/__S,$A`,T!(0',P2$"S0$A`]D!HJ1\0(`!B````,S!
+M(77-`2%VQ"``#I8`__\R*``",BP``YJ```2:P``%S```#(````#,```,@``!
+MV,`^``3,/3!^Q#T``3/H``&7P/X8FH`#.`0X0`#,```!SX$P2H``!2%\0,`!
+M?$$``4#4``/-02)<S0&A_,`>``%\0@`!",P``08D``$&*``"SAVA_<Y=H?W.
+MG:']F,#_^7Q`@`&(````?$#``230``$4S``!?$%``7Q!@`',@``+E0``!B&8
+M`##-02%MS8$A;L0>``"```(.P"(`!'X6``K,(0``Q!T``7Q"0`%\0H`!F,``
+M`\WE``"`````SD$A:<Z!(6K-P2%KS`$A;'Q`@`&(````?$#``7Q!``%\04`!
+M?$&``7Q!P`$8I!_H,F@`/`0@``&6@``(?$(``3HP``-"(``"FP```@0@`$`$
+M)``!@``"*GX"0`$*9``!FD#__R3L`!#,@``+FL``"<`J``3$+``0?I*`"LP`
+M``',*0``SL``$,0Q``&```([(50`,,T!(6W-02%NQ#(``'\?``DD]``'!W@"
+M/Y=``">'@```@``"1X```DR```)1@``"5H```EN```)@@``"97\;@`\4I``(
+MEX``'29D`/^```)V?QN`#A2D``B7@``8)F0`_X```G9_&X`,%*0`")N``!,F
+M9`#_@``"=G\;@`T4I``(FX``#B9D`/^```)V?QN`#Q2D``B;@``))F0`_X``
+M`G9_&X`.%*0`")N```0F9`#_@``"=A2D``@F9`#_,F@`/!3L``B:@/V7?$-`
+M`7Q#@`%\0\`!S```"Y;```;/02%ISX$A:L_!(6O,`2%L@````,_U``"`````
+M,F@`/)J`_[/40`!_@````'Q`P`%\00`!P!X``144`!+`(@`"P"8`!)5```3`
+M)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!(6G-`2%JFH``!\U!
+M(6O-@2%LEL#]<L0P`!F7`/__@````,@4`!A56``@S4$A:\V!(6R6P/UJ@``"
+MCWQ!``%\04`!S$```\Q```3,``/DS``#Y<P``^;`#H``?$)``7Q"@`&`````
+M?$#``1C0`>@%*`*I',S^",R```N5```)AH```(```K2```+#@``"RH```M&`
+M``+7@``"XX```P',P:*D?$"``8@```#`$@@`?$%``7Q"``%]#,`*P!(`!!58
+M``,57``-?='`"1(@`!-^'D`*?DZ`"LZ!HJ3-@:'^?$"``8@````$$"$8Q!0`
+M"Y5`___440``S,&BI'Q`@`&(````!!`A!L04``R50/__U%$``,S!HJ1\0(`!
+MB````-A```_,P:*DQ!``#YD`__]\0(`!B````!C0`#01%``4Q"0`#99`___,
+M02$`?45`"LU!(0',02$"S$$A`\S!HJ1\0(`!B````"38``%\00`!?$%``1&<
+M`!!\0@`!?5U`"A5D`!TF9``"E8``"<0\`!^7P/__FD``#<0H`#`6J``"?BH`
+M`<P``!6```+[Q#P`()?`__^:0``%Q"@`,!:H``)^*@`!S```%<T!(5C-02%9
+MS@$A6LS!HJ1\0(`!B````!C0`#01%``4)-@`/Y4`_ZW$)``-ED#__S6<``;,
+M`2$`S4$A`<P!(0+,`2$#F<```]D!HJ2`````!"``%,X!HJ1\0(`!B````'Q`
+MP`$4T``=&-0`/)D```*`````S4``'(````!\0,`!C``#'GQ`@`&(````V$``
+M'L0\`"$G_``"E\#__LR```O90:*DQ#\``L_``!K`/@`$S`&A],P](`3$/0`!
+MS```!=A``!^0````?$#``00\`"+,@``+S\&BI,P```9\0(`!B````,`2``%\
+M44`*S(``"]15``!\0(`!B````'Q`P`%04``@?-#`&E4<`#]\04`!?$&``<R`
+M``O0P`"#E<```\`<@`#-P2`0E8#\NXP`!2+=@P``!5P@`,P```O470``@``%
+M*GQ`P`%04``@?-#`&GQ!0`%\08`!S(``"]#``(25@/RMC``%(MV#```%7*``
+MU%T``(``!2I\0,`!4%``('S0P!I\04`!?$&``<R```O0P`"%E8#\H(P`!2+=
+M@P``!5PL`-1=``"```4JS(``"]1#(`!\0(`!B````,R```O40Z``?$"``8@`
+M``#,@``+U$,L`'Q`@`&(````?$#``8P`!2)\00`!?$%``93```)\08`!?$'`
+M`7Q"``&,``4FE0``"I5```G,@``+S$,L`,W#+`#,@``+S$,L`,X#+`!\0(`!
+MB````,0D`![,0`!_S$``?QIH`#!\0(`!?$#``9:`_'78@``N?$"``8@```#,
+M@``+S$.@`'Q`P`$$&``!W8,``(P`!2+40Z``@``%*B2,___,@``+U$T``'Q`
+M@`',@``+B````'Q`P`$8U``P&-`!Z!C\`#0DS``/!.@#IGQ!@`%\0<`!E,``
+M2H:```"```.^@``#QH```\^```/>@``#L8```[2```.V@``#N(```[J```.\
+M4=P`('V>`!J```/]R"``+8```_W((``6@``#_<@@`!>```/]R"``&(```_W(
+M(``R@``#_9E```,AW``P@``#PB'<`%#-@2%MS<$A;L@B``"```/]4=P`('V=
+M@!K8```CT8``)-A``"?$*``LFH#__\@@`"Z```/]Q!P`,,`R``1]G8`!%9@`
+M`LV!)<+,,27#E4```\R```O,,27#Q"$``95``"3$)0`!4F0`('XF`!J```/]
+M,:P(`,0T`!"6P``#S````8```_`YK`I\/;`*=YK```27```#S````8```_`Y
+MK`K</;`*V9K```.7```"S````8```_#$-``0S(``"\`Z``1]N8`*S!D``)5`
+M``,%F``!S!D``,0A``&50``%Q"4``5)D`"!^)@`:ST``$`4H!`%\08`!?$'`
+M`94```>&@```@``$,H``!#R```1*@``$%8``!"?$-``0S(``"\X9``"50``$
+M!9@``58@`"#.&0``E\#[\L`Z``3,.2%`Q#D``<]``!!\0(`!B````#&L"`#$
+M-``0EL```\P```&```0(.:P*?#VP"G?$-``0FL``!)<```/,```!@``$"#FL
+M"MP]L`K9FL```Y<```+,```!@``$"%'<`"!]G8`:V```'<X:``"50``$!9@`
+M!%8@`"#.&@``F\``D'Q`@`&(````E4```B'<`#)6)``@S8$A:<W!(6K.`2%K
+MSD$A;)O`_E9\0(`!B````%'<`"!]G8`:T8``*\X``"R50``#5B0`(,Y``"S8
+M0``MC``%+Y?`^[O$.``OFX#__WQ`@`&(````Q!P`,,`J``%]G8`!%9@``LV!
+M)<?.*27(E4```U8D`"#.:27(E\#[K<`Z``3,.27+Q#D``7Q`@`&(````Q!0`
+M'#U8``29@/_^S```#7Q`P`$H4(``%10`'QD8`'T9'`!TQ"``,#&8``$QW``!
+ME8```GS@P`%\0D`!E<```GYB0`',P2&`S0$A@<Y!(8+,02&#S$$AA)5`^Y'$
+M%``<F4#__WQ`@`&(````P!8`!,00`";,@``+S%4A0,09``',$`/W?$"``8@`
+M``#$(``FV```'L0,`"$DS``!E,#__L8G`^1\0,`!S(``"\S!(7S,02%]Q!@`
+M)'Q!``%\04`!ED```LV!(7K-`2%^P#8`P,`J``1_3T`)$5P``07<``&70``4
+MS"DA?\0E``$:;``^EL``!Q%<``$%W``!"=P``9G`___,@``+@``$DA=T`!<H
+M+`!@FT```B@L`$#.P``CV$``)\0T`"R;0/__@``$J@G<``&9P/__S(``"\PI
+M(7_$)0`!%FP`'Q%<``$%W``!FL#_^!3\`!_8```?F\#[4,00`";,$`/W?$"`
+M`8@```!\0,`!?$$``148`!]1%``@&1P`,9F```C-```=?4U`&M16``"5P/M"
+MQ"``'9H`__^`````W#H``,`F``3,P2%I?24`"LT!(6H+N``"S$$A:\Q!(6R;
+M@/_]F<#]Q'Q`@`&(````)$P`_\Q,`P!\0(`!B````,0@`";$3P,`S(``"\SA
+M(46`````S(``"]K!HJ1\0,`!?$"``8@```#$#``:F,```]A``"^```3<V$``
+M,'Q!``%]`4`!%50``254``&90``))1```94`^QG(%``TE4``!<@8`!N5@``#
+M?97`#I7`^Q/((``ST@``,M@``![$(``A)B```98`__[`)@A`SD$A?,P!(7W$
+M*``DSH$A>LP!(7[`*@`$!!0`!$%<``@H+`!`SL``(]A``"<)W``!F<#__\R`
+M``O,*2%_Q"4``19L`!]!7``"FL#_^<0T`"R;0/__V```'WQ`@`&(````Q`P`
+M$S#0``&5```#S(``"]L!HJ3,0``.Q`P`$L00`!,PU```/1@``7U9P`K80``Q
+MF<#_^MA``!/0```R?$"``8@```#`#@$`S````<S!,$J```4AV$``$<0\`!&7
+MP/_]D````-@``!'$/``1F\#_^9````#8```1Q#P`$9O`__5\0(`!B````-B`
+M`![$/``A)_P`!)?`__[`.``OP#X`!,^!(?C,/2'YQ#@`)@0\``5_^X`"Q#T`
+M`7_[P`4G_``!F\#_]MB``!^0````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0.7`!```@`1``4`$@`*`!4`)0`6`"L`%P"Q`!L`-``<`$$`'0!O`!X`
+M3``A`+L`)`#9`"4`V0`G`.,`*`#6`"H`WP`L`-D`+0#C`"X`YP`O`.T`,`#Q
+M`#(!0@`T`0,`-0#C`#<!8P`X`-D`.0'+`#H![@`[`?X`/`(9`#T">@`_`4``
+M0`.=`$$$60!"!'0`0P1\`$0"F`!%`AD`1@*C`$<"HP!(`J,`2@,3`%(#&@!3
+M`RT`5P,T`%\#60!@`SH`80-,`&@#9@!I`VH`<@-R`',#CP!V`VX`=P-N`'H$
+MM0!]!,X`?@32`(4$UP"&!-P`B@4-`(L%#0`/!1X`#P4>``\%'@`/!1X`#P4>
+M``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`
+M#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/
+:!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_pfp.bin.uu
new file mode 100644
index 0000000..9099262
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_pfp.bin.uu
@@ -0,0 +1,194 @@
+begin 644 PITCAIRN_pfp.bin
+M?$"``8@```#,@```U$```'Q`@`&(````S(```,S```#40```?$"``8@````D
+M3``/,.@``B20``*:@``,?$%``5!8`"!]E<`:F,```]'``!F`````F0```]'`
+M`!J`````T<``&X````#$(``5QB0`"I9``6-\00`!?$%``<R```#,P```S0``
+M`,U```#-```MS4``+GQ`@`&(````S(```,Q```#,```2@``#BLQ``"A\0(`!
+MB````,@,`!M\Q0`1T0```]C```/,@```S````,Q```!\0(`!B````,@,`!I\
+MQ0`1T0```]D```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L
+M`'XB[$Y(EH```MB``"+.P```V````,Q```#,0```'(@`$,R```#,0```?$"`
+M`8@```#(#``:?,4`$7Q!0`%\08`!?$'``7Q"``%\0D`!E<#_J=$```/9```#
+MQ"@`$,P``!2:@``$Q"@`!<Z```#,````Q"@`"1JH`#`@+`!^(NQ.2):```+8
+M@``BSL```-@```#-0```S8```!R(`!`)W``!S(```,Y```"5P/^2?2$`$8``
+M`%C(#``:?,4`$<46``"50`,3*!@`!'T9@!'%E@``E4`##\P``";1```GT0``
+M`]E```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L`'XB[$Y(
+MEH```MB``"+.P```V$```,Q```#,0```'(@`$,R```#,0```?$"``8@```#(
+M#``:?,4`$<46``"50`+R*!@`!'T9@!'%E@``E4`"[GQ!0`%\08`!?$'``7Q"
+M``%\0D`!E<#_8<P``";1```GT0```]E```/$*``0S```%)J```3$*``%SH``
+M`,P```#$*``)&J@`,"`L`'XB[$Y(EH```MB``"+.P```V$```,U```#-@```
+M'(@`$`G<``',@```SD```)7`_TA](0`1@```H,08``@EF``!?$)``7Q"@`&5
+M@`+(4JP`('[FP!I\0,`!?$$``<0<`!&9P/__'(@`$""(`'`0U``"?M5`$=%`
+M``/-```#S(```,Y```#.@```S,```-PZ``#-````EX#_+GQ`P`%\00`!@```
+MR,00``_$'``$F0``!,P``!+-P```S````,08``@EF``"@```O22,``+$$``0
+MQ!@`")C```B9```%Q!P`!<P``!/-P```S````!F8`#"```"]&9@`.(```+W$
+M'``$S<```,P```#,@```U$```'Q`@`&(````Q!P`!,W```#,````R`P`&<R`
+M``#,0```$%```GT-`!%5%``@T0```]A```/,````?$"``8@```#$'``%S<``
+M`,P```#,@```U$```'Q`@`&(````Q!P`!<W```#,````Q"0`),@,`!S&4P/H
+MS(```,Q```!1$``@?-#`&GS%`!%5%``@?46`"LT```#-@```?$"``8@```!\
+M0,`!4%``('T-0!K10``8S```)7Q`@`&(````?$-``<@<`!C$&``7'(@`$""(
+M`#!\04`!?5C`!'S<P!%4T``@?$%``<R```#/0Z*>S,.A^LT#H?G-0Z*=S4``
+M`,Q```!\0(`!B````'Q#0`$<B``0((@`,'Q`P`%\00`!?$%``<R```#/0Z*>
+MS,.A^LT#H?G-0Z*=S4```,Q```!\0(`!B````'Q`P`$DT``!S,.BG]A``!>5
+M```"V(``%\R```#,P```?$"``8@```!\0,`!S(```,S#HJ+,P```?$"``8@`
+M``!\0,`!%-0`'\R```!\00`!E4```LS``!\5&``?S,```,T```"5@``"S0``
+M(,P``'^```.*(`@`?B"(!^C$(``5'*@`$,Z@``1\00`!4%0`('Q!@`$&)``!
+MSD``%16<`!A]%0`:S>``"<V@``O1(``!S:```<0L`"15,``@T0``',\L`^B:
+M```$Q"0`(YI```(AW``PS<```(```XK$(``5Q@P`"ARH`!"4P``#SJ``!H``
+M`63,```(@``!@,0@`!5\08`!"B```<84``W&&``*?5F`"LX``!65@``$S*``
+M!LU@``:```.*S*``!,U@``2```.*?$#``130`!XQ%``!E0#^=)5``?08T`'H
+M&-0`,!C8`#0%*`&;?$(``7Q"0`&5```'AH```(```XZ```..@``#CH```XZ`
+M``&I$50`$'X6``K-0``AU&$``)6`_EO$.2%`?$"``8@````15``04F0`('XF
+M`!K-0``AU&(``)6`_E+$(``3F@#__WQ`@`&(````?$#``7Q!``%\0X`!?$/`
+M`5$0`"!3_``@?[^`&GS0P!H$'``@TX```MB```+0P``"S<```@0<``@$(``!
+M?`)``<07``/$&P`#49@`('U90!K$*P`#Q"\``\0S``/$-P`#"=P``5+L`"!^
+MKH`:4W0`('\W`!I_*T`2?G9`$5:H`#]7,``_?K*`"7XJ``F9P/_QEH#_Y%/T
+M`"!_>T`:?65`$558`"#,```AS78``,VV``#$(``3F@#__WQ`@`&(````Q"``
+M)'Q`P`%\00`!S.`#_<T@`_I1%``@?-3`&M#```(5%``?&1@`\)E```($-```
+M+UP``7UV``E]7D`)F8``!,P```+,```-@``#BA68``$5+``()NP``9F``#,5
+M,``,E@```\P```*```.*!!0`(,U```(G,``!*"@``00X`"`$/``(Q!<``\0;
+M``/$'P`#Q",``WU=0`U]H<`-?5U`"A80`!\5G``??1T`"7T70`E^DH`)"[@`
+M!`O\``&;0``2F\#_\<0@`"3&#P/]QA,#^IJ```G,```-FP`!<5$4`"!\U,`:
+M!!0`(-#```+-0``"@``"`<P```V6P`%IS```#H```XK,```-FL```LP```Z7
+M@/W9"[@``<0_``.;@/_]@````,P```Z60``#S````H```XK:```"Q`L``\0/
+M``/$$P`#Q!<``\0;``/$'P`#Q"<``\0K``,5_``?%K``'W_SP`D4\``??_/`
+M"15P`!]_\\`)?8B``GW,P`*7P``,?E$``GZ50`)\D(`,?-3`#'R/0`F:P``"
+M++0``<P```V;0`$_S```#H```XK$(``DQ@\#_<83`_I1%``@?-3`&M#```*`
+M``(P?$#``130`!XQ%``!E0#]KI5``2X8U``P&-`!Z!C\`#0DS``/!.@"8GQ!
+M@`%\0<`!E,``$H:```"```)L@``#CH```XZ```..@``":8```XY1W``@?9X`
+M&H```GE1W``@?9V`&IE```/%H@``@``"><FB``"```)YQ:$``)5```4%F``!
+MQ:4``%)D`"!^)@`:!2@"?7Q!@`%\0<`!E0``!X:```"```..@``#CH```XZ`
+M``..@``"C=@``"'.&0``E4``!`68``%6(``@SAD``)?`_7?$.2%`?$"``8@`
+M``!1W``@?9V`&M@``"'.&@``E4``!`68``16(``@SAH``)O`_QI\0(`!B```
+M`'Q`P`%\00`!&10`.Y5``!O$%``2/5@``IF`__X9'`!]&2``=,04`"4QW``!
+M,B```<P``"',```C*1"``)7```)\U,`!?$)``98```)^5D`!S,$AA<T!(885
+M%``?SD$AA\Q!(8C,02&)E4#]3L04`!*90/__@````,R```#,P```S0```-1`
+M``!\0(`!B````,0H`"38:`/WS(```,Q```#&CP/WF,#__WQ`@`&(````Q"@`
+M),0P``_$-``$FH``!9L```3,```2ST```,P```!\0,`!V&@#]\R```#,P```
+MU$```!30`!^9``"X@``"P,R```#,0```S$```,Q```!\0,`!S,``%LS```#4
+M0```?$"``8@```!\0,`!%-P`'1C8`#S,@```S,```)G```.9@/T<@``#BLV`
+M`"2```.*?$#``5!0`"",``,-?-#`&L0D`!7$%``D?$.``99```C$U@``F4``
+M&=^#``#/I``/C``#$=1``'^`````Q5\#[I7`___85`/QQ5L#])6```/8%`/Q
+MF8#__,5?`^X]X``"F@``!\5C`^N:```%WX,``,^D``^,``,1U$``?PG<``'-
+MU`/NV!0#\8P``Q%\0(`!B````-@``![$/``>F\``?Y````#80``>Q#P`'I?`
+M`'N0````C``##<0@`!5\0,`!P#;_`,00`!;`,#__?/5`"7U1@`E]@8`=?/.`
+M"9F```;?@P``SZ``#XP``Q'40`!_@````(P``Q%\0(`!B````'Q`P`$4W``(
+ME<``&23<`!!\00`!4%0`()G```/%'0``@``#,WT5`!K%'@``?$(``7Q"0`%\
+M08`!?>7`"7WB@`]!K``"FH#\QP;L``,*[``!FL#__R3<`!"9P``#Q1T``(``
+M`S;%'@``@``#-LR```#,P```U$```'Q`@`&(````Q!P`!,W```#,````S(``
+M`-1```!\0(`!B````'Q`P`$DT``&,1``!L04``^9```(S```$L0D`'Z60``X
+MF4``!,0<``3-P```S````,R```#,P```U$```'Q`@`&(````?$#``7Q!``$5
+M&``?S0``(5$4`""9@``#U$T``(````!]34`:&1P`,=16``"5P/R5Q"``$YH`
+M__]\0(`!B````'Q`P`%\00`!%-0`'C%8``(DW`#_E4``!)F`_(K-'`,`@```
+M`,R```#,P```S0```'Q`@`&(````Q"``)'Q`P`'$TP,`S(```,S```#,```A
+MS2$A07Q`@`&(````U$``?WQ`@`&(````Q"0`?I9```-\0(`!B````(```XX`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P-(``4!7P`&`.P`!P#S``@!`0`)`0@`$`.'`!$`"P`2`"<`$P`K`!8`
+M+@`D`#<`)0!Q`"8!&0`7`8$`(@+H`",#%0`G`3,`'P&S`"`!XP`H`5(`*@%"
+M`"P`4``O`4P`,0.'`#(!>0`S`X<`-`-/`#4!(``X`)(`-P&/`#P#*``_`6$`
+M0`)5`$$"F`!"`KP`0P+$`$0"U`!*`MX`50-+`%\`WP!@`+L`80#6`&D`[P!S
+M`/8`=@$$`'<!"P![`V``?0-P`'X#?@!_`X<````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_rlc.bin.uu
new file mode 100644
index 0000000..0478417
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/PITCAIRN_rlc.bin.uu
@@ -0,0 +1,186 @@
+begin 644 PITCAIRN_rlc.bin
+MQ`@`)S",``*8P`,I,(P``9C``+DPC``#F,`!^H```=#`"HP`P`PD4'S(P`K$
+MT0``P`J-`,`,)%!\R,`*Q-4``'T5``HE$`.`?0%`#9````#$#``<E,`"U<V#
+M``"```-:C``$#"G,)-7$S0``?4U`"9````#`,`.0QSD``,`+__Y_BX`)$,P`
+M$'^/@`K/L0``QSD``)````#$"P`>Q`\`87R-``R9```&Q!$Q"WS0P`K,PP`>
+MP!@``<V#``Z0````EL`!/RKL``'.P``PED`!.,0@`!R6``$VS```,)````#`
+M&``!S`,`#L`-___,PP`>S,,`8<`(!0`H#```S(\`0<`*("`HB`\%!,P``<R/
+M`$'`"C`P*(@>#P3,``',CP!!P`I`0"B(*!X$S``!S(\`0<`*0$`HB#(H!,P`
+M`<R/`$'`"F!@*(@\,@3,``',CP!!P`IP<"B(4#P$S``!S(\`0<`*@(`HB%I0
+M!,P``<R/`$'`"H"`*(A?6@3,``',CP!!P`J`@"B(9%\$S``!S(\`0<`*@(`H
+MB&ED!,P``<R/`$'`"H"`*(AN:03,``',CP!!P`J`@"B(<VX$S``!S(\`0<`*
+MP,`HB'AS!,P``<R/`$'`"L#`*(A]>`3,``',CP!!P`K__RB(@'T$S``!S(\`
+M0<`(`(#,@P!>P`@#_\R``##,`P!5S`,`7<P#`%_,`P!IS`,`8LP#`&7,`P!C
+MS`,`9LP#`&3,`P!GS`,`:)`````FJ`#_%.0`!!)D``@DW``/?ES`"LS``"/.
+M@``,@``#\,`8)-5]B8`*Q9D``'T!`!Y]D,`)*!P``"@D``#`(``%E4``#"3(
+M``&4@``%?*2`!'V)@`L)5``!!=P``0H@``$4S``!!F0``9H`__8EF``?D```
+M`,P``"W-@``.S`,``,`P,$G'"0``P#(`$'RQP`F5P`-`P#`Q`<<)```DG``!
+ME<``AA2L``@F[`#_P"0``<`@``",``)$E@`#0LV#``"```/PC```.,P```[$
+M"``WQ`@`,Y2```/-@``.C``"%\0(`"J4@``#S8``#HP``<+$"``KE(```LV`
+M``[$"``HE(#_\LV```Z,``#CC```)H```+[$"``0E(``^L0(`!&4@`#XQ"@`
+M`):```G-@``.*`@``<0,`"#,@```,H@!NY2``63,`P``@```J<0G``"60`,B
+MS`,``(```*F,``$[C``#$,`(,2#,"0``?[R`"GPLP`K$$3$B)1#__WR0@`Z4
+M@`$IP`@Q(,`0``'-"0``P`@Q'\2E``#`"``4?+"`$"90`/^,``&AF4`"5,`(
+M,2#`$``"S0D``,`(``5\M(`0%E``""40`/^,``&AF4`"2\`(,2#`$``#S0D`
+M`,`(`,A\N(`0%E``$"40`/^,``&AF4`"0L`(,2#`$``$S0D``,`(`,A\O(`0
+M%E``&"40`/^,``&AF4`".<`(,2#`$``%S0D``,0+`&*4@`#KP`@Q(,`0``;-
+M"0``Q`L`8WRX@`Z8@`(NP`@Q(,`0``?-"0``Q`L`9'R\@`Z8@`(HP`@Q(,`0
+M``C-"0``Q`L`97\(@`Z8@`(BP`@Q(,`0``G-"0``Q`L`9G](@`Z8@`(<P`@Q
+M(,`0``K-"0``@``"%9````#$'P!@"=P`!R@@`!":``(N*!0`0(```WJ```/P
+MP!Z(`(P``!A\%(`*?!:`"HP``;I\#L`*P!Z(0(P``!A\%(`*$50`"'Z6@`J,
+M``&Z?L[``<`>B0",```8?!2`"A%4`!!^EH`*C``!NG[.P`'`'HE`C```&'P4
+M@`H15``8?I:`"HP``;I^SL`!SH,`6I`````H%``??)3`!23,``&8P``#"50`
+M`9E`__R0````)K@`'Q:<``@EW``?$=P`!7^?@`H6G``0)?0`'Q7<``@EW``?
+M$=P`!7]?0`J0````Q!P`,Y7`_L?,```PP"```)````#`,"`#S[$``,<Y``"0
+M````Q`@`$Y2`___,```"Q`@`#\00``.9`/__P"PQ'L;M``#`)```C```,"@X
+M``",``/Y*#@``8P``7`H#```C```'<V``!"0````Q"L``HP``5_`#H``?X^`
+M"L`.@`!_3T`**#P`H!/\`!`K_`#_C``"D,`<,07%[0``$NP`&";L`/_`)```
+MC```,,P``!*0````EX``!,`0,1G%'0``F<#__I=```3`$#$:Q1T``)G`__Z0
+M````Q!<`8`E4``=^T0`0?14`!'R10`^0````P!@DU7V)@`K%F0``*!P``"@0
+M``#`(``%E4``#"3(``&4@``%?)"`!'V)@`H)5``!!=P``0H@``$4S``!!1``
+M`9H`__8EF``?D````"@,``#`$``%))0``0D0``%\U,`!%(@``9D`__R0````
+MS`,`5<P#`%_`"##&Q(D``,`,,,7$S0``?,B``HP``5C-0P!@D````,0(`!R4
+M@`(CS8,``(```UK("3TVR`T]-Y3``<'($3TXR!4].<@=/3K((3T[R"4]-02H
+M`##.@3V"S,$]@\T!/83-03V%S<$]ALX!/8<0B``#!(P`&,B6`#R50`&QR-(`
+M*'TE``()5``!!,P`*)D`__O(D@`X!1``0'T*P`'(U@`$P!P`!,CB`!3(Y@`D
+MS@H!3,YN`4P(S``$"(@`!`KL``0)W``!F<#_^,T*`6#,"@%DS4$]1X```Y,H
+M.```C``#^2@,``",```=P#@``)````"```(`Q`L`9R2@``\4B``$?Z(`$'RL
+M@!!^"(`.F(`!0\`(,2#`$``+S0D``,0+`&@DH``/%(@`!'_B`!!\K(`0?DB`
+M#IB``3G`"#$@P!``#,T)``#`"```@``#2\`(,0G$C0``)-```9D```TDT`#^
+MQ!<`7P54``'-0P!??5%`#Y5```>,``)/Q`L`57T(@`[,@P!=S0,`5<P#`%^0
+M````P`@DU\`.B`!\C,`*Q-4``"54`/_`#HA`?(S`"L31```E$`#_$1``"'U1
+M0`K`#HD`?(S`"L31```E$`#_$1``$'U10`K`#HE`?(S`"L31```E$`#_$1``
+M&'U10`J0````,H@!O)2`_DO,`P``@``#6I;``/!^P0`*P!PPT,V=``#`'##.
+MQ=4``!4L``26P`#AC```,)8``-^0````P`J<`"B()-3`#``!S,D``,`*C``H
+MB"36Q(T``"30__\4S``0?-$``<`*C0`HB"36Q(T``"34__\4S``0?-5``7T5
+M``&0````)]``_S$0`/^9`/[0P!0Q%\_5``"0````S(,`)92``:S`'H@`C``$
+M#":,`/]\U,`+P!0``<`*B`",``&G?!I`"L`>B$",``0,%J@`"":,`/]\U,`+
+MP!0``<`*B$",``&G$9@`"'Y:0`K`'HD`C``$#!:H``@FC`#_?-3`"\`4``'`
+M"HD`C``!IQ&8`!!^6D`*P!Z)0(P`!`P6J``()HP`_WS4P`O`%``!P`J)0(P`
+M`:<1F``8?EI`"I````",``&8P!0Q%<^5``#`%#$6SU4``,`4,1C/%0``P!`Q
+M'<41```E$``!F0#_Q\`4,1?/U0``D````,`,`!_`"H@`?<D`"L45```55``0
+M?4%`'GU.@`G`"HA`?<D`"L45```55``0?4%`'GU-0`D15``(?I:`"L`*B0!]
+MR0`*Q14``!54`!!]04`>?4U`"1%4`!A^EH`*P`J)0'W)``K%%0``%50`$'U!
+M0!Y]34`)$50`&'Z6@`I^@H`>Q!<``GZ6@`F0````P`PDU<03`!Z,``+RQ!<`
+M)9E```>,```(E4``!<`,)-5^`0`*S0,`'HP``O+,`P`.D````"@X``",``/Y
+M*#@``8P``7`H#```C```'<P``"V```/P*`P``8P``!TH.``!C``#^2@X``",
+M``%PEX#_'L`X,0''N0``%[@`$">L!_^6P``#P"0``(P``##-@``"Q!```Y4`
+M___,```0P#@``9````#`,#$!QPD``"2<``*5P/Y-C``#-98`_DO-@P``@``#
+M6B44`/_`"H@`?(R`"L2A``#-20``%10`""54`/_`"HA`?(R`"L2=```1W``(
+M?>(`"LU)```5%``0)50`_\`*B0!\C(`*Q)T``!'<`!!]X@`*S4D``!44`!@E
+M5`#_P`J)0'R,@`K$G0``$=P`&'WB``K-20``D````,`*G``HC".8P!``!\T-
+M``#`"HP`*(PCF<3Q```HC".:Q/4``"B,(YO$^0``*(PCG,3]``#`"HT`*(PC
+MF<31``!],P`!*(PCFL31``!]-T`!*(PCF\31``!].X`!*(PCG,31``!]/\`!
+MD````(```RO`'##0S9T``,`<,,[%W0``?=7``GW1P`^5P/\9?0+`"I````#$
+M"``/E(#__\0K``*,``%?P`Z``'^/@`K`#H``?T]`"B@\`)`3_``0*_P`_XP`
+M`I#`'#$%Q>T``!+L`!@F[`#_P"0``<`@``",```PS8``$I````#`"``!S(,`
+M8L\#`&7/0P!CSX,`9L_#`&03H``$?BX`"LX#`&<3X``$?BX`"LX#`&B,``)G
+MSD,`8<`8``&0````S8``#LV``"W$"``2E(```HP``8;$"``0F(```HP``73$
+M)P``FD#_:X```_#$UP``!,P``0H@``$H&`#_?96`"7V1@!!]G8`$?)F`#Y6`
+M_<HH&/\`?96`"168``A]D8`0?9V`!'R9@`Z9@/W#%50`$)9```(55``(*!@`
+M_WV50`F0````P!```,`*B4!\C(`*Q)$``"40`!\1$``(P`J)`'R,@`K$E0``
+M)50`'WT5``H1$``(P`J(0'R,@`K$E0``)50`'WT5``H1$``(P`J(`'R,@`K$
+ME0``)50`'WT5``J0````!!@``<V```[-@``MC``!=,P```+,```+S```(\`P
+M,.(H+``#SO$``,`(,0#$B0``)(P`!)C```;`/@#0*_P`_\`[___`-___C``"
+MD"2,``B8P``&P#X`L"O\`/_`.___P#?__XP``I`DC``0F,``!L`^`'`K_`#_
+MP#O__\`W__^,``*0S`,`",P#``;,`P`MS`,`+L0,`-<DX``!S@,`"23D``(R
+M9``"SD,`"LY#``?,`P``S`,`(LP#`"/,`P`=S`,`),P#`!S,`P`+P`P`'Q#,
+M``@HS``?P`@`'Q"(`!!\R,`*P`@`'Q"(`!A\R,`*S,,``L`<(F^,``*>SH,`
+M(GZ"P`K`'")PC``"GLZ#`"-^KH`*SH,``<`,,0S$S0``S,,`!<0/``+`$#$#
+MS-$``,S#``_,`P`-P!```,P3`!#,$P`4S!,`&`40``$Q#``$E,#_^\0-,0/$
+M#``ZS```+<0(``.8@/__S8``$,V``!',```2S```#L0(`#;$*``!EH#\WLV`
+M``XH"``!Q`P`(<R```&```",P#`P>,^Q``"0````C``"UI>```/$#``0E,#\
+M%<V#``"```/PQ"L`#I:`_^V,``0&@``#\,V```[$%P`EF4#^N8P```B50/ZW
+M@``"S"G((F_$B0``*<PB<,3-``!\C4`*?4%`'A54`!"0````Q"<`8<0-,0DD
+MT``!F0``"L0/`%W$$3$B%1``$"40___$%P!5S4$Q(7U1``Y\T0`*F0``)L0/
+M`&D$S``!S,,`:<01,,,5$``$)1``#WS0P`^4P``>S`,`:<0M,0O`"H@`)M``
+M_\`4``&,``"4?!J`"L`*B$`6[``()M``_\`4``&,``"4$9@`"'Z:@`K`"HD`
+M%NP`"";0`/_`%``!C```E!&8`!!^FH`*P`J)0!;L``@FT`#_P!0``8P``)01
+MF``8?IJ`"GZ"0`J0````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+"````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R100_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R100_cp.bin.uu
new file mode 100644
index 0000000..38fb060
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R100_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 R100_cp.bin
+M`````"$`<```````(`!P``````0```"T````!````+@`````;UM-3`````!,
+M3$)_`````%M6BI(`````3*"<;0````"M3$Q,`````$SAKST`````V*^OKP``
+M``#63$S<`````$S1#1`````6``\````````V+R0M````!````!(````6``\`
+M```````V+R@M`````@`#@.<````"!``LEP```!8`#P`!`````#,Z-S`````"
+M``!W[P````(`!A``````&@```"$````>``!```````(`!A``````&@```"$`
+M```>``!```````(`!A``````&@```"$````>``!```````0````7`````@`#
+M@"L````"!`!GX`````0````7`````@``=^`````"``90``````(``#?A````
+M!@0`9^$````"``!WX`````(``'?A````!@``=^$`````_____P`````0````
+M`````@`#@"L````&!`!GX`````(``'9U`````@``=G8````"``!V=P````8`
+M`'9X`````@`#@"P````"!``F=@````(``'9W````!@``=G@````8````+P``
+M`!@````O````!@`````````8````,````!@````P````!@`````````"`6!0
+M``````(`!E```````@`)@``````"``80``````1DP&`^`````@`#@.8````"
+M!``EQ0```!8`"``````````````````"!``E'0````(``'6``````@`&=8$`
+M```"!``E@`````(`!G6!````!````$D```````!0``````(``X#F`````@0`
+M)<4````"``80``````(``'4.`````@`!D``````4``$050```!(```!5````
+M`@0`)0\````$``!03P````(``X#F`````@0`)<4````"``!U90````(``'5F
+M````!````%@````"``.`Y@````($`"7%`````@'F5;0````"1`&PY`````(!
+MP1#D````&"9F<&8````"!`PE90```!@```!F`````@0`)60````"``!U9@``
+M``0```!=````"`!`$&D````"`!`0``````(`#8#_````"`"``&P````"``^0
+M``````(`#@#_````!@`````````8````CP````0```!;`````@`#@.8````"
+M!``EQ0````(``'5V`````@`&4``````"``"0``````(`!!```````@P`-0X`
+M```"``20``````(`!1```````@'GA?@````"`"````````P`8`!^`````@``
+M=6,````A`&!U\`````0@`'!S````!```4',````"``.`Y@````($`"7%````
+M`@``=78````"``!U=P````(``'4.`````@``=0\````"`*!0``````P`8`"#
+M````(0!@=?`````"``!U^`````0```"#`````@`*=0X````"``.`Y@````($
+M`"7%`````@`@=0\````$`&``A@````(``'5P`````@``=7$````&``!U<@``
+M``(``X#F`````@0`)<4````"``!0``````(`H%```````@``=6@````"``80
+M``````P```"5`````@`%@``````"#&!U8@````0```"7`````@`#@.8````"
+M!``EQ0````0`8`"6`````$``<.4````"``.`Y@````($`"7%`````@`#@.4`
+M```<````J````!@`!E"J`````@0`);L````8``80JP`````$`'6\`````@``
+M=;L```````!UO`````8`"0```````@`)```````&``V``@````(``'@R````
+M`@``4``````"``.`YP````($`"R7`````@``>"`````"``!X(0```````'@`
+M`````@$@```````"(`=P``````(!(````````B``<``````"``80``````(!
+M('4;`````H!`=0H````"@$!U"P````(`$0```````@`#@.4````<````Q@``
+M`!@`!A"K`````H1`=;T````8``80J@````*$`'6[````&``&$*L````"A$!U
+MO`````0```#)`````H!`=;T````"@`!UNP````*`0'6\`````@`0@``````"
+M`4````````P`8`#-````("#`<``````2````SP````8`@```````!@"`=1T`
+M``````````````(``'=<`````@"@4``````"`&80`````"`$8"==````````
+M0``````"`>`(,``````A`'```````&1D84T`````:6AT(`````````!S````
+M```````````"``!0``````(``X#0`````@0`)>````````!UX0`````````!
+M`````@`#@.`````"!``CE````````%``````````````````````````````
+M```(``````````0`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R200_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R200_cp.bin.uu
new file mode 100644
index 0000000..a3b40b1
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R200_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 R200_cp.bin
+M`````"$`<```````(`!P``````0```"_````!````,,`````>FA>70````!=
+M756(`````&AED9<`````7:&?>`````!=75U=`````%WN75``````\JRLK```
+M``#G7?GI`````+'=#A$`````XJ^OKP```!8`#P```````$4O(RT````$````
+M$P```!8`#P```````$4O)RT````6``\``0`````^34HW`````@``=^\````"
+M``80`````!H````@````'@``0``````"``80`````!H````@````'@``0```
+M```"``80`````!H````@````'@``0``````$````%@````(``X`J`````@0`
+M9^`````$````%@````(``'?@`````@`&4``````"```WX0````8$`&?A````
+M`@``=^`````"``!WX0````8``'?A`````/____\`````$``````````'\`?P
+M`````@`#@"H````&!`!GX`````(``X`L`````@0`)T$````"!``G00````($
+M`"=#`````@``=G4````"``!V=@````(``'9W````!@``=G@````"``.`+```
+M``($`"=!`````@0`)T$````"!``G0P````(``'9V`````@``=G<````&``!V
+M>`````(``X`K`````@0`)G8````"``!V=P````(``X`L`````@0`)T$````"
+M!``G0P````8``'9X`````@`#@"P````"!``G00````($`"=!`````@0`)T,`
+M```&``!V>````!@````O````&````"\````&`````````!@````W````&```
+M`#<````&``````````(!8%```````@`&4``````"``F```````(`!A``````
+M!&3`8%$````6``@``````````````````@0`)1T````"``!U@`````(`!G6!
+M`````@0`)8`````"``9U@0````0```!:````````4``````"``80``````(`
+M`'4.`````@`!D``````4``$09````!(```!D`````@0`)0\````$``!07@``
+M``(``'5E`````@``=68````$````90````(!YE6T`````D0!L/`````"`<$0
+M\````!@F9G!Q`````@0,)64````8````<0````($`"5D`````@``=68````$
+M````:`````@`0!!T`````@`0$``````"``V`_P````@`@`!W`````@`/D```
+M```"``X`_P````8`````````&````)0````$````:`````(``'5V`````@`&
+M4``````"``"0``````(`!!```````@P`-0X````"``20``````(`!1``````
+M`@'GA?@````"`"````````P`8`"'`````@``=6,````A`&!U\`````0@`'!\
+M````!```4'P````"``!U=@````(``'5W`````@``=0X````"``!U#P````(`
+MH%``````#`!@`(H````A`&!U\`````(``'7X````!````(H````"``IU#@``
+M``(`('4/````!`!@`(T````"``!U<`````(``'5Q````!@``=7(````"``!0
+M``````(`H%```````@``=6@````"``80``````P```"8`````@`%@``````"
+M#&!U8@````0```":````!`!@`)D`````0`!P\0````(``X#Q````'````*<`
+M```8``90J0````($`"6[````&``&$*H`````!`!UO`````(``'6[````````
+M=;P````&``D```````(`"0``````!@`-@`(````"``!0``````(``'@A````
+M````>``````"``!X(0```````'@``````@%F4``````"``H```````(`!G',
+M`````@*&\<T````0````MP`````A`'``````'````+X````"``90``````(`
+M"@```````@`&$``````"``L```````(X!G``````!``*`+H`````(`!P````
+M``(!(````````B`'<``````"`2`````````@`'```````@`&$``````"`2!U
+M&P````*`0'4*`````H!`=0L````"`!$```````(``X#Q````'````-$````8
+M``80J@````*$0'6]````&``&$*D````"A`!UNP```!@`!A"J`````H1`=;P`
+M```$````U`````*`0'6]`````H``=;L````"@$!UO`````(`$(```````@%`
+M```````,`&``V````"`@P'``````$@```-H````&`(````````8`@'4=````
+M`@``);L````$``!`U`````(``'=<`````@"@4``````"`&80`````"`$8"==
+M````````0``````"``!YF0````(`H%```````@!F$``````@!&`IFP``````
+M`$```````@'@"#``````(0!P``````(``%```````@`#@%8````"!``EX```
+M`````'7A``````````$````"``.`[0`````$`'.4````````````````````
+M``````(``'C$`````@``>,4````"``!XQ@````(``'DD`````@``>24````"
+M``!Y)@````0```#R`````@``>20````"``!Y)0````(``'DF````!````/D`
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R300_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R300_cp.bin.uu
new file mode 100644
index 0000000..175b69c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R300_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 R300_cp.bin
+M`````$(`X```````0`#@``````@```"N````"````+(`````9U5+2@````!*
+M2D1U`````%52?8,`````2HR+90````!*[TKV`````$KA2DH`````Y)>7EP``
+M``#;2NO=`````)S,2DH`````T9B8F`````!*#YK6````!``,H``````X``T`
+M$@````0``.BT````.``-`!0````$``#HM@```#@`#0`6````!```Z%0````X
+M``T`&`````0``.A5````.``-`!H````$``#H5@```#@`#0`<````!```Z%<`
+M```X``T`'@````0``.@D````.``-`"`````$``#H)0```#@`#0`B````!```
+MZ#`````X``T`)`````0``/#`````.``-`"8````$``#PP0```#@`#0`H````
+M!```\$$````X``T`*@````0``/&$````.``-`"P````$``#QA0```#@`#0`N
+M````!```\88````X``T`,`````0``/&'````.``-`#(````$``#Q@````#@`
+M#0`T````!```\Y,````X``T`-@````0``/.*````.``-`#@````$``#SC@``
+M``0``.@A````!`%`H``````8````0P````0`S.@`````!``;``$````$"`!(
+M``````0`&P`!````!`@`2``````$`!L``0````0(`$@`````"````#H`````
+M``"@``````0@`$4=````!```Y8`````$``SE@0````0(`$6`````!``,Y8$`
+M```(````1P```````*``````!``,(``````$``#E#@````0``R``````*``"
+M(%$````D````40````0(`$4/````"```H$L````$``#E90````0``.5F````
+M"````%(````$`\REM`````0%0R``````!``"(``````P3,S@7@````0()T5E
+M````,````%X````$"`!%9`````0``.5F````"````%4````0`(`@80````0`
+M("``````!``;`/\````0`0``9`````0`'R``````!``<`/\````,````````
+M`#````"`````"````%4````$``#E=@````0`#*``````!``!(``````$``@@
+M``````08`&4.````!``)(``````$``H@``````0`#P``````!`!````````8
+M````=`````0``.5C````P@#`Y?D````(````:0````@``*!I````!```Y78`
+M```$``#E=P````0``.4.````!```Y0\````$`4"@`````!@```!W````P@#`
+MY?D````(````=P````0`%.4.````!`!`Y0\````(`,``>@````0``.5P````
+M!```Y7$````,``#E<@````0``*``````!`%`H``````$``#E:`````0`#"``
+M````&````(0````$``L```````08P.5B````"````(8````(`,``A0````0`
+M!P#C````.````)(````P``R@E`````0(`$6[````,``,()4`````"`#EO```
+M``0``.6[````````Y;P````,`!(```````0`$@``````#``;``(````$``"@
+M``````0``.@A````````Z``````$``#H(0```````.@N````!`+,H``````$
+M`!0```````0`#.',````!`4-X<T````$`$```````!@```"D````!`#`H```
+M```(````H0```"````"F`````$(`X``````X````K0````0`#*``````!``4
+M```````$``P@``````0`%@``````!'`,X``````(`!0`J0````!``.``````
+M!`)````````$0`[@``````0"0````````$``X``````$``P@``````0"0.4;
+M````!0"`Y0H````%`(#E"P````0`(@``````!``'`.,````X````P````#``
+M#""5````!0B`Y;T````P``P@E`````4(`.6[````,``,()4````%"(#EO```
+M``@```##````!0"`Y;T````%``#ENP````4`@.6\````!``A```````$`H``
+M`````!@`P`#'````0$&`X``````D````R0````P!````````#`$`Y1T````$
+M``!%NP````@``(##````!```\\X````$`4"@``````0`S"``````0`C`4\\`
+M``````"```````0``//2````!`%`H``````$`,P@`````$`(P%/3````````
+M@``````$``#SG0````0!0*``````!`#,(`````!`",!3G@```````(``````
+M!`/`"#``````0@#@``````0``*``````!"``1>````````#EX0`````````!
+M````!``'`.``````"`#CE```````````````!```Z,0````$``#HQ0````0`
+M`.C&````!```Z2@````$``#I*0````0``.DJ````"````.0````$``#I*```
+M``0``.DI````!```Z2H````(````ZP````0"P"``````!``&```````T````
+M\P````@```#P````!```@```````P`#@````````````````!``,(``````$
+M`!T`&`````0`&@`!````-````/L````(````2@````@%`*!*````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R420_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R420_cp.bin.uu
new file mode 100644
index 0000000..a78f40f
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R420_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 R420_cp.bin
+M`````$(`X```````0`#@``````@```"9````"````)T`````2E5+2@````!*
+M2D1G`````%52;W4`````2GY]90````#9T]_V`````$K%2DH`````R(*"@@``
+M``"_2L_!`````(>P2DH`````M8.#@P````!*#X6Z````!``,H``````X``T`
+M$@````0``.BT````.``-`!0````$``#HM@```#@`#0`6````!```Z%0````X
+M``T`&`````0``.A5````.``-`!H````$``#H5@```#@`#0`<````!```Z%<`
+M```X``T`'@````0``.@D````.``-`"`````$``#H)0```#@`#0`B````!```
+MZ#`````X``T`)`````0``/#`````.``-`"8````$``#PP0```#@`#0`H````
+M!```\$$````X``T`*@````0``/&$````.``-`"P````$``#QA0```#@`#0`N
+M````!```\88````X``T`,`````0``/&'````.``-`#(````$``#Q@````#@`
+M#0`T````!```\Y,````X``T`-@````0``/.*````.``-`#@````$``#SC@``
+M``0``.@A````!`%`H``````8````0P````0`S.@`````!``;``$````$"`!(
+M``````0`&P`!````!`@`2``````$`!L``0````0(`$@`````"````#H`````
+M``"@``````0@`$4=````!```Y8`````$``SE@0````0(`$6`````!``,Y8$`
+M```(````1P```````*``````!``,(``````$``#E#@````0``R``````*``"
+M(%$````D````40````0(`$4/````"```H$L````$``#E90````0``.5F````
+M"````%(````$`\REM`````0%0R``````!``"(``````P3,S@7@````0()T5E
+M````,````%X````$"`!%9`````0``.5F````"````%4````0`(`@80````0`
+M("``````!``;`/\````0`0``9`````0`'R``````!``<`/\````,````````
+M`#````!R````"````%4````$``#E=@````0``.5W````!```Y0X````$``#E
+M#P````0!0*``````&````&D```#"`,#E^0````@```!I````!``4Y0X````$
+M`$#E#P````@`P`!L````!```Y7`````$``#E<0````P``.5R````!```H```
+M```$`4"@``````0``.5H````!``,(``````8````=@````0`"P``````!!C`
+MY6(````(````>`````@`P`!W````!``'`,<````X````@`````0``.6[````
+M````Y;P````$``"@``````0``.@A````````Z``````$``#H(0```````.@N
+M````!`+,H``````$`!0```````0`#.',````!`4-X<T````$`$```````!@`
+M``"/````!`#`H``````(````C````"````"1`````$(`X``````X````F```
+M``0`#*``````!``4```````$``P@``````0`%@``````!'`,X``````(`!0`
+ME`````!``.``````!`)````````$0`[@``````0"0````````$``X``````$
+M``P@``````0"0.4;````!0"`Y0H````%`(#E"P````0`(@``````!``'`,<`
+M```X````I`````4`@.6]````!0``Y;L````%`(#EO`````0`(0``````!`*`
+M```````8`,``JP```$!!@.``````)````*T````,`0````````P!`.4=````
+M!```1;L````(``"`IP````0``//.````!`%`H``````$`,P@`````$`(P%//
+M````````@``````$``#ST@````0!0*``````!`#,(`````!`",!3TP``````
+M`(``````!```\YT````$`4"@``````0`S"``````0`C`4YX```````"`````
+M``0#P`@P`````$(`X``````$``"@``````0@`$7@````````Y>$`````````
+M`0````0`!P#$``````@`XY0```````````````0``.C$````!```Z,4````$
+M``#HQ@````0``.DH````!```Z2D````$``#I*@````@```#(````!```Z2@`
+M```$``#I*0````0``.DJ````"````,\````$`L`@``````0`!@``````-```
+M`-<````(````U`````0``(```````,``X``````$``#AS`````0%`.'-````
+M!``,H``````T````W@````@```#:````````H``````$`!GAS`````0`&P`!
+M````!`4`H``````$"`!!S0````0`#*``````-````/L````(````2@``````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````!``,(``````$
+M`!T`&`````0`&@`!````-````/L````(````2@````@%`*!*````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R520_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R520_cp.bin.uu
new file mode 100644
index 0000000..e703f7c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R520_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 R520_cp.bin
+M`````$(`X```````0`#@``````@```"9````"````)T`````2E5+2@````!*
+M2D1G`````%52;W4`````2GY]90````#@VN;V`````$K%2DH`````R(*"@@``
+M``"_2L_!`````(>P2M4`````M8.#@P````!*#X6Z````!``,H``````X``T`
+M$@````0``.BT````.``-`!0````$``#HM@```#@`#0`6````!```Z%0````X
+M``T`&`````0``.A5````.``-`!H````$``#H5@```#@`#0`<````!```Z%<`
+M```X``T`'@````0``.@D````.``-`"`````$``#H)0```#@`#0`B````!```
+MZ#`````X``T`)`````0``/#`````.``-`"8````$``#PP0```#@`#0`H````
+M!```X``````X``T`*@````0``.``````.``-`"P````$``#@`````#@`#0`N
+M````!```X``````X``T`,`````0``.``````.``-`#(````$``#Q@````#@`
+M#0`T````!```\Y,````X``T`-@````0``/.*````.``-`#@````$``#SC@``
+M``0``.@A````!`%`H``````8````0P````0`S.@`````!``;``$````$"`!(
+M``````0`&P`!````!`@`2``````$`!L``0````0(`$@`````"````#H`````
+M``"@``````0@`$4=````!```Y8`````$``SE@0````0(`$6`````!``,Y8$`
+M```(````1P```````*``````!``,(``````$``#E#@````0``R``````*``"
+M(%$````D````40````0(`$4/````"```H$L````$``#E90````0``.5F````
+M"````%(````$`\REM`````0%0R``````!``"(``````P3,S@7@````0()T5E
+M````,````%X````$"`!%9`````0``.5F````"````%4````0`(`@80````0`
+M("``````!``;`/\````0`0``9`````0`'R``````!``<`/\````,````````
+M`#````!R````"````%4````$``#E=@````0``.5W````!```Y0X````$``#E
+M#P````0!0*``````&````&D```#"`,#E^0````@```!I````!``4Y0X````$
+M`$#E#P````@`P`!L````!```Y7`````$``#E<0````P``.5R````!```H```
+M```$`4"@``````0``.5H````!``,(``````8````=@````0`"P``````!!C`
+MY6(````(````>`````@`P`!W````!``'`,<````X````@`````0``.6[````
+M````Y;P````$``"@``````0``.@A````````Z``````$``#H(0```````.@N
+M````!`+,H``````$`!0```````0`#.',````!`4-X<T````$`$```````!@`
+M``"/````!`#`H``````(````C````"````"1`````$(`X``````X````F```
+M``0`#*``````!``4```````$``P@``````0`%@``````!'`,X``````(`!0`
+ME`````!``.``````!`)````````$0`[@``````0"0````````$``X``````$
+M``P@``````0"0.4;````!0"`Y0H````%`(#E"P````0`(@``````!``'`,<`
+M```X````I`````4`@.6]````!0``Y;L````%`(#EO`````0`(0``````!`*`
+M```````8`,``JP```$!!@.``````)````*T````,`0````````P!`.4=````
+M!```1;L````(``"`IP````0``//.````!`%`H``````$`,P@`````$`(P%//
+M````````@``````$``#ST@````0!0*``````!`#,(`````!`",!3TP``````
+M`(``````!```\YT````$`4"@``````0`S"``````0`C`4YX```````"`````
+M``0#P`@P`````$(`X``````$``"@``````0@`$7@````````Y>$`````````
+M`0````0`!P#$``````@`XY0```````````````0``.C$````!```Z,4````$
+M``#HQ@````0``.DH````!```Z2D````$``#I*@````@```#(````!```Z2@`
+M```$``#I*0````0``.DJ````"````,\`````WJV^[P````````$6````!``'
+M`-,````$"`!0YP````0`!P#4````!`@`0!P```````#@'0````0"P"``````
+M!``&```````T````W@````@```#;````!```@```````P`#@``````0``.',
+M````!`4`X<T````$``R@`````#0```#E````"````.$```````"@``````0`
+M&>',````!``;``$````$!0"@``````0(`$'-````!``,H``````T````^P``
+M``@```!*````````````````````````````````````````````````````
+M````````````````````````````````````````````````!``,(``````$
+M`!T`&`````0`&@`!````-````/L````(````2@````@%`*!*````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R600_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R600_me.bin.uu
new file mode 100644
index 0000000..a43b5fb
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R600_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 R600_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```84``````!@``````6R
+M``````!@``````7%`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````(``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M,0`@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````(0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````'0`@#BT`````_____``H#B,````````````I%*,`````````
+M'0`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````,``@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````$``@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````$0`@-B,````````?_P`I
+M2B,`````````,``@2BT````````````@2!$`````````,@`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````+0`@%BT````````````O`*,```````````S`````
+M``"`````+@`@%BT````````````O`*0```````````S```````"!``````!`
+M``````"'````+0`@-B,`````````+@`@-B0`````````'0`@'BT`````````
+M`@`A`B<``````````!3@``````"'``````!@``````7M``````!@``````7A
+M`````@`A#B(``````````!3```````"*````&,!`-B````"0`````"[@````
+M``".`````"S@``````"-`````@!`#BT```"/`````P!`#BT```"/````#``@
+M#BT`````````&``@-B,``````````P`A#B(``````````!3```````"5``"@
+M#``@1!$``````````,`@2````````````,!`2`````"=``"@#``@1!$`````
+M```````@2!$``````````"[@``````";`````"S@``````":`````@!`#BT`
+M``"<`````P!`#BT```"<````#``@#BT````````````@2`,````````````Z
+M#`(``````#\````H#B,`````````$``A#B,`````````$P`@-B,`````````
+M'@`A`BL``````````!3```````"D````',`@-B``````````'P`A`BL`````
+M`````!3```````"G````&\`@-B``````````"``A#BL`````````?P`H#B,`
+M```````````O`B,```````````S@``````#;`````"<```````````````!@
+M``````*,@0`````@1!$`````````!@`@2!$`````````#``B'C``````F8``
+M```@1!$`````````!``@$BT`````````"``B$B0`````````$``@&!$`````
+M```````I'.0```````````!@2`<```$HFP`````@1!$````````````@2`(`
+M````G``````@1!$````````````S%&\``````````0`S/B,``````````-D`
+M2``````````````@/`4`````@0`````@1!$`````````#@`@2!$`````````
+M```@$!````````#@!P`@1!$`````````#P`A`BL``````````!3```````#%
+M`/C_"``@2!$`````F`````!`2!$```#6````\``H#B(`````````H``O`B,`
+M``````````S```````#4````$P`@#BT``````````0`O`B,```````````S@
+M``````#/`````@`O`B,```````````S@``````#.```_``!`#!$```#0```?
+M``!`#!$```#0```/```@#!$``````#@`"0`I2B,`````/P`````H#BL`````
+M`````@`B#B,`````````!P!)2B,```#6`#@/"0`@2!$`````:```!P`@2!$`
+M````````"``A2B<````````````@2!$`````!@H"```I2B0````````````@
+M2!$````````````@2!$```````"B`@`@1!$``````/\````H2B(`````````
+M,``@#BT`````````+@`@$BT````````````O`(,```````````S@``````#C
+M``````!@``````7G``````!```````#D``````!@``````7J````!P`@(BT`
+M````````!0`B#B(``````!`````H#B,````````````I(&@````````````Z
+M#`(`````````[P`H#B,````````````I(&@`````````'0`@#BT`````````
+M`P`A`B,``````````!3@``````#Q````"P`A`B@``````````!3```````#Q
+M```$```I(B@`````````&@`@-B@`````````'``A#B(``````````!3`````
+M``#V``"C#``@1!$````````````@2!$`````````'@`A#B(``````````!3`
+M``````$$``"C#P`@1!$`````````$P`@#BT``````````0`O`B,`````````
+M``S```````#]_____P!`2!$```$$`````@`O`B,```````````S```````$`
+M``#__P!`2!$```$$````!``O`B,```````````S```````$#````_P!`2!$`
+M``$$`````0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3`
+M``````$+````$$`A#B``````````&0`@-B,`````````&$`B2B``````````
+M$,!"2B````$-```````@#!$`````````&0`@-B,````````````@2!$`````
+M```````@2!$`````````"@`@$!$````````````O`B0```````````S@````
+M``$4```````@2!$``````````0!3$B0```$0_[___P`H.BX`````````&P`A
+M`B(``````````!3```````$G@0`````@1!$`````````#0`@2!$`````````
+M&``B#C``````_``````H#B,`````@0`````@1!$`````````#@`@2!$`````
+M```````@$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`
+M````````)``@'BT`````````"``A2B<````````````@2!$`````!@H"```I
+M2B0````````````@2!$````````````@2!$```````````"`````````@0``
+M```@1!$``````````0`@2!$````````A?``@1!$``````(`````@2!$`````
+M```````@2`8`````````"``A2B<``````````!<```````````0A?P!@1!$`
+M``84````'P`A`C```````````!3```````83````!`!`3!$```$N``````!@
+M```````+``````!@!!$```+^```````@!!$```````````!@"!$```&?````
+M``!@``````%1``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*D``&A_0!@1!$`
+M``+)```__P`O`B\```````````S```````$X`````,!`!``````!``````!@
+M```````+``````!@!!$```+^```````@!!$```````````!@"!$```&?```_
+M_P`O`B\```````````S@``````````````!@``````%1````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*D``&A_0!@1!$`
+M``+)```__P`O`B\```````````S```````%)`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````%\``````!@``````&-```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&)
+M``````!@``````*D`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*,E0`````@1!$````````````O
+M`B$```````````S@``````%S`````,`@2````````````0!3!B$```%OD@``
+M```@1!$``````````,!@2`````&$``&A_0`@1!$`````````$P`@!BT`````
+M``````!X!"H```+D```````@*`D````````__P`O`B\```````````S`````
+M``%E`````,!`!``````!```"$`!@!!$```+^```__P`O`B\```````````S@
+M``````&!````&\`@-B``````````',`@-B``````/X`````@!!$`````1@``
+M``!@"!$```&?``````"```````````"A_``@1!$````````__P`O`B\`````
+M``````S```````&(`````0"`2!$`````````(0"`2!$```````#__T`H#B``
+M````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0`````@
+M1!$`````````!@`@2!$`````````"``B'C``````````,@`@&BT```````#@
+M```@1!$`````__O_"0`@2!$`````````$0`@(BT````````?_P`I2B@`````
+M````!@`@(BT````````````I(.@````````````@2`@````````````@2!$`
+M````!@H"```I2B8````````````@2!$````````````@2!$````````!```@
+M&!$`````````"`!B'B@```$H````"`""(B@```````+````@1!$`````````
+M&P!@#BT```&J````'`!@#BT```&J``#`"``@1!$`````````'0`@#BT`````
+M`````!3```````&F```````@!!$````````````@2`$`````.0`````@2!$`
+M```````````@2!$```````````"`2`(`````````(``@+BT````````````[
+M#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````````
+M``"`2`,```````````!@```````+```0``!@!!$```+^```````@!!$`````
+M``````!@"!$```&?````!P`A!B\`````````&0`@"BT``````````0`@+!$`
+M``````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````#P`F
+M)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````````
+M```O`B$```````````S@``````'-```B7``@1!$`````````@0`@2!$`````
+M``"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O`B<`
+M``````````S@``````')``````!@``````'6`````0!3'B<```'%`````0`@
+M+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```&^```B
+M7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`````
+M`````0`P'B\````````````O`B<```````````S@``````````````!@````
+M``'6`````0!3'B<```'2``#__T`H#B``````````#P`F#B,`````````$,`A
+M$B``````````#P`F$B0````````````@%!$```````````!@&!$```*D``&A
+M_0`@1!$````````````O`BL```````````S@``````'E````$``B%B@`````
+M__\````H%B4```````#__P`H&BD````````````I2,4````````````@2`H`
+M```````````@+!$`````````$``B%B,`````__\````H%B4```````#__P`H
+M&B0````````````I2,4```````````!S%0,```'R```````@&`4`````````
+M``!S%20```'R```````M%,4````````````P"*(````````````@2`(`````
+M```````@*`(````````````@(`,```````````"`)`0`````````#P`A`B4`
+M`````````!3```````83```````K%`4``````````0"0%B4```````````!@
+M```````+``````!@!!$```+^```````@!!$```````````!@"!$```&?```B
+M5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`````
+M``````S@`````````````,`@!``````````B7``@1!$``````````P`X2B$`
+M``````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````$,`A
+M&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*D``&A
+M_0!@1!$```+)`````0`S!B$````````````O`B$```````````S```````(&
+M```__P`O`B\```````````S```````'_`````,!`!``````!``````!@````
+M``7%``````!`!`\```(```````!@``````6R``````!@``````7%```"$`!@
+M!!$```+^``````!@``````&-``````!@``````&)``````!@``````*D````
+M``!@``````*,DX`````@1!$````````````@2`@`````E0`````@1!$`````
+M```````O`B\```````````S@``````(?`````,!`2`````(<D@`````@1!$`
+M`````````,`@2``````````B5@`@1!$`````````%@`@2!$````````B7``@
+M1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$```````&A
+M_0`@1!$```````````!@!!$```+D`````,!`!``````!``````!@``````6R
+M``"@#``@1!$``````````,`@2````````````,!`2`````````````!@````
+M```+````&$`A"B```````````P`O`B(```````````K@``````(U````&@`@
+M(BT```````@!`0`I(B@`````````&@`@-B@```````"C#``@1!$`````````
+M`,`@2````````````,`@2````````````,!`2`````(Z``````!@```````+
+M````$`!@!!$```+^/X`````@!!$```````````!@"!$```&?```B7``@1!$`
+M`````````P`@2!$```````````!@``````)E````'0`@'BT``````````0`A
+M'B<``````````!3@``````)3````&``@'BT```````#__P`H'B<`````````
+M```T'"<``````````!+```````)(```````@'!$````````````O`.4`````
+M``````C```````)+```````@%`<`````````&``@'BT`````````$``A'B<`
+M```````````T'$<``````````!+```````)0```````@'!$````````````O
+M`.8```````````C```````)3```````@&`<```````````!@``````*J```B
+M5@`@1!$````````````T(",``````````!+```````);```````T($0`````
+M`````!+```````):````%@!`2!$```)?````&`!`2!$```)?```````T($0`
+M`````````!+```````)>````%P!`2!$```)?````&0`@2!$```````"A_``@
+M1!$``````````0`@2!$```````&A_0!@1!$```+2```__P`O`B\`````````
+M``S```````(_`````,!`!``````!````$$`A!B````````#__\`H"B``````
+M````$$`A#B````````#__\`H$B``````````$$`A%B````````#__\"(&B``
+M````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```84``````!@
+M``````6R`````,!@``````*,````!0`@"BT`````````"``B"B(`````````
+M-``@&BT`````````)``@'BT```````!P```H'B<````````````Q'.8`````
+M````,P`@&BT`````````#``B&B8````````````O`.8```````````;@````
+M``)[```````@'!$````````````@#!$`````````-``@-B,`````````$``@
+M&!$```````````!I'.(```$HDX`````@1!$````````````@2`<`````E0``
+M```@1!$````````````O`B\```````````S@``````*&`````0`S/B\`````
+M`````-D`2```````D@`````@1!$``````````,`@2```````````)`!`-B<`
+M````````#,`B"B``````````,@`@-B(`````````,<!`-B````````"BI``@
+M1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`````````
+M*0`@'BT````````````L'.,`````````*0`@-B<`````````*@`@'BT`````
+M```````L'.0`````````*@`@-B<`````````*P`@'BT````````````Q(*,`
+M```````````M'0<`````````*P`@-B<`````````+``@'BT````````````Q
+M(,0````````````M'0<`````````+`"`-B<`````````*0`@-B,`````````
+M*@`@-B0````````````Q'*,`````````*P`@-B<````````````Q',0`````
+M````+`"`-B<`````````(@`@-B<`````````(P`@-B@`````````'0`@'BT`
+M`````````@`A`B<``````````!3```````+%``````!```````+"````(@`@
+M-B<`````````(P`@-B@`````````'0`@'BT``````````@`A`B<`````````
+M`!3@``````+"`````P`A`B<``````````!3@``````+%````*P`@'BT`````
+M```````N`.$```````````+```````+%````*0`@'BT````````````Q(*$`
+M```````````N`.@```````````;```````+%````+``@'BT````````````N
+M`.(```````````+```````+%````*@`@'BT````````````Q(,(`````````
+M```N`.@```````````;```````+%``````!@``````7M``````!@``````*>
+M``````!```````+'``````!@``````*>``````!@``````7D``````!`````
+M``+'``````!@``````*0``````!```````+'````(@`@'BT`````````(P"`
+M(BT`````````$``B'B,````````````I2(<````````````Q'*,`````````
+M$``B'B<````````````I2(<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@```````````")20<`````````$``B'B,````````````I2(<`
+M````````$``B'B$````````````I2$<````````````Q'*,`````````$``B
+M'B<````````````I2(<````````````Q'*$`````````$``B'B<`````````
+M```I2$<`````````$``B'B,````````````Q(,0```````#__P`H(B@`````
+M```````I20<`````````$``B'B$````````````Q(,(```````#__P`H(B@`
+M``````````")20<`````````$``B'B,````````````I2(<``````````0`B
+M"B$````````````S"*(`````````$``B'B(`````````$``A(B(`````````
+M```I20<````````````Q'*,`````````$``B'B<````````````I2(<`````
+M`````0`B"B$````````````P"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<````````````X",4````````````P"$$`````````
+M`0`B"B(````````````S"*(`````````$``B'B(`````````$``A(B(`````
+M``````")20<`````````'0`@(BT``````````!3```````,!____[P`H!B$`
+M````````&@`@(BT```````#XX``@1!$````````````I20$```````````")
+M20$````````````@2!$````````````@2!$`````!@H"``"`2!$`````````
+M`,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@1!$`````
+M```````@2!$````````B7``@1!$``````````,`@2`````````"A_``@1!$`
+M`````````,`@2````````````,`@!`````````````"@``H`````EP`````@
+M1!$````````````@2!$`````B@`````@1!$````````````@2!$````````B
+M7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@2```````
+M`````,`@!`````````````"@``H`````EP`````@1!$````````````@2!$`
+M````B@`````@1!$````````````@2!$````````B7``@1!$``````````,`@
+M2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`````````
+M`-D`2````````````,`@!`````````````"@``H````````B5P`@1!$`````
+M`````\!(2B`````````B70`@1!$``````````,!`2`````````````!@````
+M``7%`````,`@"``````````B7``@1!$``````````P`X2B(```````"A_``@
+M1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`````````
+M``S@`````````````$`@2````````````4`P2B```````````L`P2B``````
+M`````0!3"B(```,T````/\`H"B``````@0`````@1!$``````````0`@2!$`
+M```````A^``@1!$`````````%P`@2!$```````0A^0!@1!$```84````$0`A
+M`C```````````!3@``````,]````%``O`B(```````````S```````-1```@
+M$``@1!$```````"````@2!$```````&BI``@1!$````````````@2!$`````
+M````%@!@2!$```->```A```@1!$``````````,`@2````````````,`@2```
+M`````````,`@2````````````,`@2`````````&BI``@1!$````````````@
+M2!$```````````!`2`(`````````!``O`B(```````````S```````-5```@
+M$``@1!$```````"```!`2!$```-)````*``O`B(```````````S@``````-)
+M```A!``@1!$``````````,`@2````````````,`@2````````````,`@2```
+M`````````,`@2`````````"BI``@1!$```````````!`2`(`````````-0`@
+M-B8`````````20`@&!$````````````@2!$``````````0`S&B8`````````
+M```O`B8```````````S```````-@````-0"`&BT`````````/\`H"B``````
+M````%0`O`B(```````````S@``````-V````'@`O`B(```````````S@````
+M``.`````(``O`B(```````````S@``````.,````#P`O`B(```````````S@
+M``````.8````$``O`B(```````````S@``````.8````!@`O`B(`````````
+M``S@``````.:````%@`O`B(```````````S@``````.?``"BI``@1!$`````
+M``````!`2`(`````"``````I"B(``````````T`A#B``````````#,`A$B``
+M``````@````H$B0`````````%,`B%B`````````````I%*0```````"BI``@
+M1!$````````````I2*(```````"A_@`@1!$```````````!`2`,`````@0``
+M```@1!$``````````0`@2!$````````A^``@1!$`````````%0`@2!$`````
+M``0A^0!@1!$```84````%0`A`C```````````!3@``````."```A#@`@1!$`
+M`````````,`@2````````````,`@2`````````"BI``@1!$```````````!`
+M2`(`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````````
+M%@`@2!$```````0A^0!@1!$```84`````P`A`C```````````!3@``````..
+M```A"``@1!$``````````,`@2````````````,`@2`````````"BI``@1!$`
+M``````````!`2`(````````@$``@1!$```````"```!`2!$````````@$``@
+M1!$```````"````@2!$```````&BI``@1!$````````````@2!$`````````
+M!@!`2!$````````@$``@1!$```````"````@2!$```````&BI``@1!$`````
+M```````@2!$`````````%@!@2!$```->````%@!`2!$``````````,`@"```
+M`````````,`@#```````````'0`A`B,``````````!3@``````.Y@0`````@
+M1!$``````````0`@2!$````````A^``@1!$`````````%P`@2!$```````0A
+M^0!@1!$```84````$0`A`C```````````!3@``````.K```A```@1!$`````
+M```````@2`(````````````@2`,`````NK[*_@`@2!$`````ROZZO@`@2!$`
+M```````@$``@1!$```````"````@2!$```````"BI``@1!$`````````!`!`
+M2!$````````A<``@1!$````````````@2`(````````````@2`,`````@0``
+M```@1!$`````````"@`@2!$````````````@`!```````````!3```````.^
+MC``````@1!$`````ROZZO@!`2!$`````@0`````@1!$``````````0`@2!$`
+M```````__T`H"B``````@````$`H#B``````0````,`H$B````````0```!I
+M1B(```84```````@%!`````````````O`B,```````````S```````/,````
+M`,!`&`````//```__\`H&B````````0```!I1B8```84```````@&!``````
+M```````O`B0```````````S```````/2`````,!`'`````/5```__\`H'B``
+M``````0```!I1B<```84```````@'!`````````````@1`(````````````H
+M(,4```````````!)2.@`````I8`````@"!$````````@```@#!$`````@P``
+M``!@1!$```/]```````@1`(``````````,`@2````````````$`@2```````
+M````'\`A`B```````````!3```````/B```@$``@1!$```````"````@2!$`
+M``````#__\!($B````/JIX`````@"!$```````"@```@#!$`````@P````!@
+M1!$```/]```````@1`(``````````,`@2````````````,`@2`````````#_
+M_\`H$B``````@P`````@1!$````````````P2(,`````A``````@1!$`````
+M`````,`@2````````````!T`````````@P````!@1!$```/]`````,!`!```
+M```!J8`````@"!$```````#```!`#!$```/EJX`````@"!$```````#XX`!`
+M#!$```/EK8`````@"!$```````#X@`!`#!$```/ELX`````@"!$```````#S
+M_`!`#!$```/EKX`````@"!$```````#@``!`#!$```/EL8`````@"!$`````
+M``#P``!`#!$```/E@P`````@1!$````````A2``@2!$`````A``````@1!$`
+M`````````,`@2````````````!T```````````````"``````````!@@`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H``````!B@
+M`,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M`!C``,`P1B```````````-D`2````````````,`@!`````````````"@``H`
+M`````!CXX,`P1B```````````-D`2````````````,`@!`````````````"@
+M``H``````!CX@,`P1B```````````-D`2````````````,`@!```````````
+M``"@``H``````!C@`,`P1B```````````-D`2````````````,`@!```````
+M``````"@``H``````!CP`,`P1B```````````-D`2````````````,`@!```
+M``````````"@``H``````!CS_,`P1B```````````-D`2````````````,`@
+M!`````````````"@``H`````A@`````@1!$```````````!`2`$`````A0``
+M```@1!$```````````!`2`$````````A?``@1!$``````````,`@2```````
+M`````,`@2````````````,`@2```````@0`````@1!$``````````0`@2!$`
+M`````````,`@"````````````!<```````````0A?P!@1!$```84````'P`A
+M`C```````````!3```````````````!`3`(```0N`````,`@#```````````
+M`,`@$````````````,`@%````````````,`@&````````````,`@'```````
+M``!_```H"B$```````!%```O`B(```````````S@``````0\`````,`@(```
+M`````````!<`````````````$``H"B,`````````$``O`B(```````````S@
+M``````1$@0`````@1!$``````````0`@2!$```````0```!I1B0```84````
+M``!```````1-@0`````@1!$````````````@2!$````````A;0`@1!$`````
+M```````@2`0````````````@2`4``````````!K```````1)G@`````@1!$`
+M````ROZZO@`@2!$``````````!K@``````1,```````H)/``````````!P`H
+M"B,``````````0`O`B(```````````K@``````14```````O`,D`````````
+M``3@``````1M``````!```````1Z`````@`O`B(```````````K@``````19
+M```````O`,D```````````+@``````1M``````!```````1Z`````P`O`B(`
+M``````````K@``````1>```````O`,D```````````S@``````1M``````!`
+M``````1Z````!``O`B(```````````K@``````1C```````O`,D`````````
+M``K@``````1M``````!```````1Z````!0`O`B(```````````K@``````1H
+M```````O`,D```````````;@``````1M``````!```````1Z````!@`O`B(`
+M``````````K@``````1M```````O`,D```````````C@``````1M``````!`
+M``````1Z``!_```H"B$```````!%```O`B(```````````K@````````````
+M"``A"B,``````````!3```````1W```A:0`@1!$``````````,`@2```````
+M`````,`@2````````````,`@2```````ROZZO@!`2!$``````````,`@1```
+M`````````,`@`````````````,!`2`````````!_```H"B$```````!%```O
+M`B(```````````K@``````2``````,`@`````````````,`@````````````
+M`,!```````````````!`3`@```0\`````,`@"```````````$$`A#B``````
+M````$4`A$B``````````$D`A%B`````````A:0`@1!$````````````@2`(`
+M```````````A`B4``````````!3@``````2*``0``,!)2B````2+__O__\`H
+M2B`````````````A`B,``````````!3@``````27`````,`@2```````````
+M`,`@2``````````````A`B0``````````!3`````````@0`````@1!$`````
+M````#``@2!$````````````@`!```````````!3```````23H``````@1!$`
+M````ROZZO@!`2!$`````@0`````@1!$`````````!``@2!$````````A:P`@
+M1!$``````````,`@2!``````@0`````@1!$`````````!0`@2!$````````A
+M;``@1!$``````````,`@2!`````````````O`B0```````````S@````````
+M``````!```````21`````,`A"B```````````!3```````2N@0`````@1!$`
+M```````````@2!$````````A;0`@1!$``````````,`@2````````````,`@
+M2````````````!K```````2IG@`````@1!$`````ROZZO@`@2!$`````````
+M`!K@``````2L``````!```````2R@0`````@1!$``````````0`@2!$`````
+M``0``,`I1B```````````,!@``````84`````0`A`B(``````````!3`````
+M``2Y```A:0`@1!$``````````,`@2````````````,`@2``````````````@
+M2!``````ROZZO@!`2!$``````````,`@1````````````,!`2!``````@0``
+M```@1!$``````````0`@2!$````````A^``@1!$`````````#0`@2!$`````
+M``0A^0!@1!$```84```````A`C```````````!3```````2[```A@``@1!$`
+M`````````,`@2````````````,`@`````````````,`@2````````````,`@
+M`````````````,!`2````````````P`S/B\``````````0`A`B$`````````
+M`!3@``````3K````-0`@"BT```````0``!C@#!$```3:`````0`S/B\`````
+M```A:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`
+M`````````,`@2````````````,`@2``````````A:0`@1!$````````````@
+M2`(````````````@2`,`````````"``P"B(``````````,`@2```````````
+M`-C`2`````3.```A:0`@1!$````````````@2`(````````````@2`,`````
+M````"``P"B(``````````,`@2````````````,`@2```````````-@`@$BT`
+M```````````I#(,````````A:0`@1!$````````````@2`(````````````@
+M2`,`````````"``P"B(``````````,`@2````````````,`@2```````````
+M$0`A`B0``````````!3```````````````!```````21````-<`@-B``````
+M````-L!`-B`````````P2@`@1!$`````X````,!(2B``````````#P`A`B$`
+M`````````!3```````3R``````!@```````+`````-D``````````````,!`
+M!``````!@0`````@1!$``````````@`@2!$`````````_P`H#C``````````
+M```O`B,```````````S```````3V`````,`@"````````````!3```````4+
+M```````@#!$`````````)``@-B,`````````-``@-B,`````````,@`@-B,`
+M````````,0`@-B,`````````'0`@-B,`````````+0`@-B,`````````+@`@
+M-B,`````````&P`@-B,`````````'``@-B,`````___@```@#!$`````````
+M*0`@-B,`````````*@`@-B,````````?_P`@#!$`````````*P`@-B,`````
+M````+``@-B,`````\?___P`H.BX`````````&L`B#B`````````````I.&X`
+M````@0`````@1!$`````````!@`@2!$`````````,T`@-B``````AP`````@
+M1!$``````````,`@2`````````"A]``@1!$````````````@2!``````G0``
+M```@1!$`````````'T`A2B``````E@`````@1!$``````````,`@2```````
+M`````,`@#````````````,`@$```````````'P`A%B0``````````!3`````
+M````````)0`@-B,``````````P`H'B,`````````"``B(B,`````___P```H
+M(B@````````````I(.@`````````)P`@-B@`````````&``A'B,`````````
+M*``@-B<``````````@`B%B0````````````P%*@`````````)@`@-B4`````
+M`````P`A&B0`````$``````H&B8`````[____P`H.BX```````````!).,X`
+M``8"`````4`H"B``````````!D`H#B`````````#`,`H$B``````````"``A
+M$B0``````````,`@%B```````````,`@&B`````````````A`B(`````````
+M`!3```````5!@0`````@1!$``````````0`@2!$````````B6``P"B0`````
+M``0```!I1B(```84```A:0`@1!$````````````@2`4```````(````I2B8`
+M```````````@2!``````ROZZO@`@2!$``````````@`O`B,```````````S`
+M``````5)`````,`@'!```````````,!```````5;`````@`O`B,`````````
+M``S```````5)@0`````@1!$``````````0`@2!$````````B6``P"B0`````
+M``0```!I1B(```84`````,`@'!```````````,!```````5;```````O`B,`
+M``````````S```````5-`````,`@'````````````,!```````5;````!``O
+M`B,```````````S```````59@0`````@1!$````````````@2!$````````A
+M;0`@1!$``````````,`@2````````````,`@2````````````!K```````54
+MG@`````@1!$`````ROZZO@`@2!$``````````!K@``````57``````!`'!``
+M``5;`````,`@`````````````,!```````````````[@``````5=``````!@
+M``````6D```````O`B0```````````S```````5M``"BMP`@1!$`````````
+M```@2`<`````@0`````@1!$``````````0`@2!$```````2BM@!@1!$```84
+M````&@`A(C``````````!@`B)C````````"BQ``@1!$````````````P2.D`
+M``````````#@``````5K``"BT0`@1!$```````````!`2`@```````"BT0`@
+M1!$``````````0!02B@``````````0`O`B0```````````S```````5]``"B
+MNP`@1!$````````````@2`<`````@0`````@1!$``````````0`@2!$`````
+M``2BN@!@1!$```84````&@`A(C``````````!@`B)C````````"BQ0`@1!$`
+M```````````P2.D```````````#@``````5[``"BT@`@1!$```````````!`
+M2`@```````"BT@`@1!$``````````0!02B@``````````@`O`B0`````````
+M``S```````6-``"BOP`@1!$````````````@2`<`````@0`````@1!$`````
+M`````0`@2!$```````2BO@!@1!$```84````&@`A(C``````````!@`B)C``
+M``````"BQ@`@1!$````````````P2.D```````````#@``````6+``"BTP`@
+M1!$```````````!`2`@```````"BTP`@1!$``````````0!02B@```````"B
+MPP`@1!$````````````@2`<`````@0`````@1!$``````````0`@2!$`````
+M``2BP@!@1!$```84````&@`A(C``````````!@`B)C````````"BQP`@1!$`
+M```````````P2.D```````````#@``````69``"BU``@1!$```````````!`
+M2`@```````"BU``@1!$``````````0!02B@`````A0`````@1!$`````````
+M```@2`$````````P2@`@1!$``````0`````@2!$```````````!```````6?
+MI````,`@1!$``````````,!`2````````````,!@``````6D`````,!`!```
+M```!``&BI``@1!$````````````@2!$````````````@2!$````````````@
+M2!$````````````@2!$`````````!0`@2!$```````"A]``@1!$`````````
+M```@2!$`````B``````@1!$``````````0`@2!$`````_P`````@1!$`````
+M```````@2!$``````````0`@2!$``````````@"`2!$```````````[@````
+M``6W```0```@"!$`````````-``@-B(```````````!@``````6[``````!@
+M``````6DF``````@1!$```````````"`2!$``````````,!@``````6[````
+M`,!`!``````!``"BI``@1!$`````````(@`@2!$`````B0`````@1!$`````
+M`````0`@2!$`````_P`````@1!$````````````@2!$``````````0`@2!$`
+M`````````@"`2!$````````A>L`@1!$```````````!`2!$`````EP`````@
+M1!$````````````@2!$`````B@`````@1!$````````````@2!$`````_P``
+M```@1!$````````````@2!$``````````0`@2!$``````````@"`2!$`````
+M``````!@``````7A```@$``@1!$```````"````@2!$```````&BI,`@1!$`
+M```````````@2!$`````````%@!@2!$```->````%@`@2!$````````@$``@
+M1!$```````$````@2!$`````@0`````@1!$``````````0`@2!$````````A
+M?``@1!$`````"8`````@2!$`````_____P`@2!$````````````@2!$`````
+M`````!<```````````0A?P!@1!$```84````'P`A`C```````````!3`````
+M````````!`!`3!$```7<````'0`@'BT`````````!``I'B<`````````'0"`
+M-B<`````````'0`@'BT`````____^P`H'B<`````````'0"`-B<`````````
+M'0`@'BT`````````"``I'B<`````````'0"`-B<`````````'0`@'BT`````
+M____]P`H'B<`````````'0"`-B<````````@$``@1!$```````"````@2!$`
+M``````&BI``@1!$````````````@2!$`````````%@!@2!$```->````%@`@
+M2!$````````@$``@1!$```````$````@2!$````````A?``@1!$``````8``
+M```@2!$``````/___P`@2!$````````````@2!$``````````!<`````````
+M@0`````@1!$``````````0`@2!$```````0A?P!@1!$```84```````@`!``
+M`````````!3```````83````$`!`3!$```7Y`````,`@!````````````#C`
+M````````````)0`@"BT`````````)@`@#BT`````````)P`@$BT`````````
+M*``@%BT````````A:0`@1!$````````````@2`0````````````@2`4`````
+M```````@2`$`````ROZZO@`@2!$`````````!``P$B0````````````O`&0`
+M``````````S```````82`````P`H&B(`````````"``B$B(`````___P```H
+M$B0````````````I$,0`````````)P!`-B0```````````"`````````````
+M`!K```````84GP`````@1!$`````ROZZO@`@2!$``````````!K@``````87
+M``````"```````````````!@```````+```0``!@!!$```+^```````@!!$`
+M``````````!@"!$```&?```B7``@1!$``````````P`@2!$````````B5@`@
+M1!$`````````&P`@2!$```````"A_``@1!$``````````0`@2!$```````&A
+M_<`@1!$`````````*0`@'BT`````````$``B'B<`````````+``@(BT`````
+M``#__P`H(B@````````````I20<````````````@2!$`````````*@`@(BT`
+M``````#__P`H(B@````````````I20<````````````@2!$`````````*P`@
+M'BT`````````$``B'B<````````````I20<```````````!`2!$`````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````3,$[P6;`CD``````;`!600E!9L``````A(!
+M]@(Y`4(``````A`"+@*)`BH``````\(%FP6;!9L`````!<T%S@,(!9L`````
+M!9L%H`,)`RD``````Q,":P,K`QT`````!9L%FP6;!9L`````!9L%+`6;!9L`
+M`````Z4%FP2B`RT`````!($$,P0C!9L`````!+L$[00G!,@`````!#,$]`,Z
+M`V4`````!9L%FP6;!9L`````!9L%FP6;!9L`````!9L%FP6Y!:(`````!9L%
+MFP`'!9L`````!9L%FP6;!9L`````!9L%FP6;!9L``````^,#V`/S`_$`````
+M`_D#]0/W`_L`````!`<$`P0/!`L`````!!<$$P0?!!L`````!9L%FP6;!9L`
+G````!9L%FP6;!9L`````!9L%FP6;!9L```````(&``89``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R600_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R600_pfp.bin.uu
new file mode 100644
index 0000000..a40821c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R600_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 R600_pfp.bin
+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
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%T``(!>P`#`)``!`"```4`!0`&
+M`$``!P`S``@!+P`)`$<`"@`W`!`!MP`7`*0`(@$]`",!3``@`+4`)`$H`"<`
+M3@`H`&L`*@!A`"L`4P`O`&8`,@"(`#0!@@`\`5D`/P!S`$$!CP!$`3$`50%V
+M`%8!?0!@``P`80`U`&(`.0!C`#D`9``Y`&4`.0!F`#D`9P`Y`&@`.P!I`$(`
+M:@!)`&L`20!L`$D`;0!)`&X`20!O`$D`<P&W````!P````<````'````!P``
+M``<````'````!P````<````'````!P````<````'````!P````<````'````
+)!P````<````'
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R600_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R600_rlc.bin.uu
new file mode 100644
index 0000000..465b41a
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R600_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 R600_rlc.bin
+M`"@$$``H1```U$`1`-0`>0`$&`$`U8!Z`-0`=`#4`',`U``+`(0"L@`QA!\`
+MA`(_`"@$`0#4``X`*"`$`,@0=`#(!#8`F$+0`"@IW@#(!'D`F$`(``````#(
+M*`H`EH`%```````H*=\`@`"(`-6`#@#(*```EH`I`"@(`0#4@```#HF[`)2`
+M"0#*Q`$`E0#]`#!$#`#02`0`E(#Q`"@@`0"``2H```````Z)O`"8@-P`*"`&
+M`)4!^P`.B;X`E(`$``````#5@'D`@``-``Z)O0"4@`0``````-0`>0"```T`
+M#HFT`)B`\0`H(`0`%HFW`)B![``>B;H`F('J```````.B;H`E(#I`"@@!``H
+M(`(`@`$J``````#(*`(`EH`7`"@(`0#4@`(`E0'>`":$`0"80`,``````"@@
+M```BB<@`&HW=`'R,BP"8@-@`(HF8`!J-FP!\C(L`F(#4`"*)J``:C:L`?(R+
+M`)B`T```````@`(H``````#(*`$`EH`+`"@(`0#4@`$`E0'&``Z)Z`"8@,8`
+M#HGJ`)B`Q```````@`(H``````#(*`,`EH`'``Z-Y0"8P/T`*`@!`-2``P"`
+M`B@``````,@H!`"6@`D`*`@!`-2`!`"5`;(`#HGB`)B`L@``````@`(H````
+M``#(*`4`EH.3`"@(`0#4@`4`E0&H``Z)D@"8@*@`#HF4`)2!I```````@`$J
+M`"@@`@"$`+T`*"`#`,K$```D1`(`E$`&``````#(!'@`U$!W`(`!+@``````
+MA`*R`#&$'P#*Q```)$0!`)A`/P``````R`1Z`-0`>@#("'T`RLP+`'R,@@"4
+M0`8``````)2`"P``````@`"G``````"4@(L``````(`"E0``````A`*R`#&$
+M'P"``I4`R`1]`,@(?P!\2$(`F$`$``````"$`K4``````,K$`0`P1`P`T$@`
+M`"2(`0"8@04``````(0"!```````A`+(``````"``I4``````,@$(0`P1`@`
+M*`A``,@0(@"5`TP``````-4`>`#4`'<`?`#```3,#``)$`$`F0/^``````#0
+M4```U0@```C,`0"4P`8```````1$!``$B`$`@`#*``````"(````*"Q``-6`
+M=`#*Y`L`RMP"`-9`?P#60'T`-F0$`-9`"P#60"T`U<!^`-7`?`#(!"0`,$0(
+M`-1`>P#*Q```)$00`)A#*0``````A`(W`"@$`0`,1`(`F$&8`"@%\0!]P$P`
+M?<",`(0"3P``````A`(W`"@$`P`,1`(`F$&/`"@%\`"$`C<`*`0"``Q$`@"8
+M08H`*`7P`(0"-P`H!`0`#$0"`)A!A0`H!?(`A`(Y`"@$`@"$`DH``````,$!
+M\``H!```V'```(``#0``````R`1Z`)A`!```````@``-``````#4`'H`R`1W
+M``A$`0#40'<`A`*R`#&$'P"``IX``````,K$`0`P1`P`W`0``,@$=P`$1`$`
+MU$!W``;L#`#("'@`?$B"`)2#D@``````"NP,`-6`>@"$`K(`*`0``)4!>P``
+M````@`*5``````#*Q`$`,$0,`-V$``#(!'<`!$0!`-1`=P`&[`P`A`*.````
+M``"$`CT`*`0``(0"-P`H!`$`#$0"`)1`!0``````*"`$`"@I\0``````R`1W
+M`,@(>`!\2((`E(!C``````"$`F``*"`%`(0"+```````R"@*`):#_P`H(`,`
+M*"G?`(0`O0`H(`,`RL0+`,@(?0!\2((`U(!S`)2`4P``````A`("``````"$
+M`C<`*`0$``Q$`@"802T`*`7R`,@$<P"80`H`U`!S`,K$`0`P1`P`T$@``"2(
+M`0"8@`0``````(0"R```````A`(]`"@$`0#(!"``)$3]`-1`(`"$`CD`*`0"
+M`(`"E0``````R`1Z`)1`!@``````A`(_`"@$``"80`D``````(0"L@`QA!\`
+MP0'P`,\$```H!```@``-`-1``P`H!`$`U$`#`,$!\0#/!```-$0$`)A#_@``
+M````Q"@*`)J`&0#(*```#H6\`)A`$P``````P2`$`,\$```T1!\`F$`1````
+M``#(*`4`EH`%`"@(`0#4@`4`A`(L``````#(*`,`#H7E`)1#[0``````@`&9
+M``````#4`'H`A`*R`#&$'P"$`CL`*`0"`-@P``"$`C\`*`0!`(``#0``````
+MU`!R`,K$`0`P1`P`T$@``"2(`0"8@`4``````,@(?@"``:L`U8!R`,K(`@#(
+M!'P`A`)/``````"$`C<`*`0#``Q$`@"80`0``````(`!3P``````R`1R`)1`
+M'P``````@`*!``````"$`HX``````(0"/0`H!```A`(W`"@$`0`,1`(`E$`%
+M```````H(`0`*"GQ``````#4`'(`RL@"`'P`3`"$`D\``````(0"-P`H!`(`
+M#$0"`)1#@0``````R`1R`)1`!```````@`*!``````#*Q`L`U$!V`(0"8```
+M````UH`,`"@@!``H*?``R`AV`-2`?0`TB`0`U(`+`,@$=P`$1`$`U$!W``;L
+M#`#("'@`?$B"`)2`#P``````R!0*`)5#_P``````A`"]``````#(!'T`RL@+
+M`'Q(0@"80^4`R`1V`'Q(0@"80^(``````,K$`0`P1`P`T$@``"2(`0"8@\T`
+M`````-6`<@#("'X`?`!,`(0"3P``````@`'+``````"$`D,`*`0&`,$%%@#*
+MQ`H`V'```,$%.`#*Q`@`V'```,$%.0#*Q`D`V'```,$%7P#*Q`,`V'```,$%
+M)@#*Q`8`V'```,$%+@#*Q`<`V'```,$%9P#*Q`0`V'```,$%;P#*Q`4`V'``
+M`,\$``#*Q```)$0$`)A`!``H!`$`@`(D```````H!`(`A`)#``````"(````
+M`````(0"+```````@``-```````FJ/\`UH`,`(@`````````V'```,\$```T
+M1`0`E$/^``````"(`````````(`",`#!#OL`@`(P`,$/D0"``C``P0'Q`(`"
+M,`#!`Y$`P2`#`-AP``"(````SP0``(`",`#!!1X`R#`@`"LP`@#7`"``B```
+M``````#(,"``)S/]`-<`(`"(`````````"@4'P`Q5!L`?41,`"@4"``Q5!L`
+M?4B,`,$/```H#`@`V+```-AP`0`(S`$`E,`$``<P$`"``E<``````(@`````
+M````U``P`,@(>P#(#'T`?.#,`-S(``#(#"X`W,@$`,@,+P#<R`@`R!0E`,@,
+M)P#($",`!,P!`'S1!P"9``@```````2(#`#4@'L`U,`G`-S4``"``GL`````
+M`,@()``PB`@`U(![`-0`)P!\`,P`R`@E`-S(``"$`H@``````(@`````````
+M?$*,`(0"8``H(`0`A`(L``````"``H8``````,@$#0`(1`,`F$/^``````"(
+M`````````,@$(``H1`(`U$`@`(0".0`H!`$`B`````````"$`F```````,$\
+M@0#/!```V'```,$T`0#/!```V'```(0"+`#($'0`E0%N``````#(!'H`E$`$
+M`,@D?P"``J<``````,KD"P#60'T`-F0$`-9`"P#60"T`RLP"`-3`?`#*S`$`
+M,,P,`-3`=0"```T``````,$!\`"(````V'```,@$=0#!__\`T$@,``1$!`!\
+ML,L`E,`,``````#,T```W00,``1$!``TB!``E(`&``````#,D```W00,`(`"
+MMP`$1`0`B`````````#!,$$`,80?`-AP``#!/((`V'```,$T``#8,```RL0!
+M`#!$#`#!__\`T$@,``1$!`!\L,L`E,`*`-!0#`#9#```!$0$`#2($`"4@`4`
+MT%`,`-D(``"``M(`!$0$`(@`````````R`0*`-0`>0"$`C<`*`0!`,@(?@#(
+M!'P`A`)/``````"$`C<`*`0#``Q$`@"80Y4``````(0"-P`H!`0`#$0"`)A#
+MD``H!?(`*"`$`(0"8```````A`(L``````#()'\`UD!]`#9D!`#60`L`UD`M
+,`(``#0#4`#8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/R700_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/R700_rlc.bin.uu
new file mode 100644
index 0000000..39dcd15
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/R700_rlc.bin.uu
@@ -0,0 +1,95 @@
+begin 644 R700_rlc.bin
+M-#@`$#>X``#/@``2S```T\P``-T$&``!S!@`T\P``,G,&`#)S8``U<V8`-7,
+M``#+S!@`R\P``-G,&`#9S```P\V``,C,&`#!S```P<P``,S,```+S```#H``
+M`8L`````R?@`S<G(`,1DB``@?XN`+`>T``#`,/__RXX`!#0(``0PS``/?,C`
+M`IC``@L`````RXH`#$>X``1\L,`+E,`"!@````#(T0``S3H`#`>X``0HB``0
+ME(`"``````#(D0``S3H`#(```"0'N``$R>P`V<@0`,O)^``)S!P`TYG``#L`
+M````A``!W0````"$``%]`````(```PS-G`#5R#``0#<P``+/``!`B```````
+M``#/L0``S8``#LLY```SN``0*[@`!)>`__T`````B`````````"(````````
+M`(```PDT(``(P#`T`,LY``#/L0``@``#"0`````RJ`#_SH``#(@`````````
+MRP@`1"2(``C,G`#7:(@`(,R<`,;,,`!'?`#`#,L4`$9E5``@RP@`17R4@"S,
+MR@``A```E`````"(`````````(```$3`,`'!A``!P`````"$``%]`````(``
+M`2``````A``!P`````"$``%]`````(```PS-G`#5`````,@X`%<T*`'AFX#_
+MN#0<``'("`!`,(@`()2``RK,``#=Q"@`"I:``R?,``#=-!P``<G(`-7)S`#)
+M?,B`#)2``JL`````R"@`"C0H`?#($`#+R>P`V8```-/-@``.A```/P````"(
+M`````````,@X``T+N``!FX#__@````"(`````````#0X``'/@``#R!``R\`P
+M`<'+.0``*[@`!)N`__X`````S```R`````#("``:E(`!N<V``-T`````A```
+M:C0X``+,,0``A```LC0X``'-@`#(A```MC0,``"```);`````,`P(`//L0``
+MB````,LY``#`,`.0RSD``,`+__Y_BX`+),P`$'^/@`S/L0``B````,LY``#(
+M*``*-"@!\(```-/-@``.R"@``Y:``@H`````#HP!Y9C``$<T"``!S(```X``
+M`B<`````B``````````T'``!R!``R\GL`-F```+N-"``!,P<`,/,```5A``"
+M/S0@``.9P``$`````(0``=,EN``?R?@`R9N``(P`````RO@``#.X``&;@`!Q
+M`````,GT`-7,'`#5R<@`V\K,``9\C(`"ET`"(@````"```*JS(``P\P``%#)
+MR`#7R<P`QF3,`"!\C(`LA``"!G\#``O+#`!-),P`!'S@P`S,R@``R`P`3LS*
+M``3(#`!/S,H`"(0``@9_`P`+RPP`1F3,`"#+%`!%?4U`+,L,`$?+$`!#!,P`
+M`7S1``>9`/]6`````$2(``S,G`#7:(@`(,R<`,;,\`!'S-8``(```&$`````
+MR<P`U93```@`````A```MC0,``&$``"R-#@``)N`_X4`````A```MC0,``"$
+M``'3);@`'\`P`<#+.0``-#@``(```EO/@``#R<@`PYB`_[(`````A``!?0``
+M``#)^`#!FX`![P````#)^`#/EX`![``````+N``!SYP`SP;L``>```*J````
+M`,V<`-69P``$`````(0``=,T.```E0`!*0````"```$Y`````(0``!@`````
+M@``!(`````#*\``&SQP`V\P<`-65P`(S`````,`P-`#,,0``@``#?@`````.
+MB`&\F(``SP````"5``#>``````Z(`;Z4@`#5`````,V``-.```);`````,V`
+M`,O*Y``&SEP`WLY<`-LJ9``$SD``"X0``@9_`P`+SG``3<LX`$0GN``(SYP`
+MUVNX`"#/G`#&F<``_`````"$``'3-#@``)G``/@`````P#`C58```EO.<0``
+MRL@``#"(`!"8@/[E`````,P<`,F9P``$S!P`%H0``8<T.``'A``!AS0X``&9
+MP/[>`````(```PD`````*YP`'RNX`!`SJ`#_S```S(```NXT(``$R#``0#,P
+M`_W/``!`B`````````#-@``.?!R`#,`P!1V```!$?Q\`((0``8(`````B```
+M``````#("3TVR`T]-Y3`_QL`````R!$].,@5/3G('3TZR"$].\@E/34$J``P
+MSH$]@LS!/8/-`3V$S4$]A<W!/8;.`3V')(@``P2,`!C(E@`\E4#_"LC2`"A]
+M)0`!"50``03,`"B9`/_[`````,B2`#@%$`!`?0K``,C6``3`'``$R.(`%,CF
+M`"3."@%,SFX!3`C,``0(B``$"NP`!`G<``&9P/_X`````,T*`6#,"@%DS4$]
+M1X```*@`````S!P`U9G``*$`````A``!TR6X`!^```);`````(0``TXT.``!
+M-#@``<`P`YB$``(+)[@`%,P``%?`,`.8S#$``(@```#+"0``F<`!4<P<`,&`
+M``,=P#`AN80``3T`````@``#"0````#`,`'`B````,^Q``#-G`#!F<`!RP``
+M``#`,"&YS;$``(```EX`````P#`C5L`(`0#`.O\`?XN`#,^Q``#+.0``A``#
+M3C0X``/`,"`(A``""S0X___`,"`(S#$``,LY``#`,`.8A``""S0X`0#,``!6
+MP#`#F,PQ``#+"0``P#`C5L`(`0#,L0``RSD``,`P(;:(````S#$``#0X``'/
+MG``6F(````B(``&$``(1`````(```PD`````A``!P`````#-G`#5@``#%0``
+M``"5P``#``````<P`"B(`````````,^Q``#+.0``-`@`'YB````(B``!S!P`
+M%LGP`!N7`/__`````(@`````````R?@`U9N`_Z(`````@``"6P````"9P/Y1
+MS9P`U80``=T`````@``!(``````.B`&]E(``!`````#,``#3@``"6PZ(`<&$
+M``!6`````(```EL`````B`````````"(`````````,@H``*6@`$F-`@``<R`
+M``(BB`'<&HP!W7R,@`N8@/Z8`````"*(`<@:C`';?(R`"YB`_I8P'```@``"
+M)P````"$``(&?P,`"\LX`$%GN``()<@`!32(`(!\@L`,SMP`V<L0`$*5``#!
+M`````,T<`-%]&,`!S-P`SWP`P``$S``'"1```9D`__X`````RY(``,T(```(
+MS``!E,#_U@````!'N``$!(@``8```E(`````-"``!,P```[($`#+R#@`S)N`
+M_Q@`````R#@`5C0H`<.;@/W0-!P``,@0`,O)[`#9R?@`T\@(`-U\N,`,F,#^
+M#P````#("`#(E(#^-P````#(#`!`,,P`()3``3C-@`#=Q"@`"9:``3+-@`#=
+MR<@`U<G,`,E\R(`,E(``N@````#(*``)-"@!W\GL``"```#3S8``#IB``10T
+M(``&#H@!PI2```@`````R"@`"30H`=_-G`##S9P`U9B``0LT(``##H@!PYB`
+M`&(T(``$#H@!P)B``04T(``'#H@!MYB``%PT(``$#H@!N)B``%DT(``$#H@!
+MN9B``%8T(``$#H@!M)B``%,T(``$%H@!M)B`_XD6B`&WF(#_AQZ(`<"8@/^%
+M``````Z(`;J4@`!)-"``!#0@``*```.4`````(0``=,EN``?RO@``6>X``S+
+MC@`$-,@`!'R,P`+,'`#5F,``5`````"$``,?`````(0``8<T.``!`````,@(
+M`,.8@``)S```P\G(`,&4@/\2`````(0``<L`````@``#"0````"9P/V.````
+M`,`P,$'+.0``P`O^_W^(P`O,\0``RPT``,^Q``"```,)`````,@H``0T'``!
+MR!``RY:`_XW)[`#9-`@``<R```0.B`'PE(``"@````"$```_`````,@H``HT
+M*`'PS9P`P\V<`-68@`"V-"```PZ(`>*8@`"S-"```@Z(`?:8@`"P-"``!@Z(
+M`?.8@/Y)-"```0Z(`>&8@``$`````(```B<`````R`@`0#"(`""4@/\W````
+M`,GL`-G)^`#-R<@`Q&2(`"!_BX`L9HP`$'S@P`S,^@`$A```D`````#("`!`
+M,(@`$)B``)$`````F<#_`0````"$``'=`````(```@,`````9<P`'WS(@`S,
+M@`#,A```ZP````"$``!6`````,GX`-67@`!4R>0`WC((``&8@`!2`````(``
+M`V/.7`#;A``!?0````#-G`#5A``!RP````"```,)`````,`P-!B(````S#$`
+M`,`P!15_'P`@RO@`!<^Q``#`,`50?Q\`(,KX``+/L0``P#`%6'\?`"#*^``#
+MS[$``,`P!6!_'P`@RO@`!,^Q``#+.0``B```````````````R>P`V<G(`,&8
+M@`!T`````(0``@9_`P`+RS@`0I>`_IP`````RS@`06>X``@T-``'S```%<N*
+M```+=``!FT#__@>X``3*S``&?,B``I2`_I``````F<#]=S0@``/(*``)-"@!
+MWX```-/-@``.SYP`%LV```[)\``8?SB``I2`__X`````B`````````#(*``!
+MEH#];``````P'```-`@``<R```&5`/[+#H@!Z)B`_Y`T(``$@``")P````#*
+MY``&*F0`!,Y```N$``(&?P,`"\YP`$W*S``!),P`#,S<`,UHS``@S-P`Q,[<
+M`-F9P/[M`````,`P(U6```);SG$``,@(``"4@``#-`P``<S```#`,#!!);@`
+M'\^Q``#`,"&.P`H``32(`/_,L0``RO@``6>X``S`,/__RXH`!,N*``Q'N``$
+M?+#`"Y3`_4?+D@`,S0T``$>X``0HB``0E(#]0LN2``S-"0``@``#@D>X``29
+MP/YJ-`@`'S0X``.```'[SYP`%H0``!@`````F<``"`````#`,"&2RPD```=T
+M``C,M@`,!W0`+,RV``R$``'+`````(```AL`````P#`T&,VQ``"```)>````
+M`,G(`,F8@/ZW`````,@(`,B4@/Z%`````,@H``"6@/Z"-`@``<R````P'```
+M#H@!NY2`_90`````@``!,#0@``$`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+!````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/README b/sys/contrib/dev/drm2/radeonkmsfw/README
new file mode 100644
index 0000000..0942090
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/README
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+Firmwares come from:
+ git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_me.bin.uu
new file mode 100644
index 0000000..e52fb2b
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 REDWOOD_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*!`RA_<`2``',``!%S```2GS0
+MP`?,02)<S$&A_-1-``!\0(``H````,R``$V`````S$$B7<P``$7,``!*"$P`
+M`7Q!``!\04``'5C__QE<`_`58``5S8&A`LW!(E;.`2)<E,``!2$D`"#.0:'\
+M@```?0C,``'-`:'\S`&A`GQ`@`"@````S(``37Q`@`!\0,``P"H``GQ!``!]
+M*0`'')0``1R8``8<G`,`%=P`"'Q"``!\0D``E4``#\`N``0%\")8?R\`!\PQ
+M``#(*``$S,$A:<T!(6K.@2%K*;0``LP!(6R70``.*;0``(```+W(-``.*;0`
+M`I=```DIM```P"X`!`7P(EA_+P`'S#$``,@H``2```"]R#0`#I=```1^`H``
+M@```O<@T``XIM``$ET#_20````#.`2%MSD$A;L@H``/(-``.FT``!,@\``Z$
+M``-.S```32GT``"70``'!#"BMH0``-_.@:*WSX&BQ(````#/P:+1*?0``9=`
+M``<$,**ZA```W\Z!HKO/@:+%@````,_!HM(I]``"ET``!P0PHKZ$``#?SH&B
+MO\^!HL:`````S\&BTP0PHL*$``#?SH&BP\^!HL>`````S\&BU,`N``1_+P`'
+MS#$``,@L``3`,``&?O-`(\`P`"!_:X`@B````'^SP"3,``!"@````,Q``!]\
+M0,``?$$``!D4`#V90``3!!0`+H0`!,$$&``IA``"6L@<`!,$%``JA``$P008
+M`"W-0:*DR!P`$Y7```#('``3S,$A`,T!(0',P2$"S0$A`X``!+[-@:*D'1@0
+M`)6```7('``3*>0`0)9`___('``3S,$A=<T!(7;((``4E@```,@@`!06*``!
+MFH``!,P``$^```2^S```?X```0G,P2%U?$#``'Q!``#,``!%S```2D#4``/-
+M02)<S0&A_,`:``$$'*']?=G`!WQ"```(S``!!B0``08H``+.'0``SET``)C`
+M__K.G0``?$"``*````#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A
+M;<V!(6Z```$WR!P``\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````
+MS>4``,Y!(6G.@2%JS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8
+MI!_H*F@`/):```I\`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4WP"
+M0`!^`D``FD````ID``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D`
+M`,[``!Z```%CR#``!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%H
+MGX````````"```%X?QN`#H```7Q_&X`/@``!@'\;@`R```&$?QN`#8```8A_
+M&X`1@``!C'\;@!"```&1%*0`")N``!D4I``(@``!H1YD`/^;@``5%*0`"(``
+M`:$>9`#_FX``$12D``B```&A'F0`_YN```T4I``(@``!H1YD`/^;@``)%*0`
+M"(```:$>9`#_FX``!12D``B```&A'F0`_Q2D``@>9`#_*F@`/)J`_FT4[``(
+M?$-``'Q#@`!\0\``EL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/
+M]0``S```680`!,$J:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"C,`.
+M``+,``!!@``!K\S!,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``
+M!<`F``3`)__[?24`!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,
+MS0$A:LU!(6N6P/X\S8$A;(0`!,',``!_R#``&I<```#(,``:@````7Q`@`"$
+M``3!S```?\@4`!7(&``6S4$A:Y;`_B[-@2%L@``!QLP``'_,``/ER"P`(,`.
+M("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(#``)?$$`
+M`'Q!0`#,0`!#S$``1,`.@`!\0D``?$*``!:L`!^6P/X5P#7P`,Y``^$>>``#
+M$GP`"'_WP`9_^\`'%G@`&,_``^+/@`/C$K```G\_``#/``/D@``$47R`P`!\
+M0,``&-`!Z!$H``&5```0!J@!_YZ`````````@``"%\`2"`"```(ER!0`$8``
+M`BS(%``2@``",\S!HJ2```(\'.@`/X```F1\P8`+'-``/RDH``8I+``6?JZ`
+M!\@<`!.:@``]!!0`+H````#,P:*DP!((`'Q!0`!]#,`'P!(`"!58``,57``,
+M?$(``'W1P`82(``4?AY`!WY.@`?.@:*D@````,V!H?[(%``1!!`A&)5```#(
+M%``1U%$``(````#,P:*DR!0`$@00(0:50```R!0`$M11``"`````S,&BI,S!
+MHJ0$$``!S0``&80`!,',``!_R!``&YD```#($``;@````7Q`@``JH``$*J0`
+M%'XF``<$%``NE@``"`08`"F$``):R!P`$P04`"J$``3!!`P`+<U!HJ0$$"$`
+MR!P`$Y7```#('``3U%$``(``!+[,P:*DA``$P008`"F$``):R!P`$P04`"J$
+M``3!!!@`+80``EK('``3@````7Q`@`"5P```R!P`$\U!HJ3,`2$`S`$A`<V!
+M(0+-@2$#S8&BI(@```#,``!-'9@``7Q!``!\04``F8``"7Q"``#(/``R$9@`
+M$,@<``L[_``!E\#__\@\`#*```)VR#P`,Q&8`!#('``*._P``9?`___(/``S
+M%6@`'7U90`>:@``$$>0`"GXF``?-P`!FS0$A6,U!(5G.`2%:S,&BI)J``CX%
+M$``$!"P``1+P`!U]<4`'$N``$"(@``S-`2%8S4$A6<X!(5J```2^S,&BI`0\
+M``7/P:*DP#8``H@```#/02`0?$#``!30`!V9```(%-0`')5`_6O`)@`$(F0A
+M5,PE``"`````R"@`!(``!+[-0`!AA``$P1QT``$<>``"FT```\@,`"F$``--
+MR!0`*YN```,$$``0A``#9,S!HE#-`:!0A``"_@08!`"$``3!S```8\@\`"V$
+M``,,R!``*<@<`"\=W``!R"0`)Y7```G(-``QR#@`,,@\`"U3=``@?[>`)T>X
+M!5#,``!BS_H``)I```#()``GR"@`(SJH``*:@/__R"@`(\`P``'(*``DFH``
+M`,@H`"3/``!;4-@`"!3<`!@AW(``S8$A@,W!(8%1(``(%20`&,X!(8+.02&#
+MS4$AA'Q`@`"@````S(``380`!,$<=``!''@``IM```/(#``JA``#3<@4`"R;
+M@``#!!``$(0``V3,P:)@S0&@8(0``OX$&`F`A``$P<P``&3(/``NA``##,@0
+M`"K('``O'=P``<@D`"B5P``)R#0`,<@X`##(/``N4W0`('^W@"='N`54S```
+M8L_Z``":0```R"0`*,@H`"7(*``C.J@``IJ`___(*``CFH```,@H`"6```+&
+MP#```@68P``0W``(%.``&,W9``#('``BR"0`(AW<#__-V0`!?F)`!\Y9``+8
+M&%$#V!A1!(@```#8&%$'&_@`\,`V"`"7@``#P#``@(@```#`*@`$ST$A?,\!
+M(7W-`2%^(J@A?P0D``B:0```"F0``<PI``#((``$%C@`'YN`__L$)``(B```
+M``````#(#``DE,``)#C4``&90/_]R!``(WT-``&9`/_[R`P`)(```S'(#``E
+ME,``&SC4``&90/_]R!``(WT-``&9`/_[R`P`)80`!,',``!_R#P#^YO```#(
+M/`/[T$`#_,`^``32`2'X(_PA^80`!,',/0``R#@`!!NT`#X?L``$?P+`"Q[H
+M``1^MD`'FD#_]L`^``30``/\?$$``(````%\0(``A``#37Q`P`!\0(``H```
+M`,R``$W(/``.E\```],``^:(````!#P`)L_!HJ3(/`/F"_P``<_``^:;P/_[
+MS```300\``7/P:*DS`&A](0`!,',``!'B````,P``'^$``-D?$#``'Q`@`"@
+M````S(``300\`"+/P:*DA``$P<P``$B(````S```?X0``V]\0,``?$"``*``
+M``#,@`!-!#P`(\_!HJ3,`:'SA``$P<P``$F(````S```?X````!\0,``@```
+M`'Q`P`#`$@`!?%%`!X````#450``S$``9<@X`"W(/``NP#7@`,`R``1_MX`&
+M?_?`!B.X$``C_!``SX$A5,_!(57,,2%5R"P`!,@<`"7()``D?>7`!YG`__[(
+M'``E@````7Q`@`!\0,``?$$``!DH`#"6@``(R"@`)\@D`"B:0```R"0`)YI`
+M``#()``HS``#X'Q!0`!\08``%1P`'\S``,?-``#(E<```\`<@`#-P2`0X8,`
+M``5<(`#,``!-@````-P?00!\0,``?$$``'Q!0`!\08``S,``R<T``,KA@P``
+M!5R@`(````#<'T$`?$#``'Q!``!\04``?$&``,S``,O-``#,X8,```5<Z4"`
+M````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#-S0``SN&#```%7.B`@````-P?
+M00!\0,``?$$``'Q!0`!\08``S,``S\T``-#A@P``!5S``(````#<'T$`?$#`
+M`'Q!``!\04``?$&``,S``-'-``#2X8,```5<\`"`````W!]!`'Q`P`!\00``
+M?$%``'Q!@`#,P`#3S0``U.&#```%7//\@````-P?00#40R``?$"``*````#,
+M@`!-U$.@`'Q`@`"@````S(``3=1#Z4!\0(``H````,R``$W40^B`?$"``*``
+M``#,@`!-U$/``'Q`@`"@````S(``3=1#\`!\0(``H````,R``$W40_/\?$"`
+M`*````#,@`!-!!R@`,Q#H`!\0,``V!_!`'Q`@`"@````S(``300<P`#,0\``
+M?$#``-@?P0!\0(``H````,R``$U\0,``R!,``I3```/(%P`"R!L``@0<\_S,
+M`_/\V!_!`-@?P0!\0(``H````,R``$W`'@`0R`P`*5#0``@05``"@``$*'T5
+M@"#`'@`@R`P`*E#0``@(5`0`$50``GU1@"#-P`!BU%H``'Q`@`"@````S(``
+M37Q`P``<T``#$2@``94```H&J`0RGH```'Q!@`"```1`?$'``(``!$9\0<``
+M@``$3'Q!P`!\08``?$'``!34`!`%5*``@````,V5``#`(@`$!9B@`'VA@`?,
+M&0``@``$/,@8``3`(@`$S8$EUB(@)=?,(0``@``$/,@8``3-@2%MS<$A;H``
+M!#S(&``#?$#``,@0`^'(%`/DR!@#XL@<`^/-@2%IS<$A:LS!(6O,`2%L!"``
+M!'VA@`!]ED`,ED#[I,V``^(=*``#P"WP`!$8``A]K8`&?:F`!X````#-@`/B
+M?$#``(````#,3`/@'(S__]1-``!\0(``H````,R``$W(%``C,5@`!)6`___(
+M%``CS```6\Q!(8`@3(``S,$A@130`!_,02&"S$$A@Y4`^XC,02&$R!0`(YE`
+M___(%``C@````7Q`@`#`%@`$(50A0,Q5``#(&``$@````,P``^#`*@`$?$#`
+M`,S!(7S,02%]S$$A?GQ!@``4_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`
+MF<````G<``',(0``R"0`!!9L`!]!G``%FL#_^LR``$V;P/MF`````(````#,
+M``/@?$#``'Q!```5&``?410`()F```L9'``QS0``8GU-0"?45@``E<#[6<@@
+M`"::````R"``)H````%\0(``X#H``,`F``3,P2%I?24`!\T!(6H+N``"S$$A
+M:YN`__[,02%LF<#]$,P``'^````!?$"``,`.`0#,``!!S,$P2L@\`'_,``!_
+M@````,P``'_,``!_B````,P``'\`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01H`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=P`P`'D`,@#J`#0`C@`U`&(`.0#L`#H!%``[`2D`/`%!
+M`#T!L0`_`.D`001M`$($?P!#!(4`1`'6`$4!00!&`?H`1P'Z`$@!^@!*`I$`
+M2P-V`$P"G0!-`M0`3@,@`$\#*0!1`VH`4@-(`%,#7P!4`W@`5P-Z`&`#D@!A
+M`ZH`8@-^`&,#M`!D`[X`90/(`&8#T@!G`]P`:`/F`&D#Z@!J!!P`:P/N`&P#
+M\@!M`_8`;@/Z`&\#_@!P`_8`<00B`'($$`!S!`(`=`0)`'4$+0!Z!)X`?`10
+M`'T$90`/!+H`#P2Z``\$N@`/!+H`#P2Z``\$N@`/!+H`#P2Z``\$N@`/!+H`
+M#P2Z``\$N@`/!+H`#P2Z``\$N@`/!+H`#P2Z``\$N@`/!+H`#P2Z``\$N@`/
+.!+H`#P2Z``\$N@`/!+H`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_pfp.bin.uu
new file mode 100644
index 0000000..a341b14
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 REDWOOD_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```,WS$``*ID```4`````S$``*X```S?,0``LS$``+8``
+M`S?,0``N'(P``LR``$"8P``$S$``0(```S?,``!2@``#-\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$/-
+M0`!#R!P`'=$``$.9P``%S```5<@@`!_8``/`S```0,@H`!;8``;`&J@`)Y:`
+M``/,``!`T(``7,R``$#,``!`S$``0'Q`@`"@````!"@``<@0`"S(#``K41``
+M('S0P"=\Q0`@11@`",F>``#()`/]?>:`$9:```-^7L`!?`+`!L[#HIY5%``@
+MS```;,T``&W-0`!MS0``0\U``$/('``=T4``0YG```7,``!5R"``']@``\#,
+M``!`R"@`%M@`!L`:J``GEH```\R``$#0@`!<S(``0,P``$#,0`!`?$"``*``
+M```$*``!R!@`%1V8``%\0D``E8`"P'Q"@`#('``@P#?``'Q`P`!\00``?+2`
+M!L`V``,:N`'HEX``!]!``^"$``,ZS```?\@X`^";@```R#@#X)G```#('``@
+M?+2`!Q#4``)]94``S4``0\Z``$/-``!#S(``0,Y``$#.@`!`S,``0.`Z``"7
+M@/]NS0``0'Q`P`"```"(?$$``!R,``+($``<F,``"<@@`!^9```$R!P`!H0`
+M`SW,``!2R!@`%8```'0=F``"R!``'ID`__S('``(A``#/<P``%3(&``5@```
+M=!V8``(<C``"R!``'9C```_(%`!)F0``!<@@`!_('``'A``#/<P``%/(&``5
+ME,```QB4`>@%5``&(!```7T5``.```!T?9&`!IE`__C((``?A``#/<@<``>`
+M``"SS```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/TS0`#]LT`
+M`_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``<@@`!^```#8V``$
+M0,@@`!_8``-`S```0,R``$#40`!`?$"``*`````$*``!R"``']@``\"```#H
+MS```0,@@`!^```#GV``$0,@@`!_8``-`S```0,@,`"G($``JS(``0,Q``$!1
+M$``@?-#`)Q!0``)]#0`@510`(,T``$/-0`!#T$``0\P``$!\0(``H`````0H
+M``'((``?V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=F,``
+M$L@4`$F9```%R"``'\@<``>$``,]S```4\@,`"_,@`!`S$``0,Q``$#,0`!`
+M?,3``,S``$#40`!`?$"``*`````$*``!F4#_]<@@`!^$``,]R!P`!X```0G,
+M``!N?$#``,@0`$>9```+R!0`1)E```3(&``)S8``0,P``$"```$SS(``0'Q`
+MP`#($`!'E0#_]\@4`$690``$R!@`"LV``$#,``!`@``!,]@`"$!\0,``R!``
+M1YD`__P`````S(``0,S``$#40`!`?$"``*`````$*``!R!``1M@`!T#-``!`
+MA``!2LT``$#(#`!#E,``"L@4`$B```%#!!```\@0`$;8``?`S0``0(0``4K-
+M``!`R!0`2)U```#,``!JR"@`%AZH``&:@``#P"D``8@```#`+`%6SH``7-@`
+M",#.P`!`B````,P``$`<C``"R!``'L@@`!^4P``(R!0`')D```K('``(A``#
+M/<P``%2```%ES(``0)E```3('``&A``#/<P``%+,@`!`@````-1``$#,0``G
+MS$``*(```S?,``!KP#(``\`W__^```%P?+"`!WQ#0`#((``HR!P`)\@8`";/
+M0Z*>?$%``%(@`"!]X<`G?5C``WS<P"!4T``@@``!A<R``$!\08``S(``0(``
+M`8+-@`!`P!G__\R``$#-@Z*>?$#``'Q!``!\04``S,.A^LT#H?G-0Z*=S,``
+M0,T``$#-0`!`S$``0'Q`@`"@````!"@``7Q`P``<T``!S,.BGY4```/00``F
+MT(``)LR``$"`````S,``0'Q`P`#,@`!`S,.BHH````#,P`!`?$#``!34`!_,
+M@`!`E4```WQ!``#,P`!9%1@`'\S``$"5@``#S0``0,T``%J```,WS```?\@@
+M`!]\00``V"`"1,X@`$1\04``?$&``,V@`$G-(`!!S6``0<V@`$$5$``($50`
+M&'U3P`?/P``O!B```<X``%B```,WS```?\@@`!_*#``7E,``!7Q!``#8(`+&
+M@``!K\X@`$;,``!(@``!Q0````#((``??$&```H@``'*%``:RA@`%WU9@`>5
+M@``%S@``6,R@`$:`````S6``1LR@`$2`````S6``1(```S?,0`!JS(``0(``
+M``#40`!`?$#``'Q!``!\0X``?$/```0<``+/@`!"S\``0LW``$($'``@S,``
+M0LT``$+-P`!"!!P`!P0@``%\`D``R!0``\@8``-1F``@?5E`)\@H``/(+``#
+MR#```\@T``-2[``@?JZ`)U-T`"!_-P`G?RM`(7YV0"!6J``_5S``/WZR@`9^
+M*@`&F<#_\@G<``&6@/_A4_0`('][0"=]94`@55@`(,P``%O-=@``S;8``,@@
+M`$&:````R"``08````%\0(``?$#``'Q!``#,P`/^S0`#_\S``$+-``!"%10`
+M'QD8`/`G7``!?78`!IF```5]7D`&S```0H```S?,``!-%9@``14L``B9@``Q
+M'NP``98```05,``,@``#-\P``$($%``@S4``0A\P``$@*``!!#@`(`0\``?(
+M%``#R!@``\@<``/((``#?5U`#7VAP`U]74`'%A``'Q6<`!]]'0`&?1=`!GZ2
+M@`:;0``2"[@`!)O`__(+_``!R`P#_IJ```G($`/_FP``_<P``$T$%``@S,``
+M0LT``$*```(DS4``0I;``/;,``!-@``#-\P``$Z:P``#S```3<P``$Z7@/VX
+MXX,``(````#<`P'_ED``!,P``$Z```,WS```0M(``$+("``#R`P``\@0``/(
+M%``#R!@``\@<``/()``#R"@``Q7\`!\6L``??_/`!A3P`!]_\\`&%7``'W_S
+MP`9]B(`!E\``#7W,P`%^40`!?I5``7R0@`Q\U,`,FL```WR/0`8DM``!FT``
+MS<P``$V```,WS```3L@,`_[($`/_S,``0H```E#-``!"?$#``'Q!```9%``[
+MS```6Y5``!/(%`!`,5@``I6`___(%`!`S```8R$<@`#,P2&%S<$AAA44`!_,
+M02&'S$$AB)5`_7W,02&)R!0`0)E`___(%`!`@````7Q`@`#,@`!`S,``0,T`
+M`$"`````U$``0-"``^#,@`!`A``#.LQ``$#(#`/@F,```,@,`^!\0(``H```
+M`'Z"@`9\0,``A``"HA30`!^9`/UDT$`#X(0``SK,``!_@``"E,@,`^#,@`!`
+MS,``0(@```#40`!`S(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`
+M-___T``#^]```_R`````ST`#_7Q`P``4W``=F<``!\R``$`8W``\F<``?\S`
+M`$"```,WS```:AC8`#S-@`!FS```:H```S?,P`!`?$#``%!0`""$``,ZS```
+M77S0P"?((``?R-8``)E```A\0X``XX,``,^@`$^$``,ZS```7H````#40`!_
+M@``#-\P``%Z$``,ZS```7<@@`!]\0,``P#;_`,@0`"'`,#__?/5`!GU1@`9]
+M@8`*F8``"'SS@`;C@P``SZ``3X0``SK,``!>@````-1``'^```,WS```7H0`
+M`SI\0,``%-P`")7``!D<W``0?$$``)G```105``@@``"\LD=``!]%0`GR1X`
+M`'Q"``!\0D``?$&``'WEP`9]XH`1FH#]"4&L``6:P```"NP``1S<`!"9P``$
+M`````(```O7)'0``@``"]<D>``#,@`!`S,``0(````#40`!`R"``']@``T#,
+M``!`S(``0-1``$!\0(``H`````0H``'((``?V``#P,P``$#,@`!`U$``0'Q`
+M@`"@````!"@``7Q`P``<T``&*1``!ID```?(%``<F4``!<P``%+('``&A``#
+M/<@@`!_,@`!`S,``0(````#40`!`?$#``'Q!```5&``?S0``6YF```11%``@
+M@````-1-``!]34`G&1P`,=16``"5P/S1R"``09H```#((`!!@````7Q`@`"`
+M````U$``?\P``'^`````S```?\P``'^(````S```?\W``$"(````S```0```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,&``0##@`%`:L`!@#6``<`Y0`(`/@`"0#>``H`TP`+`.(`#`$:
+M``T!)``.`3@`#P%"`!`#-0`1``H`$@`8`!,`(``6`"(`)``Q`"4`3``F`6<`
+M%P''`!@!U0`B`L$`(P+2`"<!?``?`=H`(`(*`"@!G@`I`6L`*@&0`"L!@``O
+M`9D`,@&]`#0#%@`U`6\`.0'7`#P"Y@`^`S4`/P&K`$$"<P!"`H\`0P*9`$0"
+MI@!*`K,`50,)`%8#$0!@`'(`80"7`&(`P0!C`*H`9`"J`&4`J@!F`*H`9P"J
+M`&@`S@!I`-D`:@$N`&L`^P!L`/L`;0#[`&X`^P!O`/L`<`$``',`Z`!T`.@`
+M=0%5`'L#)`````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_rlc.bin.uu
new file mode 100644
index 0000000..7fed7cf
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/REDWOOD_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 REDWOOD_rlc.bin
+M(#@`$".X``#/@``2S```A008``'-@``.S8``@\P``(+-@`"!S```"X```/P`
+M````P#`@`\^Q``"(````RSD``,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`
+M````````A```?`````"```#%`````,GX`(.;@``$`````(```,4`````S!P`
+M@X0``-@1N``?@```Q0````#(*``#EH``M`````#-@``.*HP!Y9C``"0@"``!
+MS(```X```!@`````(#@``<^```/($`""S```@<@(`!J4@``R`````,V```X`
+M````A```T2`X``+,,0``A```#"`X``'-@`"!A```\R`,``"```#%`````"J(
+M`;R8@/_8`````)4`_](`````R"@``I:``.$@"``!S8``#LR```*````8````
+M`,G,`(.4P`"3`````(0``/,@#``!A```#"`X``"7@`"-(`P`#<`P(`G,\0``
+MP#`@"L`T&!@3=``((W08&,L-``!\],`&R`@`&IB``((@'``!E,#_^P````"`
+M```P?<'`!L@X`%:;@``S(!P``,@X`%>;@``P(!P``2`<``#("`"!E(#_V0``
+M``#(*```EH#_UB`(``'-@``.S(```!P<```JB`&[E(#_RP````"```#3````
+M`!ZH`/_.@``,B`````````#(,`!`(S``0,\``$"$``"F(#@``<@P`$`?,`._
+MSP``0(```&?,``!6A```$`````#`,"`(A```N2`X___`,"`(S#$``,LY``#`
+M,`.8A```N2`X`0#`,`.8S#$``,L)``#`,"&VB````,PQ``"9P/_ER#``0",P
+M``+/``!`A```BB`X``/(,`!`'S`#_<\``$"```!GS```5H0``!``````(#@`
+M`<`P`YB$``"Y$[@`%,P``%?`,`.8S#$``(@```#+"0``S[$``,V```[+.0``
+M%[@`!)>`__X`````B`````````#/L0``RSD``"`(`!^8@```"(@``<P<`!;)
+M\``;EP#__P````"(`````````,P```[,```.R!``@B`H`<,@'```R!``@L@(
+M`(5_BX`'R`@`@92`_V<`````@```9P````"```"QP#`!P<V<`(.$``#8(#@`
+M`)4`__$`````P#`!P(@```#/L0``R"@`!):`_^D`````(`@``<V```[,@``$
+M@```&`````"$``#8$;@`'X0```P@.``!A```\R`,``#`,`'`RSD``"`X``"5
+MP/_9SX```WW!P`:$``#8(#@``(```,7/@``#P#`#D,LY``#`"__^?XN`!A#,
+M`!!_CX`'S[$``(@```#+.0``R`D]-L@-/3>4P/\[`````,@1/3C(%3TYR!T]
+M.L@A/3O()3TU!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8
+MR)8`/)5`_RK(T@`H?24``0E4``$$S``HF0#_^P````#(D@`X!1``0'T*P`#(
+MU@`$P!P`!,CB`!3(Y@`DS@H!3,YN`4P(S``$"(@`!`KL``0)W``!F<#_^```
+M``#-"@%@S`H!9,U!/4>````Y`````,@H``&6@/[[`````"`(``'-@``.S(``
+M`8```!@`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RS600_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RS600_cp.bin.uu
new file mode 100644
index 0000000..a4f620a
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RS600_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 RS600_cp.bin
+M`````$(`X```````0`#@``````@```"@````"````*0`````2E5+2@````!*
+M2D1G`````%52;W4`````2GY]90````!*YTKV`````$K32DH`````UHF)B0``
+M``#-2MW/`````(Z^2N(`````PXJ*B@````!*#XS(````!``,H``````X``T`
+M$@````0``.BT````.``-`!0````$``#HM@```#@`#0`6````!```Z%0````X
+M``T`&`````0``.A5````.``-`!H````$``#H5@```#@`#0`<````!```Z%<`
+M```X``T`'@````0``.@D````.``-`"`````$``#H)0```#@`#0`B````!```
+MZ#`````X``T`)`````0``/#`````.``-`"8````$``#PP0```#@`#0`H````
+M!```\$$````X``T`*@````0``/&$````.``-`"P````$``#QA0```#@`#0`N
+M````!```\88````X``T`,`````0``/&'````.``-`#(````$``#Q@````#@`
+M#0`T````!```\Y,````X``T`-@````0``/.*````.``-`#@````$``#SC@``
+M``0``.@A````!`%`H``````8````0P````0`S.@`````!``;``$````$"`!(
+M``````0`&P`!````!`@`2``````$`!L``0````0(`$@`````"````#H`````
+M``"@``````0@`$4=````!```Y8`````$``SE@0````0(`$6`````!``,Y8$`
+M```(````1P```````*``````!``,(``````$``#E#@````0``R``````*``"
+M(%$````D````40````0(`$4/````"```H$L````$``#E90````0``.5F````
+M"````%(````$`\REM`````0%0R``````!``"(``````P3,S@7@````0()T5E
+M````,````%X````$"`!%9`````0``.5F````"````%4````0`(`@80````0`
+M("``````!``;`/\````0`0``9`````0`'R``````!``<`/\````,````````
+M`#````!R````"````%4````$``#E=@````0``.5W````!```Y0X````$``#E
+M#P````0!0*``````&````&D```#"`,#E^0````@```!I````!``4Y0X````$
+M`$#E#P````@`P`!L````!```Y7`````$``#E<0````P``.5R````!```H```
+M```$`4"@``````0``.5H````!``,(``````8````=@````0`"P``````!!C`
+MY6(````(````>`````@`P`!W````!``'`-4````X````A````#``#*"&````
+M!`@`1;L````P``P@AP`````(`.6\````!```Y;L```````#EO`````P`$@``
+M````!``2```````,`!L``@````0``*``````!```Z"$```````#H``````0`
+M`.@A````````Z"X````$`LR@``````0`%```````!``,X<P````$!0WAS0``
+M``0`0```````&````)8````$`,"@``````@```"3````(````)@`````0@#@
+M`````#@```"?````!``,H``````$`!0```````0`#"``````!``6```````$
+M<`S@``````@`%`";`````$``X``````$`D````````1`#N``````!`)`````
+M````0`#@``````0`#"``````!`)`Y1L````%`(#E"@````4`@.4+````!``B
+M```````$``<`U0```#@```"R````,``,((<````%"(#EO0```#``#""&````
+M!0@`Y;L````P``P@AP````4(@.6\````"````+4````%`(#EO0````4``.6[
+M````!0"`Y;P````$`"$```````0"@```````&`#``+D```!`08#@`````"0`
+M``"[````#`$````````,`0#E'0````0``$6[````"```@+4````$``#SS@``
+M``0!0*``````!`#,(`````!`",!3SP```````(``````!```\](````$`4"@
+M``````0`S"``````0`C`4],```````"```````0``/.=````!`%`H``````$
+M`,P@`````$`(P%.>````````@``````$`\`(,`````!"`.``````!```H```
+M```$(`!%X````````.7A``````````$````$``<`T@`````(`..4````````
+M```````$``#HQ`````0``.C%````!```Z,8````$``#I*`````0``.DI````
+M!```Z2H````(````U@````0``.DH````!```Z2D````$``#I*@````@```#=
+M``````#@`18````$``<`X0````0(`$`<````!"``4.<````$``#@'0````@`
+M``#D````!`+`(``````$``8``````#0```#K````"````.@````$``"`````
+M``#``.``````````````````````````````````````````````````````
+M````````````````````````````````````````````````!``,(``````$
+M`!T`&`````0`&@`!````-````/L````(````2@````@%`*!*````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RS690_cp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RS690_cp.bin.uu
new file mode 100644
index 0000000..8ac379b
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RS690_cp.bin.uu
@@ -0,0 +1,49 @@
+begin 644 RS690_cp.bin
+M````"````-T````(````WP````@```"@````"````*0`````2E5+2@````!*
+M2D1G`````%52;W4`````2GY]90````!*UTKV`````$K)2DH`````S(F)B0``
+M``##2M/%`````(Y*2DH`````2HJ*B@````!*#XQ*````!``,H``````X``T`
+M$@````0``.BT````.``-`!0````$``#HM@```#@`#0`6````!```Z%0````X
+M``T`&`````0``.A5````.``-`!H````$``#H5@```#@`#0`<````!```Z%<`
+M```X``T`'@````0``.@D````.``-`"`````$``#H)0```#@`#0`B````!```
+MZ#`````X``T`)`````0``/#`````.``-`"8````$``#PP0```#@`#0`H````
+M!```\$$````X``T`*@````0``/&$````.``-`"P````$``#QA0```#@`#0`N
+M````!```\88````X``T`,`````0``/&'````.``-`#(````$``#Q@````#@`
+M#0`T````!```\Y,````X``T`-@````0``/.*````.``-`#@````$``#SC@``
+M``0``.@A````!`%`H``````8````0P````0`S.@`````!``;``$````$"`!(
+M``````0`&P`!````!`@`2``````$`!L``0````0(`$@`````"````#H`````
+M``"@``````0@`$4=````!```Y8`````$``SE@0````0(`$6`````!``,Y8$`
+M```(````1P```````*``````!``,(``````$``#E#@````0``R``````*``"
+M(%$````D````40````0(`$4/````"```H$L````$``#E90````0``.5F````
+M"````%(````$`\REM`````0%0R``````!``"(``````P3,S@7@````0()T5E
+M````,````%X````$"`!%9`````0``.5F````"````%4````0`(`@80````0`
+M("``````!``;`/\````0`0``9`````0`'R``````!``<`/\````,````````
+M`#````!R````"````%4````$``#E=@````0``.5W````!```Y0X````$``#E
+M#P````0!0*``````&````&D```#"`,#E^0````@```!I````!``4Y0X````$
+M`$#E#P````@`P`!L````!```Y7`````$``#E<0````P``.5R````!```H```
+M```$`4"@``````0``.5H````!``,(``````8````=@````0`"P``````!!C`
+MY6(````(````>`````@`P`!W````!``'`,L````X````A````#``#*"&````
+M!`@`1;L````P``P@AP`````(`.6\````!```Y;L```````#EO`````P`$@``
+M````!``2```````,`!L``@````0``*``````!```Z"$```````#H``````0`
+M`.@A````````Z"X````$`LR@``````0`%```````!``,X<P````$!0WAS0``
+M``0`0```````&````)8````$`,"@``````@```"3````(````)@`````0@#@
+M`````#@```"?````!``,H``````$`!0```````0`#"``````!``6```````$
+M<`S@``````@`%`";`````$``X``````$`D````````1`#N``````!`)`````
+M````0`#@`````"P`$```````````0``````$"`!%R`````0`)``%````!`@`
+M30L````$``P@``````0"0.4;````!0"`Y0H````%`(#E"P````0`(@``````
+M!``'`,L````X````MP```#``#""'````!0B`Y;T````P``P@A@````4(`.6[
+M````,``,((<````%"(#EO`````@```"Z````!0"`Y;T````%``#ENP````4`
+M@.6\````!``A```````$`H```````!@`P`"^````0$&`X``````D````P```
+M``P!````````#`$`Y1T````$``!%NP````@``("Z````!`/`"#``````0@#@
+M``````0``*``````!"``1>````````#EX0`````````!````!``'`,@`````
+M"`#CE```````````````!```Z,0````$``#HQ0````0``.C&````!```Z2@`
+M```$``#I*0````0``.DJ````"````,P````$``#I*`````0``.DI````!```
+MZ2H````(````TP````0"P"``````!``&```````T````VP````@```#8````
+M!```@```````P`#@`````#````#A`````$(`X``````P````X0````!``.``
+M````!``E`!L````$`",```````0`)0`%````-````.8````,``````````0`
+M)$``````!`@`1<@````$`"0`!0````P(`$T+````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````!``,(``````$
+M`!T`&`````0`&@`!````-````/L````(````2@````@%`*!*````````````
+7````````````````````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RS780_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RS780_me.bin.uu
new file mode 100644
index 0000000..0a6b8c1
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RS780_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RS780_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```8B``````!@``````71
+M``````!@``````7>`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````7_``````!@``````7S`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````7Y``````!```````#K``````!@``````7\````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```8B````
+M'P`A`C```````````!3```````8A````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``8B````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````8A```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````7>``````!`!`\```(3``````!@``````71``````!@``````7>```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````71``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```8B
+M``````!@``````71`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````7_``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````7V````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP```,`@1!$``````````,`@2!$`````B@```,`@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2````````````,`@!```
+M``````````"@``H`````EP`````@1!$````````````@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2`````````&A_0`@1!$``````````-D`2```````
+M`````,`@!`````````````"@``H````````B5P`@1!$``````````\!(2B``
+M```````B70`@1!$``````````,!`2`````````````!@``````7>`````,`@
+M"``````````B7``@1!$``````````P`X2B(```````"A_``@1!$`````````
+M`,`@2`````````&A_0`@1!$````````````O`B(```````````S@````````
+M`````$`@2````````````4`P2B```````````L`P2B```````````0!3"B(`
+M``-5````/\`H"B``````@0`````@1!$``````````0`@2!$````````A^``@
+M1!$`````````&``@2!$```````0A^0!@1!$```8B````$0`A`C``````````
+M`!3@``````->````%``O`B(```````````S```````-L``&BI``@1!$`````
+M``````!@2`(```-T```A```@1!$``````````,`@2````````````,`@2```
+M`````````,`@2````````````,!`2```````````!``O`B(```````````S`
+M``````-P``&BI``@1!$```````````!`2`(```-G````*``O`B(`````````
+M``S```````6Z``&BI``@1!$```````````!`2`(```-G````+``@-B8`````
+M````20`@&!$`````````/P`@2!$``````````0`S&B8````````````O`B8`
+M``````````S```````-V````+`"`&BT`````````/\`H"B``````````%0`O
+M`B(```````````S@``````.,````!@`O`B(```````````S@``````.W````
+M%@`O`B(```````````S@``````.Y````(``O`B(```````````S@``````.B
+M````#P`O`B(```````````S@``````.N````$``O`B(```````````S@````
+M``.N````'@`O`B(```````````S@``````.6``"BI``@1!$```````````!`
+M2`(`````"``````I"B(``````````T`A#B``````````#,`A$B````````@`
+M```H$B0`````````%,`B%B`````````````I%*0```````"BI``@1!$`````
+M```````I2*(```````"A_@`@1!$```````````!`2`,`````@0`````@1!$`
+M`````````0`@2!$````````A^``@1!$`````````%@`@2!$```````0A^0!@
+M1!$```8B````%0`A`C```````````!3@``````.8```A#@`@1!$`````````
+M`,`@2````````````,`@2`````````"BI``@1!$```````````!`2`(`````
+M@0`````@1!$``````````0`@2!$````````A^``@1!$`````````%P`@2!$`
+M``````0A^0!@1!$```8B`````P`A`C```````````!3@``````.D```A"``@
+M1!$``````````,`@2````````````,`@2`````````"BI``@1!$`````````
+M``!`2`(```````"BI``@1!$````````````@2`(`````@``````@1!$`````
+M```````@2!$`````@0`````@1!$`````````$``@2!$````````````@`!``
+M`````````!3```````.T``````!```````````&BI``@1!$`````````!@!`
+M2!$```````&BI``@1!$`````````%@!@2!$```-T``````!`````````````
+M`,`@"````````````,`@#```````````'0`A`B,``````````!3@``````/.
+M@0`````@1!$``````````0`@2!$````````A^``@1!$`````````&``@2!$`
+M``````0A^0!@1!$```8B````$0`A`C```````````!3@``````/"```A```@
+M1!$````````````@2`(````````````@2`,`````NK[*_@`@2!$`````ROZZ
+MO@`@2!$```````"BI``@1!$`````````!`!`2!$````````A<``@1!$`````
+M```````@2`(````````````@2`,`````@0`````@1!$`````````"@`@2!$`
+M```````````@`!```````````!3```````/3C``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$``````````0`@2!$````````__T`H"B``````@```
+M`$`H#B``````0````,`H$B````````0```!I1B(```8B```````@%!``````
+M```````O`B,```````````S```````/A`````,!`&`````/D```__\`H&B``
+M``````0```!I1B8```8B```````@&!`````````````O`B0```````````S`
+M``````/G`````,!`'`````/J```__\`H'B````````0```!I1B<```8B````
+M```@'!`````````````@1`(````````````H(,4```````````!)2.@`````
+MI8`````@"!$````````@```@#!$`````@P````!@1!$```02```````@1`(`
+M`````````,`@2````````````$`@2```````````'\`A`B```````````!3`
+M``````/W```@$``@1!$```````"````@2!$```````#__\!($B````/_IX``
+M```@"!$```````"@```@#!$`````@P````!@1!$```02```````@1`(`````
+M`````,`@2````````````,`@2`````````#__\`H$B``````@P`````@1!$`
+M```````````P2(,`````A``````@1!$``````````,`@2````````````!T`
+M````````@P````!@1!$```02`````,!`!``````!J8`````@"!$```````#`
+M``!`#!$```/ZJX`````@"!$```````#XX`!`#!$```/ZK8`````@"!$`````
+M``#X@`!`#!$```/ZLX`````@"!$```````#S_`!`#!$```/ZKX`````@"!$`
+M``````#@``!`#!$```/ZL8`````@"!$```````#P``!`#!$```/Z@P`````@
+M1!$````````A2``@2!$`````A``````@1!$``````````,`@2```````````
+M`!T```````````````"``````````1@@`,`P1B```````````-D`2```````
+M`````,`@!`````````````"@``H``````AB@`,`P1B```````````-D`2```
+M`````````,`@!`````````````"@``H``````QC``,`P1B```````````-D`
+M2````````````,`@!`````````````"@``H`````!!CXX,`P1B``````````
+M`-D`2````````````,`@!`````````````"@``H`````!1CX@,`P1B``````
+M`````-D`2````````````,`@!`````````````"@``H`````!AC@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H`````!QCP`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H`````"!CS
+M_,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M````,\`P"B```````````,!`-$``````````,``@"BT``````````,`I#$``
+M````````,``@-B,``````````,`@!`````````````"@``H`````A@`````@
+M1!$```````````!`2`$`````A0```,`@1!$```````````!`2`$````````A
+M?``@1!$`````````&$`A`B```````````!3```````1'`(```,!)2B````1(
+M`````,`@2````````````,`@2````````````,`@2```````@0`````@1!$`
+M`````````0`@2!$``````````,`@"```````````!``O`B(```````````;@
+M``````10````!``@"!$``````````!<```````````0A?P!@1!$```8B````
+M'P`A`C```````````!3```````````````!`3`(```10`````,`@#```````
+M`````,`@$````````````,`@%````````````,`@&````````````,`@'```
+M``````!_```H"B$```````!%```O`B(```````````S@``````1A`````,`@
+M(```````````!``O`B@```````````;@``````1A````!``@(!$`````````
+M`!<`````````````$``H"B,`````````$``O`B(```````````S@``````1I
+M@0`````@1!$``````````0`@2!$```````0```!I1B0```8B``````!`````
+M``1N@0`````@1!$````````````@2!$````````A;0`@1!$````````````@
+M2`0```````````!@2`4```8G```````H)/``````````!P`H"B,`````````
+M`0`O`B(```````````K@``````1U```````O`,D```````````3@``````2.
+M``````!```````2;`````@`O`B(```````````K@``````1Z```````O`,D`
+M``````````+@``````2.``````!```````2;`````P`O`B(```````````K@
+M``````1_```````O`,D```````````S@``````2.``````!```````2;````
+M!``O`B(```````````K@``````2$```````O`,D```````````K@``````2.
+M``````!```````2;````!0`O`B(```````````K@``````2)```````O`,D`
+M``````````;@``````2.``````!```````2;````!@`O`B(```````````K@
+M``````2.```````O`,D```````````C@``````2.``````!```````2;``!_
+M```H"B$```````!%```O`B(```````````K@````````````"``A"B,`````
+M`````!3```````28```A:0`@1!$``````````,`@2````````````,`@2```
+M`````````,`@2```````ROZZO@!`2!$``````````,`@1````````````,`@
+M`````````````,!`2`````````!_```H"B$```````!%```O`B(`````````
+M``K@``````2A`````,`@`````````````,`@`````````````,!`````````
+M``````!`3`@```1A`````,`@"```````````$$`A#B``````````$4`A$B``
+M````````$D`A%B`````````A:0`@1!$````````````@2`(````````````A
+M`B4``````````!3@``````2K``0``,!)2B````2L__O__\`H2B``````````
+M```A`B,``````````!3@``````2X`````,`@2````````````,`@2```````
+M```````A`B0``````````!3`````````@0`````@1!$`````````#``@2!$`
+M```````````@`!```````````!3```````2TH``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$`````````!``@2!$````````A:P`@1!$`````````
+M`,`@2!``````@0`````@1!$`````````!0`@2!$````````A;``@1!$`````
+M`````,`@2!`````````````O`B0```````````S@``````````````!`````
+M``2R`````,`A"B```````````!3```````3+@0`````@1!$````````````@
+M2!$````````A;0`@1!$``````````,`@2````````````,!@2`````8G````
+M``!```````3/@0`````@1!$``````````0`@2!$```````0``,`I1B``````
+M`````,!@``````8B`````0`A`B(``````````!3```````36```A:0`@1!$`
+M`````````,`@2````````````,`@2``````````````@2!``````ROZZO@!`
+M2!$``````````,`@1````````````,!`2!``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````#@`@2!$```````0A^0!@1!$```8B
+M```````A`C```````````!3```````38```A@``@1!$``````````,`@2```
+M`````````,`@`````````````,`@2````````````,`@`````````````,!`
+M2````````````P`S/B\``````````0`A`B$``````````!3@``````4(````
+M+``@"BT```````0``!C@#!$```3W`````0`S/B\````````A:0`@1!$`````
+M```````@2`(````````````@2`,`````````"``P"B(``````````,`@2```
+M`````````,`@2``````````A:0`@1!$````````````@2`(````````````@
+M2`,`````````"``P"B(``````````,`@2````````````-C`2`````3K```A
+M:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`````
+M`````,`@2````````````,`@2```````````+0`@$BT````````````I#(,`
+M```````A:0`@1!$````````````@2`(````````````@2`,`````````"``P
+M"B(``````````,`@2````````````,`@2```````````$0`A`B0`````````
+M`!3```````````````!```````2R````+,`@-B``````````+<!`-B``````
+M````#P`A`B$``````````!3```````4-``````!@```````+`````-D`````
+M`````````,!`!``````!M0`````@1!$````````@```@2!$`````M@`````@
+M1!$```````"@```@2!$`````MP`````@1!$```````#````@2!$`````N```
+M```@1!$```````#XX``@2!$`````N0`````@1!$```````#X@``@2!$`````
+MN@`````@1!$```````#@```@2!$`````NP`````@1!$```````#P```@2!$`
+M````O``````@1!$```````#S_``@2!$`````@0`````@1!$``````````@`@
+M2!$`````````_P`H#C`````````````O`B,```````````S```````4A````
+M`,`@"````````````!3```````4V```````@#!$`````````'``@-B,`````
+M````*P`@-B,`````````*0`@-B,`````````*``@-B,`````````%P`@-B,`
+M````````)0`@-B,`````````)@`@-B,`````````%0`@-B,`````````%@`@
+M-B,`````___@```@#!$`````````(0`@-B,`````````(@`@-B,````````?
+M_P`@#!$`````````(P`@-B,`````````)``@-B,`````\?___P`H.BX`````
+M````&L`B#B`````````````I.&X`````@0`````@1!$`````````!@`@2!$`
+M````````*D`@-B``````AP`````@1!$``````````,`@2`````````"A]``@
+M1!$````````````@2!``````G0`````@1!$`````````'T`A2B``````E@``
+M```@1!$``````````,`@2````````````,`@#````````````,`@$```````
+M````'P`A%B0``````````!3`````````````'0`@-B,``````````P`H'B,`
+M````````"``B(B,`````___P```H(B@````````````I(.@`````````'P`@
+M-B@`````````&``A'B,`````````(``@-B<``````````@`B%B0`````````
+M```P%*@`````````'@`@-B4``````````P`A&B0`````$``````H&B8`````
+M[____P`H.BX```````````!).,X```80`````4`H"B``````````!D`H#B``
+M```````#`,`H$B``````````"``A$B0``````````,`@%B```````````,`@
+M&B`````````````A`B(``````````!3```````5L@0`````@1!$`````````
+M`0`@2!$````````B6``P"B0```````0```!I1B(```8B```A:0`@1!$`````
+M```````@2`4```````(````I2B8````````````@2!``````ROZZO@`@2!$`
+M`````````@`O`B,```````````S```````5T`````,`@'!```````````,!`
+M``````6"`````@`O`B,```````````S```````5T@0`````@1!$`````````
+M`0`@2!$````````B6``P"B0```````0```!I1B(```8B`````,`@'!``````
+M`````,!```````6"```````O`B,```````````S```````5X`````,`@'```
+M`````````,!```````6"````!``O`B,```````````S```````6`@0`````@
+M1!$````````````@2!$````````A;0`@1!$``````````,`@2```````````
+M`,!@2`````8G``````!`'!````6"`````,`@`````````````,!`````````
+M``````[@``````6$``````!@``````7#```````O`B0```````````S`````
+M``62``"BMP`@1!$````````````@2`<`````````,P`@)BT`````````&@`A
+M(BD`````````!@`B)BD```````"BQ``@1!$````````````P2.D`````````
+M``#@``````60``"BT0`@1!$```````````!`2`@```````"BT0`@1!$`````
+M`````0!02B@``````````0`O`B0```````````S```````6@``"BNP`@1!$`
+M```````````@2`<`````````-``@)BT`````````&@`A(BD`````````!@`B
+M)BD```````"BQ0`@1!$````````````P2.D```````````#@``````6>``"B
+MT@`@1!$```````````!`2`@```````"BT@`@1!$``````````0!02B@`````
+M`````@`O`B0```````````S```````6N``"BOP`@1!$````````````@2`<`
+M````````-0`@)BT`````````&@`A(BD`````````!@`B)BD```````"BQ@`@
+M1!$````````````P2.D```````````#@``````6L``"BTP`@1!$`````````
+M``!`2`@```````"BTP`@1!$``````````0!02B@```````"BPP`@1!$`````
+M```````@2`<`````````-@`@)BT`````````&@`A(BD`````````!@`B)BD`
+M``````"BQP`@1!$````````````P2.D```````````#@``````6X``"BU``@
+M1!$```````````!`2`@```````"BU``@1!$``````````0!02B@`````A0``
+M```@1!$````````````@2`$````````P2@`@1!$``````0`````@2!$`````
+M``````!```````6^I````,`@1!$``````````,!`2````````````,!@````
+M``7#`````,!`!``````!``&BI``@1!$`````````/P`@2!$`````````/P`@
+M2!$`````````/P`@2!$`````````/P`@2!$`````````!0`@2!$```````"A
+M]``@1!$````````````@2!$`````B``````@1!$``````````0`@2!$`````
+M_P`````@1!$````````````@2!$``````````0`@2!$``````````@"`2!$`
+M``````````[@``````76```0```@"!$`````````*P`@-B(```````````!@
+M``````7:``````!@``````7#F``````@1!$```````````"`2!$`````````
+M`,!@``````7:`````,!`!``````!``"BI``@1!$`````````(@`@2!$`````
+MB0`````@1!$``````````0!`2!$```7-EP`````@1!$````````````@2!$`
+M````B@`````@1!$```````````!`2!$```7-``````!@``````7S``&BI,`@
+M1!$`````````%@!@2!$```-T```@$``@1!$```````$````@2!$`````@0``
+M```@1!$``````````0`@2!$````````A?``@1!$`````"8`````@2!$`````
+M_____P`@2!$````````````@2!$``````````!<```````````0A?P!@1!$`
+M``8B````'P`A`C```````````!3`````````````!`!`3!$```7M``````!`
+M````````````%P`@'BT`````````!``I'B<`````````%P"`-B<`````````
+M%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````%P`@'BT`````
+M````"``I'B<`````````%P"`-B<`````````%P`@'BT`````____]P`H'B<`
+M````````%P"`-B<```````&BI``@1!$`````````%@!@2!$```-T```@$``@
+M1!$```````$````@2!$````````A?``@1!$``````8`````@2!$`````____
+M_P`@2!$````````````@2!$``````````!<`````````@0`````@1!$`````
+M`````0`@2!$```````0A?P!@1!$```8B````'P`A`C```````````!3`````
+M``8A````$`!`3!$```8'`````,`@!````````````#C`````````````'0`@
+M"BT`````````'@`@#BT`````````'P`@$BT`````````(``@%BT````````A
+M:0`@1!$````````````@2`0````````````@2`4````````````@2`$`````
+MROZZO@`@2!$`````````!``P$B0````````````O`&0```````````S`````
+M``8@`````P`H&B(`````````"``B$B(`````___P```H$B0````````````I
+M$,0`````````'P!`-B0```````````"``````````````!K```````8BGP``
+M```@1!$`````ROZZO@`@2!$``````````!K@``````8E``````"`````````
+M`````!K```````8GG@`````@1!$`````ROZZO@`@2!$``````````!K@````
+M``8J``````"```````````````!@```````+```0``!@!!$```,5```````@
+M!!$```````````!@"!$```&R```B7``@1!$``````````P`@2!$````````B
+M5@`@1!$`````````&P`@2!$```````"A_``@1!$``````````0`@2!$`````
+M``&A_<`@1!$`````````(0`@'BT`````````$``B'B<`````````)``@(BT`
+M``````#__P`H(B@````````````I20<````````````@2!$`````````(@`@
+M(BT```````#__P`H(B@````````````I20<````````````@2!$`````````
+M(P`@'BT`````````$``B'B<````````````I20<```````````!`2!$`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4(%"@6Z`E```````<,!:`1!!;H``````B4"
+M"0)0`5$``````B,"10*@`D$``````]<%N@6Z!;H`````!>(%XP,?!;H`````
+M`R`%OP,@`TH``````S0"@@-,`SX`````!;H%N@6Z!;H`````!;H%5P6Z`RH`
+M`````[P%N@3#`TX`````!*($500_!;H`````!-@%N@1#!.4`````!%4%#P-;
+M`WL`````!;H%N@6Z!;H`````!;H%N@6Z!;H`````!;H%N@78!<$`````!;H%
+MN@`'!;H`````!;H%N@6Z!;H`````!;H%N@6Z!;H``````_@#[00(!`8`````
+M!`X$"@0,!!``````!!P$&`0D!"``````!"P$*`0T!#``````!;H%N@0Z!#@`
+G````!;H%N@6Z!;H`````!;H%N@6Z!;H```````(&#@8L``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RS780_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RS780_pfp.bin.uu
new file mode 100644
index 0000000..754b959
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RS780_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RS780_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``=L`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8'+`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_X``$+`@`,)`"`'TE```U%`(`?34+`"54!P!\U8``)9P'`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`R@@``,H,
+M``"``=L`U(`D`,H(``!\`,``R!0E`,@8)`!\E(@`?)B``,(``P#4`'4`?'1,
+M`(``9`#40!X`RA@``-1`'@#5@!X`@`!B`-0`=0#40!X`R@@``,H,``#*$```
+MU(`9`-3`&`#5`!<`U(`>`-3`'@#5`!X`X@`>`,H$``"@````?H*+`-0`=0#4
+M0!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>`-3`'@#5`!X`[@`>`,H$
+M``"@````?H*+`,H(```DC`$`U(!@`)3``P`$$`$`!!`"`-4`)0#40!X`@```
+M`-2`'@#*"```U(!A`-1`'@"`````U(`>`,H(``#*#```U$`>`-2`%@#4P!8`
+MU(`>`(`!VP#4P!X`Q@A#`,H,``#*$```E(`$`,H4``#D(/,`U"`3`-5@90#4
+MX!P`U2`<`-5@'`"`````!B`!`,8(0P#*#```RA```)2#]P#*%```Y"#S`(``
+MG`#4(!,`Q@A#`,H,``#*$```F(/O`,H4``#4`&0`@`"P``````#$%#(`QAA#
+M`,0(+P"50`4`Q`PP`-1`'@"`````[@`>`)6#]0#$$#$`U$`S`-4@90#4H!P`
+MU.`<`-4@'`#D`5X`U``>`(`````&(`$`RA@```H@`0#6`'8`Q`@V`)B`!P#&
+M$$4`E0$0`-0`'P#48&(`@````-0@8@#,.#4`S!0S`(0!W@#4`'(`U4`>`(``
+M``#N`!X`X@`:`(0!W@#B`!H`S!!+`,P$1P`LE`$`?0F+`)A`!0!]%<L`U``:
+M`(`!VP#4`&T`-$0!`,P,2`"80#H`S"Q*`)6`!`#,!$D`@`';`-0`&@#4P!H`
+M*"@!`(0!$P#,$`,`F(`;``0X#`"$`1,`S!`#`)B`%P`$.`@`A`$3`,P0`P"8
+M@!,`!#@$`(0!$P#,$`,`F(`4`,P03`":@`D`S!1-`)A`W`#4`&T`S!A(`-4`
+M&@#50!H`@`#L`-6`&@"6P-4`U`!M`(`!VP#4`&X`FL`#`-0`;0#4`&X`@```
+M`.P`?P":P,P`U`!M`(`!VP#4`&X`S!0#`,P8`P#,'`,`?9$#`'W5@P!]&0P`
+M-<P?`#5P'P!\\,L`?-"+`(@```!^CHL`E<`$`-0`;@"``=L`U``:`-3`&@#,
+M"`,`S`P#`,P0`P#,%`,`S!@#`,P<`P#,)`,`S"@#`#7$'P`VL!\`?'!+`#3P
+M'P!\<$L`-7`?`'QP2P!]B($`?<S!`'Y1`0!^E4$`?)""`'S4P@!\A(L`FL`#
+M`'R,BP`LB`$`F(">`-0`;0"80)P`U`!N`,P(3`#,#$T`S!!(`-2`&@#4P!H`
+M@`$D`-4`&@#,"#(`U``R`)2"M@#*#```U$`>`(````#4`!X`Y`$>`-0`'@#*
+M"```R@P``,H0``#40!X`RA0``-2`'@#4P!X`U0`>`-5`'@#50#0`@````.X`
+M'@`H!`0`X@`:`.(`&@#40!H`RC@``,P(`P#,#`,`S`P#`,P,`P"8@IH`````
+M`(0!W@#7H&\`@````.X`'P#*!```PO\``,P(-`#!/_\`?'3+`'S)"P!]`0\`
+MF0*-`'QSBP"$`=X`UZ!O`(````#N`!\`R@@``"@9``!]B8L`E8`4`"@4!`#*
+M#```RA```,H<``#*)```X@`?`-3`&@#5`!H`U4`:`,P8`P#,+`,`S"P#`,PL
+M`P!]I8L`?9Q'`)A"=```````@`&$`-3`&@#40!X`U(`>`(````#N`!X`Y`$>
+M`-0`'@#40!X`[@`>`,H$``"@````?H*+`.0!/@#4`!X`U$`>`.X`'@#*!```
+MH````'Z"BP#*"```)(P&``S,!@"8P`8`S!!.`)D`!`#4`',`Y`$>`-0`'@#4
+M0!X`U(`>`(````#N`!X`R@@``,H,```TT!@`)1`!`)4`(0#!?_\`RA```,H4
+M``#*&```U(`=`-3`'0!]L8L`P4("`,+``0#5@!T`--P.`'U=3`!_<TP`UT`>
+M`-4`'@#50!X`P4(``,+````)G`$`,=P0`']?3`!_<TP`!"@"`'V#@`#5J&\`
+MU8!F`-=`'@#L`%X`R"0"`,@D`@"``=L`U@!V`-1`'@#4@!X`U,`>`(````#N
+M`!X`@````.X`'P#4`!\`@````-0`'P#4`!\`B````-0`'P``````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0&4``(!FP`#`+(`!`"B``4``P`&
+M`#\`!P`R``@!3P`)`$8`"@`V`!`!V0`7`,4`(@%=`",!;``@`-<`)`%(`"8`
+M30`G`%P`*`"-`"D`40`J`'X`*P!A`"\`B``R`*H`-`&B`#8`;P`\`7D`/P"5
+M`$$!KP!$`5$`50&6`%8!G0!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`
+M9P`X`&@`.@!I`$$`:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@`<P'9````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV610_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV610_me.bin.uu
new file mode 100644
index 0000000..2dc61d2
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV610_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RV610_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```:-``````!@``````8Q
+M``````!@``````9%`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````9H``````!@``````9<`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````9B``````!```````#K``````!@``````9E````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```:-````
+M'P`A`C```````````!3```````:,````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``:-````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````:,```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````9%``````!`!`\```(3``````!@``````8Q``````!@``````9%```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````8Q``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:-
+M``````!@``````8Q`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````9H``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````9?````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP`````@1!$````````````@2!$`````B@`````@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`
+M`````````-D`2````````````,`@!`````````````"@``H````````B5P`@
+M1!$``````````\!(2B`````````B70`@1!$``````````,!`2```````````
+M``!@``````9%`````,`@"``````````B7``@1!$``````````P`X2B(`````
+M``"A_``@1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`
+M``````````S@`````````````$`@2````````````4`P2B```````````L`P
+M2B```````````0!3"B(```-+````/\`H"B``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````&``@2!$```````0A^0!@1!$```:-
+M````$0`A`C```````````!3@``````-4````%``O`B(```````````S`````
+M``-D```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!@
+M2`(```-N```A```@1!$``````````,`@2````````````,`@2```````````
+M`,`@2````````````,!`2```````````!``O`B(```````````S```````-J
+M```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!`2`(`
+M``-?````*``O`B(```````````S```````7```&BI``@1!$```````````!`
+M2`(```-?````+``@-B8`````````20`@&!$`````````/P`@2!$`````````
+M`0`S&B8````````````O`B8```````````S```````-P````+`"`&BT`````
+M````/\`H"B``````````%0`O`B(```````````S@``````.&````!@`O`B(`
+M``````````S@``````.Q````%@`O`B(```````````S@``````.U````(``O
+M`B(```````````S@``````.<````#P`O`B(```````````S@``````.H````
+M$``O`B(```````````S@``````.H````'@`O`B(```````````S@``````.0
+M``"BI``@1!$```````````!`2`(`````"``````I"B(``````````T`A#B``
+M````````#,`A$B````````@````H$B0`````````%,`B%B`````````````I
+M%*0```````"BI``@1!$````````````I2*(```````"A_@`@1!$`````````
+M``!`2`,`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````
+M````%@`@2!$```````0A^0!@1!$```:-````%0`A`C```````````!3@````
+M``.2```A#@`@1!$``````````,`@2````````````,`@2`````````"BI``@
+M1!$```````````!`2`(`````@0`````@1!$``````````0`@2!$````````A
+M^``@1!$`````````%P`@2!$```````0A^0!@1!$```:-`````P`A`C``````
+M`````!3@``````.>```A"``@1!$``````````,`@2````````````,`@2```
+M``````"BI``@1!$```````````!`2`(```````"BI``@1!$````````````@
+M2`(`````@``````@1!$````````````@2!$`````@0`````@1!$`````````
+M$``@2!$````````````@`!```````````!3```````.N``````!`````````
+M```@$``@1!$```````"````@2!$```````&BI``@1!$`````````!@!`2!$`
+M```````@$``@1!$```````"````@2!$```````&BI``@1!$`````````%@!@
+M2!$```-N``````!``````````````,`@"````````````,`@#```````````
+M'0`A`B,``````````!3@``````/.@0`````@1!$``````````0`@2!$`````
+M```A^``@1!$`````````&``@2!$```````0A^0!@1!$```:-````$0`A`C``
+M`````````!3@``````/````A```@1!$````````````@2`(````````````@
+M2`,`````NK[*_@`@2!$`````ROZZO@`@2!$````````@$``@1!$```````"`
+M```@2!$```````"BI``@1!$`````````!`!`2!$````````A<``@1!$`````
+M```````@2`(````````````@2`,`````@0`````@1!$`````````"@`@2!$`
+M```````````@`!```````````!3```````/3C``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$``````````0`@2!$````````__T`H"B``````@```
+M`$`H#B``````0````,`H$B````````0```!I1B(```:-```````@%!``````
+M```````O`B,```````````S```````/A`````,!`&`````/D```__\`H&B``
+M``````0```!I1B8```:-```````@&!`````````````O`B0```````````S`
+M``````/G`````,!`'`````/J```__\`H'B````````0```!I1B<```:-````
+M```@'!`````````````@1`(````````````H(,4```````````!)2.@`````
+MI8`````@"!$````````@```@#!$`````@P````!@1!$```02```````@1`(`
+M`````````,`@2````````````$`@2```````````'\`A`B```````````!3`
+M``````/W```@$``@1!$```````"````@2!$```````#__\!($B````/_IX``
+M```@"!$```````"@```@#!$`````@P````!@1!$```02```````@1`(`````
+M`````,`@2````````````,`@2`````````#__\`H$B``````@P`````@1!$`
+M```````````P2(,`````A``````@1!$``````````,`@2````````````!T`
+M````````@P````!@1!$```02`````,!`!``````!J8`````@"!$```````#`
+M``!`#!$```/ZJX`````@"!$```````#XX`!`#!$```/ZK8`````@"!$`````
+M``#X@`!`#!$```/ZLX`````@"!$```````#S_`!`#!$```/ZKX`````@"!$`
+M``````#@``!`#!$```/ZL8`````@"!$```````#P``!`#!$```/Z@P`````@
+M1!$````````A2``@2!$`````A``````@1!$``````````,`@2```````````
+M`!T```````````````"``````````1@@`,`P1B```````````-D`2```````
+M`````,`@!`````````````"@``H``````AB@`,`P1B```````````-D`2```
+M`````````,`@!`````````````"@``H``````QC``,`P1B```````````-D`
+M2````````````,`@!`````````````"@``H`````!!CXX,`P1B``````````
+M`-D`2````````````,`@!`````````````"@``H`````!1CX@,`P1B``````
+M`````-D`2````````````,`@!`````````````"@``H`````!AC@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H`````!QCP`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H`````"!CS
+M_,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M````,``@"BT``````````,`I#$``````````,``@-B,``````````,`@!```
+M``````````"@``H`````A@`````@1!$```````````!`2`$`````A0```,`@
+M1!$```````````!`2`$````````A?``@1!$`````````&$`A`B``````````
+M`!3```````1%`(```,!)2B````1&`````,`@2````````````,`@2```````
+M`````,`@2```````@0`````@1!$``````````0`@2!$``````````,`@"```
+M`````````!<```````````0A?P!@1!$```:-````'P`A`C```````````!3`
+M``````````````!`3`(```1+`````,`@#````````````,`@$```````````
+M`,`@%````````````,`@&````````````,`@'`````````!_```H"B$`````
+M``!%```O`B(```````````S@``````19`````,`@(````````````!<`````
+M````````$``H"B,`````````$``O`B(```````````S@``````1A@0`````@
+M1!$``````````0`@2!$```````0```!I1B0```:-``````!```````1F@0``
+M```@1!$````````````@2!$````````A;0`@1!$````````````@2`0`````
+M``````!@2`4```:2```````H)/``````````!P`H"B,``````````0`O`B(`
+M``````````K@``````1M```````O`,D```````````3@``````2&``````!`
+M``````23`````@`O`B(```````````K@``````1R```````O`,D`````````
+M``+@``````2&``````!```````23`````P`O`B(```````````K@``````1W
+M```````O`,D```````````S@``````2&``````!```````23````!``O`B(`
+M``````````K@``````1\```````O`,D```````````K@``````2&``````!`
+M``````23````!0`O`B(```````````K@``````2!```````O`,D`````````
+M``;@``````2&``````!```````23````!@`O`B(```````````K@``````2&
+M```````O`,D```````````C@``````2&``````!```````23``!_```H"B$`
+M``````!%```O`B(```````````K@````````````"``A"B,``````````!3`
+M``````20```A:0`@1!$``````````,`@2````````````,`@2```````````
+M`,`@2```````ROZZO@!`2!$``````````,`@1````````````,`@````````
+M`````,!`2`````````!_```H"B$```````!%```O`B(```````````K@````
+M``29`````,`@`````````````,`@`````````````,!```````````````!`
+M3`@```19`````,`@"```````````$$`A#B``````````$4`A$B``````````
+M$D`A%B`````````A:0`@1!$````````````@2`(````````````A`B4`````
+M`````!3@``````2C``0``,!)2B````2D__O__\`H2B`````````````A`B,`
+M`````````!3@``````2P`````,`@2````````````,`@2``````````````A
+M`B0``````````!3`````````@0`````@1!$`````````#``@2!$`````````
+M```@`!```````````!3```````2LH``````@1!$`````ROZZO@!`2!$`````
+M@0`````@1!$`````````!``@2!$````````A:P`@1!$``````````,`@2!``
+M````@0`````@1!$`````````!0`@2!$````````A;``@1!$``````````,`@
+M2!`````````````O`B0```````````S@``````````````!```````2J````
+M`,`A"B```````````!3```````3#@0`````@1!$````````````@2!$`````
+M```A;0`@1!$``````````,`@2````````````,!@2`````:2``````!`````
+M``3'@0`````@1!$``````````0`@2!$```````0``,`I1B```````````,!@
+M``````:-`````0`A`B(``````````!3```````3.```A:0`@1!$`````````
+M`,`@2````````````,`@2``````````````@2!``````ROZZO@!`2!$`````
+M`````,`@1````````````,!`2!``````@0`````@1!$``````````0`@2!$`
+M```````A^``@1!$`````````#@`@2!$```````0A^0!@1!$```:-```````A
+M`C```````````!3```````30```A@``@1!$``````````,`@2```````````
+M`,`@`````````````,`@2````````````,`@`````````````,!`2```````
+M`````P`S/B\``````````0`A`B$``````````!3@``````4`````+``@"BT`
+M``````0``!C@#!$```3O`````0`S/B\````````A:0`@1!$````````````@
+M2`(````````````@2`,`````````"``P"B(``````````,`@2```````````
+M`,`@2``````````A:0`@1!$````````````@2`(````````````@2`,`````
+M````"``P"B(``````````,`@2````````````-C`2`````3C```A:0`@1!$`
+M```````````@2`(````````````@2`,`````````"``P"B(``````````,`@
+M2````````````,`@2```````````+0`@$BT````````````I#(,````````A
+M:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`````
+M`````,`@2````````````,`@2```````````$0`A`B0``````````!3`````
+M``````````!```````2J````+,`@-B``````````+<!`-B``````````#P`A
+M`B$``````````!3```````4%``````!@```````+`````-D`````````````
+M`,!`!``````!M0`````@1!$````````@```@2!$`````M@`````@1!$`````
+M``"@```@2!$`````MP`````@1!$```````#````@2!$`````N``````@1!$`
+M``````#XX``@2!$`````N0`````@1!$```````#X@``@2!$`````N@`````@
+M1!$```````#@```@2!$`````NP`````@1!$```````#P```@2!$`````O```
+M```@1!$```````#S_``@2!$`````@0`````@1!$``````````@`@2!$`````
+M````_P`H#C`````````````O`B,```````````S```````49`````,`@"```
+M`````````!3```````4N```````@#!$`````````'``@-B,`````````*P`@
+M-B,`````````*0`@-B,`````````*``@-B,`````````%P`@-B,`````````
+M)0`@-B,`````````)@`@-B,`````````%0`@-B,`````````%@`@-B,`````
+M___@```@#!$`````````(0`@-B,`````````(@`@-B,````````?_P`@#!$`
+M````````(P`@-B,`````````)``@-B,`````\?___P`H.BX`````````&L`B
+M#B`````````````I.&X`````@0`````@1!$`````````!@`@2!$`````````
+M*D`@-B``````AP`````@1!$``````````,`@2`````````"A]``@1!$`````
+M```````@2!`````````````@#!$`````````,``@-B,`````G0`````@1!$`
+M````````'T`A2B``````E@`````@1!$``````````,`@2````````````,`@
+M#````````````,`@$```````````'P`A%B0``````````!3`````````````
+M'0`@-B,``````````P`H'B,`````````"``B(B,`````___P```H(B@`````
+M```````I(.@`````````'P`@-B@`````````&``A'B,`````````(``@-B<`
+M`````````@`B%B0````````````P%*@`````````'@`@-B4``````````P`A
+M&B0`````$``````H&B8`````[____P`H.BX```````````!).,X```9[````
+M`4`H"B``````````!D`H#B`````````#`,`H$B``````````"``A$B0`````
+M`````,`@%B```````````,`@&B`````````````A`B(``````````!3`````
+M``5F@0`````@1!$``````````0`@2!$````````B6``P"B0```````0```!I
+M1B(```:-```A:0`@1!$````````````@2`4```````(````I2B8`````````
+M```@2!``````ROZZO@`@2!$``````````@`O`B,```````````S```````5N
+M`````,`@'!```````````,!```````5\`````@`O`B,```````````S`````
+M``5N@0`````@1!$``````````0`@2!$````````B6``P"B0```````0```!I
+M1B(```:-`````,`@'!```````````,!```````5\```````O`B,`````````
+M``S```````5R`````,`@'````````````,!```````5\````!``O`B,`````
+M``````S```````5Z@0`````@1!$````````````@2!$````````A;0`@1!$`
+M`````````,`@2````````````,!@2`````:2``````!`'!````5\`````,`@
+M`````````````,!```````````````[@``````5^``````!@``````7)````
+M```O`B0```````````S```````6/``"BMP`@1!$````````````@2`<`````
+M@0`````@1!$``````````0`@2!$```````2BM@!@1!$```:-````&@`A(C``
+M````````!@`B)C````````0@!`!@1!$```:-``"BQ``@1!$````````````P
+M2.D```````````#@``````6-``"BT0`@1!$```````````!`2`@```````"B
+MT0`@1!$``````````0!02B@``````````0`O`B0```````````S```````6@
+M``"BNP`@1!$````````````@2`<`````@0`````@1!$``````````0`@2!$`
+M``````2BN@!@1!$```:-````&@`A(C``````````!@`B)C````````0@!`!@
+M1!$```:-``"BQ0`@1!$````````````P2.D```````````#@``````6>``"B
+MT@`@1!$```````````!`2`@```````"BT@`@1!$``````````0!02B@`````
+M`````@`O`B0```````````S```````6Q``"BOP`@1!$````````````@2`<`
+M````@0`````@1!$``````````0`@2!$```````2BO@!@1!$```:-````&@`A
+M(C``````````!@`B)C````````0@!`!@1!$```:-``"BQ@`@1!$`````````
+M```P2.D```````````#@``````6O``"BTP`@1!$```````````!`2`@`````
+M``"BTP`@1!$``````````0!02B@```````"BPP`@1!$````````````@2`<`
+M````@0`````@1!$``````````0`@2!$```````2BP@!@1!$```:-````&@`A
+M(C``````````!@`B)C````````0@!`!@1!$```:-``"BQP`@1!$`````````
+M```P2.D```````````#@``````6^``"BU``@1!$```````````!`2`@`````
+M``"BU``@1!$``````````0!02B@`````A0`````@1!$````````````@2`$`
+M```````P2@`@1!$``````0`````@2!$```````````!```````7$I````,`@
+M1!$``````````,!`2````````````,!@``````7)`````,!`!``````!````
+M+``@-B$`````@0`````@1!$`````````!@`@2!$````````````O`C``````
+M``````S```````70```````@!!$`````````,`!`-B$```7C````,``@!BT`
+M``````!^```H!B$````````````O`B$```````````S@``````7C@0`````@
+M1!$``````````0`@2!$```````2@D@!@1!$```:-````,0`@-C````````2@
+MDP!@1!$```:-````,@`@-C````````2BM@!@1!$```:-````,P`@-C``````
+M``2BN@!@1!$```:-````-``@-C````````2BO@!@1!$```:-````-0`@-C``
+M``````2BP@!@1!$```:-````-@`@-C````````0@!`!@1!$```:-``&BI``@
+M1!$`````````/P`@2!$`````````/P`@2!$`````````/P`@2!$`````````
+M/P`@2!$`````````!0`@2!$```````"A]``@1!$````````````@2!$`````
+MB``````@1!$``````````0`@2!$`````@0`````@1!$`````````!@`@2!$`
+M`````````0`O`C````````````S@``````8L````,``@!BT````````````O
+M`B$```````````S@``````8L@0`````@1!$``````````0`@2!$```````!^
+M```H!B$````````````O`B$```````````S@``````8%``"@D@`@1!$`````
+M````,0`@2BT```````"@DP`@1!$`````````,@`@2BT```````"BM@`@1!$`
+M````````,P`@2BT```````"BN@`@1!$`````````-``@2BT```````"BO@`@
+M1!$`````````-0`@2BT```````"BP@`@1!$`````````-@`@2BT`````````
+M,``@!BT````````!_P`H!B$````````````O`B$```````````S@``````8K
+M```````A`B$``````````!3```````8.``2@`P!@1!$```:-``"@`P`@1!$`
+M```````````@2!```````````0`A!B$``````````!3```````83``2@$`!@
+M1!$```:-``"@$``@1!$````````````@2!```````````0`A!B$`````````
+M```O`B$```````````S@``````8K``2@$0!@1!$```:-``"@$0`@1!$`````
+M```````@2!````````2@$@!@1!$```:-``"@$@`@1!$````````````@2!``
+M``````2@$P!@1!$```:-``"@$P`@1!$````````````@2!````````2@%`!@
+M1!$```:-``"@%``@1!$````````````@2!````````2@%0!@1!$```:-``"@
+M%0`@1!$````````````@2!````````2@%@!@1!$```:-``"@%@`@1!$`````
+M```````@2!````````2@%P!@1!$```:-``"@%P`@1!$````````````@2!``
+M``````0@!`!@1!$```:-````+`"`!BT`````_P`````@1!$````````````@
+M2!$``````````0`@2!$``````````@"`2!$```````````[@``````8]````
+M,``@!BT``````````@`H!B$````````````O`B$```````````S@``````8[
+M@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:-```0```@"!$`
+M````````*P`@-B(```````````!@``````9!``````!@``````7)F``````@
+M1!$```````````"`2!$``````````,!@``````9!`````,!`!``````!``"B
+MI``@1!$`````````(@`@2!$`````B0`````@1!$``````````0!`2!$```8M
+MEP`````@1!$````````````@2!$`````B@`````@1!$```````````!`2!$`
+M``8M``````!@``````9<```@$``@1!$```````"````@2!$```````&BI,`@
+M1!$`````````%@!@2!$```-N```@$``@1!$```````$````@2!$`````@0``
+M```@1!$``````````0`@2!$````````A?``@1!$`````"8`````@2!$`````
+M_____P`@2!$````````````@2!$``````````!<```````````0A?P!@1!$`
+M``:-````'P`A`C```````````!3`````````````!`!`3!$```96``````!`
+M````````````%P`@'BT`````````!``I'B<`````````%P"`-B<`````````
+M%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````%P`@'BT`````
+M````"``I'B<`````````%P"`-B<`````````%P`@'BT`````____]P`H'B<`
+M````````%P"`-B<````````@$``@1!$```````"````@2!$```````&BI``@
+M1!$`````````%@!@2!$```-N```@$``@1!$```````$````@2!$````````A
+M?``@1!$``````8`````@2!$`````_____P`@2!$````````````@2!$`````
+M`````!<`````````@0`````@1!$``````````0`@2!$```````0A?P!@1!$`
+M``:-````'P`A`C```````````!3```````:,````$`!`3!$```9R`````,`@
+M!````````````#C`````````````'0`@"BT`````````'@`@#BT`````````
+M'P`@$BT`````````(``@%BT````````A:0`@1!$````````````@2`0`````
+M```````@2`4````````````@2`$`````ROZZO@`@2!$`````````!``P$B0`
+M```````````O`&0```````````S```````:+`````P`H&B(`````````"``B
+M$B(`````___P```H$B0````````````I$,0`````````'P!`-B0`````````
+M``"``````````````!K```````:-GP`````@1!$`````ROZZO@`@2!$`````
+M`````!K@``````:0``````"``````````````!K```````:2G@`````@1!$`
+M````ROZZO@`@2!$``````````!K@``````:5``````"```````````````!@
+M```````+```0``!@!!$```,5```````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$````````B5@`@1!$`````````&P`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_<`@1!$`````````(0`@'BT`
+M````````$``B'B<`````````)``@(BT```````#__P`H(B@````````````I
+M20<````````````@2!$`````````(@`@(BT```````#__P`H(B@`````````
+M```I20<````````````@2!$`````````(P`@'BT`````````$``B'B<`````
+M```````I20<```````````!`2!$`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4(%`@7``E```````<,!:`0_!<```````B4"
+M"0)0`5$``````B,"10*@`D$``````]<%P`7`!<``````!DD&2@,?!<``````
+M!<`%Q0,@`T```````RH"@@-"`S0`````!<`%P`7`!<``````!<`%407`!<``
+M`````[H%P`2[`T0`````!)H$4`0]!<``````!-`%P`1!!-T`````!%`%!P-1
+M`W4`````!<`%P`7`!<``````!<`%P`7`!<``````!<`%P`8_!<<`````!<`%
+MP``'!<``````!<`%P`7`!<``````!<`%P`7`!<```````_@#[00(!`8`````
+M!`X$"@0,!!``````!!P$&`0D!"``````!"P$*`0T!#``````!<`%P`0X!<``
+G````!<`%P`7`!<``````!<`%P`7`!<````````(&>0:7``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV610_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV610_pfp.bin.uu
new file mode 100644
index 0000000..eb33b72
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV610_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RV610_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``;@`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8&H`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_\``$+`0`,)`"`'TE```U%`(`?34+`"54`P!\U8``)9P#`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`RA@``-1`
+M'@#5@!X`@`!3`-0`=0#40!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>
+M`-3`'@#5`!X`X@`>`,H$``"@````?H*+`,H(``#4@&``U$`>`(````#4@!X`
+MR@@``-2`80#40!X`@````-2`'@#*"```R@P``-1`'@#4@!8`U,`6`-2`'@"`
+M`;@`U,`>`,8(0P#*#```RA```)2`!`#*%```Y"#S`-0@$P#58&4`U.`<`-4@
+M'`#58!P`@`````8@`0#&"$,`R@P``,H0``"4@_<`RA0``.0@\P"``'D`U"`3
+M`,8(0P#*#```RA```)B#[P#*%```U`!D`(``C0``````Q!0R`,880P#$""\`
+ME4`%`,0,,`#40!X`@````.X`'@"5@_4`Q!`Q`-1`,P#5(&4`U*`<`-3@'`#5
+M(!P`Y`%>`-0`'@"`````!B`!`,H8```*(`$`U@!V`,0(-@"8@`<`QA!%`)4!
+M$`#4`!\`U&!B`(````#4(&(`S#@U`,P4,P"$`;L`U`!R`-5`'@"`````[@`>
+M`.(`&@"$`;L`X@`:`,P02P#,!$<`+)0!`'T)BP"80`4`?17+`-0`&@"``;@`
+MU`!M`#1$`0#,#$@`F$`Z`,PL2@"5@`0`S`1)`(`!N`#4`!H`U,`:`"@H`0"$
+M`/``S!`#`)B`&P`$.`P`A`#P`,P0`P"8@!<`!#@(`(0`\`#,$`,`F(`3``0X
+M!`"$`/``S!`#`)B`%`#,$$P`FH`)`,P430"80-P`U`!M`,P82`#5`!H`U4`:
+M`(``R0#5@!H`EL#5`-0`;0"``;@`U`!N`)K``P#4`&T`U`!N`(````#L`'\`
+MFL#,`-0`;0"``;@`U`!N`,P4`P#,&`,`S!P#`'V1`P!]U8,`?1D,`#7,'P`U
+M<!\`?/#+`'S0BP"(````?HZ+`)7`!`#4`&X`@`&X`-0`&@#4P!H`S`@#`,P,
+M`P#,$`,`S!0#`,P8`P#,'`,`S"0#`,PH`P`UQ!\`-K`?`'QP2P`T\!\`?'!+
+M`#5P'P!\<$L`?8B!`'W,P0!^40$`?I5!`'R0@@!\U,(`?(2+`)K``P!\C(L`
+M+(@!`)B`G@#4`&T`F$"<`-0`;@#,"$P`S`Q-`,P02`#4@!H`U,`:`(`!`0#5
+M`!H`S`@R`-0`,@"4@MD`R@P``-1`'@"`````U``>`.0!'@#4`!X`R@@``,H,
+M``#*$```U$`>`,H4``#4@!X`U,`>`-4`'@#50!X`U4`T`(````#N`!X`*`0$
+M`.(`&@#B`!H`U$`:`,HX``#,"`,`S`P#`,P,`P#,#`,`F(*]``````"$`;L`
+MUZ!O`(````#N`!\`R@0``,+_``#,"#0`P3__`'QTRP!\R0L`?0$/`)D"L`!\
+M<XL`A`&[`->@;P"`````[@`?`,H(```H&0``?8F+`)6`%``H%`0`R@P``,H0
+M``#*'```RB0``.(`'P#4P!H`U0`:`-5`&@#,&`,`S"P#`,PL`P#,+`,`?:6+
+M`'V<1P"80I<``````(`!80#4P!H`U$`>`-2`'@"`````[@`>`.0!'@#4`!X`
+MU$`>`.X`'@#*!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^
+M@HL`R@@``"2,!@`,S`8`F,`&`,P03@"9``0`U`!S`.0!'@#4`!X`U$`>`-2`
+M'@"`````[@`>`,H(``#*#```--`8`"40`0"5`"$`P7__`,H0``#*%```RA@`
+M`-2`'0#4P!T`?;&+`,%"`@#"P`$`U8`=`#3<#@!]74P`?W-,`-=`'@#5`!X`
+MU4`>`,%"``#"P```"9P!`#'<$`!_7TP`?W-,``0H`@!]@X``U:AO`-6`9@#7
+M0!X`[`!>`,@D`@#()`(`@`&X`-8`=@#40!X`U(`>`-3`'@"`````[@`>`(``
+M``#N`!\`U``?`(````#4`!\`U``?`(@```#4`!\`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%Q``(!>``#`(\`!`!_``4``P`&
+M`#\`!P`R``@!+``)`$8`"@`V`!`!M@`7`*(`(@$Z`",!20`@`+0`)`$E`"<`
+M30`H`&H`*@!@`"L`4@`O`&4`,@"'`#0!?P`\`58`/P!R`$$!C`!$`2X`50%S
+M`%8!>@!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`9P`X`&@`.@!I`$$`
+M:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@````&````!@````8````&````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV620_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV620_me.bin.uu
new file mode 100644
index 0000000..fa545b4
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV620_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RV620_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```:-``````!@``````8Q
+M``````!@``````9%`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````9H``````!@``````9<`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````9B``````!```````#K``````!@``````9E````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```:-````
+M'P`A`C```````````!3```````:,````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``:-````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````:,```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````9%``````!`!`\```(3``````!@``````8Q``````!@``````9%```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````8Q``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:-
+M``````!@``````8Q`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````9H``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````9?````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP`````@1!$````````````@2!$`````B@`````@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`
+M`````````-D`2````````````,`@!`````````````"@``H````````B5P`@
+M1!$``````````\!(2B`````````B70`@1!$``````````,!`2```````````
+M``!@``````9%`````,`@"``````````B7``@1!$``````````P`X2B(`````
+M``"A_``@1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`
+M``````````S@`````````````$`@2````````````4`P2B```````````L`P
+M2B```````````0!3"B(```-+````/\`H"B``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````&``@2!$```````0A^0!@1!$```:-
+M````$0`A`C```````````!3@``````-4````%``O`B(```````````S`````
+M``-D```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!@
+M2`(```-N```A```@1!$``````````,`@2````````````,`@2```````````
+M`,`@2````````````,!`2```````````!``O`B(```````````S```````-J
+M```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!`2`(`
+M``-?````*``O`B(```````````S```````7```&BI``@1!$```````````!`
+M2`(```-?````+``@-B8`````````20`@&!$`````````/P`@2!$`````````
+M`0`S&B8````````````O`B8```````````S```````-P````+`"`&BT`````
+M````/\`H"B``````````%0`O`B(```````````S@``````.&````!@`O`B(`
+M``````````S@``````.Q````%@`O`B(```````````S@``````.U````(``O
+M`B(```````````S@``````.<````#P`O`B(```````````S@``````.H````
+M$``O`B(```````````S@``````.H````'@`O`B(```````````S@``````.0
+M``"BI``@1!$```````````!`2`(`````"``````I"B(``````````T`A#B``
+M````````#,`A$B````````@````H$B0`````````%,`B%B`````````````I
+M%*0```````"BI``@1!$````````````I2*(```````"A_@`@1!$`````````
+M``!`2`,`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````
+M````%@`@2!$```````0A^0!@1!$```:-````%0`A`C```````````!3@````
+M``.2```A#@`@1!$``````````,`@2````````````,`@2`````````"BI``@
+M1!$```````````!`2`(`````@0`````@1!$``````````0`@2!$````````A
+M^``@1!$`````````%P`@2!$```````0A^0!@1!$```:-`````P`A`C``````
+M`````!3@``````.>```A"``@1!$``````````,`@2````````````,`@2```
+M``````"BI``@1!$```````````!`2`(```````"BI``@1!$````````````@
+M2`(`````@``````@1!$````````````@2!$`````@0`````@1!$`````````
+M$``@2!$````````````@`!```````````!3```````.N``````!`````````
+M```@$``@1!$```````"````@2!$```````&BI``@1!$`````````!@!`2!$`
+M```````@$``@1!$```````"````@2!$```````&BI``@1!$`````````%@!@
+M2!$```-N``````!``````````````,`@"````````````,`@#```````````
+M'0`A`B,``````````!3@``````/.@0`````@1!$``````````0`@2!$`````
+M```A^``@1!$`````````&``@2!$```````0A^0!@1!$```:-````$0`A`C``
+M`````````!3@``````/````A```@1!$````````````@2`(````````````@
+M2`,`````NK[*_@`@2!$`````ROZZO@`@2!$````````@$``@1!$```````"`
+M```@2!$```````"BI``@1!$`````````!`!`2!$````````A<``@1!$`````
+M```````@2`(````````````@2`,`````@0`````@1!$`````````"@`@2!$`
+M```````````@`!```````````!3```````/3C``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$``````````0`@2!$````````__T`H"B``````@```
+M`$`H#B``````0````,`H$B````````0```!I1B(```:-```````@%!``````
+M```````O`B,```````````S```````/A`````,!`&`````/D```__\`H&B``
+M``````0```!I1B8```:-```````@&!`````````````O`B0```````````S`
+M``````/G`````,!`'`````/J```__\`H'B````````0```!I1B<```:-````
+M```@'!`````````````@1`(````````````H(,4```````````!)2.@`````
+MI8`````@"!$````````@```@#!$`````@P````!@1!$```02```````@1`(`
+M`````````,`@2````````````$`@2```````````'\`A`B```````````!3`
+M``````/W```@$``@1!$```````"````@2!$```````#__\!($B````/_IX``
+M```@"!$```````"@```@#!$`````@P````!@1!$```02```````@1`(`````
+M`````,`@2````````````,`@2`````````#__\`H$B``````@P`````@1!$`
+M```````````P2(,`````A``````@1!$``````````,`@2````````````!T`
+M````````@P````!@1!$```02`````,!`!``````!J8`````@"!$```````#`
+M``!`#!$```/ZJX`````@"!$```````#XX`!`#!$```/ZK8`````@"!$`````
+M``#X@`!`#!$```/ZLX`````@"!$```````#S_`!`#!$```/ZKX`````@"!$`
+M``````#@``!`#!$```/ZL8`````@"!$```````#P``!`#!$```/Z@P`````@
+M1!$````````A2``@2!$`````A``````@1!$``````````,`@2```````````
+M`!T```````````````"``````````1@@`,`P1B```````````-D`2```````
+M`````,`@!`````````````"@``H``````AB@`,`P1B```````````-D`2```
+M`````````,`@!`````````````"@``H``````QC``,`P1B```````````-D`
+M2````````````,`@!`````````````"@``H`````!!CXX,`P1B``````````
+M`-D`2````````````,`@!`````````````"@``H`````!1CX@,`P1B``````
+M`````-D`2````````````,`@!`````````````"@``H`````!AC@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H`````!QCP`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H`````"!CS
+M_,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M````,``@"BT``````````,`I#$``````````,``@-B,``````````,`@!```
+M``````````"@``H`````A@`````@1!$```````````!`2`$`````A0```,`@
+M1!$```````````!`2`$````````A?``@1!$`````````&$`A`B``````````
+M`!3```````1%`(```,!)2B````1&`````,`@2````````````,`@2```````
+M`````,`@2```````@0`````@1!$``````````0`@2!$``````````,`@"```
+M`````````!<```````````0A?P!@1!$```:-````'P`A`C```````````!3`
+M``````````````!`3`(```1+`````,`@#````````````,`@$```````````
+M`,`@%````````````,`@&````````````,`@'`````````!_```H"B$`````
+M``!%```O`B(```````````S@``````19`````,`@(````````````!<`````
+M````````$``H"B,`````````$``O`B(```````````S@``````1A@0`````@
+M1!$``````````0`@2!$```````0```!I1B0```:-``````!```````1F@0``
+M```@1!$````````````@2!$````````A;0`@1!$````````````@2`0`````
+M``````!@2`4```:2```````H)/``````````!P`H"B,``````````0`O`B(`
+M``````````K@``````1M```````O`,D```````````3@``````2&``````!`
+M``````23`````@`O`B(```````````K@``````1R```````O`,D`````````
+M``+@``````2&``````!```````23`````P`O`B(```````````K@``````1W
+M```````O`,D```````````S@``````2&``````!```````23````!``O`B(`
+M``````````K@``````1\```````O`,D```````````K@``````2&``````!`
+M``````23````!0`O`B(```````````K@``````2!```````O`,D`````````
+M``;@``````2&``````!```````23````!@`O`B(```````````K@``````2&
+M```````O`,D```````````C@``````2&``````!```````23``!_```H"B$`
+M``````!%```O`B(```````````K@````````````"``A"B,``````````!3`
+M``````20```A:0`@1!$``````````,`@2````````````,`@2```````````
+M`,`@2```````ROZZO@!`2!$``````````,`@1````````````,`@````````
+M`````,!`2`````````!_```H"B$```````!%```O`B(```````````K@````
+M``29`````,`@`````````````,`@`````````````,!```````````````!`
+M3`@```19`````,`@"```````````$$`A#B``````````$4`A$B``````````
+M$D`A%B`````````A:0`@1!$````````````@2`(````````````A`B4`````
+M`````!3@``````2C``0``,!)2B````2D__O__\`H2B`````````````A`B,`
+M`````````!3@``````2P`````,`@2````````````,`@2``````````````A
+M`B0``````````!3`````````@0`````@1!$`````````#``@2!$`````````
+M```@`!```````````!3```````2LH``````@1!$`````ROZZO@!`2!$`````
+M@0`````@1!$`````````!``@2!$````````A:P`@1!$``````````,`@2!``
+M````@0`````@1!$`````````!0`@2!$````````A;``@1!$``````````,`@
+M2!`````````````O`B0```````````S@``````````````!```````2J````
+M`,`A"B```````````!3```````3#@0`````@1!$````````````@2!$`````
+M```A;0`@1!$``````````,`@2````````````,!@2`````:2``````!`````
+M``3'@0`````@1!$``````````0`@2!$```````0``,`I1B```````````,!@
+M``````:-`````0`A`B(``````````!3```````3.```A:0`@1!$`````````
+M`,`@2````````````,`@2``````````````@2!``````ROZZO@!`2!$`````
+M`````,`@1````````````,!`2!``````@0`````@1!$``````````0`@2!$`
+M```````A^``@1!$`````````#@`@2!$```````0A^0!@1!$```:-```````A
+M`C```````````!3```````30```A@``@1!$``````````,`@2```````````
+M`,`@`````````````,`@2````````````,`@`````````````,!`2```````
+M`````P`S/B\``````````0`A`B$``````````!3@``````4`````+``@"BT`
+M``````0``!C@#!$```3O`````0`S/B\````````A:0`@1!$````````````@
+M2`(````````````@2`,`````````"``P"B(``````````,`@2```````````
+M`,`@2``````````A:0`@1!$````````````@2`(````````````@2`,`````
+M````"``P"B(``````````,`@2````````````-C`2`````3C```A:0`@1!$`
+M```````````@2`(````````````@2`,`````````"``P"B(``````````,`@
+M2````````````,`@2```````````+0`@$BT````````````I#(,````````A
+M:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`````
+M`````,`@2````````````,`@2```````````$0`A`B0``````````!3`````
+M``````````!```````2J````+,`@-B``````````+<!`-B``````````#P`A
+M`B$``````````!3```````4%``````!@```````+`````-D`````````````
+M`,!`!``````!M0`````@1!$````````@```@2!$`````M@`````@1!$`````
+M``"@```@2!$`````MP`````@1!$```````#````@2!$`````N``````@1!$`
+M``````#XX``@2!$`````N0`````@1!$```````#X@``@2!$`````N@`````@
+M1!$```````#@```@2!$`````NP`````@1!$```````#P```@2!$`````O```
+M```@1!$```````#S_``@2!$`````@0`````@1!$``````````@`@2!$`````
+M````_P`H#C`````````````O`B,```````````S```````49`````,`@"```
+M`````````!3```````4N```````@#!$`````````'``@-B,`````````*P`@
+M-B,`````````*0`@-B,`````````*``@-B,`````````%P`@-B,`````````
+M)0`@-B,`````````)@`@-B,`````````%0`@-B,`````````%@`@-B,`````
+M___@```@#!$`````````(0`@-B,`````````(@`@-B,````````?_P`@#!$`
+M````````(P`@-B,`````````)``@-B,`````\?___P`H.BX`````````&L`B
+M#B`````````````I.&X`````@0`````@1!$`````````!@`@2!$`````````
+M*D`@-B``````AP`````@1!$``````````,`@2`````````"A]``@1!$`````
+M```````@2!`````````````@#!$`````````,``@-B,`````G0`````@1!$`
+M````````'T`A2B``````E@`````@1!$``````````,`@2````````````,`@
+M#````````````,`@$```````````'P`A%B0``````````!3`````````````
+M'0`@-B,``````````P`H'B,`````````"``B(B,`````___P```H(B@`````
+M```````I(.@`````````'P`@-B@`````````&``A'B,`````````(``@-B<`
+M`````````@`B%B0````````````P%*@`````````'@`@-B4``````````P`A
+M&B0`````$``````H&B8`````[____P`H.BX```````````!).,X```9[````
+M`4`H"B``````````!D`H#B`````````#`,`H$B``````````"``A$B0`````
+M`````,`@%B```````````,`@&B`````````````A`B(``````````!3`````
+M``5F@0`````@1!$``````````0`@2!$````````B6``P"B0```````0```!I
+M1B(```:-```A:0`@1!$````````````@2`4```````(````I2B8`````````
+M```@2!``````ROZZO@`@2!$``````````@`O`B,```````````S```````5N
+M`````,`@'!```````````,!```````5\`````@`O`B,```````````S`````
+M``5N@0`````@1!$``````````0`@2!$````````B6``P"B0```````0```!I
+M1B(```:-`````,`@'!```````````,!```````5\```````O`B,`````````
+M``S```````5R`````,`@'````````````,!```````5\````!``O`B,`````
+M``````S```````5Z@0`````@1!$````````````@2!$````````A;0`@1!$`
+M`````````,`@2````````````,!@2`````:2``````!`'!````5\`````,`@
+M`````````````,!```````````````[@``````5^``````!@``````7)````
+M```O`B0```````````S```````6/``"BMP`@1!$````````````@2`<`````
+M@0`````@1!$``````````0`@2!$```````2BM@!@1!$```:-````&@`A(C``
+M````````!@`B)C````````0@!`!@1!$```:-``"BQ``@1!$````````````P
+M2.D```````````#@``````6-``"BT0`@1!$```````````!`2`@```````"B
+MT0`@1!$``````````0!02B@``````````0`O`B0```````````S```````6@
+M``"BNP`@1!$````````````@2`<`````@0`````@1!$``````````0`@2!$`
+M``````2BN@!@1!$```:-````&@`A(C``````````!@`B)C````````0@!`!@
+M1!$```:-``"BQ0`@1!$````````````P2.D```````````#@``````6>``"B
+MT@`@1!$```````````!`2`@```````"BT@`@1!$``````````0!02B@`````
+M`````@`O`B0```````````S```````6Q``"BOP`@1!$````````````@2`<`
+M````@0`````@1!$``````````0`@2!$```````2BO@!@1!$```:-````&@`A
+M(C``````````!@`B)C````````0@!`!@1!$```:-``"BQ@`@1!$`````````
+M```P2.D```````````#@``````6O``"BTP`@1!$```````````!`2`@`````
+M``"BTP`@1!$``````````0!02B@```````"BPP`@1!$````````````@2`<`
+M````@0`````@1!$``````````0`@2!$```````2BP@!@1!$```:-````&@`A
+M(C``````````!@`B)C````````0@!`!@1!$```:-``"BQP`@1!$`````````
+M```P2.D```````````#@``````6^``"BU``@1!$```````````!`2`@`````
+M``"BU``@1!$``````````0!02B@`````A0`````@1!$````````````@2`$`
+M```````P2@`@1!$``````0`````@2!$```````````!```````7$I````,`@
+M1!$``````````,!`2````````````,!@``````7)`````,!`!``````!````
+M+``@-B$`````@0`````@1!$`````````!@`@2!$````````````O`C``````
+M``````S```````70```````@!!$`````````,`!`-B$```7C````,``@!BT`
+M``````!^```H!B$````````````O`B$```````````S@``````7C@0`````@
+M1!$``````````0`@2!$```````2@D@!@1!$```:-````,0`@-C````````2@
+MDP!@1!$```:-````,@`@-C````````2BM@!@1!$```:-````,P`@-C``````
+M``2BN@!@1!$```:-````-``@-C````````2BO@!@1!$```:-````-0`@-C``
+M``````2BP@!@1!$```:-````-@`@-C````````0@!`!@1!$```:-``&BI``@
+M1!$`````````/P`@2!$`````````/P`@2!$`````````/P`@2!$`````````
+M/P`@2!$`````````!0`@2!$```````"A]``@1!$````````````@2!$`````
+MB``````@1!$``````````0`@2!$`````@0`````@1!$`````````!@`@2!$`
+M`````````0`O`C````````````S@``````8L````,``@!BT````````````O
+M`B$```````````S@``````8L@0`````@1!$``````````0`@2!$```````!^
+M```H!B$````````````O`B$```````````S@``````8%``"@D@`@1!$`````
+M````,0`@2BT```````"@DP`@1!$`````````,@`@2BT```````"BM@`@1!$`
+M````````,P`@2BT```````"BN@`@1!$`````````-``@2BT```````"BO@`@
+M1!$`````````-0`@2BT```````"BP@`@1!$`````````-@`@2BT`````````
+M,``@!BT````````!_P`H!B$````````````O`B$```````````S@``````8K
+M```````A`B$``````````!3```````8.``2@`P!@1!$```:-``"@`P`@1!$`
+M```````````@2!```````````0`A!B$``````````!3```````83``2@$`!@
+M1!$```:-``"@$``@1!$````````````@2!```````````0`A!B$`````````
+M```O`B$```````````S@``````8K``2@$0!@1!$```:-``"@$0`@1!$`````
+M```````@2!````````2@$@!@1!$```:-``"@$@`@1!$````````````@2!``
+M``````2@$P!@1!$```:-``"@$P`@1!$````````````@2!````````2@%`!@
+M1!$```:-``"@%``@1!$````````````@2!````````2@%0!@1!$```:-``"@
+M%0`@1!$````````````@2!````````2@%@!@1!$```:-``"@%@`@1!$`````
+M```````@2!````````2@%P!@1!$```:-``"@%P`@1!$````````````@2!``
+M``````0@!`!@1!$```:-````+`"`!BT`````_P`````@1!$````````````@
+M2!$``````````0`@2!$``````````@"`2!$```````````[@``````8]````
+M,``@!BT``````````@`H!B$````````````O`B$```````````S@``````8[
+M@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:-```0```@"!$`
+M````````*P`@-B(```````````!@``````9!``````!@``````7)F``````@
+M1!$```````````"`2!$``````````,!@``````9!`````,!`!``````!``"B
+MI``@1!$`````````(@`@2!$`````B0`````@1!$``````````0!`2!$```8M
+MEP`````@1!$````````````@2!$`````B@`````@1!$```````````!`2!$`
+M``8M``````!@``````9<```@$``@1!$```````"````@2!$```````&BI,`@
+M1!$`````````%@!@2!$```-N```@$``@1!$```````$````@2!$`````@0``
+M```@1!$``````````0`@2!$````````A?``@1!$`````"8`````@2!$`````
+M_____P`@2!$````````````@2!$``````````!<```````````0A?P!@1!$`
+M``:-````'P`A`C```````````!3`````````````!`!`3!$```96``````!`
+M````````````%P`@'BT`````````!``I'B<`````````%P"`-B<`````````
+M%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````%P`@'BT`````
+M````"``I'B<`````````%P"`-B<`````````%P`@'BT`````____]P`H'B<`
+M````````%P"`-B<````````@$``@1!$```````"````@2!$```````&BI``@
+M1!$`````````%@!@2!$```-N```@$``@1!$```````$````@2!$````````A
+M?``@1!$``````8`````@2!$`````_____P`@2!$````````````@2!$`````
+M`````!<`````````@0`````@1!$``````````0`@2!$```````0A?P!@1!$`
+M``:-````'P`A`C```````````!3```````:,````$`!`3!$```9R`````,`@
+M!````````````#C`````````````'0`@"BT`````````'@`@#BT`````````
+M'P`@$BT`````````(``@%BT````````A:0`@1!$````````````@2`0`````
+M```````@2`4````````````@2`$`````ROZZO@`@2!$`````````!``P$B0`
+M```````````O`&0```````````S```````:+`````P`H&B(`````````"``B
+M$B(`````___P```H$B0````````````I$,0`````````'P!`-B0`````````
+M``"``````````````!K```````:-GP`````@1!$`````ROZZO@`@2!$`````
+M`````!K@``````:0``````"``````````````!K```````:2G@`````@1!$`
+M````ROZZO@`@2!$``````````!K@``````:5``````"```````````````!@
+M```````+```0``!@!!$```,5```````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$````````B5@`@1!$`````````&P`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_<`@1!$`````````(0`@'BT`
+M````````$``B'B<`````````)``@(BT```````#__P`H(B@````````````I
+M20<````````````@2!$`````````(@`@(BT```````#__P`H(B@`````````
+M```I20<````````````@2!$`````````(P`@'BT`````````$``B'B<`````
+M```````I20<```````````!`2!$`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4(%`@7``E```````<,!:`0_!<```````B4"
+M"0)0`5$``````B,"10*@`D$``````]<%P`7`!<``````!DD&2@,?!<``````
+M!<`%Q0,@`T```````RH"@@-"`S0`````!<`%P`7`!<``````!<`%407`!<``
+M`````[H%P`2[`T0`````!)H$4`0]!<``````!-`%P`1!!-T`````!%`%!P-1
+M`W4`````!<`%P`7`!<``````!<`%P`7`!<``````!<`%P`8_!<<`````!<`%
+MP``'!<``````!<`%P`7`!<``````!<`%P`7`!<```````_@#[00(!`8`````
+M!`X$"@0,!!``````!!P$&`0D!"``````!"P$*`0T!#``````!<`%P`0X!<``
+G````!<`%P`7`!<``````!<`%P`7`!<````````(&>0:7``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV620_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV620_pfp.bin.uu
new file mode 100644
index 0000000..2afc25c
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV620_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RV620_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``;@`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8&H`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_\``$+`0`,)`"`'TE```U%`(`?34+`"54`P!\U8``)9P#`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`RA@``-1`
+M'@#5@!X`@`!3`-0`=0#40!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>
+M`-3`'@#5`!X`X@`>`,H$``"@````?H*+`,H(``#4@&``U$`>`(````#4@!X`
+MR@@``-2`80#40!X`@````-2`'@#*"```R@P``-1`'@#4@!8`U,`6`-2`'@"`
+M`;@`U,`>`,8(0P#*#```RA```)2`!`#*%```Y"#S`-0@$P#58&4`U.`<`-4@
+M'`#58!P`@`````8@`0#&"$,`R@P``,H0``"4@_<`RA0``.0@\P"``'D`U"`3
+M`,8(0P#*#```RA```)B#[P#*%```U`!D`(``C0``````Q!0R`,880P#$""\`
+ME4`%`,0,,`#40!X`@````.X`'@"5@_4`Q!`Q`-1`,P#5(&4`U*`<`-3@'`#5
+M(!P`Y`%>`-0`'@"`````!B`!`,H8```*(`$`U@!V`,0(-@"8@`<`QA!%`)4!
+M$`#4`!\`U&!B`(````#4(&(`S#@U`,P4,P"$`;L`U`!R`-5`'@"`````[@`>
+M`.(`&@"$`;L`X@`:`,P02P#,!$<`+)0!`'T)BP"80`4`?17+`-0`&@"``;@`
+MU`!M`#1$`0#,#$@`F$`Z`,PL2@"5@`0`S`1)`(`!N`#4`!H`U,`:`"@H`0"$
+M`/``S!`#`)B`&P`$.`P`A`#P`,P0`P"8@!<`!#@(`(0`\`#,$`,`F(`3``0X
+M!`"$`/``S!`#`)B`%`#,$$P`FH`)`,P430"80-P`U`!M`,P82`#5`!H`U4`:
+M`(``R0#5@!H`EL#5`-0`;0"``;@`U`!N`)K``P#4`&T`U`!N`(````#L`'\`
+MFL#,`-0`;0"``;@`U`!N`,P4`P#,&`,`S!P#`'V1`P!]U8,`?1D,`#7,'P`U
+M<!\`?/#+`'S0BP"(````?HZ+`)7`!`#4`&X`@`&X`-0`&@#4P!H`S`@#`,P,
+M`P#,$`,`S!0#`,P8`P#,'`,`S"0#`,PH`P`UQ!\`-K`?`'QP2P`T\!\`?'!+
+M`#5P'P!\<$L`?8B!`'W,P0!^40$`?I5!`'R0@@!\U,(`?(2+`)K``P!\C(L`
+M+(@!`)B`G@#4`&T`F$"<`-0`;@#,"$P`S`Q-`,P02`#4@!H`U,`:`(`!`0#5
+M`!H`S`@R`-0`,@"4@MD`R@P``-1`'@"`````U``>`.0!'@#4`!X`R@@``,H,
+M``#*$```U$`>`,H4``#4@!X`U,`>`-4`'@#50!X`U4`T`(````#N`!X`*`0$
+M`.(`&@#B`!H`U$`:`,HX``#,"`,`S`P#`,P,`P#,#`,`F(*]``````"$`;L`
+MUZ!O`(````#N`!\`R@0``,+_``#,"#0`P3__`'QTRP!\R0L`?0$/`)D"L`!\
+M<XL`A`&[`->@;P"`````[@`?`,H(```H&0``?8F+`)6`%``H%`0`R@P``,H0
+M``#*'```RB0``.(`'P#4P!H`U0`:`-5`&@#,&`,`S"P#`,PL`P#,+`,`?:6+
+M`'V<1P"80I<``````(`!80#4P!H`U$`>`-2`'@"`````[@`>`.0!'@#4`!X`
+MU$`>`.X`'@#*!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^
+M@HL`R@@``"2,!@`,S`8`F,`&`,P03@"9``0`U`!S`.0!'@#4`!X`U$`>`-2`
+M'@"`````[@`>`,H(``#*#```--`8`"40`0"5`"$`P7__`,H0``#*%```RA@`
+M`-2`'0#4P!T`?;&+`,%"`@#"P`$`U8`=`#3<#@!]74P`?W-,`-=`'@#5`!X`
+MU4`>`,%"``#"P```"9P!`#'<$`!_7TP`?W-,``0H`@!]@X``U:AO`-6`9@#7
+M0!X`[`!>`,@D`@#()`(`@`&X`-8`=@#40!X`U(`>`-3`'@"`````[@`>`(``
+M``#N`!\`U``?`(````#4`!\`U``?`(@```#4`!\`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%Q``(!>``#`(\`!`!_``4``P`&
+M`#\`!P`R``@!+``)`$8`"@`V`!`!M@`7`*(`(@$Z`",!20`@`+0`)`$E`"<`
+M30`H`&H`*@!@`"L`4@`O`&4`,@"'`#0!?P`\`58`/P!R`$$!C`!$`2X`50%S
+M`%8!>@!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`9P`X`&@`.@!I`$$`
+M:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@````&````!@````8````&````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV630_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV630_me.bin.uu
new file mode 100644
index 0000000..a3e9bde
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV630_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RV630_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```:*``````!@``````8N
+M``````!@``````9"`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````9E``````!@``````99`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````9?``````!```````#K``````!@``````9B````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```:*````
+M'P`A`C```````````!3```````:)````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``:*````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````:)```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````9"``````!`!`\```(3``````!@``````8N``````!@``````9"```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````8N``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:*
+M``````!@``````8N`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````9E``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````9<````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP`````@1!$````````````@2!$`````B@`````@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`
+M`````````-D`2````````````,`@!`````````````"@``H````````B5P`@
+M1!$``````````\!(2B`````````B70`@1!$``````````,!`2```````````
+M``!@``````9"`````,`@"``````````B7``@1!$``````````P`X2B(`````
+M``"A_``@1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`
+M``````````S@`````````````$`@2````````````4`P2B```````````L`P
+M2B```````````0!3"B(```-+````/\`H"B``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````&``@2!$```````0A^0!@1!$```:*
+M````$0`A`C```````````!3@``````-4````%``O`B(```````````S`````
+M``-D```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!@
+M2`(```-N```A```@1!$``````````,`@2````````````,`@2```````````
+M`,`@2````````````,!`2```````````!``O`B(```````````S```````-J
+M```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!`2`(`
+M``-?````*``O`B(```````````S```````6]``&BI``@1!$```````````!`
+M2`(```-?````+``@-B8`````````20`@&!$`````````/P`@2!$`````````
+M`0`S&B8````````````O`B8```````````S```````-P````+`"`&BT`````
+M````/\`H"B``````````%0`O`B(```````````S@``````.&````!@`O`B(`
+M``````````S@``````.Q````%@`O`B(```````````S@``````.U````(``O
+M`B(```````````S@``````.<````#P`O`B(```````````S@``````.H````
+M$``O`B(```````````S@``````.H````'@`O`B(```````````S@``````.0
+M``"BI``@1!$```````````!`2`(`````"``````I"B(``````````T`A#B``
+M````````#,`A$B````````@````H$B0`````````%,`B%B`````````````I
+M%*0```````"BI``@1!$````````````I2*(```````"A_@`@1!$`````````
+M``!`2`,`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````
+M````%@`@2!$```````0A^0!@1!$```:*````%0`A`C```````````!3@````
+M``.2```A#@`@1!$``````````,`@2````````````,`@2`````````"BI``@
+M1!$```````````!`2`(`````@0`````@1!$``````````0`@2!$````````A
+M^``@1!$`````````%P`@2!$```````0A^0!@1!$```:*`````P`A`C``````
+M`````!3@``````.>```A"``@1!$``````````,`@2````````````,`@2```
+M``````"BI``@1!$```````````!`2`(```````"BI``@1!$````````````@
+M2`(`````@``````@1!$````````````@2!$`````@0`````@1!$`````````
+M$``@2!$````````````@`!```````````!3```````.N``````!`````````
+M```@$``@1!$```````"````@2!$```````&BI``@1!$`````````!@!`2!$`
+M```````@$``@1!$```````"````@2!$```````&BI``@1!$`````````%@!@
+M2!$```-N``````!``````````````,`@"````````````,`@#```````````
+M'0`A`B,``````````!3@``````/.@0`````@1!$``````````0`@2!$`````
+M```A^``@1!$`````````&``@2!$```````0A^0!@1!$```:*````$0`A`C``
+M`````````!3@``````/````A```@1!$````````````@2`(````````````@
+M2`,`````NK[*_@`@2!$`````ROZZO@`@2!$````````@$``@1!$```````"`
+M```@2!$```````"BI``@1!$`````````!`!`2!$````````A<``@1!$`````
+M```````@2`(````````````@2`,`````@0`````@1!$`````````"@`@2!$`
+M```````````@`!```````````!3```````/3C``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$``````````0`@2!$````````__T`H"B``````@```
+M`$`H#B``````0````,`H$B````````0```!I1B(```:*```````@%!``````
+M```````O`B,```````````S```````/A`````,!`&`````/D```__\`H&B``
+M``````0```!I1B8```:*```````@&!`````````````O`B0```````````S`
+M``````/G`````,!`'`````/J```__\`H'B````````0```!I1B<```:*````
+M```@'!`````````````@1`(````````````H(,4```````````!)2.@`````
+MI8`````@"!$````````@```@#!$`````@P````!@1!$```02```````@1`(`
+M`````````,`@2````````````$`@2```````````'\`A`B```````````!3`
+M``````/W```@$``@1!$```````"````@2!$```````#__\!($B````/_IX``
+M```@"!$```````"@```@#!$`````@P````!@1!$```02```````@1`(`````
+M`````,`@2````````````,`@2`````````#__\`H$B``````@P`````@1!$`
+M```````````P2(,`````A``````@1!$``````````,`@2````````````!T`
+M````````@P````!@1!$```02`````,!`!``````!J8`````@"!$```````#`
+M``!`#!$```/ZJX`````@"!$```````#XX`!`#!$```/ZK8`````@"!$`````
+M``#X@`!`#!$```/ZLX`````@"!$```````#S_`!`#!$```/ZKX`````@"!$`
+M``````#@``!`#!$```/ZL8`````@"!$```````#P``!`#!$```/Z@P`````@
+M1!$````````A2``@2!$`````A``````@1!$``````````,`@2```````````
+M`!T```````````````"``````````1@@`,`P1B```````````-D`2```````
+M`````,`@!`````````````"@``H``````AB@`,`P1B```````````-D`2```
+M`````````,`@!`````````````"@``H``````QC``,`P1B```````````-D`
+M2````````````,`@!`````````````"@``H`````!!CXX,`P1B``````````
+M`-D`2````````````,`@!`````````````"@``H`````!1CX@,`P1B``````
+M`````-D`2````````````,`@!`````````````"@``H`````!AC@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H`````!QCP`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H`````"!CS
+M_,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M````,``@"BT``````````,`I#$``````````,``@-B,``````````,`@!```
+M``````````"@``H`````A@`````@1!$```````````!`2`$`````A0```,`@
+M1!$```````````!`2`$````````A?``@1!$``````````,`@2```````````
+M`,`@2````````````,`@2```````@0`````@1!$``````````0`@2!$`````
+M`````,`@"````````````!<```````````0A?P!@1!$```:*````'P`A`C``
+M`````````!3```````````````!`3`(```1(`````,`@#````````````,`@
+M$````````````,`@%````````````,`@&````````````,`@'`````````!_
+M```H"B$```````!%```O`B(```````````S@``````16`````,`@(```````
+M`````!<`````````````$``H"B,`````````$``O`B(```````````S@````
+M``1>@0`````@1!$``````````0`@2!$```````0```!I1B0```:*``````!`
+M``````1C@0`````@1!$````````````@2!$````````A;0`@1!$`````````
+M```@2`0```````````!@2`4```:/```````H)/``````````!P`H"B,`````
+M`````0`O`B(```````````K@``````1J```````O`,D```````````3@````
+M``2#``````!```````20`````@`O`B(```````````K@``````1O```````O
+M`,D```````````+@``````2#``````!```````20`````P`O`B(`````````
+M``K@``````1T```````O`,D```````````S@``````2#``````!```````20
+M````!``O`B(```````````K@``````1Y```````O`,D```````````K@````
+M``2#``````!```````20````!0`O`B(```````````K@``````1^```````O
+M`,D```````````;@``````2#``````!```````20````!@`O`B(`````````
+M``K@``````2#```````O`,D```````````C@``````2#``````!```````20
+M``!_```H"B$```````!%```O`B(```````````K@````````````"``A"B,`
+M`````````!3```````2-```A:0`@1!$``````````,`@2````````````,`@
+M2````````````,`@2```````ROZZO@!`2!$``````````,`@1```````````
+M`,`@`````````````,!`2`````````!_```H"B$```````!%```O`B(`````
+M``````K@``````26`````,`@`````````````,`@`````````````,!`````
+M``````````!`3`@```16`````,`@"```````````$$`A#B``````````$4`A
+M$B``````````$D`A%B`````````A:0`@1!$````````````@2`(`````````
+M```A`B4``````````!3@``````2@``0``,!)2B````2A__O__\`H2B``````
+M```````A`B,``````````!3@``````2M`````,`@2````````````,`@2```
+M```````````A`B0``````````!3`````````@0`````@1!$`````````#``@
+M2!$````````````@`!```````````!3```````2IH``````@1!$`````ROZZ
+MO@!`2!$`````@0`````@1!$`````````!``@2!$````````A:P`@1!$`````
+M`````,`@2!``````@0`````@1!$`````````!0`@2!$````````A;``@1!$`
+M`````````,`@2!`````````````O`B0```````````S@``````````````!`
+M``````2G`````,`A"B```````````!3```````3`@0`````@1!$`````````
+M```@2!$````````A;0`@1!$``````````,`@2````````````,!@2`````:/
+M``````!```````3$@0`````@1!$``````````0`@2!$```````0``,`I1B``
+M`````````,!@``````:*`````0`A`B(``````````!3```````3+```A:0`@
+M1!$``````````,`@2````````````,`@2``````````````@2!``````ROZZ
+MO@!`2!$``````````,`@1````````````,!`2!``````@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````#@`@2!$```````0A^0!@1!$`
+M``:*```````A`C```````````!3```````3-```A@``@1!$``````````,`@
+M2````````````,`@`````````````,`@2````````````,`@````````````
+M`,!`2````````````P`S/B\``````````0`A`B$``````````!3@``````3]
+M````+``@"BT```````0``!C@#!$```3L`````0`S/B\````````A:0`@1!$`
+M```````````@2`(````````````@2`,`````````"``P"B(``````````,`@
+M2````````````,`@2``````````A:0`@1!$````````````@2`(`````````
+M```@2`,`````````"``P"B(``````````,`@2````````````-C`2`````3@
+M```A:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`
+M`````````,`@2````````````,`@2```````````+0`@$BT````````````I
+M#(,````````A:0`@1!$````````````@2`(````````````@2`,`````````
+M"``P"B(``````````,`@2````````````,`@2```````````$0`A`B0`````
+M`````!3```````````````!```````2G````+,`@-B``````````+<!`-B``
+M````````#P`A`B$``````````!3```````4"``````!@```````+`````-D`
+M`````````````,!`!``````!M0`````@1!$````````@```@2!$`````M@``
+M```@1!$```````"@```@2!$`````MP`````@1!$```````#````@2!$`````
+MN``````@1!$```````#XX``@2!$`````N0`````@1!$```````#X@``@2!$`
+M````N@`````@1!$```````#@```@2!$`````NP`````@1!$```````#P```@
+M2!$`````O``````@1!$```````#S_``@2!$`````@0`````@1!$`````````
+M`@`@2!$`````````_P`H#C`````````````O`B,```````````S```````46
+M`````,`@"````````````!3```````4K```````@#!$`````````'``@-B,`
+M````````*P`@-B,`````````*0`@-B,`````````*``@-B,`````````%P`@
+M-B,`````````)0`@-B,`````````)@`@-B,`````````%0`@-B,`````````
+M%@`@-B,`````___@```@#!$`````````(0`@-B,`````````(@`@-B,`````
+M```?_P`@#!$`````````(P`@-B,`````````)``@-B,`````\?___P`H.BX`
+M````````&L`B#B`````````````I.&X`````@0`````@1!$`````````!@`@
+M2!$`````````*D`@-B``````AP`````@1!$``````````,`@2`````````"A
+M]``@1!$````````````@2!`````````````@#!$`````````,``@-B,`````
+MG0`````@1!$`````````'T`A2B``````E@`````@1!$``````````,`@2```
+M`````````,`@#````````````,`@$```````````'P`A%B0``````````!3`
+M````````````'0`@-B,``````````P`H'B,`````````"``B(B,`````___P
+M```H(B@````````````I(.@`````````'P`@-B@`````````&``A'B,`````
+M````(``@-B<``````````@`B%B0````````````P%*@`````````'@`@-B4`
+M`````````P`A&B0`````$``````H&B8`````[____P`H.BX```````````!)
+M.,X```9X`````4`H"B``````````!D`H#B`````````#`,`H$B``````````
+M"``A$B0``````````,`@%B```````````,`@&B`````````````A`B(`````
+M`````!3```````5C@0`````@1!$``````````0`@2!$````````B6``P"B0`
+M``````0```!I1B(```:*```A:0`@1!$````````````@2`4```````(````I
+M2B8````````````@2!``````ROZZO@`@2!$``````````@`O`B,`````````
+M``S```````5K`````,`@'!```````````,!```````5Y`````@`O`B,`````
+M``````S```````5K@0`````@1!$``````````0`@2!$````````B6``P"B0`
+M``````0```!I1B(```:*`````,`@'!```````````,!```````5Y```````O
+M`B,```````````S```````5O`````,`@'````````````,!```````5Y````
+M!``O`B,```````````S```````5W@0`````@1!$````````````@2!$`````
+M```A;0`@1!$``````````,`@2````````````,!@2`````:/``````!`'!``
+M``5Y`````,`@`````````````,!```````````````[@``````5[``````!@
+M``````7&```````O`B0```````````S```````6,``"BMP`@1!$`````````
+M```@2`<`````@0`````@1!$``````````0`@2!$```````2BM@!@1!$```:*
+M````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQ``@1!$`
+M```````````P2.D```````````#@``````6*``"BT0`@1!$```````````!`
+M2`@```````"BT0`@1!$``````````0!02B@``````````0`O`B0`````````
+M``S```````6=``"BNP`@1!$````````````@2`<`````@0`````@1!$`````
+M`````0`@2!$```````2BN@!@1!$```:*````&@`A(C``````````!@`B)C``
+M``````0@!`!@1!$```:*``"BQ0`@1!$````````````P2.D```````````#@
+M``````6;``"BT@`@1!$```````````!`2`@```````"BT@`@1!$`````````
+M`0!02B@``````````@`O`B0```````````S```````6N``"BOP`@1!$`````
+M```````@2`<`````@0`````@1!$``````````0`@2!$```````2BO@!@1!$`
+M``:*````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQ@`@
+M1!$````````````P2.D```````````#@``````6L``"BTP`@1!$`````````
+M``!`2`@```````"BTP`@1!$``````````0!02B@```````"BPP`@1!$`````
+M```````@2`<`````@0`````@1!$``````````0`@2!$```````2BP@!@1!$`
+M``:*````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQP`@
+M1!$````````````P2.D```````````#@``````6[``"BU``@1!$`````````
+M``!`2`@```````"BU``@1!$``````````0!02B@`````A0`````@1!$`````
+M```````@2`$````````P2@`@1!$``````0`````@2!$```````````!`````
+M``7!I````,`@1!$``````````,!`2````````````,!@``````7&`````,!`
+M!``````!````+``@-B$`````@0`````@1!$`````````!@`@2!$`````````
+M```O`C````````````S```````7-```````@!!$`````````,`!`-B$```7@
+M````,``@!BT```````!^```H!B$````````````O`B$```````````S@````
+M``7@@0`````@1!$``````````0`@2!$```````2@D@!@1!$```:*````,0`@
+M-C````````2@DP!@1!$```:*````,@`@-C````````2BM@!@1!$```:*````
+M,P`@-C````````2BN@!@1!$```:*````-``@-C````````2BO@!@1!$```:*
+M````-0`@-C````````2BP@!@1!$```:*````-@`@-C````````0@!`!@1!$`
+M``:*``&BI``@1!$`````````/P`@2!$`````````/P`@2!$`````````/P`@
+M2!$`````````/P`@2!$`````````!0`@2!$```````"A]``@1!$`````````
+M```@2!$`````B``````@1!$``````````0`@2!$`````@0`````@1!$`````
+M````!@`@2!$``````````0`O`C````````````S@``````8I````,``@!BT`
+M```````````O`B$```````````S@``````8I@0`````@1!$``````````0`@
+M2!$```````!^```H!B$````````````O`B$```````````S@``````8"``"@
+MD@`@1!$`````````,0`@2BT```````"@DP`@1!$`````````,@`@2BT`````
+M``"BM@`@1!$`````````,P`@2BT```````"BN@`@1!$`````````-``@2BT`
+M``````"BO@`@1!$`````````-0`@2BT```````"BP@`@1!$`````````-@`@
+M2BT`````````,``@!BT````````!_P`H!B$````````````O`B$`````````
+M``S@``````8H```````A`B$``````````!3```````8+``2@`P!@1!$```:*
+M``"@`P`@1!$````````````@2!```````````0`A!B$``````````!3`````
+M``80``2@$`!@1!$```:*``"@$``@1!$````````````@2!```````````0`A
+M!B$````````````O`B$```````````S@``````8H``2@$0!@1!$```:*``"@
+M$0`@1!$````````````@2!````````2@$@!@1!$```:*``"@$@`@1!$`````
+M```````@2!````````2@$P!@1!$```:*``"@$P`@1!$````````````@2!``
+M``````2@%`!@1!$```:*``"@%``@1!$````````````@2!````````2@%0!@
+M1!$```:*``"@%0`@1!$````````````@2!````````2@%@!@1!$```:*``"@
+M%@`@1!$````````````@2!````````2@%P!@1!$```:*``"@%P`@1!$`````
+M```````@2!````````0@!`!@1!$```:*````+`"`!BT`````_P`````@1!$`
+M```````````@2!$``````````0`@2!$``````````@"`2!$```````````[@
+M``````8Z````,``@!BT``````````@`H!B$````````````O`B$`````````
+M``S@``````8X@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:*
+M```0```@"!$`````````*P`@-B(```````````!@``````8^``````!@````
+M``7&F``````@1!$```````````"`2!$``````````,!@``````8^`````,!`
+M!``````!``"BI``@1!$`````````(@`@2!$`````B0`````@1!$`````````
+M`0!`2!$```8JEP`````@1!$````````````@2!$`````B@`````@1!$`````
+M``````!`2!$```8J``````!@``````99```@$``@1!$```````"````@2!$`
+M``````&BI,`@1!$`````````%@!@2!$```-N```@$``@1!$```````$````@
+M2!$`````@0`````@1!$``````````0`@2!$````````A?``@1!$`````"8``
+M```@2!$`````_____P`@2!$````````````@2!$``````````!<`````````
+M``0A?P!@1!$```:*````'P`A`C```````````!3`````````````!`!`3!$`
+M``93``````!`````````````%P`@'BT`````````!``I'B<`````````%P"`
+M-B<`````````%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````
+M%P`@'BT`````````"``I'B<`````````%P"`-B<`````````%P`@'BT`````
+M____]P`H'B<`````````%P"`-B<````````@$``@1!$```````"````@2!$`
+M``````&BI``@1!$`````````%@!@2!$```-N```@$``@1!$```````$````@
+M2!$````````A?``@1!$``````8`````@2!$`````_____P`@2!$`````````
+M```@2!$``````````!<`````````@0`````@1!$``````````0`@2!$`````
+M``0A?P!@1!$```:*````'P`A`C```````````!3```````:)````$`!`3!$`
+M``9O`````,`@!````````````#C`````````````'0`@"BT`````````'@`@
+M#BT`````````'P`@$BT`````````(``@%BT````````A:0`@1!$`````````
+M```@2`0````````````@2`4````````````@2`$`````ROZZO@`@2!$`````
+M````!``P$B0````````````O`&0```````````S```````:(`````P`H&B(`
+M````````"``B$B(`````___P```H$B0````````````I$,0`````````'P!`
+M-B0```````````"``````````````!K```````:*GP`````@1!$`````ROZZ
+MO@`@2!$``````````!K@``````:-``````"``````````````!K```````:/
+MG@`````@1!$`````ROZZO@`@2!$``````````!K@``````:2``````"`````
+M``````````!@```````+```0``!@!!$```,5```````@!!$```````````!@
+M"!$```&R```B7``@1!$``````````P`@2!$````````B5@`@1!$`````````
+M&P`@2!$```````"A_``@1!$``````````0`@2!$```````&A_<`@1!$`````
+M````(0`@'BT`````````$``B'B<`````````)``@(BT```````#__P`H(B@`
+M```````````I20<````````````@2!$`````````(@`@(BT```````#__P`H
+M(B@````````````I20<````````````@2!$`````````(P`@'BT`````````
+M$``B'B<````````````I20<```````````!`2!$`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4($_P6]`E```````<,!:`0_!;T``````B4"
+M"0)0`5$``````B,"10*@`D$``````]<%O06]!;T`````!D8&1P,?!;T`````
+M!;T%P@,@`T```````RH"@@-"`S0`````!;T%O06]!;T`````!;T%3@6]!;T`
+M`````[H%O02X`T0`````!)<$300]!;T`````!,T%O01!!-H`````!$T%!`-1
+M`W4`````!;T%O06]!;T`````!;T%O06]!;T`````!;T%O08\!<0`````!;T%
+MO0`'!;T`````!;T%O06]!;T`````!;T%O06]!;T``````_@#[00(!`8`````
+M!`X$"@0,!!``````!!P$&`0D!"``````!"P$*`0T!#``````!;T%O00X!;T`
+G````!;T%O06]!;T`````!;T%O06]!;T```````(&=@:4``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV630_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV630_pfp.bin.uu
new file mode 100644
index 0000000..77b299d
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV630_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RV630_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``;@`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8&H`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_\``$+`0`,)`"`'TE```U%`(`?34+`"54`P!\U8``)9P#`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`RA@``-1`
+M'@#5@!X`@`!3`-0`=0#40!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>
+M`-3`'@#5`!X`X@`>`,H$``"@````?H*+`,H(``#4@&``U$`>`(````#4@!X`
+MR@@``-2`80#40!X`@````-2`'@#*"```R@P``-1`'@#4@!8`U,`6`-2`'@"`
+M`;@`U,`>`,8(0P#*#```RA```)2`!`#*%```Y"#S`-0@$P#58&4`U.`<`-4@
+M'`#58!P`@`````8@`0#&"$,`R@P``,H0``"4@_<`RA0``.0@\P"``'D`U"`3
+M`,8(0P#*#```RA```)B#[P#*%```U`!D`(``C0``````Q!0R`,880P#$""\`
+ME4`%`,0,,`#40!X`@````.X`'@"5@_4`Q!`Q`-1`,P#5(&4`U*`<`-3@'`#5
+M(!P`Y`%>`-0`'@"`````!B`!`,H8```*(`$`U@!V`,0(-@"8@`<`QA!%`)4!
+M$`#4`!\`U&!B`(````#4(&(`S#@U`,P4,P"$`;L`U`!R`-5`'@"`````[@`>
+M`.(`&@"$`;L`X@`:`,P02P#,!$<`+)0!`'T)BP"80`4`?17+`-0`&@"``;@`
+MU`!M`#1$`0#,#$@`F$`Z`,PL2@"5@`0`S`1)`(`!N`#4`!H`U,`:`"@H`0"$
+M`/``S!`#`)B`&P`$.`P`A`#P`,P0`P"8@!<`!#@(`(0`\`#,$`,`F(`3``0X
+M!`"$`/``S!`#`)B`%`#,$$P`FH`)`,P430"80-P`U`!M`,P82`#5`!H`U4`:
+M`(``R0#5@!H`EL#5`-0`;0"``;@`U`!N`)K``P#4`&T`U`!N`(````#L`'\`
+MFL#,`-0`;0"``;@`U`!N`,P4`P#,&`,`S!P#`'V1`P!]U8,`?1D,`#7,'P`U
+M<!\`?/#+`'S0BP"(````?HZ+`)7`!`#4`&X`@`&X`-0`&@#4P!H`S`@#`,P,
+M`P#,$`,`S!0#`,P8`P#,'`,`S"0#`,PH`P`UQ!\`-K`?`'QP2P`T\!\`?'!+
+M`#5P'P!\<$L`?8B!`'W,P0!^40$`?I5!`'R0@@!\U,(`?(2+`)K``P!\C(L`
+M+(@!`)B`G@#4`&T`F$"<`-0`;@#,"$P`S`Q-`,P02`#4@!H`U,`:`(`!`0#5
+M`!H`S`@R`-0`,@"4@MD`R@P``-1`'@"`````U``>`.0!'@#4`!X`R@@``,H,
+M``#*$```U$`>`,H4``#4@!X`U,`>`-4`'@#50!X`U4`T`(````#N`!X`*`0$
+M`.(`&@#B`!H`U$`:`,HX``#,"`,`S`P#`,P,`P#,#`,`F(*]``````"$`;L`
+MUZ!O`(````#N`!\`R@0``,+_``#,"#0`P3__`'QTRP!\R0L`?0$/`)D"L`!\
+M<XL`A`&[`->@;P"`````[@`?`,H(```H&0``?8F+`)6`%``H%`0`R@P``,H0
+M``#*'```RB0``.(`'P#4P!H`U0`:`-5`&@#,&`,`S"P#`,PL`P#,+`,`?:6+
+M`'V<1P"80I<``````(`!80#4P!H`U$`>`-2`'@"`````[@`>`.0!'@#4`!X`
+MU$`>`.X`'@#*!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^
+M@HL`R@@``"2,!@`,S`8`F,`&`,P03@"9``0`U`!S`.0!'@#4`!X`U$`>`-2`
+M'@"`````[@`>`,H(``#*#```--`8`"40`0"5`"$`P7__`,H0``#*%```RA@`
+M`-2`'0#4P!T`?;&+`,%"`@#"P`$`U8`=`#3<#@!]74P`?W-,`-=`'@#5`!X`
+MU4`>`,%"``#"P```"9P!`#'<$`!_7TP`?W-,``0H`@!]@X``U:AO`-6`9@#7
+M0!X`[`!>`,@D`@#()`(`@`&X`-8`=@#40!X`U(`>`-3`'@"`````[@`>`(``
+M``#N`!\`U``?`(````#4`!\`U``?`(@```#4`!\`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%Q``(!>``#`(\`!`!_``4``P`&
+M`#\`!P`R``@!+``)`$8`"@`V`!`!M@`7`*(`(@$Z`",!20`@`+0`)`$E`"<`
+M30`H`&H`*@!@`"L`4@`O`&4`,@"'`#0!?P`\`58`/P!R`$$!C`!$`2X`50%S
+M`%8!>@!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`9P`X`&@`.@!I`$$`
+M:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@````&````!@````8````&````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV635_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV635_me.bin.uu
new file mode 100644
index 0000000..4156a1e
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV635_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RV635_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```:*``````!@``````8N
+M``````!@``````9"`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````9E``````!@``````99`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````9?``````!```````#K``````!@``````9B````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```:*````
+M'P`A`C```````````!3```````:)````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``:*````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````:)```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````9"``````!`!`\```(3``````!@``````8N``````!@``````9"```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````8N``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:*
+M``````!@``````8N`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````9E``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````9<````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP`````@1!$````````````@2!$`````B@`````@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`
+M`````````-D`2````````````,`@!`````````````"@``H````````B5P`@
+M1!$``````````\!(2B`````````B70`@1!$``````````,!`2```````````
+M``!@``````9"`````,`@"``````````B7``@1!$``````````P`X2B(`````
+M``"A_``@1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`
+M``````````S@`````````````$`@2````````````4`P2B```````````L`P
+M2B```````````0!3"B(```-+````/\`H"B``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````&``@2!$```````0A^0!@1!$```:*
+M````$0`A`C```````````!3@``````-4````%``O`B(```````````S`````
+M``-D```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!@
+M2`(```-N```A```@1!$``````````,`@2````````````,`@2```````````
+M`,`@2````````````,!`2```````````!``O`B(```````````S```````-J
+M```@$``@1!$```````"````@2!$```````&BI``@1!$```````````!`2`(`
+M``-?````*``O`B(```````````S```````6]``&BI``@1!$```````````!`
+M2`(```-?````+``@-B8`````````20`@&!$`````````/P`@2!$`````````
+M`0`S&B8````````````O`B8```````````S```````-P````+`"`&BT`````
+M````/\`H"B``````````%0`O`B(```````````S@``````.&````!@`O`B(`
+M``````````S@``````.Q````%@`O`B(```````````S@``````.U````(``O
+M`B(```````````S@``````.<````#P`O`B(```````````S@``````.H````
+M$``O`B(```````````S@``````.H````'@`O`B(```````````S@``````.0
+M``"BI``@1!$```````````!`2`(`````"``````I"B(``````````T`A#B``
+M````````#,`A$B````````@````H$B0`````````%,`B%B`````````````I
+M%*0```````"BI``@1!$````````````I2*(```````"A_@`@1!$`````````
+M``!`2`,`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````
+M````%@`@2!$```````0A^0!@1!$```:*````%0`A`C```````````!3@````
+M``.2```A#@`@1!$``````````,`@2````````````,`@2`````````"BI``@
+M1!$```````````!`2`(`````@0`````@1!$``````````0`@2!$````````A
+M^``@1!$`````````%P`@2!$```````0A^0!@1!$```:*`````P`A`C``````
+M`````!3@``````.>```A"``@1!$``````````,`@2````````````,`@2```
+M``````"BI``@1!$```````````!`2`(```````"BI``@1!$````````````@
+M2`(`````@``````@1!$````````````@2!$`````@0`````@1!$`````````
+M$``@2!$````````````@`!```````````!3```````.N``````!`````````
+M```@$``@1!$```````"````@2!$```````&BI``@1!$`````````!@!`2!$`
+M```````@$``@1!$```````"````@2!$```````&BI``@1!$`````````%@!@
+M2!$```-N``````!``````````````,`@"````````````,`@#```````````
+M'0`A`B,``````````!3@``````/.@0`````@1!$``````````0`@2!$`````
+M```A^``@1!$`````````&``@2!$```````0A^0!@1!$```:*````$0`A`C``
+M`````````!3@``````/````A```@1!$````````````@2`(````````````@
+M2`,`````NK[*_@`@2!$`````ROZZO@`@2!$````````@$``@1!$```````"`
+M```@2!$```````"BI``@1!$`````````!`!`2!$````````A<``@1!$`````
+M```````@2`(````````````@2`,`````@0`````@1!$`````````"@`@2!$`
+M```````````@`!```````````!3```````/3C``````@1!$`````ROZZO@!`
+M2!$`````@0`````@1!$``````````0`@2!$````````__T`H"B``````@```
+M`$`H#B``````0````,`H$B````````0```!I1B(```:*```````@%!``````
+M```````O`B,```````````S```````/A`````,!`&`````/D```__\`H&B``
+M``````0```!I1B8```:*```````@&!`````````````O`B0```````````S`
+M``````/G`````,!`'`````/J```__\`H'B````````0```!I1B<```:*````
+M```@'!`````````````@1`(````````````H(,4```````````!)2.@`````
+MI8`````@"!$````````@```@#!$`````@P````!@1!$```02```````@1`(`
+M`````````,`@2````````````$`@2```````````'\`A`B```````````!3`
+M``````/W```@$``@1!$```````"````@2!$```````#__\!($B````/_IX``
+M```@"!$```````"@```@#!$`````@P````!@1!$```02```````@1`(`````
+M`````,`@2````````````,`@2`````````#__\`H$B``````@P`````@1!$`
+M```````````P2(,`````A``````@1!$``````````,`@2````````````!T`
+M````````@P````!@1!$```02`````,!`!``````!J8`````@"!$```````#`
+M``!`#!$```/ZJX`````@"!$```````#XX`!`#!$```/ZK8`````@"!$`````
+M``#X@`!`#!$```/ZLX`````@"!$```````#S_`!`#!$```/ZKX`````@"!$`
+M``````#@``!`#!$```/ZL8`````@"!$```````#P``!`#!$```/Z@P`````@
+M1!$````````A2``@2!$`````A``````@1!$``````````,`@2```````````
+M`!T```````````````"``````````1@@`,`P1B```````````-D`2```````
+M`````,`@!`````````````"@``H``````AB@`,`P1B```````````-D`2```
+M`````````,`@!`````````````"@``H``````QC``,`P1B```````````-D`
+M2````````````,`@!`````````````"@``H`````!!CXX,`P1B``````````
+M`-D`2````````````,`@!`````````````"@``H`````!1CX@,`P1B``````
+M`````-D`2````````````,`@!`````````````"@``H`````!AC@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H`````!QCP`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H`````"!CS
+M_,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M````,``@"BT``````````,`I#$``````````,``@-B,``````````,`@!```
+M``````````"@``H`````A@`````@1!$```````````!`2`$`````A0```,`@
+M1!$```````````!`2`$````````A?``@1!$``````````,`@2```````````
+M`,`@2````````````,`@2```````@0`````@1!$``````````0`@2!$`````
+M`````,`@"````````````!<```````````0A?P!@1!$```:*````'P`A`C``
+M`````````!3```````````````!`3`(```1(`````,`@#````````````,`@
+M$````````````,`@%````````````,`@&````````````,`@'`````````!_
+M```H"B$```````!%```O`B(```````````S@``````16`````,`@(```````
+M`````!<`````````````$``H"B,`````````$``O`B(```````````S@````
+M``1>@0`````@1!$``````````0`@2!$```````0```!I1B0```:*``````!`
+M``````1C@0`````@1!$````````````@2!$````````A;0`@1!$`````````
+M```@2`0```````````!@2`4```:/```````H)/``````````!P`H"B,`````
+M`````0`O`B(```````````K@``````1J```````O`,D```````````3@````
+M``2#``````!```````20`````@`O`B(```````````K@``````1O```````O
+M`,D```````````+@``````2#``````!```````20`````P`O`B(`````````
+M``K@``````1T```````O`,D```````````S@``````2#``````!```````20
+M````!``O`B(```````````K@``````1Y```````O`,D```````````K@````
+M``2#``````!```````20````!0`O`B(```````````K@``````1^```````O
+M`,D```````````;@``````2#``````!```````20````!@`O`B(`````````
+M``K@``````2#```````O`,D```````````C@``````2#``````!```````20
+M``!_```H"B$```````!%```O`B(```````````K@````````````"``A"B,`
+M`````````!3```````2-```A:0`@1!$``````````,`@2````````````,`@
+M2````````````,`@2```````ROZZO@!`2!$``````````,`@1```````````
+M`,`@`````````````,!`2`````````!_```H"B$```````!%```O`B(`````
+M``````K@``````26`````,`@`````````````,`@`````````````,!`````
+M``````````!`3`@```16`````,`@"```````````$$`A#B``````````$4`A
+M$B``````````$D`A%B`````````A:0`@1!$````````````@2`(`````````
+M```A`B4``````````!3@``````2@``0``,!)2B````2A__O__\`H2B``````
+M```````A`B,``````````!3@``````2M`````,`@2````````````,`@2```
+M```````````A`B0``````````!3`````````@0`````@1!$`````````#``@
+M2!$````````````@`!```````````!3```````2IH``````@1!$`````ROZZ
+MO@!`2!$`````@0`````@1!$`````````!``@2!$````````A:P`@1!$`````
+M`````,`@2!``````@0`````@1!$`````````!0`@2!$````````A;``@1!$`
+M`````````,`@2!`````````````O`B0```````````S@``````````````!`
+M``````2G`````,`A"B```````````!3```````3`@0`````@1!$`````````
+M```@2!$````````A;0`@1!$``````````,`@2````````````,!@2`````:/
+M``````!```````3$@0`````@1!$``````````0`@2!$```````0``,`I1B``
+M`````````,!@``````:*`````0`A`B(``````````!3```````3+```A:0`@
+M1!$``````````,`@2````````````,`@2``````````````@2!``````ROZZ
+MO@!`2!$``````````,`@1````````````,!`2!``````@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````#@`@2!$```````0A^0!@1!$`
+M``:*```````A`C```````````!3```````3-```A@``@1!$``````````,`@
+M2````````````,`@`````````````,`@2````````````,`@````````````
+M`,!`2````````````P`S/B\``````````0`A`B$``````````!3@``````3]
+M````+``@"BT```````0``!C@#!$```3L`````0`S/B\````````A:0`@1!$`
+M```````````@2`(````````````@2`,`````````"``P"B(``````````,`@
+M2````````````,`@2``````````A:0`@1!$````````````@2`(`````````
+M```@2`,`````````"``P"B(``````````,`@2````````````-C`2`````3@
+M```A:0`@1!$````````````@2`(````````````@2`,`````````"``P"B(`
+M`````````,`@2````````````,`@2```````````+0`@$BT````````````I
+M#(,````````A:0`@1!$````````````@2`(````````````@2`,`````````
+M"``P"B(``````````,`@2````````````,`@2```````````$0`A`B0`````
+M`````!3```````````````!```````2G````+,`@-B``````````+<!`-B``
+M````````#P`A`B$``````````!3```````4"``````!@```````+`````-D`
+M`````````````,!`!``````!M0`````@1!$````````@```@2!$`````M@``
+M```@1!$```````"@```@2!$`````MP`````@1!$```````#````@2!$`````
+MN``````@1!$```````#XX``@2!$`````N0`````@1!$```````#X@``@2!$`
+M````N@`````@1!$```````#@```@2!$`````NP`````@1!$```````#P```@
+M2!$`````O``````@1!$```````#S_``@2!$`````@0`````@1!$`````````
+M`@`@2!$`````````_P`H#C`````````````O`B,```````````S```````46
+M`````,`@"````````````!3```````4K```````@#!$`````````'``@-B,`
+M````````*P`@-B,`````````*0`@-B,`````````*``@-B,`````````%P`@
+M-B,`````````)0`@-B,`````````)@`@-B,`````````%0`@-B,`````````
+M%@`@-B,`````___@```@#!$`````````(0`@-B,`````````(@`@-B,`````
+M```?_P`@#!$`````````(P`@-B,`````````)``@-B,`````\?___P`H.BX`
+M````````&L`B#B`````````````I.&X`````@0`````@1!$`````````!@`@
+M2!$`````````*D`@-B``````AP`````@1!$``````````,`@2`````````"A
+M]``@1!$````````````@2!`````````````@#!$`````````,``@-B,`````
+MG0`````@1!$`````````'T`A2B``````E@`````@1!$``````````,`@2```
+M`````````,`@#````````````,`@$```````````'P`A%B0``````````!3`
+M````````````'0`@-B,``````````P`H'B,`````````"``B(B,`````___P
+M```H(B@````````````I(.@`````````'P`@-B@`````````&``A'B,`````
+M````(``@-B<``````````@`B%B0````````````P%*@`````````'@`@-B4`
+M`````````P`A&B0`````$``````H&B8`````[____P`H.BX```````````!)
+M.,X```9X`````4`H"B``````````!D`H#B`````````#`,`H$B``````````
+M"``A$B0``````````,`@%B```````````,`@&B`````````````A`B(`````
+M`````!3```````5C@0`````@1!$``````````0`@2!$````````B6``P"B0`
+M``````0```!I1B(```:*```A:0`@1!$````````````@2`4```````(````I
+M2B8````````````@2!``````ROZZO@`@2!$``````````@`O`B,`````````
+M``S```````5K`````,`@'!```````````,!```````5Y`````@`O`B,`````
+M``````S```````5K@0`````@1!$``````````0`@2!$````````B6``P"B0`
+M``````0```!I1B(```:*`````,`@'!```````````,!```````5Y```````O
+M`B,```````````S```````5O`````,`@'````````````,!```````5Y````
+M!``O`B,```````````S```````5W@0`````@1!$````````````@2!$`````
+M```A;0`@1!$``````````,`@2````````````,!@2`````:/``````!`'!``
+M``5Y`````,`@`````````````,!```````````````[@``````5[``````!@
+M``````7&```````O`B0```````````S```````6,``"BMP`@1!$`````````
+M```@2`<`````@0`````@1!$``````````0`@2!$```````2BM@!@1!$```:*
+M````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQ``@1!$`
+M```````````P2.D```````````#@``````6*``"BT0`@1!$```````````!`
+M2`@```````"BT0`@1!$``````````0!02B@``````````0`O`B0`````````
+M``S```````6=``"BNP`@1!$````````````@2`<`````@0`````@1!$`````
+M`````0`@2!$```````2BN@!@1!$```:*````&@`A(C``````````!@`B)C``
+M``````0@!`!@1!$```:*``"BQ0`@1!$````````````P2.D```````````#@
+M``````6;``"BT@`@1!$```````````!`2`@```````"BT@`@1!$`````````
+M`0!02B@``````````@`O`B0```````````S```````6N``"BOP`@1!$`````
+M```````@2`<`````@0`````@1!$``````````0`@2!$```````2BO@!@1!$`
+M``:*````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQ@`@
+M1!$````````````P2.D```````````#@``````6L``"BTP`@1!$`````````
+M``!`2`@```````"BTP`@1!$``````````0!02B@```````"BPP`@1!$`````
+M```````@2`<`````@0`````@1!$``````````0`@2!$```````2BP@!@1!$`
+M``:*````&@`A(C``````````!@`B)C````````0@!`!@1!$```:*``"BQP`@
+M1!$````````````P2.D```````````#@``````6[``"BU``@1!$`````````
+M``!`2`@```````"BU``@1!$``````````0!02B@`````A0`````@1!$`````
+M```````@2`$````````P2@`@1!$``````0`````@2!$```````````!`````
+M``7!I````,`@1!$``````````,!`2````````````,!@``````7&`````,!`
+M!``````!````+``@-B$`````@0`````@1!$`````````!@`@2!$`````````
+M```O`C````````````S```````7-```````@!!$`````````,`!`-B$```7@
+M````,``@!BT```````!^```H!B$````````````O`B$```````````S@````
+M``7@@0`````@1!$``````````0`@2!$```````2@D@!@1!$```:*````,0`@
+M-C````````2@DP!@1!$```:*````,@`@-C````````2BM@!@1!$```:*````
+M,P`@-C````````2BN@!@1!$```:*````-``@-C````````2BO@!@1!$```:*
+M````-0`@-C````````2BP@!@1!$```:*````-@`@-C````````0@!`!@1!$`
+M``:*``&BI``@1!$`````````/P`@2!$`````````/P`@2!$`````````/P`@
+M2!$`````````/P`@2!$`````````!0`@2!$```````"A]``@1!$`````````
+M```@2!$`````B``````@1!$``````````0`@2!$`````@0`````@1!$`````
+M````!@`@2!$``````````0`O`C````````````S@``````8I````,``@!BT`
+M```````````O`B$```````````S@``````8I@0`````@1!$``````````0`@
+M2!$```````!^```H!B$````````````O`B$```````````S@``````8"``"@
+MD@`@1!$`````````,0`@2BT```````"@DP`@1!$`````````,@`@2BT`````
+M``"BM@`@1!$`````````,P`@2BT```````"BN@`@1!$`````````-``@2BT`
+M``````"BO@`@1!$`````````-0`@2BT```````"BP@`@1!$`````````-@`@
+M2BT`````````,``@!BT````````!_P`H!B$````````````O`B$`````````
+M``S@``````8H```````A`B$``````````!3```````8+``2@`P!@1!$```:*
+M``"@`P`@1!$````````````@2!```````````0`A!B$``````````!3`````
+M``80``2@$`!@1!$```:*``"@$``@1!$````````````@2!```````````0`A
+M!B$````````````O`B$```````````S@``````8H``2@$0!@1!$```:*``"@
+M$0`@1!$````````````@2!````````2@$@!@1!$```:*``"@$@`@1!$`````
+M```````@2!````````2@$P!@1!$```:*``"@$P`@1!$````````````@2!``
+M``````2@%`!@1!$```:*``"@%``@1!$````````````@2!````````2@%0!@
+M1!$```:*``"@%0`@1!$````````````@2!````````2@%@!@1!$```:*``"@
+M%@`@1!$````````````@2!````````2@%P!@1!$```:*``"@%P`@1!$`````
+M```````@2!````````0@!`!@1!$```:*````+`"`!BT`````_P`````@1!$`
+M```````````@2!$``````````0`@2!$``````````@"`2!$```````````[@
+M``````8Z````,``@!BT``````````@`H!B$````````````O`B$`````````
+M``S@``````8X@0`````@1!$``````````0`@2!$```````0@!`!@1!$```:*
+M```0```@"!$`````````*P`@-B(```````````!@``````8^``````!@````
+M``7&F``````@1!$```````````"`2!$``````````,!@``````8^`````,!`
+M!``````!``"BI``@1!$`````````(@`@2!$`````B0`````@1!$`````````
+M`0!`2!$```8JEP`````@1!$````````````@2!$`````B@`````@1!$`````
+M``````!`2!$```8J``````!@``````99```@$``@1!$```````"````@2!$`
+M``````&BI,`@1!$`````````%@!@2!$```-N```@$``@1!$```````$````@
+M2!$`````@0`````@1!$``````````0`@2!$````````A?``@1!$`````"8``
+M```@2!$`````_____P`@2!$````````````@2!$``````````!<`````````
+M``0A?P!@1!$```:*````'P`A`C```````````!3`````````````!`!`3!$`
+M``93``````!`````````````%P`@'BT`````````!``I'B<`````````%P"`
+M-B<`````````%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````
+M%P`@'BT`````````"``I'B<`````````%P"`-B<`````````%P`@'BT`````
+M____]P`H'B<`````````%P"`-B<````````@$``@1!$```````"````@2!$`
+M``````&BI``@1!$`````````%@!@2!$```-N```@$``@1!$```````$````@
+M2!$````````A?``@1!$``````8`````@2!$`````_____P`@2!$`````````
+M```@2!$``````````!<`````````@0`````@1!$``````````0`@2!$`````
+M``0A?P!@1!$```:*````'P`A`C```````````!3```````:)````$`!`3!$`
+M``9O`````,`@!````````````#C`````````````'0`@"BT`````````'@`@
+M#BT`````````'P`@$BT`````````(``@%BT````````A:0`@1!$`````````
+M```@2`0````````````@2`4````````````@2`$`````ROZZO@`@2!$`````
+M````!``P$B0````````````O`&0```````````S```````:(`````P`H&B(`
+M````````"``B$B(`````___P```H$B0````````````I$,0`````````'P!`
+M-B0```````````"``````````````!K```````:*GP`````@1!$`````ROZZ
+MO@`@2!$``````````!K@``````:-``````"``````````````!K```````:/
+MG@`````@1!$`````ROZZO@`@2!$``````````!K@``````:2``````"`````
+M``````````!@```````+```0``!@!!$```,5```````@!!$```````````!@
+M"!$```&R```B7``@1!$``````````P`@2!$````````B5@`@1!$`````````
+M&P`@2!$```````"A_``@1!$``````````0`@2!$```````&A_<`@1!$`````
+M````(0`@'BT`````````$``B'B<`````````)``@(BT```````#__P`H(B@`
+M```````````I20<````````````@2!$`````````(@`@(BT```````#__P`H
+M(B@````````````I20<````````````@2!$`````````(P`@'BT`````````
+M$``B'B<````````````I20<```````````!`2!$`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4($_P6]`E```````<,!:`0_!;T``````B4"
+M"0)0`5$``````B,"10*@`D$``````]<%O06]!;T`````!D8&1P,?!;T`````
+M!;T%P@,@`T```````RH"@@-"`S0`````!;T%O06]!;T`````!;T%3@6]!;T`
+M`````[H%O02X`T0`````!)<$300]!;T`````!,T%O01!!-H`````!$T%!`-1
+M`W4`````!;T%O06]!;T`````!;T%O06]!;T`````!;T%O08\!<0`````!;T%
+MO0`'!;T`````!;T%O06]!;T`````!;T%O06]!;T``````_@#[00(!`8`````
+M!`X$"@0,!!``````!!P$&`0D!"``````!"P$*`0T!#``````!;T%O00X!;T`
+G````!;T%O06]!;T`````!;T%O06]!;T```````(&=@:4``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV635_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV635_pfp.bin.uu
new file mode 100644
index 0000000..ce20634
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV635_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RV635_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``;@`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8&H`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_\``$+`0`,)`"`'TE```U%`(`?34+`"54`P!\U8``)9P#`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`RA@``-1`
+M'@#5@!X`@`!3`-0`=0#40!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>
+M`-3`'@#5`!X`X@`>`,H$``"@````?H*+`,H(``#4@&``U$`>`(````#4@!X`
+MR@@``-2`80#40!X`@````-2`'@#*"```R@P``-1`'@#4@!8`U,`6`-2`'@"`
+M`;@`U,`>`,8(0P#*#```RA```)2`!`#*%```Y"#S`-0@$P#58&4`U.`<`-4@
+M'`#58!P`@`````8@`0#&"$,`R@P``,H0``"4@_<`RA0``.0@\P"``'D`U"`3
+M`,8(0P#*#```RA```)B#[P#*%```U`!D`(``C0``````Q!0R`,880P#$""\`
+ME4`%`,0,,`#40!X`@````.X`'@"5@_4`Q!`Q`-1`,P#5(&4`U*`<`-3@'`#5
+M(!P`Y`%>`-0`'@"`````!B`!`,H8```*(`$`U@!V`,0(-@"8@`<`QA!%`)4!
+M$`#4`!\`U&!B`(````#4(&(`S#@U`,P4,P"$`;L`U`!R`-5`'@"`````[@`>
+M`.(`&@"$`;L`X@`:`,P02P#,!$<`+)0!`'T)BP"80`4`?17+`-0`&@"``;@`
+MU`!M`#1$`0#,#$@`F$`Z`,PL2@"5@`0`S`1)`(`!N`#4`!H`U,`:`"@H`0"$
+M`/``S!`#`)B`&P`$.`P`A`#P`,P0`P"8@!<`!#@(`(0`\`#,$`,`F(`3``0X
+M!`"$`/``S!`#`)B`%`#,$$P`FH`)`,P430"80-P`U`!M`,P82`#5`!H`U4`:
+M`(``R0#5@!H`EL#5`-0`;0"``;@`U`!N`)K``P#4`&T`U`!N`(````#L`'\`
+MFL#,`-0`;0"``;@`U`!N`,P4`P#,&`,`S!P#`'V1`P!]U8,`?1D,`#7,'P`U
+M<!\`?/#+`'S0BP"(````?HZ+`)7`!`#4`&X`@`&X`-0`&@#4P!H`S`@#`,P,
+M`P#,$`,`S!0#`,P8`P#,'`,`S"0#`,PH`P`UQ!\`-K`?`'QP2P`T\!\`?'!+
+M`#5P'P!\<$L`?8B!`'W,P0!^40$`?I5!`'R0@@!\U,(`?(2+`)K``P!\C(L`
+M+(@!`)B`G@#4`&T`F$"<`-0`;@#,"$P`S`Q-`,P02`#4@!H`U,`:`(`!`0#5
+M`!H`S`@R`-0`,@"4@MD`R@P``-1`'@"`````U``>`.0!'@#4`!X`R@@``,H,
+M``#*$```U$`>`,H4``#4@!X`U,`>`-4`'@#50!X`U4`T`(````#N`!X`*`0$
+M`.(`&@#B`!H`U$`:`,HX``#,"`,`S`P#`,P,`P#,#`,`F(*]``````"$`;L`
+MUZ!O`(````#N`!\`R@0``,+_``#,"#0`P3__`'QTRP!\R0L`?0$/`)D"L`!\
+M<XL`A`&[`->@;P"`````[@`?`,H(```H&0``?8F+`)6`%``H%`0`R@P``,H0
+M``#*'```RB0``.(`'P#4P!H`U0`:`-5`&@#,&`,`S"P#`,PL`P#,+`,`?:6+
+M`'V<1P"80I<``````(`!80#4P!H`U$`>`-2`'@"`````[@`>`.0!'@#4`!X`
+MU$`>`.X`'@#*!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^
+M@HL`R@@``"2,!@`,S`8`F,`&`,P03@"9``0`U`!S`.0!'@#4`!X`U$`>`-2`
+M'@"`````[@`>`,H(``#*#```--`8`"40`0"5`"$`P7__`,H0``#*%```RA@`
+M`-2`'0#4P!T`?;&+`,%"`@#"P`$`U8`=`#3<#@!]74P`?W-,`-=`'@#5`!X`
+MU4`>`,%"``#"P```"9P!`#'<$`!_7TP`?W-,``0H`@!]@X``U:AO`-6`9@#7
+M0!X`[`!>`,@D`@#()`(`@`&X`-8`=@#40!X`U(`>`-3`'@"`````[@`>`(``
+M``#N`!\`U``?`(````#4`!\`U``?`(@```#4`!\`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%Q``(!>``#`(\`!`!_``4``P`&
+M`#\`!P`R``@!+``)`$8`"@`V`!`!M@`7`*(`(@$Z`",!20`@`+0`)`$E`"<`
+M30`H`&H`*@!@`"L`4@`O`&4`,@"'`#0!?P`\`58`/P!R`$$!C`!$`2X`50%S
+M`%8!>@!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`9P`X`&@`.@!I`$$`
+M:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@````&````!@````8````&````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV670_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV670_me.bin.uu
new file mode 100644
index 0000000..ded47c2
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV670_me.bin.uu
@@ -0,0 +1,481 @@
+begin 644 RV670_me.bin
+M`````,`@!`````````````"@``H```````#__P`H1B$``````````-D`2```
+M`````````,`@!`````````````"@``H```````````#@``````````$``,`I
+M1B```````````-D`2````````````,`@!`````````````"@``H`````@0``
+M```@1!$``````````0`@2!$```````0@!`!@1!$```9\``````!@``````8D
+M``````!@``````8X`````,`@"``````````/```H%B(`````````"``A%B4`
+M````````&``@-B4`````C0`````@1!$`````````!``O`B4```````````S@
+M```````8`$$@``!`2!$````9`$(@```@2!$`````C@`````@1!$`````````
+M*``@2BT`````D``````@1!$````````````@2`4`````````#``A%B(`````
+M`````P`H%B4`````````&0`A&B(`````````!``H&B8````````````I%,4`
+M````````&0`@-B4````````````Z%`(`````````%@`A%B4``````````P`H
+M%B4`````````%P`@#BT`````_____``H#B,````````````I%*,`````````
+M%P`@-B4```````"````H#B(`````````!P`B#B,````````````I.&X`````
+M(``````H#B(`````````!@`A#B,````````````I.&X````````````B`B(`
+M`````````!3@```````X`````"[@```````U`````"S@```````W``````!`
+M#BT````Y````"``@#BT`````````"0!`$BT```!&`````0!`#BT````Y````
+M`,`@#````````#___``H$B,``````````@`B$B0`````````'P`A'B,`````
+M`````!3@```````^````"`!`'!$```!!````#0`@'BT`````````#P`H'B<`
+M`````````P`B'B<`````?\`````H&B,`````````%``A&B8``````````0`S
+M&B8`````````"``B&B8````````````I#,<`````````)P`@-B0```````!_
+M```H$B$````````4```O`B0```````````S@``````!+`````0`I#B,`````
+M````#@`@-B,```````#@```@1!$`````__@````I2B,````````````Z+`(`
+M`````````@`B#BL`````_``````H#B,`````````#P`@-B,````````?_P`I
+M2B,`````````)P`@2BT````````````@2!$`````````*0`@#BT`````!@H"
+M```I2B,````````````@2!$````````````@2!$``````````0`A`B(`````
+M`````!3@``````!A`````"[@``````!?`````"S@``````!>``````!`#BT`
+M``!B`````0!`#BT```!B````"@`@#BT`````````"P!`$BT```!J`````,`@
+M#````````#___``H$B,``````````@`B$B0`````?\`````H%B,`````````
+M%``A%B4``````````0`S%B4`````@``````H#B,````````````I#*,`````
+M/__\```I#B,`````````'P`A'B,``````````!3@``````!M```!``!`'!$`
+M``!P````#0`@'BT`````````\``H'B<`````````!``B'B<`````@0`````@
+M1!$`````````#0`@2!$`````___P_P`H&C````````"@*``@1!$`````````
+M```I2.8```````"@&``@1!$`````/____P`H2B,```````"@$``@1!$`````
+M```````@2`0`````````,``@%BT``````````@`I%B4`````````,``@-B4`
+M````````)0`@%BT````````````O`*,```````````S```````"#````)@`@
+M%BT````````````O`*0```````````S```````"$``````!```````"*````
+M)0`@-B,`````````)@`@-B0`````````%P`@'BT``````````@`A`B<`````
+M`````!3@``````"*``````!@``````99``````!@``````9-`````@`A#B(`
+M`````````!3```````"-````$L!`-B````"3`````"[@``````"1`````"S@
+M``````"0`````@!`#BT```"2`````P!`#BT```"2````#``@#BT`````````
+M$@`@-B,``````````P`A#B(``````````!3```````"8``"@#``@1!$`````
+M`````,`@2````````````,!`2`````"@``"@#``@1!$````````````@2!$`
+M`````````"[@``````">`````"S@``````"=`````@!`#BT```"?`````P!`
+M#BT```"?````#``@#BT````````````@2`,````````````Z#`(``````#\`
+M```H#B,`````````$``A#B,`````````$0`@-B,`````````'@`A`BL`````
+M`````!3```````"G````%L`@-B``````````'P`A`BL``````````!3`````
+M``"J````%<`@-B``````````"``A#BL`````````?P`H#B,````````````O
+M`B,```````````S@``````#A`````"<```````````````!@``````*C````
+M`0`O`B,```````````K@``````"S``````!@``````$Z@0`````@1!$`````
+M````!@`@2!$`````````#``B'C``````F8`````@1!$`````````!``@$BT`
+M````````"``B$B0`````````$``@&!$````````````I'.0```````````!@
+M2`<```$OFP`````@1!$````````````@2`(`````G``````@1!$`````````
+M```S%&\``````````0`S/B,``````````-D`2``````````````@/`4`````
+M@0`````@1!$`````````#@`@2!$````````````@$!````````#@!P`@1!$`
+M````````#P`A`BL``````````!3```````#+`/C_"``@2!$`````F`````!`
+M2!$```#<````\``H#B(`````````H``O`B,```````````S```````#:````
+M$0`@#BT``````````0`O`B,```````````S@``````#5`````@`O`B,`````
+M``````S@``````#4```_``!`#!$```#6```?``!`#!$```#6```/```@#!$`
+M`````#@`"0`I2B,`````/P`````H#BL``````````@`B#B,`````````!P!)
+M2B,```#<`#@/"0`@2!$`````:```!P`@2!$`````````"``A2B<`````````
+M```@2!$`````!@H"```I2B0````````````@2!$````````````@2!$`````
+M``"B`@`@1!$``````/\````H#B(`````````@``I2B,`````````)P`@#BT`
+M````````)@`@$BT````````````O`(,```````````S@``````#J``````!@
+M``````93``````!```````#K``````!@``````96````!P`@(BT`````````
+M!0`B#B(``````!`````H#B,````````````I(&@````````````Z#`(`````
+M````[P`H#B,````````````I(&@`````````%P`@#BT``````````P`A`B,`
+M`````````!3@``````#X````"P`A`B@``````````!3```````#X```$```I
+M(B@`````````%``@-B@`````````'``A#B(``````````!3```````#]``"C
+M#``@1!$````````````@2!$`````````'@`A#B(``````````!3```````$+
+M``"C#P`@1!$`````````$0`@#BT``````````0`O`B,```````````S`````
+M``$$_____P!`2!$```$+`````@`O`B,```````````S```````$'``#__P!`
+M2!$```$+````!``O`B,```````````S```````$*````_P!`2!$```$+````
+M`0`@2!$```````+$```@1!$`````````'P`A#B(``````````!3```````$2
+M````$$`A#B``````````$P`@-B,`````````&$`B2B``````````$,!"2B``
+M``$4```````@#!$`````````$P`@-B,````````````@2!$````````````@
+M2!$`````````"@`@$!$````````````O`B0```````````S@``````$;````
+M```@2!$``````````0!3$B0```$7_[___P`H.BX`````````&P`A`B(`````
+M`````!3```````$N@0`````@1!$`````````#0`@2!$`````````&``B#C``
+M````_``````H#B,`````@0`````@1!$`````````#@`@2!$````````````@
+M$!````````#@#@`@1!$`````!_C_"``@2!$````````````I2B,`````````
+M'``@'BT`````````"``A2B<````````````@2!$`````!@H"```I2B0`````
+M```````@2!$````````````@2!$```````````"`````````@0`````@1!$`
+M`````````0`@2!$````````A?``@1!$``````(`````@2!$````````````@
+M2`8`````````"``A2B<``````````!<```````````0A?P!@1!$```9\````
+M'P`A`C```````````!3```````9[````!`!`3!$```$U@0`````@1!$`````
+M`````0`@2!$````````A^``@1!$`````````'``@2!$```````0A^0!@1!$`
+M``9\````$0`A`C```````````!3@``````$\``````"```````````````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R````
+M``!@``````%@``#__T`H#B``````````$,`A$B````````#__T`H!B``````
+M````$,`A"B`````````````T%&$```````````!T&((```*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%'`````,!`!``````!``````!@
+M```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R```_
+M_P`O`B\```````````S@``````````````!@``````%@````$$`A#B``````
+M``#__\`H$B``````````$$`A%B````````#__\!H&B````*[``&A_0!@1!$`
+M``+@```__P`O`B\```````````S```````%8`````,!`!``````!```B7``@
+M1!$``````````0`P"B\``````````0`A"B(``````````P`X2B(````````B
+M5@`@1!$`````````&@`@2!$```````"A_``@1!$``````````0"`2!$`````
+M``````!@```````+``````!@``````&/``````!@``````&@```__P`O`B\`
+M``````````S@```````````````@+`@````````````@)!$````````````@
+M*!$````````B5@`@1!$`````````%@`@2!$````````B7``@1!$`````````
+M`P`@2!$`````DX`````@1!$``````````@`B'BD```````````!P2.L```&<
+M``````!@``````*[`````4`S!B```````````,`P)`D````````__P`O`B\`
+M``````````S@``````````````!@``````*C```````O`B$```````````K@
+M``````&!``````!@``````$Z``````!```````&&E0`````@1!$`````````
+M```O`B$```````````S@``````&&`````,`@2````````````0!3!B$```&"
+MD@`````@1!$``````````,!@2`````&7``&A_0`@1!$`````````$0`@!BT`
+M``````````!X!"H```+[```````@*`D````````__P`O`B\```````````S`
+M``````%T`````,!`!``````!```"$`!@!!$```,5```__P`O`B\`````````
+M``S@``````&4````%<`@-B``````````%L`@-B``````/X`````@!!$`````
+M1@````!@"!$```&R``````"```````````"A_``@1!$````````__P`O`B\`
+M``````````S```````&;`````0"`2!$`````````(0"`2!$```````#__T`H
+M#B``````````$,`A$B````````#__T`H%B``````````$,"!&B``````@0``
+M```@1!$`````````!@`@2!$`````````"``B'C``````````*0`@&BT`````
+M``#@```@1!$`````__O_"0`@2!$`````````#P`@(BT````````?_P`I2B@`
+M````````!@`@(BT````````````I(.@````````````@2`@````````````@
+M2!$`````!@H"```I2B8````````````@2!$````````````@2!$````````!
+M```@&!$`````````"`!B'B@```$O````"`""(B@```````+````@1!$`````
+M````%0!@#BT```&]````%@!@#BT```&]``#`"``@1!$`````````%P`@#BT`
+M`````````!3```````&Y```````@!!$````````````@2`$`````.0`````@
+M2!$````````````@2!$```````````"`2`(`````````&``@+BT`````````
+M```[#6,`````````"``B2B,`````````$``B2B,`````````&``B2B,`````
+M``````"`2`,```````````!@```````+```0``!@!!$```,5```````@!!$`
+M``````````!@"!$```&R````!P`A!B\`````````$P`@"BT``````````0`@
+M+!$```````#__T`H(B``````````#P`F(B@`````````$$`A)B``````````
+M#P`F)BD````````````@*`(````````B5@`@1!$`````````&P`@2!$`````
+M```````O`B$```````````S@``````'@```B7``@1!$`````````@0`@2!$`
+M``````"A_``@1!$``````````0`@2!$`````````@``@'!$````````````O
+M`B<```````````S@``````'<``````!@``````'I`````0!3'B<```'8````
+M`0`@+!$`````````'P`H"B(`````````'P`H*BH``````````0!3!B$```'1
+M```B7``@1!$``````````@`P2B\```````"A_``@1!$``````````0`@2!$`
+M`````````0`P'B\````````````O`B<```````````S@``````````````!@
+M``````'I`````0!3'B<```'E``#__T`H#B``````````#P`F#B,`````````
+M$,`A$B``````````#P`F$B0````````````@%!$```````````!@&!$```*[
+M``&A_0`@1!$````````````O`BL```````````S@``````'X````$``B%B@`
+M````__\````H%B4```````#__P`H&BD````````````I2,4````````````@
+M2`H````````````@+!$`````````$``B%B,`````__\````H%B4```````#_
+M_P`H&B0````````````I2,4```````````!S%0,```(%```````@&`4`````
+M``````!S%20```(%```````M%,4````````````P"*(````````````@2`(`
+M```````````@*`(````````````@(`,```````````"`)`0`````````#P`A
+M`B4``````````!3```````9[```````K%`4``````````0"0%B4`````````
+M``!@```````+``````!@!!$```,5```````@!!$```````````!@"!$```&R
+M```B5@`@1!$`````````&@`I2B(``````````,`@```````````__P`O`B\`
+M``````````S@`````````````,`@!``````````B7``@1!$``````````P`X
+M2B$```````"A_``@1!$``````````0`@2!$```````#__T`H$B``````````
+M$,`A&B````````#__T`H#B``````````$,`A%B````````````!T%&4```*[
+M``&A_0!@1!$```+@`````0`S!B$````````````O`B$```````````S`````
+M``(9```__P`O`B\```````````S```````(2`````,!`!``````!``````!@
+M``````8X``````!`!`\```(3``````!@``````8D``````!@``````8X```"
+M$`!@!!$```,5``````!@``````&@``````!@``````&<``````!@``````*[
+M``````!@``````*CDX`````@1!$````````````@2`@````````````O`B\`
+M``````````K@``````(R``````!@``````$Z``````!```````(VE0`````@
+M1!$````````````O`B\```````````S@``````(V`````,!`2`````(SD@``
+M```@1!$``````````,`@2``````````B5@`@1!$`````````%@`@2!$`````
+M```B7``@1!$``````````P`@2!$```````"A_``@1!$``````````0`@2!$`
+M``````&A_0`@1!$```````````!@!!$```+[`````,!`!``````!``````!@
+M``````8D``"@#``@1!$``````````,`@2````````````,!`2```````````
+M``!@```````+````&$`A"B```````````P`O`B(```````````K@``````),
+M````%``@(BT```````@!`0`I(B@`````````%``@-B@```````"C#``@1!$`
+M`````````,`@2````````````,`@2````````````,!`2`````)1``````!@
+M```````+````$`!@!!$```,5/X`````@!!$```````````!@"!$```&R```B
+M7``@1!$``````````P`@2!$```````````!@``````)\````%P`@'BT`````
+M`````0`A'B<``````````!3@``````)J````$@`@'BT```````#__P`H'B<`
+M```````````T'"<``````````!+```````)?```````@'!$````````````O
+M`.4```````````C```````)B```````@%`<`````````$@`@'BT`````````
+M$``A'B<````````````T'$<``````````!+```````)G```````@'!$`````
+M```````O`.8```````````C```````)J```````@&`<```````````!@````
+M``+!```B5@`@1!$````````````T(",``````````!+```````)R```````T
+M($0``````````!+```````)Q````%@!`2!$```)V````&`!`2!$```)V````
+M```T($0``````````!+```````)U````%P!`2!$```)V````&0`@2!$`````
+M``"A_``@1!$``````````0`@2!$```````&A_0!@1!$```+I```__P`O`B\`
+M``````````S```````)6`````,!`!``````!````$$`A!B````````#__\`H
+M"B``````````$$`A#B````````#__\`H$B``````````$$`A%B````````#_
+M_\"(&B``````@0`````@1!$``````````0`@2!$```````0@!`!@1!$```9\
+M``````!@``````8D`````,!@``````*C````!0`@"BT`````````"``B"B(`
+M````````*P`@&BT`````````'``@'BT```````!P```H'B<````````````Q
+M'.8`````````*@`@&BT`````````#``B&B8````````````O`.8`````````
+M``;@``````*2```````@'!$````````````@#!$`````````*P`@-B,`````
+M````$``@&!$```````````!I'.(```$ODX`````@1!$````````````@2`<`
+M````E0`````@1!$````````````O`B\```````````S@``````*=`````0`S
+M/B\``````````-D`2```````D@`````@1!$``````````,`@2```````````
+M'`!`-B<`````````#,`B"B``````````*0`@-B(`````````*,!`-B``````
+M``"BI``@1!$`````````"0`@2!$`````H0`````@1!$``````````0"`2!$`
+M````````(0`@'BT````````````L'.,`````````(0`@-B<`````````(@`@
+M'BT````````````L'.0`````````(@`@-B<`````````(P`@'BT`````````
+M```Q(*,````````````M'0<`````````(P`@-B<`````````)``@'BT`````
+M```````Q(,0````````````M'0<`````````)`"`-B<`````````(0`@-B,`
+M````````(@`@-B0````````````Q'*,`````````(P`@-B<````````````Q
+M',0`````````)`"`-B<`````````&@`@-B<`````````&P`@-B@`````````
+M%P`@'BT``````````@`A`B<``````````!3```````+<``````!```````+9
+M````&@`@-B<`````````&P`@-B@`````````%P`@'BT``````````@`A`B<`
+M`````````!3@``````+9`````P`A`B<``````````!3@``````+<````(P`@
+M'BT````````````N`.$```````````+```````+<````(0`@'BT`````````
+M```Q(*$````````````N`.@```````````;```````+<````)``@'BT`````
+M```````N`.(```````````+```````+<````(@`@'BT````````````Q(,(`
+M```````````N`.@```````````;```````+<``````!@``````99``````!@
+M``````*U``````!```````+>``````!@``````*U``````!@``````90````
+M``!```````+>``````!@``````*G``````!```````+>````&@`@'BT`````
+M````&P"`(BT`````````$``B'B,````````````I2(<````````````Q'*,`
+M````````$``B'B<````````````I2(<`````````$``B'B,````````````Q
+M(,0```````#__P`H(B@```````````")20<`````````$``B'B,`````````
+M```I2(<`````````$``B'B$````````````I2$<````````````Q'*,`````
+M````$``B'B<````````````I2(<````````````Q'*$`````````$``B'B<`
+M```````````I2$<`````````$``B'B,````````````Q(,0```````#__P`H
+M(B@````````````I20<`````````$``B'B$````````````Q(,(```````#_
+M_P`H(B@```````````")20<`````````$``B'B,````````````I2(<`````
+M`````0`B"B$````````````S"*(`````````$``B'B(`````````$``A(B(`
+M```````````I20<````````````Q'*,`````````$``B'B<````````````I
+M2(<``````````0`B"B$````````````P"*(`````````$``B'B(`````````
+M$``A(B(````````````I20<`````````$``B'B,````````````Q(,0`````
+M``#__P`H(B@````````````I20<````````````X",4````````````P"$$`
+M`````````0`B"B(````````````S"*(`````````$``B'B(`````````$``A
+M(B(```````````")20<`````````%P`@(BT``````````!3```````,8____
+M[P`H!B$`````````%``@(BT```````#XX``@1!$````````````I20$`````
+M``````")20$````````````@2!$````````````@2!$`````!@H"``"`2!$`
+M`````````,`@````````EP```,`@1!$``````````,`@2!$`````B@`````@
+M1!$````````````@2!$````````B7``@1!$``````````,`@2`````````"A
+M_``@1!$``````````,`@2````````````,`@!`````````````"@``H`````
+MEP`````@1!$````````````@2!$`````B@`````@1!$````````````@2!$`
+M```````B7``@1!$``````````,`@2`````````"A_``@1!$``````````,`@
+M2````````````,`@!`````````````"@``H`````EP`````@1!$`````````
+M```@2!$`````B@`````@1!$````````````@2!$````````B7``@1!$`````
+M`````,`@2`````````"A_``@1!$``````````,`@2`````````&A_0`@1!$`
+M`````````-D`2````````````,`@!`````````````"@``H````````B5P`@
+M1!$``````````\!(2B`````````B70`@1!$``````````,!`2```````````
+M``!@``````8X`````,`@"``````````B7``@1!$``````````P`X2B(`````
+M``"A_``@1!$``````````,`@2`````````&A_0`@1!$````````````O`B(`
+M``````````S@`````````````$`@2````````````4`P2B```````````L`P
+M2B```````````0!3"B(```-+````/\`H"B``````@0`````@1!$`````````
+M`0`@2!$````````A^``@1!$`````````&``@2!$```````0A^0!@1!$```9\
+M````$0`A`C```````````!3@``````-4````%``O`B(```````````S`````
+M``-B``&BI``@1!$```````````!@2`(```-J```A```@1!$``````````,`@
+M2````````````,`@2````````````,`@2````````````,!`2```````````
+M!``O`B(```````````S```````-F``&BI``@1!$```````````!`2`(```-=
+M````*``O`B(```````````S```````6S``&BI``@1!$```````````!`2`(`
+M``-=````+``@-B8`````````20`@&!$`````````/P`@2!$``````````0`S
+M&B8````````````O`B8```````````S```````-L````+`"`&BT`````````
+M/\`H"B``````````%0`O`B(```````````S@``````."````!@`O`B(`````
+M``````S@``````.M````%@`O`B(```````````S@``````.O````(``O`B(`
+M``````````S@``````.8````#P`O`B(```````````S@``````.D````$``O
+M`B(```````````S@``````.D````'@`O`B(```````````S@``````.,``"B
+MI``@1!$```````````!`2`(`````"``````I"B(``````````T`A#B``````
+M````#,`A$B````````@````H$B0`````````%,`B%B`````````````I%*0`
+M``````"BI``@1!$````````````I2*(```````"A_@`@1!$```````````!`
+M2`,`````@0`````@1!$``````````0`@2!$````````A^``@1!$`````````
+M%@`@2!$```````0A^0!@1!$```9\````%0`A`C```````````!3@``````..
+M```A#@`@1!$``````````,`@2````````````,`@2`````````"BI``@1!$`
+M``````````!`2`(`````@0`````@1!$``````````0`@2!$````````A^``@
+M1!$`````````%P`@2!$```````0A^0!@1!$```9\`````P`A`C``````````
+M`!3@``````.:```A"``@1!$``````````,`@2````````````,`@2```````
+M``"BI``@1!$```````````!`2`(```````"BI``@1!$````````````@2`(`
+M````@``````@1!$````````````@2!$`````@0`````@1!$`````````$``@
+M2!$````````````@`!```````````!3```````.J``````!```````````&B
+MI``@1!$`````````!@!`2!$```````&BI``@1!$`````````%@!@2!$```-J
+M``````!``````````````,`@"````````````,`@#```````````'0`A`B,`
+M`````````!3@``````/$@0`````@1!$``````````0`@2!$````````A^``@
+M1!$`````````&``@2!$```````0A^0!@1!$```9\````$0`A`C``````````
+M`!3@``````.X```A```@1!$````````````@2`(````````````@2`,`````
+MNK[*_@`@2!$`````ROZZO@`@2!$```````"BI``@1!$`````````!`!`2!$`
+M```````A<``@1!$````````````@2`(````````````@2`,`````@0`````@
+M1!$`````````"@`@2!$````````````@`!```````````!3```````/)C```
+M```@1!$`````ROZZO@!`2!$`````@0`````@1!$``````````0`@2!$`````
+M```__T`H"B``````@````$`H#B``````0````,`H$B````````0```!I1B(`
+M``9\```````@%!`````````````O`B,```````````S```````/7`````,!`
+M&`````/:```__\`H&B````````0```!I1B8```9\```````@&!``````````
+M```O`B0```````````S```````/=`````,!`'`````/@```__\`H'B``````
+M``0```!I1B<```9\```````@'!`````````````@1`(````````````H(,4`
+M``````````!)2.@`````I8`````@"!$````````@```@#!$`````@P````!@
+M1!$```0(```````@1`(``````````,`@2````````````$`@2```````````
+M'\`A`B```````````!3```````/M```@$``@1!$```````"````@2!$`````
+M``#__\!($B````/UIX`````@"!$```````"@```@#!$`````@P````!@1!$`
+M``0(```````@1`(``````````,`@2````````````,`@2`````````#__\`H
+M$B``````@P`````@1!$````````````P2(,`````A``````@1!$`````````
+M`,`@2````````````!T`````````@P````!@1!$```0(`````,!`!``````!
+MJ8`````@"!$```````#```!`#!$```/PJX`````@"!$```````#XX`!`#!$`
+M``/PK8`````@"!$```````#X@`!`#!$```/PLX`````@"!$```````#S_`!`
+M#!$```/PKX`````@"!$```````#@``!`#!$```/PL8`````@"!$```````#P
+M``!`#!$```/P@P`````@1!$````````A2``@2!$`````A``````@1!$`````
+M`````,`@2````````````!T```````````````"``````````1@@`,`P1B``
+M`````````-D`2````````````,`@!`````````````"@``H``````AB@`,`P
+M1B```````````-D`2````````````,`@!`````````````"@``H``````QC`
+M`,`P1B```````````-D`2````````````,`@!`````````````"@``H`````
+M!!CXX,`P1B```````````-D`2````````````,`@!`````````````"@``H`
+M````!1CX@,`P1B```````````-D`2````````````,`@!`````````````"@
+M``H`````!AC@`,`P1B```````````-D`2````````````,`@!```````````
+M``"@``H`````!QCP`,`P1B```````````-D`2````````````,`@!```````
+M``````"@``H`````"!CS_,`P1B```````````-D`2````````````,`@!```
+M``````````"@``H`````````,``@"BT``````````,`I#$``````````,``@
+M-B,``````````,`@!`````````````"@``H`````A@`````@1!$`````````
+M``!`2`$`````A0```,`@1!$```````````!`2`$````````A?``@1!$`````
+M`````,`@2````````````,`@2````````````,`@2```````@0`````@1!$`
+M`````````0`@2!$``````````,`@"````````````!<```````````0A?P!@
+M1!$```9\````'P`A`C```````````!3```````````````!`3`(```0^````
+M`,`@#````````````,`@$````````````,`@%````````````,`@&```````
+M`````,`@'`````````!_```H"B$```````!%```O`B(```````````S@````
+M``1,`````,`@(````````````!<`````````````$``H"B,`````````$``O
+M`B(```````````S@``````14@0`````@1!$``````````0`@2!$```````0`
+M``!I1B0```9\``````!```````19@0`````@1!$````````````@2!$`````
+M```A;0`@1!$````````````@2`0```````````!@2`4```:!```````H)/``
+M````````!P`H"B,``````````0`O`B(```````````K@``````1@```````O
+M`,D```````````3@``````1Y``````!```````2&`````@`O`B(`````````
+M``K@``````1E```````O`,D```````````+@``````1Y``````!```````2&
+M`````P`O`B(```````````K@``````1J```````O`,D```````````S@````
+M``1Y``````!```````2&````!``O`B(```````````K@``````1O```````O
+M`,D```````````K@``````1Y``````!```````2&````!0`O`B(`````````
+M``K@``````1T```````O`,D```````````;@``````1Y``````!```````2&
+M````!@`O`B(```````````K@``````1Y```````O`,D```````````C@````
+M``1Y``````!```````2&``!_```H"B$```````!%```O`B(```````````K@
+M````````````"``A"B,``````````!3```````2#```A:0`@1!$`````````
+M`,`@2````````````,`@2````````````,`@2```````ROZZO@!`2!$`````
+M`````,`@1````````````,`@`````````````,!`2`````````!_```H"B$`
+M``````!%```O`B(```````````K@``````2,`````,`@`````````````,`@
+M`````````````,!```````````````!`3`@```1,`````,`@"```````````
+M$$`A#B``````````$4`A$B``````````$D`A%B`````````A:0`@1!$`````
+M```````@2`(````````````A`B4``````````!3@``````26``0``,!)2B``
+M``27__O__\`H2B`````````````A`B,``````````!3@``````2C`````,`@
+M2````````````,`@2``````````````A`B0``````````!3`````````@0``
+M```@1!$`````````#``@2!$````````````@`!```````````!3```````2?
+MH``````@1!$`````ROZZO@!`2!$`````@0`````@1!$`````````!``@2!$`
+M```````A:P`@1!$``````````,`@2!``````@0`````@1!$`````````!0`@
+M2!$````````A;``@1!$``````````,`@2!`````````````O`B0`````````
+M``S@``````````````!```````2=`````,`A"B```````````!3```````2V
+M@0`````@1!$````````````@2!$````````A;0`@1!$``````````,`@2```
+M`````````,!@2`````:!``````!```````2Z@0`````@1!$``````````0`@
+M2!$```````0``,`I1B```````````,!@``````9\`````0`A`B(`````````
+M`!3```````3!```A:0`@1!$``````````,`@2````````````,`@2```````
+M```````@2!``````ROZZO@!`2!$``````````,`@1````````````,!`2!``
+M````@0`````@1!$``````````0`@2!$````````A^``@1!$`````````#@`@
+M2!$```````0A^0!@1!$```9\```````A`C```````````!3```````3#```A
+M@``@1!$``````````,`@2````````````,`@`````````````,`@2```````
+M`````,`@`````````````,!`2````````````P`S/B\``````````0`A`B$`
+M`````````!3@``````3S````+``@"BT```````0``!C@#!$```3B`````0`S
+M/B\````````A:0`@1!$````````````@2`(````````````@2`,`````````
+M"``P"B(``````````,`@2````````````,`@2``````````A:0`@1!$`````
+M```````@2`(````````````@2`,`````````"``P"B(``````````,`@2```
+M`````````-C`2`````36```A:0`@1!$````````````@2`(````````````@
+M2`,`````````"``P"B(``````````,`@2````````````,`@2```````````
+M+0`@$BT````````````I#(,````````A:0`@1!$````````````@2`(`````
+M```````@2`,`````````"``P"B(``````````,`@2````````````,`@2```
+M````````$0`A`B0``````````!3```````````````!```````2=````+,`@
+M-B``````````+<!`-B``````````#P`A`B$``````````!3```````3X````
+M``!@```````+`````-D``````````````,!`!``````!M0`````@1!$`````
+M```@```@2!$`````M@`````@1!$```````"@```@2!$`````MP`````@1!$`
+M``````#````@2!$`````N``````@1!$```````#XX``@2!$`````N0`````@
+M1!$```````#X@``@2!$`````N@`````@1!$```````#@```@2!$`````NP``
+M```@1!$```````#P```@2!$`````O``````@1!$```````#S_``@2!$`````
+M@0`````@1!$``````````@`@2!$`````````_P`H#C`````````````O`B,`
+M``````````S```````4,`````,`@"````````````!3```````4A```````@
+M#!$`````````'``@-B,`````````*P`@-B,`````````*0`@-B,`````````
+M*``@-B,`````````%P`@-B,`````````)0`@-B,`````````)@`@-B,`````
+M````%0`@-B,`````````%@`@-B,`````___@```@#!$`````````(0`@-B,`
+M````````(@`@-B,````````?_P`@#!$`````````(P`@-B,`````````)``@
+M-B,`````\?___P`H.BX`````````&L`B#B`````````````I.&X`````@0``
+M```@1!$`````````!@`@2!$`````````*D`@-B``````AP`````@1!$`````
+M`````,`@2`````````"A]``@1!$````````````@2!`````````````@#!$`
+M````````,``@-B,`````G0`````@1!$`````````'T`A2B``````E@`````@
+M1!$``````````,`@2````````````,`@#````````````,`@$```````````
+M'P`A%B0``````````!3`````````````'0`@-B,``````````P`H'B,`````
+M````"``B(B,`````___P```H(B@````````````I(.@`````````'P`@-B@`
+M````````&``A'B,`````````(``@-B<``````````@`B%B0````````````P
+M%*@`````````'@`@-B4``````````P`A&B0`````$``````H&B8`````[___
+M_P`H.BX```````````!).,X```9J`````4`H"B``````````!D`H#B``````
+M```#`,`H$B``````````"``A$B0``````````,`@%B```````````,`@&B``
+M```````````A`B(``````````!3```````59@0`````@1!$``````````0`@
+M2!$````````B6``P"B0```````0```!I1B(```9\```A:0`@1!$`````````
+M```@2`4```````(````I2B8````````````@2!``````ROZZO@`@2!$`````
+M`````@`O`B,```````````S```````5A`````,`@'!```````````,!`````
+M``5O`````@`O`B,```````````S```````5A@0`````@1!$``````````0`@
+M2!$````````B6``P"B0```````0```!I1B(```9\`````,`@'!``````````
+M`,!```````5O```````O`B,```````````S```````5E`````,`@'```````
+M`````,!```````5O````!``O`B,```````````S```````5M@0`````@1!$`
+M```````````@2!$````````A;0`@1!$``````````,`@2````````````,!@
+M2`````:!``````!`'!````5O`````,`@`````````````,!`````````````
+M``[@``````5Q``````!@``````6\```````O`B0```````````S```````6"
+M``"BMP`@1!$````````````@2`<`````@0`````@1!$``````````0`@2!$`
+M``````2BM@!@1!$```9\````&@`A(C``````````!@`B)C````````0@!`!@
+M1!$```9\``"BQ``@1!$````````````P2.D```````````#@``````6```"B
+MT0`@1!$```````````!`2`@```````"BT0`@1!$``````````0!02B@`````
+M`````0`O`B0```````````S```````63``"BNP`@1!$````````````@2`<`
+M````@0`````@1!$``````````0`@2!$```````2BN@!@1!$```9\````&@`A
+M(C``````````!@`B)C````````0@!`!@1!$```9\``"BQ0`@1!$`````````
+M```P2.D```````````#@``````61``"BT@`@1!$```````````!`2`@`````
+M``"BT@`@1!$``````````0!02B@``````````@`O`B0```````````S`````
+M``6D``"BOP`@1!$````````````@2`<`````@0`````@1!$``````````0`@
+M2!$```````2BO@!@1!$```9\````&@`A(C``````````!@`B)C````````0@
+M!`!@1!$```9\``"BQ@`@1!$````````````P2.D```````````#@``````6B
+M``"BTP`@1!$```````````!`2`@```````"BTP`@1!$``````````0!02B@`
+M``````"BPP`@1!$````````````@2`<`````@0`````@1!$``````````0`@
+M2!$```````2BP@!@1!$```9\````&@`A(C``````````!@`B)C````````0@
+M!`!@1!$```9\``"BQP`@1!$````````````P2.D```````````#@``````6Q
+M``"BU``@1!$```````````!`2`@```````"BU``@1!$``````````0!02B@`
+M````A0`````@1!$````````````@2`$````````P2@`@1!$``````0`````@
+M2!$```````````!```````6WI````,`@1!$``````````,!`2```````````
+M`,!@``````6\`````,!`!``````!````+``@-B$`````@0`````@1!$`````
+M````!@`@2!$````````````O`C````````````S```````7#```````@!!$`
+M````````,`!`-B$```76````,``@!BT```````!^```H!B$````````````O
+M`B$```````````S@``````76@0`````@1!$``````````0`@2!$```````2@
+MD@!@1!$```9\````,0`@-C````````2@DP!@1!$```9\````,@`@-C``````
+M``2BM@!@1!$```9\````,P`@-C````````2BN@!@1!$```9\````-``@-C``
+M``````2BO@!@1!$```9\````-0`@-C````````2BP@!@1!$```9\````-@`@
+M-C````````0@!`!@1!$```9\``&BI``@1!$`````````/P`@2!$`````````
+M/P`@2!$`````````/P`@2!$`````````/P`@2!$`````````!0`@2!$`````
+M``"A]``@1!$````````````@2!$`````B``````@1!$``````````0`@2!$`
+M````@0`````@1!$`````````!@`@2!$``````````0`O`C````````````S@
+M``````8?````,``@!BT````````````O`B$```````````S@``````8?@0``
+M```@1!$``````````0`@2!$```````!^```H!B$````````````O`B$`````
+M``````S@``````7X``"@D@`@1!$`````````,0`@2BT```````"@DP`@1!$`
+M````````,@`@2BT```````"BM@`@1!$`````````,P`@2BT```````"BN@`@
+M1!$`````````-``@2BT```````"BO@`@1!$`````````-0`@2BT```````"B
+MP@`@1!$`````````-@`@2BT`````````,``@!BT````````!_P`H!B$`````
+M```````O`B$```````````S@``````8>```````A`B$``````````!3`````
+M``8!``2@`P!@1!$```9\``"@`P`@1!$````````````@2!```````````0`A
+M!B$``````````!3```````8&``2@$`!@1!$```9\``"@$``@1!$`````````
+M```@2!```````````0`A!B$````````````O`B$```````````S@``````8>
+M``2@$0!@1!$```9\``"@$0`@1!$````````````@2!````````2@$@!@1!$`
+M``9\``"@$@`@1!$````````````@2!````````2@$P!@1!$```9\``"@$P`@
+M1!$````````````@2!````````2@%`!@1!$```9\``"@%``@1!$`````````
+M```@2!````````2@%0!@1!$```9\``"@%0`@1!$````````````@2!``````
+M``2@%@!@1!$```9\``"@%@`@1!$````````````@2!````````2@%P!@1!$`
+M``9\``"@%P`@1!$````````````@2!````````0@!`!@1!$```9\````+`"`
+M!BT`````_P`````@1!$````````````@2!$``````````0`@2!$`````````
+M`@"`2!$```````````[@``````8P````,``@!BT``````````@`H!B$`````
+M```````O`B$```````````S@``````8N@0`````@1!$``````````0`@2!$`
+M``````0@!`!@1!$```9\```0```@"!$`````````*P`@-B(```````````!@
+M``````8T``````!@``````6\F``````@1!$```````````"`2!$`````````
+M`,!@``````8T`````,!`!``````!``"BI``@1!$`````````(@`@2!$`````
+MB0`````@1!$``````````0!`2!$```8@EP`````@1!$````````````@2!$`
+M````B@`````@1!$```````````!`2!$```8@``````!@``````9-``&BI,`@
+M1!$`````````%@!@2!$```-J```@$``@1!$```````$````@2!$`````@0``
+M```@1!$``````````0`@2!$````````A?``@1!$`````"8`````@2!$`````
+M_____P`@2!$````````````@2!$``````````!<```````````0A?P!@1!$`
+M``9\````'P`A`C```````````!3`````````````!`!`3!$```9'``````!`
+M````````````%P`@'BT`````````!``I'B<`````````%P"`-B<`````````
+M%P`@'BT`````____^P`H'B<`````````%P"`-B<`````````%P`@'BT`````
+M````"``I'B<`````````%P"`-B<`````````%P`@'BT`````____]P`H'B<`
+M````````%P"`-B<```````&BI``@1!$`````````%@!@2!$```-J```@$``@
+M1!$```````$````@2!$````````A?``@1!$``````8`````@2!$`````____
+M_P`@2!$````````````@2!$``````````!<`````````@0`````@1!$`````
+M`````0`@2!$```````0A?P!@1!$```9\````'P`A`C```````````!3`````
+M``9[````$`!`3!$```9A`````,`@!````````````#C`````````````'0`@
+M"BT`````````'@`@#BT`````````'P`@$BT`````````(``@%BT````````A
+M:0`@1!$````````````@2`0````````````@2`4````````````@2`$`````
+MROZZO@`@2!$`````````!``P$B0````````````O`&0```````````S`````
+M``9Z`````P`H&B(`````````"``B$B(`````___P```H$B0````````````I
+M$,0`````````'P!`-B0```````````"``````````````!K```````9\GP``
+M```@1!$`````ROZZO@`@2!$``````````!K@``````9_``````"`````````
+M`````!K```````:!G@`````@1!$`````ROZZO@`@2!$``````````!K@````
+M``:$``````"```````````````!@```````+```0``!@!!$```,5```````@
+M!!$```````````!@"!$```&R```B7``@1!$``````````P`@2!$````````B
+M5@`@1!$`````````&P`@2!$```````"A_``@1!$``````````0`@2!$`````
+M``&A_<`@1!$`````````(0`@'BT`````````$``B'B<`````````)``@(BT`
+M``````#__P`H(B@````````````I20<````````````@2!$`````````(@`@
+M(BT```````#__P`H(B@````````````I20<````````````@2!$`````````
+M(P`@'BT`````````$``B'B<````````````I20<```````````!`2!$`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````4($]06S`E```````<,!:`0U!;,``````B4"
+M"0)0`5$``````B,"10*@`D$``````\T%LP6S!;,`````!CP&/0,?!;,`````
+M!;,%N`,@`T```````RH"@@-"`S0`````!;,%LP6S!;,`````!;,%1`6S!;,`
+M`````[(%LP2N`T0`````!(T$0P0S!;,`````!,,%LP0W!-``````!$,$^@-1
+M`W$`````!;,%LP6S!;,`````!;,%LP6S!;,`````!;,%LP8R!;H`````!;,%
+MLP`'!;,`````!;,%LP6S!;,`````!;,%LP6S!;,``````^X#XP/^`_P`````
+M!`0$``0"!`8`````!!($#@0:!!8`````!"($'@0J!"8`````!;,%LP0N!;,`
+G````!;,%LP6S!;,`````!;,%LP6S!;,```````(&:`:&``8`````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV670_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV670_pfp.bin.uu
new file mode 100644
index 0000000..cb6a852
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV670_pfp.bin.uu
@@ -0,0 +1,55 @@
+begin 644 RV670_pfp.bin
+M`,H$``"@````?H*+`'P#BP"``;@`?`.+`-1`'@#N`!X`R@0``*````!^@HL`
+MQ!@X`,HD``#**```E8&H`,0<.@##P```R@@``,H,``!\=$L`P@`%`)G```#$
+M'#H`?'1,`,#_\``$+`0`,)`"`'TE```U%`(`?34+`"54`P!\U8``)9P#`)7`
+M!`#5`!L`?MW!`'V=@`#6@!L`U8`;`-1`'@#50!X`UD`>`-:`'@#4@!X`U,`>
+M`)>#TP#5P!X`R@@``(``&@#*#```Y`$>`-0`'@"```P`Q!@X`.0!/@#4`!X`
+M@``,`,08.`#40!X`[@`>`,H$``"@````?H*+`.0!'@#4`!X`U$`>`.X`'@#*
+M!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^@HL`RA@``-1`
+M'@#5@!X`@`!3`-0`=0#40!X`R@@``,H,``#*$```U(`9`-3`&`#5`!<`U(`>
+M`-3`'@#5`!X`X@`>`,H$``"@````?H*+`,H(``#4@&``U$`>`(````#4@!X`
+MR@@``-2`80#40!X`@````-2`'@#*"```R@P``-1`'@#4@!8`U,`6`-2`'@"`
+M`;@`U,`>`,8(0P#*#```RA```)2`!`#*%```Y"#S`-0@$P#58&4`U.`<`-4@
+M'`#58!P`@`````8@`0#&"$,`R@P``,H0``"4@_<`RA0``.0@\P"``'D`U"`3
+M`,8(0P#*#```RA```)B#[P#*%```U`!D`(``C0``````Q!0R`,880P#$""\`
+ME4`%`,0,,`#40!X`@````.X`'@"5@_4`Q!`Q`-1`,P#5(&4`U*`<`-3@'`#5
+M(!P`Y`%>`-0`'@"`````!B`!`,H8```*(`$`U@!V`,0(-@"8@`<`QA!%`)4!
+M$`#4`!\`U&!B`(````#4(&(`S#@U`,P4,P"$`;L`U`!R`-5`'@"`````[@`>
+M`.(`&@"$`;L`X@`:`,P02P#,!$<`+)0!`'T)BP"80`4`?17+`-0`&@"``;@`
+MU`!M`#1$`0#,#$@`F$`Z`,PL2@"5@`0`S`1)`(`!N`#4`!H`U,`:`"@H`0"$
+M`/``S!`#`)B`&P`$.`P`A`#P`,P0`P"8@!<`!#@(`(0`\`#,$`,`F(`3``0X
+M!`"$`/``S!`#`)B`%`#,$$P`FH`)`,P430"80-P`U`!M`,P82`#5`!H`U4`:
+M`(``R0#5@!H`EL#5`-0`;0"``;@`U`!N`)K``P#4`&T`U`!N`(````#L`'\`
+MFL#,`-0`;0"``;@`U`!N`,P4`P#,&`,`S!P#`'V1`P!]U8,`?1D,`#7,'P`U
+M<!\`?/#+`'S0BP"(````?HZ+`)7`!`#4`&X`@`&X`-0`&@#4P!H`S`@#`,P,
+M`P#,$`,`S!0#`,P8`P#,'`,`S"0#`,PH`P`UQ!\`-K`?`'QP2P`T\!\`?'!+
+M`#5P'P!\<$L`?8B!`'W,P0!^40$`?I5!`'R0@@!\U,(`?(2+`)K``P!\C(L`
+M+(@!`)B`G@#4`&T`F$"<`-0`;@#,"$P`S`Q-`,P02`#4@!H`U,`:`(`!`0#5
+M`!H`S`@R`-0`,@"4@MD`R@P``-1`'@"`````U``>`.0!'@#4`!X`R@@``,H,
+M``#*$```U$`>`,H4``#4@!X`U,`>`-4`'@#50!X`U4`T`(````#N`!X`*`0$
+M`.(`&@#B`!H`U$`:`,HX``#,"`,`S`P#`,P,`P#,#`,`F(*]``````"$`;L`
+MUZ!O`(````#N`!\`R@0``,+_``#,"#0`P3__`'QTRP!\R0L`?0$/`)D"L`!\
+M<XL`A`&[`->@;P"`````[@`?`,H(```H&0``?8F+`)6`%``H%`0`R@P``,H0
+M``#*'```RB0``.(`'P#4P!H`U0`:`-5`&@#,&`,`S"P#`,PL`P#,+`,`?:6+
+M`'V<1P"80I<``````(`!80#4P!H`U$`>`-2`'@"`````[@`>`.0!'@#4`!X`
+MU$`>`.X`'@#*!```H````'Z"BP#D`3X`U``>`-1`'@#N`!X`R@0``*````!^
+M@HL`R@@``"2,!@`,S`8`F,`&`,P03@"9``0`U`!S`.0!'@#4`!X`U$`>`-2`
+M'@"`````[@`>`,H(``#*#```--`8`"40`0"5`"$`P7__`,H0``#*%```RA@`
+M`-2`'0#4P!T`?;&+`,%"`@#"P`$`U8`=`#3<#@!]74P`?W-,`-=`'@#5`!X`
+MU4`>`,%"``#"P```"9P!`#'<$`!_7TP`?W-,``0H`@!]@X``U:AO`-6`9@#7
+M0!X`[`!>`,@D`@#()`(`@`&X`-8`=@#40!X`U(`>`-3`'@"`````[@`>`(``
+M``#N`!\`U``?`(````#4`!\`U``?`(@```#4`!\`````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````0%Q``(!>``#`(\`!`!_``4``P`&
+M`#\`!P`R``@!+``)`$8`"@`V`!`!M@`7`*(`(@$Z`",!20`@`+0`)`$E`"<`
+M30`H`&H`*@!@`"L`4@`O`&4`,@"'`#0!?P`\`58`/P!R`$$!C`!$`2X`50%S
+M`%8!>@!@``L`80`T`&(`.`!C`#@`9``X`&4`.`!F`#@`9P`X`&@`.@!I`$$`
+M:@!(`&L`2`!L`$@`;0!(`&X`2`!O`$@````&````!@````8````&````!@``
+M``8````&````!@````8````&````!@````8````&````!@````8````&````
+)!@````8````&
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV710_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV710_me.bin.uu
new file mode 100644
index 0000000..ee8a241
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV710_me.bin.uu
@@ -0,0 +1,124 @@
+begin 644 RV710_me.bin
+MS``#Z@0(``/,@`!#?$"``*````#,@`!B@````]!``'^````#S$``07Q`P`#`
+M%@`$,-`__WT5``S,$0``*-@`'C&8``$HW``?R"``!)7```9\0D``S```8GY6
+M@`S,*0``R"0`!'XF``N5@``&?$+``,P``&)^UP`,S#$``,@L``1^+@`,S```
+M8C$0/_^````#SA$``'Q`P`"````#S$``0(````/,02)7?$&``,Q``$7,0`!(
+MS$$B7,Q!H?Q\0(``H````,R``&+,0`!%S$``2'Q`P`#,02)<S$&A_'Q`@`"@
+M````S(``8LP``$7,``!(S$$B7,Q!H?Q\0(``H````,R``&($#*']P!(``<P`
+M`$7,``!(?-#`#,Q!(ES,0:'\T$T``'Q`@`"@````S(``8H````/,02)=?$"`
+M`'Q`P`#`*@`"?$$``'TI``PPE``!,)@`!C"<`P`IW``(?$(``'Q"0`"50``/
+MP"X`!`7P(EA_+P`,S#$``,@H``3,P2%IS0$A:LZ!(6L-M``"S`$A;)=```X-
+MM```@```?<@T``H-M``"ET``"0VT``#`+@`$!?`B6'\O``S,,0``R"@`!(``
+M`'W(-``*ET``!'X"@`"```!]R#0`"@VT``270/^,`````,X!(6W.02%NR"@`
+M`\@T``J;0``$!#P`!80``FW,``!B#?0``)=```O(+`/FSH&BM\`P``9^\T`H
+MP#``(']K@"!_L\`ISX&BQ(````//P:+1#?0``9=```O(+`/GSH&BN\`P``9^
+M\T`HP#``(']K@"!_L\`ISX&BQ8````//P:+2#?0``I=```O(+`/HSH&BO\`P
+M``9^\T`HP#``(']K@"!_L\`ISX&BQH````//P:+3R"P#Z<Z!HL/`,``&?O-`
+M*,`P`"!_:X`@?[/`*<^!HL>````#S\&BU(````/,0`!"?$#``'Q!```I%``=
+M,50``9E```PQ&!``R!P`$97```#('``1S,$A`,T!(0',P2$"S0$A`P08``2`
+M``-^S8&BI,`J``25@``(-J@AH\PI``#(*``$R!P`$0WD`$"60/__R!P`$<S!
+M(7#-`2%QR"``$I8```#((``2@``#?LP``&1\0,``?$$``,P``$7,``!(0-0`
+M`\U!(ES-`:'\P!H``00<H?U]V<`,?$(```C,``$&)``!!B@``LX=``#.70``
+MF,#_^LZ=``!\0(``H````,R``&)\0,``,-```2C,``%\04``E0``!GQ!@`#-
+M02%MS8$A;H```/3('``#P"(`!'X6``S,(0``R!P`!'Q"0`"8P``$?$*``(``
+M``/-Y0``SD$A:<Z!(6K-P2%K@````\P!(6Q\0,``?$$``'Q!0`!\08``?$'`
+M`"BD``@R9`#_#F@`/):```I\`@``?$(``!XP``/,``!JFP```T(@``4$(`!`
+M@``!$7P"0`!^`D``FD````ID``$P[``0FL``"LP``&+`*@`$R"P`(7Z2@`S,
+M``!!S"D``,[``"&```$AR#``!,T!(6W-02%NR#```W\?``LP]``')W@``9=`
+M`"H'N`$FGX````````"```$V?QN`!(```3I_&X`%@``!/G\;@`*```%"?QN`
+M`X```49_&X`'@``!2G\;@`:```%/**0`")N``!DHI``(@``!7S)D`/^;@``5
+M**0`"(```5\R9`#_FX``$2BD``B```%?,F0`_YN```THI``(@``!7S)D`/^;
+M@``)**0`"(```5\R9`#_FX``!2BD``B```%?,F0`_RBD``@R9`#_#F@`/)J`
+M_K(H[``(?$-``'Q#@`!\0\``EL``!\P``&+/02%ISX$A:L_!(6N````#S`$A
+M;(````//]0``S```:X0``X$.:``\FH``!,@H`!6````#T$``?Y:`_ZM^`D``
+MA``".\`.``+,``!!@``".<S!,$I\0,``?$$``,`>``$I)``2P"(``I9```7`
+M)@`$P"?_^WTE``O`)@``?=*`"WX2P`M])0`,?$%``'Q!@`#,P2%IFH``"LT!
+M(6K-02%KEL#^@\V!(6S(,``8EP```,@P`!B````#S```&(0``X',``!_R!0`
+M$\@8`!3-02%KEL#^=\V!(6R```&#R#``&,@,``B8P```R`P`"'Q!``"5```"
+M`````'Q!0`#((``)S$``0\X!H?3,0`!$P`Z``'Q"0`!\0H``*JP`'Y;`_F3`
+M-?``SD`#XC)X``,F?``(?_?`"W_[P`PJ>``8S\`#X\^``^0FL``"?S\``,\`
+M`^6```,??(#``'Q`P``HT``(,1``#Y4```\E*``!!J@!M)Z`````````@``!
+MU<`2"`"```'CR!0`#X```>K(%``0@``!\<S!HJ2```'ZR!0`$3#0`#\-*``5
+MFH``$@TH`!Z:@``>#2@`()J``",-)``/#2@`$'YJ@`R:@``F#2``!`TD`!0-
+M*``H?F)`#'ZF@`R:@``JR!0`$8````/,P:*DP!((`'Q!0`!]#,`,P!(`""E8
+M``,I7``,?$(``'W1P`LF(``4?AY`#'Y.@`S.@:*D@````\V!H?[(%``/!!`A
+M#I5```#(%``/T%$``(````/,P:*DR!0`$`00(0B50```R!0`$-!1``"````#
+MS,&BI,S!HJ0$$``!S0``&80``X',``!_R!``&9D```#($``9@```!'Q`@``$
+M$"$`E4```,@4`!'040``@``#?LS!HJ1\0,``S$``#93`_@',0``.?$$``)4`
+M``4(S``!R!0`!9E``!0`````F,#_^WQ!``"````$?0"``,@4``5\0,``F4``
+M#,@8``Q\00``E8#]\,@@``[('``-9B``('X>`"PE)``"?F)`((````/,Y@``
+M?$$``,P``&S,``!MR!@`'\@<`!YEF``@?=G`+'S4P`S,W@``1=P`!,@H`!>6
+M@``/P`X``2AH``@JK``6,J@`_PZP`$E_+P`+EP``!@````#(%``%?$#``(``
+M`B-\00``@``")M!``'^$``([S```0<S!,$J4````R#P`&@0\``7/P:*DP#8?
+MD,`X?_]\`\`0?WM`#,]!(7S/P2%]S`$A?L`Z``0$-"%_?WM`#,PU``#(/``$
+M*_P`'P0X`""7P``%S```8IN````+N``!@``"1\P``'',`:'T!#@`%L`V``+/
+M@:*DB````,]!(!!\0,``*-``')4```4$U``!S4``98````/-0`!H"50``H``
+M``/-0`!FA``";,@8`^I\0,``F8#]G\@4`!8(T``!F4``*\T``&A\0(``H```
+M`,R``&($/``%S\&BI,P!H?2$``.!S```1H@```#,``!_A``"?L@8`^I\0,``
+MF8#]C<@4`!8(T``!F4``&<T``&A\0(``H````,R``&($/``BS\&BI(0``X',
+M``!'B````,P``'_($``6F0``#<Q``&>````$?$"``,@8`^J9@/UY?$#``)3`
+M``/($``6F0``!,S``&B````$?$"``(0``CO`%(``S```0<U!,$K`%(``F0``
+M`,@0`!:````$?$"``,`2``%\44`,@````]!5``!\0,``?$$``'Q!0`!\08``
+M*1P`'\S``$K-``!+E<```\`<@`#-P2`0W8,```5<(`#,``!B@````]@?00!\
+M0,``?$$``'Q!0`!\08``S,``3,T``$W=@P``!5R@`(````/8'T$`?$#``'Q!
+M``!\04``?$&``,S``$[-``!/W8,```5<P`"````#V!]!`'Q`P`!\00``?$%`
+M`'Q!@`#,P`!0S0``4=V#```%7/C@@````]@?00!\0,``?$$``'Q!0`!\08``
+MS,``4LT``%/=@P``!5SX@(````/8'T$`?$#``'Q!``!\04``?$&``,S``%3-
+M``!5W8,```5<X`"````#V!]!`'Q`P`!\00``?$%``'Q!@`#,P`!6S0``5]V#
+M```%7/``@````]@?00!\0,``?$$``'Q!0`!\08``S,``6,T``%G=@P``!5SS
+M_(````/8'T$`T$,@`'Q`@`"@````S(``8M!#H`!\0(``H````,R``&+00\``
+M?$"``*````#,@`!BT$/XX'Q`@`"@````S(``8M!#^(!\0(``H````,R``&+0
+M0^``?$"``*````#,@`!BT$/P`'Q`@`"@````S(``8M!#\_Q\0(``H````,R`
+M`&+(%`/@S$,``,Q#``#,0P``?47``,W#``#00P``?$"``*````#,@`!B?$#`
+M`,@0`^+(%`/ER!@#X\@<`^3-@2%IS<$A:LS!(6O,`2%L!"``!'VA@`!]ED`"
+MED#\V<V``^,Q*``#P"WP`"48``A]K8`+?:F`#(````/-@`/C,(S__]!-``!\
+M0(``H````,R``&+(%``@%5@``I6`___(%``@S```;LQ!(8!\0,``S,$AC<Q!
+M(8$HT``?-%B``,V!(8R5`/R_S$$A@L@4`""90/__R!0`((````1\0(``?$#`
+M`"C0`!@Q$``!P!8`@)4```/`*@`$?-3`#,S!(7S,02%]S$$A?GQ!@``=L``#
+M-J`A?YL```-!G``%!!P`0)G````)W``!S"$``,@D``0J;``?09P`!9K`__K,
+M@`!B@```!'Q`@`!\0,``!-0#YH````/,5```@``#?LQ``^K`'(``!$R@`,W!
+M(!!\00``R!0`"008```$'``(S8``<0G<``$%F``!S0T``)G`__S,@`!B@``#
+M?LU``''`#@$`S```0<S!,$K(/`!_S```?X````/,``!_S```?X@```#,``!_
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````0,S`!``!@`7
+M``@`(0`*`"<`*@`H`"4`*0`K`"H`*``K`"L`+0`Z`"X`00`O`$P`-`!.`#8`
+M,@`Y`+$`.@#1`#L`Y@`\`/X`/0%M`#\`KP!!`S@`0P-+`$0!D`!%`/X`1@&N
+M`$<!K@!(`@``20(.`$H"5P!+`H0`4@)A`%,"<P!4`HD`5P*;`&`"GP!A`JX`
+M8@*X`&,"P@!D`LP`90+6`&8"X`!G`NH`:`+T`&D"^`!J`OP`:P,``&P#!`!M
+M`P@`;@,,`&\#$`!P`Q0`<@-E`'0#:P!Y`VD`?`,>``\#>@`/`WH`#P-Z``\#
+M>@`/`WH`#P-Z``\#>@`/`WH`#P-Z``\#>@`/`WH`#P-Z``\#>@`/`WH`#P-Z
+H``\#>@`/`WH`#P-Z``\#>@`/`WH`#P-Z``\#>@`/`WH`#P-Z``\#>@``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV710_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV710_pfp.bin.uu
new file mode 100644
index 0000000..4c9b3f8
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV710_pfp.bin.uu
@@ -0,0 +1,79 @@
+begin 644 RV710_pfp.bin
+M?$"``*````!^@H`+@````-P#``#,@`!`T$``0'Q`@`"@````?H*`"\@8``XQ
+MF``!?$)``)6``CI\0H``R!P`',`WP`!\0,``?$$``'RT@`O`-@`#F<```,@<
+M`!Q\M(`,)-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``0,Z``$#,P`!`W#H`
+M`)>`_][-``!`?$#``(```!A\00``U``#0-0`#\#4``^BR!@`#H````PQF``"
+MU``#P-0`#\#4``^BR!@`#BB,``@PS``/-!```7T-``B````,?9&`"\R``$#0
+M0`!`?$"``*````!^@H`+U``#0-0`#\#4``^BS(``0-!``$!\0(``H````'Z"
+M@`O4``/`U``/P-0`#Z+,@`!`T$``0'Q`@`"@````?H*`"\Q``_F```))S$`#
+M^,`W__]\04``ST&BGL@@`_C('`/Y9B``(,@8`_M]X<`L?5C`"'S<P"!I$``@
+MP#8``\P``%1\M(`,@```:<R``$!\08``S8&BGLR``$"```!GS8``0,`9___,
+M@`!`S8&BGGQ`P`!\00``?$%``,S!H?K-`:'YS4&BG<S``$#-``!`S4``0,Q`
+M`$!\0(``H````'Z"@`O,``!4S(``0'Q`P`!\00``?$%``,S!H?K-`:'YS4&B
+MG<S``$#-``!`S4``0-!``$!\0(``H````'Z"@`M\0,``,-```<S!HI^5```#
+M!!0``004``+-0`/[S(``0(````#,P`!`?$#``,R``$#,P:*B@````,S``$!\
+M0,``*-0`'\R``$"50``#?$$``,S``%<I&``?S,``0)6```/-``!`S0``6(``
+M`DG,``!_R"``%\@P`"*:```&#B@``<@D`!X*9``!U``20,Y``$#`-L``EH``
+M!S=T>0`$'``!ST``0,W``$#/``/Z?`,``,H,`!!\00``E,``!'Q!0`#4(`+$
+MS>``1)L```M\08``S```2\V@`$G-(`!!S6``0<V@`$$&(``!S@``5H```DG,
+M``!_R"@`(,@L`"',``!C?NI``65T`"!_4T`L)IP``GWUP"!I^``@SH``2\Y@
+M`$G-X`!!SZ``0<Y@`$$G'``"??7`(&GX`"!]LD`!SP``2\Y@`$G-X`!!SZ``
+M08```+S.8`!!R"``%\@P`"*:```&#B@``<@D`!X*9``!U``20,Y``$#*#``0
+M?$$``)3```O`-L``EH``!S=T>0`$'``!ST``0,W``$#/``/Z?`,``(```+5\
+M04``S```2(```.X`````R"``%\@<`",.)``"F<``%7Q!@``*(``!S@``5M0`
+M!$#,``!`P#;``,H4`!.60``'-W1Y`,]``$#,``!`R#`#^H```0//```BS```
+M(I5``4;,``!_S*``1H````#,(`!&@``"2<P``&3((``7R!``'Y8```4)$``!
+MU``$0,T``$#-```BS(``0-!``$#(#``EE,#^[,@0``C-``!`U``/P(````#4
+M``^B?$#``'Q!``#,P`/]S0`#_,S``$+-``!"*10`'RD8`!`QF``'.UP``7UV
+M``N9@``%?5Y`"\P``$*```))S```32F8``$I+``(F8``/3+L``&6```$*3``
+M#(```DG,``!"!!0`$,U``$(S,``!-"@``80``5W(%``#FT``&P0X``R$``%=
+MR!0``YM``!<$.``(A``!7<@4``.;0``3!#@`!(0``5W(%``#FT``%<@,`_V:
+M@``)R!`#_)L``0',``!-!!0`$,S``$+-``!"@``!-<U``$*6P`#ZS```38``
+M`DG,``!.FL```\P``$W,``!.WX,``(````#8`P'_FL``\,P``$V```))S```
+M3L@8``/('``#R"```WU=0`-]H<`#?5U`#"H0`!\IG``??1T`"WT70`N(````
+M?I*`"Y9```3,``!.@``"2<P``$($.``(SX``0L@(``/(#``#R!```\@4``/(
+M&``#R!P``\@D``/(*``#*?P`'RJP`!]_\\`+*/``'W_SP`LI<``??_/`"WV(
+M@`%]S,`!?E$``7Z50`%\D(`"?-3``GR\@`N:P``#?(]`"SBT``&;0`#!S```
+M39O``+_,``!.R`P#_<@0`_S,P`!"@``!;LT``$+4``-`U``/P-0`#Z+,@`!`
+MS$``0,Q``$#,0`!`?$#``,S``$#,P``-@````-!``$!\0,``?$$``&44`"!]
+M34`L)%@``GU9@"!\0<``S8``0FF8`"#-@`!"S<``0L`CP``%Y``"?*"`"R9D
+M`!!\I(`,S(``0,W``$#,P`!`E<``#LT``$`)W``!R"@``Y:```C.@`!`R#0`
+M'9=```#(-``=)J@`"(0``DS,*P``F<#_]PG<``'<.@``EX``!'Q!@`"```&B
+M)9@``J````!]@(``R!@`'7Q`P`!DT``(E8```,@8`!W,$P``S(``0,S``$"`
+M````S$``0,@0`!]\0,``S(``0'S10`S-0`!`!1@``8````#-@``B?$#``&10
+M`""$``),S```87S0P"S((``7R-8``)E```A\0X``WX,``,^@`$^$``),S```
+M8H````#00`!_@``"2<P``&*$``),S```8<@@`!=\0,``P#;_`,@0``W`,#__
+M?/5`"WU1@`M]@8`/F8``"'SS@`O?@P``SZ``3X0``DS,``!B@````-!``'^`
+M``))S```8H0``DQ\0,``*-P`")7``!DPW``0?$$``)G```1D5``@@``"",D=
+M``!]%0`LR1X``'Q"``!\0D``?$&``'WEP`M]XH`'FH``#D&L``6:P```"NP`
+M`3#<`!"9P``$`````(```@O)'0``@``""\D>``#,@`!`S,``0-!``$#(#``E
+ME,#]Y,@0``C-``!`U``/P(````#4``^BU``#0-0`#\#4``^BS(``0-!``$!\
+M0(``H````'Z"@`O4``/`U``/P-0`#Z+,@`!`T$``0'Q`@`"@````?H*`"WQ`
+MP``PT``&#1``!ID```?(%``5F4``!<P``%+4``-`U``/P-0`#Z+,@`!`S,``
+M0(````#00`!`?$#``,Q-``#<.@``EX#]O03,``&```)"S$T``(````#00`!_
+MS```?X````#,``!_S```?X@```#,``!_````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````,"(@`$`BH`!0"?``(``P`&`#P`!P`G``@!D0`)`$0`
+M"@`M`!`"1P`7`/``(@'7`",!Z``F`$P`)P!?`"`!&@`H`)(`*0!/`"H`@P`K
+M`&0`+P"-`#(`V``T`C(`-@!T`#D!"@`\`?P`/P"?`$$`!0!$`90`2`&=`$D!
+MQ0!*`<\`50(E`%8"+0!@``H`80`J`&(`,`!C`#``9``P`&4`,`!F`#``9P`P
+M`&@`-P!I`#\`:@!'`&L`1P!L`$<`;0!'`&X`1P!O`$<`<`!'`',"1P![`D``
+M```%````!0````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+1!0````4````%````!0````4`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV710_uvd.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV710_uvd.bin.uu
new file mode 100644
index 0000000..778b9ad
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV710_uvd.bin.uu
@@ -0,0 +1,2584 @@
+begin 644 RV710_uvd.bin
+MPARS`N_/;T(A;%H+MT0;G'.?$L!CH2XB#V4_E0_F=+[8^X_!&*G(SJC1^K6(
+MN3/U\>",M```````PP$``P````4```&#9R*/0\4)5RV-&X_9[I?._+<26U!2
+M5'^T?M%/IAVT`HN*X&0&```!3BP=ZCHAXU=5P(F7P;.%:,D*3%\Y>/$#]=+E
+M.^)3?5T,`6])!P```5R3S4UW)*C3;]-\7M#KZ;Y2LX0NH'ZYV-K\XY>':B`U
+M+)//L@``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````,5)$-5)(.5),/5)`#0``-S_`&'0
+M_P!A$``!82\`!`"Y#`1@``````````````````````````````````````#%
+M"1#5"2#E"3#U"0`U````````````````````````````````````````````
+M````````````````````````R4D`T0D0V4D@Z4DP^4E`@$E0D$E@H$EPL$D`
+M-````````````````````````````````````````````````,D)$-D)(.D)
+M<-$),/D)0(<)4)<)8*<)<+<)`#4`````````````````````````````````
+M``````````````#-20#1"1#=22#M23#]24!`25!026!@27!P28"`29"02:"@
+M2;"P20`T````````````````````````````````S0D0W0D@[0FPT0DP_0E`
+M2PE06PE@:PEP>PF`BPF0FPF@JPFPNPD`-0``````````````````````````
+M````#```Y!,``!,``1,``A,``Q,`!!,`!1,0(```21,`2!,0(```:!,`@!,`
+M@1,`D!,`D1,`H!,`H1,P(```L1,`LA,`LQ,`PA,`PQ,`T1,`TA,`TQ,`Z!,`
+MZA,`\!,`\1,`\A,,\B#F$Q`@`$P"#`-V@@[2<P/2<T/2<X/2<\,RTP$`(``B
+MH$`RH`!V@@[R<P#R<Q#R<R#R<S`RTP$`(`!,`@P#=H(.@G,#@G-#@G.#@G/#
+M,M,!,"``(J`@,J``=H(.<G,`<G,0<G,@<G,P,M,!,"``#"5`50$,`PST0&-0
+M6C-`8U!:,T!C4%HS#$0&````0&-0`"``\"``\"``6C,,]$!C4%HS0&-06C-`
+M8U!:,T!C4``@``P##/1`XU!:,T#C4%HS0.-06C,,1$#C4%HS#"1`XU!:,PST
+M0.-06C,,)$#C4%HS#/1`XU`P(``\`B#C$P*@!`N`#``,`0P"#`,,!`P%#`8,
+M!R"`0%9P_@P1#``021,`2!,`(``0(``11?\A1?\Q1?\Y`C%%_S#F$Q`@`"!@
+M`"%#_R`%$V7X`"T*,2X#*0,,$C$O`RD#AI3_````.1%)(5DQ:4%Y48EAF7&I
+M@;F1R:'9L>G!^=$@``,P`0,IX3GQ(`(#,`,#(F$0,F$1(.8#,+$#(F$2,F$3
+M;`,P(A`K(B#F$Q+1`1+!@!`@`!`1(!4%`!+!@#(A$2(A$#`#$R`"$SCQ*.$P
+M`1,@`!,B(1(R(1,@YA,PL1,0(`#XT>C!V+'(H;B1J(&8<8AA>%%H05@Q2"$X
+M$2@!$M$!$L&``#`````V`0$@80!`X@-0Y`,A,`-01!`@1!!61``@;P`=\##T
+M0!SR,#+``!-`03$#0$.PG&,,$@`BH2#C$R(D`&(D`19"_-`"`(;O_P`@\`,@
+M\!,H!&@4%@+[T`(`ANK_`#8A`##J`RHS,/`3'?`````V(0#VP@E1,0-0(K`Y
+M`DD2'?``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````"*L#L9E_P``
+M````````````````````````````````(JP8QEW_````````````````````
+M```````````````0-````````````````````````````````````````!+!
+M@"D!(.@#9D("1E#_*`$2T0$2P8`BK!=&2/\`````(JP6QD7_```V(0!`;P`P
+MY`,@,R`PY!-`YA,0(``=\``V(0!`;P`PY`,@,R`@,S`PY!-`YA,0(``=\```
+M`````"*L%<8U_P``-B$`(.H#'?`V(0`@\!,`(``=\``V(0`@\`,=\```````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````PP%@````````````````T0$``!$!``#1`0``T0$``-$!```1`0``=P$`
+M`-$!``#1`0``=P$``-$!``#1`0``T0$``!$"``#_`0``T0$``-$!``#1`0``
+MT0$``-$!``#=`0``````````````````7````"\````_`@``!P(``-D!``!5
+M`0``TP`````````&#10<#10<(!0<("4<("4J"@X4&`X4&!L4&!L>&!L>(@`!
+M!`@%`@,&"0P-"@<+#@\``0@0"0(#"A$8(!D2"P0%#!,:(2@P*2(;%`T&!PX5
+M'",J,3@Y,BLD'18/%QXE+#,Z.S0M)A\G+C4\/38O-SX_-`D``#0)``#4"0``
+MQ`D``,0)``#5!@``U08``-4&``#5!@``U08``-4&``#$"0``M`D``*0)``#5
+M!@``U08``-4&``#5!@``U08``-4&``#5!@``I`D``)0)``"$"0``U08``-4&
+M``#5!@``U08``-4&``#5!@``U08``'0)``!T"0``9`D``-4&``#5!@``U08`
+M`-4&``#5!@``U08``-4&``!4"0``1`D```````#$````JP(``(\"``!S`@``
+M5P(``#L"```P`@``%`(``/@!``#<`0``P`$``*0!``"(`0``;`$``%`!```T
+M`0``&`$``/P```#@```````````!`@,$!08'"`D*"PP-#@\0$1(3%!46%Q@9
+M&AL<'1T>'R`@(2(B(R,D)"4E)28F)B<G)R<````````````````/```!!P(+
+M!`T(#@,#!04*"@P,#P$'`@L$#0@.!@8)"0``````````````````````````
+M```````````````````````````````````````````````````````````O
+M`!\0#P$``A<$&P@=(!X#!P4+"@T,#@\G+RL'+0LN#1`.`P8%"0H?#",3)14J
+M&BP<(2,B)20J*"PG`2L"+00N"!$1$A(4%!@8$P85"1H6'!D7(!LA'2(>)!8H
+M&28F*2D`````$````"`````/````'P```"\```````````````(!`P,$!P4/
+M"!\"`@,&!`X%'@<^````````````````'T`?01]"'T,?6Q]<'UT?7@!`@`%!
+M@0)"@@-#@P1$A`5%A09&A@='APA(B`E)B0I*B@M+BPQ,C`U-C0Y.C@]/CQ!0
+MD!%1D1)2DA-3DQ14E!55E196EA=7EQA8F!E9F1I:FAM;FQQ<G!U=G1Y>GA]?
+MGR!@H"%AH2)BHB-CHR1DI"5EI29FIB=GIRAHJ"EIJ2IJJ@``````````````
+M``````("`@```@```0$!`P,!`P.`5:I`P#-FF<PKUR5*;Y2YWB!@H.``````
+M`````````!\X'SD?.A\['SP?/1\^'S\?2!])'TH?2Q],'TT?3A]/'QL?'!\=
+M'QX?)Q\H'RD?*A]$'T4?1A]'```````````?7Q]@'V$?8A]C'V0?91]F'Q\?
+M(!\A'R(?(Q\D'R4?)A\7'Q@?&1\:'PT?#A\/'Q``"`$%"0T#"P``````````
+M#1T)!14F-C($!Q<#)S<S`(!5JD#`,V:9S"O7)4IOE+G>(&"@X````-SQ_)\4
+M)_V?T?\'`!##`6"T"````/+\G\0?`&``]OR?````"/__'P````"`Z!\`8(0?
+M`&"($P````!@```(``````("____/P````(`[OR?@):8```N_)\``#`#`/[[
+MGX<3``#___\!````P/__7P#D#0``````8O____T```(``!\```!```#_?_#_
+M```*`/^___\```B`__#__P```X````*````&@````8`]``!`P)X!8```!(``
+M``V````,@```!8``&```_^?__P````$-``!``/K\GP#^_)\@3@``````X```
+M`/````"@.&L``!1K``!L#```@`P``+`F`&``*0!@W!$``````$#___^_U&@`
+M`-0/``#___\``#__````8`8`J0!@@*D#`-P/``#L:````/\`__@=``#P_P``
+M0`@``"`__P`"(```-\U"_6:X](R+\4\'9&H``+`)```0"`!@6"\`8.AH```P
+M"@`````D`"U=``"H#```U`P``%@1```4"0``P`H``(`*``#___]_W!,``)1:
+M``#4"```\&@``$@*``#@.@``.#L``$@Y``#8&```,!D``*`*``!P"`!@1$H`
+M8%`*``#`"```5`D``)0)``#L#P``____@```\`^L"0``%P``"`@-``!@#0``
+M:!```,0X``"T#P``#R<```((``!H:@``````!,P)``#8#P``/&@``,`/```T
+M#```M%L``!1;``"X#P``_&H````)`&"4:0!@,0P```!2`@```#@$`."&`@``
+MS````,````!X``!X:0``=B\``-@;``#L#0``1@4`>E\``'Q?```Z8```/&``
+M`)@*``#D$0``\`\``/QH``!,"@``T`\``(`8```L70``K%L``+@(``!)"@``
+MD%P``!Q=``#86@``W%H``&P*``!L:@``+`H``!BA`&`PH0!@E&@``/__`_C_
+M`?S_``#\!P#^`P#@#P``B#H``,1H````/_\!`P@``+`)`&!PJ0!@&-H`8(#-
+M`&!`]0!@X``!8-S#`&"TM@!@2,X`8`S&`&!\W@!@W.@`8)0!`6!$^0!@I+<`
+M8."M`&"TZ0!@K.``8``*`&``@``````0^```0/@`"P!@````^```,/@(@```
+M``#@`0``(/@3``$`&P``@!L``$`;```0&P``D!L``%`;```@&P``H!L``&`;
+M```P&P``L!L``'`;``#P&P``P!L``-`;``#@&0``$!D``"`9```P&@``$!H`
+M`"`:```P'```P!P``(`<``!`'```(!P``!!`"@!@____!^!H``"D"```""H!
+M8&@G`6`!/_\``0#P#T$`\`]$_A\`5$<!8``.``#^_P```@D``#@(````(`,`
+M@'^`?X$`\`](@`%@X%4!8,A[`6"060%@(`L`8"H+`&",@0%@%(0!8-""`6#H
+M?`%@*'\!8`A^`6#,5@%@B%H!8*18`6!X7`%@N%<!8(!;`6`+``(`4`L`8$`+
+M`&```%$```!0````<````'$````1````$``?,@``'S$`````T0```)$```#0
+M````D``"$0```A,```(6```"&````@\```(4``#^#P``_A\``!\U```?,P``
+M'S0``!]8``#@"P!@'U```/`+`&`"$@```@X``!]7```?60``'UH``&`,`&`?
+M5```'U(``"`,`&`?40``4`P`8`(,``!X#`!@'U8``!`,`&!`#`!@.`P`8`(+
+M```P#`!@'U,``"1P`6#,2P%@M'`!8%Q-`6!D<0%@+'@!8)Q1`6"0<P%@F'D!
+M8!\K``"0#`!@```@````X`"`#`!@'S``````L``<C`%@H`P`8!]5````WOR?
+M```!`,#_````XOR?'Z$'`)24`6"PE@%@````A```@````$`````(````!`#_
+M__/____\__\`__\```"#````&```#``````,````$````(8`\/____]___\/
+M`/\````*````#@````8````<````%#;!$K$R`PP"XM$)HM$)#`D,"(D!F7J1
+M,P.)#BF:\BFJ^1'($0QBHL$((,P@PFFJ@FG$9?$:I28!H$H@)3(1H#H@I;D8
+ML30#B\$A-0/A,P.!-@,PE'.0FG.908)NVC(NY=+1"($W`S`P-#)M+_(M+Z(M
+M+Y(M+X#_$<"J$?"J(*"9())NY8)B%8)B%S(N]S)M+Z(M+_*OQQP#\*H0,*H@
+MHF[WDBZ_DFTO\BTO#!B1.`.`_R#R;2^B+2^B;K^28G3R+J*"IP"BH`>`_R#R
+M;2_2+2_2;J+E#/^BH`BQ.0/"P0@E#/\,:K$Z`\T!90O_HJ&`I2?_43L#03P#
+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
+M-S(","+`UB<`("!@'?``-S(","+`UB<`("!@'?``````````````````````
+M``````````````##`6``PP%@`,,!8`##`6``````_____P````#_____````
+M`/____\`````_____P````#_____`````/____\`````_____P````#_____
+M`````/____\`````_____P````#_____`````/____\`````_____P````#_
+M____`````/____\`````_____P````#_____`````/____\`````_____P``
+M``#_____`````/____\`````_____P````#_____`````/____\`````____
+M_P````#_____`````/____\`````_____P````#_____`````/____\`````
+4_____P````#_____`,,!``4P@`,`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV730_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV730_me.bin.uu
new file mode 100644
index 0000000..3bebdcb
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV730_me.bin.uu
@@ -0,0 +1,124 @@
+begin 644 RV730_me.bin
+MS``#ZGQ`@`"@````S(``8H````'00`!_@````<Q``$%\0,``P!8`!##0/_]]
+M%0`,S!$``"C8`!XQF``!*-P`'\@@``25P``&?$)``,P``&)^5H`,S"D``,@D
+M``1^)@`+E8``!GQ"P`#,``!B?M<`#,PQ``#(+``$?BX`#,P``&(Q$#__@```
+M`<X1``!\0,``@````<Q``$"````!S$$B5WQ!@`#,0`!%S$``2,Q!(ES,0:'\
+M?$"``*````#,@`!BS$``1<Q``$A\0,``S$$B7,Q!H?Q\0(``H````,R``&+,
+M``!%S```2,Q!(ES,0:'\?$"``*````#,@`!B!`RA_<`2``',``!%S```2'S0
+MP`S,02)<S$&A_-!-``!\0(``H````,R``&*````!S$$B77Q`@`!\0,``P"H`
+M`GQ!``!]*0`,,)0``3"8``8PG`,`*=P`"'Q"``!\0D``E4``#\`N``0%\")8
+M?R\`#,PQ``#(*``$S,$A:<T!(6K.@2%K#;0``LP!(6R70``.#;0``(```'O(
+M-``*#;0``I=```D-M```P"X`!`7P(EA_+P`,S#$``,@H``2```![R#0`"I=`
+M``1^`H``@```>\@T``H-M``$ET#_C`````#.`2%MSD$A;L@H``/(-``*FT``
+M!`0\``6$``)KS```8@WT``"70``+R"P#YLZ!HK?`,``&?O-`*,`P`"!_:X`@
+M?[/`*<^!HL2````!S\&BT0WT``&70``+R"P#Y\Z!HKO`,``&?O-`*,`P`"!_
+M:X`@?[/`*<^!HL6````!S\&BT@WT``*70``+R"P#Z,Z!HK_`,``&?O-`*,`P
+M`"!_:X`@?[/`*<^!HL:````!S\&BT\@L`^G.@:+#P#``!G[S0"C`,``@?VN`
+M('^SP"G/@:+'@````<_!HM2````!S$``0GQ`P`!\00``*10`'3%4``&90``,
+M,1@0`,@<`!&5P```R!P`$<S!(0#-`2$!S,$A`LT!(0,$&``$@``#?,V!HJ3`
+M*@`$E8``"#:H(:/,*0``R"@`!,@<`!$-Y`!`ED#__\@<`!',P2%PS0$A<<@@
+M`!*6````R"``$H```WS,``!D?$#``'Q!``#,``!%S```2$#4``/-02)<S0&A
+M_,`:``$$'*']?=G`#'Q"```(S``!!B0``08H``+.'0``SET``)C`__K.G0``
+M?$"``*````#,@`!B?$#``##0``$HS``!?$%``)4```9\08``S4$A;<V!(6Z`
+M``#RR!P``\`B``1^%@`,S"$``,@<``1\0D``F,``!'Q"@`"````!S>4``,Y!
+M(6G.@2%JS<$A:X````',`2%L?$#``'Q!``!\04``?$&``'Q!P``HI``(,F0`
+M_PYH`#R6@``*?`(``'Q"```>,``#S```:IL```-"(``%!"``0(```0]\`D``
+M?@)``)I````*9``!,.P`$)K```K,``!BP"H`!,@L`"%^DH`,S```0<PI``#.
+MP``A@``!'\@P``3-`2%MS4$A;L@P``-_'P`+,/0`!R=X``&70``J![@!))^`
+M````````@``!-'\;@`2```$X?QN`!8```3Q_&X`"@``!0'\;@`.```%$?QN`
+M!X```4A_&X`&@``!32BD``B;@``9**0`"(```5TR9`#_FX``%2BD``B```%=
+M,F0`_YN``!$HI``(@``!73)D`/^;@``-**0`"(```5TR9`#_FX``"2BD``B`
+M``%=,F0`_YN```4HI``(@``!73)D`/\HI``(,F0`_PYH`#R:@/ZR*.P`"'Q#
+M0`!\0X``?$/``);```?,``!BST$A:<^!(6K/P2%K@````<P!(6R````!S_4`
+M`,P``&N$``-_#F@`/)J```3(*``5@````=!``'^6@/^K?@)``(0``CG`#@`"
+MS```08```C?,P3!*?$#``'Q!``#`'@`!*20`$L`B``*60``%P"8`!,`G__M]
+M)0`+P"8``'W2@`M^$L`+?24`#'Q!0`!\08``S,$A:9J```K-`2%JS4$A:Y;`
+M_H/-@2%LR#``&)<```#(,``8@````<P``!B$``-_S```?\@4`!/(&``4S4$A
+M:Y;`_G?-@2%L@``!@<@P`!C(#``(F,```,@,``A\00``E0```@````!\04``
+MR"``"<Q``$/.`:'TS$``1,`.@`!\0D``?$*``"JL`!^6P/YDP#7P`,Y``^(R
+M>``#)GP`"'_WP`M_^\`,*G@`&,_``^//@`/D)K```G\_``#/``/E@``#'7R`
+MP`!\0,``*-``"#$0``^5```/)2@``0:H`;*>@````````(```=/`$@@`@``!
+MX<@4``^```'HR!0`$(```>_,P:*D@``!^,@4`!$PT``_#2@`%9J``!(-*``>
+MFH``'@TH`"":@``C#20`#PTH`!!^:H`,FH``)@T@``0-)``4#2@`*'YB0`Q^
+MIH`,FH``*L@4`!&````!S,&BI,`2"`!\04``?0S`#,`2``@I6``#*5P`#'Q"
+M``!]T<`+)B``%'X>0`Q^3H`,SH&BI(````'-@:'^R!0`#P00(0Z50```R!0`
+M#]!1``"````!S,&BI,@4`!`$$"$(E4```,@4`!#040``@````<S!HJ3,P:*D
+M!!```<T``!F$``-_S```?\@0`!F9````R!``&8````)\0(``!!`A`)5```#(
+M%``1T%$``(```WS,P:*D?$#``,Q```V4P/X!S$``#GQ!``"5```%",P``<@4
+M``690``4`````)C`__M\00``@````GT`@`#(%``%?$#``)E```S(&``,?$$`
+M`)6`_?#((``.R!P`#68@`"!^'@`L)20``GYB0""````!S.8``'Q!``#,``!L
+MS```;<@8`!_('``>99@`('W9P"Q\U,`,S-X``$7<``3(*``7EH``#\`.``$H
+M:``(*JP`%C*H`/\.L`!)?R\`"Y<```8`````R!0`!7Q`P`"```(A?$$``(``
+M`B300`!_A``".<P``$',P3!*E````,@\`!H$/``%S\&BI,`V'Y#`.'__?`/`
+M$'][0`S/02%\S\$A?<P!(7[`.@`$!#0A?W][0`S,-0``R#P`!"O\`!\$.``@
+ME\``!<P``&*;@```"[@``8```D7,``!QS`&A]`0X`!;`-@`"SX&BI(@```#/
+M02`0?$#``"C0`!R5```%!-0``<U``&6````!S4``:`E4``*````!S4``9H0`
+M`FK(&`/J?$#``)F`_9_(%``6"-```9E``"O-``!H?$"``*````#,@`!B!#P`
+M!<_!HJ3,`:'TA``#?\P``$:(````S```?X0``GS(&`/J?$#``)F`_8W(%``6
+M"-```9E``!G-``!H?$"``*````#,@`!B!#P`(L_!HJ2$``-_S```1X@```#,
+M``!_R!``%ID```W,0`!G@````GQ`@`#(&`/JF8#]>7Q`P`"4P``#R!``%ID`
+M``3,P`!H@````GQ`@`"$``(YP!2``,P``$'-03!*P!2``)D```#($``6@```
+M`GQ`@`#`$@`!?%%`#(````'050``?$#``'Q!``!\04``?$&``"D<`!_,P`!*
+MS0``2Y7```/`'(``S<$@$-V#```%7"``S```8H````'8'T$`?$#``'Q!``!\
+M04``?$&``,S``$S-``!-W8,```5<H`"````!V!]!`'Q`P`!\00``?$%``'Q!
+M@`#,P`!.S0``3]V#```%7,``@````=@?00!\0,``?$$``'Q!0`!\08``S,``
+M4,T``%'=@P``!5SXX(````'8'T$`?$#``'Q!``!\04``?$&``,S``%+-``!3
+MW8,```5<^("````!V!]!`'Q`P`!\00``?$%``'Q!@`#,P`!4S0``5=V#```%
+M7.``@````=@?00!\0,``?$$``'Q!0`!\08``S,``5LT``%?=@P``!5SP`(``
+M``'8'T$`?$#``'Q!``!\04``?$&``,S``%C-``!9W8,```5<\_R````!V!]!
+M`-!#(`!\0(``H````,R``&+00Z``?$"``*````#,@`!BT$/``'Q`@`"@````
+MS(``8M!#^.!\0(``H````,R``&+00_B`?$"``*````#,@`!BT$/@`'Q`@`"@
+M````S(``8M!#\`!\0(``H````,R``&+00_/\?$"``*````#,@`!BR!0#X,Q#
+M``#,0P``S$,``'U%P`#-PP``T$,``'Q`@`"@````S(``8GQ`P`#($`/BR!0#
+MY<@8`^/('`/DS8$A:<W!(6K,P2%KS`$A;`0@``1]H8``?99``I9`_-G-@`/C
+M,2@``\`M\``E&``(?:V`"WVI@`R````!S8`#XS",___030``?$"``*````#,
+M@`!BR!0`(!58``*5@/__R!0`(,P``&[,02&`?$#``,S!(8W,02&!*-``'S18
+M@`#-@2&,E0#\O\Q!(8+(%``@F4#__\@4`""````"?$"``'Q`P``HT``8,1``
+M`<`6`("5```#P"H`!'S4P`S,P2%\S$$A?<Q!(7Y\08``';```S:@(7^;```#
+M09P`!00<`$"9P```"=P``<PA``#()``$*FP`'T&<``6:P/_ZS(``8H````)\
+M0(``?$#```34`^:````!S%0``(```WS,0`/JP!R```1,H`#-P2`0?$$``,@4
+M``D$&```!!P`",V``'$)W``!!9@``<T-``"9P/_\S(``8H```WS-0`!QP`X!
+M`,P``$',P3!*R#P`?\P``'^````!S```?\P``'^(````S```?P``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````0,Q`!``!``7
+M``8`(0`(`"<`*``H`",`*0`I`"H`)@`K`"D`+0`X`"X`/P`O`$H`-`!,`#8`
+M,``Y`*\`.@#/`#L`Y``\`/P`/0%K`#\`K0!!`S8`0P-)`$0!C@!%`/P`1@&L
+M`$<!K`!(`?X`20(,`$H"50!+`H(`4@)?`%,"<0!4`H<`5P*9`&`"G0!A`JP`
+M8@*V`&,"P`!D`LH`90+4`&8"W@!G`N@`:`+R`&D"]@!J`OH`:P+^`&P#`@!M
+M`P8`;@,*`&\##@!P`Q(`<@-C`'0#:0!Y`V<`?`,<``\#>``/`W@`#P-X``\#
+M>``/`W@`#P-X``\#>``/`W@`#P-X``\#>``/`W@`#P-X``\#>``/`W@`#P-X
+H``\#>``/`W@`#P-X``\#>``/`W@`#P-X``\#>``/`W@`#P-X``\#>```
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV730_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV730_pfp.bin.uu
new file mode 100644
index 0000000..d4b3c63
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV730_pfp.bin.uu
@@ -0,0 +1,79 @@
+begin 644 RV730_pfp.bin
+M?$"``*````!^@H`+@````-P#``#,@`!`T$``0'Q`@`"@````?H*`"\@8``XQ
+MF``!?$)``)6``CI\0H``R!P`',`WP`!\0,``?$$``'RT@`O`-@`#F<```,@<
+M`!Q\M(`,)-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``0,Z``$#,P`!`W#H`
+M`)>`_][-``!`?$#``(```!A\00``U``#0-0`#\#4``^BR!@`#H````PQF``"
+MU``#P-0`#\#4``^BR!@`#BB,``@PS``/-!```7T-``B````,?9&`"\R``$#0
+M0`!`?$"``*````!^@H`+U``#0-0`#\#4``^BS(``0-!``$!\0(``H````'Z"
+M@`O4``/`U``/P-0`#Z+,@`!`T$``0'Q`@`"@````?H*`"\Q``_F```))S$`#
+M^,`W__]\04``ST&BGL@@`_C('`/Y9B``(,@8`_M]X<`L?5C`"'S<P"!I$``@
+MP#8``\P``%1\M(`,@```:<R``$!\08``S8&BGLR``$"```!GS8``0,`9___,
+M@`!`S8&BGGQ`P`!\00``?$%``,S!H?K-`:'YS4&BG<S``$#-``!`S4``0,Q`
+M`$!\0(``H````'Z"@`O,``!4S(``0'Q`P`!\00``?$%``,S!H?K-`:'YS4&B
+MG<S``$#-``!`S4``0-!``$!\0(``H````'Z"@`M\0,``,-```<S!HI^5```#
+M!!0``004``+-0`/[S(``0(````#,P`!`?$#``,R``$#,P:*B@````,S``$!\
+M0,``*-0`'\R``$"50``#?$$``,S``%<I&``?S,``0)6```/-``!`S0``6(``
+M`DG,``!_R"``%\@P`"*:```&#B@``<@D`!X*9``!U``20,Y``$#`-L``EH``
+M!S=T>0`$'``!ST``0,W``$#/``/Z?`,``,H,`!!\00``E,``!'Q!0`#4(`+$
+MS>``1)L```M\08``S```2\V@`$G-(`!!S6``0<V@`$$&(``!S@``5H```DG,
+M``!_R"@`(,@L`"',``!C?NI``65T`"!_4T`L)IP``GWUP"!I^``@SH``2\Y@
+M`$G-X`!!SZ``0<Y@`$$G'``"??7`(&GX`"!]LD`!SP``2\Y@`$G-X`!!SZ``
+M08```+S.8`!!R"``%\@P`"*:```&#B@``<@D`!X*9``!U``20,Y``$#*#``0
+M?$$``)3```O`-L``EH``!S=T>0`$'``!ST``0,W``$#/``/Z?`,``(```+5\
+M04``S```2(```.X`````R"``%\@<`",.)``"F<``%7Q!@``*(``!S@``5M0`
+M!$#,``!`P#;``,H4`!.60``'-W1Y`,]``$#,``!`R#`#^H```0//```BS```
+M(I5``4;,``!_S*``1H````#,(`!&@``"2<P``&3((``7R!``'Y8```4)$``!
+MU``$0,T``$#-```BS(``0-!``$#(#``EE,#^[,@0``C-``!`U``/P(````#4
+M``^B?$#``'Q!``#,P`/]S0`#_,S``$+-``!"*10`'RD8`!`QF``'.UP``7UV
+M``N9@``%?5Y`"\P``$*```))S```32F8``$I+``(F8``/3+L``&6```$*3``
+M#(```DG,``!"!!0`$,U``$(S,``!-"@``80``5W(%``#FT``&P0X``R$``%=
+MR!0``YM``!<$.``(A``!7<@4``.;0``3!#@`!(0``5W(%``#FT``%<@,`_V:
+M@``)R!`#_)L``0',``!-!!0`$,S``$+-``!"@``!-<U``$*6P`#ZS```38``
+M`DG,``!.FL```\P``$W,``!.WX,``(````#8`P'_FL``\,P``$V```))S```
+M3L@8``/('``#R"```WU=0`-]H<`#?5U`#"H0`!\IG``??1T`"WT70`N(````
+M?I*`"Y9```3,``!.@``"2<P``$($.``(SX``0L@(``/(#``#R!```\@4``/(
+M&``#R!P``\@D``/(*``#*?P`'RJP`!]_\\`+*/``'W_SP`LI<``??_/`"WV(
+M@`%]S,`!?E$``7Z50`%\D(`"?-3``GR\@`N:P``#?(]`"SBT``&;0`#!S```
+M39O``+_,``!.R`P#_<@0`_S,P`!"@``!;LT``$+4``-`U``/P-0`#Z+,@`!`
+MS$``0,Q``$#,0`!`?$#``,S``$#,P``-@````-!``$!\0,``?$$``&44`"!]
+M34`L)%@``GU9@"!\0<``S8``0FF8`"#-@`!"S<``0L`CP``%Y``"?*"`"R9D
+M`!!\I(`,S(``0,W``$#,P`!`E<``#LT``$`)W``!R"@``Y:```C.@`!`R#0`
+M'9=```#(-``=)J@`"(0``DS,*P``F<#_]PG<``'<.@``EX``!'Q!@`"```&B
+M)9@``J````!]@(``R!@`'7Q`P`!DT``(E8```,@8`!W,$P``S(``0,S``$"`
+M````S$``0,@0`!]\0,``S(``0'S10`S-0`!`!1@``8````#-@``B?$#``&10
+M`""$``),S```87S0P"S((``7R-8``)E```A\0X``WX,``,^@`$^$``),S```
+M8H````#00`!_@``"2<P``&*$``),S```8<@@`!=\0,``P#;_`,@0``W`,#__
+M?/5`"WU1@`M]@8`/F8``"'SS@`O?@P``SZ``3X0``DS,``!B@````-!``'^`
+M``))S```8H0``DQ\0,``*-P`")7``!DPW``0?$$``)G```1D5``@@``"",D=
+M``!]%0`LR1X``'Q"``!\0D``?$&``'WEP`M]XH`'FH``#D&L``6:P```"NP`
+M`3#<`!"9P``$`````(```@O)'0``@``""\D>``#,@`!`S,``0-!``$#(#``E
+ME,#]Y,@0``C-``!`U``/P(````#4``^BU``#0-0`#\#4``^BS(``0-!``$!\
+M0(``H````'Z"@`O4``/`U``/P-0`#Z+,@`!`T$``0'Q`@`"@````?H*`"WQ`
+MP``PT``&#1``!ID```?(%``5F4``!<P``%+4``-`U``/P-0`#Z+,@`!`S,``
+M0(````#00`!`?$#``,Q-``#<.@``EX#]O03,``&```)"S$T``(````#00`!_
+MS```?X````#,``!_S```?X@```#,``!_````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````,"(@`$`BH`!0"?``(``P`&`#P`!P`G``@!D0`)`$0`
+M"@`M`!`"1P`7`/``(@'7`",!Z``F`$P`)P!?`"`!&@`H`)(`*0!/`"H`@P`K
+M`&0`+P"-`#(`V``T`C(`-@!T`#D!"@`\`?P`/P"?`$$`!0!$`90`2`&=`$D!
+MQ0!*`<\`50(E`%8"+0!@``H`80`J`&(`,`!C`#``9``P`&4`,`!F`#``9P`P
+M`&@`-P!I`#\`:@!'`&L`1P!L`$<`;0!'`&X`1P!O`$<`<`!'`',"1P![`D``
+M```%````!0````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+1!0````4````%````!0````4`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV770_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV770_me.bin.uu
new file mode 100644
index 0000000..ab7c524
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV770_me.bin.uu
@@ -0,0 +1,124 @@
+begin 644 RV770_me.bin
+MS``#ZGQ`@`"@````S(``8H````'00`!_@````<Q``$%\0,``P!8`!##0/_]]
+M%0`,S!$``"C8`!XQF``!*-P`'\@@``25P``&?$)``,P``&)^5H`,S"D``,@D
+M``1^)@`+E8``!GQ"P`#,``!B?M<`#,PQ``#(+``$?BX`#,P``&(Q$#__@```
+M`<X1``!\0,``@````<Q``$"````!S$$B5WQ!@`#,0`!%S$``2,Q!(ES,0:'\
+M?$"``*````#,@`!BS$``1<Q``$A\0,``S$$B7,Q!H?Q\0(``H````,R``&+,
+M``!%S```2,Q!(ES,0:'\?$"``*````#,@`!B!`RA_<`2``',``!%S```2'S0
+MP`S,02)<S$&A_-!-``!\0(``H````,R``&*````!S$$B77Q`@`!\0,``P"H`
+M`GQ!``!]*0`,,)0``3"8``8PG`,`*=P`"'Q"``!\0D``E4``#\`N``0%\")8
+M?R\`#,PQ``#(*``$S,$A:<T!(6K.@2%K#;0``LP!(6R70``.#;0``(```'O(
+M-``*#;0``I=```D-M```P"X`!`7P(EA_+P`,S#$``,@H``2```![R#0`"I=`
+M``1^`H``@```>\@T``H-M``$ET#_C`````#.`2%MSD$A;L@H``/(-``*FT``
+M!`0\``6$``)MS```8@WT``"70``+R"P#YLZ!HK?`,``&?O-`*,`P`"!_:X`@
+M?[/`*<^!HL2````!S\&BT0WT``&70``+R"P#Y\Z!HKO`,``&?O-`*,`P`"!_
+M:X`@?[/`*<^!HL6````!S\&BT@WT``*70``+R"P#Z,Z!HK_`,``&?O-`*,`P
+M`"!_:X`@?[/`*<^!HL:````!S\&BT\@L`^G.@:+#P#``!G[S0"C`,``@?VN`
+M('^SP"G/@:+'@````<_!HM2````!S$``0GQ`P`!\00``*10`'3%4``&90``-
+M,1@0`,@<`!$)W``!E<#__\@<`!',P2$`S0$A`<S!(0+-`2$#!!@`!(```Y_-
+M@:*DP"H`!)6```@VJ"&CS"D``,@H``3('``1#>0`0)9`___('``1S,$A<,T!
+M(7'((``2E@```,@@`!*```.?S```9'Q`P`!\00``S```1<P``$A`U``#S4$B
+M7,T!H?S`&@`!!!RA_7W9P`Q\0@``",P``08D``$&*``"SAT``,Y=``"8P/_Z
+MSIT``'Q`@`"@````S(``8GQ`P``PT``!*,P``7Q!0`"5```&?$&``,U!(6W-
+M@2%N@```\\@<``/`(@`$?A8`#,PA``#('``$?$)``)C```1\0H``@````<WE
+M``#.02%ISH$A:LW!(6N````!S`$A;'Q`P`!\00``?$%``'Q!@`!\0<``**0`
+M"#)D`/\.:``\EH``"GP"``!\0@``'C```\P``&J;```#0B``!00@`$"```$0
+M?`)``'X"0`":0```"F0``3#L`!":P``*S```8L`J``3(+``A?I*`#,P``$',
+M*0``SL``(8```2#(,``$S0$A;<U!(6[(,``#?Q\`"S#T``<G>``!ET``*@>X
+M`26?@````````(```35_&X`$@``!.7\;@`6```$]?QN``H```4%_&X`#@``!
+M17\;@`>```%)?QN`!H```4XHI``(FX``&2BD``B```%>,F0`_YN``!4HI``(
+M@``!7C)D`/^;@``1**0`"(```5XR9`#_FX``#2BD``B```%>,F0`_YN```DH
+MI``(@``!7C)D`/^;@``%**0`"(```5XR9`#_**0`"#)D`/\.:``\FH#^L2CL
+M``A\0T``?$.``'Q#P`"6P``'S```8L]!(6G/@2%JS\$A:X````',`2%L@```
+M`<_U``#,``!KA``#H@YH`#R:@``$R"@`%8````'00`!_EH#_JWX"0`"$``([
+MP`X``LP``$&```(YS,$P2GQ`P`!\00``P!X``2DD`!+`(@`"ED``!<`F``3`
+M)__[?24`"\`F``!]TH`+?A+`"WTE``Q\04``?$&``,S!(6F:@``*S0$A:LU!
+M(6N6P/Z"S8$A;,@P`!B7````R#``&(````',```8A``#HLP``'_(%``3R!@`
+M%,U!(6N6P/YVS8$A;(```8+(,``8R`P`")C```#(#``(?$$``)4```(`````
+M?$%``,@@``G,0`!#S@&A],Q``$3`#H``?$)``'Q"@``JK``?EL#^8\`U\`#.
+M0`/B,G@``R9\``A_]\`+?_O`#"IX`!C/P`/CSX`#Y":P``)_/P``SP`#Y8``
+M`Q]\@,``?$#``"C0``@Q$``/E0``#R4H``$&J`&SGH````````"```'4P!((
+M`(```>+(%``/@``!Z<@4`!"```'PS,&BI(```?G(%``1,-``/PTH`!6:@``2
+M#2@`'IJ``!X-*``@FH``(PTD``\-*``0?FJ`#)J``"8-(``$#20`%`TH`"A^
+M8D`,?J:`#)J``"K(%``1@````<S!HJ3`$@@`?$%``'T,P`S`$@`(*5@``RE<
+M``Q\0@``?='`"R8@`!1^'D`,?DZ`#,Z!HJ2````!S8&A_L@4``\$$"$.E4``
+M`,@4``_040``@````<S!HJ3(%``0!!`A")5```#(%``0T%$``(````',P:*D
+MS,&BI`00``'-```9A``#HLP``'_($``9F0```,@0`!F````"?$"```00(0`)
+M5``!E4#__\@4`!'040``@``#G\S!HJ1\0,``S$``#93`_?_,0``.?$$``)4`
+M``4(S``!R!0`!9E``!0`````F,#_^WQ!``"````"?0"``,@4``5\0,``F4``
+M#,@8``Q\00``E8#][L@@``[('``-9B``('X>`"PE)``"?F)`((````',Y@``
+M?$$``,P``&S,``!MR!@`'\@<`!YEF``@?=G`+'S4P`S,W@``1=P`!,@H`!>6
+M@``/P`X``2AH``@JK``6,J@`_PZP`$E_+P`+EP``!@````#(%``%?$#``(``
+M`B-\00``@``")M!``'^$``([S```0<S!,$J4````R#P`&@0\``7/P:*DP#8?
+MD,`X?_]\`\`0?WM`#,]!(7S/P2%]S`$A?L`Z``0$-"%_?WM`#,PU``#(/``$
+M*_P`'P0X`""7P``%S```8IN````+N``!@``"1\P``'',`:'T!#@`%L`V``+/
+M@:*DB````,]!(!!\0,``*-``')4```4$U``!S4``98````'-0`!H"50``H``
+M``'-0`!FA``";,@8`^I\0,``F8#]G<@4`!8(T``!F4``*\T``&A\0(``H```
+M`,R``&($/``%S\&BI,P!H?2$``.BS```1H@```#,``!_A``"?L@8`^I\0,``
+MF8#]B\@4`!8(T``!F4``&<T``&A\0(``H````,R``&($/``BS\&BI(0``Z+,
+M``!'B````,P``'_($``6F0``#<Q``&>````"?$"``,@8`^J9@/UW?$#``)3`
+M``/($``6F0``!,S``&B````"?$"``(0``CO`%(``S```0<U!,$K`%(``F0``
+M`,@0`!:````"?$"``,`2``%\44`,@````=!5``!\0,``?$$``'Q!0`!\08``
+M*1P`'\S``$K-``!+E<```\`<@`#-P2`0W8,```5<(`#,``!B@````=@?00!\
+M0,``?$$``'Q!0`!\08``S,``3,T``$W=@P``!5R@`(````'8'T$`?$#``'Q!
+M``!\04``?$&``,S``$[-``!/W8,```5<P`"````!V!]!`'Q`P`!\00``?$%`
+M`'Q!@`#,P`!0S0``4=V#```%7/C@@````=@?00!\0,``?$$``'Q!0`!\08``
+MS,``4LT``%/=@P``!5SX@(````'8'T$`?$#``'Q!``!\04``?$&``,S``%3-
+M``!5W8,```5<X`"````!V!]!`'Q`P`!\00``?$%``'Q!@`#,P`!6S0``5]V#
+M```%7/``@````=@?00!\0,``?$$``'Q!0`!\08``S,``6,T``%G=@P``!5SS
+M_(````'8'T$`T$,@`'Q`@`"@````S(``8M!#H`!\0(``H````,R``&+00\``
+M?$"``*````#,@`!BT$/XX'Q`@`"@````S(``8M!#^(!\0(``H````,R``&+0
+M0^``?$"``*````#,@`!BT$/P`'Q`@`"@````S(``8M!#\_Q\0(``H````,R`
+M`&+(%`/@S$,``,Q#``#,0P``?47``,W#``#00P``?$"``*````#,@`!B?$#`
+M`,@0`^+(%`/ER!@#X\@<`^3-@2%IS<$A:LS!(6O,`2%L!"``!'VA@`!]ED`"
+MED#\U\V``^,Q*``#P"WP`"48``A]K8`+?:F`#(````'-@`/C,(S__]!-``!\
+M0(``H````,R``&)\0,``?$$``"DD`!@R9``!FD``$\@4`"`56``"E8#__\@4
+M`"#,``!NS,$A@,T!(8W,02&!*10`'S18@`#-@2&,E4#\N<Q!(8+(%``@F4#_
+M_\@4`""````"?$"``'Q!0`!\08``?$'``&6T`"!_5T`LU#>!`$=T``34-X$`
+M1W0`!-0W@0!'=``$"=P`!-0W@0"9P/_X1W0`!"DD`!_`.``9ED#\H<`^``3/
+M@2'X-^`A^<PA``#((``$*B``&#(@``&:`/_[SX$A^(````)\0(``?$#``"C0
+M`!@Q$``!P!8`@)4```/`*@`$?-3`#,S!(7S,02%]S$$A?GQ!@``=L``#-J`A
+M?YL```-!G``%!!P`0)G````)W``!S"$``,@D``0J;``?09P`!9K`__K,@`!B
+M@````GQ`@`!\0,``!-0#YH````',5```@``#G\Q``^K`'(``!$R@`,W!(!!\
+M00``R!0`"008```$'``(S8``<0G<``$%F``!S0T``)G`__S,@`!B@``#G\U`
+M`''`#@$`S```0<S!,$K(/`!_S```?X````',``!_S```?X@```#,``!_````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````0,S`!``!``7
+M``8`(0`(`"<`*``H`",`*0`I`"H`)@`K`"D`+0`X`"X`/P`O`$H`-`!,`#8`
+M,``Y`*\`.@#0`#L`Y0`\`/T`/0%L`#\`K0!!`S@`0P-L`$0!CP!%`/T`1@&M
+M`$<!K0!(`@``20(.`$H"5P!+`H0`4@)A`%,"<P!4`HD`5P*;`&`"GP!A`JX`
+M8@*X`&,"P@!D`LP`90+6`&8"X`!G`NH`:`+T`&D"^`!J`OP`:P,``&P#!`!M
+M`P@`;@,,`&\#$`!P`Q0`<@.&`'0#C`!Y`XH`?`,>``\#FP`/`YL`#P.;``\#
+MFP`/`YL`#P.;``\#FP`/`YL`#P.;``\#FP`/`YL`#P.;``\#FP`/`YL`#P.;
+H``\#FP`/`YL`#P.;``\#FP`/`YL`#P.;``\#FP`/`YL`#P.;``\#FP``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/RV770_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/RV770_pfp.bin.uu
new file mode 100644
index 0000000..9d97399
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/RV770_pfp.bin.uu
@@ -0,0 +1,79 @@
+begin 644 RV770_pfp.bin
+M?$"``*````!^@H`+@````-P#``#,@`!`T$``0'Q`@`"@````?H*`"\@8``XQ
+MF``!?$)``)6``E)\0H``R!P`',`WP`!\0,``?$$``'RT@`O`-@`#F<```,@<
+M`!Q\M(`,)-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``0,Z``$#,P`!`W#H`
+M`)>`_][-``!`?$#``(```!A\00``U``#0-0`#\#4``^BR!@`#H````PQF``"
+MU``#P-0`#\#4``^BR!@`#BB,``@PS``/-!```7T-``B````,?9&`"\R``$#0
+M0`!`?$"``*````!^@H`+U``#0-0`#\#4``^BS(``0-!``$!\0(``H````'Z"
+M@`O4``/`U``/P-0`#Z+,@`!`T$``0'Q`@`"@````?H*`"\Q``_F```)AS$`#
+M^,@@`_C('`/YR!@#^\`W__]\04``ST&BGF8@`"!]X<`L?5C`"'S<P"!HT``@
+MP#8``\P``%1\M(`,@```:LR``$!\08``S8&BGLR``$#-@`!`@```:,P``%3`
+M&?__S(``0,V!HIY\0,``?$$``'Q!0`#,P:'ZS0&A^<U!HIW,P`!`S0``0,U`
+M`$#,0`!`?$"``*````!^@H`+S```5,R``$!\0,``?$$``'Q!0`#,P:'ZS0&A
+M^<U!HIW,P`!`S0``0,U``$#00`!`?$"``*````!^@H`+?$#``##0``',P:*?
+ME0```P04``$$%``"S4`#^\R``$"`````S,``0'Q`P`#,@`!`S,&BHH````#,
+MP`!`?$#``"C4`!_,@`!`E4```WQ!``#,P`!7*1@`'\S``$"5@``#S0``0,T`
+M`%B```)AS```?\@@`!?(,``BF@``!@XH``'()``>"F0``=0`$D#.0`!`P#;`
+M`):```<W='D`!!P``<]``$#-P`!`SP`#^GP#``#*#``0?$$``)3```1\04``
+MU"`"Q,W@`$2;```+?$&``,P``$O-H`!)S2``0<U@`$'-H`!!!B```<X``%:`
+M``)AS```?\@H`"#(+``AS```8W[J0`%E=``@?U-`+":<``)]]<`@:?@`(,Z`
+M`$O.8`!)S>``0<^@`$'.8`!!)QP``GWUP"!I^``@?;)``<\``$O.8`!)S>``
+M0<^@`$&```"]SF``0<@@`!?(,``BF@``!@XH``'()``>"F0``=0`$D#.0`!`
+MR@P`$'Q!``"4P``+P#;``):```<W='D`!!P``<]``$#-P`!`SP`#^GP#``"`
+M``"V?$%``,P``$B```#O`````,@@`!?('``C#B0``IG``!5\08``"B```<X`
+M`%;4``1`S```0,`VP`#*%``3ED``!S=T>0#/0`!`S```0,@P`_J```$$SP``
+M(LP``"*50`%=S```?\R@`$:`````S"``1H```F',``!DR"``%\@0`!^6```%
+M"1```=0`!$#-``!`S0``(LR``$#00`!`R`P`)93`_NO($``(S0``0-0`#\"`
+M````U``/HGQ`P`!\00``S,`#_<T``_S,P`!"S0``0BD4`!\I&``0,9@`!SM<
+M``%]=@`+F8``!7U>0`O,``!"@``"8<P``$TIF``!*2P`")F``#TR[``!E@``
+M!"DP``R```)AS```0@04`!#-0`!",S```30H``&$``%>R!0``YM``!L$.``,
+MA``!7L@4``.;0``7!#@`"(0``5[(%``#FT``$P0X``2$``%>R!0``YM``!7(
+M#`/]FH``"<@0`_R;``$8S```3004`!#,P`!"S0``0H```3;-0`!"EL`!$<P`
+M`$V```)AS```3IK```/,``!-S```3M^#``"`````V`,!_YK``0?,``!-@``"
+M8<P``$[(&``#R!P``\@@``-]74`#?:'``WU=0`PJ$``?*9P`'WT=``M]%T`+
+MB````'Z2@`N60``$S```3H```F',``!"!#@`",^``$+("``#R`P``\@0``/(
+M%``#R!@``\@<``/()``#R"@``RG\`!\JL``??_/`"RCP`!]_\\`+*7``'W_S
+MP`M]B(`!?<S``7Y1``%^E4`!?)"``GS4P`)\O(`+FL```WR/0`LXM``!FT``
+MV,P``$V;P`#6S```3L@,`_W($`/\S,``0H```6_-``!"U``#0-0`#\#4``^B
+MS(``0,Q``$#,0`!`S$``0'Q`P`#,P`!`S,``#8````#00`!`?$#``'Q!``!E
+M%``@?4U`+"18``)]68`@?$'``,V``$)IF``@S8``0LW``$+`(\``!>0``GR@
+M@`LF9``0?*2`#,R``$#-P`!`S,``0)7```[-``!`"=P``<@H``.6@``(SH``
+M0,@T`!V70```R#0`'2:H``B$``)DS"L``)G`__<)W``!W#H``)>```1\08``
+M@``!HR68``*@````?8"``,@8`!U\0,``9-``")6```#(&``=S!,``,R``$#,
+MP`!`@````,Q``$#($``??$#``,R``$!\T4`,S4``0`48``&`````S8``(GQ`
+MP`!D4``@A``"9,P``&%\T,`LR"``%\C6``"90``(?$.``-^#``#/H`!/A``"
+M9,P``&*`````T$``?X```F',``!BA``"9,P``&'((``7?$#``,`V_P#($``-
+MP#`__WSU0`M]48`+?8&`#YF```A\\X`+WX,``,^@`$^$``)DS```8H````#0
+M0`!_@``"8<P``&*$``)D?$#``"C<``B5P``9,-P`$'Q!``"9P``$9%0`((``
+M`@G)'0``?14`+,D>``!\0@``?$)``'Q!@`!]Y<`+?>*`!YJ```Y!K``%FL``
+M``KL``$PW``0F<``!`````"```(,R1T``(```@S)'@``S(``0,S``$#00`!`
+MR`P`)93`_>/($``(S0``0-0`#\"`````U``/HM0``T#4``_`U``/HLR``$#0
+M0`!`?$"``*````!^@H`+U``#P-0`#\#4``^BS(``0-!``$!\0(``H````'Z"
+M@`M\0,``,-``!@T0``:9```'R!0`%9E```7,``!2U``#0-0`#\#4``^BS(``
+M0,S``$"`````T$``0'Q`P`#,30``W#H``)>`_;P$S``!@``"0\Q-``!\0,``
+M?$$``"DD`!@R9``!ED``#\R``$!\04``?$&``'Q!P`#,P`!#S0``0S'<?__-
+MP`!#S,``0,T``$#-0`!`S8``0(````#-P`!`S,``0,T``$"`````T$``0(``
+M``#00`!_S```?X````#,``!_S```?X@```#,``!_````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````,"(P`$`BL`!0"@``(``P`&`#P`!P`G``@!D@`)`$0`
+M"@`M`!`"7P`7`/$`(@'8`",!Z0`F`$P`)P!?`"`!&P`H`),`*0!/`"H`A``K
+M`&4`+P".`#(`V0`T`C,`-@!U`#D!"P`\`?T`/P"@`$$"2`!$`94`2`&>`$D!
+MQ@!*`=``50(F`%8"+@!@``H`80`J`&(`,`!C`#``9``P`&4`,`!F`#``9P`P
+M`&@`-P!I`#\`:@!'`&L`1P!L`$<`;0!'`&X`1P!O`$<`<`!'`',"7P![`D$`
+M```%````!0````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+1!0````4````%````!0````4`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_me.bin.uu
new file mode 100644
index 0000000..f2e2b21
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 SUMO2_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`?$#``,U!(EW,0`!%
+MS$``2LT!(ES,0:'\?$"``*````#,@`!-@````,Q!(E=\08``S$``1<Q``$K,
+M02)<S$&A_'Q`@`"@````S(``3<P``$6```!ES```2L`.``',``!%S```2LQ!
+M(ES,0:'\U$VA_7Q`@`"@````S(``38````#,02)=S```1<P``$H(3``!?$$`
+M`'Q!0``=6/__&5P#\!5@`!7-@:$"S<$B5LX!(ER4P``%(20`(,Y!H?R```!\
+M",P``<T!H?S,`:$"?$"``*````#,@`!-?$"``'Q`P`#`*@`"?$$``'TI``<<
+ME``!')@`!AR<`P`5W``(?$(``'Q"0`"50``/P"X`!`7P(EA_+P`'S#$``,@H
+M``3,P2%IS0$A:LZ!(6LIM``"S`$A;)=```XIM```@```O,@T``XIM``"ET``
+M"2FT``#`+@`$!?`B6'\O``?,,0``R"@`!(```+S(-``.ET``!'X"@`"```"\
+MR#0`#BFT``270/]*`````,X!(6W.02%NR"@``\@T``Z;0``$R#P`#H0``US,
+M``!-*?0``)=```<$,**VA```WLZ!HK?/@:+$@````,_!HM$I]``!ET``!P0P
+MHKJ$``#>SH&BN\^!HL6`````S\&BTBGT``*70``'!#"BOH0``-[.@:*_SX&B
+MQH````#/P:+3!#"BPH0``-[.@:+#SX&BQX````#/P:+4P"X`!'\O``?,,0``
+MR"P`!,`P``9^\T`CP#``(']K@""(````?[/`),P``$*`````S$``'WQ`P`!\
+M00``&10`/9E``!,$%``NA``$H008`"F$``)ER!P`$P04`"J$``2A!!@`+<U!
+MHJ3('``3E<```,@<`!/,P2$`S0$A`<S!(0+-`2$#@``$GLV!HJ0=&!``E8``
+M!<@<`!,IY`!`ED#__\@<`!/,P2%US0$A=L@@`!26````R"``%!8H``&:@``$
+MS```3X``!)[,``!_@``!",S!(75\0,``?$$``,P``$7,``!*0-0``\U!(ES-
+M`:'\P!X``7Q"```(S``!!B0``08H``+.':']SEVA_9C`__K.G:']?$"``*``
+M``#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A;<V!(6Z```$TR!P`
+M`\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````S>4``,Y!(6G.@2%J
+MS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8I!_H*F@`/):```I\
+M`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4'P"0`!^`D``FD````ID
+M``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D``,[``!Z```%@R#``
+M!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%EGX````````"```%U
+M?QN`#H```7E_&X`/@``!?7\;@`R```&!?QN`#8```85_&X`1@``!B7\;@!"`
+M``&.%*0`")N``!D4I``(@``!GAYD`/^;@``5%*0`"(```9X>9`#_FX``$12D
+M``B```&>'F0`_YN```T4I``(@``!GAYD`/^;@``)%*0`"(```9X>9`#_FX``
+M!12D``B```&>'F0`_Q2D``@>9`#_*F@`/)J`_G`4[``(?$-``'Q#@`!\0\``
+MEL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/]0``S```680`!*$J
+M:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"E\`.``+,``!!@``!K,S!
+M,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``!<`F``3`)__[?24`
+M!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,S0$A:LU!(6N6P/X_
+MS8$A;(0`!*',``!_R#``&I<```#(,``:@````7Q`@`"$``2AS```?\@4`!7(
+M&``6S4$A:Y;`_C'-@2%L@``!P\P``']\0,``?$"``!24`!`15``%'(C__Q"(
+M``5\0,``%-``$!S,___`&@`$!9@;I,P9``#(&``$'9@/_WT9`!"9`/X>?8T`
+M$)D`_AS,``!8S```680`!*',@2%TR`P`%Y3`___,``!9@````7Q`@`#,``/E
+MR"P`(,`.("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(
+M#``)?$$``'Q!0`#,``/GS``#Z,P``^G,0`!#S$``1-1``'^`````?(#``'Q`
+MP``8T`'H$2@``94``!`&J`(*GH````````"```(BP!((`(```C#(%``1@``"
+M-\@4`!*```(^S,&BI(```D<<Z``_@``";WS!@`L<T``_*2@`!BDL`!9^KH`'
+MR!P`$YJ``#T$%``N@````,S!HJ3`$@@`?$%``'T,P`?`$@`(%5@``Q5<``Q\
+M0@``?='`!A(@`!1^'D`'?DZ`!\Z!HJ2`````S8&A_L@4`!$$$"$8E4```,@4
+M`!'440``@````,S!HJ3(%``2!!`A!I5```#(%``2U%$``(````#,P:*DS,&B
+MI`00``'-```9A``$H<P``'_($``;F0```,@0`!N````!?$"``"J@``0JI``4
+M?B8`!P04`"Z6```(!!@`*80``F7('``3!!0`*H0`!*$$#``MS4&BI`00(0#(
+M'``3E<```,@<`!/440``@``$GLS!HJ2$``2A!!@`*80``F7('``3!!0`*H0`
+M!*$$&``MA``"9<@<`!.````!?$"``)7```#('``3S4&BI,P!(0#,`2$!S8$A
+M`LV!(0/-@:*DB````,P``$T=F``!?$$``'Q!0`"9@``)?$(``,@\`#(1F``0
+MR!P`"SO\``&7P/__R#P`,H```H'(/``S$9@`$,@<``H[_``!E\#__\@\`#,5
+M:``=?5E`!YJ```01Y``*?B8`!\W``&;-`2%8S4$A6<X!(5K,P:*DFH`"$P40
+M``0$+``!$O``'7UQ0`<2X``0(B``#,T!(5C-02%9S@$A6H``!)[,P:*D!#P`
+M!<_!HJ3`-@`"B````,]!(!!\0,``%-``'9D```@4U``<E4#]8,`F``0B9"%4
+MS"4``(````#(*``$@``$GLU``&&$``2A''0``1QX``*;0``#R`P`*80``UO(
+M%``KFX```P00`!"$``-RS,&B4,T!H%"$``,,!!@$`(0`!*',``!CR#P`+80`
+M`QK($``IR!P`+QW<``'()``GE<``"<@T`#'(.``PR#P`+5-T`"!_MX`G1[@%
+M4,P``&+/^@``FD```,@D`"?(*``C.J@``IJ`___(*``CP#```<@H`"2:@```
+MR"@`),\``%M0V``(%-P`&,`^$``AW(``??W`!\V!(8#-P2&!42``"!4D`!A^
+M?D`'S@$A@LY!(8/-02&$?$"``*````#,@`!-A``$H1QT``$<>``"FT```\@,
+M`"J$``-;R!0`+)N```,$$``0A``#<LS!HF#-`:!@A``##`08"8"$``2AS```
+M9,@\`"Z$``,:R!``*L@<`"\=W``!R"0`*)7```G(-``QR#@`,,@\`"Y3=``@
+M?[>`)T>X!53,``!BS_H``)I```#()``HR"@`(SJH``*:@/__R"@`(\@H`"6:
+M@```R"@`)8```M'`,``"!9C``!#<``@4X``8S=D``,@<`"+()``B'=P/_\W9
+M``%^8D`'SED``M@840/8&%$$B````-@840<;^`#PP#8(`)>```/`,`"`B```
+M`,`J``3/02%\SP$A?<T!(7XBJ"%_!"0`")I````*9``!S"D``,@@``06.``?
+MFX#_^P0D``B(`````````,@,`"24P``D.-0``9E`__W($``C?0T``9D`__O(
+M#``D@``#/\@,`"64P``;.-0``9E`__W($``C?0T``9D`__O(#``EA``$H<P`
+M`'_(/`/[F\```,@\`_O00`/\P#X`!-(!(?@C_"'YA``$H<P]``#(.``$&[0`
+M/A^P``1_`L`+'N@`!'ZV0`>:0/_VP#X`!-```_Q\00``@````7Q`@`"$``-;
+M?$#``'Q`@`"@````S(``3<@\``Z7P``#TP`#YH@````$/``FS\&BI,@\`^8+
+M_``!S\`#YIO`__O,``!-!#P`!<_!HJ3,`:'TA``$H<P``$>(````S```?X0`
+M`W)\0,``?$"``*````#,@`!-!#P`(L_!HJ2$``2AS```2(@```#,``!_A``#
+M?7Q`P`!\0(``H````,R``$T$/``CS\&BI,P!H?.$``2AS```28@```#,``!_
+M@````'Q`P`"`````?$#``,`2``%\44`'@````-15``#,0`!ER#@`+<@\`"[`
+M->``P#(`!'^W@`9_]\`&([@0`"/\$`#/@2%4S\$A5<PQ(57(+``$R!P`)<@D
+M`"1]Y<`'F<#__L@<`"6````!?$"``'Q`P`!\00``&2@`,):```C(*``GR"0`
+M*)I```#()``GFD```,@D`"C,``/@?$%``'Q!@``5'``?S,``Q\T``,B5P``#
+MP!R``,W!(!#A@P``!5P@`,P``$V`````W!]!`'Q`P`!\00``?$%``'Q!@`#,
+MP`#)S0``RN&#```%7*``@````-P?00!\0,``?$$``'Q!0`!\08``S,``R\T`
+M`,SA@P``!5SI0(````#<'T$`?$#``'Q!``!\04``?$&``,S``,W-``#.X8,`
+M``5<Z("`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#/S0``T.&#```%7,``
+M@````-P?00!\0,``?$$``'Q!0`!\08``S,``T<T``-+A@P``!5SP`(````#<
+M'T$`?$#``'Q!``!\04``?$&``,S``-/-``#4X8,```5<\_R`````W!]!`-1#
+M(`!\0(``H````,R``$W40Z``?$"``*````#,@`!-U$/I0'Q`@`"@````S(``
+M3=1#Z(!\0(``H````,R``$W40\``?$"``*````#,@`!-U$/P`'Q`@`"@````
+MS(``3=1#\_Q\0(``H````,R``$T$'*``S$.@`'Q`P`#8'\$`?$"``*````#,
+M@`!-!!S``,Q#P`!\0,``V!_!`'Q`@`"@````S(``37Q`P`!\00``E,```WQ!
+M0`!\08``S`/S_,Q#\_S,0_/\?$"``*````#,@`!-P!X`$,@,`"E0T``($%0`
+M`H``!#5]%8`@P!X`(,@,`"I0T``("%0$`!%4``)]48`@S<``8M1:``!\0(``
+MH````,R``$U\0,``'-```Q$H``&5```*!J@$/YZ```!\08``@``$37Q!P`"`
+M``13?$'``(``!%E\0<``?$&``'Q!P``4U``0!52@`(````#-E0``P"(`!`68
+MH`!]H8`'S!D``(``!$G(&``$P"(`!,V!)=8B("77S"$``(``!$G(&``$S8$A
+M;<W!(6Z```1)R!@``WQ`P`"`````S$P#X!R,___430``?$"``*````#,@`!-
+MR!0`(S%8``25@/__R!0`(\P``%O,02&`($R``,S!(8$4T``?S$$A@LQ!(8.5
+M`/N0S$$AA,@4`".90/__R!0`(X````%\0(``P!8`!"%4(4#,50``R!@`!(``
+M``#,``/@?$#``!C0`#C`%@"`E0```\`J``1\U,`'S,$A?,Q!(7W,02%^?$&`
+M`!3\`!\=F/__.;```R*@(7^;```#09P`!00<`$"9P```"=P``<PA``#()``$
+M%FP`'T&<``6:P/_ZS(``39O`^VH`````@````,P``^#`#@$`S```0<S!,$K(
+M/`!_S```?X````#,``!_S```?X@```#,``!_````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01@`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!B`"@`5``I`&,`*@!@`"L`
+M8P`L`%<`+0!J`"X`;0`O`'8`,`!X`#(`Z0`T`(T`-0!C`#@`5P`Y`.L`.@$3
+M`#L!)@`\`3X`/0&N`#X!TP`_`.@`001E`$($=P!#!'T`1`'N`$4!/@!&`@4`
+M1P(%`$@"!0!*`IP`2P.$`$P"J`!-`N(`3@,N`$\#-P!1`W@`4@-6`%,#;0!4
+M`X8`5P.(`&`#H`!A`[@`8@.,`&,#P@!D`\P`90/6`&8#X`!G`^H`:`/T`&D#
+M^`!J!"D`:P/\`&P$``!M!`0`;@0(`&\$#`!P!`0`<00O`'($'@!S!!``=`07
+M`'4$.@!]!%T`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`
+M#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/
+.!)H`#P2:``\$F@`/!)H`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_pfp.bin.uu
new file mode 100644
index 0000000..be6ee20
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO2_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 SUMO2_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-OS$``*ID```4`````S$``*X```V_,0``LS$``+8``
+M`V_,0``N'(P``LR``$"8P``$S$``0(```V_,``!2@``#;\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``7Q`P`!\04``@```.7Q!@`!\0,``!!0``<`:``-\
+MF(`'?$'``,@0`"S((``K41``('TA`"=\T,`@E4#_P530`"#,P`!"S0``0M$`
+M`$+((``#R"0``\@H``.6`/^YR"P``Y9`_[?(,``=FP``!,P``%78``/`S```
+M0,@P`!;`-@`$R#@`#1LP`"=_>T`'ST``0,P``$#.``!`SD``0,Z``$"7```#
+MSL``0-"``%P)5``!S(``0,P``$#,``!`S```0,W``$"50/^>?-C`((```$%4
+MT``@?$#``'Q!0`"```!N?$&``'Q`P``$%``!P!H``WR8@`=\0<``R!``+,@@
+M`"M1$``@?2$`)WS0P""50/^,5-``(,S``$+-``!"T4``0L@@``/()``#R"@`
+M`\@L``.6`/^#R#```Y9`_X'(-`/]?K>`$9>```-_:T`!?`-`!L]#HI[,``!L
+MS,``;<T``&W(-``=FT``!,P``%78``/`S```0,@T`!;`.@`%R#P`#1MT`"=_
+MOX`'SX``0-!``$#.``!`SD``0,Z``$#.P`!`ET```\\``$#0@`!<"50``<R`
+M`$#,``!`S```0,P``$#-P`!`E4#_7GS8P""```!V5-``(,@8`!4=F``!T```
+M;WQ"0`"5@`+#?$*``,@<`"#`-\``?$#``'Q!``!\M(`&P#8``QJX`>B7@``'
+MT$`#X(0``W+,``!_R#@#X)N```#(.`/@F<```,@<`"!\M(`'$-0``GUE0`#-
+M0`!#SH``0\T``$/,@`!`SD``0,Z``$#,P`!`X#H``)>`_SG-``!`?$#``(``
+M`+U\00``'(P``IC```G($``<F0``!,@<``:$``-US```4L@8`!6```"H'9@`
+M`L@0`!Z9`/_\R!P`"(0``W7,``!4R!@`%8```*@=F``"'(P``L@0`!V8P``.
+MR!0`29D```3('``'A``#=<P``%/(&``5E,```QB4`>@%5``&(!```7T5``.`
+M``"H?9&`!IE`__C('``'S<``0,P``$"```#FS```;L`.@(#,``!G!-"`@,P`
+M`&C-``/QS0`#\LT``_/-``/TS0`#]LT``_?-``/X@```!<T``_G,@`!`U$``
+M0'Q`@`"@````!"@``8```0G8``1`V``#0,P``$#,@`!`U$``0'Q`@`"@````
+M!"@``=@``\"```$6S```0(```178``1`V``#0,P``$#(#``IR!``*LR``$#,
+M0`!`41``('S0P"<04``"?0T`(%44`"#-``!#S4``0]!``$/,``!`?$"``*``
+M```$*``!V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=F,``
+M$<@4`$F9```$R!P`!X0``W7,``!3R`P`+\R``$#,0`!`S$``0,Q``$!\Q,``
+MS,``0-1``$!\0(``H`````0H``&90/_UR!P`!\W``$#,``!`@``!-<P``&Y\
+M0,``R!``1YD```O(%`!$F4``!,@8``G-@`!`S```0(```5_,@`!`?$#``,@0
+M`$>5`/_WR!0`19E```3(&``*S8``0,P``$"```%?V``(0'Q`P`#($`!'F0#_
+M_`````#,@`!`S,``0-1``$!\0(``H`````0H``'($`!&V``'0,T``$"$``%V
+MS0``0,@,`$.4P``*R!0`2(```6\$$``#R!``1M@`!\#-``!`A``!=LT``$#(
+M%`!(G4```,P``&K(*``6'J@``9J```/`*0`!B````,`L`5;.@`!<V``(P,[`
+M`$"(````S```0!R,``+($``>E,``",@4`!R9```*R!P`"(0``W7,``!4@``!
+MD,R``$"90``$R!P`!H0``W7,``!2S(``0(````#40`!`S$``)\Q``"B```-O
+MS```:\`R``/`-___@``!FWRP@`=\0T``R"``*,@<`"?(&``FST.BGGQ!0`!2
+M(``@?>'`)WU8P`-\W,`@5-``((```;#,@`!`?$&``,R``$"```&MS8``0,`9
+M___,@`!`S8.BGGQ`P`!\00``?$%``,S#H?K-`Z'YS4.BG<S``$#-``!`S4``
+M0,Q``$!\0(``H`````0H``%\0,``'-```<S#HI^5```#T$``)M"``";,@`!`
+M@````,S``$!\0,``S(``0,S#HJ*`````S,``0,@<`$Q\0,``*>```!34`!]]
+M84`&S(``0)5```-\00``S,``6148`!_,P`!`E8```\T``$#-``!:@``#;\P`
+M`'_((``??$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)S2``0<U@`$'-H`!!%1``
+M"!%4`!A]4\`'S\``+P8@``'.``!8@``#;\P``'_((``?R@P`%Y3```5\00``
+MV"`"QH```=W.(`!&S```2(```?,`````R"``'WQ!@``*(``!RA0`&LH8`!=]
+M68`'E8``!<X``%C,H`!&@````,U@`$;,H`!$@````,U@`$2```-OS$``:L@,
+M`_J8P``+T$`#^L@8`$+('`!#R!``'<@4`!P1$``!F8#_6'T5``>9P/]@````
+M`-```_J`````?$#``,R``$"`````U$``0'Q`P`!\00``?$.``'Q#P``$'``"
+MSX``0L_``$+-P`!"!!P`!,S``$+-``!"S<``0@0<```$(``!?`)``,@4``/(
+M&``#49@`('U90"?(*``#R"P``\@P``/(-``#4NP`('ZN@"=3=``@?S<`)W\K
+M0"%^=D`@5J@`/U<P`#]^LH`&?BH`!IG`__()W``!EH#_X5/T`"!_>T`G?65`
+M(%58`"#,``!;S78``,VV``#((`!!F@```,@@`$&````!?$"``'Q`P`!\00``
+MS,`#_LT``__,P`!"S0``0A44`!\9&`#P)UP``7UV``:9@``%?5Y`!LP``$*`
+M``-OS```3168``$5+``(F8``,1[L``&6```$%3``#(```V_,``!"!!0`!,U`
+M`$(?,``!("@``00X``0$/```R!0``\@8``/('``#R"```WU=0`U]H<`-?5U`
+M!Q80`!\5G``??1T`!GT70`9^DH`&FT``$@NX``2;P/_R"_P``<@,`_Z:@``)
+MR!`#_YL``/C,``!-!!0`!,S``$+-``!"@``"8<U``$*6P`#QS```38```V_,
+M``!.FL```\P``$W,``!.EX#]>^.#``"`````W`,!_Y9```3,``!.@``#;\P`
+M`$+2``!"R`@``\@,``/($``#R!0``\@8``/('``#R"0``\@H``,5_``?%K``
+M'W_SP`84\``??_/`!A5P`!]_\\`&?8B``9?```U]S,`!?E$``7Z50`%\D(`,
+M?-3`#)K```-\CT`&)+0``9M``,C,``!-@``#;\P``$[(#`/^R!`#_\S``$*`
+M``*-S0``0GQ`P`!\00``?$+``'Q#``#`.P`??$-``'^W@`;`/A``EX#]2'T]
+M``=_/P`'&10`.\P``%N50``3R!0`0#%8``*5@/__R!0`0,P``&,A'(``S,$A
+MA<W!(885%``?SL$AA\\!(8B50/TWST$AB<@4`$"90/__R!0`0(````%\0(``
+MS(``0,S``$#-``!`SL``0,\``$"`````ST``0-"``^#,@`!`A``#<LQ``$#(
+M#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``"ZA30`!^9`/T<T$`#X(0`
+M`W+,``!_@``"W,@,`^#,@`!`S,``0(@```#40`!`!!0#X`08`!_,%```!50`
+M`9F`__X)F``!S(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`-___
+M@````,]``_U\0,``%-P`'9G```?,@`!`&-P`/)G``&O,P`!`@``#;\P``&H8
+MV``\S8``9LP``&J```-OS,``0'Q`P`!04``@A``#<LP``%U\T,`GR"``'\C6
+M``"90``(?$.``..#``#/H`!/A``#<LP``%Z`````U$``?X```V_,``!>A``#
+M<LP``%W((``??$#``,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\\X`&
+MXX,``,^@`$^$``-RS```7H````#40`!_@``#;\P``%Z$``-R?$#``!S<`0"5
+MP``9'-P`$'Q!``"9P``$4%0`((```S[)'0``?14`)\D>``!\0@``?$)``'Q!
+M@`!]Y<`&?>*`$9J`_+U!K``%FL````KL``$<W``0F<``!`````"```-!R1T`
+M`(```T')'@``S(``0,S``$"`````U$``0-@``T#,``!`S(``0-1``$!\0(``
+MH`````0H``'8``/`S```0,R``$#40`!`?$"``*`````$*``!?$#``!S0``8I
+M$``&F0``!L@4`!R90``$S```4H0``W7('``&S(``0,S``$"`````U$``0(``
+M``#40`!_S```?X````#,``!_S```?X@```#,``!_S<``0(@```#,``!`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P-2``0#60`%`=D`!@$(``<!%``(`28`"0$/``H!!@`+`1(`#`%&
+M``T!4``.`60`#P%N`!`#;0`1``H`$@`8`!,`(``6`"(`)``U`"4`:@`F`9(`
+M%P'U`!@"`P`:`@4`(@,-`",#'@`G`:<`'P(7`"`"1P`H`<D`*0&6`"H!NP`K
+M`:L`+``Q`"\!Q``R`>L`-`-@`#4!F@`X`&8`.0(4`#P#,@`_`=D`00*P`$("
+MUP!#`N$`1`+N`$H"_P!5`U0`5@-;`&``I@!A`,P`8@#T`&,`W@!D`-X`90#>
+M`&8`W@!G`-X`:`$!`&D!"@!J`5H`:P$H`&P!*`!M`2@`;@$H`&\!*`!P`2T`
+M<P$6`'0!%@!U`8$````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_me.bin.uu
new file mode 100644
index 0000000..2d08543
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 SUMO_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`?$#``,U!(EW,0`!%
+MS$``2LT!(ES,0:'\?$"``*````#,@`!-@````,Q!(E=\08``S$``1<Q``$K,
+M02)<S$&A_'Q`@`"@````S(``3<P``$6```!ES```2L`.``',``!%S```2LQ!
+M(ES,0:'\U$VA_7Q`@`"@````S(``38````#,02)=S```1<P``$H(3``!?$$`
+M`'Q!0``=6/__&5P#\!5@`!7-@:$"S<$B5LX!(ER4P``%(20`(,Y!H?R```!\
+M",P``<T!H?S,`:$"?$"``*````#,@`!-?$"``'Q`P`#`*@`"?$$``'TI``<<
+ME``!')@`!AR<`P`5W``(?$(``'Q"0`"50``/P"X`!`7P(EA_+P`'S#$``,@H
+M``3,P2%IS0$A:LZ!(6LIM``"S`$A;)=```XIM```@```O,@T``XIM``"ET``
+M"2FT``#`+@`$!?`B6'\O``?,,0``R"@`!(```+S(-``.ET``!'X"@`"```"\
+MR#0`#BFT``270/]*`````,X!(6W.02%NR"@``\@T``Z;0``$R#P`#H0``US,
+M``!-*?0``)=```<$,**VA```WLZ!HK?/@:+$@````,_!HM$I]``!ET``!P0P
+MHKJ$``#>SH&BN\^!HL6`````S\&BTBGT``*70``'!#"BOH0``-[.@:*_SX&B
+MQH````#/P:+3!#"BPH0``-[.@:+#SX&BQX````#/P:+4P"X`!'\O``?,,0``
+MR"P`!,`P``9^\T`CP#``(']K@""(````?[/`),P``$*`````S$``'WQ`P`!\
+M00``&10`/9E``!,$%``NA``$H008`"F$``)ER!P`$P04`"J$``2A!!@`+<U!
+MHJ3('``3E<```,@<`!/,P2$`S0$A`<S!(0+-`2$#@``$GLV!HJ0=&!``E8``
+M!<@<`!,IY`!`ED#__\@<`!/,P2%US0$A=L@@`!26````R"``%!8H``&:@``$
+MS```3X``!)[,``!_@``!",S!(75\0,``?$$``,P``$7,``!*0-0``\U!(ES-
+M`:'\P!X``7Q"```(S``!!B0``08H``+.':']SEVA_9C`__K.G:']?$"``*``
+M``#,@`!-?$#``!S0``$4S``!?$%``)4```9\08``S4$A;<V!(6Z```$TR!P`
+M`\`B``1^%@`'S"$``,@<``1\0D``F,``!'Q"@`"`````S>4``,Y!(6G.@2%J
+MS<$A:X````#,`2%L?$#``'Q!``!\04``?$&``'Q!P``8I!_H*F@`/):```I\
+M`@``?$(``#HP``/,``!8FP```T(@``4$(`!`@``!4'P"0`!^`D``FD````ID
+M``$<[``0FL``"LP``$W`*@`$R"P`('Z2@`?,``!!S"D``,[``!Z```%@R#``
+M!,T!(6W-02%NR#```W\?``8<]``'$W@``9=``"H'N`%EGX````````"```%U
+M?QN`#H```7E_&X`/@``!?7\;@`R```&!?QN`#8```85_&X`1@``!B7\;@!"`
+M``&.%*0`")N``!D4I``(@``!GAYD`/^;@``5%*0`"(```9X>9`#_FX``$12D
+M``B```&>'F0`_YN```T4I``(@``!GAYD`/^;@``)%*0`"(```9X>9`#_FX``
+M!12D``B```&>'F0`_Q2D``@>9`#_*F@`/)J`_G`4[``(?$-``'Q#@`!\0\``
+MEL``!\P``$W/02%ISX$A:L_!(6N`````S`$A;(````#/]0``S```680`!*$J
+M:``\FH``!,@H`!>`````U$``?Y:`_ZM^`D``A``"E\`.``+,``!!@``!K,S!
+M,$J4````R#P`''Q`P`!\00``P!X``14D`!+`(@`"ED``!<`F``3`)__[?24`
+M!L`F``!]TH`&?A+`!GTE``=\04``?$&``,S!(6F:@``,S0$A:LU!(6N6P/X_
+MS8$A;(0`!*',``!_R#``&I<```#(,``:@````7Q`@`"$``2AS```?\@4`!7(
+M&``6S4$A:Y;`_C'-@2%L@``!P\P``']\0,``?$"``!24`!`15``%'(C__Q"(
+M``5\0,``%-``$!S,___`&@`$!9@;I,P9``#(&``$'9@/_WT9`!"9`/X>?8T`
+M$)D`_AS,``!8S```680`!*',@2%TR`P`%Y3`___,``!9@````7Q`@`#,``/E
+MR"P`(,`.("0$$#``(,PB:P04,`',``!!T!$``,S5``#.P``>R`P`"9C```#(
+M#``)?$$``'Q!0`#,``/GS``#Z,P``^G,0`!#S$``1-1``'^`````?(#``'Q`
+MP``8T`'H$2@``94``!`&J`(*GH````````"```(BP!((`(```C#(%``1@``"
+M-\@4`!*```(^S,&BI(```D<<Z``_@``";WS!@`L<T``_*2@`!BDL`!9^KH`'
+MR!P`$YJ``#T$%``N@````,S!HJ3`$@@`?$%``'T,P`?`$@`(%5@``Q5<``Q\
+M0@``?='`!A(@`!1^'D`'?DZ`!\Z!HJ2`````S8&A_L@4`!$$$"$8E4```,@4
+M`!'440``@````,S!HJ3(%``2!!`A!I5```#(%``2U%$``(````#,P:*DS,&B
+MI`00``'-```9A``$H<P``'_($``;F0```,@0`!N````!?$"``"J@``0JI``4
+M?B8`!P04`"Z6```(!!@`*80``F7('``3!!0`*H0`!*$$#``MS4&BI`00(0#(
+M'``3E<```,@<`!/440``@``$GLS!HJ2$``2A!!@`*80``F7('``3!!0`*H0`
+M!*$$&``MA``"9<@<`!.````!?$"``)7```#('``3S4&BI,P!(0#,`2$!S8$A
+M`LV!(0/-@:*DB````,P``$T=F``!?$$``'Q!0`"9@``)?$(``,@\`#(1F``0
+MR!P`"SO\``&7P/__R#P`,H```H'(/``S$9@`$,@<``H[_``!E\#__\@\`#,5
+M:``=?5E`!YJ```01Y``*?B8`!\W``&;-`2%8S4$A6<X!(5K,P:*DFH`"$P40
+M``0$+``!$O``'7UQ0`<2X``0(B``#,T!(5C-02%9S@$A6H``!)[,P:*D!#P`
+M!<_!HJ3`-@`"B````,]!(!!\0,``%-``'9D```@4U``<E4#]8,`F``0B9"%4
+MS"4``(````#(*``$@``$GLU``&&$``2A''0``1QX``*;0``#R`P`*80``UO(
+M%``KFX```P00`!"$``-RS,&B4,T!H%"$``,,!!@$`(0`!*',``!CR#P`+80`
+M`QK($``IR!P`+QW<``'()``GE<``"<@T`#'(.``PR#P`+5-T`"!_MX`G1[@%
+M4,P``&+/^@``FD```,@D`"?(*``C.J@``IJ`___(*``CP#```<@H`"2:@```
+MR"@`),\``%M0V``(%-P`&,`^$``AW(``??W`!\V!(8#-P2&!42``"!4D`!A^
+M?D`'S@$A@LY!(8/-02&$?$"``*````#,@`!-A``$H1QT``$<>``"FT```\@,
+M`"J$``-;R!0`+)N```,$$``0A``#<LS!HF#-`:!@A``##`08"8"$``2AS```
+M9,@\`"Z$``,:R!``*L@<`"\=W``!R"0`*)7```G(-``QR#@`,,@\`"Y3=``@
+M?[>`)T>X!53,``!BS_H``)I```#()``HR"@`(SJH``*:@/__R"@`(\@H`"6:
+M@```R"@`)8```M'`,``"!9C``!#<``@4X``8S=D``,@<`"+()``B'=P/_\W9
+M``%^8D`'SED``M@840/8&%$$B````-@840<;^`#PP#8(`)>```/`,`"`B```
+M`,`J``3/02%\SP$A?<T!(7XBJ"%_!"0`")I````*9``!S"D``,@@``06.``?
+MFX#_^P0D``B(`````````,@,`"24P``D.-0``9E`__W($``C?0T``9D`__O(
+M#``D@``#/\@,`"64P``;.-0``9E`__W($``C?0T``9D`__O(#``EA``$H<P`
+M`'_(/`/[F\```,@\`_O00`/\P#X`!-(!(?@C_"'YA``$H<P]``#(.``$&[0`
+M/A^P``1_`L`+'N@`!'ZV0`>:0/_VP#X`!-```_Q\00``@````7Q`@`"$``-;
+M?$#``'Q`@`"@````S(``3<@\``Z7P``#TP`#YH@````$/``FS\&BI,@\`^8+
+M_``!S\`#YIO`__O,``!-!#P`!<_!HJ3,`:'TA``$H<P``$>(````S```?X0`
+M`W)\0,``?$"``*````#,@`!-!#P`(L_!HJ2$``2AS```2(@```#,``!_A``#
+M?7Q`P`!\0(``H````,R``$T$/``CS\&BI,P!H?.$``2AS```28@```#,``!_
+M@````'Q`P`"`````?$#``,`2``%\44`'@````-15``#,0`!ER#@`+<@\`"[`
+M->``P#(`!'^W@`9_]\`&([@0`"/\$`#/@2%4S\$A5<PQ(57(+``$R!P`)<@D
+M`"1]Y<`'F<#__L@<`"6````!?$"``'Q`P`!\00``&2@`,):```C(*``GR"0`
+M*)I```#()``GFD```,@D`"C,``/@?$%``'Q!@``5'``?S,``Q\T``,B5P``#
+MP!R``,W!(!#A@P``!5P@`,P``$V`````W!]!`'Q`P`!\00``?$%``'Q!@`#,
+MP`#)S0``RN&#```%7*``@````-P?00!\0,``?$$``'Q!0`!\08``S,``R\T`
+M`,SA@P``!5SI0(````#<'T$`?$#``'Q!``!\04``?$&``,S``,W-``#.X8,`
+M``5<Z("`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#/S0``T.&#```%7,``
+M@````-P?00!\0,``?$$``'Q!0`!\08``S,``T<T``-+A@P``!5SP`(````#<
+M'T$`?$#``'Q!``!\04``?$&``,S``-/-``#4X8,```5<\_R`````W!]!`-1#
+M(`!\0(``H````,R``$W40Z``?$"``*````#,@`!-U$/I0'Q`@`"@````S(``
+M3=1#Z(!\0(``H````,R``$W40\``?$"``*````#,@`!-U$/P`'Q`@`"@````
+MS(``3=1#\_Q\0(``H````,R``$T$'*``S$.@`'Q`P`#8'\$`?$"``*````#,
+M@`!-!!S``,Q#P`!\0,``V!_!`'Q`@`"@````S(``37Q`P`!\00``E,```WQ!
+M0`!\08``S`/S_,Q#\_S,0_/\?$"``*````#,@`!-P!X`$,@,`"E0T``($%0`
+M`H``!#5]%8`@P!X`(,@,`"I0T``("%0$`!%4``)]48`@S<``8M1:``!\0(``
+MH````,R``$U\0,``'-```Q$H``&5```*!J@$/YZ```!\08``@``$37Q!P`"`
+M``13?$'``(``!%E\0<``?$&``'Q!P``4U``0!52@`(````#-E0``P"(`!`68
+MH`!]H8`'S!D``(``!$G(&``$P"(`!,V!)=8B("77S"$``(``!$G(&``$S8$A
+M;<W!(6Z```1)R!@``WQ`P`"`````S$P#X!R,___430``?$"``*````#,@`!-
+MR!0`(S%8``25@/__R!0`(\P``%O,02&`($R``,S!(8$4T``?S$$A@LQ!(8.5
+M`/N0S$$AA,@4`".90/__R!0`(X````%\0(``P!8`!"%4(4#,50``R!@`!(``
+M``#,``/@?$#``!C0`#C`%@"`E0```\`J``1\U,`'S,$A?,Q!(7W,02%^?$&`
+M`!3\`!\=F/__.;```R*@(7^;```#09P`!00<`$"9P```"=P``<PA``#()``$
+M%FP`'T&<``6:P/_ZS(``39O`^VH`````@````,P``^#`#@$`S```0<S!,$K(
+M/`!_S```?X````#,``!_S```?X@```#,``!_````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01@`!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!B`"@`5``I`&,`*@!@`"L`
+M8P`L`%<`+0!J`"X`;0`O`'8`,`!X`#(`Z0`T`(T`-0!C`#@`5P`Y`.L`.@$3
+M`#L!)@`\`3X`/0&N`#X!TP`_`.@`001E`$($=P!#!'T`1`'N`$4!/@!&`@4`
+M1P(%`$@"!0!*`IP`2P.$`$P"J`!-`N(`3@,N`$\#-P!1`W@`4@-6`%,#;0!4
+M`X8`5P.(`&`#H`!A`[@`8@.,`&,#P@!D`\P`90/6`&8#X`!G`^H`:`/T`&D#
+M^`!J!"D`:P/\`&P$``!M!`0`;@0(`&\$#`!P!`0`<00O`'($'@!S!!``=`07
+M`'4$.@!]!%T`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`
+M#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/!)H`#P2:``\$F@`/
+.!)H`#P2:``\$F@`/!)H`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_pfp.bin.uu
new file mode 100644
index 0000000..2ae2b9b
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 SUMO_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-OS$``*ID```4`````S$``*X```V_,0``LS$``+8``
+M`V_,0``N'(P``LR``$"8P``$S$``0(```V_,``!2@``#;\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``7Q`P`!\04``@```.7Q!@`!\0,``!!0``<`:``-\
+MF(`'?$'``,@0`"S((``K41``('TA`"=\T,`@E4#_P530`"#,P`!"S0``0M$`
+M`$+((``#R"0``\@H``.6`/^YR"P``Y9`_[?(,``=FP``!,P``%78``/`S```
+M0,@P`!;`-@`$R#@`#1LP`"=_>T`'ST``0,P``$#.``!`SD``0,Z``$"7```#
+MSL``0-"``%P)5``!S(``0,P``$#,``!`S```0,W``$"50/^>?-C`((```$%4
+MT``@?$#``'Q!0`"```!N?$&``'Q`P``$%``!P!H``WR8@`=\0<``R!``+,@@
+M`"M1$``@?2$`)WS0P""50/^,5-``(,S``$+-``!"T4``0L@@``/()``#R"@`
+M`\@L``.6`/^#R#```Y9`_X'(-`/]?K>`$9>```-_:T`!?`-`!L]#HI[,``!L
+MS,``;<T``&W(-``=FT``!,P``%78``/`S```0,@T`!;`.@`%R#P`#1MT`"=_
+MOX`'SX``0-!``$#.``!`SD``0,Z``$#.P`!`ET```\\``$#0@`!<"50``<R`
+M`$#,``!`S```0,P``$#-P`!`E4#_7GS8P""```!V5-``(,@8`!4=F``!T```
+M;WQ"0`"5@`+#?$*``,@<`"#`-\``?$#``'Q!``!\M(`&P#8``QJX`>B7@``'
+MT$`#X(0``W+,``!_R#@#X)N```#(.`/@F<```,@<`"!\M(`'$-0``GUE0`#-
+M0`!#SH``0\T``$/,@`!`SD``0,Z``$#,P`!`X#H``)>`_SG-``!`?$#``(``
+M`+U\00``'(P``IC```G($``<F0``!,@<``:$``-US```4L@8`!6```"H'9@`
+M`L@0`!Z9`/_\R!P`"(0``W7,``!4R!@`%8```*@=F``"'(P``L@0`!V8P``.
+MR!0`29D```3('``'A``#=<P``%/(&``5E,```QB4`>@%5``&(!```7T5``.`
+M``"H?9&`!IE`__C('``'S<``0,P``$"```#FS```;L`.@(#,``!G!-"`@,P`
+M`&C-``/QS0`#\LT``_/-``/TS0`#]LT``_?-``/X@```!<T``_G,@`!`U$``
+M0'Q`@`"@````!"@``8```0G8``1`V``#0,P``$#,@`!`U$``0'Q`@`"@````
+M!"@``=@``\"```$6S```0(```178``1`V``#0,P``$#(#``IR!``*LR``$#,
+M0`!`41``('S0P"<04``"?0T`(%44`"#-``!#S4``0]!``$/,``!`?$"``*``
+M```$*``!V``#P,P``$#,@`!`U$``0'Q`@`"@````!"@``1R,``+($``=F,``
+M$<@4`$F9```$R!P`!X0``W7,``!3R`P`+\R``$#,0`!`S$``0,Q``$!\Q,``
+MS,``0-1``$!\0(``H`````0H``&90/_UR!P`!\W``$#,``!`@``!-<P``&Y\
+M0,``R!``1YD```O(%`!$F4``!,@8``G-@`!`S```0(```5_,@`!`?$#``,@0
+M`$>5`/_WR!0`19E```3(&``*S8``0,P``$"```%?V``(0'Q`P`#($`!'F0#_
+M_`````#,@`!`S,``0-1``$!\0(``H`````0H``'($`!&V``'0,T``$"$``%V
+MS0``0,@,`$.4P``*R!0`2(```6\$$``#R!``1M@`!\#-``!`A``!=LT``$#(
+M%`!(G4```,P``&K(*``6'J@``9J```/`*0`!B````,`L`5;.@`!<V``(P,[`
+M`$"(````S```0!R,``+($``>E,``",@4`!R9```*R!P`"(0``W7,``!4@``!
+MD,R``$"90``$R!P`!H0``W7,``!2S(``0(````#40`!`S$``)\Q``"B```-O
+MS```:\`R``/`-___@``!FWRP@`=\0T``R"``*,@<`"?(&``FST.BGGQ!0`!2
+M(``@?>'`)WU8P`-\W,`@5-``((```;#,@`!`?$&``,R``$"```&MS8``0,`9
+M___,@`!`S8.BGGQ`P`!\00``?$%``,S#H?K-`Z'YS4.BG<S``$#-``!`S4``
+M0,Q``$!\0(``H`````0H``%\0,``'-```<S#HI^5```#T$``)M"``";,@`!`
+M@````,S``$!\0,``S(``0,S#HJ*`````S,``0,@<`$Q\0,``*>```!34`!]]
+M84`&S(``0)5```-\00``S,``6148`!_,P`!`E8```\T``$#-``!:@``#;\P`
+M`'_((``??$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)S2``0<U@`$'-H`!!%1``
+M"!%4`!A]4\`'S\``+P8@``'.``!8@``#;\P``'_((``?R@P`%Y3```5\00``
+MV"`"QH```=W.(`!&S```2(```?,`````R"``'WQ!@``*(``!RA0`&LH8`!=]
+M68`'E8``!<X``%C,H`!&@````,U@`$;,H`!$@````,U@`$2```-OS$``:L@,
+M`_J8P``+T$`#^L@8`$+('`!#R!``'<@4`!P1$``!F8#_6'T5``>9P/]@````
+M`-```_J`````?$#``,R``$"`````U$``0'Q`P`!\00``?$.``'Q#P``$'``"
+MSX``0L_``$+-P`!"!!P`",S``$+-``!"S<``0@0<``$$(``!?`)``,@4``/(
+M&``#49@`('U90"?(*``#R"P``\@P``/(-``#4NP`('ZN@"=3=``@?S<`)W\K
+M0"%^=D`@5J@`/U<P`#]^LH`&?BH`!IG`__()W``!EH#_X5/T`"!_>T`G?65`
+M(%58`"#,``!;S78``,VV``#((`!!F@```,@@`$&````!?$"``'Q`P`!\00``
+MS,`#_LT``__,P`!"S0``0A44`!\9&`#P)UP``7UV``:9@``%?5Y`!LP``$*`
+M``-OS```3168``$5+``(F8``,1[L``&6```$%3``#(```V_,``!"!!0`",U`
+M`$(?,``!("@``00X``@$/``!R!0``\@8``/('``#R"```WU=0`U]H<`-?5U`
+M!Q80`!\5G``??1T`!GT70`9^DH`&FT``$@NX``2;P/_R"_P``<@,`_Z:@``)
+MR!`#_YL``/C,``!-!!0`",S``$+-``!"@``"8<U``$*6P`#QS```38```V_,
+M``!.FL```\P``$W,``!.EX#]>^.#``"`````W`,!_Y9```3,``!.@``#;\P`
+M`$+2``!"R`@``\@,``/($``#R!0``\@8``/('``#R"0``\@H``,5_``?%K``
+M'W_SP`84\``??_/`!A5P`!]_\\`&?8B``9?```U]S,`!?E$``7Z50`%\D(`,
+M?-3`#)K```-\CT`&)+0``9M``,C,``!-@``#;\P``$[(#`/^R!`#_\S``$*`
+M``*-S0``0GQ`P`!\00``?$+``'Q#``#`.P`??$-``'^W@`;`/A``EX#]2'T]
+M``=_/P`'&10`.\P``%N50``3R!0`0#%8``*5@/__R!0`0,P``&,A'(``S,$A
+MA<W!(885%``?SL$AA\\!(8B50/TWST$AB<@4`$"90/__R!0`0(````%\0(``
+MS(``0,S``$#-``!`SL``0,\``$"`````ST``0-"``^#,@`!`A``#<LQ``$#(
+M#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``"ZA30`!^9`/T<T$`#X(0`
+M`W+,``!_@``"W,@,`^#,@`!`S,``0(@```#40`!`!!0#X`08`!_,%```!50`
+M`9F`__X)F``!S(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`-___
+M@````,]``_U\0,``%-P`'9G```?,@`!`&-P`/)G``&O,P`!`@``#;\P``&H8
+MV``\S8``9LP``&J```-OS,``0'Q`P`!04``@A``#<LP``%U\T,`GR"``'\C6
+M``"90``(?$.``..#``#/H`!/A``#<LP``%Z`````U$``?X```V_,``!>A``#
+M<LP``%W((``??$#``,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\\X`&
+MXX,``,^@`$^$``-RS```7H````#40`!_@``#;\P``%Z$``-R?$#``!S<`0"5
+MP``9'-P`$'Q!``"9P``$4%0`((```S[)'0``?14`)\D>``!\0@``?$)``'Q!
+M@`!]Y<`&?>*`$9J`_+U!K``%FL````KL``$<W``0F<``!`````"```-!R1T`
+M`(```T')'@``S(``0,S``$"`````U$``0-@``T#,``!`S(``0-1``$!\0(``
+MH`````0H``'8``/`S```0,R``$#40`!`?$"``*`````$*``!?$#``!S0``8I
+M$``&F0``!L@4`!R90``$S```4H0``W7('``&S(``0,S``$"`````U$``0(``
+M``#40`!_S```?X````#,``!_S```?X@```#,``!_S<``0(@```#,``!`````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P-2``0#60`%`=D`!@$(``<!%``(`28`"0$/``H!!@`+`1(`#`%&
+M``T!4``.`60`#P%N`!`#;0`1``H`$@`8`!,`(``6`"(`)``U`"4`:@`F`9(`
+M%P'U`!@"`P`:`@4`(@,-`",#'@`G`:<`'P(7`"`"1P`H`<D`*0&6`"H!NP`K
+M`:L`+``Q`"\!Q``R`>L`-`-@`#4!F@`X`&8`.0(4`#P#,@`_`=D`00*P`$("
+MUP!#`N$`1`+N`$H"_P!5`U0`5@-;`&``I@!A`,P`8@#T`&,`W@!D`-X`90#>
+M`&8`W@!G`-X`:`$!`&D!"@!J`5H`:P$H`&P!*`!M`2@`;@$H`&\!*`!P`2T`
+M<P$6`'0!%@!U`8$````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_rlc.bin.uu
new file mode 100644
index 0000000..d1a3ebc
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_rlc.bin.uu
@@ -0,0 +1,72 @@
+begin 644 SUMO_rlc.bin
+M(#@`$".X``#/@``2S``"!008``'-@``.S8`"`\P``@+-@`(!S```"\P``@C,
+M``(+S``""<P``@S,``('S``"!LV``@#(#`!`'.``@"H@`(`<Y`$`*F0!`)8`
+M``8`````FD``!`````"$``'D`````(```/$`````P!`@"\`4``#`%L``S5$`
+M`,D5``#`,/__R(X``'SQ``:5``$S1(@`!,B6``#-40``%,P`$'SQ``:5``$M
+M1(@`!,B6``#-40``@```)$2(``2$``%(`````"`X``'`,`.8A``"R!.X`!3,
+M``!7P#`#F,PQ``"(````RPD``(0``*D1N``?A``!8"`X``&$``%0(`P``,`P
+M`<#+.0``(#@``)7``$[/@``#?<'`!H0``*D@.```@```E,^```/`""&@R(T`
+M`!3,`!8<S``!F,#__0````"(`````````(0``,A3N``(P#"A]",(!`#,"0``
+M(P@(`,P)```C"`P`S`D``",($`#,"0``(P@4`,P)```C"!@`S`D``",('`#,
+M"0``P`PAMLP-``#-@`(`A```J2`X``"(`````````,`P___(C```?/$`!I4`
+M`DX$B``!R14``,U(```4S``0?/$`!I4``D@$B``!R14``,U(``#(+``:FL`"
+M0WPMP`>```!N!(@``80``*D1N``?A``!8"`X``+`,"`(P`C__LRQ``#+#0``
+MS#$``,L-``":0`"6`````(0``F(@"`(0@``!(@````"$``'S`````(```)0`
+M````S```#LP```[($`("("@!PR`<``#($`("R`@"!7^+@`?("`(!E(``%```
+M``"```'W`````(0``$T`````B`````````#-G`(#A```J2`X``"5`/_O````
+M`,`P`<"(````S[$``"`X``'/@``#R!`"`LP``@'("``:E(`!1@````#-@``.
+M`````(0``*D1N``?A``!ER`X``+,,0``R`@"`)B```0`````A```?P````"$
+M``%@(#@``<V``@&$``%0(`P``(0``*D@.```@```E`````#+B@``P`PA@<R-
+M``#`#"&#S`T``,`H``1'N``$RXX``!ST``&;0/_/1[@`!,N2``!'N``$RY8`
+M`(0``9L*J``!FH#_]@````"$``!-P`@AH(```,[`*``$R#@`2)N``)=3N``(
+MB`````````"9P`'PR#``0",P``+/``!`A``!RR`X``/(,`!`'S`#_<\``$"`
+M``'WS```5LR``@>(`````````,@)/3;(#3TWE,#_P@````#($3TXR!4].<@=
+M/3K((3T[R"4]-02H`##.@3V"S,$]@\T!/83-03V%S<$]ALX!/8<0B``#!(P`
+M&,B6`#R50/^QR-(`*'TE``$)5``!!,P`*)D`__L`````R)(`.`40`$!]"L``
+MR-8`!,`<``3(X@`4R.8`),X*`4S.;@%,",P`!`B(``0*[``$"=P``9G`__@`
+M````S0H!8,P*`63-03U'@```M0````#("`!$A```'E"(``C(.`!(EX#_0\@X
+M`@:;@``$`````(0``-X`````R#@`1Q^X``&7@``#P#@`$,^``$?(.`!''[@`
+M$)N`__X`````A```30````"$``%@(#@``9I`_Q_(.`!(A``!HL@X`@>```!7
+M`````"`(``',@``#P#``1\`((`#+#0``?,C`!IC`__X`````P#`]-<VQ``"`
+M``"4`````,^<`!;-@``.R?``&'\X@`R4@/_^`````(@`````````P#`#D,LY
+M``#`"__^?XN`!A#,`!!_CX`'S[$``(@```#+.0``B`````````#,'`(#A```
+MJ1&X`!^```"4`````,`P(`//L0``B````,LY``#`,/__R(X``'SQ``:5```R
+M1(@`!,D5``#-2@``%,P`$'SQ``:5```L1(@`!,D5``#-2@``R"P`&IK``"=\
+M+<`'@``!942(``3("`('!(@``<N.``#,R```1[@`!`2(``'+C@``S,@``$>X
+M``0$B``!RXX``,S(``!'N``$!(@``<N.``#,R```1[@`!`2(``'+C@``'-``
+M`94`__/,R```B````,S``@:$``"I$;@`'X0``6`@.``!S(```X0``*D@.```
+M@```E`````"```*=P#`!P8@`````````P`@A@,S)``#`""&"S0D``,`((82(
+M````S4D``,@X`@<'N``!RX@``,`,(8',C0``P`PA@\P-``#`*``$![@``<N,
+M```<]``!FT``F0>X``'+D```![@``<N4``"$``&;"J@``9J`__8`````A```
+M3<`((:"```&JP"@`!,@H``.6@`$%`````,V```XJC`'EF,``YR`(``$JC`'D
+M?.#`!IC``'`@"``!S(```X```(\`````(`@``8```)3,@``#A``!2`````#`
+M,"`(A``"R"`X___`,"`(S#$``,LY``#`,`.8A``"R"`X`0#`,`.8S#$``,L)
+M``#`,"&VB````,PQ``#(*``!EH#_W0`````@"``!S8``#LR```&```"/````
+M`,@X`$13N``((`@"$,`P___+C@``?/%`!I5`_P3,R```!(@``<P(```$B``!
+MS`@```2(``&```'H1[@`!!ZH`/_.@``,B`````````#(.`!6FX#^ZR`<``#(
+M.`!7FX#^Z"`<``'(.`!''[@``9>```/`.``0SX``1R`<``#("`(!E(``5P``
+M``#(*```EH``5"`(``'-@``.S(```!P<```JB`&[E(``20````"```"D````
+M`,@(`$10B``(A``!9`````"9P/]Y(`@``(0``6`@.```EX#_=2`(``#,``(`
+MS``"`<`P(8T@#``!S/$``,`P(8X@S#__S/$``,`P(;;`"A0`S+$``,@(`$`<
+MB`(`F(#_H,`P`$?+$0``'0P$`)3``$P`````R`P`&I3`__L`````@``!C@``
+M``#)S`(#E,#_6B`(``#`#"&VR-$``,`*%`!]"0`&F0#_5"`(``"$``%@(#@`
+M`I>`_U`@"```FD#_T0````"$``!M(`@"$(```A4`````A```30````"(````
+M`````,@X`@:;@``&`````)I```0`````A```W@````#)^`(#FX#_"0````"`
+M``"4`````"J(`;R8@/_S`````)4`_C8`````R"@``I:`_X`@"``!S8``#LR`
+M``*```"/`````,`0(`O`%```P!;``,U1``#)%0``P##__\B,``!\\0`&E0``
+M#`2(``'(E```S5$``!3,`!!\\0`&E0``!@2(``'(E```S5$``(```F@$B``!
+MB``````````=#$``E,#_3\`P/:_+#0``',P``I3`_TO`,#TTRPT``)C`_PX`
+M`````````,@(`@@$B``!S(`"",`P/37,,0``P#`],<VQ``#`,#TTRPT``!S(
+M``&8@/ZO',@``IB```?(#``:E,#_^@````#($`()!1```<T``@G($`(+!1``
+M`<T``@O`,#TUS;$``(```8X@"```S[$``,V```[+.0``%[@`!!^X``^7@/_]
+M`````(@`````````R<P"`Y3`_98`````A``!4"`,``&$``%@(#@``)>`_9`@
+M#``-P#`@"<SQ``#`,"`*P#08&!-T``@C=!@8RPT``'STP`;("``:F(#]A2`<
+M``&4P/_[`````(```*Q]P<`&B`````````#(*``$EH#]TP`````@"``!S8``
+M#LR```2```"/`````,^Q``#+.0``(`@`'YB````(B``!S!P`%LGP`!N7`/__
+M`````(@`````````R#``0",P`$#/``!`A```,B`X``'(,`!`'S`#O\\``$"`
+M``'WS```5@``````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+,````````````````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/SUMO_uvd.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_uvd.bin.uu
new file mode 100644
index 0000000..87830ad
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/SUMO_uvd.bin.uu
@@ -0,0 +1,4561 @@
+begin 644 SUMO_uvd.bin
+M'C+/K\Q2"/C$LN"`#FHWS,J]526@KM_\--S+=A[$Q2C!$=>N6O^"4_QL8PQ[
+M;LBK@O6B6P``````'@,`!P````P```$;,]2P`1P)_4>(.9C@Y^0VMT;DMVA,
+MVG4XK8X]*4OU>CK"%1\-```!E<B%N'-/+W^6(1LF?'?[11/IEC,"5J-\O2UV
+MO<M?EP&V*DV]#@```3\3$#;*N;T[%^_]MXU>_N->SXNR?[*B+=E8`\F?)ALE
+M7;\&P@\```'Z:Z&+.R1B0.6*F'F-Y=S:B7J'PHT``];"E-/C]54?]NBR8(D0
+M```!6NEDI$(H<O-(7F88PM'8R02[V>2).M])KKTCN"=SXD\^-(:*$0```:YI
+M_W^%:W!^?2P:89X08C"%"R8P+E1R:#^#XNX?V[ULT#@]7!(```$^ZW6[1L?^
+M]`#AT24M?H7'8;-^T!!J2-5$J@`_9WE;YBS_2?,`````````````````````
+M`````````````````````````````````,5)$-5)(.5),/5)`#0``-S_`&'0
+M_P!A$``!82\`!`"Q@`1@``````````````````````````````````````#%
+M"1#5"2#E"3#U"0`U````````````````````````````````````````````
+M````````````````````````R4D`T0D0V4D@Z4DP^4E`@$E0D$E@H$EPL$D`
+M-````````````````````````````````````````````````,D)$-D)(.D)
+M<-$),/D)0(<)4)<)8*<)<+<)`#4`````````````````````````````````
+M``````````````#-20#1"1#=22#M23#]24!`25!026!@27!P28"`29"02:"@
+M2;"P20`T````````````````````````````````S0D0W0D@[0FPT0DP_0E`
+M2PE06PE@:PEP>PF`BPF0FPF@JPFPNPD`-0``````````````````````````
+M````#```Y!,``!,``1,``A,``Q,`!!,`!1,0(```21,`2!,0(```:!,`@!,`
+M@1,`D!,`D1,`H!,`H1,P(```L1,`LA,`LQ,`PA,`PQ,`T1,`TA,`TQ,`Z!,`
+MZA,`\!,`\1,`\A,,\B#F$Q`@`$P"#`-V@@[2<P/2<T/2<X/2<\,RTP$`(``B
+MH$`RH`!V@@[R<P#R<Q#R<R#R<S`RTP$`(`!,`@P#=H(.@G,#@G-#@G.#@G/#
+M,M,!,"``(J`@,J``=H(.<G,`<G,0<G,@<G,P,M,!,"``#"5`50$,`PST0&-0
+M6C-`8U!:,T!C4%HS#$0&````0&-0`"``\"``\"``6C,,]$!C4%HS0&-06C-`
+M8U!:,T!C4``@``P##/1`XU!:,T#C4%HS0.-06C,,1$#C4%HS#"1`XU!:,PST
+M0.-06C,,)$#C4%HS#/1`XU`P(``\`B#C$P*@!`N`#``,`0P"#`,,!`P%#`8,
+M!R"`0%9P_@P1#``021,`2!,`(``0(``11?\A1?\Q1?\Y`C%%_S#F$Q`@`"!@
+M`"%#_R`%$V5J""T*,2P`*0,,$C$M`"D#AI3_````.1%)(5DQ:4%Y48EAF7&I
+M@;F1R:'9L>G!^=$@``,P`0,IX3GQ(`(#,`,#(F$0,F$1(.8#,+$#(F$2,F$3
+M;`,P(A`K(B#F$Q+1`1+!@!`@`!`1(!4%`!+!@#(A$2(A$#`#$R`"$SCQ*.$P
+M`1,@`!,B(1(R(1,@YA,PL1,0(`#XT>C!V+'(H;B1J(&8<8AA>%%H05@Q2"$X
+M$2@!$M$!$L&``#`````V`0$@80!`X@-0Y`,A+@!01!`@1!!61``@;P`=\##T
+M0!SR,#+``!-`02\`0$.PG&,,$@`BH2#C$R(D`&(D`19"_-`"`(;O_P`@\`,@
+M\!,H!&@4%@+[T`(`ANK_`#8A`##J`RHS,/`3'?`````V(0#VP@E1+P!0(K`Y
+M`DD2'?``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````8P````````
+M````````````````````````````````AE[_````````````````````````
+M```````````````0-````````````````````````````````````````!+!
+M@"D!(.@#9D("1E#_*`$2T0$2P8`&2?\`````````AD;_`#8A`$!O`##D`R`S
+M(##D$T#F$Q`@`!WP`#8A`$!O`##D`R`S("`S,##D$T#F$Q`@`!WP````````
+M`````(8V_P`@TA,A,``Y$DDB63)I0GE2B6*9<JF"N9+)HMFRZ<+YTC```T`!
+M`SGB2?(P`@-``P,R8A!"8A$0(`!`X@-0Y`,Q,0!01!`P1!`6!`HP]$`<]3`U
+MP``30"83?F8C`D8@``P5`%6A4.,3'/1'$P1&\O\``/$R`.$S`"QC.0\,`SD?
+M#`-"H&0,M5D/J!\7Z@<;,T<C\<;H_RPC.0^8'PRS.0\,(S"J(*D?,30`,#D0
+M.0XX#BPS.0^8'S$U`#`Y(#D..`X,`T$V`%@.834`8%40C#4;,T<C\$;8_P!0
+M\0-0\1/&U?]0\@-0\A.&T_\``#(B$4(B$#`#$T`"$SCR2.(P`1-``!,0(`#X
+MTNC"V++(HKB2J(*8<HAB>%)H0E@R2"(X$B#2`Q`R`````#8A`"#J`QWP-B$`
+M(/`3`"``'?``-B$`(/(3`"``'?``-B$`(/`#'?``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````'@-@````````````````OJ8`8+ZF`&`QIP!@OJ8`8+ZF`&"^I@!@OJ8`
+M8"JG`&"^I@!@*J<`8+ZF`&"^I@!@OJ8`8+ZF`&"^I@!@OJ8`8("X`&#)N0!@
+M@+@`8("X`&"`N`!@R;D`8"NZ`&"`N`!@@+@`8"NZ`&"`N`!@@+@`8("X`&"6
+MN@!@@+H`8("X`&"`N`!@@+@`8("X`&"`N`!@H[D`8````````````````,#C
+M`&"/XP!@-^4`8`/E`&#CY`!@:^0`8!CD`&``````"@X4&`X4&!L4&!L>&!L>
+M(@8-%!P-%!P@%!P@)1P@)2H``00(!0(#!@D,#0H'"PX/``$($`D"`PH1&"`9
+M$@L$!0P3&B$H,"DB&Q0-!@<.%1PC*C$X.3(K)!T6#Q<>)2PS.CLT+28?)RXU
+M/#TV+S<^/T85`6!&%0%@7A8!8$(6`6!"%@%@G1(!8)T2`6"=$@%@G1(!8)T2
+M`6"=$@%@0A8!8"86`6`*%@%@G1(!8)T2`6"=$@%@G1(!8)T2`6"=$@%@G1(!
+M8`H6`6#N%0%@TA4!8)T2`6"=$@%@G1(!8)T2`6"=$@%@G1(!8)T2`6"V%0%@
+MMA4!8)H5`6"=$@%@G1(!8)T2`6"=$@%@G1(!8)T2`6"=$@%@?A4!8&(5`6``
+M``````$"`P0%!@<("0H+#`T.#Q`1$A,4%187&!D:&QP='1X?("`A(B(C(R0D
+M)24E)B8F)R<G)P`````````````````````0````(`````\````?````+P``
+M````````````#P```0<""P0-"`X#`P4%"@H,#`\!!P(+!`T(#@8&"0D`````
+M````````````````````````````````````````````````````````````
+M````````````````````+P`?$`\!``(7!!L('2`>`P<%"PH-#`X/)R\K!RT+
+M+@T0#@,&!0D*'PPC$R45*AHL'"$C(B4D*B@L)P$K`BT$+@@1$1(2%!08&!,&
+M%0D:%AP9%R`;(1TB'B06*!DF)BDI`@$#`P0'!0\('P("`P8$#@4>!SX`````
+M````````````0(`!08$"0H(#0X,$1(0%184&1H8'1X<(2(@)28D*2HH+2XL,
+M3(P-38T.3HX/3X\04)`149$24I(34Y,45)0559465I875Y<86)@969D:6IH;
+M6YL<7)P=79T>7IX?7Y\@8*`A8:$B8J(C8Z,D9*0E9:4F9J8G9Z<H:*@I::DJ
+M:JH````````````````````?0!]!'T(?0Q];'UP?71]>@%6J0,`S9IG,*]<E
+M2F^4N=X@8*#@```````````````"`@(```(```$!`0,#`0,#'QL?'!\='QX?
+M)Q\H'RD?*A]$'T4?1A]'```````````?'Q\@'R$?(A\C'R0?)1\F'Q<?&!\9
+M'QH?#1\.'P\?$!\X'SD?.A\['SP?/1\^'S\?2!])'TH?2Q],'TT?3A]/'U\?
+M8!]A'V(?8Q]D'V4?9@T="045)C8R!`<7`R<W,P``"`$%"0T#"P``````````
+M@%6J0,`S9IG,*]<E2F^4N=X@8*#@````'A@9'C(\,$@($1(3%1<9&Q$2$Q47
+M&1L<%!46%Q@:'!X5%A<8&AP>(!87&!H<'B`C%Q@:'!X@(R89&AP>(",F*1L<
+M'B`C)BDM$!$2$Q05%A<1$A,4%187&!(3%!46%Q@9$Q05%A<8&AL4%187&1H;
+M'!46%Q@:&QP>%A<8&AL<'A\7&!D;'!X?(04`````````````````````````
+M`````(````!@````"`````8````!````L````)`````+````"0````(```!@
+M`0``(`$``!8````2`````P```,`"``!``@``6````!(````$````@`4``(`$
+M``!@`0``$@````4`````````````````````````!0``````````````````
+M```````````````````````!`````0````$````!`````0````$````!````
+M`0````$````!`````0````(````"````&#T"8"T]`F"#0`)@>D`"8'%``F!H
+M0`)@7T`"8``````#`````P````,````#````!`````0````$````!`````4`
+M`````````````````````````0````(````#``````````$````"`````P``
+M````````````````````````````!`````@````,````$````!0````8````
+M'````"`````D````*````"P````P````-````#@````\````______[___\!
+M`````@`````````````````````````!`````0````$````!`````@````(`
+M```"`````@````,````#`````P````,````$````!`````0````$````!0``
+M```````````````````````!`````@````,``````````0````(````#````
+M``````$````"`````P`````````!`````@````,``````````0````(````#
+M`````````````````````````#P````X````-````#`````L````*````"0`
+M```@````'````!@````4````$`````P````(````!`````````#_5@)@35<"
+M8$!7`F`S5P)@)E<"8!E7`F`,5P)@``````,````#`````P````,````$````
+M!`````0````$````!0`````````````````````````!`````@````,`````
+M`````0````(````#`````````````````````````/_____^____`0````(`
+M````````!`````@````,````$````!0````8````'````"`````D````*```
+M`"P````P````-````#@````\``````````````````````````$````!````
+M`0````$````"`````@````(````"`````P````,````#`````P````0````$
+M````!`````0````%``````````````````````````$````"`````P``````
+M```!`````@````,``````````0````(````#``````````$````"`````P``
+M```````!`````@````,`````````````````````````/````#@````T````
+M,````"P````H````)````"`````<````&````!0````0````#`````@````$
+M`````````(VD`F##I`)@NJ0"8+&D`F"HI`)@GZ0"8):D`F``````0``&`$4`
+M``!&````O@`"`,(`!@#D`08`,`$``#`!```P`@8`Q@(&`"@#!@"(`P8`"`,`
+M``@#```(`P``"`,```D#```)`P``0@4&`+@%!@#V`P``]@,``/8#``#V`P``
+M]P,``/<#``"F!@8`200``$H$``!*!```2@0``$H$``!+!```2P0``$L$``!+
+M!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$
+M``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0`
+M`$L$``!+!```2P0``$L$``!+!```2P0`````````````````````````````
+M```````````````````````````````````````````````````````````!
+M`````@```$```P`(````2``#`%```@`3````$P```!0````4````%````!0`
+M```4````%````!0````4````%0```!4````5````%0```!4````5````%0``
+M`!4````5````%0```!4````5````%0```!4````5````%0```%0``@!8``(`
+M'````!P````=````'@```!\````@````(0```"$````A````(0```%P``0`D
+M````)0```%X`!0`#`````P````,````#````!`````4````&````!P````D`
+M```*````"P````P````-````#0````X````.````#P```!`````1````$@``
+M`!8````6````%P```!@````9````&@```!L````;````(@```",````F````
+M)@```"<````H````*0```"H````K````+````"T````N````+P```#`````Q
+M````,@```#,````T````-0```#8````W````.````#D````Z````.P```#P`
+M```]````/@```#\```!`````00```$(```!#````1````$<```!'````2```
+M`$D```!```4`8``%`(``!0"@``4`P``$`-``!`#@``0`\``#`/@``@#Y````
+M^@```/H```#[````^P```/L```#[````_````/P```#\````_````/P```#\
+M````_````/P```#]````_0```/T```#]````_0```/T```#]````_0```/X`
+M``#^````_``!`/X``@`"`0$`!`$!``@!```&`00`$@$``!(!```2`0``$@$`
+M`!(!```2`0``$@$``!(!```3`0``$P$``!,!```3`0``%@$#`!X!`@`>`0``
+M'@$``!\!```?`0``'P$``!\!```?`0``'P$``!\!```?`0``2@```$L```!,
+M````30```$X```!/````4````%$```!2````4P```%0```!5````5@```%<`
+M``!8````60```%H```!;````7````%T```!>````7P```&````!A````8@``
+M`&,```!D````90```&8```!G````:````&D```!J````:P```&P```!M````
+M;@```&\```!P````<0```'(```!S````=````'4```!V````=P```'@```!Y
+M````>@```'L```!\````?0```'X```!_````@````($```""````@P```(0`
+M``"%````A@```(<```"(````B0```(H```"+````C````(T```".````CP``
+M`)````"1````D@```),```"4````E0```)8```"7````F````)D```":````
+MFP```)P```"=````G@```)\```"@````H0```*(```"C````I````*4```"F
+M````IP```*@```"I````J@```*L```"L````K0```*X```"O````L````+$`
+M``"R````LP```+0```"U````M@```+<```"X````N0```+H```"[````O```
+M`+T```"^````OP```,````#!````P@```,,```#$````Q````,4```#%````
+MQ@```,8```#'````R````,D```#*````RP```,P```#-````S@```,\```#0
+M````T0```-(```#3````U````-4```#6````UP```-@```#9````V@```-L`
+M``#<````W0```-X```#?````X````.$```#B````XP```.0```#E````Y@``
+M`.<```#H````Z0```.D```#J````Z@```.L```#K````[````.P```#M````
+M[0```.X```#N````[P```.\```#P````\0```/(```#S````]````/0```#U
+M````]0```/8```#W````^````/@```#_``````$```$!```"`0```P$```,!
+M```$`0``!0$```8!```'`0``"0$```H!```+`0``"P$```P!```,`0``#0$`
+M``T!```.`0``#@$```\!```/`0``$`$``!`!```1`0``$0$``!0!```5`0``
+M%@$``!<!```8`0``&0$``!H!```:`0``&P$``!P!```=`0``'0$``"`!```@
+M`0``(`$``"`!```@`0``(`$``"`!```@`0``(`$``"`!```@`0``(`$``"`!
+M```@`0``(`$``"`!```A`0``(0$``"$!```A`0``(@$``"(!```C`0``0``"
+M`"<!```G`0``)P$``"<!``!$``(`2``"`"X!```N`0``+P$``"\!```O`0``
+M+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O
+M`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!
+M```O`0``+P$``"\!```O`0``+P$``"\!```D`0``)0$``"8!```F`0``*`$`
+M`"@!```I`0``*@$``"L!```L`0``+0$``"T!```Q`0``,0$``#$!```Q`0``
+M,0$``#$!```Q`0``,0$``#$!```Q`0``,0$``#$!```Q`0``,0$``#$!```Q
+M`0``,@$``#(!```R`0``,@$``#(!```R`0``,@$``#(!```S`0``,P$``#0!
+M``!```0`/@$``#X!```_`0``4``$`%`!``!0`0``4`$``%`!``!0`0``4`$`
+M`%`!``!0`0``4`$``%`!``!0`0``4`$``%`!``!0`0``4`$``%`!``!1`0``
+M40$``%$!``!1`0``8``$`'``!`"```,`B``#`'P!``!\`0``?0$``)```0"`
+M`0``@`$``($!``"2``(`-0$``#4!```U`0``-0$``#4!```U`0``-0$``#4!
+M```V`0``-P$``#@!```Y`0``.@$``#L!```\`0``/0$``$`!``!!`0``0@$`
+M`$,!``!$`0``10$``$8!``!'`0``2`$``$D!``!*`0``2P$``$P!``!-`0``
+M3@$``$\!``!2`0``4P$``%0!``!5`0``5@$``%<!``!8`0``60$``%H!``!;
+M`0``7`$``%T!``!>`0``7P$``&`!``!A`0``8@$``&,!``!D`0``90$``&8!
+M``!G`0``:`$``&D!``!J`0``:@$``&L!``!K`0``;`$``&P!``!M`0``;0$`
+M`&X!``!O`0``<`$``'$!``!R`0``<P$``'0!``!U`0``=@$``'<!``!X`0``
+M>0$``'H!``!Z`0``>P$``'L!``!^`0``?P$``((!``""`0``@P$``(0!``"%
+M`0``A0$``(4!``"%`0``A0$``(4!``"%`0``A0$``(8!``"&`0``A@$``(8!
+M``"&`0``A@$``(8!``"&`0``AP$``(<!``"'`0``AP$``(<!``"'`0``AP$`
+M`(<!``"'`0``AP$``(<!``"'`0``AP$``(<!``"'`0``AP$``(@!``"(`0``
+MB`$``(@!``!```$`0@`%`)$!``"1`0``D@$``)(!``"2`0``D@$``),!``"3
+M`0``DP$``),!``"4`0``E`$``)0!``"4`0``E`$``)0!``"4`0``E`$``)0!
+M``"4`0``E`$``)0!``"4`0``E`$``)0!``"4`0``B0$``(H!``"+`0``BP$`
+M`(L!``"+`0``BP$``(L!``"+`0``BP$``(L!``"+`0``BP$``(L!``"+`0``
+MBP$``(L!``"+`0``C`$``(P!``",`0``C`$``(P!``",`0``C`$``(P!``"-
+M`0``C0$``(X!``"/`0``D`$``)`!``"0`0``D`$``)4!``"5`0``E0$``)4!
+M``"5`0``E0$``)4!``"5`0``E@$``)8!``!```,`2``#`%```P!8``,`L@$`
+M`+,!``"T`0``M`$``+0!``"T`0``M`$``+0!``"T`0``M`$``+0!``"T`0``
+MM`$``+0!``"T`0``M`$``+0!``"T`0``M0$``+4!``"U`0``M0$``+4!``"U
+M`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!
+M``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$`
+M`+4!``"U`0``M0$``+4!``"7`0``EP$``)<!``"7`0``F`$``)D!``":`0``
+MFP$``)P!``"=`0``G@$``)\!``"@`0``H0$``*(!``"C`0``I`$``*4!``"F
+M`0``IP$``*@!``"I`0``J@$``*L!``"L`0``K0$``*X!``"O`0``L`$``+`!
+M``"Q`0``L0$``+8!``"V`0``0``"`$0``0"]`0``O0$``+T!``"]`0``O@$`
+M`+X!``"^`0``O@$``$8``@!*``(`3@`"`,D!``#*`0``R@$``,H!``#*`0``
+MR@$``,H!``#*`0``R@$``,H!``#*`0``R@$``,H!``#*`0``R@$``,H!``#*
+M`0``RP$``,L!``#+`0``RP$``,L!``#+`0``RP$``,L!``#,`0``S`$``,T!
+M``#-`0``4@`%`'(`!0#I`0``Z0$``.H!``#J`0``D@`%`+(`!0#2``4`\@`%
+M`!(!!0`R`04`4@$%`'(!!`""`00`D@$$`*(!`P"J`0,`L@$"`+8!`@"W`0``
+MN`$``+D!``"Z`0``NP$``+P!``"_`0``OP$``,`!``#!`0``P@$``,,!``#$
+M`0``Q0$``,8!``#'`0``R`$``,@!``#.`0``S@$``,X!``#.`0``S@$``,X!
+M``#.`0``S@$``,\!``#0`0``T0$``-(!``#3`0``U`$``-4!``#6`0``UP$`
+M`-<!``#7`0``UP$``-<!``#7`0``UP$``-<!``#7`0``UP$``-<!``#7`0``
+MUP$``-<!``#7`0``UP$``-@!``#8`0``V`$``-@!``#8`0``V`$``-@!``#8
+M`0``V`$``-@!``#8`0``V`$``-@!``#8`0``V`$``-@!``#9`0``V@$``-L!
+M``#<`0``W0$``-X!``#?`0``X`$``.$!``#B`0``XP$``.0!``#E`0``Y@$`
+M`.<!``#H`0``ZP$``.P!``#M`0``[@$``.\!``#P`0``\0$``/(!``#S`0``
+M]`$``/4!``#V`0``]P$``/@!``#Y`0``^@$``/L!``#\`0``_0$``/X!``#_
+M`0````(```$"```"`@```P(```0"```%`@``!@(```<"```(`@``"0(```H"
+M```+`@``#`(```T"```.`@``#P(``!`"```1`@``$@(``!,"```4`@``%0(`
+M`!8"```7`@``&`(``!D"```:`@``&P(``!P"```=`@``'@(``!\"```@`@``
+M(0(``"("```C`@``)`(``"4"```F`@``)P(``"@"```I`@``*@(``"L"```L
+M`@``+0(``"X"```O`@``,`(``#$"```R`@``,P(``#0"```U`@``-@(``#<"
+M```X`@``.0(``#H"```[`@``/`(``#T"```^`@``/P(``$`"``!!`@``0@(`
+M`$,"``!$`@``10(``$8"``!'`@``2`(``$D"``!*`@``2P(``$P"``!-`@``
+M3@(``$\"``!0`@``40(``%("``!3`@``5`(``%4"``!6`@``5P(``%@"``!9
+M`@``6@(``%L"``!<`@``70(``%X"``!?`@``8`(``&$"``!B`@``8P(``&0"
+M``!E`@``9@(``&<"``!H`@``:0(``&H"``!K`@``;`(``&T"``!N`@``;P(`
+M`'`"``!Q`@``<@(``',"``!T`@``=0(``'8"``!W`@``>`(``'D"``!Z`@``
+M>P(``'P"``!]`@``?@(``'\"``"``@``@0(``(("``"#`@``A`(``(4"``"&
+M`@``AP(``(@"``")`@``B@(``(L"``",`@``C0(``(X"``"/`@``D`(``)$"
+M``"2`@``DP(``)0"``"5`@``E@(``)<"``"8`@``F0(``)H"``";`@``G`(`
+M`)T"``">`@``GP(``*`"``"A`@``H@(``*,"``"D`@``I0(``*8"``"G`@``
+MJ`(``*D"``"J`@``JP(``*P"``"M`@``K@(``*\"``"P`@``L0(``+("``"S
+M`@``M`(``+4"``"V`@``MP(``+@"``"Y`@``N@(``+L"``"[`@``O`(``+P"
+M``"]`@``O0(``+X"``"^`@``OP(``+\"``#``@``P`(``,$"``#!`@``P@(`
+M`,("``##`@``Q`(``,4"``#&`@``QP(``,@"``#)`@``R@(``,L"``#,`@``
+MS0(``,X"``#/`@``T`(``-$"``#2`@``TP(``-0"``#5`@``U@(``-<"``#8
+M`@``V0(``-H"``#;`@``W`(``-T"``#>`@``WP(``.`"``#A`@``X@(``.,"
+M``#D`@``Y0(``.8"``#G`@``Z`(``.D"``#J`@``ZP(``.P"``#M`@``[@(`
+M`.\"``#O`@``\`(``/`"``#Q`@``\@(``/,"``#T`@``]0(``/8"``#W`@``
+M^`(``/D"``#Z`@``^P(``/P"``#]`@``_@(``/\"``#_`@````,```$#```"
+M`P```P,```0#```%`P``!@,```<#```*`P``"@,```H#```*`P``"P,```L#
+M```+`P``"P,```P#```,`P``#`,```P#```,`P``#`,```P#```,`P``0``!
+M``\#```0`P``$`,``!$#``!"``(`%@,``!8#```7`P``%P,``!<#```7`P``
+M1@`"`$H``@!.``$`(0,``"(#``!0``$`4@`!`"<#```H`P``*`,``"D#```J
+M`P``5``#`%P``P!D``,`;``"`'```@!)`P``2@,``'0``0!-`P``30,``$T#
+M``!-`P``30,``$T#``!-`P``30,``$T#``!-`P``30,``$T#``!-`P``30,`
+M`$T#``!-`P``#0,```X#```2`P``$P,``!0#```5`P``&`,``!D#```:`P``
+M&P,``!P#```=`P``'@,``!X#```?`P``(`,``",#```D`P``)0,``"8#```K
+M`P``+`,``"T#```N`P``+P,``#`#```Q`P``,@,``#,#```T`P``-0,``#8#
+M```W`P``.`,``#D#```Z`P``.P,``#P#```]`P``/@,``#\#``!``P``00,`
+M`$$#``!"`P``0P,``$0#``!%`P``1@,``$<#``!(`P``2`,``$L#``!,`P``
+M3@,``$```0!1`P``40,``%(#``!"``0`60,``%(``0!<`P``70,``%X#``!>
+M`P``7P,``%\#``!?`P``7P,``&`#``!@`P``8`,``&`#``!@`P``8`,``&`#
+M``!@`P``8`,``&`#``!@`P``8`,``&`#``!@`P``8`,``&`#``!A`P``80,`
+M`%0`!`!D``0`>P,``'L#``![`P``>P,``'0`!`"$``0`E``$`*0`!`"T``0`
+MQ``#`,P``P#4``,`W``"`.```@#D``(`Z``"`.P``0#R`P``\P,``/0#``#U
+M`P``]0,``/4#``#U`P``]0,``/4#``#U`P``]0,``$\#``!0`P``4P,``%,#
+M``!4`P``50,``%8#``!6`P``5@,``%8#``!7`P``5P,``%<#``!7`P``6`,`
+M`%@#``!8`P``6`,``%H#``!;`P``8@,``&(#``!B`P``8@,``&(#``!B`P``
+M8@,``&(#``!C`P``9`,``&4#``!F`P``9P,``&@#``!I`P``:@,``&L#``!L
+M`P``;0,``&X#``!O`P``<`,``'$#``!R`P``<P,``'0#``!U`P``=@,``'<#
+M``!X`P``>0,``'H#``!\`P``?0,``'X#``!_`P``@`,``($#``""`P``@P,`
+M`(0#``"%`P``A@,``(<#``"(`P``B0,``(H#``"+`P``C`,``(T#``".`P``
+MCP,``)`#``"1`P``D@,``),#``"4`P``E0,``)8#``"7`P``F`,``)D#``":
+M`P``FP,``)P#``"=`P``G@,``)\#``"@`P``H0,``*(#``"C`P``I`,``*4#
+M``"F`P``IP,``*@#``"I`P``J@,``*L#``"L`P``K0,``*X#``"O`P``L`,`
+M`+$#``"R`P``LP,``+0#``"U`P``M@,``+<#``"X`P``N0,``+H#``"[`P``
+MO`,``+T#``"^`P``OP,``,`#``#!`P``P@,``,,#``#$`P``Q0,``,8#``#'
+M`P``R`,``,@#``#)`P``R0,``,H#``#+`P``S`,``,T#``#.`P``SP,``-`#
+M``#1`P``T@,``-,#``#4`P``U0,``-8#``#7`P``V`,``-D#``#:`P``VP,`
+M`-P#``#=`P``W@,``-\#``#@`P``X`,``.$#``#B`P``XP,``.0#``#E`P``
+MY@,``.<#``#H`P``Z0,``.H#``#K`P``[`,``.T#``#N`P``[P,``.\#``#P
+M`P``\0,``/@#``!```(`_`,``/T#``#^`P``_@,``/X#``#^`P``_P,````$
+M``!$``(`2``"`$P``0`*!```"P0```P$```-!```#00```T$```-!```#@0`
+M``X$```.!```#@0```\$```/!```#P0```\$```0!```$`0``!`$```0!```
+M3@`$`%X``0`8!```&00``!H$```:!```&P0``!L$``!@``,`(00``"($```B
+M!```:``#`'```P!X``,`@``"`#T$```^!```/P0``#\$``!`!```000``(0`
+M`@"(``$`1P0``$<$``!'!```1P0``$@$``!(!```2`0``$@$``#Y`P``^0,`
+M`/H#``#[`P```00```($```#!```!`0```4$```&!```!P0```<$```(!```
+M"00``!$$```1!```$00``!$$```2!```$P0``!0$```4!```%00``!4$```5
+M!```%00``!4$```5!```%00``!4$```6!```%P0``!P$```<!```'`0``!P$
+M```=!```'@0``!\$```@!```(P0``"0$```E!```)@0``"<$```H!```*00`
+M`"H$```K!```+`0``"T$```N!```+P0``#`$```Q!```,@0``#,$```T!```
+M-00``#8$```W!```.`0``#D$```Y!```.@0``#L$```\!```/`0``$($``!#
+M!```1`0``$0$``!%!```1@0``("``@#_!P8`!O\&`/@``0#W_@,``O0#``'V
+M`P#U_0,`_`(&``'X`P`1``,`^PD#``#B`P`(`0(``@<"``7Y`@#]^@(`!OP"
+M``O_`@`%`04`_P,#```#`@#Y_0$`^OP"```*`@`!]P(`"O\"``,$`0#[_P4`
+M!/X&`/4`!@#W``8`"P`&``0`!``'_0$`!OX!``0"!@`"!`8`\_X$`/0&!0`)
+M"04`^@P%``D5!0`*ZP4`"O0%``KY!0#Z#04`^@X%`/H/!0#Z$`4`X0<%`/H4
+M!0`%#@4`!1$%``4?!0#W%P4``@P%``H&!0#[[04`"^T%``(9!0#[]@4`_Q,%
+M`/CP!0`![`4`\/P%`.,#!0#_&04`^/D%`/\!!@`!`08``@`!`/\"`@`"_P(`
+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
+M"OT#``/U`P`#]@,`]P4#```,`P`#"P,`"_D#```/`P#G`0,`_PT#``G[`P#T
+M_P,`_QH#`/#_`P#M``,`'_\#`/D&`P#^"P,``1T"`/\+`@`)_0(``O<"``?\
+M`@`/``(`"/P"`!H``@`;_P(`"0("``'E`@#C`0(`\0`"`!T!`@`*`0(`]?\!
+M`/H#`0`#^@$`_00&`/K_!@`!!@8`_OX#`/\`!``!_P4`!?X&`/_W`0#^"@(`
+M^@4"``'Z!@#[`P8`_P0$`/L"!@`#!08`_?<"``0&`@`=_P(``0@"``7Z`@`>
+M``(``P8!`!D``0#_"0$``OH&``+Y!@`(``8``P,$`/T"!```^00`_?X$`/SZ
+M`@`&\@0`]PD$``#T`P#]_`$`_?D!`/P%`0`*``8``0<&``#Z!0#_^04`_@@!
+M``,/`P#^#0,`_A8#`/_A`P``]P8``?D%``KZ`P`/`@,`!P8#``;N`P`(]@,`
+M"/@#`!,!`P`7`@,`&``#`/(``P#U!0,`!_4#``?W`P`!$0,`\0,#``GW`P#W
+M_`,`^`<#``L'`P#Y]P,`_Q<#`/0!`P#Y!0(`!@8"`/D$`@#[!0$`_04&`.0`
+M!@`'`04`Y0`&`/S]!@`&^`(`\?T"``,'`0#B``$`!@0!`/[]!`#]`P0```(&
+M```!!`````$`````````````````````````````````````````````````
+M`````````````````````````````````````$``!@!-````R``&`"X!!@">
+M````G@```(X!!@#N`08`,@(&`)("!@#L`@8`1`,&`&X!``!N`0``;@$``&X!
+M``"F`P8`&@0&`.L!``#K`0``[`$``.P!``#L`0``[`$``'P$!@#L!`8`7@4&
+M`,8%!@#C`@``XP(``.,"``#C`@``)`8&`#0#``"D!@8`$`<&`*<#``"G`P``
+M?@<&`,X'!@`'!```!P0``#X(!@!^"`8`2P0``$L$``!+!```2P0``$```P!(
+M``,`4``"`%0``@!8``$`6@`#`!X````>````8@`!`"$````B````(@```",`
+M```C````(P```",````D````)````"0````D````)````"0````D````)```
+M`"0````D````)````"0````D````)````"0````D````9``"`&@``@!L``$`
+M+P```#`````P````,````#`````Q````,@```#,````T````-0```#4````U
+M````-0```&X``P!V``$`/````#T````^````/@```'@``P"```,`3````$P`
+M``!,````3````$P```!,````3````$P````!`````@````,````$````!0``
+M``8````'````"`````D````*````"P````P````-````#@````\````/````
+M$````!$````2````$P```!0````5````%@```!<````8````&0```!H````:
+M````&@```!H````;````&P```!P````=````'P```"`````E````)@```"<`
+M```H````*0```"H````K````+````"T````N````-@```#8````W````.```
+M`#D````Y````.0```#D````Z````.P```#\````_````/P```#\```!`````
+M00```$(```!#````1````$4```!&````1P```$@```!)````2@```$L```!.
+M````3@```$X```!.````3@```$X```!.````3@```$\```!/````3P```$\`
+M``!```,`2``#`%```P!8``(`7``"`&```0!P````<````'$```!Q````<@``
+M`&(``0!U````=0```'8```!D``$`>0```'D```!Y````>0```'H```!Z````
+M>@```'H```!Z````>@```'H```!Z````>@```'H```!Z````>@```'H```!Z
+M````>@```'H```!Z````>@```'H```!Z````>@```'H```!Z````>@```'H`
+M``!Z````>@```'H```!Z````>@```'H```!Z````4````%$```!2````4P``
+M`%0```!5````5@```%<```!8````60```%H```!;````7````%T```!>````
+M7P```&````!A````8@```&,```!D````9````&4```!E````9@```&<```!H
+M````:0```&H```!K````;````&T```!N````;P```',```!T````=P```'@`
+M``![````>P```'L```![````>P```'L```![````>P```'L```![````>P``
+M`'L```![````>P```'L```![````?````'P```!\````?````$```P""````
+M2``"`$P``@!0``(`5``!`%8``0"2````6``!`%H``0!<``$`7@`!`)L```";
+M````FP```)L```";````FP```)L```";````FP```)L```";````FP```)L`
+M``";````FP```)L```"<````G````)P```"<````G````)P```"<````G```
+M`)T```"=````G0```)T```"=````G0```)T```"=````?0```'T```!^````
+M?P```(````"`````@0```($```"#````A````(4```"&````AP```(@```")
+M````B@```(L```",````C0```(T```".````CP```)````"1````DP```)0`
+M``"5````E@```)<```"8````F0```)H```!```(`H@```*,```!$``(`J```
+M`*@```"H````J````$@``@!,``(`4``"`+0```"U````M@```+<```"W````
+MN````+@```"X````N````+D```"Y````5``!`%8``0"^````OP```,````!8
+M``(`Q````,0```#%````7``"`,H```#*````R@```,H```#*````R@```,H`
+M``#*````R@```,H```#*````R@```,H```#*````R@```,H```#*````R@``
+M`,H```#*````R@```,H```#*````R@```,H```#*````R@```,H```#*````
+MR@```,H```#*````GP```)\```"@````H0```*0```"E````I@```*<```"I
+M````J@```*L```"L````K0```*X```"O````L````+$```"R````LP```+,`
+M``"Z````NP```+P```"]````P0```,$```#"````PP```,8```#'````R```
+M`,D```#+````RP```,L```#+````RP```,L```#+````RP```,L```#+````
+MRP```,L```#+````RP```,L```#+````S````,P```#,````S````,P```#,
+M````S````,P```#-````S0```,T```#-````0``"`-$```#2````T@```-,`
+M``#3````TP```-,```#3````TP```-,```#3````TP```-,```#3````TP``
+M`-,```#3````TP```-,```#3````TP```-,```#3````TP```-,```#3````
+MTP```-,```#3````TP```-,```#3````TP```-,```#3````S@```,\```#0
+M````T````-0```#4````U````-0```#4````U````-0```#4````U````-0`
+M``#4````U````-0```#4````U````-0```#5````U0```-4```#5````0``"
+M`$0``0!&``$`2``!`$H``0#A````X@```.(```!,``(`4``"`%0``@!8``(`
+M\@```/(```#R````\@```/(```#R````\@```/(```#R````\@```/(```#R
+M````\@```/(```#R````\@```%P``0!>``$`]P```/@```#Y````^0```/D`
+M``#Y````^@```/H```#Z````^@```/L```#[````^P```/L```#6````U@``
+M`-<```#8````V0```-H```#;````W````-T```#>````WP```.````#C````
+MXP```.0```#E````Y@```.<```#H````Z0```.H```#K````[````.T```#N
+M````[P```/````#Q````\P```/0```#U````]@```/P```#\````_````/P`
+M``#]````_0```$```@!$``$``P$``$8``@`'`0``!P$```@!```(`0``"`$`
+M``@!```)`0``"0$```D!```)`0``"0$```D!```)`0``"0$```H!```*`0``
+M"@$```H!``!*``(`3@`"`%(``@!6``$`&0$``!D!```9`0``&0$``!D!```9
+M`0``&0$``!D!```9`0``&0$``!D!```9`0``&0$``!D!```9`0``&0$``!H!
+M```:`0``&P$``%@``0`>`0``'@$``!X!```>`0``'P$``!\!```?`0``'P$`
+M`"`!```@`0``(`$``"`!``#^````_P`````!`````0```0$```(!```$`0``
+M!`$```4!```&`0``"P$```P!```-`0``#@$```\!```0`0``$0$``!(!```3
+M`0``%`$``!4!```6`0``%P$``!@!```<`0``'0$``"$!```A`0``(0$``"$!
+M```A`0``(0$``"$!```A`0``(0$``"$!```A`0``(0$``"$!```A`0``(0$`
+M`"$!```B`0``(@$``"(!```B`0``(@$``"(!```B`0``(@$``"(!```B`0``
+M(@$``"(!```B`0``(@$``"(!```B`0``0``!`"4!```F`0``)P$``"@!```H
+M`0``*`$``"@!``!"``(`1@`"`$H``@!.``(`4@`!`%0``0!6``$`/@$``#\!
+M```_`0``/P$``#\!```_`0``/P$``#\!```_`0``/P$``#\!```_`0``/P$`
+M`#\!```_`0``/P$``#\!```C`0``)`$``"D!```J`0``*P$``"P!```M`0``
+M+@$``"\!```P`0``,0$``#(!```S`0``-`$``#4!```V`0``-P$``#<!```X
+M`0``.0$``#H!```[`0``/`$``#T!``!``0``0`$``$`!``!``0``0`$``$`!
+M``!``0``0`$``$$!``!!`0``00$``$$!``!```$`0@`!`$0``0!&``(`3`$`
+M`$P!``!,`0``3`$``$H``@!.``(`4@`"`%8``0!:`0``6@$``%H!``!:`0``
+M6@$``%H!``!:`0``6@$``%@``0!:``$`7P$``&`!``!A`0``7``!`&0!``!D
+M`0``90$``&4!``!E`0``90$``&8!``!F`0``9@$``&8!``!G`0``9P$``&<!
+M``!G`0``:`$``&@!``!>``$`8``!`&T!``!M`0``;0$``&T!``!M`0``;0$`
+M`&T!``!M`0``0@$``$,!``!$`0``10$``$8!``!'`0``2`$``$D!``!*`0``
+M2P$``$T!``!.`0``3P$``%`!``!1`0``4@$``%,!``!4`0``50$``%8!``!7
+M`0``5P$``%@!``!9`0``6P$``%P!``!=`0``7@$``&(!``!C`0``:0$``&H!
+M``!K`0``;`$``&\!``!P`0``<0$``'(!``!S`0``<P$``',!``!S`0``=`$`
+M`'0!``!T`0``=`$``$```@!$``(`2``"`$P``@!0``(`5``!`(H!``"*`0``
+MBP$``(L!``"+`0``BP$``%8``0!8``$`D`$``)$!``"2`0``D@$``)(!``"2
+M`0``DP$``),!``"3`0``DP$``),!``"3`0``DP$``),!``!:``$`E@$``)<!
+M``"7`0``F`$``)@!``!<``(`G`$``)T!``"=`0``G@$``&```@"C`0``HP$`
+M`*,!``"C`0``9``"`&@``@!L``$`;@`!`'```0!R``$`M`$``+4!``!U`0``
+M=0$``'8!``!W`0``>`$``'D!``!Z`0``>P$``'P!``!]`0``?@$``'\!``"`
+M`0``@0$``((!``"#`0``A`$``(4!``"&`0``AP$``(@!``")`0``C`$``(T!
+M``".`0``CP$``)0!``"5`0``F0$``)D!``":`0``FP$``)\!``"@`0``H0$`
+M`*(!``"D`0``I0$``*8!``"G`0``J`$``*D!``"J`0``JP$``*P!``"M`0``
+MK@$``*\!``"P`0``L0$``+(!``"S`0``M@$``+8!``"V`0``M@$``+<!``"W
+M`0``MP$``+<!``"X`0``N`$``+@!``"X`0``N`$``+@!``"X`0``N`$``+D!
+M``"Y`0``N@$``+L!``"\`0``O`$``+P!``"\`0``O0$``$```0#``0``P`$`
+M`$(``0!$``$`Q0$``,4!``#&`0``Q@$``,8!``#&`0``Q@$``,8!``#&`0``
+MQ@$``,<!``#'`0``1@`"`,L!``#,`0``S`$``,P!``#,`0``2@`"`$X``@!2
+M``(`5@`"`%H``@!>``$`8``!`.4!``#F`0``YP$``.@!``#I`0``Z@$``.H!
+M``#J`0``Z@$``+X!``"_`0``P0$``,(!``##`0``Q`$``,@!``#(`0``R0$`
+M`,H!``#-`0``S@$``,\!``#0`0``T0$``-(!``#3`0``U`$``-4!``#6`0``
+MUP$``-@!``#9`0``V@$``-L!``#<`0``W0$``-X!``#?`0``X`$``.$!``#B
+M`0``XP$``.0!``#M`0``[@$``$```0!"``$`\P$``/,!``#S`0``\P$``$0`
+M`0!&``$`2``!`$H``0!,``$`_@$``/\!`````@```0(```$"```"`@```@(`
+M``,"```#`@```P(```,"```$`@``!`(```0"```$`@``!`(```0"```$`@``
+M!`(```4"```%`@``!@(```8"```'`@``3@`"`%(``@!6``(`%`(``!0"```4
+M`@``%`(``!0"```4`@``%`(``!0"``!:``(`7@`"`&(``@!F``$`:``!`&H`
+M`0!L``$`*0(``"H"```J`@``*P(``"P"```M`@``+0(``"X"``!N``$`[P$`
+M`/`!``#Q`0``\@$``/0!``#U`0``]@$``/<!``#X`0``^0$``/H!``#[`0``
+M_`$``/T!```(`@``"0(```H"```+`@``#`(```T"```.`@``#P(``!`"```1
+M`@``$@(``!,"```5`@``%@(``!<"```8`@``&0(``!H"```;`@``'`(``!T"
+M```>`@``'P(``"`"```A`@``(@(``","```D`@``)0(``"8"```G`@``*`(`
+M`"\"```P`@``,0(``#$"```Q`@``,0(``$```0!"``$`-@(``#<"```X`@``
+M.`(``#D"```Z`@``1``"`$@``@!,``(`4``"`$L"``!+`@``2P(``$L"``!+
+M`@``2P(``$L"``!+`@``5``"`%@``@!<``(`8``!`&(``0!D``$`9@`!`&`"
+M``!A`@``80(``&$"``!A`@``80(``&$"``!A`@``80(``&$"``!A`@``80(`
+M`&$"``!A`@``80(``&$"``!A`@``8@(``&("``!B`@``8@(``&,"``!C`@``
+M8P(``&,"``!H``$`9@(``&<"``!H`@``:@`!`&P``0!N``$`<``!`#("```S
+M`@``-`(``#4"```[`@``/`(``#T"```^`@``/P(``$`"``!!`@``0@(``$,"
+M``!$`@``10(``$8"``!'`@``2`(``$D"``!*`@``3`(``$T"``!.`@``3P(`
+M`%`"``!1`@``4@(``%,"``!4`@``50(``%8"``!7`@``6`(``%D"``!:`@``
+M6P(``%P"``!=`@``7@(``%\"``!D`@``90(``&D"``!J`@``:P(``&P"``!M
+M`@``;@(``&\"``!P`@``<0(``'("``!S`@``<P(``'0"``!U`@``=@(``'8"
+M``!W`@``=P(``'<"``!W`@``>`(``'@"``!Y`@``>0(``$```@!$``(`2``"
+M`$P``@!0``(`5``!`%8``0!8``$`6@`!`)8"``"7`@``EP(``)@"``"8`@``
+MF`(``)@"``"9`@``F0(``)D"``"9`@``7``!`)P"``"=`@``7@`!`*`"``"@
+M`@``H`(``*`"``!@``$`8@`!`*4"``"E`@``I@(``*8"``"F`@``I@(``*8"
+M``"F`@``I@(``*8"``"G`@``9``"`*L"``"L`@``K0(``*X"``"O`@``KP(`
+M`'H"``![`@``?`(``'T"``!^`@``?P(``(`"``"!`@``@@(``(,"``"$`@``
+MA0(``(8"``"'`@``B`(``(D"``"*`@``BP(``(P"``"-`@``C@(``(\"``"0
+M`@``D0(``)("``"3`@``E`(``)4"``":`@``FP(``)X"``"?`@``H0(``*("
+M``"C`@``I`(``*@"``"H`@``J0(``*H"``"P`@``L`(``+`"``"P`@``L0(`
+M`+$"``"Q`@``L0(``+("``!```(`1``"`$@``@!,``(`4``!`,4"``#&`@``
+MQP(``,<"``#'`@``QP(``,@"``#(`@``4@`"`,P"``#-`@``S0(``,X"``#.
+M`@``SP(``%8``0#2`@``T@(``-,"``#3`@``TP(``-,"``#3`@``TP(``-,"
+M``#3`@``6``!`%H``0!<``$`V@(``-L"``#;`@``W`(``-P"``#=`@``W0(`
+M`-T"``#=`@``W@(``-X"``#?`@``WP(``.`"``#@`@``X0(``.$"``#B`@``
+MX@(``.("``#B`@``LP(``+0"``"U`@``M@(``+<"``"X`@``N0(``+H"``"[
+M`@``O`(``+T"``"^`@``OP(``,`"``#!`@``P@(``,,"``#$`@``R0(``,D"
+M``#*`@``RP(``-`"``#1`@``U`(``-4"``#6`@``UP(``-@"``#9`@``Y`(`
+M`.0"``#E`@``Y0(``.8"``!```(`ZP(``.L"``!$``(`2``"`$P``@!0``(`
+M5``"`%@``@!<``(`8``!``D#```)`P``"0,```D#```)`P``"0,```D#```)
+M`P``"0,```D#```)`P``"0,```D#```)`P``"0,```D#``!B``$`9``!`&8`
+M`0!H``$`:@`!`!0#```5`P``%@,``!<#```7`P``&`,``!D#```:`P``&@,`
+M`!L#```;`P``;``"`'```0!R``$`=``!`'8``0!X``$`>@`!`'P``@`N`P``
+M+@,``"\#```P`P``,0,``#(#```S`P``,P,``.<"``#H`@``Z0(``.H"``#L
+M`@``[0(``.X"``#O`@``\`(``/$"``#R`@``\P(``/0"``#U`@``]@(``/<"
+M``#X`@``^0(``/H"``#[`@``_`(``/T"``#^`@``_P(````#```!`P```@,`
+M``,#```$`P``!0,```8#```&`P``!P,```@#```*`P``"P,```P#```-`P``
+M#@,```\#```0`P``$0,``!(#```3`P``'`,``!T#```>`P``'@,``!\#```@
+M`P``(0,``"(#```C`P``)`,``"4#```F`P``)P,``"@#```I`P``*@,``"L#
+M```K`P``+`,``"T#```U`P``-0,``#4#```U`P``-@,``#8#``!```(`1``"
+M`$@``@!,``(`4``"`%0``@!8``(`7``"`&```0!B``$`6@,``%H#``!;`P``
+M6P,``%P#``!<`P``70,``%T#``!>`P``7@,``%X#``!>`P``7P,``%\#``!?
+M`P``7P,``&`#``!D``$`9@`!`&@``0!G`P``9P,``&<#``!G`P``:`,``&@#
+M``!H`P``:`,``&H``0!K`P``;`,``&P#``!M`P``;0,``&T#``!M`P``;0,`
+M`&T#``!M`P``;0,``&T#``!M`P``;0,``&T#``!M`P``;0,``&T#``!M`P``
+M-P,``#@#```Y`P``.@,``#L#```\`P``/0,``#X#```_`P``0`,``$$#``!"
+M`P``0P,``$0#``!%`P``1@,``$<#``!(`P``20,``$H#``!+`P``3`,``$T#
+M``!.`P``3P,``%`#``!1`P``4@,``%,#``!4`P``50,``%4#``!6`P``5P,`
+M`%@#``!9`P``80,``&(#``!C`P``9`,``&4#``!F`P``:0,``&H#``!N`P``
+M;@,``&X#``!N`P``;@,``&X#``!N`P``;@,``&X#``!N`P``;@,``&X#``!N
+M`P``;@,``&X#``!N`P``;P,``&\#``!P`P``<`,``'$#``!R`P``<P,``',#
+M``!T`P``=`,``'0#``!T`P``=0,``'4#``!```(`1``"`'X#``!^`P``?@,`
+M`'X#``!^`P``?@,``'X#``!^`P``?@,``'X#``!^`P``?@,``'X#``!^`P``
+M?@,``'X#``!(``(`3``"`%```@!4``(`6``"`%P``@!@``(`9``!`&8``0!H
+M``$`:@`!`&P``0"D`P``I0,``*8#``"F`P``=@,``'<#``!X`P``>0,``'H#
+M``![`P``?`,``'T#``!_`P``@`,``($#``""`P``@P,``(0#``"%`P``A@,`
+M`(<#``"(`P``B0,``(H#``"+`P``C`,``(T#``".`P``CP,``)`#``"1`P``
+MD@,``),#``"4`P``E0,``)8#``"7`P``F`,``)D#``"9`P``F@,``)L#``"<
+M`P``G0,``)X#``"?`P``H`,``*$#``"B`P``HP,``*@#``"H`P``J`,``*@#
+M``"I`P``J0,``*H#``!```$`K0,``*T#``"M`P``K0,``*X#``"N`P``K@,`
+M`*X#``"O`P``KP,``+`#``"Q`P``L@,``+,#``"T`P``M`,``+4#``"U`P``
+MM0,``+4#``"U`P``M0,``+4#``"U`P``M@,``+8#``"V`P``M@,``+8#``"V
+M`P``M@,``+8#``"V`P``M@,``+8#``"V`P``M@,``+8#``"V`P``M@,``+<#
+M``!"``$`1``!`$8``0!(``$`2@`!`$P``0!.``$`Q@,``,<#``#(`P``R0,`
+M`,H#``#*`P``RP,``,L#``"K`P``K`,``+@#``"Y`P``N@,``+L#``"\`P``
+MO0,``+X#``"_`P``P`,``,$#``#"`P``PP,``,0#``#%`P``S`,``$```@#0
+M`P``T0,``-(#``#2`P``TP,``-,#``#4`P``U`,``-0#``#4`P``1``"`$@`
+M`@!,``(`4``"`%0``@!8``(`7``"`&```@!D``$`9@`!`&@``0!J``$`;``!
+M`&X``0`!!````@0```,$```$!```!00```4$```&!```!@0```8$```&!```
+M!@0```8$```&!```!@0```8$```&!```!@0```8$```&!```!@0```8$```&
+M!```!@0```8$```&!```!@0```8$```&!```!@0```8$```&!```!@0```8$
+M```&!```!@0```8$```&!```!@0``,T#``#-`P``S@,``,\#``#5`P``U@,`
+M`-<#``#8`P``V0,``-H#``#;`P``W`,``-T#``#>`P``WP,``.`#``#A`P``
+MX@,``.,#``#D`P``Y0,``.8#``#G`P``Z`,``.D#``#J`P``ZP,``.P#``#M
+M`P``[@,``.\#``#P`P``\0,``/(#``#S`P``]`,``/4#``#V`P``]P,``/@#
+M``#Y`P``^@,``/L#``#\`P``_0,``/X#``#_`P````0```@$```(!```"`0`
+M``@$```(!```"`0```@$```(!```"`0```@$```(!```"`0```@$```(!```
+M"`0```@$```)!```"00```H$```+!```#`0```T$```.!```#@0```\$```/
+M!```#P0```\$```/!```#P0```\$```/!```$`0``!`$```0!```$`0``!`$
+M```0!```$`0``!`$```0!```$`0``!`$```0!```$`0``!`$```0!```$`0`
+M`!`$```0!```$`0``!`$```0!```$`0``!`$```0!```$`0``!`$```0!```
+M$`0``!`$```0!```$`0``!`$``!```$`0@`!`$0``0!&``$`2``!`$H``0!,
+M``$`'P0``"`$```@!```(`0``"`$```A!```3@`"`"8$```G!```*`0``"@$
+M```H!```*`0``"@$```H!```*`0``"@$```I!```*@0``"L$```L!```+00`
+M`"T$```N!```+@0``"\$```O!```+P0``"\$```O!```+P0``"\$```O!```
+M+P0``"\$```O!```+P0``"\$```O!```+P0``"\$```P!```,`0``#`$```P
+M!```,00``#$$```Q!```,00``#($```R!```4@`"`%8``@!:``(`7@`"`&(`
+M`@!F``(`$00``!($```3!```%`0``!4$```6!```%P0``!@$```9!```&@0`
+M`!L$```<!```'00``!X$```B!```(P0``"0$```E!```,P0``#0$```U!```
+M-@0``#<$```X!```.00``#H$```[!```/`0``#T$```^!```/P0``$`$``!!
+M!```0@0``$,$``!$!```100``$8$``!'!```2`0``$D$``!*!``````"``H'
+M`P`#%0,`X_P#`!,'`P`#&0,`\`X#``/J`P#^%`,`'_L#`!D#`P`'"@,`!PT#
+M`/D;`P`#[P,`$P("`/_I`@`0`@(`X@$"`.;_`@`"$0(`_@L"`/P*`@`!$P(`
+M!_L!``$*`0`%^0$`'`("``8<`P#I!@,`!@$%`!,``0#^]@$``?<&``#X!0``
+M^@0``/T"``C]`@#[]P(`#OT"`/_N`@#I_@(``PT"`/T1`@#_ZP(`#P`!```0
+M`0`'`P8`!?\$`/D"!@#^^08`^/X&``/Y!@`=``0`!_@"`/#X`P`$]P,`$@`!
+M```-`0#S`0$`&P$&`/WY!@#^!`4`'P$!``T'`P#_[`,`'/T#`.[X`P`"X`,`
+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
+M_PT&`/[[!0#X`04`^OT&``'D`0#X"0(`#?H"`/?^!@#B_P8`_/T%``,$!0#^
+M_`0``A4"`/X3`@`7Y0(`%_4"`.'^`@#]X@(`_1\"`/H)`@#\]`(`^>$"`/\8
+M`@`$]0(`]O@"`/'Y`@#^Y0(`%/P"`.(#`@`,^@(`#/P"`!G^`@#Z\@(`'OT"
+M``GW`@`'"`(`&0("`/KT`@`."@(`$0<"`.L"`@#P_`(`\QT"`.4&`@`"#@$`
+M&0$!`.W]`0#Z!P$``0P!`.W^`0`0_P$`_A(!`.L!`0#G_P$`&``!``+S`0`!
+M"P8```X&``()!@`)_@8`!/P%``+_`0`!`04``0,"`/H"!0#\^@8``.T&``D"
+M!@#@``8``!D%``/^`P`#``$`%P`!`/H(`0#@_P$`^@4!``,/`0#AX0$`$P,!
+M``'P`0`5_P$`_^`!``T#`0#L`0$`_>$!`/WQ`0`$^P8`Y0`$``8&!@`;^P(`
+M!AX"``?I`@`:!`(``@H&`/\*!@`$_P,`#P$&```/!@#Q`08`_QP&`/_W!0`!
+M"04``OX"``($!```'`0`_00%``;Q`@#YZ0(`$1$"`!+X`@#V^0(`_!8"`!L"
+M`@#I!P(`&P4"`.?C`@#\X0(`%_D"`/$&`@#D!@(``PP"`!(#`@#U!`(`_>P"
+M``P<`@`/!`(`\@8"`/@(`@#S^0(`^0L"`/__!`!```(`-!@``!`4```0%```
+M"!0```@4``!$``(`+!@```P0```,$```#!````P0```4$```%!```!00```4
+M$```!Q@``$@``@`X&```%Q@```,0```#$````Q````,0```$$```!!````00
+M```$$```3``&``\8```^&```C``"``88``"0``(`&!@``)0`!``"$````A``
+M``(0```"$```*!0``"@4```@%```(!0``!88``"D``,``10```$4```\#```
+M/`P``#P,```\#```/`P``#P,```\#```/`P``#\4```_%```#A@``*P``P`<
+M%```'!0``#`4```P%```"P0```L$```B"```/0@``"L(```O"```)`0``"0$
+M```Z"```-P@``",(```%"```.P@``#L(```["```.P@``#L(```["```.P@`
+M`#L(```["```.P@``#L(```["```.P@``#L(```["```.P@``#D4```Y%```
+M'1@``"48```9$```&1```!D0```9$```-1```#40```U$```-1```"T0```M
+M$```+1```"T0```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($
+M```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($```R!```,@0`
+M`#($```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($```R!```
+M,@0```T(```J"```$P0``!,$```?!```'P0``"X(```;"```$@0``!($```2
+M!```$@0``!($```2!```$@0``!($```S"```,P@``#,(```S"```&@P``!H,
+M```Q$```*1```!$,```G#```'@@``!X(```V"```-@@``!4(```5"```"0@`
+M``D(```F#```(0P```H$```*!```"@0```H$``!```8`'!@``"@4```H%```
+M(!```"`0```@$```(!```"P8```8&```/!0``#P4```0$```$!```!`0```0
+M$`````@````(````"`````@````(````"`````@````(````"`````@````(
+M````"`````@````(````"`````@``.(`!@`T&```#!0```P4```D&```,@$&
+M``(8```"`@8`,!0``#`4```X%```.!0``!00```4$```%!```!00```(#```
+M"`P```@,```(#```"`P```@,```(#```"`P```0,```$#```!`P```0,```$
+M#```!`P```0,```$#````00```$$```!!````00```$$```!!````00```$$
+M```!!````00```$$```!!````00```$$```!!````00```$$```!!````00`
+M``$$```!!````00```$$```!!````00```$$```!!````00```$$```!!```
+M`00```$$```&#```!@P```8,```&#```!@P```8,```&#```!@P```<8```?
+M&```0``&``L8```]$```/1```#T0```]$```+A```"X0```N$```+A```#<8
+M```9&```#10```T4```_$```/Q```#\0```_$```@``!`&`8```K&```@@`%
+M`'$8``!I&```31@``$48``!U&```71@``%$4``!1%```8A```&(0``!B$```
+M8A```'(0``!R$```<A```'(0``!/$```3Q```$\0``!/$```;Q```&\0``!O
+M$```;Q```'8,``!V#```=@P``'8,``!V#```=@P``'8,``!V#```>`0``'@$
+M``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0`
+M`'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```
+M>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!L!```3`0``'`$``!P
+M!```<`0``'`$``!P!```<`0``'`$``!P!```<`0``'`$``!P!```<`0``'`$
+M``!P!```<`0``'`$``!##```0PP``$,,``!##```5Q```%<0``!S$```<Q``
+M`$D4``!3%```2A```$H0``!N$```;A```$L0``!+$```0`0``$`$``!`!```
+M0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`
+M!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$
+M``!`!```0`0``$`$``!`!```0`0``$`$```>$```'A```!X0```>$```,10`
+M`#$4```M%```+10```D0```)$```"1````D0```V$```-A```#80```V$```
+M$@P``!(,```2#```$@P``!(,```2#```$@P``!(,```C&```$Q@``$@8``!`
+M``0`!1````40```%$```!1```'0$``!T!```=`0``'0$``!T!```=`0``'0$
+M``!T!```6`@``%@(``!8"```6`@``$<0``!K$```4@P``%(,```*#```"@P`
+M``H,```*#```"@P```H,```*#```"@P``#H0```Z$```.A```#H0```R$```
+M,A```#(0```R$```(1```"$0```A$```(1```!T4```=%```-10``#44```#
+M#````PP```,,```##````PP```,,```##````PP``!8,```6#```%@P``!8,
+M```6#```%@P``!8,```6#```.Q@``$``!@!_&```?A@``'P0``!\$```?!``
+M`'P0```B#```(@P``"(,```B#```(@P``"(,```B#```(@P``%`8``"(``,`
+M,Q@``)``!@`O%```+Q0``!<4```7%```7`0``%P$``!<!```7`0``%P$``!<
+M!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$
+M``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0`
+M`%P$``!<!```7`0``%P$``!]#```?0P``'T,``!]#```?0P``'T,``!]#```
+M?0P``$84``!&%```0``#`%48``!M$```;1```&T0``!M$```6A```%H0``!:
+M$```6A```$X0``!.$```3A```$X0``!>$```7A```%X0``!>$```8Q```&,0
+M``!C$```8Q```&H$``!J!```:@0``&H$``!Y#```90P``%D(``!9"```7PP`
+M`'<,``!["```>P@``%0$``!4!```5`0``%0$```G!```)P0``"<$```G!```
+M)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G
+M!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$
+M```G!```)P0``"<$```G!```)P0``&0(``!D"```9`@``&0(``!D"```9`@`
+M`&0(``!D"```9`@``&0(``!D"```9`@``&0(``!D"```9`@``&0(``!Z#```
+M>@P``'H,``!Z#```>@P``'H,``!Z#```>@P``%L8``!6&```9A0``&84``!G
+M%```9Q0``&$4``!A%```/@@``#X(```^"```/@@``#X(```^"```/@@``#X(
+M```^"```/@@``#X(```^"```/@@``#X(```^"```/@@```X,```.#```#@P`
+M``X,```.#```#@P```X,```.#```)A```"80```F$```)A```!$0```1$```
+M$1```!$0```Y$```.1```#D0```Y$```0``!`&@8```E%```)10``"D0```I
+M$```*1```"D0```5$```%1```!40```5$```*@P``"H,```J#```*@P``"H,
+M```J#```*@P``"H,```:$```&A```!H0```:$```1!@``$(8```/%```#Q0`
+M`!L$``!!!```"!`0$Q`3%A86%A86&A@:&QL;&AH:&AL;&QT='2(B(AT='1L;
+M'1T@("(B)28E(R,B(R8F*"@H,#`N+C@X.D5%4]SQ_)\4)_V?T?\'`!`>`V`0
+M'P-@)@#X_X#U_)]\]OR?____?P```(```&```/+\GX;W`P``]OR?6!,``/2?
+M`&`````(__\?``````$```!``.[\GP```@`PH`!@9)X`8````D*($P````@`
+M`("6F`#]"?S_`/K\GP#>_)\`&````.+\G__G__\`4OR?```!`/___O_`#P``
+M```_``````0#`__@`P+_X```,`,&"__P!```@`$``(#_]___`"[\GP```H"'
+M$P``____#P```,``_ON?Y`T``/___P'__U\`>_C]_P```&(#``"`A`<"``#^
+M_)\````"____O?____```!"`__/__P`?````0```_W_P_P"`"0````#P_[__
+M_P``"(````.`__#_____#_\```^````&@````8```!&`E0$`0)4``$``#@``
+M``#`````,`````P````#`)T``$"5`P!`E0(`0```"@````6````$@```#8``
+M``R`C0``0!`(`&```/`/`#__`/___X`6```(($X``````.````"@____P/=]
+M__\`@```````4""__P`I!`0```!X`":DA`#&A(0`)*20$@``,`8A)`0`0&\`
+M`.AN``#@#P``3`\``(`/``!(K@!@6+$`8/___[]$,R(1____`+P2``"H:P``
+MP+8&`-Q'`6```%(`S&L``!!N```,;```K&P```#_`/_X'0``\/\``$`(```@
+M/_\``B```#?-0OUFN/2,B_%/!SQM``#`$@````#`/XP,``!0"`!@P&L``!`-
+M```_G``````D``%@``"(#P``M`\``/0+``"`#0``H`T``+`6``!H70``Z%T`
+M`"L-``#$$@``M`L``"@-``"T/0``##X``)D]``"L&P``!!P``)`,``"P"`!@
+M"`P``%1M```T#```=`P``*@+``#H#P``2!,``$`0```5/0``E!(```((``"(
+M#```0&T``*P,``"0"0``N!0``+@2``"L70``;&L``*@2```4#P``B%X``)P2
+M``!`"0!@\&T``!!K```1#P```%("````.`0`X(8"``#,``!X:0``=B\``-@;
+M``#L#0``1@4`3F(``%!B```.8P``$&,``/QK``#0#@``8&T``!`/```8#P``
+M/!0``%0;``#__[__@%X`````0`"8"P``9%\``/!?``"P70``*0T``/1=```,
+M"0``3`T``$1M```,"@``#`T``(@_`6"D/P%@9G>(F?__`_@``/P'`/X#`+02
+M``!</0``G&L````__P'4:P``W'4!8*!I`6"4GP%@%&`!8#13`6!,:@%@/&(!
+M8.R>`6`HA@%@#%0!8"B3`6"$2@%@8)<!8%R%`6!TH0%@J'H!8-!\`6!\AP%@
+M\`D`8```$/@``$#X,`H`8````/@``##X"(``````X`$``"#X&0``$!D``"`;
+M```0&P``(!,``0`;``"`&P``0!L``)`;``!0&P``H!L``&`;```P&P``L!L`
+M`'`;``#P&P``P!L``-`;``#@&0``,!H``!`:```@&@``,!P``,`<``"`'```
+M0!P``"`<```04`H`8(@(``#`"````#@``)S%`6"$PP%@_O\```$`\`]$_AX`
+M00#P#P$__P````">%P``"/#;`6``(`,`@'^`?U0(```\"@)@;.H!8)@(`F"H
+MZP%@$`L`8!H+`&!8"@)@D`H"8'0*`F"T"`)@[`@"8-`(`F"$Z@%@P.L!8+3J
+M`6#PZP%@G.H!8-CK`6"!`/`/`P@```L``@#_W___,`L`8,`+`&```%$```!0
+M````<0```'`````1`!\R```?,0`````0````T0```)$```#0````D`#_#P``
+M_Q\``/X/``#^'P``'S4``!\S```?-````A(```#````?6```T`L`8!]0```"
+M#@``'U<``#@,`&`?5```'UH``!]9``!0#`!@8`P`8"`,`&`?4@``'U$``$`,
+M`&`0#`!@'U8```@,`&``#`!@'U,``&3^`6"0X`%@]/X!8/3A`6"H_P%@9`0"
+M8.#E`6!T`0)@G`4"8!\K``!P#`!@@`P`8!\P`````+``#`@``%@5`F#@#@``
+MD`P`8/___P<?50``````L`()```"#````A```*@,`&`_@`T`0/L"`"PK``!(
+M*`)@```)``"`!`#P#`!@<"8"8)A0`F"@*@``Q"4``,PF```C/_\`(S__\`,`
+M\`]P``<`^`T``"PI```P=0```P#_#P,`\0_____^0"L```#0`@#X(@```Q8`
+M`,0D`````%#XU"4``(#_``#`_P``5$$"8/!``F#0)0```A$```(6```P#0!@
+M,$\"8`(8```0#@!@`Q$```41``"X"P``T`T`8"0I```X(P``O$\"8#\)``!$
+M(P``P%X"8`A^`F`H;P)@^%P"8.`/`&`(40)@F)@"8`B1`F"040)@!0``0&R0
+M`F"`90)@L),"8&R1`F!$F@)@-(0"8%`F``"0G`)@4)X"8!!1`F!\40)@:%$"
+M8%11`F!`40)@+%$"8!A1`F"W"P``("D``#`.`&"0#@!@:",``.`.`&#0#@!@
+MH`\`8#PD```,)```%"0``&`E``"8)```<",``&@D``"H(P``=",``+`1`&#P
+MI`)@4+0"8.BF`F!0IP)@Q*X"8%BL`F`<M0)@4*D"8&`0`&`#$P```;`&`#`0
+M`&!P$`!@;",```L!8``_"@``/PL``+`0`&`0$0!@`?`!`'`1`&`"$P```PD`
+M``,*```""@``T!$`8)`N`&#`/P!@8&,`8-@E``"LO`)@U,4"8(RX`F#$MP)@
+MN,$"8%C&`F#TPP)@D'0`8&!W`&!8(P``\,<"8(3*`F"$T0)@'Z$'`/____UP
+M@`!@=-4"8-32`F",&`-@$"<``!\(```?"0``'PH```````4#%P```@L```,+
+M```8#0``````A```(````(`````(````!`#___/____\__\`__\```"#````
+M&`````P````0`/#__P```(;_#P#___]__P````X````*````!@```!P````4
+M)@#_``8`\`\VH2@,!;+1$]+1%&$X`#$W``P'>0$B(ZHI$?@1#`PA.0!@_R#R
+M8ZIR8\3B(A?I(8@AR4UR:S?,>*+!#+$Z`.40*9+1$W)CM')CM;(CL[)I&:(I
+M&7SD0*H0HF.S@B('@FD:I2@"PM$3HFP^Y6D3;0KE="2@2B"E+1K2T1/2+3Z@
+MY'/P(`!@W7/@W7-PW7/9425H$Z!*("4L&O$\`*!$<W!$<TEA\F/:XB/E83T`
+M@M$3X.`TXF@;HB@;TB@;DB@;\J_'P-T1@)D1T)D@H)D@DF/E8F(58F(70B/W
+M0F@;XB@;'`9!/@#P[A!@[B#B8_?2(]ZQ.P#"P0Q`W2#2:!NB*!NB8][2(Z*2
+MIP#Q0`"0W2#2:!NB*!NB8Z*2(]V2:!N100""*!OA/P"BH`>0B"""8]UR;U;B
+M8\:EE/<,BK%"`,O!)93W#&JQ0P#-`663]Z*AP&6O]PP>@40`B2'X(?)CQ.)B
+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
+MLM("L@M$=VL!'?"M`@P,92+Q'?``````````````````````````````````
+M`````````````````!X#8``>`V``'@-@`!X#8`````#_____`````/____\`
+M````_____P````#_____`````/____\`````_____P````#_____`````/__
+M__\`````_____P````#_____`````/____\`````_____P````#_____````
+M`/____\`````_____P````#_____`````/____\`````_____P````#_____
+M`````/____\`````_____P````#_____`````/____\`````_____P````#_
+M____`````/____\`````_____P````#_____`````/____\`````_____P``
+M``#_____`````/____\`````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+/```````````>`P`'A0`"
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_ce.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_ce.bin.uu
new file mode 100644
index 0000000..b2ebe23
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_ce.bin.uu
@@ -0,0 +1,194 @@
+begin 644 TAHITI_ce.bin
+M?$"``8@```#40`!_?$"``8@```#$(``+Q@P`!93``"0D4``/,10``I5```3,
+M0``DS$``)8`````Q%``#E4`!.\Q``";,0``G@````,0@``O,(``%?$$``5!4
+M`"!\08`!!B0``<Y````5G``8?14`&LW@``K-H``,T2```\V@``.:```$Q"0`
+M$II```(AW``P@``!3,0@``O&#``%'*@`$)3```/.H``'@```%<P```G$)`!_
+MQ"``"WQ!@`$*(``!QA0`",88``5]68`*S@```)6```/,(``'@````,P@``6`
+M````?$#``130`!XQ%``"E4`!#AC0`>@8U``P&-@`-`4H`$1\0@`!?$)``94`
+M``>&@```@``!4(```5"```%0@``!4(```%(15``0?A8`"LU``!'480``E8#_
+MLL0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``!'48@``E8#_J<0@``Z:`/__
+M?$"``8@```!\0,`!%-``'C$4``*50`#K&-0`,!C0`>@8_``T),P`#P3H`&A\
+M08`!?$'``93``!*&@```@```<H```5"```%0@``!4(```&^```%04=P`('V>
+M`!J```!_4=P`('V=@!J90``#Q:(``(```'_)H@``@```?\6A``"50``%!9@`
+M`<6E``!29``@?B8`&@4H`(-\08`!?$'``94```>&@```@``!4(```5"```%0
+M@``!4(```)/8```1SAD``)5```0%F``!5B``(,X9``"7P/]QQ#DA0'Q`@`&(
+M````4=P`('V=@!K8```1SAH``)5```0%F``$5B``(,X:``";P/^]?$"``8@`
+M``#8``/VV``#]=@``_38``/SV``#\M@``_'8``/PV``#[]@``^[,0`!_S$``
+M?\Q``']\0,`!S,```=1``'^`````?$#``5!0`"",``#+?-#`&L0@``O$U@``
+M?$.``<0D`!.:```)V&0#],9K`_&:@/__QFL#[@:H``'.I`/NS60#Z]@D`_29
+M0``)WX,``,^@``Z,``#/U$``?YH`_SS&<P/NFP#__X````",``#/?$"``8@`
+M``#8```"Q#P`#9O``(.0````V$```L0\``V7P`!_D````-@``!)\0,`!4%``
+M(,0\`!`G_``!E\#__GS0P!K0P``4S$``%<00`"%\4,`!S,``%M@``!.`````
+MQ!``(7Q0P`',P``7U$``&(````#$$``A?%#``<S``!?$$``@?%#``<S``!F`
+M````Q!``(7Q0P`',P``:S$``&WQ`P`%04``@?-#`&M#``!R`````S$``(=@`
+M`"*`````?$#``5!0`"!]#4`:V$``*<@8`!U]E<`/E<#__M@``"F`````?$#`
+M`<@0`!W(%``>?16`#IF```_80``IR!``'7U1@!)]C<`/F<#__=@``"E0X``!
+M?A9`#II```1]8H`2TH``(X````#0```C@````-B``"G$/`!_S```(-A``"C$
+M#``<F,#__]@``"A\00`!4%0`('T6`!K2```>V$``'8````#,```@V$``*,0,
+M`!R8P/__V```*-```![0```?V$``'7Q!``&`````?$#``7Q!``$5&``?S0``
+M$5$4`""9@``#U$T``(````!]34`:&1P`,=16``#$(``.E<#^R,0@``Z:`/__
+M@````'Q`P`%\08`!%-``'C$0``(DU`#_E0#^O\V4`P"`````Q"``$WQ`P`'$
+MTP,`S```$<TA(4&`````U$``?X````#$)`!^ED```WQ`@`&(````@``!4```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0`"`!`!2@`1``4`&0`M`#$`)0`S`!,`@`#3`($`X0""`.8`@P#M`#<`
+M.0!``%P`1`">`(0`]@"'`/D`B`$"`(D!%P!]`3P`?@%$`'\!+``B`*X`BP$B
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_mc.bin.uu
new file mode 100644
index 0000000..42dcc68
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_mc.bin.uu
@@ -0,0 +1,694 @@
+begin 644 TAHITI_mc.bin
+M``/HX``"O@$```('``/_```#_P```J`.``'`&0`#Z````^@0``/H(``#Z#``
+M`V`@``-A2``",;@``TEL``-("@`#KPH``K0$``)O]```^BT``K0/``)/%```
+M^@H``ZB,``#"`0`#0"0``K1```*U#P`#2J8``D1!``/P`@`"294``VJF``-*
+M40`#0"0``K@"``*Y_@`"1)0``DB!``.H@``"9$@``VI1``-`)@`"OX```KP$
+M``))^0`#\$(``_0```'`00`"OX```TA4``*X#P`"N?```D$8``)"*0`#:%0`
+M`TMI``/`C``"9$P``VMI``)$2``#:VD``F$?``)B+``#:%0``BP%``-+3``#
+M_P```V%$``-+'``#0"H``K3\``-A0``"0S0``F$>``-K'``"2JX``_!&``-)
+MU0`"O!```DS'``/P0@`"O"T``C)S``-`)``"M$```K7P``-*I@`"1$$``_`"
+M``)IE0`#:J8``T````/_```#^`$``\1```/$40`"QD4``@````-`$``#_P``
+M`_\```/H(``#Z#```V`0``"1Y0``D@T``_@#``(POP`",;(``T@(``*TGP`"
+M0`0``V@(``-(P``#2,8``K3\``*U#P`"010``DF4``)")0`"2J4``D,U``)+
+MM0`#:,```VC&``-(```#2`4``KL_``*\OP`"O^\``)(E``"*)@``@BH``+HH
+M``"J+``"01L``KO[``)`#``#:````KS^``)%7P`"1WP``V@%``-($``#2=T`
+M`KOQ``*\`@``BBD``*HK``)!&P`"81P``V@0``)%6P`"95P``VG=``-`#0`#
+M_P```_\```.A3```B?\``K,"``)#-``#HS```)G^``*S!``"0S0``Z,R``"9
+M_0`#0"D``T````*\(```N<<``D(L``/P!P`"L````((Q``(Z,P`#Z````('E
+M``/T```!PEP``T````*\(```\C$``D,\``/P!0`".C,``^@```"!Y0`#]```
+M`<)<``-((0`"L\$``D=S``-H(0`#:HD``T@E``*SP0`"1W,``V@E``-JC0`#
+M2"D``TEP``-`$@`"OP<``D`/``.````#``X``Z^(``-)U@`"O!```DS+``/P
+M00`"P`\``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H+0`#P00``\$5
+M``-IZ``#:>P``TK"``*_P``"2(\``VK"``-JQ@`#Z````^C0``(NE@`#:.0`
+M`\'>``(NE@`#:00``^A```*]```",@(``KT!``(R`@`#0"P``_\```*T`@`"
+M1`0``*()``-)U@`"M1```D1;``.D1@``H@L``J!.``/P`P`",[<``_0```'!
+M!0`#]````=)]``*\```",CT``T`.``#R,@`#Z/```Z"V``-)U0``^@0``K$/
+M``)"%P`"I2```_`!``#Z,@`"0QL``J4C``/P`0``\@0``T````-`+@`"MA``
+M`K0,```J,@`"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!``/HP```
+MX@,``T`(``*T````>@0``J`D``/P00`"L@@``J#^``/P00`"L@0``K0_``)"
+M)```DAH``TJ4``/_```#88```T````/_```"M$```D0$``/P`P`#Z````((Q
+M``(BX``#0````_\```*T0``"1!0``_`"``#R,0`"(N```T````/_```"M$``
+M`F$0``)$%``#\`$``BSW``-*E``#_P```V&$``-````#_P```K0"``)$)``#
+M\`,``^@```"",0`"(PP``T````/_```"M`(``D0T``/P`@``\C$``B,,``-*
+ME``#_P```V&(``(QL@`#0````_\```/_```"1`X``_`#``/H````@C$``B0;
+M``(QL@`#0````_\```/_```"1!X``_`"``#R,0`")!L``BTN``-*E``#_P``
+M`V&,``-````#_P```K0"``)$0``#\`L``^@```"",0`")@<``T`L``/_```"
+MM"```D1```/P`P`#Z````((Q``(Q*0`#2I0``_\```-AD``#0````_\```*T
+M!``"1$```_`#``/H````@C$``B?3``-*E``#_P```V&4``-````#_P```K00
+M``)$0``#\`P``^@```"",0`"*'H```'_``/_```#_P```J0.``/P!```\@``
+M`BAZ``/H````@@```TJ4``/_```#89@``T````/_```"M"```D1```/P`P`#
+MZ````((Q``(J"@`#2I0``_\```-AG````@,``_\```*T`0`"1`0``_`$``/H
+M````@C$``\'^``(JO````@,``_\```*T`@`"1`0``_`$``/H````@C$``^CP
+M``(JO``#0````_\```/_```"1"X``_`#``/H````@C$``C?1``-````#_P``
+M`K00``)$)``#\`,``^@```"",0`"./4``_@#``-*E``#_P```V%@``-````#
+M_P```K0"``)$00`#\`H``/(Q``(F!P`#0"P``_\```*T(``"1$```_`"``#R
+M,0`",2D``TJ4``/_```#860``T````/_```"M`0``D1!``/P`@``\C$``B?3
+M``-*E``#_P```V%H``-````#_P```K00``)$00`#\`L``/(Q``(H>@```?\`
+M`_\```/_```"I`X``_`$``#R```"*'H``^@```""```#2I0``_\```-A;``#
+M0````_\```*T(``"1$$``_`"``#R,0`"*@H``TJ4``/_```#87````(#``/_
+M```"M`0``D0$``/P`P``\C$``\'^``(JO````@,``_\```*T"``"1`0``_`#
+M``#R,0`#Z/```BJ\``-````#_P```_\```)$/@`#\`(``/(Q``(WT0`#0```
+M`_\```*T$``"1#0``_`"``#R,0`"./4``TJ4``/_```#870``_@#``-````#
+M_P```K0(``)@`0`"1`0``_`,``-("``#_P```K1```)@!``#:`@``TF8``*T
+M_0`"010``VF8``/H,``#P2X``V@P``(Q1``#Z````^@0``/H,``"L@,``V@P
+M``-````#_P```K6```)A$``"114``_`!``(W,``#2I0``_\```-A>``"O`$`
+M`C(]```",@`#_P```_\```*A#@`#\`(``^@```""!P`"+2X``T@```-(!0``
+M"B8```(J```2)0``*BP``#HH``/_```#:````V@%``-($``#2=T```HI```J
+M*P`#_P```V@0``-IW0`#27$``K(!``/H,``#P08``\$7``-H,``",40``^@`
+M``/H$``"L@,``K,```-H,````@L``_\```/_```"H`X``@*!``/T```!P```
+M``'E``-`$@`#0!4```H-``*@#@`#\`(``_0```'"G``"P1X``(H-``)KN@`"
+M95L``L9N``/P00`#!FX``V`5``*R#P`"1$(``J44``/P!P`#Z*```^BP``-@
+M$@`#Z````('E``/T```!P&L``T`L``/_```"M"```D!```/P`@`#]````<*H
+M``/H````@C$``C$I``#R,0`",2D``^@```"",0`",%X``/(Q``(P7@`#23T`
+M`TC```*V"``"1F0``_`"``*U,``"8B4``VC```-HQ``#2QT``T`H``*\$``"
+MOP0``DS```/P!0`"9W\``VL=``(Q1``"9WX``VL=``-`(``#_P```_\```+"
+M+@`#\$0``L,^``/P0@`"LO\``K/_``-@(``",;(``TE(``-`*@`"M#\``K6`
+M``*V0``"1F@``_!%``)#-``"8S4``VE(``)#-``#:4@``^@```/H$``#Z"``
+M`^@P``-DI``#9.0``_0```'````#0`0``&HQ``/H@``#Z)```^B@``/HL``"
+MH-X``_`#``-DJ@`#]````_!!``-DZ@``8>D``J#>``/P`P`#Z$```_0```/P
+M00`#A.H``]A```/<P```>>@``_@#``/4G@`#^P```P_^``("]P``(<,``J#>
+M``/P`P``8<(``_0```/P00``8<$``K\(``/<0``#V,```_@#``/4G@`#^P``
+M`P_^``(#!@`#^`,``^P````",@``:C$``_\```*@#@`#\`$``^P```-).``"
+MH-X``_!!``-).``"N/X``D(H``-I.``#2=```K0$``)A%``"L@$``K,2``*@
+MW@`#\$$``K,1``-H,``#27$``KCO``*Y!``#P08``F%Y``)#.``#:#```T@)
+M``*X_0`"1$@``V@)``(M"``#2:```K01``/!)``"L0\``VF@``-*1``"M/X`
+M`F$>``-J1``"010``VI$``*@W@`#\`,``T)A``/T```#\$$``T)=``/_```#
+M_P```^A@``-II0`#:&L``KH,``*XP``#W($``]BA``*P^``"L0<``^@@``/H
+M,``#_@```]0?``-H:P`#Z/```B/)``(CL@`"(]X``J'^``/P00`#8GH``T)X
+M``/_```#_P```J"```'#9P`"H)$``<-G``*@H@`!PV<``J"S``'#9P`"S_X`
+M`KP,``*A_``#\$(``_0```'#40``^<X``^CP``(CL@`"(\D``B/>``-">``#
+M_P```_\```*@@``!PWT``J"1``'#?0`"H*(``<-]``*@LP`!PWT``L_^``*\
+M#``"H?P``_!"``/T```!PVH``&'.``#YQ0`#_P```J7/``'#C0`"I?P``<.(
+M``/H\``#Z,```_0```'#D``##,\``ZS```/H\``#]````<.0``,/_``#K_``
+M`^C```(CR0`#P?P``B.R``-).``"H-X``_!!``-).``#_P```F(N``-I.``#
+M2=```K3[``)!%``"L@$``K,2``*@W@`#\$$``K,1``-H,``#27$``KCO``*Y
+M^P`#P08``D%Y``)#.``#:#```T@)``*X_0`"1$@``V@)``*P&``"(_T``BTN
+M``/L```#P0\``\$?``/!+P`#P3\``J#>``/P!0`#9+```V2T``-DN``#]```
+M`_!#``-D\``#9/0``V3X``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#
+M:,@``^P```/!#P`#P1\``\$O``/!/P`"H-X``_`$``-DK``#9+P``_0```/P
+M0@`#9.P``V3\``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P`
+M``*P$``"(_T``TH<``(D#0`#P8P``TH@``(D#0`#C,8``FB,``-*)``")`T`
+M`\&<``-**``")`T``XS&``)IG``#2BP``B0-``/!K``#2C```B0-``.,Q@`"
+M:JP``THT``(D#0`#P;P``THX``(D#0`#C,8``FN\``/L```#:&L``KD(``*X
+MP``#W(```]B0``/H$``#Z"```^@P``/^```#U!X``VAK``/!CP`"OQ```BT$
+M``/!^``#[````^C```.'/``#IW8``X8L``.F:``#A1P``Z5:``.$#``#I$P`
+M`FS'``)LQ@`";,4``FS$``/L```#0"0``&HQ``/_```#H`8``J$.``/P`0``
+M@?D``TFA``-)I``"NT```KJ_``)%I0`"H-X``_`#``)#HP`#]````_!!``)C
+MLP`#::0``VFA``(R8``#Z````^@@``/H,``"H-X``_`#```)^P`#]````_!!
+M```)^@`"N,```VAK``/8```#W(```]0>``*_"``"+00``X#@``"!]@``@?4`
+M`^@```"!]```@?,``/'R``-(5``"H-X``_`#``.$Z``#]````_!!``.$Z@`"
+M8B0``VA4``-)=0`#B.8``F!H``/!%P`#P2X``\$^``*@W@`#\`$``X,P``-H
+M,``#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``\!$``)")``#:%0``&(+
+M``*_`@`"+00``J#.``/P`@`#]````@2#``(NJ``#Z'```X3F``)&2P`"H&0`
+M`_!*``-)T@`#Z&```XJR``.JJ@`"H:X``_`"``,!K@`")?<``_0```'%(@`"
+MOP@``D_Y``.O]``#B[(``ZN\``(E.P`#]````<4B``-`#``#_P```K\(``)/
+M\``#\$(``_0```'$E``"OP```KL!``(E.P```@0``_\```/_```"H`X``_!"
+M``/T```!Q2(``/'T``#Q\P`"H-X``_`#``!Y^``#]````_!!``!Y]P`#C>(`
+M`]S0``/8\``#B>8``FF>``#QXP``0?D``^C0``./X``#P:@``XSM``#AYP``
+MXC```BX1``*W`0``0?D``^B@``#1XP`"H'X``_`!``.H@``##]\``\'9``/!
+MJ``#C.T``.'G``#B,``"+A$``BY2``/!!``#P28``V)P``*_`0`#0!$``XC@
+M``*@_@`#\`0``D1(``/P`@`#]````@4(``*W`0``0?D``_\```*@?@`#\`$`
+M`ZB```/HT``#C^```\&H``.,[0``X><``.(P``(N$0`"+E(``T)P``.,ZP`#
+MC.H``^CP``+(0``#J(```"H)``+*8@`#JJ```J9>``($Y0``:C$``/()``/!
+M6``#P7H``V)Q``/T```"!)\``J%>``/P#@``:C$``\&1``/!LP`"H-X``_`#
+M``-A+@`#]````_!!``-A,@`"P($``Z@```+"HP`#JB```X50``"J"0`#@>``
+M`P"$``/P)``"H80``_`!``+$00`#!$X``\%4``,"I@`#\"0``J&F``/P`0`"
+MQF$``P9N``/!=@`#U%X``F`"``($]P``:C$``K\"``(M!``#27$``X'D``/!
+M!@`#HFP``J`N``(%(@`"87$``\$N``/!/@`"H-X``_`!``.#,``#AF```_!'
+M``-H,``#C^T``BT$``./[0`"+00``X_M``(M!``#C^T``BT$``-)=0`#P2X`
+M`\$&``/!%P`#P3X``J#>``/P`0`#@S```V@P```!Y0`#_P```_\```*E#@`#
+M\$@``T`1``*@W@`#\`,``F9N``/T```#\$$``F=^``-@$0`#Z````('E``/L
+M```"H/X``<5'``*P#P`"L0\``K(/``*S#P`"H-X``_`#``-C*``#]````_!!
+M``-C:``",40``TI```!!\@``2?8``%'U``*\,P`"1`P``D4<``)D10`"1BP`
+M`D<\``)F9P`"9$8``J%.``/P`0`"M`$``J".``/P!0`"I$D``_!#``*D2P`#
+M\$$``/'T``"A]@`"O,P``D0,``)%'``"1BP``D<\``)D10`"9$8``F1'``*A
+M3@`#\`$``K0!``*@C@`#\`4``J1*``/P0P`"I$L``_!!``#Q\P``H?4``^A`
+M``"A\@```?0``!'S``*Q#P`"LP4``J7^``(%G0`"H/X``_!!``/H\``"H`X`
+M`_`!``+/_@`"L1```J`N``/P`0`"S_$``K.0``*F\P`#\$(``/'E``/L```"
+M0P(``_!#``(EW0`#]````<5'``*T$0`##_0``J#>``/P`P``^?$``_0$``/P
+M`0``^?```T,I``*@W@`#\$$``T-I``*_=P`");P``^P```-(Y0`"H-X``_!!
+M``-)!0`"N!$``J`.``/P`0`"Q$@``DE!``*DDP`#\`$``/'T``*@+@`#\`$`
+M`L58``))40`"I),``_`!``#Q\P`"H-X``_`#``-HY0`#]````_!!``-I!0`"
+M0`(``J`.``(%1P`"L0(``B7W``/L```"H?X``_!!``/L```#H?8``X_V``.@
+M]@`"H0X``_`'``*\"0`"H$P``_!!``*\#P`#P4P``\%<``,`#@`"H1X``_`'
+M``*\"0`"H&P``_!!``*\#P`#P6P``\%\``,!'@`"H-X``_`#``-C*0`#]```
+M`_!!``-C:0`"8@$``@7"``/L```#0RD``J#>``/P00`#0VD``J`.``/P!0`"
+MM`\``DS^``/P`0`"M`D``\%4``*@+@`#\`8``K8/``.L]@`"3,X``_`!``*V
+M"0`#P78``J#>``/P`P`#8RD``_0```/P00`#8VD``^P```-(Y0`"H-X``_!!
+M``-)!0`"L!$``L1```+%4``"H-X``_`#``-HY0`#]````_!!``-I!0`#`1X`
+M`@7[``/L````:C$``^@```(N@@``\>\``^@```"![@`#0`P``T`M``*X$``"
+MN0@``DH8``.JI@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!``*S
+M!@`#0"T```H$``*P0``"0$```_!!``/H,``"01X``_`!``/H,```F>T``BT(
+M``*X$``"N?X``J#>``/P"0`#2"$``KH/``)&:@`"1WD``F9H``-H(0`#:HD`
+M`_0```/P1P`#2"4``KH/``)&:@`"1WD``F9H``-H)0`#:HT``C`H``*_`P`"
+M+_0``K]D``(M!```:C$``_\```/_```"H-X``_`#``*[```#]````_!!``*[
+M0```V>```\$.``*Q$0`"LA```VI$``*Q$``#Z"```VI$``*P_P`"L?\``K+]
+M``*S_P`#:&```TI@``*_]P`"L1,``D`/``)@#@`#:F```#'^```Y_0`"O`@`
+M`K_^``.&:@`"8B8``J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(M!``#
+M:&L``_\```/^````8B\``%HN``/_```#V,$``]RQ``./XP`"+00``]`?``.,
+M[P`#C^0``F_^``)``0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!G@``J#>
+M``/P`P`#2"$``_0```/P00`#2"4``\#,``(&I``#C.8``L9L``/P00`"QWX`
+M`J#>``/P!``#:"$``VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!
+MQDH``T`1``*P"```\>4``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T
+M```"!]$``X#A``.!!@`"81X``X+G``-J1``#@08``^@@``-J1``","@``T`L
+M``!:'0`"M`0``^CP``)$0``#\`$``K\!``*DO@`#\`$``K\$``(O]```\AD`
+M`/(7``(R6@`","@```HM```1_@``&?T``K`"``*@W@`#\$$``K`$``."*@`"
+MI#X``_`!``*S!``#@18``F`!``*Q,P`#:F```T`*``*P`0`"L0(``K(```*S
+M`0`"H"L``_`"``/H(``#P3L``VIH``/!#@`"L@D``D`)``/P`0`#Z"```K`3
+M``*Q`@`#@B8``^@P``-J<``#0"T``&($```2&@`"OT```D]/``/P`P`"H,X`
+M`_`!``*R"``"L"$``K$"``*S`0`#:G0```H=``*P`0`#_P```J0>``/P!0`"
+ML00``K(```*S`@`#]`0``_`#``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`0`"L0(``K,$``-J?````>X``_\```/_```"P`X``('N``(O[P```AD``T`*
+M``-`#0`"H`X``_`%``*P`0`"0`4``X`&``/T!``#\`,``K`$``)`"0`#@`(`
+M`K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"
+M+LH```'O``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H``J#>``/P
+M`0`#Z/```]CP``*\"0`"OS\``DL?``(MBP`#Z/```/GO```![@`#_P```_\`
+M``+`#@``@>X```GM``-`+@`#_P```J`!``('2@`"L`$``D$(``/P!0```C(`
+M`_\```/_```"H`X``@=*``-*=```>AH``_\```/_```#P2\``VIT``(O[P``
+M`AD``T`*``-`#0`"H`X``_`%``*P!``"0`4``X`"``/T!``#\`(``K`0``)`
+M"0`"L4,``F@!``-*9``"M(```!'@``)`!``"8`@``Z(B``/!/@`#:F0``BZ]
+M``(NR@``0@,``K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''>@`#0`X`
+M`K`0``/_```"00D``J`0``('>@```AD``_\```/_```"P`X``((9``*Q`@`"
+MI`$``@<```!!X````<,``_\```/_```#V(```]P```*_"0`"L````]P!``*P
+MP``#V`$``BZT```![@`#_P```_\```+`#@``@>X``B_O``-`"@`"L$```_\`
+M``)`"0`#H`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$`
+M`VID``(NO0`"+LH``T`E``!"`P`"L"```D`%``/P2``"L`(``J#>``/P00`#
+M@`(``D`(``/P`@`#]````<>_``-`+@`#_P```K`(``)!"``"H!```@>_``*P
+M@``"00@``_`%```",@`#_P```_\```*@#@`"![\```(7``/_```#_P```^@0
+M``"*%P`"I`X``@<R```!X```0<,``_\```/_```#V````]R```*_"0`"L,``
+M`]@!``*P```#W`$``C)@``-H:P``$=8``K/```/HT``#8G0``BVS``(P'@`#
+M[````&HQ``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_
+M````V>P``C"E``/H```"+H(``KL"``#:,``#Z````K%@``/H(``#Z#```VF@
+M``/H```"L1```^@@``/H,``#:D0``C`H``*_`@`"+_0``K#_``*Q_P`"LOT`
+M`K/_``-H8```"BT``!'^```9_0`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+00``VAK``/_
+M```#_@```C`>``-*8```,?X``#G]``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"```*R"0`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``",EH``^AP``-*9``"M(```D`$``/H(``#Z#```VID
+M``-*9``"M(```!'L``)`!``"M`,``F`$``*S$``#:F0``BZ]``-*9``"M`@`
+M`D1```)G=``"I7X``@AX``/H```"+H(``J#>``/P`P`#2"(``_0```/P00`#
+M2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H(@`#:HH``_0```/P
+M0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R#T``T`2``#QY0`"OP0``J#>
+M``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R'@``C`>``/L````:C$`
+M`/'O``/H````@@8``T`(``-`+0`"N$```KD(``)*"``#JJH``DM)``.KM``"
+MLP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!```/P
+M00`#Z#```D$>``/P`0`#Z#```)H%```AY0`#Z%```_\```"B#```J>4``&HQ
+M``/_```#_P```J#>``/P`P``6<(``_0```/P0P``6<$``_\```/_````V>``
+M`T`L``!:'0`"M`0``^CP``)$0``#\`$``K\!``)+O@`"H+X``_`#``(O)0`#
+M]````<BW``*_RP`",8H``/(8``#R%P`",EH``C`H```*+0``$?X``!G]``*P
+M`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B(0`"I#X``_`!
+M``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"``*R```"LP$`
+M`J`K``/P`@`#Z"```\$[``-J:``"L`$``K((``)`"0`#\`$``^@@``*P$P`"
+ML0(``X(F``/H,``#:G```T`M``!B!```$AH``K]```)/3P`#\`,``J#.``/P
+M`0`"L@@``K`A``*Q`@`"LP$``VIT```*'0`"L`$``_\```)!$``"I!X``_`%
+M``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P``
+M`K`!``*Q`@`"LP0``VI\```*'0`#_P```_\```)!'@`"I!X``@E/```"!@`#
+M_P```_\```+`#@``@@8``B_O```"&``#0`H``T`-``*@#@`#\`4``K`"``)`
+M!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"'0`#_P```_\`
+M``)`#@`"I`X``_`+```2&@`"L",``K$#``*S`0`#:G0``TI\``/_```"L`$`
+M`K$$``*S!``#:GP``TID``*T@```$>```D`$``)@"``#HB(``K,!``-J9``"
+M+KT``B[*```![P`#_P```_\```*@#@`#\$X``T`L``*\!``#W,```K_```*@
+MW@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+8L``^CP``#Y[P```@8``_\`
+M``/_```"P`X``((&``!:'0``>A<``K@(``)*O@`"H*X``<EP``.JL``"2JX`
+M`_!#``(KQ``#]````<EO``-*<``"NH@``KEP``*@^``#\$,``\$J``/T```!
+MR6T``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C%7``(R6@``"@4```(&``-`
+M+@`#_P```J`!``()A``"L`$``D$(``/P!0```C(``_\```/_```"H`X``@F$
+M``-*=```>AH``_\```/_```#P2\``VIT``(O[P```A@``T`*``-`#0`"H`X`
+M`_`%``*P"``"0`4``X````/T!``#\`,``K`@``)`"0`#H````K%#``)H`0`#
+M2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"+LH``$(#``*P
+M`0`"H-X``_!!``.``@`"0`@``_`"``/T```!R;4``T`*``/_```"L$```D$(
+M``*@$``"";4```(8``/_```#_P```L`.``""&``"L0(``J0!``()#````>``
+M`$'#``/_```#_P```]@```/<@``"OP@``K#```/8`0`"L````]P!``(NM```
+M`@8``_\```/_```"P`X``((&``(O[P`#0`H``K"```/_```"0`D``Z`$``*Q
+M`P`":`$``TID``*T@```$>```D`$``)@"``#HB(``K,!``*Q```#:F0``BZ]
+M``(NR@``0@,``K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```')]P`#0"X`
+M`_\```*P"``"00@``J`0``()]P`"L(```D$(``/P!0```C(``_\```/_```"
+MH`X``@GW```"%P`#_P```_\```/H$```BA<``J0.``()3P``8<,``%G@``/_
+M```#W,```]BP``*_"``"L,```]@!``*P```#W`$``C)@``-H:P``$=8``K/`
+M``/HT``#8G0``BVS``(P'@`#[````&HQ``/_```#_P```J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``_\```/_````V>P``T`0``*['P`#2"D``J#>``/P00`#
+M2"T``D`+``.O`@`#C/8``FS/``./]@`#2>@``J-,``/P!``#!$P``P5?``/T
+M```#\$(``P3$``,%]0`#P00``\$5``*@W@`#\`0``V@I``-IZ``#]````_!"
+M``-H+0`#:>P``^@```(NE@`#Z````K%```/H(``#Z#```VI$``(P*``"OP(`
+M`B\E```*+0``$?X``!G]``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"L0(``K(*``/H
+M,``#:F@``K"```*R"``"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP
+M``*P(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP`
+M`_\```*P`@`"L0(``K,$``-J?``",EH``^AP``(O[P`#2F0``K2````1[``"
+M0`0``K0#``)@!``"LQ```VID``(NO0`#2F0``K0(``)$0``"9W0``J5^``(*
+MN0`#Z````BZ6``*@W@`#\`0``T@J``-)Z``#]````_!"``-(+@`#2>P``KP1
+M``*_$``"R9\``LB,``/P00`#Z(```\$(``/!&0`"H-X``_`$``-H*@`#:>@`
+M`_0```/P0@`#:"X``VGL``-*P``"OP<``DW>``/P`0`"OS@``J&.``/P0P`"
+M8`\``VK```-JQ``"NP$``-HP``/H<``"3_```_`#``*[_P`"H(L``_`"``/T
+M```!RG$``T`2``#QY0`"OR```J#>``/P`P`":J\``_0```/P00`":[\``V`2
+M``(P*``"+^\``^P```!J,0`#Z````(',``*@W@`#\`,``%G"``/T```#\$$`
+M`%G!``*P?P`"H?X``_!!``)+L```V>```C):``(P*```"BT``!'^```9_0`"
+ML`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&```)B(0`"I#X``_`!``*S
+M!``#0!4``K$(``*V\``"1$8``F$4``-J8``"L`$``K$"``*R```"LP(``VIH
+M``*R"``"L!,``K$"``.")@`#Z#```VIP```2&@`"L"$``K$"``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P`0`"L0(``K,$``-J?``"
+MO`0``]S```!YX``"O`@``KL8``/8\``"+8L```',``-`)0`"OQ```L`.``"!
+MS``"3U\``_`#``(KQ``#]````<L6``*_"``"H`X``_`!``/!_@`",5<``TJ`
+M``*@_@`#\$$``VJ$``!AX``"L(```^CP``*AP``#\$$``\'^``(K=P`"+^\`
+M`!'@``/H$``"L",``Z(B``*S`0`#:F0``BZ]``!AS````>````G#``-`)@`"
+MLA```]@```/<$``"OP@``K#```/8`0`"L````]P!``)"*0`#\$4``Z_P``*@
+MS@`#\`(``_L```/[`0`#T)X``_L```*E+@`#\`$``_L```/4GP`#^P$``J4N
+M``/P`0`#^P$``P_^``(+.````<P``_\```/_```"P`X``(',``!AX``"L(``
+M`\'^``*AP``#\$$``^CP``(K=P`"+^\``!'@``*P`P`#Z!```Z(B``*S`0`#
+M:F0``BZ]``(NR@`#0"4```',``*Q`P`"L@@``K,0``)#-0`#\`(``D(E``/P
+M`@`"I0$``<L#``!APP``6>```_\```/<P``#V+```K#```/8`0`"L````]P!
+M``*_"``",F```VAK```1U@`"L\```^C0``-B=``"+;,``C`>``/L```"O!$`
+M`J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(\0`"*Z\``J#>``/P!``#
+M:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$``-(U``#2-D``_0```/P
+M0@`#2/0``TCY``(KKP`"H-X``_`$``-HU``#:-D``_0```/P0@`#:/0``VCY
+M``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#\`0``L`,``+!'``#]```
+M`_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P00`#:/P``^P```*@_@`#
+M\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L``+'?``#]````_!(``,`
+M#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP``^P```*P?P`"L?\``K+_
+M``*S_P`#:&```VAK```)U@`#Z````Z`#``/<```#V!```T`Q``*_`P`"O`(`
+M`J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^``/P00`#
+MP00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""](``T`U``*_
+M`P`#_P```J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^
+M``/P00`#P00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""^H`
+M`T`X``-`/0`#_P```VJ$``-J@0`#[````TA5``/_```"M\```VA5``-H:P`#
+M2`H``K]_``)H^``"LN\``Z"!``*_PP`"0`\``T`E``*S_P`"L?\``D]>``/P
+M`@`"N?,``D(I``*\`@`"3%P``_`!``*S^P`#:&```TA```./\@`"O/L``D$<
+M``)A'P`#:$```VAK``-)?``"M`0``F$4``-I?``#2I0``_\```-A?``#:&L`
+M`C%$``/_```#_@```_\```-!20`#_P```_\```-(9``#B$0``ZB```/H\``#
+MW/```KQ```+,R``#V,```]0>``(R9@`#84D``TAD``*T$``"1B0``_`"``/T
+M```!S)D``TAD``-(-@`"M$```K4$``)$0``"15@``F1%``',60`"M#P``D1`
+M``/P0P`".KT``_0```',*P`#0!0``_\```/_```"PSX``_!!``,#/@`#8!0`
+M`K#_``*Q_P`"LO\``K/_``-JD``#^`,``TAD``.,Z@``\@@``DP,``',=0`#
+M2#0``KP$``),P``"#&0``.((``-)/0`"OQ```D1/``/P!``"O_\``BT$``*_
+M4``"+00``K\(``(M!``#]````<R&``-(0@`#2=0``#(S``*U$```FC,``KQ`
+M``)%4P`#\`D``DS)``/P!P`"H&,``_!%``#R`@`"-&L``VAK``/T```!P$$`
+M`TA4``*U/P`"0U,``K</``)C-P`#:%0``C)@``/H````@@(``T)Q``(R9@`#
+M8G$``T@(``*T@``"1$```_`"``/T```!UNP``^P```/X`P`#2`@``K2```)$
+M0``#\`(``_0```'6[``#2=```K@(``)).``"H)@``@SP``-)U``"M!```D,T
+M``*@-``"#,X``T@(``*X"``"8`@``V@(``-(*``"N"```F,X``-(+0`#:"@`
+M`VGH``)G>``#:"T``VGM``-(R``"N/L``D(H``-HR``#2)@``K@@``)@"``#
+M2+$``VB8``)D2``#:+$``\$.``/!'@`#P2X``\$^``-C,``#8W```V,T``-C
+M=``#8S@``V-X``/T```!S/```T@(``*X]P`"0`@``V@(``-(*``"N-\``D,X
+M``-(+0`#:"@``VGH``)'>``#:"T``VGM``-(R``"N`0``F(H``-HR``#2)@`
+M`KC?``)`"``#2+$``VB8``)$2``#:+$``K`#``/!$``#P2```\$P``-C,``#
+M8W```V,T``-C=``#8S@``V-X``-)?``"M/L``D$4``-I?``#:&L``_0```',
+M*P`#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(``VC*``)H(0`#:,H``\&"
+M``-HR@`#[````_@#``,/_@`"#04``^P```(R8``#:&L``\$.``/H$``#Z"``
+M`^@P``.D$P`#V!```]Q```/^```#U!X``VAK``-II``#Z````_X```/4'@`#
+M:&L``VFD``*@W@`#\`,``T)@``/T```#\$$``T)<``-"60`"H-X``VFD``/P
+M`P`#0F@``_0```/P00`#0F0``VFA``/^```#U!X``VAK``-H:P`#[````C)@
+M``-H:P`#0E8``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/4'@`"OP(`
+M`BT$``-H:P`#::0``VFB``/H```#_P```]0>``*_`@`"+00``VAK``-II``"
+M,F```VAK``/L```#:&L``C)@``*Q#``#Z````Z`#``/<```#V!```^@```/H
+M$``#Z"```^@P``/^```#U!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>
+M``-H:P`#^P```PB.``(-6@`#[````"'K``/H4``#Z&```^AP``*Y"``"N,``
+M`]R!``/8D0`#0E```_@#``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#
+M:&L``\&/``*_$``"+00``K09``/^```#U%\``VAK``*_$``"+00``\'X``-)
+MI0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#"9X``@V'
+M``-II0`#[````J&^``/P#@`#T!X``P^^``*Z/P`#``X``D`*``,!'@`"01H`
+M`P(N``)"*@`#`SX``D,Z``/4'@`##_X``@V0``/[```##,X``@V+``/L```"
+MH;X``_`.``/0'@`##[X``KH_``+`#@`"0`H``L$>``)!&@`"PBX``D(J``+#
+M/@`"0SH``]0>``,/_@`"#:0``_L```,,S@`"#9\``^P```/0G@`#T!\``KP_
+M``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP``KP@``+`A``#H```
+M`J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#
+M\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``KP'``*CW``#\$X``W)T``-2
+M=@`#_P```_\```/^```#U!X``VAK``/[```#<G8``U)T``/_```#_P```_0$
+M``/P"``"O`@``J3<``/P`0`#:H0``KP)``*DW``#\`$``VJ```(R6@`#^P``
+M`_L!``+-W@`"IM\``@VS``(O[P`"L````K$```*R```"LP$``VIT``*P,0`"
+ML08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#:GP``TID``*T
+M@``"0`0``K0#``)@!``#:F0``BZ]``-*9``"M(```D`$``-J9```:C$``C&R
+M``/L````6><``&(P``/_```"H;X``_!"``#QY0`#[````J'.``/P00`#"[X`
+M`PS.``#9YP``XC```TI```!:"0`#_P```_\```*@O@`#\$(``Z````.B(``#
+MT%X``&'\``!9XP`#H@(``D`)``)"*0`"I8X``@X\``,(C@`"H`T``_`+``!!
+M^0`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$3P`#P50``J6N
+M``(.3``#"JX``J`M``/P"P``4?D``L9O``/!=@`"H+X``_!&``/47@`"QF\`
+M`\%V``/47@`"QF\``\%V``/47@`##,X``@Y-``)KB@`"#A$``^P```-"<```
+M4@D``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"H6@``_!!``+&
+M:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&:``#`B@``P,X
+M``,*K@`"#F```\%4``/!=@`#U%X``V)P``/L```#P6(``P9N``/<$``#V```
+M`]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X``_L```,&;@`"
+M#G4``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#:1```VD4``-I
+M&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I-``#[````\$0
+M``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<``/T```#\$4`
+M`VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4``D$#``-)T@`#
+M_P```D`*``-)P@`"I1```_`!``-)Q@`#[````]">``/[```#_P```_\```/4
+MGP`#^P$``P_^``(.M``#[````_@!``*_!``#2F0``_\```/_```"00\``@Z_
+M``/X`P`#:&L``_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\`
+M`@[K``-`$@`"M1```J4E``/P!``"OP(``FJO``/T```!SN@``L15``*E)``#
+M\`0``K\"``)KOP`#]````<[H``+$10`"I20``_`$``*_$``":J\``_0```'.
+MZ``"OQ```FN_``#QY0`#8!(``B[L``/L```#2G```_\```/!P@`#0"X``K`!
+M``-JJ``#_P```_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,`
+M`TJM``*_D``"H,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#
+M\`L``T`9``/_```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P
+M20`#0!T``_\```/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P`
+M``+$1@`#:JD``_\```/_```#_P```TJL``/L```",F```VAK```)U@`"L,``
+M`]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P50`#
+MP1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$``*T
+MJ@`#P50``\%D``/!=``"O`<``J/^``(/G@``0?\``_\```/_```"H(X``@]D
+M``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J,0``:@```J3>``/P!``#P(@`
+M`\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G>P``
+M:C$``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK``/[
+M```##,X``@]D``!!_P``8@```_\```*@C@`"#XD``T!*``*DS@`#\`0``\"(
+M``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`":JL`
+M`KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@2@`#
+MP1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+``/!
+M$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,``J#Y
+M``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"#ZH`
+M`K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L```"
+M,F```VAK```)U@`"L,```]P```/8$``"M/\``\%D``/!=``"O`<``_X```*U
+M_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X``VAK``/[```##,X``@_%
+M``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#2F(``B_O``/H\``"+_L`
+M`VIB```)U@`"L,```]P```/8$``"M/\``\%4``/!9``#P70``KP'``/^```#
+MU%X``VAK``/[```##,X``@_G``(R6@`#[````TID``*T@``"0`0``VID``/L
+M```"L`0``J#P``/P`P`"+R4``_0$``/P`0`"*\0``^@```/````#P1```K+]
+M``*S_P`#:&````HM```Q_@``&?T``K`*``*@W@`#\$$``K`,``.!%@`"8`$`
+M`K$6``*D/@`#\`$``K,$``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"
+ML@0``F(F``-J8``#C^$``BT$``-H:P`#_P```_X```/L```#2F```_\```/H
+M,``"8`X``VI@``-*9``"M/(``D`$``-J9``#[````K`!``/H$``#Z"```^@P
+M``-J8``#[````&HQ``-`!``#_P```K@$``)%X``"H%X``_!$``*@W@`#\$(`
+M`T`D``/_````8>D``_\```/_```#W,```X_J``*@W@`#\`$``^CP``/8\``#
+MC.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<``D`(``/P
+M0P`"+8L``_0```/P00`"+9\``D1N``/P"0`#Z,```ZMB``.E8``"15X``_!#
+M``(MBP`#]````_!!``(MGP`#[````&HQ``-`*``#0"$``KA```)(@``#\`,`
+M`D9N``/P`0`#[````%'#``*@W@`#\`,``%G"``/T```#\$$``%G!``/_```#
+MW*```]BP``-`!@`#_P```_\```)`Z``#\`,``J#>``/P00`#0"8``_\```/_
+M```#24$``J`.``/P0P`"H-X``_!!``/!10`"14X``_!#``.,Y``#]````_!!
+M``.,XP`#B9@``ZJ<``*@K@`#\`,``BV+``/T```#\$$``BV?``-`!@`#_P``
+M`_\```-)00`"0(X``J`.``/P0P`"H-X``_!!``/!10`#Z,```ZM"``)%3@`#
+M\`<``Z5```)%7@`#\$,``BV+``/T```#\$$``BV?``/L```"H-X``_`#``-(
+M(0`#]````_!!``-()0`#_P```KL!``.B9@`#@68``Z$6``.'=@`"8"<``P`+
+M``.G!@`#@@8``F8A``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`^P```./[0`"+00``^@P``."X``#Z!```^@```-H,``#C^T``BT$``-)G``#
+M2=4``T`J``*T$``"1$<``K4"``)%6@`#A50``D1%``.D0``"MO<``D(F``)B
+M)``#:9P``^CP``-)<``#Z'```K8!``/!40`#P4```V@Q``*X_``#P5,``\%"
+M``)%6``#270``C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29@`
+M`C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29P``C%$``-H,0`#
+MP5$``\%```(Q1``#:#$``\%3``/!0@`#2.@``C%$``-H,0`#P5$``\%```*W
+M$``",40``V@Q``/!4P`#P4(``C%$``-H,0`#[````KP#``-)/0`#2,```J#>
+M``/P00`#2,0``K8$``)&9``#\`0``X;*``/!?``"8B8``F$7``*@W@`#\`,`
+M`VC```/T```#\$$``VC$``-`*@`"M@@``X?&``)&:``#\`$``F,W``*@W@`#
+M\`,``VC```/T```#\$$``VC$``/L```","X``TD]``-`*``"OP@``KP$``)/
+M#P`"3$P``F#\``/P00`#[````K0!``(R`@`",0D``J'^``/P"0`",<,``C`H
+M``-`*``"O`@``_\```)"+``#\$(``_0```/P0@`#Z$```C("``/L```#_P``
+M`_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@``/H,``#
+M:.@``^@```/_```#:.@``T%(``/_```#[````C)@``-H:P``"=8``^@```.@
+M`P`#W````]@0``*\`P`"L/<``J#^``/P00`"L'\``\$0``/!(``#P3```K3_
+M``/!5``#P60``\%T``/^```#U!X``VAK``.@`0`#H1$``Z(A``.C,0`#^P``
+M`_X```/47@`#:&L``_L```,,S@`"$6H``K#_``*\"``#P1```\$@``/!,``#
+M:H```J3^``'1A``"H/P``_`"``-JA``#[````K#W``.A`0`#HA$``Z,A``-J
+MA``#[````TD]``/_```"N(```F1(``-I/0`"L`$``K$"``*R/P`"0B\``K,`
+M``-J:``"L````K$```*R```"LP(``VIT``*Q`0`"L@@``K,```-J>``"L`$`
+M`K(```-J?```$>```K#```)`#P`#H`(``F`.``*Q```#HB(``K,!``-J9``"
+M,EH``_\```/_```"+KT``KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S
+M```#:#```^P```-`+``#_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8
+M``-@'``#[````&HQ``*P`0`#Z!```^@@``/H,``#:F```K\!``(O]``"OQ``
+M`BT$``*\%``#2F```K_W``*Q$P`"0`\``F`.``-J8```,?X``#G]``*\B``"
+MM?X``X9J``)B)@`"I'X``_`!``*S!``"0`4``F`,``-J8``#2I8``T`I``*\
+M!P`#_P```D1,``.%1``"Q5X``\'%``/H0``#Z&```^AP``-JD0`"M/\``K5_
+M``*V_P`"M_\``VAA``-H:P`#_P```_X```,)G``#\$4``\"9``,*K@`#\$(`
+M`\"J``,+O@`#:I(``X````.@```#:F```K\0``(M!``#[````T`J``-'+``"
+MH-X``_!!``-';``"MG\``X5,``)`!@`"29X``_`!``)@!0`#P1```\$@``/!
+M,``"H-X``_!$``-G+``#9S```_0```/P0@`#9VP``V=P``-'-``"H-X``_!!
+M``-'=``"MM\``X5(``)`!@`"8`4``\$0``/!(``#P3```J#>``/P1``#9S0`
+M`V<X``/T```#\$(``V=T``-G>``#2,```J#>``/P00`#2,0``K8_``)")@`"
+MML```J!.``/P`0`#Z&```F(F``*@W@`#\`,``VC```/T```#\$$``VC$``/L
+M```#29@``K@/``*Y]0`#Z#```\$N``*@S@`#\`(``F`(``)!&0`#:#```T@(
+M``*X0``"H,X``_`"``)@"``#:`@``^P```-A4``#854``V%:``-A7P`"+`4`
+M`T%0``-!50`#05H``T%?``/_```#_P```^P```*P_P`"L;\``K+_``*S_P`#
+M:&```^P```*P?P`"L?\``K+_``*S_P`#:&```^P```+$3@`#\$H``L5>``/P
+M2``"QFX``_!&``+'?@`#\$0``K3_``*U_P`"MO\``K?_``/L```"H<X``_`'
+M``,,S@`"OWP``BT$``/_```#_P```PS.``(2=@`#[````^@```"",0`"(N``
+M`/(Q``(BX``",O@``BSW``-)F``"M/<``K4/``)!%``"8`4``VF8``/!+@`#
+MZ#```V@P```""@`#@>```^A```*@`0`#\`$``\%.``(T7@`#2`@``KC^``)!
+M&``#:`@``KP```(T"0`"-#H``T`!``/H````@C$``D1.``/P`0`")!L``T`!
+M``/_````\C$``D5>``/P`0`")!L```(*``.!X``#_P```J00``/P`@`#P4X`
+M`C1>``*\`0`"-`D``C0Z``*_`P`"-N0``C-%``(NJ``"OQ```D_[``'2X```
+M><L``_\```/_```"H/X``_`&``*]```"-IX``KT!``(VG@`#]````=+H``-`
+M```"O````.(Q``*A#@`#\`$``C20``-````#_P```/(Q``*A'@`#\`$``C20
+M``-`!``#0`$``KP(``),P0`#\`H``KT```)$3@`#\`$``C;$``*]`0`"15X`
+M`_`!``(VQ``"OP```/G+``/T```!TN@``TG0``*\@``"3,,``_`$``*]```"
+M-GX``KT!``(V?@`#0"P``KA```*Y@``"N_\``TJE``)(&``#\`$``KO/``))
+M&0`#\`(``KH_``)+N@`"15L``VJE``/T```!PEP``TG1``(NJ``#Z(```J40
+M``/P`0`"N$```D1X``.$0``#2)P``K4$``)D10`"MG\``D`&``)@!``#:)P`
+M`VB@``-HM``#:+@``TDX``*U_``"0B4``K4,``)B)0`#:3@``^@```/HT``"
+M+H(``\'>``(N@@`"+J@``X3B``/!R0`#Z````K$#``*R"@`"LRT``D1)``/P
+M`0`"LR\``^A0``(N<0`#@.H``BYQ``*X+P`"M`(``D1,``/P`0`"N"T``\&8
+M``/!J``#P;@``V,J``-C:@`"+J@``X'B``.@X0`#HY8``X+D``+"+@`#Z%``
+M`BYQ``.@XP`"+G$``BZH``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#
+M@.```H((``)"`@`#@B0``)'4``/L```"+J@``TEP``)$C@`#\$,``K7S``)"
+M)0`#:7```^AP``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D
+M``/!4P`#P4(``V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@`
+M`X1```.%1@`"8`4``F$4``/H,``#P2X``V@P``-#I```(=0``K7/``)`!0`"
+M8`0``\$0``/!(``#P3```V.D``-CY``"1$0``_`!``(VWP`#@80``Z`8``."
+M!@`"8`(``^C0``(NE@`#P=X``BZ6``-)T0`"+J@``^A@``*E$``#\`$``K9`
+M``)&=@`#IFH``TB0``.DN@`"H$X``_!!``*T!``"M0,``J!%``/P00`"M`$`
+M`K7P``)!%0`"810``K?^``)`!P`"8`8``VB0``-HJ``#:)0``VBL``.@I@`#
+MP1```\$@``/!,``#9"0``V1D``.*M@`#2"$``K@#``)F:``"N0\``KO^``)&
+M:0`"9FH``D=[``-H(0`#:HD``V@E``-JC0`#2`@``T@A``)A'@`#:`@``TC(
+M``*X0``"N3\``F`(``-HR``"0`D``VC(``/L```#0"P``KA```*Y@``#Z+``
+M`TJE``)(&``#\`$``KLP``))&0`#\`(``KK```)KN@`"95L``VJE``-(G``"
+MO'L``D`,``-HG``#:*```VBT``-HN``#2)```X3B``.EYP`"014``F$4``*U
+M_@`"0`4``VB0``-HJ``#:)0``VBL``-).``"M0,``F(E``*U\P`"0B4``VDX
+M``/HP``"-`D``C0Z``/H```"L0,``K()``/H,``#Z%```BYQ``.`Z@`"+G$`
+M`K`$``/!$``#P2```\$P``-C)``#8V0``K`@``/!$``#P2```\$P``-C*``#
+M8V@``C;?``-("``#2"$``ZCM``)!&``#:`@``ZCK``)&:``#P#X``D53``-H
+M(0`#:HD``V@E``-JC0`#Z$```C1>``/H\``"/B(``K\!``(^(@`#[````T`I
+M``/_```"N"H``D)>``/P`0`"N&0``J#.``/P00`"N!```\&8``/!J``#P;@`
+M`V<N``-G,@`#9VX``V=R``*X*@`"0EX``_`!``*XY``"H,X``_!!``*X$``#
+MP9@``\&H``/!N``#8ZX``V/N``-(G@`#P!0``Z$<``.!%``"L/<``DB```)H
+M@0`#:)X``VBB``-HM@`#:+H``TKJ``*P^P`#@2(``DJ@``)JH0`#:NH``VKN
+M``-J\@`#:O8``^P```-`*0`#1S8``K`'``*Q"``"0EX``_`!``*Q&``"H,X`
+M`_!!``*Q```"2(```FB!``/!F``#P:@``\&X``-G-@`#9SH``V=V``-G>@`#
+M0[(``K`'``*Q*``"0EX``_`!``*Q.``"H,X``_!!``*Q```"2(```FB!``/!
+MF``#P:@``\&X``-CL@`#8_(``^P```-)=``#P6X``^AP``.(2``#P%X``X59
+M``)")0`"8B@``VET``/!0@`#P5,``V@Q``/L```"OP,``C;D``-("``"N/X`
+M`D$8``-H"``#0"@``KP$``*_`P`"3,(``_`#``(]RP`#]````=2+``-(5``"
+MO&```F(L``-H5``#278``KP0``)DK``#P5L``\%N``/H<``#:#$``C%$``-(
+M5``"O)\``D(L``-H5``#P4H``V@Q``(SJP`#0D4``C)F``-B10`#[````&HQ
+M``(M"```\>4``C`H``(KQ``#0`0``T`*``*\`P`"OP0``D$<``,&\0`"0`\`
+M`_`!``/!:@`"Q&X``K4(``(XK@`#0`0``^CP``#Z!@`"LD```D(@``'4\0`#
+MCP0``Z_X``#Z`P`#2<$``KP/``)(SP`#J(```XF"``*ZXP`"1$H``F1)``))
+M_@`#B9(``KK[``)%6@`"95D``VG!``.!A@`"8($``BZ6``/H```"H-X``_!!
+M``*P0``"L0,``K()``*S"0`"1.\``_`!``*S#P`#Z%```BYQ``*C_``!U/$`
+M`^C```#AS@``X>X``C97``-`&``"H-X``_!!``-`'```0>X``&'.``)@`0`"
+M8`(``F`#``*A#@`#\$(``LB.``#![@`"N@(``KL?``+,R@``X<X``J7+``'4
+MS```2@8``'H#``/_```"H8D``=3L``,/_@`"L!```L_P``/H````@>4``_0`
+M``'4J@`"S_X``/H#``#"!@`#]````=2J``/HP```X@,``^@P``(V:P`#W.``
+M`K\(``/8\``"L"```\$0``/!(``#P3```K\1``/4'@`#_P```_L```,/_@`"
+M%/T``C97``!B`P`"L````]P```/<`0`#C\(``K!```+`#P`#V````K`_``)!
+M#P`"L,```L`!``/8`0`#U%X``]`?``*_$``"H<\``=4>``*@W@`#\`,``\$*
+M``/T!``#\`$``\$+``/4'P`#]````=4E``*@W@`#\`,``\$J``/T!``#\`$`
+M`\$K``/4'P`"-@\``T`&``*P'P`"L2```\$N``)!&``#\`$``L(N``+,P@``
+MX@,``J7```(5`@`#2I0``_\```-@O``#0`0``]S@``*_"``#V/```]SA``*_
+M+``#V/$``K\(``.L%@`"I<\``_!#``/`S``";,\``LS.``*_"``#T!X``]!?
+M``/!B0`#P9H``\&K``+$0``#H$```L`,``/!L``"Q5$``Z%0``+!'``"IAL`
+M`_`!``/!L0`"QF(``Z)@``+"+``"IBL``_`!``/!L@`"QW,``Z-P``+#/``"
+MICL``_`!``/!LP`#U!X``]2?``/[```#^P$``P_^``(50P`#03@``T%)``-!
+M*@`"O`X``J,!``/P`0`#P0$``J,"``/P`0`#P0(``J,#``/P`0`#P0,``J,(
+M``/P`0`#P0@``J,)``/P`0`#P0D``^@0``*F#``#\`,``\````.`!@`#H08`
+M`\$!``*C10`#\`$``\%%``*C1@`#\`$``\%&``*C1P`#\`$``\%'``*C2@`#
+M\`$``\%*``*C2P`#\`$``\%+``/H(``"IDP``_`#``/`1``#A$8``Z)&``/!
+M,@`"H-X``_`#``-DJ``#]`0``_`!``-DZ``#W.```K\(``/8\``#T%X``K\$
+M``/<\0`"OX```J#>``/P00`"O\```]CQ``*\$``"N`$``KD#``*Z#P`"H4P`
+M`_!%``/`1``"1$H``P0$``/T!``#\`(``P1*``+$0``"H5P``_!%``/`50`"
+M15H``P4%``/T!``#\`(``P5:``+%4``"H6P``_!%``/`9@`"1FH``P8&``/T
+M!``#\`(``P9J``+&8``"H7P``_!%``/`=P`"1WH``P<'``/T!``#\`(``P=Z
+M``+'<``#U%\``_L```/[`0`#T%X``PB.``(5J0`"N`$``\$!``/!$@`#P2,`
+M`PF>``(5J0`#1*@``J#>``/P00`#1.@``J%,``/P10`#P$0``D1*``,$!``#
+M]`0``_`"``,$2@`"Q$```J%<``/P10`#P%4``D5:``,%%0`#]`0``_`"``,%
+M6@`"Q5$``J%L``/P10`#P&8``D9J``,&)@`#]`0``_`"``,&:@`"QF(``J%\
+M``/P10`#P'<``D=Z``,'-P`#]`0``_`"``,'>@`"QW,``]1?``(L]P`"-&L`
+M`C`H``(O[P`#[````BZH``.CE@`"-FL``X#E``)#H``"-G0``_0```'6`@`#
+MP9```J'/``/P`0`#P9(``V)U``#)S@`#W.```K\(``/8\``#W.$``K\L``/8
+M\0`"OP$``\$$``(V,0`#0G4``K\!``/_```#P04``C8Q``-"=0`"OP$``_\`
+M``/!!@`"-C$``T)U``*_`0`#_P```\$'``(V,0```<X``K\```(V,0`#[```
+M`K(@``/07@`#T)\``D$.``/P1``"H$(``_!!``/!3``#P8P``Z````)!#@`#
+M\$0``J!2``/P00`#P5P``\&<``.@```"00X``_!$``*@8@`#\$$``\%L``/!
+MK``#H````D$.``/P1``"H'(``_!!``/!?``#P;P``]1>``/4GP`#^P```_L!
+M``.@```##_X``A8R``/L```"LQ```J7#``/P!@`#P#P``X,V``.C-@`"-G0`
+M`_0```'69``"LP\``LS.``)#/``"-FL``C&X``(L]P`"-&L``K\8``(X7``"
+M+NP``^P```*Q!``"L(```J#>``/P00`"L,```K()``/H4``"+G$``^P```/!
+M`P`#P1,``\$C``*@W@`#\`,``V2H``/T!``#\`$``V3H``/L```#0`0``KR`
+M``/_```"3,```=:>``-!`0`"H-X``_!!``-!!0`"L00``K"```*@W@`#\$$`
+M`K#```/<$``#V````\&$``(VNP`#P84``C:[``/!A@`"-KL``\&'``(VNP`"
+MH-X``_`#``-DH0`#]`0``_`!``-DX0`#]````=:X``*Q!``"L(```J#>``/P
+M00`"L,```]P1``/8`0`"L0$``K`(``*@W@`#\$$``K`L``/<$``#V````K\(
+M``(NM``#00$``J#>``/P00`#004``J#>``/P`P`#9*D``_0$``/P`0`#9.D`
+M`BSW``(T:P`#[````\&8``/!J``#P;@``K(!``/4G@`#^P```P(N``(6OP`#
+M[````K$$``*P@``"H-X``_!!``*PP``#W!```]@```*Q`0`"L`@``J#>``/P
+M00`"L"P``]P1``/8`0`"OP@``BZT``-$J``"H-X``_!!``-$Z``"H-X``_`#
+M``-A```#]`0``_`!``-A!``#[````TL,``*U_``"014``VL,``/L```#2PX`
+M`\#/``)JKP`#:PX``C%$``)*K``#:PX``^P```*_`P`"-N0``TG```-)U0`"
+M3`X``_!"``/T```!URD``TG```.'=@`"IG```_!"``/!$@`#Z````Z(6``.!
+M%@`#H18``TB1``*\\``"15P``F52``*\!``"0PP``Z,R``*\_@`"1$P``F1#
+M``-HD0`#:)4``VBI``-HK0`#P4$``\%1``/!80`#P7$``V0A``-D)0`#9&$`
+M`V1E``*\`@`"0@P``X(J``-(G0`"LW\``D1#``)D0@`#:)T``VBA``-HM0`#
+M:+D``J$.``/P`@`"-M\``K`0``/!$``#P2```\$P``-CH``#8Z0``V/@``-C
+MY``#27P``K3[``)!%``#:7P``VAK``/T```!S`4``C`H``(O[P`#0````_\`
+M``/_```#H`P``Z$<``.!$``"81```P\>``/HT``"H/X``_!!``*]`0`#P<X`
+M`T@(``/_```#A.@``F`$``-H"``#29@``K7[``)!%0`#:9@``K0/``)@!``#
+MZ#```\$N``-H,``#27$``X'A``/!!@`"87$``\$N``/H,``#:#```BU(``/X
+M`0`#0`T``_\```*P`0`"0`8``A=I``*@_@`#\`(``J#M``/P!0`"NSX``DNV
+M``.KL``#]`0``_`&``.F:@`"QFX``PNF``/T!``#\`$``^BP``-(&0`"LN``
+M`D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BT(``(M80`"
+MM`\``C%$``-*0``#^`$``J1```/P!@`"I$$``_`$``*D0@`#\`(``J!#``(7
+ME@`"RJX``K`@``*@H``#\$$``^B@``*@JP`"%\```T@9``*RX``"1F(``F9J
+M``-H&0`#2>4``_\```)&8@`"9FH``VGE``/T!``"%W8``J/^``(7R@``T=``
+M`J#>``(7GP``T=$``LW>``/T!``"%U4``$'1``/_```#_P```J"H``(7R@`"
+MH:@``_!(``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%\H``T@9``*R
+MX``"1F(``F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P
+M``)G<P`#:"4``VJ-``/T!``"%\H``T`1``/HP```\>4``KB```)G>``#8!$`
+M`TF8``*U!``"814``VF8``-("``#_P```X3(``)@!``#:`@``_@#``/L````
+M:C$``^@```""#```@<\``CC*``-`)``#_P```_\```)`#@`#\$L``T`0``*\
+M!``#W,```X_J``*@W@`#\`$``^CP``/8\``"O`D``\&Q``(MBP`#0"0``_\`
+M``*\`@`"0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/``
+M`XSD``/!L0`"+8L``BO$``*T!@`"M0@``K8$``(XK@`"OQ@``CA<``(X@P`"
+MOP```B_T``-*<``#_P```_\```*RD``#:G```K\3``(X7``".(,``T`D``/_
+M```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP
+M``*\"0`#BQ```BV?``-`)``#_P```KP"``)`#``#\$L``T`0``*\!``#W,``
+M`K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(MGP`#2G```_\```/_```"
+MLH```VIP``*_&``".%P``CB#``*_```"+_0``TIP``/_```#_P```K*0``-J
+M<``"OQ,``CA<``(X@P`#0"0``_\```/_```"0`X``_!+``-`$``"O`0``]S`
+M``./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+8L``T`D``/_```"O`(`
+M`D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"OX```]CP``.,Y``#
+MP;D``BV+``(X[``#[````^@```/````"L;\``\$@``*S_P`#:&```C`H``(O
+M[P``"BT``!'^```9_0`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$
+M``)B(0`"I#X``_`!``*S!``#P1\``VI@``-*9``"M(```!'L``)`!``"M`,`
+M`F`$``*S$``#:F0``BZ]``*_"``"3_```_`!``#R#``#[`````(,``/_```#
+M_P```J4.``/P`0`#[````^@```""#``#0!(``_\```/_```"1(X``J!.``/P
+M`0``\>4``K]```*@W@`#\`,``FJO``/T```#\$$``FN_``-@$@`"+NP``'G/
+M``/_```#0"```J#^``/P00`#[````J#>``/P!0`"P`X``_!!``*P_P`#]```
+M`_!#``+!'@`#\$$``K'_``-@(```\<\``^P```*P`0`"L0(``\$D``/H,``#
+M:F@``\$E``*P$P`"L0(``X(F``/H,``#:G```K`A``*Q`@`#P28``K,!``-J
+M=``"L`$``K$"``*R#P`"LP$``VIX``-*?``#_P```K````*Q```"LP0``VI\
+M``/L```"L`$``K$1``*R$``#:D0``K$0``/H(``#:D0``J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``-GL``-("``"M$```('F``)@!``#:`@``T@!``*POP`"
+M1$```V@!``/H```"L4```^@@``/H,``#:D0``K`!``/H$``#Z"```^@P``-J
+M8``#[````C`H``(O[P``(>8``_\```-("``#_P```\$$``-H"``#[`````HR
+M``!J,0`#_P```D`>``/P00`#[````CC*``*_```"+_0``#(:``/_```"M0D`
+M`Z9B``+&;@`"Q&X``CBN``-`*``#Z/```J#>``/P00`"OT```/G@``.@#```
+M@<4``T`8``-`'0`#0"X``&'E``/_```#_P```V%0``-A50`#85H``.''``-`
+M$```>>```KP$``/<P``#V/```KP)``/!L0`"+8L``^C```#AS@`"L!```K$`
+M``*R$``"LP```V)T``*P@``#V`$``K````/<`0`"L!(``K$"``*R$@`"LP(`
+M`V)T``*P$``"L1(``K(0``*S$@`#8G```V)$``-B3``#8D@``\&,``/!G``#
+MP:P``\&\``(YVP`",;@``K\3``(X7``"+NP``&'.``/_```"L````]P```*P
+M0``#C\(``L`/``/8```#0!@``J#>``/P00`#0!P``T`M``/_```#U!X``]1?
+M``*_`0`#W/```K\```.(P@`"S_@``]CP``/$```#Q!$``\0B``/$,P`"H-X`
+M`_!!``/!9P`"M1$``D1E``/$1``"P`0``K4B``)$90`#Q$0``L$4``*U1``"
+M1&4``\1$``+")``"M8@``D1E``/$1``"PS0``]0>``!YQ0`#0G4``T)R``)/
+M_@`#\$(``L`!``+"(P`"H00``_!&``*E"0`#\`0``\&,``/!D``#P:P``\&P
+M``*C"0`#\$(``\&L``/!L``#8G(``T)&``*A)@`#\$8``J4I``/P!``#P8P`
+M`\&2``/!K``#P;(``J,I``/P0@`#P:P``\&R``-B1@`"H/X``=FN``-"3@`"
+MH14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#\$(``\&L``/!
+ML0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!K``#P;,``J,Y
+M``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.'.``*@P0`!V3<`
+M`T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD``_\```+)`@`#
+MJ9```LM&``.KL``".=L``T`0``!YX``"O`0``]S```/8\``"O`D``\&Q``(M
+MGP`","@``B_O``-!4``#054``T%:``!AQP`#_P```_\```-@&``#8!T``V`N
+M``#AY0`#[````KLA``*[$````<4``_\```/_```"0`X``=H3``.IA``#JZ0`
+M`KP/``.(@``"2(P``XJ@``)*K``#2)P``TBA``*@W@`#\$(``TBT``-(N0`#
+MP1@``\%:``.,%@`#CU8``F$<``)E7P`"H-X``_`$``-HG``#:*$``_0```/P
+M0@`#:+0``VBY``-*Z``#2NT``J#>``/P0@`#2O```TKU``*\[@`"0`P``D1,
+M``.(E@`";)@``F`,``.*M@`";+H``F1,``*@W@`#\`0``VKH``-J[0`#]```
+M`_!"``-J\``#:O4``^P```*_!0`"O````J#>``/P00`"O$```]SP``/8P``"
+MO(```FB,``)IG``":JP``FN\``/!"``".BL``\$)``(Z*P`#P0H``CHK``/!
+M"P`".BL``]2>``/[```#U)X``^P```/!$``#P2```\$P``/4'@`#^P```]0>
+M``/[```#[````&HQ``(M"``#Z````K%@``/H(``#Z#```VF@``-)F``"N`\`
+M`K7U``*S```#P2X``F`(``)!%0`#:#```K\!``(M!``".,H``C`H``-`+``"
+MOP0``_\```)/\``#K_(``^CP``(O]```,AH``_\```*U"0`"Q&X``CBN``/H
+M\``"H-X``_!!``*_0```^>```%G'``!YX``"O`0``]S```/8\``"O`D``BV+
+M``/HP```X<X``.'&``/H@``#Z*```CG;``*_0``"O````]S!``/8\0`"OT``
+M`]S@``/8\``",;@``K\3``(X7``"+NP``J#>``/P00`#P:L``&'.``!YQ@`#
+MU%\``_L!``/07@`"NP(``J'^``/P00`#P4H``J#^``/P00`#P5H``J#[``/P
+M00`#P6H``J;[``/P00`#P7H``]1>``/[```"L!```LS.``*EP``#\`8``.'.
+M``/!C``#P:P``CG;``/T```!VFL``K$$``+/_@``^<8``J'Q``':I@`#Z+``
+M`-G.``/!BP`#P:L``CG;``!YX``"O`0``]S```/8\``"O`D``\&^``(MBP`#
+MW.```KM```/8L``#]````=IK``(X[``"N`@``KH(``(YVP``6<<``'G@``*\
+M!``#W,```]CP``*\`P`"R[P``KP)``(MGP`#2`@``K1@``)@!``#:`@``TF8
+M``/_```"L@$``^@P``-H,``#[````K0$``)&-``"H&0``=K*``/H\``"/?0`
+M`K\!``(]]``#:&L``T))``(R9@`#8DD``^P```-"30`",F8``V)-``-(9``#
+M^`$``KT,``))T@`"H-D``_!&``*_`P`".RD``K\#``*]```".PH``^P```*]
+M!``"2=(``_`&``*_`0`".RD``K\!``*]```".PH``^P```*]"``"2=(``_`&
+M``*_`@`".RD``K\"``*]```".PH``^P```*]8``"2=(``J#9``/P1P`"OP,`
+M`CNP``*_`P`"O0$``KP!``(["@`#[````KT@``))T@`#\`<``K\!``([L``"
+MOP$``KT!``*\`0`".PH``^P```*]0``"2=(``_`'``*_`@`".[```K\"``*]
+M`0`"O`$``CL*``/L```#2&(``DS.``(;'``#@/(``\````.!^``#P!$``DW>
+M``/P10`#P````FJ@``)*H0`#]`0``_`#``/`$0`"2J```FJA``-H8@`"L/(`
+M`FJ@``*@"@`#\$<``TA```*T"``"M?<``F$4``-H0``"014``VA```-H:P`#
+M[````TA4``/H@``"N0,``DO^``/P`0`":(D``KH"``*Y#``"2_H``_`!``)H
+MB0`"8S@``VA4``/HD``"M`0``DO^``/P`0`":9H``DOZ``/P`0`":90``TE@
+M``-H:P`#_P```_\```-(90`#_P```DO6``*@O0`!VZ<``DN3``';/@`#0"@`
+M`X3P``"B`@`#HB8``C%$``,"+@`!VTT``T@$``*T[P``BBP``D$4``-H!``"
+MM8```DO^``/P!0`#2)@``K2_``)#-``"8S4``VB8``)+^@`#\`4``TBP``*T
+MOP`"0S0``F,U``-HL``"/>@``K8$``-H,0`#0"@``C%$``)!&@`"&Y```$H!
+M``/_```"N(```\"9``.)G``"2_X``_`&``-)/``#2)D``F,X``)D20`#:3P`
+M`VB9``)+^@`#\`8``TE```-(L0`"8S@``F1)``-I0``#:+$``DO^``/P!@`#
+M2)```TB5``)@"``"9$@``VB0``-HE0`"2_H``_`&``-(J``#2*T``F`(``)D
+M2``#:*@``VBM``-`*``#_P```K@$``)!&``#\`$``CQH``-`*``#_P```K@(
+M``)!&``#\`$``CTJ``-(0``"N(```DO^``/P`0`"81@``DOZ``/P`0`"8B@`
+M`VA```*\`0`#[````TA4``/`B``"0S@``VA4``-"20`",F8``V))``*\```#
+M[````T`H``#YNP`"N`@``D$8``/P`0`"/4$``T`H``/_```"N`0``D$8``/P
+M`0`"/+<``T`H``/_```"N`(``D$8``(;YP`"2_X``AO*``-)/``#2)D``KA_
+M``)#.``"1$@``VD\``-HF0`"O`(``DO\``(;U``#24```TBQ``*X?P`"0S@`
+M`D1(``-I0``#:+$``DO^``(;W0`#2)```TB5``*X?P`"0`@``D1(``-HD``#
+M:)4``KP"``)+_``"&^<``TBH``-(K0`"N'\``D`(``)$2``#:*@``VBM``-`
+M*``#_P```K@.``)!&``"'`<``CT4``)!%P`#:,@``T@(``*X$``"01@``=P'
+M``)+_@`"&_P``T@@``*T`0`"M?P``F$4``-H(``"014``V@@``*\`@`"2_P`
+M`AP&``-()``"M`$``K7\``)A%``#:"0``D$5``-H)``"-N0``DO^``(<#@`#
+M2)@``K3```)C-``"0S0``VB8``*\`@`"2_P``AP6``-(L``"M,```F,T``)#
+M-``#:+```KP#``(]R``#2$```KA_``)+_@`#\`$``D(H``*\`@`"2_P``_`!
+M``)!&``#:$```T@(``*X$``"01@``=PQ``-`*``"O`0``_\```),P@`#\`,`
+M`CU8``/T```#\$$``CW+``).[@`!W#,``KP(``(]R```>;L``_\```/_```"
+M2_X``_`$``-(F``"M#\``D,T``-HF``"O`(``DO\``/P!``#2+```K0_``)#
+M-``#:+```TA```*X(``"2($``AQ*``(]Z``"M@(``V@Q``-)?``"N`(``DB`
+M``(<40`#27$``CWH``-H,0`#2`0``"(L``/_```#_P```\$4``-H!```>;L`
+M`K@```*\`@`#2%0``DO^``/P`0`"N`,``DO\``/P`@`"O`P``FB,``/`B``"
+M0S@``VA4``.`^```@@(``^P```-("``"N!```D$8``'<>0`"2_X``_`$``-*
+M5``"M`\``F`$``-J5``"NP(``DO[``/P!``#2E@``K0/``)@!``#:E@``DO^
+M``/P!``#2E0``K3P``)@!``#:E0``KL"``)+^P`#\`0``TI8``*T\``"8`0`
+M`VI8``-("``"N!```D$8``'<EP`"2_X``_`$``-*5``"M`\``F$4``-J5``"
+MNP(``DO[``/P!``#2E@``K0/``)A%``#:E@``DO^``/P!``#2E0``K3P``)A
+M%``#:E0``KL"``)+^P`#\`0``TI8``*T\``"810``VI8``-("``"N!```D$8
+M``/P`0`#[````DO^``/P!``#2E0``K0!``)B)``#:E0``KL"``)+^P`#\`0`
+M`TI8``*T`0`"8B0``VI8``/L```#2`@``K@0``)!&``!W,@``DO^``/P!``#
+M2E0``K3^``)")``#:E0``KP"``)+_``"',@``TI8``*T_@`"0B0``VI8``)+
+M_@`#\`0``TI4``*T#P`"010``VI4``*\`@`"2_P``AS5``-*6``"M`\``D$4
+M``-J6``#2`@``K@0``/_```"01@``=SG``)+_@`#\`0``TI4``*T\``"010`
+M`VI4``*\`@`"2_P``ASG``-*6``"M/```D$4``-J6``"2_X``_`$``-*5``"
+MM`\``D`$``-J5``"O`(``DO\``(<]``#2E@``K0/``)`!``#:E@``T@(``*X
+M$``"01@``=T%``)+_@`#\`0``TI4``*T\``"0`0``VI4``*\`@`"2_P``_`$
+M``-*6``"M/```D`$``-J6``"O`@``CW(``(]%``#P=\``DO>``/P`@`"OP``
+M`CWT``*\`@`"2]P``_`"``*_`0`"/?0``\']``/L```"M_P``K8S``*U1``"
+MM````TC(``*@_@`#\$$``K0!``*\`@`"H/P``_!!``*T`@`"810``VC(``)@
+M!0`#:,@``_\```)`!@`#:,@``KP"``(]R``#[````T@(``*X$``"01@``=T[
+M``)+_@`#\`0``TB8``*T?P`"0B0``VB8``*[`@`"2[\``_`$``-(L``"M'\`
+M`D(D``-HL``#23@``X3R``/`1``"0B0``VDX``/L```#23@``X3R``)B)``#
+M:3@``T@(``*X$``"01@``_`!``/L```"2_X``_`$``-(F``"M(```F(D``-H
+MF``"NP(``DN_``/P!``#2+```K2```)B)``#:+```^P```-"20`",F8``V))
+M``)!_@`"'64``T.N``*P[P`#_P```DNP``)*L``"2;```DBP``-CK@`"L0(`
+M`D'Q``(=<``#0^X``K#O``/_```"2[```DJP``))L``"2+```V/N``-(5``#
+MC/@``F(L``-H5``#270``KS?``)$+``#P5,``CWH``-H,0`",40``KP0``)D
+M3``#:#$``C%$``-(5``"O)\``D(L``-H5``#270``_\```/!0@`#P5,``CWH
+M``-H,0`"0?X``AV3``-#K@`"L!```_\```)KL``":K```FFP``)HL``#8ZX`
+M`K$"``)!\0`"'9X``T/N``*P$``#_P```FNP``)JL``":;```FBP``-C[@`"
+MO`(``D?^``),_``";,<``K<#``*@?P`#\$$``^C```-(R``"N$```KD_``)@
+M"``"81P``VC(``)`"0`#:,@``\#,``)!'``#:,@``KO\``)*_@`#\`@``T@A
+M``/_```"95X``V@A``-JB0`"15L``V@A``-JB0`"N@(``DJO``/P"``#2"4`
+M`_\```)E7@`#:"4``VJ-``)%6P`#:"4``VJ-``/L```##,X``=W(``/L```"
+M/>@``K8"``-H,0`"M@$``TF>``*\$``"9*P``\%;``-H,0`#29H``KP"``)D
+MK``#P5L``V@Q``/_```#270``KP0``)D+``#P5,``V@Q``(Q1``#P,P``D1,
+M``-H,0`",40``\%*``/!6P`#:#$``^P```/!;@`"MP,``DW^``/P`@`"O0(`
+M`D=]``*]`@`"3?T``_`"``*]`0`"1WT``^P```*X!``"L0(``K"```)/_@`#
+M\`$``K#```(^0@`"L0,``K````)/_@`#\`$``K!```(^0@`"L0,``K"```)/
+M_@`#\`$``K#```(^0@`"L00``K````)/_@`#\`$``K!```(^0@`"L00``K"`
+M``)/_@`#\`$``K#```(^0@`"3_X``_!'``-'-``#1SD``_\```-G-``#9SD`
+M`_0$``/P!0`#1W0``T=Y``/_```#9W0``V=Y``/L```"N`0``^@```/H$``#
+MZ"```^@P``)/_@`"'C```V4L``-E,``#930``V4X``-E/``#]````=XU``-E
+M;``#97```V5T``-E>``#97P``K$&``*P```"3_X``_`!``*P0``"/D(``K$&
+M``*P@``"3_X``_`!``*PP``"/D(``^P```+""``#W!```]@```/<$0`#V"$`
+M`]`>``/07P`"O`<``]0>``/47P`#^P```_L```/[`0`#^P$``]`>``/07P`#
+:#,X``=Y*``/L```#_P```_\```/_```#_P``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_me.bin.uu
new file mode 100644
index 0000000..74b24a0
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_me.bin.uu
@@ -0,0 +1,194 @@
+begin 644 TAHITI_me.bin
+M?$"``8@```#40`!_?$"``8@```!\0,`!S$``*,Q``"E\0(`!B````-A``![$
+M$``A)1```I4`__Y\00`!Q!P`)L0@`"38```<S(``"\W!H-G.`:#:V$``',04
+M``>50``"V4&BI,0;``+8```;S8``&L`^``3,`:'TS#T@!,0]``',```%V$``
+M&]A``!]\0(`!B````,Q!+@',02X"S$$N`\Q!+@!\0(`!B````'Q`P`&,``4B
+MS$$N`<Q!+@+,02X#C``%)LQ!+@!\0(`!B````'Q`P`'$&``PQ!P`,7W90`)\
+MU@`.Q"0`%9I`__^:```#S,``%(````#`*(``SH$P2L0\`'\DD``"P"H``7Q`
+MP`&5```#Q!0`,'S4P`$4S``"S,$EQ]1I)<A\0(`!B````'Q`P`$8T`'H),P`
+M?WQ!0`%06``@?5E`&GQ!@`%07``@?9V`&GQ!P`%08``@?>'`&GQ"``$E)``!
+MS,``(]%``"31@``ET<``)MA``">60``,Q"@`+)J`___()``M?EZ`#)J`_YP2
+M+``&!NP``0KL``&:P/__V$``)X```&#$*``LFH#__WQ`@`&(````?$#``<00
+M`##,027,?04``<Q!)<_-`27.?$%``230`'\56``0)50`_\T!)=/-@271S4$E
+MT,Q!)=)\04`!?$&``1C<`#`8X``Q&.0`,ACH`#,8[``TS$$EULQ!)=?-@275
+MS4$EU,`R``260``AEL```LPQ)=G,,278EH``!);```+,,27;S#$EVGP#`!&6
+MP``#Q#$``5,P`"#$-0`!?S<`&M,``!:6@``(?`.`$9;```/$.0`!4[@`(,0]
+M``%_OX`:TX``%Y7`_V":P``$?7<`#)<`_^2`````4;@`('^7@!I_.X`,EX#_
+MWX````"6`/]6S#$ES<R```O$-0`!ET#__'Q`@`&(````Q"``)GQ!0`'&)P/D
+ME4```LP```',```)"F0``<Y@`^1\0(`!B````'Q`P`'`%@`$)-#__WT5``K,
+M@``+S!$``!C8`#X4W``?Q"$``7Q"0`&5P``%?E:`"LP```O,*0``Q"4``7XF
+M``E\0L`!E8``!7[7``K,```+S#$``,0M``%^+@`*)1#__\P```O.$0``@```
+M`'Q`P`',0```@````,R```O-02)=S0$B7,Q!H?Q\0(`!B````,R```O,02)7
+M?$"``8@```#,02)<S$&A_'Q`@`&(````P`X``<Q!(ES,0:'\U$VA_7Q`@`&(
+M````S(``"\Q!(EU\0(`!B`````A,``%\00`!S(``"WQ!0`$E6/__&5P#\!5@
+M`!7-@:$"S<$B5LX!(ER4P``$S0&A_`C,``&```#TS0&A_,P!H0)\0(`!B```
+M`'Q`@`'`*@`"?$#``7Q!``%]*0`*))0``228``8DG`,`%=P`"'Q"``%\0D`!
+MP"X`!,R```N50``,!?`B6'\O``K,,0``Q"D``<S!(6G-`2%JSH$A:S&T``+,
+M`2%LET``"H```2XQM``"ET``!\`N``0%\")8?R\`"LPQ``#$*0`!@``!+C&T
+M``"70``#?@*``8```2XQM``$ET#^UR)D`##.`2%MSD$A;L0J``#$+``),?``
+M`#'T``$Q^``"FL```HP``Q[:@:*DEP```\Z!HK>`````ET```\Z!HKN`````
+MEX```\Z!HK^`````SH&BPX`````$&```@``!0P08``'$)``F?$#``<9K`^08
+MT``P)-0`_P:H``'.I`/DFD``$L0X``?80``>Q#P`(2?\``*7P/_^S(``"Y>`
+M``+90:*DQ#\``L_``!K`/@`$S`&A],P](`3$.0`!S```!=A``!_-0:#:S(``
+M"\U!+A29@``"S````LU```A\0(`!B````'Q`P`$8T`'H&-0`,!C8`#0%*`%K
+M?$(``7Q"0`&5```'AH```(```86```&I@``!OX``!1Z```%[$50`$'X6``K,
+M@``+U&$``)6`_HO`.@`$S#DA0,0Y``%\0(`!B````!%4`!!29``@?B8`&LU`
+M`!W48@``E8#^@,0@`!V:`/__?$"``8@```#<.@``F4``&R><``&5P``-"[@`
+M`<X!(6G.02%JS$$A:\P!(6R;@``#E8#^<8```9U29``@?B8`&D8@``16)``@
+M(F0`,LX!(6G.02%J"[@``LQ!(6O,02%LFX#__96`_F3$,``9EP#__WQ`@`&(
+M````"[@``<X!(6G.02%JS$$A:\P!(6R;@/_[E8#^68```9U29``@?B8`&IE`
+M``K2```KU$``+-A``"V,``4OE8#^4,0X`"^;@/__?$"``8@```#<-@``"W0`
+M`=(``"O,0``LV$``+8P`!2^;0/_[F8#_]7Q`@`&(````Q!P`,,`J``%^'@`!
+M%B```LX!)<?4:27(E8#^.\`Z``3,.27+Q#D``7Q`@`&(````?$#``7Q!``$9
+M%``]F4``"L0<``V5P/__S,$A`,T!(0',P2$"S0$A`]D!HJ1\0(`!B````,S!
+M(77-`2%VQ"``#I8`__\R*``",BP``YJ```2:P``%S```#(````#,```,@``!
+MV,`^``3,/3!^Q#T``3/H``&7P/X8FH`#.`0X0`#,```!SX$P2H``!2%\0,`!
+M?$$``4#4``/-02)<S0&A_,`>``%\0@`!",P``08D``$&*``"SAVA_<Y=H?W.
+MG:']F,#_^7Q`@`&(````?$#``230``$4S``!?$%``7Q!@`',@``+E0``!B&8
+M`##-02%MS8$A;L0>``"```(.P"(`!'X6``K,(0``Q!T``7Q"0`%\0H`!F,``
+M`\WE``"`````SD$A:<Z!(6K-P2%KS`$A;'Q`@`&(````?$#``7Q!``%\04`!
+M?$&``7Q!P`$8I!_H,F@`/`0@``&6@``(?$(``3HP``-"(``"FP```@0@`$`$
+M)``!@``"*GX"0`$*9``!FD#__R3L`!#,@``+FL``"<`J``3$+``0?I*`"LP`
+M``',*0``SL``$,0Q``&```([(50`,,T!(6W-02%NQ#(``'\?``DD]``'!W@"
+M/Y=``">'@```@``"1X```DR```)1@``"5H```EN```)@@``"97\;@`\4I``(
+MEX``'29D`/^```)V?QN`#A2D``B7@``8)F0`_X```G9_&X`,%*0`")N``!,F
+M9`#_@``"=G\;@`T4I``(FX``#B9D`/^```)V?QN`#Q2D``B;@``))F0`_X``
+M`G9_&X`.%*0`")N```0F9`#_@``"=A2D``@F9`#_,F@`/!3L``B:@/V7?$-`
+M`7Q#@`%\0\`!S```"Y;```;/02%ISX$A:L_!(6O,`2%L@````,_U``"`````
+M,F@`/)J`_[/40`!_@````'Q`P`%\00`!P!X``144`!+`(@`"P"8`!)5```3`
+M)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!(6G-`2%JFH``!\U!
+M(6O-@2%LEL#]<L0P`!F7`/__@````,@4`!A56``@S4$A:\V!(6R6P/UJ@``"
+MCWQ!``%\04`!S$```\Q```3,``/DS``#Y<P``^;`#H``?$)``7Q"@`&`````
+M?$#``1C0`>@%*`*I',S^",R```N5```)AH```(```K2```+#@``"RH```M&`
+M``+7@``"XX```P',P:*D?$"``8@```#`$@@`?$%``7Q"``%]#,`*P!(`!!58
+M``,57``-?='`"1(@`!-^'D`*?DZ`"LZ!HJ3-@:'^?$"``8@````$$"$8Q!0`
+M"Y5`___440``S,&BI'Q`@`&(````!!`A!L04``R50/__U%$``,S!HJ1\0(`!
+MB````-A```_,P:*DQ!``#YD`__]\0(`!B````!C0`#01%``4Q"0`#99`___,
+M02$`?45`"LU!(0',02$"S$$A`\S!HJ1\0(`!B````"38``%\00`!?$%``1&<
+M`!!\0@`!?5U`"A5D`!TF9``"E8``"<0\`!^7P/__FD``#<0H`#`6J``"?BH`
+M`<P``!6```+[Q#P`()?`__^:0``%Q"@`,!:H``)^*@`!S```%<T!(5C-02%9
+MS@$A6LS!HJ1\0(`!B````!C0`#01%``4)-@`/Y4`_ZW$)``-ED#__S6<``;,
+M`2$`S4$A`<P!(0+,`2$#F<```]D!HJ2`````!"``%,X!HJ1\0(`!B````'Q`
+MP`$4T``=&-0`/)D```*`````S4``'(````!\0,`!C``#'GQ`@`&(````V$``
+M'L0\`"$G_``"E\#__LR```O90:*DQ#\``L_``!K`/@`$S`&A],P](`3$/0`!
+MS```!=A``!^0````?$#``00\`"+,@``+S\&BI,P```9\0(`!B````,`2``%\
+M44`*S(``"]15``!\0(`!B````'Q`P`%04``@?-#`&E4<`#]\04`!?$&``<R`
+M``O0P`"#E<```\`<@`#-P2`0E8#\NXP`!2+=@P``!5P@`,P```O470``@``%
+M*GQ`P`%04``@?-#`&GQ!0`%\08`!S(``"]#``(25@/RMC``%(MV#```%7*``
+MU%T``(``!2I\0,`!4%``('S0P!I\04`!?$&``<R```O0P`"%E8#\H(P`!2+=
+M@P``!5PL`-1=``"```4JS(``"]1#(`!\0(`!B````,R```O40Z``?$"``8@`
+M``#,@``+U$,L`'Q`@`&(````?$#``8P`!2)\00`!?$%``93```)\08`!?$'`
+M`7Q"``&,``4FE0``"I5```G,@``+S$,L`,W#+`#,@``+S$,L`,X#+`!\0(`!
+MB````,0D`![,0`!_S$``?QIH`#!\0(`!?$#``9:`_'78@``N?$"``8@```#,
+M@``+S$.@`'Q`P`$$&``!W8,``(P`!2+40Z``@``%*B2,___,@``+U$T``'Q`
+M@`',@``+B````'Q`P`$8U``P&-`!Z!C\`#0DS``/!.@#IGQ!@`%\0<`!E,``
+M2H:```"```.^@``#QH```\^```/>@``#L8```[2```.V@``#N(```[J```.\
+M4=P`('V>`!J```/]R"``+8```_W((``6@``#_<@@`!>```/]R"``&(```_W(
+M(``R@``#_9E```,AW``P@``#PB'<`%#-@2%MS<$A;L@B``"```/]4=P`('V=
+M@!K8```CT8``)-A``"?$*``LFH#__\@@`"Z```/]Q!P`,,`R``1]G8`!%9@`
+M`LV!)<+,,27#E4```\R```O,,27#Q"$``95``"3$)0`!4F0`('XF`!J```/]
+M,:P(`,0T`!"6P``#S````8```_`YK`I\/;`*=YK```27```#S````8```_`Y
+MK`K</;`*V9K```.7```"S````8```_#$-``0S(``"\`Z``1]N8`*S!D``)5`
+M``,%F``!S!D``,0A``&50``%Q"4``5)D`"!^)@`:ST``$`4H!`%\08`!?$'`
+M`94```>&@```@``$,H``!#R```1*@``$%8``!"?$-``0S(``"\X9``"50``$
+M!9@``58@`"#.&0``E\#[\L`Z``3,.2%`Q#D``<]``!!\0(`!B````#&L"`#$
+M-``0EL```\P```&```0(.:P*?#VP"G?$-``0FL``!)<```/,```!@``$"#FL
+M"MP]L`K9FL```Y<```+,```!@``$"%'<`"!]G8`:V```'<X:``"50``$!9@`
+M!%8@`"#.&@``F\``D'Q`@`&(````E4```B'<`#)6)``@S8$A:<W!(6K.`2%K
+MSD$A;)O`_E9\0(`!B````%'<`"!]G8`:T8``*\X``"R50``#5B0`(,Y``"S8
+M0``MC``%+Y?`^[O$.``OFX#__WQ`@`&(````Q!P`,,`J``%]G8`!%9@``LV!
+M)<?.*27(E4```U8D`"#.:27(E\#[K<`Z``3,.27+Q#D``7Q`@`&(````Q!0`
+M'#U8``29@/_^S```#7Q`P`$H4(``%10`'QD8`'T9'`!TQ"``,#&8``$QW``!
+ME8```GS@P`%\0D`!E<```GYB0`',P2&`S0$A@<Y!(8+,02&#S$$AA)5`^Y'$
+M%``<F4#__WQ`@`&(````P!8`!,00`";,@``+S%4A0,09``',$`/W?$"``8@`
+M``#$(``FV```'L0,`"$DS``!E,#__L8G`^1\0,`!S(``"\S!(7S,02%]Q!@`
+M)'Q!``%\04`!ED```LV!(7K-`2%^P#8`P,`J``1_3T`)$5P``07<``&70``4
+MS"DA?\0E``$:;``^EL``!Q%<``$%W``!"=P``9G`___,@``+@``$DA=T`!<H
+M+`!@FT```B@L`$#.P``CV$``)\0T`"R;0/__@``$J@G<``&9P/__S(``"\PI
+M(7_$)0`!%FP`'Q%<``$%W``!FL#_^!3\`!_8```?F\#[4,00`";,$`/W?$"`
+M`8@```!\0,`!?$$``148`!]1%``@&1P`,9F```C-```=?4U`&M16``"5P/M"
+MQ"``'9H`__^`````W#H``,`F``3,P2%I?24`"LT!(6H+N``"S$$A:\Q!(6R;
+M@/_]F<#]Q'Q`@`&(````)$P`_\Q,`P!\0(`!B````,0@`";$3P,`S(``"\SA
+M(46`````S(``"]K!HJ1\0,`!?$"``8@```#$#``:F,```]A``"^```3<V$``
+M,'Q!``%]`4`!%50``254``&90``))1```94`^QG(%``TE4``!<@8`!N5@``#
+M?97`#I7`^Q/((``ST@``,M@``![$(``A)B```98`__[`)@A`SD$A?,P!(7W$
+M*``DSH$A>LP!(7[`*@`$!!0`!$%<``@H+`!`SL``(]A``"<)W``!F<#__\R`
+M``O,*2%_Q"4``19L`!]!7``"FL#_^<0T`"R;0/__V```'WQ`@`&(````Q`P`
+M$S#0``&5```#S(``"]L!HJ3,0``.Q`P`$L00`!,PU```/1@``7U9P`K80``Q
+MF<#_^MA``!/0```R?$"``8@```#`#@$`S````<S!,$J```4AV$``$<0\`!&7
+MP/_]D````-@``!'$/``1F\#_^9````#8```1Q#P`$9O`__5\0(`!B````-B`
+M`![$/``A)_P`!)?`__[`.``OP#X`!,^!(?C,/2'YQ#@`)@0\``5_^X`"Q#T`
+M`7_[P`4G_``!F\#_]MB``!^0````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0.7`!```@`1``4`$@`*`!4`)0`6`"L`%P"Q`!L`-``<`$$`'0!O`!X`
+M3``A`+L`)`#9`"4`V0`G`.,`*`#6`"H`WP`L`-D`+0#C`"X`YP`O`.T`,`#Q
+M`#(!0@`T`0,`-0#C`#<!8P`X`-D`.0'+`#H![@`[`?X`/`(9`#T">@`_`4``
+M0`.=`$$$60!"!'0`0P1\`$0"F`!%`AD`1@*C`$<"HP!(`J,`2@,3`%(#&@!3
+M`RT`5P,T`%\#60!@`SH`80-,`&@#9@!I`VH`<@-R`',#CP!V`VX`=P-N`'H$
+MM0!]!,X`?@32`(4$UP"&!-P`B@4-`(L%#0`/!1X`#P4>``\%'@`/!1X`#P4>
+M``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`
+M#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/
+:!1X`#P4>``\%'@`/!1X`#P4>``\%'@`/!1X`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_pfp.bin.uu
new file mode 100644
index 0000000..4d84cdf
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_pfp.bin.uu
@@ -0,0 +1,194 @@
+begin 644 TAHITI_pfp.bin
+M?$"``8@```#,@```U$```'Q`@`&(````S(```,S```#40```?$"``8@````D
+M3``/,.@``B20``*:@``,?$%``5!8`"!]E<`:F,```]'``!F`````F0```]'`
+M`!J`````T<``&X````#$(``5QB0`"I9``6-\00`!?$%``<R```#,P```S0``
+M`,U```#-```MS4``+GQ`@`&(````S(```,Q```#,```2@``#BLQ``"A\0(`!
+MB````,@,`!M\Q0`1T0```]C```/,@```S````,Q```!\0(`!B````,@,`!I\
+MQ0`1T0```]D```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L
+M`'XB[$Y(EH```MB``"+.P```V````,Q```#,0```'(@`$,R```#,0```?$"`
+M`8@```#(#``:?,4`$7Q!0`%\08`!?$'``7Q"``%\0D`!E<#_J=$```/9```#
+MQ"@`$,P``!2:@``$Q"@`!<Z```#,````Q"@`"1JH`#`@+`!^(NQ.2):```+8
+M@``BSL```-@```#-0```S8```!R(`!`)W``!S(```,Y```"5P/^2?2$`$8``
+M`%C(#``:?,4`$<46``"50`,3*!@`!'T9@!'%E@``E4`##\P``";1```GT0``
+M`]E```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L`'XB[$Y(
+MEH```MB``"+.P```V$```,Q```#,0```'(@`$,R```#,0```?$"``8@```#(
+M#``:?,4`$<46``"50`+R*!@`!'T9@!'%E@``E4`"[GQ!0`%\08`!?$'``7Q"
+M``%\0D`!E<#_8<P``";1```GT0```]E```/$*``0S```%)J```3$*``%SH``
+M`,P```#$*``)&J@`,"`L`'XB[$Y(EH```MB``"+.P```V$```,U```#-@```
+M'(@`$`G<``',@```SD```)7`_TA](0`1@```H,08``@EF``!?$)``7Q"@`&5
+M@`+(4JP`('[FP!I\0,`!?$$``<0<`!&9P/__'(@`$""(`'`0U``"?M5`$=%`
+M``/-```#S(```,Y```#.@```S,```-PZ``#-````EX#_+GQ`P`%\00`!@```
+MR,00``_$'``$F0``!,P``!+-P```S````,08``@EF``"@```O22,``+$$``0
+MQ!@`")C```B9```%Q!P`!<P``!/-P```S````!F8`#"```"]&9@`.(```+W$
+M'``$S<```,P```#,@```U$```'Q`@`&(````Q!P`!,W```#,````R`P`&<R`
+M``#,0```$%```GT-`!%5%``@T0```]A```/,````?$"``8@```#$'``%S<``
+M`,P```#,@```U$```'Q`@`&(````Q!P`!<W```#,````Q"0`),@,`!S&4P/H
+MS(```,Q```!1$``@?-#`&GS%`!%5%``@?46`"LT```#-@```?$"``8@```!\
+M0,`!4%``('T-0!K10``8S```)7Q`@`&(````?$-``<@<`!C$&``7'(@`$""(
+M`#!\04`!?5C`!'S<P!%4T``@?$%``<R```#/0Z*>S,.A^LT#H?G-0Z*=S4``
+M`,Q```!\0(`!B````'Q#0`$<B``0((@`,'Q`P`%\00`!?$%``<R```#/0Z*>
+MS,.A^LT#H?G-0Z*=S4```,Q```!\0(`!B````'Q`P`$DT``!S,.BG]A``!>5
+M```"V(``%\R```#,P```?$"``8@```!\0,`!S(```,S#HJ+,P```?$"``8@`
+M``!\0,`!%-0`'\R```!\00`!E4```LS``!\5&``?S,```,T```"5@``"S0``
+M(,P``'^```.*(`@`?B"(!^C$(``5'*@`$,Z@``1\00`!4%0`('Q!@`$&)``!
+MSD``%16<`!A]%0`:S>``"<V@``O1(``!S:```<0L`"15,``@T0``',\L`^B:
+M```$Q"0`(YI```(AW``PS<```(```XK$(``5Q@P`"ARH`!"4P``#SJ``!H``
+M`63,```(@``!@,0@`!5\08`!"B```<84``W&&``*?5F`"LX``!65@``$S*``
+M!LU@``:```.*S*``!,U@``2```.*?$#``130`!XQ%``!E0#^=)5``?08T`'H
+M&-0`,!C8`#0%*`&;?$(``7Q"0`&5```'AH```(```XZ```..@``#CH```XZ`
+M``&I$50`$'X6``K-0``AU&$``)6`_EO$.2%`?$"``8@````15``04F0`('XF
+M`!K-0``AU&(``)6`_E+$(``3F@#__WQ`@`&(````?$#``7Q!``%\0X`!?$/`
+M`5$0`"!3_``@?[^`&GS0P!H$'``@TX```MB```+0P``"S<```@0<``@$(``!
+M?`)``<07``/$&P`#49@`('U90!K$*P`#Q"\``\0S``/$-P`#"=P``5+L`"!^
+MKH`:4W0`('\W`!I_*T`2?G9`$5:H`#]7,``_?K*`"7XJ``F9P/_QEH#_Y%/T
+M`"!_>T`:?65`$558`"#,```AS78``,VV``#$(``3F@#__WQ`@`&(````Q"``
+M)'Q`P`%\00`!S.`#_<T@`_I1%``@?-3`&M#```(5%``?&1@`\)E```($-```
+M+UP``7UV``E]7D`)F8``!,P```+,```-@``#BA68``$5+``()NP``9F``#,5
+M,``,E@```\P```*```.*!!0`(,U```(G,``!*"@``00X`"`$/``(Q!<``\0;
+M``/$'P`#Q",``WU=0`U]H<`-?5U`"A80`!\5G``??1T`"7T70`E^DH`)"[@`
+M!`O\``&;0``2F\#_\<0@`"3&#P/]QA,#^IJ```G,```-FP`!<5$4`"!\U,`:
+M!!0`(-#```+-0``"@``"`<P```V6P`%IS```#H```XK,```-FL```LP```Z7
+M@/W9"[@``<0_``.;@/_]@````,P```Z60``#S````H```XK:```"Q`L``\0/
+M``/$$P`#Q!<``\0;``/$'P`#Q"<``\0K``,5_``?%K``'W_SP`D4\``??_/`
+M"15P`!]_\\`)?8B``GW,P`*7P``,?E$``GZ50`)\D(`,?-3`#'R/0`F:P``"
+M++0``<P```V;0`$_S```#H```XK$(``DQ@\#_<83`_I1%``@?-3`&M#```*`
+M``(P?$#``130`!XQ%``!E0#]KI5``2X8U``P&-`!Z!C\`#0DS``/!.@"8GQ!
+M@`%\0<`!E,``$H:```"```)L@``#CH```XZ```..@``":8```XY1W``@?9X`
+M&H```GE1W``@?9V`&IE```/%H@``@``"><FB``"```)YQ:$``)5```4%F``!
+MQ:4``%)D`"!^)@`:!2@"?7Q!@`%\0<`!E0``!X:```"```..@``#CH```XZ`
+M``..@``"C=@``"'.&0``E4``!`68``%6(``@SAD``)?`_7?$.2%`?$"``8@`
+M``!1W``@?9V`&M@``"'.&@``E4``!`68``16(``@SAH``)O`_QI\0(`!B```
+M`'Q`P`%\00`!&10`.Y5``!O$%``2/5@``IF`__X9'`!]&2``=,04`"4QW``!
+M,B```<P``"',```C*1"``)7```)\U,`!?$)``98```)^5D`!S,$AA<T!(885
+M%``?SD$AA\Q!(8C,02&)E4#]3L04`!*90/__@````,R```#,P```S0```-1`
+M``!\0(`!B````,0H`"38:`/WS(```,Q```#&CP/WF,#__WQ`@`&(````Q"@`
+M),0P``_$-``$FH``!9L```3,```2ST```,P```!\0,`!V&@#]\R```#,P```
+MU$```!30`!^9``"X@``"P,R```#,0```S$```,Q```!\0,`!S,``%LS```#4
+M0```?$"``8@```!\0,`!%-P`'1C8`#S,@```S,```)G```.9@/T<@``#BLV`
+M`"2```.*?$#``5!0`"",``,-?-#`&L0D`!7$%``D?$.``99```C$U@``F4``
+M&=^#``#/I``/C``#$=1``'^`````Q5\#[I7`___85`/QQ5L#])6```/8%`/Q
+MF8#__,5?`^X]X``"F@``!\5C`^N:```%WX,``,^D``^,``,1U$``?PG<``'-
+MU`/NV!0#\8P``Q%\0(`!B````-@``![$/``>F\``?Y````#80``>Q#P`'I?`
+M`'N0````C``##<0@`!5\0,`!P#;_`,00`!;`,#__?/5`"7U1@`E]@8`=?/.`
+M"9F```;?@P``SZ``#XP``Q'40`!_@````(P``Q%\0(`!B````'Q`P`$4W``(
+ME<``&23<`!!\00`!4%0`()G```/%'0``@``#,WT5`!K%'@``?$(``7Q"0`%\
+M08`!?>7`"7WB@`]!K``"FH#\QP;L``,*[``!FL#__R3<`!"9P``#Q1T``(``
+M`S;%'@``@``#-LR```#,P```U$```'Q`@`&(````Q!P`!,W```#,````S(``
+M`-1```!\0(`!B````'Q`P`$DT``&,1``!L04``^9```(S```$L0D`'Z60``X
+MF4``!,0<``3-P```S````,R```#,P```U$```'Q`@`&(````?$#``7Q!``$5
+M&``?S0``(5$4`""9@``#U$T``(````!]34`:&1P`,=16``"5P/R5Q"``$YH`
+M__]\0(`!B````'Q`P`%\00`!%-0`'C%8``(DW`#_E4``!)F`_(K-'`,`@```
+M`,R```#,P```S0```'Q`@`&(````Q"``)'Q`P`'$TP,`S(```,S```#,```A
+MS2$A07Q`@`&(````U$``?WQ`@`&(````Q"0`?I9```-\0(`!B````(```XX`
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P-(``4!7P`&`.P`!P#S``@!`0`)`0@`$`.'`!$`"P`2`"<`$P`K`!8`
+M+@`D`#<`)0!Q`"8!&0`7`8$`(@+H`",#%0`G`3,`'P&S`"`!XP`H`5(`*@%"
+M`"P`4``O`4P`,0.'`#(!>0`S`X<`-`-/`#4!(``X`)(`-P&/`#P#*``_`6$`
+M0`)5`$$"F`!"`KP`0P+$`$0"U`!*`MX`50-+`%\`WP!@`+L`80#6`&D`[P!S
+M`/8`=@$$`'<!"P![`V``?0-P`'X#?@!_`X<````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_rlc.bin.uu
new file mode 100644
index 0000000..5177d91
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_rlc.bin.uu
@@ -0,0 +1,186 @@
+begin 644 TAHITI_rlc.bin
+MQ`@`)S",``*8P`-[,(P``9C``6LPC``#F,``2X```R+$)P!AQ`TQ"230``&9
+M```*Q`\`7<01,2(5$``0)1#__\07`%7-03$A?5$`#GS1``J9```FQ`\`:03,
+M``',PP!IQ!$PPQ40``0E$``/?-#`#Y3``![,`P!IQ"TQ"\`*B``FT`#_P!0`
+M`8P``JI\&H`*P`J(0!;L``@FT`#_P!0``8P``JH1F``(?IJ`"L`*B0`6[``(
+M)M``_\`4``&,``*J$9@`$'Z:@`K`"HE`%NP`"";0`/_`%``!C``"JA&8`!A^
+MFH`*?H)`"I````#$"P!G)*``#Q2(``1_H@`0?*R`$'X(@`Z8@`%GP`@Q(,`0
+M``O-"0``Q`L`:"2@``\4B``$?^(`$'RL@!!^2(`.F(`!7<`(,2#`$``,S0D`
+M`,`(``"```&I@```4<`,`/_`"H@`?<D`"L45```55``0?4%`'GU.@`G`"HA`
+M?<D`"L45```55``0?4%`'GU-0`D15``(?I:`"L`*B0!]R0`*Q14``!54`!!]
+M04`>?4U`"1%4`!A^EH`*P`J)0'W)``K%%0``%50`$'U!0!Y]34`)$50`&'Z6
+M@`I^@H`>Q!<``GZ6@`F0````Q!<`8`E4``=^T0`0?14`!'R10`^0````P!@`
+M`<P#``[`#?__S,,`'LS#`&'`"`4`*`P``,R/`$'`"B`@*(@/!03,``',CP!!
+MP`HP,"B('@\$S``!S(\`0<`*0$`HB"@>!,P``<R/`$'`"D!`*(@R*`3,``',
+MCP!!P`I@8"B(/#($S``!S(\`0<`*<'`HB%`\!,P``<R/`$'`"H"`*(A:4`3,
+M``',CP!!P`J`@"B(7UH$S``!S(\`0<`*@(`HB&1?!,P``<R/`$'`"H"`*(AI
+M9`3,``',CP!!P`J`@"B(;FD$S``!S(\`0<`*@(`HB'-N!,P``<R/`$'`"L#`
+M*(AX<P3,``',CP!!P`K`P"B(?7@$S``!S(\`0<`*__\HB(!]!,P``<R/`$'`
+M"`"`S(,`7L`(`__,@``PS`,`5<P#`%W,`P!?S`,`:<P#`&+,`P!ES`,`8\P#
+M`&;,`P!DS`,`9\P#`&B0````Q`@`$Y2`___,```"Q`@`#\00``.9`/__P"PQ
+M'L;M``#`)```C```_B@X``",``)9*#@``8P``BTH#```C``"#,V``!"0````
+MP!Z(`(P``D-\%(`*?!:`"HP``P-\#L`*P!Z(0(P``D-\%(`*$50`"'Z6@`J,
+M``,#?L[``<`>B0",``)#?!2`"A%4`!!^EH`*C``#`W[.P`'`'HE`C``"0WP4
+M@`H15``8?I:`"HP``P-^SL`!SH,`6I````"6P`"I*NP``<[``#"60`"BQ"``
+M')8``*#,```PD````"@,``&,``(,*#@``8P``EDH.```C``"+9>``?_`.#$!
+MQ[D``!>X`!`GK`?_EL```\`D``",``#^S8```L00``.5`/__S```$,`X``&0
+M````P!PPT,V=``#`'##.Q=T``'W5P`)]T<`/E<``-WT"P`J0````Q"L``HP`
+M`N7`#H``?X^`"L`.@`!_3T`**#P`H!/\`!`K_`#_C``"7,`<,07%[0``$NP`
+M&";L`/_`)```C```_LP``!*0````D````"?0`/\Q$`#_F0#__<`4,1?/U0``
+MD````"@X``",``)9*#@``8P``BTH#```C``"#,P``"V```0RP`J,`,`,)%!\
+MR,`*Q-$``,`*C0#`#"10?,C`"L35``!]%0`*)1`#@'T!0`V0````EL#_TG[!
+M``K`'##0S9T``,`<,,[%U0``%2P`!);`_\.,``#^E@#_P9````#,```MS8``
+M#LP#``#`,#!)QPD``,`R`!!\L<`)E<`"T,`P,0''"0``))P``97``NT4K``(
+M)NP`_\`D``'`(```C``!4)8``8G-@P``@``$,HP``'O,```.Q`@`-\0(`#.4
+M@``#S8``#HP``DC$"``JE(```\V```Z,``,8Q`@`*Y2```+-@``.Q`@`*)2`
+M__+-@``.C``!N(P``ZV```%PQ`@`')2``J[-@P``@``$2":H`/\4Y``$$F0`
+M""3<``]^7,`*S,``(\Z```R```0RQ`@`$)2`__/$"``1E(#_\<0H``"6@`$2
+MS8``#B@(``'$#``@S(```#*(`;N4@`!NS`,``(```5O$'P!@"=P`!R@@`!":
+M``'W*!0`0(```ZS$'``SE<#_7<P``##`(```D````,`(``',@P!BSP,`9<]#
+M`&//@P!FS\,`9!.@``1^+@`*S@,`9Q/@``1^+@`*S@,`:(P``FK.0P!AP!@`
+M`9````",``#AC``#3,`(,2#,"0``?[R`"GPLP`K$$3$B)1#__WR0@`Z4@/Z.
+MP`@Q(,`0``'-"0``P`@Q'\2E``#`"``@?+"`$"90`/^,``!UF4#_W<`(,2#`
+M$``"S0D``,`(``A\M(`0%E``""40`/^,``!UF4#_U,`(,2#`$``#S0D``,`(
+M`4!\N(`0%E``$"40`/^,``!UF4#_R\`(,2#`$``$S0D``,`(`4!\O(`0%E``
+M&"40`/^,``!UF4#_PL`(,2#`$``%S0D``,0+`&*4@/Y0P`@Q(,`0``;-"0``
+MQ`L`8WRX@`Z8@/^WP`@Q(,`0``?-"0``Q`L`9'R\@`Z8@/^QP`@Q(,`0``C-
+M"0``Q`L`97\(@`Z8@/^KP`@Q(,`0``G-"0``Q`L`9G](@`Z8@/^EP`@Q(,`0
+M``K-"0``@```3S*(`;R4@/]^S`,``(``!$C`,`.0QSD``,`+__Y_BX`)$,P`
+M$'^/@`K/L0``QSD``)````#`$```P`J)0'R,@`K$D0``)1``_Q$0``C`"HD`
+M?(R`"L25```E5`#_?14`"A$0``C`"HA`?(R`"L25```E5`#_?14`"A$0``C`
+M"H@`?(R`"L25```E5`#_?14`"I````#`,"`#S[$``,<Y``"0````P`J<`"B(
+M)-3`#``!S,D``,`*C``HB"36Q(T``"30__\4S``0?-$``<`*C0`HB"36Q(T`
+M`"34__\4S``0?-5``7T5``&0````C``"URG,)-7$S0``?4U`"9````#`"#$)
+MQ(T``"30``&9```-)-``_L07`%\%5``!S4,`7WU10`^50``'C``",<0+`%5]
+M"(`.S(,`7<T#`%7,`P!?D````,`P,'C/L0``D````(P``W3`%#$5SY4``,`4
+M,1;/50``P!0Q&,\5``#`$#$=Q1$``"40``&9`/[0P!0Q%\_5``"0````S(,`
+M)92`_9W`'H@`C``"UR:,`/]\U,`+P!0``<`*B`",``*3?!I`"L`>B$",``+7
+M%J@`"":,`/]\U,`+P!0``<`*B$",``*3$9@`"'Y:0`K`'HD`C``"UQ:H``@F
+MC`#_?-3`"\`4``'`"HD`C``"DQ&8`!!^6D`*P!Z)0(P``M<6J``()HP`_WS4
+MP`O`%``!P`J)0(P``I,1F``8?EI`"I````#`&"35?8F`"L69```H'```*!``
+M`,`@``B50``,),@``92```5\D(`$?8F`"@E4``$%W``!"B```13,``$%$``!
+MF@#_]B68`/^0````Q"<``)9``$K,`P``@``!6\`8)-5]B8`*Q9D``'T!`!Y]
+MD,`)*!P``"@D``#`(``(E4``#"3(``&4@``%?*2`!'V)@`L)5``!!=P``0H@
+M``$4S``!!F0``9H`__8EF`#_D````,`()-?`#H@`?(S`"L35```E5`#_P`Z(
+M0'R,P`K$T0``)1``_Q$0``A]44`*P`Z)`'R,P`K$T0``)1``_Q$0`!!]44`*
+MP`Z)0'R,P`K$T0``)1``_Q$0`!A]44`*D````"G((F_$B0``*<PB<,3-``!\
+MC4`*?4%`'A54`!"0````S8``#L07`"690`"&C``!1)5``(2```-R)K@`_Q:<
+M``@EW`#_$=P`"'^?@`H6G``0)?0`_Q7<``@EW`#_$=P`"']?0`J0````Q"L`
+M#I:``4",``+?@``$,HP``0:7@``#Q`P`$)3``)O-@P``@``$,L`P,0''"0``
+M))P``I7``56,``-^E@`!4\V#``"```1(*`P``,`0``@DE``!"1```7S4P`$4
+MB``!F0#__)`````H.```C``"62@,``",``(,P#@``)`````H%``??)3`!23,
+M``&8P``#"50``9E`__R0````S`,`5<P#`%_`"##&Q(D``,`,,,7$S0``?,B`
+M`HP``Q'-0P!@D````,@)/3;(#3TWE,``L<@1/3C(%3TYR!T].L@A/3O()3TU
+M!*@`,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8R)8`/)5``*'(
+MT@`H?24``@E4``$$S``HF0#_^\B2`#@%$`!`?0K``<C6``3`'``$R.(`%,CF
+M`"3."@%,SFX!3`C,``0(B``$"NP`!`G<``&9P/_XS0H!8,P*`63-03U'@``#
+MU<`*G``HC".8P!``!\T-``#`"HP`*(PCF<3Q```HC".:Q/4``"B,(YO$^0``
+M*(PCG,3]``#`"HT`*(PCF<31``!],P`!*(PCFL31``!]-T`!*(PCF\31``!]
+M.X`!*(PCG,31``!]/\`!D````,`,)-7$$P`>C``#M\07`"690``'C``!1)5`
+M``7`#"35?@$`"LT#`!Z,``.WS`,`#I````"7@``$P!`Q&<4=``"9P/_^ET``
+M!,`0,1K%'0``F<#__I````"```-]Q`@`#Y2`___$*P`"C``"Y<`.@`!_CX`*
+MP`Z``']/0`HH/`"0$_P`$"O\`/^,``)<P!PQ!<7M```2[``8)NP`_\`D``'`
+M(```C```_LV``!*0````Q`P`')3`_V?-@P``@``$2,37```$S``!"B```2@8
+M`/]]E8`)?9&`$'V=@`1\F8`/E8#^`2@8_P!]E8`)%9@`"'V1@!!]G8`$?)F`
+M#IF`_?H55``0ED```A54``@H&`#_?95`"9````#$"P`>Q`\`87R-``R9```&
+MQ!$Q"WS0P`K,PP`>P!@``<V#``Z0````)10`_\`*B`!\C(`*Q*$``,U)```5
+M%``()50`_\`*B$!\C(`*Q)T``!'<``A]X@`*S4D``!44`!`E5`#_P`J)`'R,
+M@`K$G0``$=P`$'WB``K-20``%10`&"54`/_`"HE`?(R`"L2=```1W``8?>(`
+M"LU)``"0````!!@``<V```[-@``MC```S\P```+,```+S```(\`P,.(H+``#
+MSO$``,`(,0#$B0``)(P`!)C```;`/@#0*_P`_\`[___`-___C``"7"2,``B8
+MP``&P#X`L"O\`/_`.___P#?__XP``EPDC``0F,``!L`^`'`K_`#_P#O__\`W
+M__^,``)<S`,`",P#``;,`P`MS`,`+L0,`-<DX``!S@,`"23D``(R9``"SD,`
+M"LY#``?,`P``S`,`(LP#`"/,`P`=S`,`),P#`!S,`P`+P`P`_Q#,``@HS`#_
+MP`@`_Q"(`!!\R,`*P`@`_Q"(`!A\R,`*S,,``L`<(F^,``!2SH,`(GZ"P`K`
+M'")PC```4LZ#`"-^KH`*SH,``<`,,0S$S0``S,,`!<0/``+`$#$#S-$``,S#
+M``_,`P`-P!```,P3`!#,$P`4S!,`&`40``$Q#``$E,#_^\0-,0/$#``ZS```
+M+<0(``.8@/__S8``$,V``!',```2S```#L0(`#;$#``*E,``#,V```[`###J
+MQ,D``,`,,.G$R0``Q)4``,`0`BC-40``P!`"*<V1``#,```.Q"@``9:`_4W-
+M@``.*`@``<0,`"',@``!@``!A\V```[-@``MQ`@`$I2```*,``$CQ`@`$)B`
+M``*,``#/Q"<``)I`_.N```0R@``$,@``````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+"````
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_uvd.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_uvd.bin.uu
new file mode 100644
index 0000000..f9267f4
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TAHITI_uvd.bin.uu
@@ -0,0 +1,4885 @@
+begin 644 TAHITI_uvd.bin
+MN<48X</E,-8XI)FNU4#09_X@M4<QQ5'60P2<3:7_K1]>/1=KM,\,<<PY@MO(
+M+,UJ>:T\B```````5P,`!0```!0```%BG>0>8>H(\]]+MR/TG;T>2D<,J`#U
+MNZ7DB+4]VXH.CGAI44T5```!CWQ(XCF?ZF;JP7SFC;DQAT2V+8SD6[\PG>JP
+M;=8$C>&U![WV%@```3,TA:R18(0257X/K?B!TQ0[(V.M`:4-3]975?2,9UW3
+MBE'N7!<```':QR\H[&(X_$#*"(X8`K`_L(-/G*GF\L($8M`SHOZX[6;/T$T8
+M```!R.O__)`]W@6`-OY2&K<]?P$K@CIA;.*8(-92CGE(:O&B:3%=````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````,5)$-5)(.5),/5)`#0``-S_`&'0
+M_P!A$``!82\`!`"Q@`1@``````````````````````````````````````#%
+M"1#5"2#E"3#U"0`U````````````````````````````````````````````
+M````````````````````````R4D`T0D0V4D@Z4DP^4E`@$E0D$E@H$EPL$D`
+M-````````````````````````````````````````````````,D)$-D)(.D)
+M<-$),/D)0(<)4)<)8*<)<+<)`#4`````````````````````````````````
+M``````````````#-20#1"1#=22#M23#]24!`25!026!@27!P28"`29"02:"@
+M2;"P20`T````````````````````````````````S0D0W0D@[0FPT0DP_0E`
+M2PE06PE@:PEP>PF`BPF0FPF@JPFPNPD`-0``````````````````````````
+M````#```Y!,``!,``1,``A,``Q,`!!,`!1,0(```21,`2!,0(```:!,`@!,`
+M@1,`D!,`D1,`H!,`H1,P(```L1,`LA,`LQ,`PA,`PQ,`T1,`TA,`TQ,`Z!,`
+MZA,`\!,`\1,`\A,,\B#F$Q`@`$P"#`-V@@[2<P/2<T/2<X/2<\,RTP$`(``B
+MH$`RH`!V@@[R<P#R<Q#R<R#R<S`RTP$`(`!,`@P#=H(.@G,#@G-#@G.#@G/#
+M,M,!,"``(J`@,J``=H(.<G,`<G,0<G,@<G,P,M,!,"``#"5`50$,`PST0&-0
+M6C-`8U!:,T!C4%HS#$0&````0&-0`"``\"``\"``6C,,]$!C4%HS0&-06C-`
+M8U!:,T!C4``@``P##/1`XU!:,T#C4%HS0.-06C,,1$#C4%HS#"1`XU!:,PST
+M0.-06C,,)$#C4%HS#/1`XU`P(``\`B#C$P*@!`N`#``,`0P"#`,,!`P%#`8,
+M!R"`0%9P_@P1#``021,`2!,`(``0(``11?\A1?\Q1?\Y`C%%_S#F$Q`@`"!@
+M`"%#_R`%$R5\""T*,2P`*0,,$C$M`"D#AI3_````.1%)(5DQ:4%Y48EAF7&I
+M@;F1R:'9L>G!^=$@``,P`0,IX3GQ(`(#,`,#(F$0,F$1(.8#,+$#(F$2,F$3
+M;`,P(A`K(B#F$Q+1`1+!@!`@`!`1(!4%`!+!@#(A$2(A$#`#$R`"$SCQ*.$P
+M`1,@`!,B(1(R(1,@YA,PL1,0(`#XT>C!V+'(H;B1J(&8<8AA>%%H05@Q2"$X
+M$2@!$M$!$L&``#`````V`0$@80!`X@-0Y`,A+@!01!`@1!!61``@;P`=\##T
+M0!SR,#+``!-`02\`0$.PG&,,$@`BH2#C$R(D`&(D`19"_-`"`(;O_P`@\`,@
+M\!,H!&@4%@+[T`(`ANK_`#8A`##J`RHS,/`3'?`````V(0#VP@E1+P!0(K`Y
+M`DD2'?``````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````````8P````````
+M````````````````````````````````AE[_````````````````````````
+M```````````````0-````````````````````````````````````````!+!
+M@"D!(.@#9D("1E#_*`$2T0$2P8`&2?\`````````AD;_`#8A`$!O`##D`R`S
+M(##D$T#F$Q`@`!WP`#8A`$!O`##D`R`S("`S,##D$T#F$Q`@`!WP````````
+M`````(8V_P`@TA,A,``Y$DDB63)I0GE2B6*9<JF"N9+)HMFRZ<+YTC```T`!
+M`SGB2?(P`@-``P,R8A!"8A$0(`!`X@-0Y`,Q,0!01!`P1!`6!`HP]$`<]3`U
+MP``30"83?F8C`D8@``P5`%6A4.,3'/1'$P1&\O\``/$R`.$S`"QC.0\,`SD?
+M#`-"H&0,M5D/J!\7Z@<;,T<C\<;H_RPC.0^8'PRS.0\,(S"J(*D?,30`,#D0
+M.0XX#BPS.0^8'S$U`#`Y(#D..`X,`T$V`%@.834`8%40C#4;,T<C\$;8_P!0
+M\0-0\1/&U?]0\@-0\A.&T_\``#(B$4(B$#`#$T`"$SCR2.(P`1-``!,0(`#X
+MTNC"V++(HKB2J(*8<HAB>%)H0E@R2"(X$B#2`Q`R`````#8A`"#J`QWP-B$`
+M(/`3`"``'?``-B$`(/(3`"``'?``-B$`(/`#'?``````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````5P-@````````````````7K(`8%ZR`&#1L@!@7K(`8%ZR`&!>L@!@7K(`
+M8,JR`&!>L@!@RK(`8%ZR`&!>L@!@7K(`8%ZR`&!>L@!@7K(`8*S%`&#UQ@!@
+MK,4`8*S%`&"LQ0!@]<8`8%?'`&"LQ0!@K,4`8%?'`&"LQ0!@K,4`8*S%`&#"
+MQP!@K,<`8*S%`&"LQ0!@K,4`8*S%`&"LQ0!@S\8`8````````````````.SP
+M`&"[\`!@8_(`8"_R`&`/\@!@E_$`8$3Q`&``````"@X4&`X4&!L4&!L>&!L>
+M(@8-%!P-%!P@%!P@)1P@)2H``00(!0(#!@D,#0H'"PX/``$($`D"`PH1&"`9
+M$@L$!0P3&B$H,"DB&Q0-!@<.%1PC*C$X.3(K)!T6#Q<>)2PS.CLT+28?)RXU
+M/#TV+S<^/Y(B`6"2(@%@JB,!8(XC`6".(P%@Z1\!8.D?`6#I'P%@Z1\!8.D?
+M`6#I'P%@CB,!8'(C`6!6(P%@Z1\!8.D?`6#I'P%@Z1\!8.D?`6#I'P%@Z1\!
+M8%8C`6`Z(P%@'B,!8.D?`6#I'P%@Z1\!8.D?`6#I'P%@Z1\!8.D?`6`"(P%@
+M`B,!8.8B`6#I'P%@Z1\!8.D?`6#I'P%@Z1\!8.D?`6#I'P%@RB(!8*XB`6``
+M``````$"`P0%!@<("0H+#`T.#Q`1$A,4%187&!D:&QP='1X?("`A(B(C(R0D
+M)24E)B8F)R<G)P`````````````````````0````(`````\````?````+P``
+M````````````#P```0<""P0-"`X#`P4%"@H,#`\!!P(+!`T(#@8&"0D`````
+M````````````````````````````````````````````````````````````
+M````````````````````+P`?$`\!``(7!!L('2`>`P<%"PH-#`X/)R\K!RT+
+M+@T0#@,&!0D*'PPC$R45*AHL'"$C(B4D*B@L)P$K`BT$+@@1$1(2%!08&!,&
+M%0D:%AP9%R`;(1TB'B06*!DF)BDI`@$#`P0'!0\('P("`P8$#@4>!SX`````
+M````````````0(`!08$"0H(#0X,$1(0%184&1H8'1X<(2(@)28D*2HH+2XL,
+M3(P-38T.3HX/3X\04)`149$24I(34Y,45)0559465I875Y<86)@969D:6IH;
+M6YL<7)P=79T>7IX?7Y\@8*`A8:$B8J(C8Z,D9*0E9:4F9J8G9Z<H:*@I::DJ
+M:JH````````````````````?0!]!'T(?0Q];'UP?71]>@%6J0,`S9IG,*]<E
+M2F^4N=X@8*#@```````````````"`@(```(```$!`0,#`0,#'QL?'!\='QX?
+M)Q\H'RD?*A]$'T4?1A]'```````````?'Q\@'R$?(A\C'R0?)1\F'Q<?&!\9
+M'QH?#1\.'P\?$!\X'SD?.A\['SP?/1\^'S\?2!])'TH?2Q],'TT?3A]/'U\?
+M8!]A'V(?8Q]D'V4?9@T="045)C8R!`<7`R<W,P``"`$%"0T#"P``````````
+M@%6J0,`S9IG,*]<E2F^4N=X@8*#@````'A@9'C(\,$@($1(3%1<9&Q$2$Q47
+M&1L<%!46%Q@:'!X5%A<8&AP>(!87&!H<'B`C%Q@:'!X@(R89&AP>(",F*1L<
+M'B`C)BDM$!$2$Q05%A<1$A,4%187&!(3%!46%Q@9$Q05%A<8&AL4%187&1H;
+M'!46%Q@:&QP>%A<8&AL<'A\7&!D;'!X?(04`````````````````````````
+M`````(````!@````"`````8````!````L````)`````+````"0````(```!@
+M`0``(`$``!8````2`````P```,`"``!``@``6````!(````$````@`4``(`$
+M``!@`0``$@````4`````````````````````````!0``````````````````
+M```````````````````````!`````0````$````!`````0````$````!````
+M`0````$````!`````0````(````"````C',"8*%S`F#W=@)@[G8"8.5V`F#<
+M=@)@TW8"8``````#`````P````,````#````!`````0````$````!`````4`
+M`````````````````````````0````(````#``````````$````"`````P``
+M````````````````````````````!`````@````,````$````!0````8````
+M'````"`````D````*````"P````P````-````#@````\````______[___\!
+M`````@`````````````````````````!`````0````$````!`````@````(`
+M```"`````@````,````#`````P````,````$````!`````0````$````!0``
+M```````````````````````!`````@````,``````````0````(````#````
+M``````$````"`````P`````````!`````@````,``````````0````(````#
+M`````````````````````````#P````X````-````#`````L````*````"0`
+M```@````'````!@````4````$`````P````(````!`````````!SC0)@P8T"
+M8+2-`F"GC0)@FHT"8(V-`F"`C0)@``````,````#`````P````,````$````
+M!`````0````$````!0`````````````````````````!`````@````,`````
+M`````0````(````#`````````````````````````/_____^____`0````(`
+M````````!`````@````,````$````!0````8````'````"`````D````*```
+M`"P````P````-````#@````\``````````````````````````$````!````
+M`0````$````"`````@````(````"`````P````,````#`````P````0````$
+M````!`````0````%``````````````````````````$````"`````P``````
+M```!`````@````,``````````0````(````#``````````$````"`````P``
+M```````!`````@````,`````````````````````````/````#@````T````
+M,````"P````H````)````"`````<````&````!0````0````#`````@````$
+M``````````';`F`WVP)@+ML"8"7;`F`<VP)@$]L"8`K;`F``````0``&`$4`
+M``!&````O@`"`,(`!@#D`08`,`$``#`!```P`@8`Q@(&`"@#!@"(`P8`"`,`
+M``@#```(`P``"`,```D#```)`P``0@4&`+@%!@#V`P``]@,``/8#``#V`P``
+M]P,``/<#``"F!@8`200``$H$``!*!```2@0``$H$``!+!```2P0``$L$``!+
+M!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$
+M``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0``$L$``!+!```2P0`
+M`$L$``!+!```2P0``$L$``!+!```2P0`````````````````````````````
+M```````````````````````````````````````````````````````````!
+M`````@```$```P`(````2``#`%```@`3````$P```!0````4````%````!0`
+M```4````%````!0````4````%0```!4````5````%0```!4````5````%0``
+M`!4````5````%0```!4````5````%0```!4````5````%0```%0``@!8``(`
+M'````!P````=````'@```!\````@````(0```"$````A````(0```%P``0`D
+M````)0```%X`!0`#`````P````,````#````!`````4````&````!P````D`
+M```*````"P````P````-````#0````X````.````#P```!`````1````$@``
+M`!8````6````%P```!@````9````&@```!L````;````(@```",````F````
+M)@```"<````H````*0```"H````K````+````"T````N````+P```#`````Q
+M````,@```#,````T````-0```#8````W````.````#D````Z````.P```#P`
+M```]````/@```#\```!`````00```$(```!#````1````$<```!'````2```
+M`$D```!```4`8``%`(``!0"@``4`P``$`-``!`#@``0`\``#`/@``@#Y````
+M^@```/H```#[````^P```/L```#[````_````/P```#\````_````/P```#\
+M````_````/P```#]````_0```/T```#]````_0```/T```#]````_0```/X`
+M``#^````_``!`/X``@`"`0$`!`$!``@!```&`00`$@$``!(!```2`0``$@$`
+M`!(!```2`0``$@$``!(!```3`0``$P$``!,!```3`0``%@$#`!X!`@`>`0``
+M'@$``!\!```?`0``'P$``!\!```?`0``'P$``!\!```?`0``2@```$L```!,
+M````30```$X```!/````4````%$```!2````4P```%0```!5````5@```%<`
+M``!8````60```%H```!;````7````%T```!>````7P```&````!A````8@``
+M`&,```!D````90```&8```!G````:````&D```!J````:P```&P```!M````
+M;@```&\```!P````<0```'(```!S````=````'4```!V````=P```'@```!Y
+M````>@```'L```!\````?0```'X```!_````@````($```""````@P```(0`
+M``"%````A@```(<```"(````B0```(H```"+````C````(T```".````CP``
+M`)````"1````D@```),```"4````E0```)8```"7````F````)D```":````
+MFP```)P```"=````G@```)\```"@````H0```*(```"C````I````*4```"F
+M````IP```*@```"I````J@```*L```"L````K0```*X```"O````L````+$`
+M``"R````LP```+0```"U````M@```+<```"X````N0```+H```"[````O```
+M`+T```"^````OP```,````#!````P@```,,```#$````Q````,4```#%````
+MQ@```,8```#'````R````,D```#*````RP```,P```#-````S@```,\```#0
+M````T0```-(```#3````U````-4```#6````UP```-@```#9````V@```-L`
+M``#<````W0```-X```#?````X````.$```#B````XP```.0```#E````Y@``
+M`.<```#H````Z0```.D```#J````Z@```.L```#K````[````.P```#M````
+M[0```.X```#N````[P```.\```#P````\0```/(```#S````]````/0```#U
+M````]0```/8```#W````^````/@```#_``````$```$!```"`0```P$```,!
+M```$`0``!0$```8!```'`0``"0$```H!```+`0``"P$```P!```,`0``#0$`
+M``T!```.`0``#@$```\!```/`0``$`$``!`!```1`0``$0$``!0!```5`0``
+M%@$``!<!```8`0``&0$``!H!```:`0``&P$``!P!```=`0``'0$``"`!```@
+M`0``(`$``"`!```@`0``(`$``"`!```@`0``(`$``"`!```@`0``(`$``"`!
+M```@`0``(`$``"`!```A`0``(0$``"$!```A`0``(@$``"(!```C`0``0``"
+M`"<!```G`0``)P$``"<!``!$``(`2``"`"X!```N`0``+P$``"\!```O`0``
+M+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O
+M`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!```O`0``+P$``"\!
+M```O`0``+P$``"\!```O`0``+P$``"\!```D`0``)0$``"8!```F`0``*`$`
+M`"@!```I`0``*@$``"L!```L`0``+0$``"T!```Q`0``,0$``#$!```Q`0``
+M,0$``#$!```Q`0``,0$``#$!```Q`0``,0$``#$!```Q`0``,0$``#$!```Q
+M`0``,@$``#(!```R`0``,@$``#(!```R`0``,@$``#(!```S`0``,P$``#0!
+M``!```0`/@$``#X!```_`0``4``$`%`!``!0`0``4`$``%`!``!0`0``4`$`
+M`%`!``!0`0``4`$``%`!``!0`0``4`$``%`!``!0`0``4`$``%`!``!1`0``
+M40$``%$!``!1`0``8``$`'``!`"```,`B``#`'P!``!\`0``?0$``)```0"`
+M`0``@`$``($!``"2``(`-0$``#4!```U`0``-0$``#4!```U`0``-0$``#4!
+M```V`0``-P$``#@!```Y`0``.@$``#L!```\`0``/0$``$`!``!!`0``0@$`
+M`$,!``!$`0``10$``$8!``!'`0``2`$``$D!``!*`0``2P$``$P!``!-`0``
+M3@$``$\!``!2`0``4P$``%0!``!5`0``5@$``%<!``!8`0``60$``%H!``!;
+M`0``7`$``%T!``!>`0``7P$``&`!``!A`0``8@$``&,!``!D`0``90$``&8!
+M``!G`0``:`$``&D!``!J`0``:@$``&L!``!K`0``;`$``&P!``!M`0``;0$`
+M`&X!``!O`0``<`$``'$!``!R`0``<P$``'0!``!U`0``=@$``'<!``!X`0``
+M>0$``'H!``!Z`0``>P$``'L!``!^`0``?P$``((!``""`0``@P$``(0!``"%
+M`0``A0$``(4!``"%`0``A0$``(4!``"%`0``A0$``(8!``"&`0``A@$``(8!
+M``"&`0``A@$``(8!``"&`0``AP$``(<!``"'`0``AP$``(<!``"'`0``AP$`
+M`(<!``"'`0``AP$``(<!``"'`0``AP$``(<!``"'`0``AP$``(@!``"(`0``
+MB`$``(@!``!```$`0@`%`)$!``"1`0``D@$``)(!``"2`0``D@$``),!``"3
+M`0``DP$``),!``"4`0``E`$``)0!``"4`0``E`$``)0!``"4`0``E`$``)0!
+M``"4`0``E`$``)0!``"4`0``E`$``)0!``"4`0``B0$``(H!``"+`0``BP$`
+M`(L!``"+`0``BP$``(L!``"+`0``BP$``(L!``"+`0``BP$``(L!``"+`0``
+MBP$``(L!``"+`0``C`$``(P!``",`0``C`$``(P!``",`0``C`$``(P!``"-
+M`0``C0$``(X!``"/`0``D`$``)`!``"0`0``D`$``)4!``"5`0``E0$``)4!
+M``"5`0``E0$``)4!``"5`0``E@$``)8!``!```,`2``#`%```P!8``,`L@$`
+M`+,!``"T`0``M`$``+0!``"T`0``M`$``+0!``"T`0``M`$``+0!``"T`0``
+MM`$``+0!``"T`0``M`$``+0!``"T`0``M0$``+4!``"U`0``M0$``+4!``"U
+M`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!
+M``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$``+4!``"U`0``M0$`
+M`+4!``"U`0``M0$``+4!``"7`0``EP$``)<!``"7`0``F`$``)D!``":`0``
+MFP$``)P!``"=`0``G@$``)\!``"@`0``H0$``*(!``"C`0``I`$``*4!``"F
+M`0``IP$``*@!``"I`0``J@$``*L!``"L`0``K0$``*X!``"O`0``L`$``+`!
+M``"Q`0``L0$``+8!``"V`0``0``"`$0``0"]`0``O0$``+T!``"]`0``O@$`
+M`+X!``"^`0``O@$``$8``@!*``(`3@`"`,D!``#*`0``R@$``,H!``#*`0``
+MR@$``,H!``#*`0``R@$``,H!``#*`0``R@$``,H!``#*`0``R@$``,H!``#*
+M`0``RP$``,L!``#+`0``RP$``,L!``#+`0``RP$``,L!``#,`0``S`$``,T!
+M``#-`0``4@`%`'(`!0#I`0``Z0$``.H!``#J`0``D@`%`+(`!0#2``4`\@`%
+M`!(!!0`R`04`4@$%`'(!!`""`00`D@$$`*(!`P"J`0,`L@$"`+8!`@"W`0``
+MN`$``+D!``"Z`0``NP$``+P!``"_`0``OP$``,`!``#!`0``P@$``,,!``#$
+M`0``Q0$``,8!``#'`0``R`$``,@!``#.`0``S@$``,X!``#.`0``S@$``,X!
+M``#.`0``S@$``,\!``#0`0``T0$``-(!``#3`0``U`$``-4!``#6`0``UP$`
+M`-<!``#7`0``UP$``-<!``#7`0``UP$``-<!``#7`0``UP$``-<!``#7`0``
+MUP$``-<!``#7`0``UP$``-@!``#8`0``V`$``-@!``#8`0``V`$``-@!``#8
+M`0``V`$``-@!``#8`0``V`$``-@!``#8`0``V`$``-@!``#9`0``V@$``-L!
+M``#<`0``W0$``-X!``#?`0``X`$``.$!``#B`0``XP$``.0!``#E`0``Y@$`
+M`.<!``#H`0``ZP$``.P!``#M`0``[@$``.\!``#P`0``\0$``/(!``#S`0``
+M]`$``/4!``#V`0``]P$``/@!``#Y`0``^@$``/L!``#\`0``_0$``/X!``#_
+M`0````(```$"```"`@```P(```0"```%`@``!@(```<"```(`@``"0(```H"
+M```+`@``#`(```T"```.`@``#P(``!`"```1`@``$@(``!,"```4`@``%0(`
+M`!8"```7`@``&`(``!D"```:`@``&P(``!P"```=`@``'@(``!\"```@`@``
+M(0(``"("```C`@``)`(``"4"```F`@``)P(``"@"```I`@``*@(``"L"```L
+M`@``+0(``"X"```O`@``,`(``#$"```R`@``,P(``#0"```U`@``-@(``#<"
+M```X`@``.0(``#H"```[`@``/`(``#T"```^`@``/P(``$`"``!!`@``0@(`
+M`$,"``!$`@``10(``$8"``!'`@``2`(``$D"``!*`@``2P(``$P"``!-`@``
+M3@(``$\"``!0`@``40(``%("``!3`@``5`(``%4"``!6`@``5P(``%@"``!9
+M`@``6@(``%L"``!<`@``70(``%X"``!?`@``8`(``&$"``!B`@``8P(``&0"
+M``!E`@``9@(``&<"``!H`@``:0(``&H"``!K`@``;`(``&T"``!N`@``;P(`
+M`'`"``!Q`@``<@(``',"``!T`@``=0(``'8"``!W`@``>`(``'D"``!Z`@``
+M>P(``'P"``!]`@``?@(``'\"``"``@``@0(``(("``"#`@``A`(``(4"``"&
+M`@``AP(``(@"``")`@``B@(``(L"``",`@``C0(``(X"``"/`@``D`(``)$"
+M``"2`@``DP(``)0"``"5`@``E@(``)<"``"8`@``F0(``)H"``";`@``G`(`
+M`)T"``">`@``GP(``*`"``"A`@``H@(``*,"``"D`@``I0(``*8"``"G`@``
+MJ`(``*D"``"J`@``JP(``*P"``"M`@``K@(``*\"``"P`@``L0(``+("``"S
+M`@``M`(``+4"``"V`@``MP(``+@"``"Y`@``N@(``+L"``"[`@``O`(``+P"
+M``"]`@``O0(``+X"``"^`@``OP(``+\"``#``@``P`(``,$"``#!`@``P@(`
+M`,("``##`@``Q`(``,4"``#&`@``QP(``,@"``#)`@``R@(``,L"``#,`@``
+MS0(``,X"``#/`@``T`(``-$"``#2`@``TP(``-0"``#5`@``U@(``-<"``#8
+M`@``V0(``-H"``#;`@``W`(``-T"``#>`@``WP(``.`"``#A`@``X@(``.,"
+M``#D`@``Y0(``.8"``#G`@``Z`(``.D"``#J`@``ZP(``.P"``#M`@``[@(`
+M`.\"``#O`@``\`(``/`"``#Q`@``\@(``/,"``#T`@``]0(``/8"``#W`@``
+M^`(``/D"``#Z`@``^P(``/P"``#]`@``_@(``/\"``#_`@````,```$#```"
+M`P```P,```0#```%`P``!@,```<#```*`P``"@,```H#```*`P``"P,```L#
+M```+`P``"P,```P#```,`P``#`,```P#```,`P``#`,```P#```,`P``0``!
+M``\#```0`P``$`,``!$#``!"``(`%@,``!8#```7`P``%P,``!<#```7`P``
+M1@`"`$H``@!.``$`(0,``"(#``!0``$`4@`!`"<#```H`P``*`,``"D#```J
+M`P``5``#`%P``P!D``,`;``"`'```@!)`P``2@,``'0``0!-`P``30,``$T#
+M``!-`P``30,``$T#``!-`P``30,``$T#``!-`P``30,``$T#``!-`P``30,`
+M`$T#``!-`P``#0,```X#```2`P``$P,``!0#```5`P``&`,``!D#```:`P``
+M&P,``!P#```=`P``'@,``!X#```?`P``(`,``",#```D`P``)0,``"8#```K
+M`P``+`,``"T#```N`P``+P,``#`#```Q`P``,@,``#,#```T`P``-0,``#8#
+M```W`P``.`,``#D#```Z`P``.P,``#P#```]`P``/@,``#\#``!``P``00,`
+M`$$#``!"`P``0P,``$0#``!%`P``1@,``$<#``!(`P``2`,``$L#``!,`P``
+M3@,``$```0!1`P``40,``%(#``!"``0`60,``%(``0!<`P``70,``%X#``!>
+M`P``7P,``%\#``!?`P``7P,``&`#``!@`P``8`,``&`#``!@`P``8`,``&`#
+M``!@`P``8`,``&`#``!@`P``8`,``&`#``!@`P``8`,``&`#``!A`P``80,`
+M`%0`!`!D``0`>P,``'L#``![`P``>P,``'0`!`"$``0`E``$`*0`!`"T``0`
+MQ``#`,P``P#4``,`W``"`.```@#D``(`Z``"`.P``0#R`P``\P,``/0#``#U
+M`P``]0,``/4#``#U`P``]0,``/4#``#U`P``]0,``$\#``!0`P``4P,``%,#
+M``!4`P``50,``%8#``!6`P``5@,``%8#``!7`P``5P,``%<#``!7`P``6`,`
+M`%@#``!8`P``6`,``%H#``!;`P``8@,``&(#``!B`P``8@,``&(#``!B`P``
+M8@,``&(#``!C`P``9`,``&4#``!F`P``9P,``&@#``!I`P``:@,``&L#``!L
+M`P``;0,``&X#``!O`P``<`,``'$#``!R`P``<P,``'0#``!U`P``=@,``'<#
+M``!X`P``>0,``'H#``!\`P``?0,``'X#``!_`P``@`,``($#``""`P``@P,`
+M`(0#``"%`P``A@,``(<#``"(`P``B0,``(H#``"+`P``C`,``(T#``".`P``
+MCP,``)`#``"1`P``D@,``),#``"4`P``E0,``)8#``"7`P``F`,``)D#``":
+M`P``FP,``)P#``"=`P``G@,``)\#``"@`P``H0,``*(#``"C`P``I`,``*4#
+M``"F`P``IP,``*@#``"I`P``J@,``*L#``"L`P``K0,``*X#``"O`P``L`,`
+M`+$#``"R`P``LP,``+0#``"U`P``M@,``+<#``"X`P``N0,``+H#``"[`P``
+MO`,``+T#``"^`P``OP,``,`#``#!`P``P@,``,,#``#$`P``Q0,``,8#``#'
+M`P``R`,``,@#``#)`P``R0,``,H#``#+`P``S`,``,T#``#.`P``SP,``-`#
+M``#1`P``T@,``-,#``#4`P``U0,``-8#``#7`P``V`,``-D#``#:`P``VP,`
+M`-P#``#=`P``W@,``-\#``#@`P``X`,``.$#``#B`P``XP,``.0#``#E`P``
+MY@,``.<#``#H`P``Z0,``.H#``#K`P``[`,``.T#``#N`P``[P,``.\#``#P
+M`P``\0,``/@#``!```(`_`,``/T#``#^`P``_@,``/X#``#^`P``_P,````$
+M``!$``(`2``"`$P``0`*!```"P0```P$```-!```#00```T$```-!```#@0`
+M``X$```.!```#@0```\$```/!```#P0```\$```0!```$`0``!`$```0!```
+M3@`$`%X``0`8!```&00``!H$```:!```&P0``!L$``!@``,`(00``"($```B
+M!```:``#`'```P!X``,`@``"`#T$```^!```/P0``#\$``!`!```000``(0`
+M`@"(``$`1P0``$<$``!'!```1P0``$@$``!(!```2`0``$@$``#Y`P``^0,`
+M`/H#``#[`P```00```($```#!```!`0```4$```&!```!P0```<$```(!```
+M"00``!$$```1!```$00``!$$```2!```$P0``!0$```4!```%00``!4$```5
+M!```%00``!4$```5!```%00``!4$```6!```%P0``!P$```<!```'`0``!P$
+M```=!```'@0``!\$```@!```(P0``"0$```E!```)@0``"<$```H!```*00`
+M`"H$```K!```+`0``"T$```N!```+P0``#`$```Q!```,@0``#,$```T!```
+M-00``#8$```W!```.`0``#D$```Y!```.@0``#L$```\!```/`0``$($``!#
+M!```1`0``$0$``!%!```1@0``("``@#_!P8`!O\&`/@``0#W_@,``O0#``'V
+M`P#U_0,`_`(&``'X`P`1``,`^PD#``#B`P`(`0(``@<"``7Y`@#]^@(`!OP"
+M``O_`@`%`04`_P,#```#`@#Y_0$`^OP"```*`@`!]P(`"O\"``,$`0#[_P4`
+M!/X&`/4`!@#W``8`"P`&``0`!``'_0$`!OX!``0"!@`"!`8`\_X$`/0&!0`)
+M"04`^@P%``D5!0`*ZP4`"O0%``KY!0#Z#04`^@X%`/H/!0#Z$`4`X0<%`/H4
+M!0`%#@4`!1$%``4?!0#W%P4``@P%``H&!0#[[04`"^T%``(9!0#[]@4`_Q,%
+M`/CP!0`![`4`\/P%`.,#!0#_&04`^/D%`/\!!@`!`08``@`!`/\"`@`"_P(`
+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
+M"OT#``/U`P`#]@,`]P4#```,`P`#"P,`"_D#```/`P#G`0,`_PT#``G[`P#T
+M_P,`_QH#`/#_`P#M``,`'_\#`/D&`P#^"P,``1T"`/\+`@`)_0(``O<"``?\
+M`@`/``(`"/P"`!H``@`;_P(`"0("``'E`@#C`0(`\0`"`!T!`@`*`0(`]?\!
+M`/H#`0`#^@$`_00&`/K_!@`!!@8`_OX#`/\`!``!_P4`!?X&`/_W`0#^"@(`
+M^@4"``'Z!@#[`P8`_P0$`/L"!@`#!08`_?<"``0&`@`=_P(``0@"``7Z`@`>
+M``(``P8!`!D``0#_"0$``OH&``+Y!@`(``8``P,$`/T"!```^00`_?X$`/SZ
+M`@`&\@0`]PD$``#T`P#]_`$`_?D!`/P%`0`*``8``0<&``#Z!0#_^04`_@@!
+M``,/`P#^#0,`_A8#`/_A`P``]P8``?D%``KZ`P`/`@,`!P8#``;N`P`(]@,`
+M"/@#`!,!`P`7`@,`&``#`/(``P#U!0,`!_4#``?W`P`!$0,`\0,#``GW`P#W
+M_`,`^`<#``L'`P#Y]P,`_Q<#`/0!`P#Y!0(`!@8"`/D$`@#[!0$`_04&`.0`
+M!@`'`04`Y0`&`/S]!@`&^`(`\?T"``,'`0#B``$`!@0!`/[]!`#]`P0```(&
+M```!!`````$`````````````````````````````````````````````````
+M`````````````````````````````````````$``!@!-````R``&`"X!!@">
+M````G@```(X!!@#N`08`,@(&`)("!@#L`@8`1`,&`&X!``!N`0``;@$``&X!
+M``"F`P8`&@0&`.L!``#K`0``[`$``.P!``#L`0``[`$``'P$!@#L!`8`7@4&
+M`,8%!@#C`@``XP(``.,"``#C`@``)`8&`#0#``"D!@8`$`<&`*<#``"G`P``
+M?@<&`,X'!@`'!```!P0``#X(!@!^"`8`2P0``$L$``!+!```2P0``$```P!(
+M``,`4``"`%0``@!8``$`6@`#`!X````>````8@`!`"$````B````(@```",`
+M```C````(P```",````D````)````"0````D````)````"0````D````)```
+M`"0````D````)````"0````D````)````"0````D````9``"`&@``@!L``$`
+M+P```#`````P````,````#`````Q````,@```#,````T````-0```#4````U
+M````-0```&X``P!V``$`/````#T````^````/@```'@``P"```,`3````$P`
+M``!,````3````$P```!,````3````$P````!`````@````,````$````!0``
+M``8````'````"`````D````*````"P````P````-````#@````\````/````
+M$````!$````2````$P```!0````5````%@```!<````8````&0```!H````:
+M````&@```!H````;````&P```!P````=````'P```"`````E````)@```"<`
+M```H````*0```"H````K````+````"T````N````-@```#8````W````.```
+M`#D````Y````.0```#D````Z````.P```#\````_````/P```#\```!`````
+M00```$(```!#````1````$4```!&````1P```$@```!)````2@```$L```!.
+M````3@```$X```!.````3@```$X```!.````3@```$\```!/````3P```$\`
+M``!```,`2``#`%```P!8``(`7``"`&```0!P````<````'$```!Q````<@``
+M`&(``0!U````=0```'8```!D``$`>0```'D```!Y````>0```'H```!Z````
+M>@```'H```!Z````>@```'H```!Z````>@```'H```!Z````>@```'H```!Z
+M````>@```'H```!Z````>@```'H```!Z````>@```'H```!Z````>@```'H`
+M``!Z````>@```'H```!Z````>@```'H```!Z````4````%$```!2````4P``
+M`%0```!5````5@```%<```!8````60```%H```!;````7````%T```!>````
+M7P```&````!A````8@```&,```!D````9````&4```!E````9@```&<```!H
+M````:0```&H```!K````;````&T```!N````;P```',```!T````=P```'@`
+M``![````>P```'L```![````>P```'L```![````>P```'L```![````>P``
+M`'L```![````>P```'L```![````?````'P```!\````?````$```P""````
+M2``"`$P``@!0``(`5``!`%8``0"2````6``!`%H``0!<``$`7@`!`)L```";
+M````FP```)L```";````FP```)L```";````FP```)L```";````FP```)L`
+M``";````FP```)L```"<````G````)P```"<````G````)P```"<````G```
+M`)T```"=````G0```)T```"=````G0```)T```"=````?0```'T```!^````
+M?P```(````"`````@0```($```"#````A````(4```"&````AP```(@```")
+M````B@```(L```",````C0```(T```".````CP```)````"1````DP```)0`
+M``"5````E@```)<```"8````F0```)H```!```(`H@```*,```!$``(`J```
+M`*@```"H````J````$@``@!,``(`4``"`+0```"U````M@```+<```"W````
+MN````+@```"X````N````+D```"Y````5``!`%8``0"^````OP```,````!8
+M``(`Q````,0```#%````7``"`,H```#*````R@```,H```#*````R@```,H`
+M``#*````R@```,H```#*````R@```,H```#*````R@```,H```#*````R@``
+M`,H```#*````R@```,H```#*````R@```,H```#*````R@```,H```#*````
+MR@```,H```#*````GP```)\```"@````H0```*0```"E````I@```*<```"I
+M````J@```*L```"L````K0```*X```"O````L````+$```"R````LP```+,`
+M``"Z````NP```+P```"]````P0```,$```#"````PP```,8```#'````R```
+M`,D```#+````RP```,L```#+````RP```,L```#+````RP```,L```#+````
+MRP```,L```#+````RP```,L```#+````S````,P```#,````S````,P```#,
+M````S````,P```#-````S0```,T```#-````0``"`-$```#2````T@```-,`
+M``#3````TP```-,```#3````TP```-,```#3````TP```-,```#3````TP``
+M`-,```#3````TP```-,```#3````TP```-,```#3````TP```-,```#3````
+MTP```-,```#3````TP```-,```#3````TP```-,```#3````S@```,\```#0
+M````T````-0```#4````U````-0```#4````U````-0```#4````U````-0`
+M``#4````U````-0```#4````U````-0```#5````U0```-4```#5````0``"
+M`$0``0!&``$`2``!`$H``0#A````X@```.(```!,``(`4``"`%0``@!8``(`
+M\@```/(```#R````\@```/(```#R````\@```/(```#R````\@```/(```#R
+M````\@```/(```#R````\@```%P``0!>``$`]P```/@```#Y````^0```/D`
+M``#Y````^@```/H```#Z````^@```/L```#[````^P```/L```#6````U@``
+M`-<```#8````V0```-H```#;````W````-T```#>````WP```.````#C````
+MXP```.0```#E````Y@```.<```#H````Z0```.H```#K````[````.T```#N
+M````[P```/````#Q````\P```/0```#U````]@```/P```#\````_````/P`
+M``#]````_0```$```@!$``$``P$``$8``@`'`0``!P$```@!```(`0``"`$`
+M``@!```)`0``"0$```D!```)`0``"0$```D!```)`0``"0$```H!```*`0``
+M"@$```H!``!*``(`3@`"`%(``@!6``$`&0$``!D!```9`0``&0$``!D!```9
+M`0``&0$``!D!```9`0``&0$``!D!```9`0``&0$``!D!```9`0``&0$``!H!
+M```:`0``&P$``%@``0`>`0``'@$``!X!```>`0``'P$``!\!```?`0``'P$`
+M`"`!```@`0``(`$``"`!``#^````_P`````!`````0```0$```(!```$`0``
+M!`$```4!```&`0``"P$```P!```-`0``#@$```\!```0`0``$0$``!(!```3
+M`0``%`$``!4!```6`0``%P$``!@!```<`0``'0$``"$!```A`0``(0$``"$!
+M```A`0``(0$``"$!```A`0``(0$``"$!```A`0``(0$``"$!```A`0``(0$`
+M`"$!```B`0``(@$``"(!```B`0``(@$``"(!```B`0``(@$``"(!```B`0``
+M(@$``"(!```B`0``(@$``"(!```B`0``0``!`"4!```F`0``)P$``"@!```H
+M`0``*`$``"@!``!"``(`1@`"`$H``@!.``(`4@`!`%0``0!6``$`/@$``#\!
+M```_`0``/P$``#\!```_`0``/P$``#\!```_`0``/P$``#\!```_`0``/P$`
+M`#\!```_`0``/P$``#\!```C`0``)`$``"D!```J`0``*P$``"P!```M`0``
+M+@$``"\!```P`0``,0$``#(!```S`0``-`$``#4!```V`0``-P$``#<!```X
+M`0``.0$``#H!```[`0``/`$``#T!``!``0``0`$``$`!``!``0``0`$``$`!
+M``!``0``0`$``$$!``!!`0``00$``$$!``!```$`0@`!`$0``0!&``(`3`$`
+M`$P!``!,`0``3`$``$H``@!.``(`4@`"`%8``0!:`0``6@$``%H!``!:`0``
+M6@$``%H!``!:`0``6@$``%@``0!:``$`7P$``&`!``!A`0``7``!`&0!``!D
+M`0``90$``&4!``!E`0``90$``&8!``!F`0``9@$``&8!``!G`0``9P$``&<!
+M``!G`0``:`$``&@!``!>``$`8``!`&T!``!M`0``;0$``&T!``!M`0``;0$`
+M`&T!``!M`0``0@$``$,!``!$`0``10$``$8!``!'`0``2`$``$D!``!*`0``
+M2P$``$T!``!.`0``3P$``%`!``!1`0``4@$``%,!``!4`0``50$``%8!``!7
+M`0``5P$``%@!``!9`0``6P$``%P!``!=`0``7@$``&(!``!C`0``:0$``&H!
+M``!K`0``;`$``&\!``!P`0``<0$``'(!``!S`0``<P$``',!``!S`0``=`$`
+M`'0!``!T`0``=`$``$```@!$``(`2``"`$P``@!0``(`5``!`(H!``"*`0``
+MBP$``(L!``"+`0``BP$``%8``0!8``$`D`$``)$!``"2`0``D@$``)(!``"2
+M`0``DP$``),!``"3`0``DP$``),!``"3`0``DP$``),!``!:``$`E@$``)<!
+M``"7`0``F`$``)@!``!<``(`G`$``)T!``"=`0``G@$``&```@"C`0``HP$`
+M`*,!``"C`0``9``"`&@``@!L``$`;@`!`'```0!R``$`M`$``+4!``!U`0``
+M=0$``'8!``!W`0``>`$``'D!``!Z`0``>P$``'P!``!]`0``?@$``'\!``"`
+M`0``@0$``((!``"#`0``A`$``(4!``"&`0``AP$``(@!``")`0``C`$``(T!
+M``".`0``CP$``)0!``"5`0``F0$``)D!``":`0``FP$``)\!``"@`0``H0$`
+M`*(!``"D`0``I0$``*8!``"G`0``J`$``*D!``"J`0``JP$``*P!``"M`0``
+MK@$``*\!``"P`0``L0$``+(!``"S`0``M@$``+8!``"V`0``M@$``+<!``"W
+M`0``MP$``+<!``"X`0``N`$``+@!``"X`0``N`$``+@!``"X`0``N`$``+D!
+M``"Y`0``N@$``+L!``"\`0``O`$``+P!``"\`0``O0$``$```0#``0``P`$`
+M`$(``0!$``$`Q0$``,4!``#&`0``Q@$``,8!``#&`0``Q@$``,8!``#&`0``
+MQ@$``,<!``#'`0``1@`"`,L!``#,`0``S`$``,P!``#,`0``2@`"`$X``@!2
+M``(`5@`"`%H``@!>``$`8``!`.4!``#F`0``YP$``.@!``#I`0``Z@$``.H!
+M``#J`0``Z@$``+X!``"_`0``P0$``,(!``##`0``Q`$``,@!``#(`0``R0$`
+M`,H!``#-`0``S@$``,\!``#0`0``T0$``-(!``#3`0``U`$``-4!``#6`0``
+MUP$``-@!``#9`0``V@$``-L!``#<`0``W0$``-X!``#?`0``X`$``.$!``#B
+M`0``XP$``.0!``#M`0``[@$``$```0!"``$`\P$``/,!``#S`0``\P$``$0`
+M`0!&``$`2``!`$H``0!,``$`_@$``/\!`````@```0(```$"```"`@```@(`
+M``,"```#`@```P(```,"```$`@``!`(```0"```$`@``!`(```0"```$`@``
+M!`(```4"```%`@``!@(```8"```'`@``3@`"`%(``@!6``(`%`(``!0"```4
+M`@``%`(``!0"```4`@``%`(``!0"``!:``(`7@`"`&(``@!F``$`:``!`&H`
+M`0!L``$`*0(``"H"```J`@``*P(``"P"```M`@``+0(``"X"``!N``$`[P$`
+M`/`!``#Q`0``\@$``/0!``#U`0``]@$``/<!``#X`0``^0$``/H!``#[`0``
+M_`$``/T!```(`@``"0(```H"```+`@``#`(```T"```.`@``#P(``!`"```1
+M`@``$@(``!,"```5`@``%@(``!<"```8`@``&0(``!H"```;`@``'`(``!T"
+M```>`@``'P(``"`"```A`@``(@(``","```D`@``)0(``"8"```G`@``*`(`
+M`"\"```P`@``,0(``#$"```Q`@``,0(``$```0!"``$`-@(``#<"```X`@``
+M.`(``#D"```Z`@``1``"`$@``@!,``(`4``"`$L"``!+`@``2P(``$L"``!+
+M`@``2P(``$L"``!+`@``5``"`%@``@!<``(`8``!`&(``0!D``$`9@`!`&`"
+M``!A`@``80(``&$"``!A`@``80(``&$"``!A`@``80(``&$"``!A`@``80(`
+M`&$"``!A`@``80(``&$"``!A`@``8@(``&("``!B`@``8@(``&,"``!C`@``
+M8P(``&,"``!H``$`9@(``&<"``!H`@``:@`!`&P``0!N``$`<``!`#("```S
+M`@``-`(``#4"```[`@``/`(``#T"```^`@``/P(``$`"``!!`@``0@(``$,"
+M``!$`@``10(``$8"``!'`@``2`(``$D"``!*`@``3`(``$T"``!.`@``3P(`
+M`%`"``!1`@``4@(``%,"``!4`@``50(``%8"``!7`@``6`(``%D"``!:`@``
+M6P(``%P"``!=`@``7@(``%\"``!D`@``90(``&D"``!J`@``:P(``&P"``!M
+M`@``;@(``&\"``!P`@``<0(``'("``!S`@``<P(``'0"``!U`@``=@(``'8"
+M``!W`@``=P(``'<"``!W`@``>`(``'@"``!Y`@``>0(``$```@!$``(`2``"
+M`$P``@!0``(`5``!`%8``0!8``$`6@`!`)8"``"7`@``EP(``)@"``"8`@``
+MF`(``)@"``"9`@``F0(``)D"``"9`@``7``!`)P"``"=`@``7@`!`*`"``"@
+M`@``H`(``*`"``!@``$`8@`!`*4"``"E`@``I@(``*8"``"F`@``I@(``*8"
+M``"F`@``I@(``*8"``"G`@``9``"`*L"``"L`@``K0(``*X"``"O`@``KP(`
+M`'H"``![`@``?`(``'T"``!^`@``?P(``(`"``"!`@``@@(``(,"``"$`@``
+MA0(``(8"``"'`@``B`(``(D"``"*`@``BP(``(P"``"-`@``C@(``(\"``"0
+M`@``D0(``)("``"3`@``E`(``)4"``":`@``FP(``)X"``"?`@``H0(``*("
+M``"C`@``I`(``*@"``"H`@``J0(``*H"``"P`@``L`(``+`"``"P`@``L0(`
+M`+$"``"Q`@``L0(``+("``!```(`1``"`$@``@!,``(`4``!`,4"``#&`@``
+MQP(``,<"``#'`@``QP(``,@"``#(`@``4@`"`,P"``#-`@``S0(``,X"``#.
+M`@``SP(``%8``0#2`@``T@(``-,"``#3`@``TP(``-,"``#3`@``TP(``-,"
+M``#3`@``6``!`%H``0!<``$`V@(``-L"``#;`@``W`(``-P"``#=`@``W0(`
+M`-T"``#=`@``W@(``-X"``#?`@``WP(``.`"``#@`@``X0(``.$"``#B`@``
+MX@(``.("``#B`@``LP(``+0"``"U`@``M@(``+<"``"X`@``N0(``+H"``"[
+M`@``O`(``+T"``"^`@``OP(``,`"``#!`@``P@(``,,"``#$`@``R0(``,D"
+M``#*`@``RP(``-`"``#1`@``U`(``-4"``#6`@``UP(``-@"``#9`@``Y`(`
+M`.0"``#E`@``Y0(``.8"``!```(`ZP(``.L"``!$``(`2``"`$P``@!0``(`
+M5``"`%@``@!<``(`8``!``D#```)`P``"0,```D#```)`P``"0,```D#```)
+M`P``"0,```D#```)`P``"0,```D#```)`P``"0,```D#``!B``$`9``!`&8`
+M`0!H``$`:@`!`!0#```5`P``%@,``!<#```7`P``&`,``!D#```:`P``&@,`
+M`!L#```;`P``;``"`'```0!R``$`=``!`'8``0!X``$`>@`!`'P``@`N`P``
+M+@,``"\#```P`P``,0,``#(#```S`P``,P,``.<"``#H`@``Z0(``.H"``#L
+M`@``[0(``.X"``#O`@``\`(``/$"``#R`@``\P(``/0"``#U`@``]@(``/<"
+M``#X`@``^0(``/H"``#[`@``_`(``/T"``#^`@``_P(````#```!`P```@,`
+M``,#```$`P``!0,```8#```&`P``!P,```@#```*`P``"P,```P#```-`P``
+M#@,```\#```0`P``$0,``!(#```3`P``'`,``!T#```>`P``'@,``!\#```@
+M`P``(0,``"(#```C`P``)`,``"4#```F`P``)P,``"@#```I`P``*@,``"L#
+M```K`P``+`,``"T#```U`P``-0,``#4#```U`P``-@,``#8#``!```(`1``"
+M`$@``@!,``(`4``"`%0``@!8``(`7``"`&```0!B``$`6@,``%H#``!;`P``
+M6P,``%P#``!<`P``70,``%T#``!>`P``7@,``%X#``!>`P``7P,``%\#``!?
+M`P``7P,``&`#``!D``$`9@`!`&@``0!G`P``9P,``&<#``!G`P``:`,``&@#
+M``!H`P``:`,``&H``0!K`P``;`,``&P#``!M`P``;0,``&T#``!M`P``;0,`
+M`&T#``!M`P``;0,``&T#``!M`P``;0,``&T#``!M`P``;0,``&T#``!M`P``
+M-P,``#@#```Y`P``.@,``#L#```\`P``/0,``#X#```_`P``0`,``$$#``!"
+M`P``0P,``$0#``!%`P``1@,``$<#``!(`P``20,``$H#``!+`P``3`,``$T#
+M``!.`P``3P,``%`#``!1`P``4@,``%,#``!4`P``50,``%4#``!6`P``5P,`
+M`%@#``!9`P``80,``&(#``!C`P``9`,``&4#``!F`P``:0,``&H#``!N`P``
+M;@,``&X#``!N`P``;@,``&X#``!N`P``;@,``&X#``!N`P``;@,``&X#``!N
+M`P``;@,``&X#``!N`P``;P,``&\#``!P`P``<`,``'$#``!R`P``<P,``',#
+M``!T`P``=`,``'0#``!T`P``=0,``'4#``!```(`1``"`'X#``!^`P``?@,`
+M`'X#``!^`P``?@,``'X#``!^`P``?@,``'X#``!^`P``?@,``'X#``!^`P``
+M?@,``'X#``!(``(`3``"`%```@!4``(`6``"`%P``@!@``(`9``!`&8``0!H
+M``$`:@`!`&P``0"D`P``I0,``*8#``"F`P``=@,``'<#``!X`P``>0,``'H#
+M``![`P``?`,``'T#``!_`P``@`,``($#``""`P``@P,``(0#``"%`P``A@,`
+M`(<#``"(`P``B0,``(H#``"+`P``C`,``(T#``".`P``CP,``)`#``"1`P``
+MD@,``),#``"4`P``E0,``)8#``"7`P``F`,``)D#``"9`P``F@,``)L#``"<
+M`P``G0,``)X#``"?`P``H`,``*$#``"B`P``HP,``*@#``"H`P``J`,``*@#
+M``"I`P``J0,``*H#``!```$`K0,``*T#``"M`P``K0,``*X#``"N`P``K@,`
+M`*X#``"O`P``KP,``+`#``"Q`P``L@,``+,#``"T`P``M`,``+4#``"U`P``
+MM0,``+4#``"U`P``M0,``+4#``"U`P``M@,``+8#``"V`P``M@,``+8#``"V
+M`P``M@,``+8#``"V`P``M@,``+8#``"V`P``M@,``+8#``"V`P``M@,``+<#
+M``!"``$`1``!`$8``0!(``$`2@`!`$P``0!.``$`Q@,``,<#``#(`P``R0,`
+M`,H#``#*`P``RP,``,L#``"K`P``K`,``+@#``"Y`P``N@,``+L#``"\`P``
+MO0,``+X#``"_`P``P`,``,$#``#"`P``PP,``,0#``#%`P``S`,``$```@#0
+M`P``T0,``-(#``#2`P``TP,``-,#``#4`P``U`,``-0#``#4`P``1``"`$@`
+M`@!,``(`4``"`%0``@!8``(`7``"`&```@!D``$`9@`!`&@``0!J``$`;``!
+M`&X``0`!!````@0```,$```$!```!00```4$```&!```!@0```8$```&!```
+M!@0```8$```&!```!@0```8$```&!```!@0```8$```&!```!@0```8$```&
+M!```!@0```8$```&!```!@0```8$```&!```!@0```8$```&!```!@0```8$
+M```&!```!@0```8$```&!```!@0``,T#``#-`P``S@,``,\#``#5`P``U@,`
+M`-<#``#8`P``V0,``-H#``#;`P``W`,``-T#``#>`P``WP,``.`#``#A`P``
+MX@,``.,#``#D`P``Y0,``.8#``#G`P``Z`,``.D#``#J`P``ZP,``.P#``#M
+M`P``[@,``.\#``#P`P``\0,``/(#``#S`P``]`,``/4#``#V`P``]P,``/@#
+M``#Y`P``^@,``/L#``#\`P``_0,``/X#``#_`P````0```@$```(!```"`0`
+M``@$```(!```"`0```@$```(!```"`0```@$```(!```"`0```@$```(!```
+M"`0```@$```)!```"00```H$```+!```#`0```T$```.!```#@0```\$```/
+M!```#P0```\$```/!```#P0```\$```/!```$`0``!`$```0!```$`0``!`$
+M```0!```$`0``!`$```0!```$`0``!`$```0!```$`0``!`$```0!```$`0`
+M`!`$```0!```$`0``!`$```0!```$`0``!`$```0!```$`0``!`$```0!```
+M$`0``!`$```0!```$`0``!`$``!```$`0@`!`$0``0!&``$`2``!`$H``0!,
+M``$`'P0``"`$```@!```(`0``"`$```A!```3@`"`"8$```G!```*`0``"@$
+M```H!```*`0``"@$```H!```*`0``"@$```I!```*@0``"L$```L!```+00`
+M`"T$```N!```+@0``"\$```O!```+P0``"\$```O!```+P0``"\$```O!```
+M+P0``"\$```O!```+P0``"\$```O!```+P0``"\$```P!```,`0``#`$```P
+M!```,00``#$$```Q!```,00``#($```R!```4@`"`%8``@!:``(`7@`"`&(`
+M`@!F``(`$00``!($```3!```%`0``!4$```6!```%P0``!@$```9!```&@0`
+M`!L$```<!```'00``!X$```B!```(P0``"0$```E!```,P0``#0$```U!```
+M-@0``#<$```X!```.00``#H$```[!```/`0``#T$```^!```/P0``$`$``!!
+M!```0@0``$,$``!$!```100``$8$``!'!```2`0``$D$``!*!``````"``H'
+M`P`#%0,`X_P#`!,'`P`#&0,`\`X#``/J`P#^%`,`'_L#`!D#`P`'"@,`!PT#
+M`/D;`P`#[P,`$P("`/_I`@`0`@(`X@$"`.;_`@`"$0(`_@L"`/P*`@`!$P(`
+M!_L!``$*`0`%^0$`'`("``8<`P#I!@,`!@$%`!,``0#^]@$``?<&``#X!0``
+M^@0``/T"``C]`@#[]P(`#OT"`/_N`@#I_@(``PT"`/T1`@#_ZP(`#P`!```0
+M`0`'`P8`!?\$`/D"!@#^^08`^/X&``/Y!@`=``0`!_@"`/#X`P`$]P,`$@`!
+M```-`0#S`0$`&P$&`/WY!@#^!`4`'P$!``T'`P#_[`,`'/T#`.[X`P`"X`,`
+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
+M_PT&`/[[!0#X`04`^OT&``'D`0#X"0(`#?H"`/?^!@#B_P8`_/T%``,$!0#^
+M_`0``A4"`/X3`@`7Y0(`%_4"`.'^`@#]X@(`_1\"`/H)`@#\]`(`^>$"`/\8
+M`@`$]0(`]O@"`/'Y`@#^Y0(`%/P"`.(#`@`,^@(`#/P"`!G^`@#Z\@(`'OT"
+M``GW`@`'"`(`&0("`/KT`@`."@(`$0<"`.L"`@#P_`(`\QT"`.4&`@`"#@$`
+M&0$!`.W]`0#Z!P$``0P!`.W^`0`0_P$`_A(!`.L!`0#G_P$`&``!``+S`0`!
+M"P8```X&``()!@`)_@8`!/P%``+_`0`!`04``0,"`/H"!0#\^@8``.T&``D"
+M!@#@``8``!D%``/^`P`#``$`%P`!`/H(`0#@_P$`^@4!``,/`0#AX0$`$P,!
+M``'P`0`5_P$`_^`!``T#`0#L`0$`_>$!`/WQ`0`$^P8`Y0`$``8&!@`;^P(`
+M!AX"``?I`@`:!`(``@H&`/\*!@`$_P,`#P$&```/!@#Q`08`_QP&`/_W!0`!
+M"04``OX"``($!```'`0`_00%``;Q`@#YZ0(`$1$"`!+X`@#V^0(`_!8"`!L"
+M`@#I!P(`&P4"`.?C`@#\X0(`%_D"`/$&`@#D!@(``PP"`!(#`@#U!`(`_>P"
+M``P<`@`/!`(`\@8"`/@(`@#S^0(`^0L"`/__!`!```(`-!@``!`4```0%```
+M"!0```@4``!$``(`+!@```P0```,$```#!````P0```4$```%!```!00```4
+M$```!Q@``$@``@`X&```%Q@```,0```#$````Q````,0```$$```!!````00
+M```$$```3``&``\8```^&```C``"``88``"0``(`&!@``)0`!``"$````A``
+M``(0```"$```*!0``"@4```@%```(!0``!88``"D``,``10```$4```\#```
+M/`P``#P,```\#```/`P``#P,```\#```/`P``#\4```_%```#A@``*P``P`<
+M%```'!0``#`4```P%```"P0```L$```B"```/0@``"L(```O"```)`0``"0$
+M```Z"```-P@``",(```%"```.P@``#L(```["```.P@``#L(```["```.P@`
+M`#L(```["```.P@``#L(```["```.P@``#L(```["```.P@``#D4```Y%```
+M'1@``"48```9$```&1```!D0```9$```-1```#40```U$```-1```"T0```M
+M$```+1```"T0```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($
+M```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($```R!```,@0`
+M`#($```R!```,@0``#($```R!```,@0``#($```R!```,@0``#($```R!```
+M,@0```T(```J"```$P0``!,$```?!```'P0``"X(```;"```$@0``!($```2
+M!```$@0``!($```2!```$@0``!($```S"```,P@``#,(```S"```&@P``!H,
+M```Q$```*1```!$,```G#```'@@``!X(```V"```-@@``!4(```5"```"0@`
+M``D(```F#```(0P```H$```*!```"@0```H$``!```8`'!@``"@4```H%```
+M(!```"`0```@$```(!```"P8```8&```/!0``#P4```0$```$!```!`0```0
+M$`````@````(````"`````@````(````"`````@````(````"`````@````(
+M````"`````@````(````"`````@``.(`!@`T&```#!0```P4```D&```,@$&
+M``(8```"`@8`,!0``#`4```X%```.!0``!00```4$```%!```!00```(#```
+M"`P```@,```(#```"`P```@,```(#```"`P```0,```$#```!`P```0,```$
+M#```!`P```0,```$#````00```$$```!!````00```$$```!!````00```$$
+M```!!````00```$$```!!````00```$$```!!````00```$$```!!````00`
+M``$$```!!````00```$$```!!````00```$$```!!````00```$$```!!```
+M`00```$$```&#```!@P```8,```&#```!@P```8,```&#```!@P```<8```?
+M&```0``&``L8```]$```/1```#T0```]$```+A```"X0```N$```+A```#<8
+M```9&```#10```T4```_$```/Q```#\0```_$```@``!`&`8```K&```@@`%
+M`'$8``!I&```31@``$48``!U&```71@``%$4``!1%```8A```&(0``!B$```
+M8A```'(0``!R$```<A```'(0``!/$```3Q```$\0``!/$```;Q```&\0``!O
+M$```;Q```'8,``!V#```=@P``'8,``!V#```=@P``'8,``!V#```>`0``'@$
+M``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0`
+M`'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!X!```
+M>`0``'@$``!X!```>`0``'@$``!X!```>`0``'@$``!L!```3`0``'`$``!P
+M!```<`0``'`$``!P!```<`0``'`$``!P!```<`0``'`$``!P!```<`0``'`$
+M``!P!```<`0``'`$``!##```0PP``$,,``!##```5Q```%<0``!S$```<Q``
+M`$D4``!3%```2A```$H0``!N$```;A```$L0``!+$```0`0``$`$``!`!```
+M0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`
+M!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$``!`!```0`0``$`$
+M``!`!```0`0``$`$``!`!```0`0``$`$```>$```'A```!X0```>$```,10`
+M`#$4```M%```+10```D0```)$```"1````D0```V$```-A```#80```V$```
+M$@P``!(,```2#```$@P``!(,```2#```$@P``!(,```C&```$Q@``$@8``!`
+M``0`!1````40```%$```!1```'0$``!T!```=`0``'0$``!T!```=`0``'0$
+M``!T!```6`@``%@(``!8"```6`@``$<0``!K$```4@P``%(,```*#```"@P`
+M``H,```*#```"@P```H,```*#```"@P``#H0```Z$```.A```#H0```R$```
+M,A```#(0```R$```(1```"$0```A$```(1```!T4```=%```-10``#44```#
+M#````PP```,,```##````PP```,,```##````PP``!8,```6#```%@P``!8,
+M```6#```%@P``!8,```6#```.Q@``$``!@!_&```?A@``'P0``!\$```?!``
+M`'P0```B#```(@P``"(,```B#```(@P``"(,```B#```(@P``%`8``"(``,`
+M,Q@``)``!@`O%```+Q0``!<4```7%```7`0``%P$``!<!```7`0``%P$``!<
+M!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$
+M``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0``%P$``!<!```7`0`
+M`%P$``!<!```7`0``%P$``!]#```?0P``'T,``!]#```?0P``'T,``!]#```
+M?0P``$84``!&%```0``#`%48``!M$```;1```&T0``!M$```6A```%H0``!:
+M$```6A```$X0``!.$```3A```$X0``!>$```7A```%X0``!>$```8Q```&,0
+M``!C$```8Q```&H$``!J!```:@0``&H$``!Y#```90P``%D(``!9"```7PP`
+M`'<,``!["```>P@``%0$``!4!```5`0``%0$```G!```)P0``"<$```G!```
+M)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G
+M!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$```G!```)P0``"<$
+M```G!```)P0``"<$```G!```)P0``&0(``!D"```9`@``&0(``!D"```9`@`
+M`&0(``!D"```9`@``&0(``!D"```9`@``&0(``!D"```9`@``&0(``!Z#```
+M>@P``'H,``!Z#```>@P``'H,``!Z#```>@P``%L8``!6&```9A0``&84``!G
+M%```9Q0``&$4``!A%```/@@``#X(```^"```/@@``#X(```^"```/@@``#X(
+M```^"```/@@``#X(```^"```/@@``#X(```^"```/@@```X,```.#```#@P`
+M``X,```.#```#@P```X,```.#```)A```"80```F$```)A```!$0```1$```
+M$1```!$0```Y$```.1```#D0```Y$```0``!`&@8```E%```)10``"D0```I
+M$```*1```"D0```5$```%1```!40```5$```*@P``"H,```J#```*@P``"H,
+M```J#```*@P``"H,```:$```&A```!H0```:$```1!@``$(8```/%```#Q0`
+M`!L$``!!!```"!`0$Q`3%A86%A86&A@:&QL;&AH:&AL;&QT='2(B(AT='1L;
+M'1T@("(B)28E(R,B(R8F*"@H,#`N+C@X.D5%4]SQ_)\4)_V?T?\'`!!7`V`0
+M6`-@)@#X_X#U_)]\]OR?____?P```(```&```/+\GX;W`P``]OR?2!0``&RJ
+M`&`````(__\?``````$```!``.[\GP```@"HJ@!@W*@`8````D*($P````@`
+M``$`@````(```%+\GP"9`````OR?@):8`/T)_/\`^OR?`/[\GP8``.`&``"@
+M`"[\GP#>_)\`&````.+\G__G______^_```!`/___O_`#P`````_``````0#
+M`__@`P+_X```,`,&"__P!```@`$``(#_]___```"@(<3``#___\/````P/_O
+M`````!```/[[G^0-``#___\!__]?`'OX_?\```"@````X`$``.`!``"@`P``
+MX`,``*`*``#@"@``H````&(#``"`A`<"``````+___^]____\```$(#_\___
+M`!\```!```#_?_#_`(`)`````/#_O___```(@````X#_\/____\/_P``#X``
+M``:````!@```$8"5`0!`E0``0``.`````,`````P````#`````,`__\_^/__
+M_\<```X`````.`#P`0```,`'G0``0)4#`$"5`@!``(`,````"@````6````$
+M@```#8````R`C0``0!`(`&```/`/`#__`/___X`6```(($X``/___\#W??__
+M`(```````%`@O_\`*00$````>``FI(0`QH2$`"2DD!(``#`&(20$``,@```"
+M(```0&\``.AN``#@#P``3`\``(`/``!@NP!@?+X`8$0S(A&\$@``J&L``/__
+M_P#`M@8`*%4!8```4@#,:P``$&X```QL``"L;````/\`__@=``#P_P``0`@`
+M`"`__P`WS4+]9KCTC(OQ3P<\;0``P!(`````P#^,#```4`@`8,!K```0#0``
+M/YP`````)``!8```B`\``+0/``#T"P``@`T``*`-``"P%@``:%T``.A=```K
+M#0``Q!(``+0+```H#0``M#T```P^``"9/0``K!L```0<``"0#```L`@`8`@,
+M``!4;0``-`P``'0,``"H"P``Z`\``$@3``!`$```%3T``)02````(`,``@@`
+M`(@,``!`;0``K`P``)`)``"X%```N!(``*Q=``!L:P``J!(``!0/``"(7@``
+MG!(``$`)`&#P;0``$&L``!$/````4@(````X!`#@A@(``,P``'AI``!V+P``
+MV!L``.P-``!&!0!.8@``4&(```YC```08P``_&L``-`.``!@;0``$`\``!@/
+M```\%```5!L``/__O_^`7@````!``)@+``!D7P``\%\``+!=```I#0``]%T`
+M``P)``!,#0``1&T```P*```,#0``U$P!8/!,`6!F=XB9__\#^```_`<`_@,`
+MM!(``%P]``"<:P```#__`=1K```H@P%@['8!8."L`6!@;0%@@&`!8)AW`6"(
+M;P%@.*P!8'23`6!880%@=*`!8-!7`6"LI`%@J)(!8,"N`6#TAP%@'(H!8,B4
+M`6#P"0!@```0^```0/@P"@!@````^```,/@(@`````#@`0``(/@9```0&0``
+M(!L``!`;```@$P`!`!L``(`;``!`&P``D!L``%`;``"@&P``8!L``#`;``"P
+M&P``<!L``/`;``#`&P``T!L``.`9```P&@``$!H``"`:```P'```P!P``(`<
+M``!`'```(!P``!!0"@!@B`@``,`(````.```Z-(!8-#0`6#^_P```0#P#T3^
+M'@!!`/`/`3__`````)X7```(2.D!8(!_@']4"```E!<"8,3W`6#P%0)@`/D!
+M8!`+`&`:"P!@L!<"8.@7`F#,%P)@#!8"8$06`F`H%@)@W/<!8!CY`6`,^`%@
+M2/D!8/3W`6`P^0%@@0#P#P,(```+``(`_]___S`+`&#`"P!@``!1````4```
+M`'$```!P````$0`?,@``'S$`````T0```)$```#0````D`#_#P``_Q\``/X/
+M``#^'P``'S4``!\S```?-````A(```#````?6```T`L`8!]0```"#@``'U<`
+M`#@,`&`?5```'UH``!]9``!0#`!@8`P`8"`,`&`?4@``'U$``$`,`&`0#`!@
+M'U8```@,`&``#`!@'U,``+P+`F#H[0%@3`P"8$SO`6``#0)@O!$"8#CS`6#,
+M#@)@]!("8!\K``!P#`!@@`P`8!\P`````+``#`@``+`B`F#@#@``D`P`8/__
+M_P<?50``````#P```+`""0```@P```(0``"H#`!@`#@"8)PT`F#\_P``1/X?
+M``H`\`\*`_`/__\````0``````0````(````(```\`````\```"``P``?```
+M4``B````_P_OOJW>#0``0/"^K=[__```8!$``````&"`$0``H!$``,`1``"D
+M$```!!$``````#RH$```"!$``````!#,$```+!$``-`0```P$0``K!````P1
+M`````-S_``#@_P#P_P``7V`!*)0`````_P``_P```0```8N%`@"+A08`````
+M_@``$`$,A@(`#(8&`/G_``#P#P``/X`-`$#[`@`L*P``=%X"8```"0``@`0`
+M\`P`8)Q<`F`,AP)@H"H``,0E``#,)@``(S__`",___`#`/`/<``'`/@-```L
+M*0``,'4```,`_P\#`/$/_____D`K````T`(`^"(```,6``#$)`````!0^-0E
+M``"`_P``P/\``,AW`F!D=P)@T"4```(1```"%@``,`T`8*2%`F`"&```$`X`
+M8`,1```%$0``N`L``-`-`&`D*0``.",``#"&`F`_"0``1",``#25`F!\M`)@
+MG*4"8&R3`F#@#P!@?(<"8`S/`F!\QP)@!(@"8`4``$#@Q@)@])L"8"3*`F#@
+MQP)@N-`"8*BZ`F!0)@``!-,"8,34`F"$AP)@\(<"8-R'`F#(AP)@M(<"8*"'
+M`F",AP)@MPL``"`I```P#@!@D`X`8&@C``#@#@!@T`X`8*`/`&`\)```#"0`
+M`!0D``!@)0``F"0``'`C``!H)```J",``'0C``"P$0!@9-L"8,3J`F!<W0)@
+MQ-T"8#CE`F#,X@)@D.L"8,3?`F!@$`!@`Q,```&P!@`P$`!@<!``8&PC```+
+M`6``/PH``#\+``"P$`!@$!$`8`'P`0!P$0!@`A,```,)```#"@```@H``-`1
+M`&"0+@!@P#\`8&!C`&#8)0``(/,"8$C\`F``[P)@..X"8"SX`F#,_`)@:/H"
+M8)!T`&!@=P!@6",``&3^`F`4`@-@E`H#8!^A!P#____]<(``8(0.`V#D"P-@
+MI%$#8!`G```?"```'PD``!\*```````%`Q<```(+```#"P``&`T``````(3_
+M__/____\__\`__\```"#````&`````P`\/__````AO\/`/___W__````#@``
+M``H````&````'````!0F`/\`!@#P#S:A*PP"#`4,!*+!$`S+83@`\M$5#`XQ
+M-P`,!WD!TB.JTF$!B!'B;Q!R;PY@B"""8ZKED2RBP2"RH$#"T152;!=";!8B
+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
+M____`````/____\`````_____P````#_____`````/____\`````_____P``
+M``#_____`````/____\`````_____P````#_____`````/____\`````____
+M_P````#_____`````/____\`````_____P````#_____`````/____\`````
+M_____P````#_____`````/____\`````_____P````#_____`````/____\`
+M````_____P````#_____`````/____\`````_____P````#_____`````/__
+M__\`````_____P````#_____`````/____\`````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+;``````````````````````````!7`P`(-P`!
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TURKS_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_mc.bin.uu
new file mode 100644
index 0000000..8ea2331
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_mc.bin.uu
@@ -0,0 +1,539 @@
+begin 644 TURKS_mc.bin
+M``/HX``"O@$```(4``/_```#_P```J`.``'`'0`#Z````^@0``/H(``#Z#``
+M`V`8``-@'``#8"```V`H``*P_P`"L?\``K+_``*S_P`#83@``TEL``/_```#
+MKPH``K0$``)O]```^CL``K0/``)/%```^A<``T`D``*T0``"M0\``TJF``)$
+M00`#\`(``DF5``-JI@`"+:@``TG4```R0P``(A@``#H5``*U$```FD,``D53
+M``/P"``"H'X``_!&``*@8P`#\$0``/(/``(TOP`#]````<`E``/H````@@\`
+M`T`D``*T0``"M?```TJF``)$00`#\`(``FF5``-JI@`#0````_\```/X`0`#
+MQ$```\11``+&10`"`````T`0``/_```#_P```^@@``/H,``#8!```_@#``(S
+M;``",J@``T@(``*TGP`"0`0``V@(``-((0`"L\$``D=S``-H(0`#:HD``T@E
+M``*SP0`"1W,``V@E``-JC0`#2,```TC&``"",0``BC```,(O``#*+@`#Z!``
+M`^B0``-HP``#:,8``TJD``/H0``#_P```D(D``-JI``#2````T@%``*[/P`"
+MO+\``K_O``"2,P``BC0``((X``"Z-@``JCH``D$;``*[^P`"0BL``D`,``-H
+M```"15\``V@%``-($``#2=T``KOQ``*\`@``BC<``*HY``)!&P`"81P``V@0
+M``)%6P`"95P``VG=``-`#0`#_P```_\```.A3```B@T``K,"``)#-``#HS``
+M`)H,``*S!``"0S0``Z,R``":"P`"L`@``()!``*P"0``@D(``T@I``-)<``"
+MOP<``D`/``.````#``X``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H
+M+0`#P00``\$5``-IZ``#:>P``^@```/HT``",$\``VCD``/!W@`",$\``VD$
+M``-`+``#_P```K0"``)$!```HA8``TG6``*U$``"1%L``Z1&``"B&``"H$X`
+M`_`#``(T:@`#]````<#%``/T```!TW(``T`.``#R0``#Z/```Z"V``-)U0``
+M^A$``K$/``)"%P`"I2```_`!``#Z0``"0QL``J4C``/P`0``\A$``T````-`
+M+@`"MA```K0,```J0``"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!
+M``/HP```XA```T`(``*T````>A$``J`D``/P00`"L@@``J#^``/P00`"L@0`
+M`K0_``)")```DB@``TJ4``/_```#8&P``T````/_```"M$```D0$``/P`P`#
+MZ````((_``(B^@`#0````_\```*T0``"1!0``_`"``#R/P`"(OH``T````/_
+M```"M$```D04``/P`0`"+FX``TJ4``/_```#8'```T````/_```"M`(``D0D
+M``/P`P`#Z````((_``(C,0`#0````_\```*T`@`"1#0``_`"``#R/P`"(S$`
+M`TJ4``/_```#830``C-L``-````#_P```_\```)$#@`#\`,``^@```""/P`"
+M)%H``C-L``-````#_P```_\```)$'@`#\`(``/(_``(D6@`"+JD``TJ4``/_
+M```#8'0``K````""*P`#0````_\```*T`@`"1$```_`#``/H````@C\``B89
+M``-*E``#_P```V!X``-````#_P```K0$``)$0``#\`,``^@```""/P`"*)P`
+M`TJ4``/_```#8'P``T````/_```"M!```D1```/P#``#Z````((_``(I;```
+M`@T``_\```/_```"I`X``_`$``#R#@`"*6P``^@```""#@`#2I0``_\```-@
+MK``#0````_\```*T(``"1$```_`#``/H````@C\``BN$``-*E``#_P```V"P
+M``/H````@C\``K#_``*Q_P`#P2```VA@``-H:``#0````_\```*T$``"1$``
+M`_!"``/T```"`8\``T`-``-`)@`"L4```K(0``*S"``"010``Z$:``)")``#
+MHB0``F(A``)#.``#HS```F(C``"2*P`"I!X``_`)``-)/0`"LH```\`B``)$
+M0@`"*6P``TD]``/_```"LH```F1"```"$``#_P```K0!``)$!``#\`0``^@`
+M``""/P`#P?X``BQ&```"$``#_P```K0"``)$!``#\`0``^@```""/P`#Z/``
+M`BQ&``-````#_P```_\```)$+@`#\`,``^@```""/P`"-7<``T````/_```"
+MM!```D0D``/P`P`#Z````((_``(VJ0`#^`,``TJ4``/_```#8+0``K````""
+M*P`#0````_\```*T`@`"1$$``_`"``#R/P`")AD``TJ4``/_```#8+@``T``
+M``/_```"M`0``D1!``/P`@``\C\``BB<``-*E``#_P```V"\``-````#_P``
+M`K00``)$00`#\`L``/(_``(I;````@T``_\```/_```"I`X``_`$``#R#@`"
+M*6P``^@```""#@`#2I0``_\```-@[``#0````_\```*T(``"1$$``_`"``#R
+M/P`"*X0``TJ4``/_```#8/```/(_``*P_P`"L?\``\$@``-H8``#:&@``T``
+M``/_```"M!```D1!``/P0@`#]````@(.``-`#0`#0"8``K%```*R$``"LP@`
+M`D$4``.A&@`"0B0``Z(D``)B(0`"0S@``Z,P``)B(P``DBL``J0>``/P"0`#
+M23T``K*```/`(@`"1$(``BEL``-)/0`#_P```K*```)D0@```A```_\```*T
+M!``"1`0``_`#``#R/P`#P?X``BQ&```"$``#_P```K0(``)$!``#\`,``/(_
+M``/H\``"+$8``T````/_```#_P```D0^``/P`@``\C\``C5W``-````#_P``
+M`K00``)$-``#\`(``/(_``(VJ0`#2I0``_\```-@]``#^`,```(8``/_```#
+M_P```J`.``/P0@`#]````@)L``-`+``#_P```K0@``)`0``"H`0``_!(``/H
+M````@C\``C((``(R30``\C\``C((``(R30`",N0``T````/_```"M`@``D0$
+M``/P#``#2`@``_\```*T0``"8`0``V@(``-)F``"M/T``D$4``-IF``#Z#``
+M`\$N``-H,``",O@``^@```/H$``#Z#```K(#``-H,``#0````_\```*U"``"
+M114``_`!``(TUP`#2I0``_\```-@^````D```_\```/_```"H0X``_`"``/H
+M````@A0``BZI``-(```#2`4```HT```".```$C,``"HZ```Z-@`#_P```V@`
+M``-H!0`#2!```TG=```*-P``*CD``_\```-H$``#:=T``TEQ``*R`0`#Z#``
+M`\$&``/!%P`#:#```TEL``*U%@`"H%$``<*?``*PSP`"L04``K(!``*S```#
+M:#```C+X``*PM``#:#```C+X``*PO``#:#```C+X``*PN``#:#```C+X``*P
+MRP`#:#```C+X``*PC``#:#```C+X``*PT0`#:#```C+X``/H```#Z!```K(#
+M``*S```#:#````(8``/_```#_P```J`.``/P0@`#]````<`````!]``#0!(`
+M`T`5```*&P`"H`X``_`"``/T```!PL\``L$>``"*&P`":[H``F5;``+&;@`#
+M\$$``L=^``-@%0`"L@\``D1"``*E%``#\`<``^B@``/HL``#8!(``^@```"!
+M]``#]````<!-``-`+``#_P```K0@``)`0``"H`0``_!"``/T```!PN0``^@`
+M``""/P`",@@``C)-``#R/P`",@@``C)-``(RY``#0!```_\```/_```#H`8`
+M`X`&``/!\``"+GL``\'P``(N>P`#P?```BY[``/!\``"+GL``T`@``/_```#
+M_P```L`.``/P10`"P1X``_!#``+"+@`#\$$``L,^``-@(``",VP``TE(``*T
+M/P`"M8```D,T``)C-0`#:4@``D,T``-I2``#]````<````-`!```:C\``^B`
+M``/HD``#Z*```^BP``*U$``"1!4``_`&``*@W@`#\`,``V2J``/T```#\$$`
+M`V3J``/X`0`"M0@``D0%``(#'```8?@``J#>``/P`P`#Z$```_0```/P00`#
+MA.H``]A```/<P```>?<``_@#``/4G@`#^P```P_^``(#&``#^`$``X7D``)$
+M%0`"`R\``"'Y``*@W@`#\`,``&'Q``/T```#\$$``&'P``*_"``#W$```]C`
+M``/X`P`#U)X``_L```,/_@`"`RL``_@#``/L`````A0```I```!J/P`#_P``
+M`D`!``*@#@`#\`$``^P```-).``"H-X``_!!``-*7``"N/X``D(H``*@W@`#
+M\`,``VDX``/T```#\$$``VI<``-)T``"M`0``F$4``*R`0`"LQ(``J#>``/P
+M00`"LQ$``V@P``-)<0`"N.\``KD$``/!!@`"87D``D,X``-H,``#2`D``KC]
+M``)$2``#:`D``BY_``-)H``"M!$``\$D``*Q#P`#::```TI$``*T_@`"81X`
+M`VI$``)!%``#:D0``J#>``/P`P`#0F$``_0```/P00`#0ET``_\```/_```#
+MZ&```VFE``-H:P`"N@P``KC```/<@0`#V*$``K#X``*Q!P`#Z"```^@P``/^
+M```#U!\``VAK``/H\``"(_\``B/B``(D'``"H?X``_!!``-B>@`#0G@``_\`
+M``/_```"H(```<.3``*@D0`!PY,``J"B``'#DP`"H+,``<.3``+/_@`"O`P`
+M`J'\``/P0@`#]````<-]``#Z!``#Z/```B/B``(C_P`")!P``T)X``/_```#
+M_P```J"```'#J0`"H)$``<.I``*@H@`!PZD``J"S``'#J0`"S_X``KP,``*A
+M_``#\$(``_0```'#E@``8@0``/H#``/_```"I<\``<.Y``*E_``!P[0``^CP
+M``/HP``#]````<.\``,,SP`#K,```^CP``/T```!P[P``P_\``.O\``#Z,``
+M`B/_``/!_``"(^(``TDX``*@W@`#\$$``TI<``/_```"8BX``J#>``/P`P`#
+M:3@``_0```/P00`#:EP``TG0``*T^P`"010``K(!``*S$@`"H-X``_!!``*S
+M$0`#:#```TEQ``*X[P`"N?L``\$&``)!>0`"0S@``V@P``-("0`"N/T``D1(
+M``-H"0`"L!@``B1```/L```#1+D``J#>``/P00`#1/D``\$/``/!'P`#P2\`
+M`\$_``/!3P`#P5\``J#>``/P!0`#9+```V2T``-DN0`#]````_!#``-D\``#
+M9/0``V3Y``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P```-$
+MN0`"H-X``_!!``-$^0`#P0\``\$?``/!+P`#P3\``\%O``/!?P`"H-X``_`%
+M``-DK``#9+P``V2Y``/T```#\$,``V3L``-D_``#9/D``TC(``*T\P`"M00`
+M`D`$``)@!0`#:,@``D`$``-HR``#[````K`0``(D0``",O@``C+X``(R^``"
+M,O@``C+X``-*'``")$P``\&,``-*(``")$P``XS&``)HC``#2B0``B1,``/!
+MG``#2B@``B1,``.,Q@`":9P``THL``(D3``#P:P``THP``(D3``#C,8``FJL
+M``-*-``")$P``\&\``-*.``")$P``XS&``)KO``#[````VAK``*Y"``"N,``
+M`]R```/8D``#Z!```^@@``/H,``#_@```]0>``-H:P`#[````^C```.'/``#
+MIW8``X8L``.F:``#A1P``Z5:``.$#``#I$P``FS'``)LQ@`";,4``FS$``/L
+M````(@\``T`D``/_```"1$X``Z`&``*A#@`#\`$``(('``-)I``#2:$``&H_
+M``.+Z@`#P*L``D6E``*@W@`#\`,``D.C``/T```#\$$``F.S``-II``#::$`
+M`K+_``*Q_P`"L'\``VA@``/H```#Z"```^@P``*@W@`#\`,```H)``/T```#
+M\$$```H(``*XP``#:&L``]@```/<@``#U!X``K\"``(N>P`#@.```(($``""
+M`P`#Z````(("``""`0``\@```TA4``*@W@`#\`,``X3H``/T```#\$$``X3J
+M``)B)``#:%0``TF8``.(Y0`#P3X``J#>``/P`0`#@S```\$N``)@"``#:#``
+M`TEU``.(Y@`"8&@``\$7``/!+@`#P3X``J#>``/P`0`#@S```V@P``-(5``"
+MH-X``_`#``.$Z``#]````_!!``.$Z@`#P$0``D(D``-H5``"OP(``BY[```"
+M&``#_P```_\```*@#@`#\`(``_0```($UP`",&$``^AP``.$Y@`"1DL``J!D
+M``/P3P`#2=(``^A@``.*L@`#JJH``X2F``)D2@`#P50``J#>``/P`P`#:.4`
+M`_0```/P00`#:04``_0```'%@@`"OP@``D_Y``.O]``#B[(``ZN\``(EI@`#
+M]````@6"``-`#``#_P```K\(``)/\``#\$(``_0```'$]``"OP```KL!``(E
+MI@```A$``_\```/_```"H`X``_!"``/T```!Q8(``K$"``*P$0`"Q$```L50
+M``*@W@`#\`,``VCE``/T```#\$$``VD%``,!'@`"!.D``/("``#R`0`"H-X`
+M`_`#``!Z!@`#]````_!!``!Z!0`#C>(``]S0``/8\``#B>8``FF>``#Q\@``
+M0@<``^C0``./X``#P:@``XSM``#A]@``XCX``B_*``*W`0``0@<``^B@``#1
+M\@`"H'X``_`!``.H@``##]\``\'9``/!J``#C.T``.'V``#B/@`"+\H``C`+
+M``/!!``#P28``V)P``*_`0`#0!$``XC@``*@_@`#\`0``D1(``/P`@`#]```
+M`@5H``*W`0``0@<``_\```*@?@`#\`$``ZB```/HT``#C^```\&H``.,[0``
+MX?8``.(^``(OR@`",`L``T)P``.,ZP`#C.H``^CP``+(0``#J(```"H6``+*
+M8@`#JJ```J9>``(%10``:C\``/(6``/!6``#P7H``V)Q``/T```"!/\``J%>
+M``/P#@``:C\``\&1``/!LP`"H-X``_`#``-A+@`#]````_!!``-A,@`"P($`
+M`Z@```+"HP`#JB```X50``"J%@`#@>```P"$``/P)``"H80``_`!``+$00`#
+M!$X``\%4``,"I@`#\"0``J&F``/P`0`"QF$``P9N``/!=@`#U%X``F`"``(%
+M5P``:C\``K\"``(N>P`#27$``X'D``/!!@`#HFP``J`N``(%@@`"87$``\$N
+M``/!/@`"H-X``_`!``.#,``#AF```_!'``-H,``#C^T``BY[``./[0`"+GL`
+M`X_M``(N>P`#C^T``BY[``-)=0`#P2X``\$&``/!%P`#P3X``J#>``/P`0`#
+M@S```V@P``-)F``#_P```\$^``*@W@`#\`$``X,P``/!+@`#:#````H/```!
+M]``#_P```D$>``/P`0`#[````J4.``/P2``#0!$``J#>``/P`P`"9FX``_0`
+M``/P00`"9WX``V`1``/H````@?0``^P```(R^``#2D```$(```!*!```4@,`
+M`KPS``)$#``"11P``F1%``)&+``"1SP``F9G``)D1@`"H4X``_`!``*T`0`"
+MH(X``_`%``*D20`#\$,``J1+``/P00``\@(``*($``*\S``"1`P``D4<``)&
+M+``"1SP``F1%``)D1@`"9$<``J%.``/P`0`"M`$``J".``/P!0`"I$H``_!#
+M``*D2P`#\$$``/(!``"B`P`#Z$```*(```-#*0`"H-X``_!!``-#:0```@(`
+M`!(!``*Q#P`"LP<``J7^``(%_``"H`X``_`&``*\#P`"I$$``_`!``*\"0`#
+MP4P``\%<``*@+@`#\`8``KP/``*D80`#\`$``KP)``/!;``#P7P``J#>``/P
+M`P`#8RD``_0```/P00`#8VD``DP"``*@S@`#\`8``L_^``*\"0`"I?P``_`"
+M``/T```!Q:8``TCE``*@W@`#\$$``TD%``*X$0`"H`X``_`!``+$2``"24$`
+M`J23``/P`0``\@(``J`N``/P`0`"Q5@``DE1``*DDP`#\`$``/(!``*@W@`#
+M\`,``VCE``/T```#\$$``VD%``)``@`"H`X``@6F``/L````:C\``^@```(P
+M.P`#29@``K@/``*U]0`"LP$``J#>``/P`0`#@S```\$N``)@"``"014``V@P
+M``*_```"+GL``/'_``/H````@?X``T`,``-`+0`"N!```KD(``)*&``#JJ8`
+M`DM)``.KM``"LP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*$0`"
+ML$```D!```/P00`#Z#```D$>``/P`0`#Z#```)G]``(N?P`"O`$``J#>``/P
+M"0`#2"$``XS&``.&9@`#IF8``F9L``-H(0`#:HD``_0```/P1P`#2"4``XS&
+M``.&9@`#IF8``F9L``-H)0`#:HT``K`!``/H$``#Z"```^@P``-J8``"OP,`
+M`C'5``-("``#A.H``('U``)@!``#:`@``K]D``(N>P``:C\``_\```/_```"
+MH-X``_`#``*[```#]````_!!``*[0```V>\``\$.``/!'@`#@18``F$>``."
+MY@`#:D0``\$>``.!%@`#Z"```VI$``/H```#P````\$0``*R_0`#:&```TI@
+M``*_]P`"L1,``D`/``)@#@`#:F```#(,```Z"P`"O`@``K_^``.&:@`"8B8`
+M`J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(N>P`#:&L``_\```/^````
+M8CT``%H\``/_```#V,$``]RQ``./XP`"+GL``]`?``.,[P`#C^0``F_^``)`
+M`0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!J(``J#>``/P`P`#2"$``_0`
+M``/P00`#2"4``\#,``(&S@`#C.8``L9L``/P00`"QWX``J#>``/P!``#:"$`
+M`VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!QG$``T`1``*P"```
+M\?0``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T```""(,``X#A``.!
+M!@`"81X``X+G``-J1``#@08``^@@``-J1``"L`$``^@0``/H(``#Z#```VI@
+M``-`+```6BL``K0$``/H\``"1$```_`!``*_`0`"I+X``_`!``*_!``",=4`
+M`/(G``#R)0`"L/\``K&_``/!(``#:&```K`!``/H$``#Z"```^@P``-J8```
+M"CL``!(,```:"P`"L`(``J#>``/P00`"L`0``X(J``*D/@`#\`$``K,$``.!
+M%@`"8`$``K$S``-J8``#0`H``K`!``*Q`@`"L@```K,!``*@*P`#\`(``^@@
+M``/!.P`#:F@``\$.```20@`"0`D``_`!``/H(``"L!,``K$"``.")@`#Z#``
+M`VIP``-`+0``8A$``!(H``*_0``"3T\``_`#``*@S@`#\`$``K((``*P(0`"
+ML0(``K,!``-J=```"BL``K`!``/_```"I!X``_`%``*Q!``"L@```K,"``/T
+M!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P```K`!``*Q`@`"LP0``VI\
+M```!_@`#_P```_\```+`#@``@?X``C'0```")P`#0`H``T`-``*@#@`#\`4`
+M`K`!``)`!0`#@`8``_0$``/P`P`"L`0``D`)``.``@`"L0,``F@!```"*P`#
+M_P```_\```*D#@`#\`L``!(H``*P(P`"L0,``K,!``-J=``#2GP``_\```*P
+M`0`"L00``K,$``-J?``#2F0``K2````1[P`"0`0``F`(``.B(@`"LP$``VID
+M``(PE0`",*(```'_``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H`
+M`J#>``/P`0`#Z/```]CP``*\"0`"OS\``DL?``(O"P`#Z/```/G_```!_@`#
+M_P```_\```+`#@``@?X``T`E```:$``"L@0``D(@``*@W@`#\$$``Z,R``*Y
+M`@`"29,``F(I``*Y@``"294``F(I``*YA@`#Z(```J`I``/P00`#P8X``,':
+M```)_0`#0"X``_\```*@`0`"!Z(``K`!``)!"``#\`4```)```/_```#_P``
+M`J`.``('H@`#2G0``'HH``/_```#_P```\$O``-J=``",=````(G``-`"@`#
+M0`T``J`.``/P!0`"L`0``D`%``.``@`#]`0``_`"``*P$``"0`D``'G:``*Q
+M0P`#_P```J#^``/P00`"L2,``F@!```"*P`#_P```_\```*@#@`"!]0``!(H
+M``*P0P`"L00``K,!``-J=``#2GP``_\```*P`0`"L04``K,$``-J?``#2F0`
+M`K2````1[P`"0`0``F`(``*X(``"8`@``KB_``)`"``#HB(``\$^``-J9``#
+M]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``/!/@`#:F0``C"5``(P
+MH@``0A```K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```'']0`#0`X``K`0
+M``/_```"00D``J`0``(']0```B<``_\```/_```"P`X``((G``*Q`@`"I`$`
+M`@<U``!![P```?D``_\```/_```#V(```]P```!Z0@`"L`$``]P!``*P```#
+MV`$``$G:``/_```#_P```J">``/P1@`#Z/```K$D``+(@0`#V(```L`!``/8
+M@0`",(P```'^``/_```#_P```L`.``"!_@``>=H``C'0``*@_@`#\$4``K`/
+M``/!$``#P2```\$P``-J@``#0`H``K!```/_```"0`D``Z`"``*Q`P`":`$`
+M``(K``/_```#_P```J0.``/P"P``$B@``K!#``*Q!0`"LP$``VIT``-*?``#
+M_P```K`!``*Q!@`"LP0``VI\``-*9``"M(```!'O``)`!``"8`@``Z(B``*S
+M`0`#:F0``C"5``(PH@`#0"4``$(0``*P(``"0`4``_!(``*P`@`"H-X``_!!
+M``.``@`"0`@``_`"``/T```!R&4``!'^``*P@``"LP,``J`C``/P0P`"0`4`
+M`_`!``(QE@`#0"X``_\```*P"``"00@``J`0``((90`"L(```D$(``/P!0``
+M`D```_\```/_```"H`X``@AE```")0`#_P```_\```/H$```BB4``J0.``('
+M=P```>\``$'Y``/_```#_P```]@```/<@```>D(``K````/8`0`"L`$``]P!
+M``-`#0`"O2```_\```)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\`
+M`K+_``-H8``#:&L``!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#
+MZ#```VI@``-*9``"M(```D`$``-J9```(?4``_\```-("``#_P```\$$``-H
+M"``#[````^@```/H$``"H-X``_`#``-I'``#]`0``_`!``-I-``#[````&H_
+M``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_````V?P`
+M`C*.``/H```",#L``KL"``#:/@`#2`$``K"_``)$0``#:`$``TF8``*T#P`"
+MM?T``F`$``)!%0`#P2X``\$^``*@W@`#\`$``X,P``-H,``#2`@``K1```"!
+M]0`"8`0``V@(``/H```"L6```^@@``/H,``#::```^@```*Q$``#Z"```^@P
+M``-J1``"L`$``^@0``/H(``#Z#```VI@``*_`@`",=4``^@```/````#P1``
+M`K+]``-H8```"CL``!(,```:"P`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+GL``VAK``/_
+M```#_@```C'^``-*8```,@P``#H+``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"````20@`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``"L/\``K&_``/!(``#:&```^AP``-*9``"M(```D`$
+M``/H(``#Z#```VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0`
+M`C"5``-*9``"M`@``D1```)G=``"I7X``@E<``/H```",#L``J#>``/P`P`#
+M2"(``_0```/P00`#2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H
+M(@`#:HH``_0```/P0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R2$``T`2
+M``#Q]``"OP0``J#>``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R5P`
+M`K`!``/H$``#Z"```^@P``-J8``#2F0``K2```)`!``#:F0``"'U``/_```#
+M2`@``_\```/!!``#:`@``^P```!J/P``\?\``^@```""$P`#0`@``T`M``*X
+M0``"N0@``DH(``.JJ@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!
+M``*S!@`#0"T```H1``*P0``"0$```_!!``/H,``"01X``_`!``/H,```FA(`
+M`"'T``/H4``#_P```*(9``"I]```:C\``_\```/_```"H-X``_`#``!9\0`#
+M]````_!#``!9\``#_P```_\```#9[P`#2````X3J``/`1``#_P```D`$``-H
+M```#2`0``\!^``/_```#_P```D,W``-H!``#0"P``%HK``*T!``#Z/```D1`
+M``/P`0`"OP$``DN^``*@O@`#\`,``C#]``/T```!R;4``K_+``(S00``\B8`
+M`/(E``*P_P`"L;\``\$@``-H8``"L`$``^@0``/H(``#Z#```VI@```*.P``
+M$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B
+M(0`"I#X``_`!``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"
+M``*R```"LP$``J`K``/P`@`#Z"```\$[``-J:``"L`$``!)!``)`"0`#\`$`
+M`^@@``*P$P`"L0(``X(F``/H,``#:G```T`M``!B$0``$B@``K]```)/3P`#
+M\`,``J#.``/P`0`"L@@``K`A``*Q`@`"LP$``VIT```**P`"L`$``_\```)!
+M$``"I!X``_`%``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX
+M``-*?``#_P```K`!``*Q`@`"LP0``VI\```**P`#_P```_\```)!'@`"I!X`
+M`@I4```"$P`#_P```_\```+`#@``@A,``C'0```")@`#0`H``T`-``*@#@`#
+M\`4``K`"``)`!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"
+M*P`#_P```_\```)`#@`"I`X``_`+```2*``"L",``K$#``*S`0`#:G0``TI\
+M``/_```"L`$``K$$``*S!``#:GP``TID``*T@```$>\``D`$``)@"``#HB(`
+M`K,!``-J9``",)4``C"B```!_P`#_P```_\```*@#@`#\$X``T`L``*\!``#
+MW,```K_```*@W@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+PL``^CP``#Y
+M_P```A,``_\```/_```"P`X``((3``!:*P``>B4``K@(``)*O@`"H*X``<IX
+M``.JL``"2JX``_!#``(M:``#]````<IT``-*<``"NH@``KEP``*@^``#\$,`
+M`\$J``/T```!RG(``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C,+``*P_P`"
+ML;\``\$@``-H8```"A(```(3``-`+@`#_P```J`!``(*C``"L`$``D$(``/P
+M!0```D```_\```/_```"H`X``@J,``-*=```>B@``_\```/_```#P2\``VIT
+M``(QT````B8``T`*``-`#0`"H`X``_`%``*P"``"0`4``X````/T!``#\`,`
+M`K`@``)`"0`#H````K%#``)H`0```BL``_\```/_```"0`X``J`.``(*O```
+M$B@``K!#``*Q!``"LP$``VIT``-*?``#_P```K`!``*Q!0`"LP0``VI\``-*
+M9``"M(```!'O``)`!``"8`@``K@@``)@"``"N+\``D`(``.B(@`"L00``\$^
+M``-J9``#]`0``_`(``-*9``"M(```!'O``)`!``"8`@``Z(B``*S`0`#:F0`
+M`C"5``(PH@``6BL``KH!``/_```"2[H``J"Z``/P0@`#]````<KE``!"$``"
+ML`$``J#>``/P00`#@`(``D`(``/P`@`#]````<KE``-`"@`#_P```K!```)!
+M"``"H!```@KE```")@`#_P```_\```+`#@``@B8``K$"``*D`0`""A$```'O
+M``!!^0`#_P```_\```/8```#W(```'I!``*P```#V`$``K`!``/<`0`",(P`
+M``(3``/_```#_P```L`.``""$P`",=```T`*``*P@``#_P```D`)``.@!``"
+ML0,``F@!```"*P`#_P```_\```)`#@`"I`X``_`+```2*``"L$,``K$%``*S
+M`0`#:G0``TI\``/_```"L`$``K$&``*S!``#:GP``TID``*T@```$>\``D`$
+M``)@"``#HB(``K,!``*Q```#:F0``C"5``(PH@``6BL``KH#``*Y`0`#_P``
+M`DBZ``*DB0`!RU<``KD$``/_```"2+H``J"*``'+.0```B4``K((``*S```#
+M_P```J0"``'+5P`"H`X``_!#``":)0`#]````<I4``)+N0`"H+D``<M7``"2
+M)0`#]````<I4``/T```!RU<``$(0``*P`0`"H-X``_!!``.``@`"0`@``_`"
+M``/T```!RU<``T`N``/_```"L`@``D$(``*@$``""U<``K"```)!"``#\`4`
+M``)```/_```#_P```J`.``(+5P```B4``_\```/_```#Z!```(HE``*D#@`"
+M"E0``%HK``/_```#2G```_\```)+O@`"H+X``_!"``*R@``#:G```&'Y``!9
+M[P`#_P```]S```/8L```>D$``K````/8`0`"L`$``]P!``-`#0`"O4```_\`
+M``)-U0`"IMX``_`#``(O*P`#]`0``_`*``*P?P`"L?\``K+_``-H8``#:&L`
+M`!'E``*SP``#Z-```V!,``(O9@`"L`$``^@0``/H(``#Z#```VI@``(QT``#
+M[````&H_``/_```#_P```J#>``/P`P`"NU,``_0```/P00`"NUL``_\```/_
+M````V?P``T`0``*[#P`#2"D``J#>``/P00`#2"T``K\$``)`"P`#JP(``P_[
+M``.,]@`";,\``X_V``-)Z``"HTP``_`$``,$3``#!5\``_0```/P10`#A.8`
+M`X56``.E5@`"950``F1.``/!!``#P14``J#>``/P!``#:"D``VGH``/T```#
+M\$(``V@M``-I[``#Z````C!/``-(`0`"L+\``D1```-H`0`#Z````K%```/H
+M(``#Z#```VI$``*P`0`#Z!```^@@``/H,``#:F```K\"``(QU0``"CL``!(,
+M```:"P`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$``)B(0`"I#X`
+M`_`!``*S!``"L1@``VI@``-`"@`"L`$``K$"``*R$@`#Z#```VIH``*P@```
+M$D$``D`(``/P`0`#Z"```K`3``*Q`@`#@B8``^@P``-J<``"L"$``K$"``*R
+M`0`"LP$``VIT``*P`0`"L0(``K(/``*S`0`#:G@``TI\``/_```"L`(``K$"
+M``*S!``#:GP``^@```/````"L;\``\$@``-H8``#Z'```TID``*T@``"0`0`
+M`VID``-*9``"M(```!'\``)`!``"M`,``F`$``*S$``#:F0``C"5``-*9``"
+MM`@``D1```)G=``"I7X``@P\``/H```",$\``J#>``/P!``#2"H``TGH``/T
+M```#\$(``T@N``-)[``"O!$``K\0``+)GP`"R(P``\$(``/!&0`"H-X``_`$
+M``-H*@`#:>@``_0```/P0@`#:"X``VGL``*[`0``VCX``^AP``.+Y0`#B[8`
+M`J6+``/P`@`#]````<O\``-`$@``\?0``K\@``*@W@`#\`,``FJO``/T```#
+M\$$``FN_``-@$@`#]````<P\``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID``/L````:C\``^@```"!V0`"L`@``('[``*@W@`#\`,``%GQ
+M``/T```#\$$``%GP``*P?P`"H?X``_!!``)+L```V>\``K#_``*QOP`#P2``
+M`VA@``*P`0`#Z!```^@@``/H,``#:F````H[```2#```&@L``K`"``*@W@`#
+M\$$``K`$``.!%@`"8`$``X(J``*Q@``"8B$``J0^``/P`0`"LP0``T`5``*Q
+M"``"MO```D1&``)A%``#:F```K`!``*Q`@`"L@```K,"``-J:```$?L``K`3
+M``*Q`@`#@B8``^@P``-J<```$B@``K`A``*Q`@`"LP$``VIT``*P`0`"L0(`
+M`K(/``*S`0`#:G@``TI\``/_```"L`$``K$"``*S!``#:GP``KP$``/<P```
+M>>\``&'[``*[&``#V/```B\+```!V0`#0"4``K\0``+`#@``@=D``D]?``/P
+M`P`"+6@``_0```',J0`"OP@``J`.``/P`0`#P?X``C,+``-*@``"H/X``_!!
+M``-JA```8>\``K"```/H\``"H<```_!!``/!_@`"+1L``C'0```1[P`#Z!``
+M`K`C``.B(@`"LP$``VID``(PE0``8=D```'O```)^0`#0"8``K(0``/8```#
+MW!```'G[``*P```#V`$``K`!``/<`0`"0BD``_!%``.O\``"H,X``_`"``/[
+M```#^P$``]">``/[```"I2X``_`!``/[```#U)\``_L!``*E+@`#\`$``_L!
+M``,/_@`"#,L```'9``/_```#_P```L`.``"!V0``8>\``K"```/!_@`"H<``
+M`_!!``/H\``"+1L``C'0```1[P`"L`,``^@0``.B(@`"LP$``VID``(PE0`"
+M,*(``T`E```!V0`"L0,``K((``*S$``"0S4``_`"``)")0`#\`(``J4!``',
+ME@``8?D``%GO``/_```#W,```]BP``*P```#V`$``K`!``/<`0``>?L``T`-
+M``*]0``#_P```DW5``*FW@`#\`,``B\K``/T!``#\`H``K!_``*Q_P`"LO\`
+M`VA@``-H:P``$>4``K/```/HT``#8$P``B]F``*P`0`#Z!```^@@``/H,``#
+M:F```C'0``/L```"O!$``J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(
+M\0`"+5,``J#>``/P!``#:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$
+M``-(U``#2-D``_0```/P0@`#2/0``TCY``(M4P`"H-X``_`$``-HU``#:-D`
+M`_0```/P0@`#:/0``VCY``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#
+M\`0``L`,``+!'``#]````_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P
+M00`#:/P``^P```*@_@`#\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L
+M``+'?``#]````_!(``,`#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP`
+M`^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#H`,``]P```/8$``#
+M0#$``K\#``*\`@`"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X``_!!``/!
+M!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#^P```P_^
+M``(-=0`#0#4``K\#``/_```"IOP``_!!``/!!P`"H/P``_!!``/!!@`"H/X`
+M`_!!``/!!0`"H?X``_!!``/!!``#P1```\$@``/!,``#_@```]0>``-H:P`#
+M^P```P_^``(-C0`#0#@``T`]``/_```#:H0``VJ!``/L```#85```V%5``-A
+M6@`#85\``TA4``/_```#Z#```Z,S``-H5``#:&L``TA5``/H```#Z'```K+O
+M``*Q_P`"L+\``VA@``-H:P`#27P``K0$``)A%``#:7P``TD\``/_```"81X`
+M`VD\``-*E``#03D``_\```/_```"IC<``_`'``*F)@`#\`4``J85``/P`P`"
+MI00``_`!``-A.``#8/P``_\```/^```#_P```TAD``*T$``"0B0``J`D``/P
+M0P`"+A4``_0```'-T``"L/\``K'_``*R_P`"L_\``VJ0``-)/``#P$X``D$4
+M``-I/``#2%0``K4_``)#4P`#:%0``^@```"!]```@AH``((;``-(9``#C.H`
+M`/(5``),#``#\$@``T@T``/_```#@`@``Z`,``*@#@`#^`$``@WQ``""%0`#
+M^`,``TA5``/H```#AP<``VA5``-)/0`"OQ```D1/``/P!``"O_\``BY[``*_
+M4``"+GL``Z=P``,'?@`"#@<``\`@``/`$``#P````VA@``-H:P`#H!```VA@
+M``-!4``#054``T%:``-!7P`#[````_@#``-)T``"N`@``DDX``*@F``"#F@`
+M`TG4``*T$``"0S0``J`T``(.1``#2`@``K@(``)@"``#:`@``T@H``*X(``"
+M8S@``T@M``-H*``#:>@``F=X``-H+0`#:>T``TC(``*X^P`"0B@``VC(``-(
+MF``"N"```F`(``-(L0`#:)@``F1(``-HL0`#P0X``\$>``/!+@`#P3X``V,P
+M``-C<``#8S0``V-T``-C.``#8W@``_0```'.:``#2`@``KCW``)`"``#:`@`
+M`T@H``*XWP`"0S@``T@M``-H*``#:>@``D=X``-H+0`#:>T``TC(``*X!``"
+M8B@``VC(``-(F``"N-\``D`(``-(L0`#:)@``D1(``-HL0`"L`,``\$0``/!
+M(``#P3```V,P``-C<``#8S0``V-T``/!+@`#P3X``V,X``-C>``#27P``K3[
+M``)!%``#:7P``VAK``/L```#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(`
+M`VC*``)H(0`#:,H``\&"``-HR@`#[````_@#``,/_@`"#GP``^P```/H```#
+MP!```\`@``.@$``#:&```VAK``/!#@`#Z!```^@@``/H,``#I!,``]@0``/<
+M0``#_@```]0>``-H:P`#::0``^@```/^```#U!X``VAK``-II``"H-X``_`#
+M``-"8``#]````_!!``-"7``#0ED``J#>``-II``#\`,``T)H``/T```#\$$`
+M`T)D``-IH0`#_@```]0>``-H:P`#:&L``^P```/H```#P"```\`0``.@$``#
+M:&```VAK``-"5@`#P0X``^@0``/H(``#Z#```Z03``/8$``#W$```]0>``*_
+M`@`"+GL``VAK``-II``#::(``^@```/_```#U!X``K\"``(N>P`#:&L``VFD
+M``/H```#P"```\`0``/````#:&```VAK``/L```#:&L``K!_``*Q_P`"LO\`
+M`VA@``*Q#``#Z````Z`#``/<```#V!```^@```/H$``#Z"```^@P``/^```#
+MU!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>``-H:P`#^P```PB.``(.
+MX``#[````"'Z``/H4``#Z&```^AP``*Y"``"N,```]R!``/8D0`#0E```_@#
+M``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#:&L``K09``/^```#U%\`
+M`VAK``-)I0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#
+M"9X``@\'``-II0`#[````J&^``/P"@`#T!X``P^^``/X`P`#``X``P$>``,"
+M+@`#`SX``]0>``,/_@`"#Q```_L```,,S@`"#PL``^P```*AO@`#\`H``]`>
+M``,/O@`#^`,``L`.``+!'@`"PBX``L,^``/4'@`##_X``@\@``/[```##,X`
+M`@\;``/L```#T)X``]`?``*\/P`"2(P``DF<``)*K``"2[P``D0,``)%'``"
+M1BP``D<\``*\(``"P(0``Z````*C2``#\$$``L`,``+!E0`#H1```J-9``/P
+M00`"P1P``L*F``.B(``"HVH``_!!``+"+``"P[<``Z,P``*C>P`#\$$``L,\
+M``/HT``#C.D``P2```+HC0`#!9$``NF=``,&H@`"ZJT``P>S``+KO0`#8FX`
+M`DB,``))G``"2JP``DN\``/4G@`#0FX``F1%``)D1@`"9$<``@]-``!J/P`#
+M^P```_L!``,/_@`"#RL``^P```/0G@`#T!\``KP_``)(C``"29P``DJL``)+
+MO``"1`P``D4<``)&+``"1SP``KP@``+`A``#H````J-(``/P00`"P`P``L&5
+M``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#\$$``L(L``+#MP`#HS``
+M`J-[``/P00`"PSP``KP'``*CW``#\$X``W!,``-03@`#_P```_\```/^```#
+MU!X``VAK``/[```#<$X``U!,``/_```#_P```_0$``/P"``"O`@``J3<``/P
+M`0`#:H0``KP)``*DW``#\`$``VJ```*P_P`"L;\``K+_``-H8``#^P```_L!
+M``+-W@`"IM\``@]F``-*9``"M(```D`$``-J9``"L````K$```*R```"LP$`
+M`VIT``*P,0`"L08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#
+M:GP``TID``*T@``"0`0``K0#``)@!``#:F0``C"5``-*9``"M(```D`$``-J
+M9```:C\``C-L``/L````6?8``&(^``/_```"H;X``_!"``#Q]``#[````J'.
+M``/P00`#"[X``PS.``#9]@``XCX``TI```!:%@`#_P```_\```*@O@`#\$(`
+M`Z````.B(``#T%X``&(*``!9\@`#H@(``D`)``)"*0`"I8X``@_U``,(C@`"
+MH`T``_`+``!"!P`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$
+M3P`#P50``J6N``(0!0`#"JX``J`M``/P"P``4@<``L9O``/!=@`"H+X``_!&
+M``/47@`"QF\``\%V``/47@`"QF\``\%V``/47@`##,X``A`&``)KB@`"#\H`
+M`^P```-"<```4A8``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"
+MH6@``_!!``+&:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&
+M:``#`B@``P,X``,*K@`"$!D``\%4``/!=@`#U%X``V)P``/L```#P6(``P9N
+M``/<$``#V````]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X`
+M`_L```,&;@`"$"X``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#
+M:1```VD4``-I&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I
+M-``#[````\$0``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<
+M``/T```#\$4``VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4`
+M`D$#``-)T@`#_P```D`*``-)P@`"I1```_`!``-)Q@`#[````K!_``*Q_P`"
+MLO\``VA@``-H:P`#Z````^@0``/!+@`"LS```VFD``/H```"L3```^@@``/H
+M,``#Z$```Z5#``/80``#W%```_X```/4'@`#:&L``_L```/[```"L!(``^@0
+M``/^```#U!X``VAK``,(C@`"$(8``^P```/0G@`#^P```_\```/_```#U)\`
+M`_L!``,/_@`"$(P``^P```/X`0`"OP0``TID``/_```#_P```D$/``(0EP`#
+M^`,``VAK``/_```#_P```_X```/L```#2F0``_\```*_"``"00\``J`?``(0
+MPP`#0!(``K40``*E)0`#\`0``K\"``)JKP`#]````=#```+$50`"I20``_`$
+M``*_`@`":[\``_0```'0P``"Q$4``J4D``/P!``"OQ```FJO``/T```!T,``
+M`K\0``)KOP``\?0``V`2``(PQ``#[````TIP``/_```#P<(``T`N``*P`0`#
+M:J@``_\```/_```#_P```TJL``*T`@`#:JD``\````/`$0`#P"(``\`S``-*
+MK0`"OY```J#/``/P!0`#P$0``K\/``)/3P`#]````_!!``/`]``"H-X``_`+
+M``-`&0`#_P```_\```)D0``"95$``F9B``)G<P`#8!D``FJO``/T```#\$D`
+M`T`=``/_```#_P```F1```)E40`"9F(``F=S``-@'0`":[\``V`N``/L```"
+MQ$8``VJI``/_```#_P```_\```-*K``#[````K!_``*Q_P`"LO\``VA@``-H
+M:P``">4``K#```/<```#V!```J#^``/P!``#Z````^@0``/H(``#Z#```J#^
+M``/P1``"L%4``\$0``/!(``#P3```J#^``/P!``"M/\``\%4``/!9``#P70`
+M`J#^``/P1``"M*H``\%4``/!9``#P70``KP'``*C_@`"$7D``$(-``/_```#
+M_P```J".``(1/P`"H-X``_`#``-`0@`#]`0``_`!``-`1@``ZC\``&H.``*D
+MW@`#\`0``\"(``/`F0`#P*H``\"[``)@"``"81D``F(J``)C.P`"9$@``F59
+M``)F:@`"9WL``&H_``/_```#_P```_X```/4'@`#:&L``_L```,,S@`#_@``
+M`]1>``-H:P`#^P```PS.``(1/P``0@T``&(.``/_```"H(X``A%D``-`2@`"
+MI,X``_`$``/`B``#P)D``\"J``/`NP`"I-X``_`"``/!B@`#P9L``KH/``)*
+MJ``#BZ8``FJK``*[\``"2[@``Z>V``)KMP`#]`0``_`#``/H8``#Z*```^BP
+M``*T\``"8$H``\$0``/!(``#P3```VJ$``*@_@`#\`,``K3P``/T!``#\`$`
+M`K0/``)@2P`#P1```\$@``/!,``#:H```^P```/^```#U!X``VAK``/[```#
+M#,X``KD#``*@^0`#\$0``^A```/H4``#Z&```^AP``/^```#U%X``VAK``/[
+M```##,X``A&%``*P\``"L?\``J#Y``/P0@`#Z````^@0``/!(0`#P3$``VJ$
+M``-J@``#[````K!_``*Q_P`"LO\``VA@``-H:P``">4``K#```/<```#V!``
+M`K3_``/!9``#P70``KP'``/^```"M?\``]1>``-H:P`#^P```PS.``/^```"
+MM>\``]1>``-H:P`#^P```PS.``(1HP`"M?\``VJ%``*P\``#P1```\$@``/!
+M,``#:H```TIB``(QT``#Z/```C'<``-J8@``">4``K#```/<```#V!```K3_
+M``/!5``#P60``\%T``*\!P`#_@```]1>``-H:P`#^P```PS.``(1Q0`"L/\`
+M`K&_``/!(``#:&```^P```-*9``"M(```D`$``-J9``#[````K`$``*@\``#
+M\`,``C#]``/T!``#\`$``BUH``/H```#P````\$0``*R_0`#:&````H[```R
+M#```&@L``K`*``*@W@`#\$$``K`,``.!%@`"8`$``K$6``*D/@`#\`$``K,$
+M``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"L@0``F(F``-J8``#C^$`
+M`BY[``-H:P`#_P```_X```/L```#2F```_\```/H,``"8`X``VI@``-*9``"
+MM/(``D`$``-J9``#[````&H_``-`!``#_P```K@$``)%X``"H%X``_!$``*@
+MW@`#\$(``T`D``/_````8?@``_\```/_```#W,```X_J``*@W@`#\`$``^CP
+M``/8\``#C.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<`
+M`D`(``/P0P`"+PL``_0```/P00`"+QL``D1N``/P"0`#Z,```ZMB``.E8``"
+M15X``_!#``(O"P`#]````_!!``(O&P`#[````TC```-(Q0`#Z!```^A0``*@
+MW@`#\`@``VC````",0``"C```_\```/_```#:,```_0```/P1@`#:,4``"(O
+M```J+@`#_P```_\```-HQ0`#[````&H_``/_```#_P```%'Y``*@W@`#\`,`
+M`%GQ``/T```#\$$``%GP``/_```#W*```]BP``-`!@`#_P```_\```)`Z``#
+M\`,``J#>``/P00`#0"8``_\```/_```#24$``J`.``/P0P`"H-X``_!!``/!
+M10`"14X``_!#``.,Y``#]````_!!``.,XP`#B9@``ZJ<``*@K@`#\`,``B\+
+M``/T```#\$$``B\;``-`!@`#_P```_\```-)00`"0(X``J`.``/P0P`"H-X`
+M`_!!``/!10`#Z,```ZM"``)%3@`#\`<``Z5```)%7@`#\$,``B\+``/T```#
+M\$$``B\;``/L```"H-X``_`#``-((0`#]````_!!``-()0`#_P```KL!``.B
+M9@`#@68``Z$6``.'=@`"8"<``P`+``.G!@`#@@8``F8A``*@W@`#\`0``V@A
+M``-JB0`#]````_!"``-H)0`#:HT``^P```./[0`"+GL``^@P``."X``#Z!``
+M`^@```-H,``#C^T``BY[``/H\``#27```^AP``*V`0`#P5$``\%```-H,0`"
+MN/P``\%3``/!0@`"15@``TET``(R^``#:#$``\%1``/!0``",O@``V@Q``/!
+M4P`#P4(``TF8``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TF<
+M``(R^``#:#$``\%1``/!0``",O@``V@Q``/!4P`#P4(``TCH``(R^``#:#$`
+M`\%1``/!0``"MQ```C+X``-H,0`#P5,``\%"``(R^``#:#$``^P```-)/0`"
+ML`@``D`$``/P!0`#2J0``_\```/_```"L@,``VJD``*P!``"000``J`0``/P
+M1@`#2,```TC%``*Q`P`"M0,``VC```-HQ0`#[````_\```/_```#_P```^P`
+M``-A2``#84$``V%&``-B?P`#P0X``^@0``/H(``#Z#```VCH``/H```#_P``
+M`VCH``-!2``#_P```^P```*P?P`"L?\``K+_``-H8``#:&L```GE``/H```#
+MH`,``]P```/8$``"O`,``K#W``*@_@`#\$$``K!_``/!$``#P2```\$P``*T
+M_P`#P50``\%D``/!=``#_@```]0>``-H:P`#H`$``Z$1``.B(0`#HS$``_L`
+M``/^```#U%X``VAK``/[```##,X``A,A``*P_P`"O`@``\$0``/!(``#P3``
+M`VJ```*D_@`!TSL``J#\``/P`@`#:H0``^P```*P]P`#H0$``Z(1``.C(0`#
+M:H0``^P```-)/0`#_P```KB```)D2``#:3T``K`!``*Q`@`"LC\``D(O``*S
+M```#:F@``K````*Q```"L@```K,"``-J=``"L0$``K((``*S```#:G@``K`!
+M``*R```#:GP``!'O``*PP``"0`\``Z`"``)@#@`"L0```Z(B``*S`0`#:F0`
+M`K#_``*QOP`#P2```VA@``/_```#_P```C"5``*X?P`"1$@``VD]``/L```#
+MZ````^@0``*R`P`"LP```V@P``/L```#Z````((_``(B^@``\C\``B+Z``(S
+MJ``"+FX``TF8``*T]P`"010``VF8``/!+@`#Z#```V@P```"%P`#@>```^A`
+M``*@`0`#\`$``\%.``(TL@`#2`@``KC^``)!&``#:`@``^@```""/P`")%H`
+M`/(_``(D6@```A<``X'@``/_```"I!```_`"``/!3@`"-+(``C0"``-`+``"
+MN$```KF```*[_P`#2J4``D@8``/P`0`"N\\``DD9``/P`@`"NC\``DNZ``)%
+M6P`#:J4``_0```'";``#2=$``KA```)$>``#A$```TB<``.%X@`"8`0``F`%
+M``-HG``#:*```VBT``-HN``#23@``X7A``/`50`"0B4``VDX``-J7``#H.$`
+M`X'A``/H,``#@N@``X7E``(P*@`#0Z8``X#H``/_```"2(4``FB```/!F``#
+MP:@``\&X``-CI@`#8^8``^@```/HT``",#L``\'>``(P.P`",&$``X3B``/!
+MR0`#Z````X'A``.#Y``"PC$``P(N``+#/@`"1$D``_`!``.#Y0`#Z%```C`J
+M``.`Z@`","H``XCE``.$X``"1$P``_`"``.(Y``"R(X``\&8``/!J``#P;@`
+M`V,J``-C:@`",&$``X'B``.@X0`#HY8``X+D``+"+@`#Z%```C`J``.@XP`"
+M,"H``C!A``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#@.```H((``)"
+M`@`#@B0``)'C``/L```",&$``TEP``)$C@`#\$,``K7S``)")0`#:7```^AP
+M``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D``/!4P`#P4(`
+M`V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@``X1```.%1@`"
+M8`4``F$4``/H,``#P2X``V@P``-#I```(>,``K4/``/_```"0`4``F`$``/!
+M$``#P2```\$P``-CI``#8^0``X&$``.@&``#@@8``F`"``/HT``",$\``\'>
+M``(P3P`#2)```Z2Z``.EYP`"014``F$4``-HD``#:*@``VB4``-HK``#H*8`
+M`\$0``/!(``#P3```V0D``-D9``#BK8``T@A``*X`P`"9F@``KD/``*[_@`"
+M1FD``F9J``)'>P`#:"$``VJ)``-H)0`#:HT``T@(``-((0`"81X``V@(``-(
+MR``"N$```KD_``)@"``#:,@``D`)``-HR``"95X``V@A``-JB0`#:"4``VJ-
+M``)%6P`#:"$``VJ)``-H)0`#:HT``^P```-`+``"N$```KF```/HL``#2J4`
+M`D@8``/P`0`"NS```DD9``/P`@`"NL```FNZ``)E6P`#:J4``TB<``-(H0`"
+MO'L``D`,``)$3``#:)P``VBA``-(M``#2+D``D`,``)$3``#:+0``VBY``-(
+MD``#A.(``Z7G``)!%0`"810``VB0``-HJ``#:)0``VBL``-).``#A>$``F(E
+M``-I.``#:EP``Z#A``.!X0`#@^@``X+H``.%Y0`","H``^@```.!X0`#@^0`
+M`L(Q``/H,``#Z%```C`J``.`Z@`","H``T@(``-((0`#J.T``D$8``-H"``#
+MJ.L``D9H``/`/@`"15,``V@A``-JB0`#:"4``VJ-``/H0``"-+(``^P```-)
+M=``#P6X``^AP``.(2``#P%X``X59``)")0`"8B@``VET``/!0@`#P5,``V@Q
+M``/L```#2`@``KC^``)!&``#:`@``TA4``*\8``"8BP``VA4``-)=@`"O!``
+M`F2L``/!6P`#P6X``^AP``-H,0`",O@``TA4``*\GP`"0BP``VA4``/!2@`#
+M:#$``C14``/L````\=X``/'=``/!_0`#P<X``T@$``/`?@`"0S<``V@$``-(
+M"``#_P```X3H``)@!``#:`@``TF8``.%X@`#P%4``D$5``.$Y0`"8`0``^@P
+M``/!+@`#:#```^C0``(NRP`#^`$``T`-``/_```"L`$``D`&``(5"P`"H.T`
+M`_`%``*[/@`"2[8``ZNP``/T!``#\`T``K````*R`@`#HVH``PNN``*@,``#
+M\`<``PN^``*@/@`#\`0``PN^``*@,@`#\`$``PN^``/T!``#\`$``^BP``-(
+M&0`"LN```D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BY_
+M``(NYP`"M`\``TI```/X`0`"I$```_`&``*D00`#\`0``J1"``/P`@`"H$,`
+M`A4W``+*K@`"L"```J"@``/P00`#Z*```J"K``(57P`#2!D``K+@``)&8@`"
+M9FH``V@9``-)Y0`#_P```D9B``)F:@`#:>4``_0$``(5&```T=\``J#>``(5
+M/@``T>```LW>``/T!``"%.\``$'@``/_```#_P```J"H``(590`"H:@``_!(
+M``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%64``T@9``*RX``"1F(`
+M`F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P``)G<P`#
+M:"4``VJ-``/T!``"%64``T`1``/HP```\?0``KB```)G>``#8!$``\'?``-)
+MF``#A>(``\!5``)!%0`#:9@``^@P``/!+@`#:#```T@(``/_```#A,@``F`$
+M``-H"``#^`,``^P```/_```#_P```&H_``/H````@AD``('<``*P`0`"L1$`
+M`K(0``-J1``"L1```^@@``-J1``#0"0``J#>``/P`P`"NU,``_0```/P00`"
+MNUL``-G\``)`#@`#\$L``T`0``*\!``#W,```X_J``*@W@`#\`$``^CP``/8
+M\``"O`D``\&Q``(O"P`#0"0``_\```*\`@`"0`P``_!+``-`$``"O`0``]S`
+M``*_P``"H-X``_`!``*_@``#V/```XSD``/!L0`"+PL``TF8``.(Y0`"M?T`
+M`\$^``*@W@`#\`$``X,P``/!+@`"8`@``D$5``-H,``#2`@``K1```"!]0`"
+M8`0``V@(``-(`0`"L+\``D1```-H`0`#Z````K%```/H(``#Z#```VI$``-`
+M+@`"L`$``^@0``/H(``#Z#```VI@``(M:``"L`$``K$"``*R!@`#Z#```VIH
+M```200`"L!,``K$"``.")@`#Z#```VIP``*P(0`"L0(``K($``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P```"L0```K,$``-J?``"
+MOQ@``C91``(V?@`"OP```C'5``-*<``#_P```_\```*RD``#:G```K\3``(V
+M40`"-GX``T`D``/_```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>
+M``/P`0`#Z/```]CP``*\"0`#BQ```B\;``-`)``#_P```KP"``)`#``#\$L`
+M`T`0``*\!``#W,```K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(O&P`#
+M2G```_\```/_```"LH```VIP``*_&``"-E$``C9^``*_```",=4``TIP``/_
+M```#_P```K*0``-J<``"OQ,``C91``(V?@`#0"0``_\```/_```"0`X``_!+
+M``-`$``"O`0``]S```./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+PL`
+M`T`D``/_```"O`(``D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"
+MOX```]CP``.,Y``#P;D``B\+``*P`0`#Z!```^@@``/H,``#:F```TID``*T
+M@``"0`0``VID```A]0`#_P```T@(``/_```#P00``V@(``/L```#Z````\``
+M``*QOP`#P2```VA@``*P`0`#Z!```^@@``/H,``#:F```TID``*T@``"0`0`
+M`VID```*.P``$@P``!H+``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``/!'P`#:F```TID``*T@```$?P``D`$``*T
+M`P`"8`0``K,0``-J9``",)4``K\(``)/\``#\`$``/(9``/L`````AD``_\`
+M``/_```"I0X``_`!``/L```#Z````((9``-`$@`#_P```_\```)$C@`"H$X`
+M`_`!``#Q]``"OT```J#>``/P`P`":J\``_0```/P00`":[\``V`2``(PQ```
+M>=P``_\```-`*``"H/X``_!!``/L```"H-X``_`%``+`#@`#\$$``L$>``/T
+M```#\$,``L(N``/P00`"PSX``V`H``#QW``#[`````(4```*0```:C\``_\`
+M``)``0`"H`X``_`!``/L```#2)P``TBA``-*2@`"H-X``_!#``-(M``#2+D`
+M`TI.``*\$``"8BX``F9N``)HC``":9P``J#>``/P!0`#:)P``VBA``-J2@`#
+M]````_!#``-HM``#:+D``VI.``/HP```X=L``K`0``*Q```"LA```K,```-B
+M=``"L(```]@!``*P```#W`$``K`2``*Q`@`"LA(``K,"``-B=``"L!```K$2
+M``*R$``"LQ(``V)P``-B1``"L0(``K,"``-B3``#8D@``T`L``/_```#_P``
+M`^@@``/H,``#8"P``^@```/H$```8=L``V`8``-@'``#P8P``\&<``/!K``#
+MP;P``C=S``(U=P``8=L``_\```*P```#W````K!```./P@`"P`\``]@```-`
+M&``"H-X``_!!``-`'``#0"T``_\```/4'@`#U%\``K\```/<\``"O\```XC"
+M``+/^``#V/```\0```/$$0`#Q"(``\0S``*U#P`"1&4``Z5F``*@W@`#\$,`
+M`K4/``)$=0`#I78``Z9"``.$2@`#IU(``X5:``/$1``#Q&8``L`!``+`!``"
+MPB,``L(F``/$%0`#Q#<``]0>``-"=0`#0G(``K\0``*A!``#\$8``J4)``/P
+M!``#P8P``\&0``/!K``#P;```J,)``/P0@`#P:P``\&P``-B<@`#0D8``J$F
+M``/P1@`"I2D``_`$``/!C``#P9(``\&L``/!L@`"HRD``_!"``/!K``#P;(`
+M`V)&``-"3@`"H14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#
+M\$(``\&L``/!L0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!
+MK``#P;,``J,Y``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.';
+M``*@P0`!UN(``T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD`
+M`_\```+)`@`#J9```LM&``.KL``"-W,``^P```-(G``#2*$``J#>``/P0@`#
+M2+0``TBY``/!&``#P5H``XF6``.+M@`"81D``F5;``*@W@`#\`0``VB<``-H
+5H0`#]````_!"``-HM``#:+D``^P`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TURKS_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_me.bin.uu
new file mode 100644
index 0000000..2eebbc6
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_me.bin.uu
@@ -0,0 +1,126 @@
+begin 644 TURKS_me.bin
+M?$"``*````#,@`!-@````-1``'\<C``"F,``"WQ!``#(#``.F,```P0\``7/
+MP:*DS```8,P!H?3,``!'@````-!``&#(#``0F,```P0\`"//P:*DS```8,P!
+MH?/,``!)@````-!``&#,``!&A```+<P``$O,02)DS$$B9<Q!(F:`````S$&B
+MW<Q``$:$```MS```2P04(F0$&")E!!PB9M@700#8&T$`V!]!`(````#,0:+=
+MP#H`!`0T(FL$,")<?WM`!\PU``#(/``$B````,_Q``!\0,``E,#_RLP``!^`
+M````S```07Q`P`#`%@`$'-#__WT5``?,$0``&-@`/A3<`!_((``$E<``!GQ"
+M0`#,``!-?E:`!\PI``#()``$?B8`!I6```9\0L``S```37[7``?,,0``R"P`
+M!'XN``?,``!-'1#__X````#.$0``?$#``(````#,0`!`S4$B7<Q``$7,``!*
+MS0$B7,Q!H?Q\0(``H````,R``$V`````S$$B5WQ!@`#,0`!%S$``2LQ!(ES,
+M0:'\?$"``*````#,@`!-S```18```&3,``!*P`X``<P``$7,``!*S$$B7,Q!
+MH?S43:']?$"``*````#,@`!-@````,Q!(EW,``!%S```2@A,``%\00``?$%`
+M`!U8__\97`/P%6``%<V!H0+-P2)6S@$B7)3```4A)``@SD&A_(```'L(S``!
+MS0&A_,P!H0)\0(``H````,R``$U\0(``?$#``,`J``)\00``?2D`!QR4``$<
+MF``&')P#`!7<``A\0@``?$)``)5```_`+@`$!?`B6'\O``?,,0``R"@`!,S!
+M(6G-`2%JSH$A:RFT``+,`2%LET``#BFT``"```"[R#0`#BFT``*70``)*;0`
+M`,`N``0%\")8?R\`!\PQ``#(*``$@```N\@T``Z70``$?@*``(```+O(-``.
+M*;0`!)=`_TL`````S@$A;<Y!(6[(*``#R#0`#IM```3(/``.A``#0\P``$TI
+M]```ET``!P0PHK:$``#=SH&BM\^!HL2`````S\&BT2GT``&70``'!#"BNH0`
+M`-W.@:*[SX&BQ8````#/P:+2*?0``I=```<$,**^A```W<Z!HK_/@:+&@```
+M`,_!HM,$,*+"A```W<Z!HL//@:+'@````,_!HM3`+@`$?R\`!\PQ``#(+``$
+MP#``!G[S0"/`,``@?VN`((@```!_L\`DS```0H````#,0``??$#``'Q!```9
+M%``]F4``$P04`"Z$``2=!!@`*80``F3('``3!!0`*H0`!)T$&``MS4&BI,@<
+M`!.5P```R!P`$\S!(0#-`2$!S,$A`LT!(0.```2:S8&BI!T8$`"5@``%R!P`
+M$RGD`$"60/__R!P`$\S!(77-`2%VR"``%)8```#((``4%B@``9J```3,``!/
+M@``$FLP``'^```$'S,$A=7Q`P`!\00``S```1<P``$I`U``#S4$B7,T!H?S`
+M'@`!?$(```C,``$&)``!!B@``LX=H?W.7:']F,#_^LZ=H?U\0(``H````,R`
+M`$U\0,``'-```13,``%\04``E0``!GQ!@`#-02%MS8$A;H```3/('``#P"(`
+M!'X6``?,(0``R!P`!'Q"0`"8P``$?$*``(````#-Y0``SD$A:<Z!(6K-P2%K
+M@````,P!(6Q\0,``?$$``'Q!0`!\08``?$'``!BD'^@J:``\EH``"GP"``!\
+M0@``.C```\P``%B;```#0B``!00@`$"```%/?`)``'X"0`":0```"F0``1SL
+M`!":P``*S```3<`J``3(+``@?I*`!\P``$',*0``SL``'H```5_(,``$S0$A
+M;<U!(6[(,``#?Q\`!AST``<3>``!ET``*@>X`62?@````````(```71_&X`.
+M@``!>'\;@`^```%\?QN`#(```8!_&X`-@``!A'\;@!&```&(?QN`$(```8T4
+MI``(FX``&12D``B```&='F0`_YN``!44I``(@``!G1YD`/^;@``1%*0`"(``
+M`9T>9`#_FX``#12D``B```&='F0`_YN```D4I``(@``!G1YD`/^;@``%%*0`
+M"(```9T>9`#_%*0`"!YD`/\J:``\FH#^<13L``A\0T``?$.``'Q#P`"6P``'
+MS```3<]!(6G/@2%JS\$A:X````#,`2%L@````,_U``#,``!9A``$G2IH`#R:
+M@``$R"@`%X````#40`!_EH#_JWX"0`"$``*6P`X``LP``$&```&KS,$P2I0`
+M``#(/``<?$#``'Q!``#`'@`!%20`$L`B``*60``%P"8`!,`G__M])0`&P"8`
+M`'W2@`9^$L`&?24`!WQ!0`!\08``S,$A:9J```S-`2%JS4$A:Y;`_D#-@2%L
+MA``$G<P``'_(,``:EP```,@P`!J````!?$"``(0`!)W,``!_R!0`%<@8`!;-
+M02%KEL#^,LV!(6R```'"S```?WQ`P`!\0(``%)0`$!%4``4<B/__$(@`!7Q`
+MP``4T``0',S__\`:``0%F!NDS!D``,@8``0=F`__?1D`$)D`_A]]C0`0F0#^
+M'<P``%C,``!9A``$G<R!(73(#``7E,#__\P``%F````!?$"``,P``^7(+``@
+MP`X@0`00,``@S")K!!0P`<P``$'0$0``S-4``,[``![(#``)F,```,@,``E\
+M00``?$%``,P``^?,``/HS``#Z<Q``$/,0`!$U$``?X````!\@,``?$#``!C0
+M`>@1*``!E0``$`:H`@F>@````````(```B'`$@@`@``"+\@4`!&```(VR!0`
+M$H```CW,P:*D@``"1ASH`#^```)N?,&`"QS0`#\I*``&*2P`%GZN@`?('``3
+MFH``/004`"Z`````S,&BI,`2"`!\04``?0S`!\`2``@56``#%5P`#'Q"``!]
+MT<`&$B``%'X>0`=^3H`'SH&BI(````#-@:'^R!0`$000(1B50```R!0`$=11
+M``"`````S,&BI,@4`!($$"$&E4```,@4`!+440``@````,S!HJ3,P:*D!!``
+M`<T``!F$``2=S```?\@0`!N9````R!``&X````%\0(``*J``!"JD`!1^)@`'
+M!!0`+I8```@$&``IA``"9,@<`!,$%``JA``$G00,`"W-0:*D!!`A`,@<`!.5
+MP```R!P`$]11``"```2:S,&BI(0`!)T$&``IA``"9,@<`!,$%``JA``$G008
+M`"V$``)DR!P`$X````%\0(``E<```,@<`!/-0:*DS`$A`,P!(0'-@2$"S8$A
+M`\V!HJ2(````S```31V8``%\00``?$%``)F```E\0@``R#P`,A&8`!#('``+
+M._P``9?`___(/``R@``"@,@\`#,1F``0R!P`"CO\``&7P/__R#P`,Q5H`!U]
+M64`'FH``!!'D``I^)@`'S<``9LT!(5C-02%9S@$A6LS!HJ2:@`(0!1``!`0L
+M``$2\``=?7%`!Q+@`!`B(``,S0$A6,U!(5G.`2%:@``$FLS!HJ0$/``%S\&B
+MI,`V``*(````ST$@$'Q`P``4T``=F0``"!34`!R50/UAP"8`!")D(53,)0``
+M@````,@H``2```2:S4``880`!)T<=``!''@``IM```/(#``IA``#0L@4`"N;
+M@``#!!``$(0``U+,P:)0S0&@4(0``P\$&`0`A``$G<P``&/(/``MA``#'<@0
+M`"G('``O'=P``<@D`">5P``)R#0`,<@X`##(/``M4W0`('^W@"='N`50S```
+M8L_Z``":0```R"0`)\@H`",ZJ``"FH#__\@H`"/`,``!R"@`))J```#(*``D
+MSP``6U#8``@4W``8P#X0`"'<@`!]_<`'S8$A@,W!(8'`'@`@42``"!4D`!A^
+M?D`'$S``'GYR0`=]74`'S@$A@LY!(8/-02&$?$"``*````#,@`!-A``$G1QT
+M``$<>``"FT```\@,`"J$``-"R!0`+)N```,$$``0A``#4LS!HF#-`:!@A``#
+M#P08"8"$``2=S```9,@\`"Z$``,=R!``*L@<`"\=W``!R"0`*)7```G(-``Q
+MR#@`,,@\`"Y3=``@?[>`)T>X!53,``!BS_H``)I```#()``HR"@`(SJH``*:
+M@/__R"@`(\@H`"6:@```R"@`)8```M#`,``"!9C``!#<``@4X``8S=D``,@<
+M`"+()``B'=P/_\W9``%^8D`'SED``M@840/8&%$$B````-@840<;^`#PP#8(
+M`)>```/`,`"`B````,`J``3/02%\SP$A?<T!(7XBJ"%_!"0`")I````*9``!
+MS"D``,@@``06.``?FX#_^P0D``B(`````````,@D`"1\00``FD```,@D`"2`
+M```!?$"``,@D`"5\00``FD```,@D`"6````!?$"``(0``T)\0,``?$"``*``
+M``#,@`!-R#P`#I?```/3``/FB`````0\``7/P:*DS`&A](0`!)W,``!'B```
+M`,P``'^$``-2?$#``'Q`@`"@````S(``300\`"+/P:*DA``$G<P``$B(````
+MS```?X0``UU\0,``?$"``*````#,@`!-!#P`(\_!HJ3,`:'SA``$G<P``$F(
+M````S```?X````!\0,``@````'Q`P`#`$@`!?%%`!X````#450``S$``9<@X
+M`"W(/``NP#7@`,`R``1_MX`&?_?`!B.X$``C_!``SX$A5,_!(57,,2%5R"P`
+M!,@<`"7()``D?>7`!YG`__[('``E@````7Q`@`!\0,``?$$``!DH`#"6@``(
+MR"@`)\@D`"B:0```R"0`)YI```#()``HS``#X'Q!0`!\08``%1P`'\S``,?-
+M``#(E<```\`<@`#-P2`0X8,```5<(`#,``!-@````-P?00!\0,``?$$``'Q!
+M0`!\08``S,``R<T``,KA@P``!5R@`(````#<'T$`?$#``'Q!``!\04``?$&`
+M`,S``,O-``#,X8,```5<Z4"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#-
+MS0``SN&#```%7.B`@````-P?00!\0,``?$$``'Q!0`!\08``S,``S\T``-#A
+M@P``!5S``(````#<'T$`?$#``'Q!``!\04``?$&``,S``-'-``#2X8,```5<
+M\`"`````W!]!`'Q`P`!\00``?$%``'Q!@`#,P`#3S0``U.&#```%7//\@```
+M`-P?00#40R``?$"``*````#,@`!-U$.@`'Q`@`"@````S(``3=1#Z4!\0(``
+MH````,R``$W40^B`?$"``*````#,@`!-U$/``'Q`@`"@````S(``3=1#\`!\
+M0(``H````,R``$W40_/\?$"``*````#,@`!-!!R@`,Q#H`!\0,``V!_!`'Q`
+M@`"@````S(``300<P`#,0\``?$#``-@?P0!\0(``H````,R``$U\0,``?$$`
+M`)3```-\04``?$&``,P#\_S,0_/\S$/S_'Q`@`"@````S(``3<`>`!#(#``I
+M4-``"!!4``*```05?16`(,`>`"#(#``J4-``"`A4!``15``"?5&`(,W``&+4
+M6@``?$"``*````#,@`!-?$#``!S0``,1*``!E0``"@:H!!^>@```?$&``(``
+M!"U\0<``@``$,WQ!P`"```0Y?$'``'Q!@`!\0<``%-0`$`54H`"`````S94`
+M`,`B``0%F*``?:&`!\P9``"```0IR!@`!,`B``3-@276(B`EU\PA``"```0I
+MR!@`!,V!(6W-P2%N@``$*<@8``-\0,``@````,Q,`^`<C/__U$T``'Q`@`"@
+M````S(``3<@4`",Q6``$E8#__\@4`"/,``!;S$$A@"!,@`#,P2&!%-``'\Q!
+M(8+,02&#E0#[L,Q!(83(%``CF4#__\@4`".````!?$"``,`6``0A5"%`S%4`
+M`,@8``2`````S``#X'Q`P``8T``XP!8`@)4```/`*@`$?-3`!\S!(7S,02%]
+MS$$A?GQ!@``4_``?'9C__SFP``,BH"%_FP```T&<``4$'`!`F<````G<``',
+M(0``R"0`!!9L`!]!G``%FL#_^LR``$V;P/N*`````(````#,``/@?$#``'Q!
+M```5&``?410`()F```L9'``QS0``8GU-0"?45@``E<#[?<@@`"::````R"``
+M)H````%\0(``X#H``,`F``3,P2%I?24`!\T!(6H+N``"S$$A:YN`__[,02%L
+MF<#],,P``'^````!?$"``,`.`0#,``!!S,$P2L@\`'_,``!_@````,P``'_,
+M``!_B````,P``'\`````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````01``!```P`2
+M``4`%0`:`!8`(@`7`#4`(0`Z`"0`5P`E`%<`)P!A`"@`5``I`&(`*@!?`"L`
+M8@`M`&D`+@!L`"\`=0`P`'<`,@#H`#0`C``U`&(`.0#J`#H!$@`[`24`/`$]
+M`#T!K0`^`=(`/P#G`$$$10!"!%<`0P1=`$0![0!%`3T`1@($`$<"!`!(`@0`
+M2@*;`$L#9`!,`J<`30+E`$X#,0!/`S<`40-8`%(#/0!3`TT`5`-F`%<#:`!@
+M`X``80.8`&(#;`!C`Z(`9`.L`&4#M@!F`\``9P/*`&@#U`!I`]@`:@0)`&L#
+MW`!L`^``;0/D`&X#Z`!O`^P`<`/D`'$$#P!R`_X`<P/P`'0#]P!U!!H`?00]
+M`'H$>@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`
+M#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/!)8`#P26``\$E@`/
+.!)8`#P26``\$E@`/!)8`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/TURKS_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_pfp.bin.uu
new file mode 100644
index 0000000..6d902c1
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/TURKS_pfp.bin.uu
@@ -0,0 +1,103 @@
+begin 644 TURKS_pfp.bin
+M?$"``*`````$*``!@````.`#``#,@`!`U$``0'Q`@`"@````!"@``1!,``&8
+MP``%')```LQ``"F```-?S$``*ID```4`````S$``*X```U_,0``LS$``+8``
+M`U_,0``N'(P``LR``$"8P``$S$``0(```U_,``!2@``#7\P``%2`````S$`#
+M_<@0`"[(#``M41``('S0P"=\Q0`@510`(,T``$/-0`!#T,``0\R``$#,``!`
+MS$``0'Q`@`"@````!"@``<@0`"S(#``K41``('S0P"=\Q0`@510`(,T``$+-
+M0`!"T0``0GQ`P`#(&``#R!P``\@@``.5@/_"R"0``Y7`_\#(*``=FH``!,P`
+M`%78``/`S```0,@H`!;`+@`$R#``#1JH`"=^\L`'SL``0,P``$#-@`!`S<``
+M0,X``$"6@``#SD``0-"``%S,@`!`S```0,S``$!\0(``H`````0H``'($``L
+MR`P`*U$0`"!\T,`G?,4`(%44`"#-``!"S4``0M%``$)\0,``R!@``\@<``/(
+M(``#R"0``Y6`_YG(*``#E<#_E\@L`_U^+P`1EP```W[BP`%\`L`&SL.BGLP`
+M`&S-``!MS4``;<@P`!V;```$S```5=@``\#,``!`R"P`%L`R``7(-``-&NP`
+M)W\W``?/``!`T$``0,V``$#-P`!`S@``0,Y``$"6P``#SH``0-"``%S,@`!`
+MS```0,S``$!\0(``H`````0H``'(&``5'9@``7Q"0`"5@`+.?$*``,@<`"#`
+M-\``?$#``'Q!``!\M(`&P#8``QJX`>B7@``'T$`#X(0``V+,``!_R#@#X)N`
+M``#(.`/@F<```,@<`"!\M(`'$-0``GUE0`#-0`!#SH``0\T``$/,@`!`SD``
+M0,Z``$#,P`!`X#H``)>`_U3-``!`?$#``(```*)\00``'(P``IC```G($``<
+MF0``!,@<``:$``-ES```4L@8`!6```".'9@``L@0`!Z9`/_\R!P`"(0``V7,
+M``!4R!@`%8```(X=F``"'(P``L@0`!V8P``.R!0`29D```3('``'A``#9<P`
+M`%/(&``5E,```QB4`>@%5``&(!```7T5``.```".?9&`!IE`__C('``'S<``
+M0,P``$"```#+S```;L`.@(#,``!G!-"`@,P``&C-``/QS0`#\LT``_/-``/T
+MS0`#]LT``_?-``/X@```!<T``_G,@`!`U$``0'Q`@`"@````!"@``8```.[8
+M``1`V``#0,P``$#,@`!`U$``0'Q`@`"@````!"@``=@``\"```#[S```0(``
+M`/K8``1`V``#0,P``$#(#``IR!``*LR``$#,0`!`41``('S0P"<04``"?0T`
+M(%44`"#-``!#S4``0]!``$/,``!`?$"``*`````$*``!V``#P,P``$#,@`!`
+MU$``0'Q`@`"@````!"@``1R,``+($``=F,``$<@4`$F9```$R!P`!X0``V7,
+M``!3R`P`+\R``$#,0`!`S$``0,Q``$!\Q,``S,``0-1``$!\0(``H`````0H
+M``&90/_UR!P`!\W``$#,``!`@``!&LP``&Y\0,``R!``1YD```O(%`!$F4``
+M!,@8``G-@`!`S```0(```43,@`!`?$#``,@0`$>5`/_WR!0`19E```3(&``*
+MS8``0,P``$"```%$V``(0'Q`P`#($`!'F0#__`````#,@`!`S,``0-1``$!\
+M0(``H`````0H``'($`!&V``'0,T``$"$``%;S0``0,@,`$.4P``*R!0`2(``
+M`50$$``#R!``1M@`!\#-``!`A``!6\T``$#(%`!(G4```,P``&K(*``6'J@`
+M`9J```/`*0`!B````,`L`5;.@`!<V``(P,[``$"(````S```0!R,``+($``>
+ME,``",@4`!R9```*R!P`"(0``V7,``!4@``!=<R``$"90``$R!P`!H0``V7,
+M``!2S(``0(````#40`!`S$``)\Q``"B```-?S```:\`R``/`-___@``!@'RP
+M@`=\0T``R"``*,@<`"?(&``FST.BGGQ!0`!2(``@?>'`)WU8P`-\W,`@5-``
+M((```97,@`!`?$&``,R``$"```&2S8``0,`9___,@`!`S8.BGGQ`P`!\00``
+M?$%``,S#H?K-`Z'YS4.BG<S``$#-``!`S4``0,Q``$!\0(``H`````0H``%\
+M0,``'-```<S#HI^5```#T$``)M"``";,@`!`@````,S``$!\0,``S(``0,S#
+MHJ*`````S,``0'Q`P``4U``?S(``0)5```-\00``S,``6148`!_,P`!`E8``
+M`\T``$#-``!:@``#7\P``'_((``??$$``-@@`D3.(`!$?$%``'Q!@`#-H`!)
+MS2``0<U@`$'-H`!!%1``"!%4`!A]4\`'S\``+P8@``'.``!8@``#7\P``'_(
+M(``?R@P`%Y3```5\00``V"`"QH```;_.(`!&S```2(```=4`````R"``'WQ!
+M@``*(``!RA0`&LH8`!=]68`'E8``!<X``%C,H`!&@````,U@`$;,H`!$@```
+M`,U@`$2```-?S$``:L@,`_J8P``+T$`#^L@8`$+('`!#R!``'<@4`!P1$``!
+MF8#_6WT5``>9P/]C`````-```_J`````?$#``,R``$"`````U$``0'Q`P`!\
+M00``?$.``'Q#P``$'``"SX``0L_``$+-P`!"!!P`",S``$+-``!"S<``0@0<
+M``$$(``!?`)``,@4``/(&``#49@`('U90"?(*``#R"P``\@P``/(-``#4NP`
+M('ZN@"=3=``@?S<`)W\K0"%^=D`@5J@`/U<P`#]^LH`&?BH`!IG`__()W``!
+MEH#_X5/T`"!_>T`G?65`(%58`"#,``!;S78``,VV``#((`!!F@```,@@`$&`
+M```!?$"``'Q`P`!\00``S,`#_LT``__,P`!"S0``0A44`!\9&`#P)UP``7UV
+M``:9@``%?5Y`!LP``$*```-?S```3168``$5+``(F8``,1[L``&6```$%3``
+M#(```U_,``!"!!0`",U``$(?,``!("@``00X``@$/``!R!0``\@8``/('``#
+MR"```WU=0`U]H<`-?5U`!Q80`!\5G``??1T`!GT70`9^DH`&FT``$@NX``2;
+MP/_R"_P``<@,`_Z:@``)R!`#_YL``0;,``!-!!0`",S``$+-``!"@``"0\U`
+M`$*6P`#_S```38```U_,``!.FL```\P``$W,``!.EX#]F>.#``"`````W`,!
+M_Y9```3,``!.@``#7\P``$+2``!"R`@``\@,``/($``#R!0``\@8``/('``#
+MR"0``\@H``,5_``?%K``'W_SP`84\``??_/`!A5P`!]_\\`&?8B``9?```U]
+MS,`!?E$``7Z50`%\D(`,?-3`#)K```-\CT`&)+0``9M``-;,``!-@``#7\P`
+M`$[(#`/^R!`#_\S``$*```)OS0``0GQ`P`!\00``?$+``'Q#``#`.P`??$-`
+M`'^W@`;`/A``EX#]9GT]``=_/P`'&10`.\P``%N50``3R!0`0#%8``*5@/__
+MR!0`0,P``&,A'(``S,$AA<W!(885%``?SL$AA\\!(8B50/U5ST$AB<@4`$"9
+M0/__R!0`0(````%\0(``S(``0,S``$#-``!`SL``0,\``$"`````ST``0-"`
+M`^#,@`!`A``#8LQ``$#(#`/@F,```,@,`^!\0(``H````'Z"@`9\0,``A``"
+MS!30`!^9`/TZT$`#X(0``V+,``!_@``"OL@,`^#,@`!`S,``0(@```#40`!`
+MS(``0,Q``$#,0`!`S$``0'Q`P`#,P``AS,``0-1``$#`-___T``#^]```_S0
+M``/Z@````,]``_U\0,``%-P`'9G```?,@`!`&-P`/)G``'S,P`!`@``#7\P`
+M`&H8V``\S8``9LP``&J```-?S,``0'Q`P`!04``@A``#8LP``%U\T,`GR"``
+M'\C6``"90``(?$.``..#``#/H`!/A``#8LP``%Z`````U$``?X```U_,``!>
+MA``#8LP``%W((``??$#``,`V_P#($``AP#`__WSU0`9]48`&?8&`"IF```A\
+M\X`&XX,``,^@`$^$``-BS```7H````#40`!_@``#7\P``%Z$``-B?$#``!3<
+M``B5P``9'-P`$'Q!``"9P``$4%0`((```QW)'0``?14`)\D>``!\0@``?$)`
+M`'Q!@`!]Y<`&?>*`$9J`_-Y!K``%FL````KL``$<W``0F<``!`````"```,@
+MR1T``(```R#)'@``S(``0,S``$"`````U$``0-@``T#,``!`S(``0-1``$!\
+M0(``H`````0H``'8``/`S```0,R``$#40`!`?$"``*`````$*``!?$#``!S0
+M``8I$``&F0``!L@4`!R90``$S```4H0``V7('``&S(``0,S``$"`````U$``
+M0'Q`P`!\00``%1@`'\T``%N9@``$410`((````#430``?4U`)QD<`#'45@``
+ME<#\J<@@`$&:````R"``08````%\0(``@````-1``'_,``!_@````,P``'_,
+M``!_B````,P``'_-P`!`B````,P``$``````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"``,``P,Q``0#.``%`;L`!@#M``<`^0`(`0L`"0#T``H`ZP`+`/<`#`$K
+M``T!-0`.`4D`#P%3`!`#70`1``H`$@`8`!,`(``6`"(`)``Q`"4`60`F`7<`
+M%P'7`!@!Y0`:`><`(@+L`","_0`G`8P`'P'Y`"`"*0`H`:X`*0%[`"H!H``K
+M`9``+P&I`#(!S0`T`S\`-0%_`#D!]@`\`Q$`/P&[`$$"D@!"`KD`0P+#`$0"
+MT`!*`MX`50,S`%8#.@!@`(P`80"Q`&(`V0!C`,,`9`##`&4`PP!F`,,`9P##
+M`&@`Y@!I`.\`:@$_`&L!#0!L`0T`;0$-`&X!#0!O`0T`<`$2`',`^P!T`/L`
+M=0%F`'L#3`````4````%````!0````4````%````!0````4````%````!0``
+M``4````%````!0````4````%````!0````4````%````!0````4````%````
+9!0````4````%````!0````4````%````!0``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/VERDE_ce.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_ce.bin.uu
new file mode 100644
index 0000000..89b637f
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_ce.bin.uu
@@ -0,0 +1,194 @@
+begin 644 VERDE_ce.bin
+M?$"``8@```#40`!_?$"``8@```#$(``+Q@P`!93``"0D4``/,10``I5```3,
+M0``DS$``)8`````Q%``#E4`!.\Q``";,0``G@````,0@``O,(``%?$$``5!4
+M`"!\08`!!B0``<Y````5G``8?14`&LW@``K-H``,T2```\V@``.:```$Q"0`
+M$II```(AW``P@``!3,0@``O&#``%'*@`$)3```/.H``'@```%<P```G$)`!_
+MQ"``"WQ!@`$*(``!QA0`",88``5]68`*S@```)6```/,(``'@````,P@``6`
+M````?$#``130`!XQ%``"E4`!#AC0`>@8U``P&-@`-`4H`$1\0@`!?$)``94`
+M``>&@```@``!4(```5"```%0@``!4(```%(15``0?A8`"LU``!'480``E8#_
+MLL0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``!'48@``E8#_J<0@``Z:`/__
+M?$"``8@```!\0,`!%-``'C$4``*50`#K&-0`,!C0`>@8_``T),P`#P3H`&A\
+M08`!?$'``93``!*&@```@```<H```5"```%0@``!4(```&^```%04=P`('V>
+M`!J```!_4=P`('V=@!J90``#Q:(``(```'_)H@``@```?\6A``"50``%!9@`
+M`<6E``!29``@?B8`&@4H`(-\08`!?$'``94```>&@```@``!4(```5"```%0
+M@``!4(```)/8```1SAD``)5```0%F``!5B``(,X9``"7P/]QQ#DA0'Q`@`&(
+M````4=P`('V=@!K8```1SAH``)5```0%F``$5B``(,X:``";P/^]?$"``8@`
+M``#8``/VV``#]=@``_38``/SV``#\M@``_'8``/PV``#[]@``^[,0`!_S$``
+M?\Q``']\0,`!S,```=1``'^`````?$#``5!0`"",``#+?-#`&L0@``O$U@``
+M?$.``<0D`!.:```)V&0#],9K`_&:@/__QFL#[@:H``'.I`/NS60#Z]@D`_29
+M0``)WX,``,^@``Z,``#/U$``?YH`_SS&<P/NFP#__X````",``#/?$"``8@`
+M``#8```"Q#P`#9O``(.0````V$```L0\``V7P`!_D````-@``!)\0,`!4%``
+M(,0\`!`G_``!E\#__GS0P!K0P``4S$``%<00`"%\4,`!S,``%M@``!.`````
+MQ!``(7Q0P`',P``7U$``&(````#$$``A?%#``<S``!?$$``@?%#``<S``!F`
+M````Q!``(7Q0P`',P``:S$``&WQ`P`%04``@?-#`&M#``!R`````S$``(=@`
+M`"*`````?$#``5!0`"!]#4`:V$``*<@8`!U]E<`/E<#__M@``"F`````?$#`
+M`<@0`!W(%``>?16`#IF```_80``IR!``'7U1@!)]C<`/F<#__=@``"E0X``!
+M?A9`#II```1]8H`2TH``(X````#0```C@````-B``"G$/`!_S```(-A``"C$
+M#``<F,#__]@``"A\00`!4%0`('T6`!K2```>V$``'8````#,```@V$``*,0,
+M`!R8P/__V```*-```![0```?V$``'7Q!``&`````?$#``7Q!``$5&``?S0``
+M$5$4`""9@``#U$T``(````!]34`:&1P`,=16``#$(``.E<#^R,0@``Z:`/__
+M@````'Q`P`%\08`!%-``'C$0``(DU`#_E0#^O\V4`P"`````Q"``$WQ`P`'$
+MTP,`S```$<TA(4&`````U$``?X````#$)`!^ED```WQ`@`&(````@``!4```
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0`"`!`!2@`1``4`&0`M`#$`)0`S`!,`@`#3`($`X0""`.8`@P#M`#<`
+M.0!``%P`1`">`(0`]@"'`/D`B`$"`(D!%P!]`3P`?@%$`'\!+``B`*X`BP$B
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+M``(````"`````@````(````"`````@````(````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/VERDE_mc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_mc.bin.uu
new file mode 100644
index 0000000..2797c58
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_mc.bin.uu
@@ -0,0 +1,694 @@
+begin 644 VERDE_mc.bin
+M``/HX``"O@$```('``/_```#_P```J`.``'`&0`#Z````^@0``/H(``#Z#``
+M`V`@``-A2``",;@``TEL``-("@`#KPH``K0$``)O]```^BT``K0/``)/%```
+M^@H``ZB,``#"`0`#0"0``K1```*U#P`#2J8``D1!``/P`@`"294``VJF``-*
+M40`#0"0``K@"``*Y_@`"1)0``DB!``.H@``"9$@``VI1``-`)@`"OX```KP$
+M``))^0`#\$(``_0```'`00`"OX```TA4``*X#P`"N?```D$8``)"*0`#:%0`
+M`TMI``/`C``"9$P``VMI``)$2``#:VD``F$?``)B+``#:%0``BP%``-+3``#
+M_P```V%$``-+'``#0"H``K3\``-A0``"0S0``F$>``-K'``"2JX``_!&``-)
+MU0`"O!```DS'``/P0@`"O"T``C)S``-`)``"M$```K7P``-*I@`"1$$``_`"
+M``)IE0`#:J8``T````/_```#^`$``\1```/$40`"QD4``@````-`$``#_P``
+M`_\```/H(``#Z#```V`0``"1Y0``D@T``_@#``(POP`",;(``T@(``*TGP`"
+M0`0``V@(``-(P``#2,8``K3\``*U#P`"010``DF4``)")0`"2J4``D,U``)+
+MM0`#:,```VC&``-(```#2`4``KL_``*\OP`"O^\``)(E``"*)@``@BH``+HH
+M``"J+``"01L``KO[``)`#``#:````KS^``)%7P`"1WP``V@%``-($``#2=T`
+M`KOQ``*\`@``BBD``*HK``)!&P`"81P``V@0``)%6P`"95P``VG=``-`#0`#
+M_P```_\```.A3```B?\``K,"``)#-``#HS```)G^``*S!``"0S0``Z,R``"9
+M_0`#0"D``T````*\(```N<<``D(L``/P!P`"L````((Q``(Z,P`#Z````('E
+M``/T```!PEP``T````*\(```\C$``D,\``/P!0`".C,``^@```"!Y0`#]```
+M`<)<``-((0`"L\$``D=S``-H(0`#:HD``T@E``*SP0`"1W,``V@E``-JC0`#
+M2"D``TEP``-`$@`"OP<``D`/``.````#``X``Z^(``-)U@`"O!```DS+``/P
+M00`"P`\``X0&``.%5@`#I58``F54``)D0``#2>@``V@I``-H+0`#P00``\$5
+M``-IZ``#:>P``TK"``*_P``"2(\``VK"``-JQ@`#Z````^C0``(NE@`#:.0`
+M`\'>``(NE@`#:00``^A```*]```",@(``KT!``(R`@`#0"P``_\```*T`@`"
+M1`0``*()``-)U@`"M1```D1;``.D1@``H@L``J!.``/P`P`",[<``_0```'!
+M!0`#]````=)]``*\```",CT``T`.``#R,@`#Z/```Z"V``-)U0``^@0``K$/
+M``)"%P`"I2```_`!``#Z,@`"0QL``J4C``/P`0``\@0``T````-`+@`"MA``
+M`K0,```J,@`"0B0``Z(B``)#-``";",``D9H``/P`P`"H%X``_`!``/HP```
+MX@,``T`(``*T````>@0``J`D``/P00`"L@@``J#^``/P00`"L@0``K0_``)"
+M)```DAH``TJ4``/_```#88```T````/_```"M$```D0$``/P`P`#Z````((Q
+M``(BX``#0````_\```*T0``"1!0``_`"``#R,0`"(N```T````/_```"M$``
+M`F$0``)$%``#\`$``BSW``-*E``#_P```V&$``-````#_P```K0"``)$)``#
+M\`,``^@```"",0`"(PP``T````/_```"M`(``D0T``/P`@``\C$``B,,``-*
+ME``#_P```V&(``(QL@`#0````_\```/_```"1`X``_`#``/H````@C$``B0;
+M``(QL@`#0````_\```/_```"1!X``_`"``#R,0`")!L``BTN``-*E``#_P``
+M`V&,``-````#_P```K0"``)$0``#\`L``^@```"",0`")@<``T`L``/_```"
+MM"```D1```/P`P`#Z````((Q``(Q*0`#2I0``_\```-AD``#0````_\```*T
+M!``"1$```_`#``/H````@C$``B?3``-*E``#_P```V&4``-````#_P```K00
+M``)$0``#\`P``^@```"",0`"*'H```'_``/_```#_P```J0.``/P!```\@``
+M`BAZ``/H````@@```TJ4``/_```#89@``T````/_```"M"```D1```/P`P`#
+MZ````((Q``(J"@`#2I0``_\```-AG````@,``_\```*T`0`"1`0``_`$``/H
+M````@C$``\'^``(JO````@,``_\```*T`@`"1`0``_`$``/H````@C$``^CP
+M``(JO``#0````_\```/_```"1"X``_`#``/H````@C$``C?1``-````#_P``
+M`K00``)$)``#\`,``^@```"",0`"./4``_@#``-*E``#_P```V%@``-````#
+M_P```K0"``)$00`#\`H``/(Q``(F!P`#0"P``_\```*T(``"1$```_`"``#R
+M,0`",2D``TJ4``/_```#860``T````/_```"M`0``D1!``/P`@``\C$``B?3
+M``-*E``#_P```V%H``-````#_P```K00``)$00`#\`L``/(Q``(H>@```?\`
+M`_\```/_```"I`X``_`$``#R```"*'H``^@```""```#2I0``_\```-A;``#
+M0````_\```*T(``"1$$``_`"``#R,0`"*@H``TJ4``/_```#87````(#``/_
+M```"M`0``D0$``/P`P``\C$``\'^``(JO````@,``_\```*T"``"1`0``_`#
+M``#R,0`#Z/```BJ\``-````#_P```_\```)$/@`#\`(``/(Q``(WT0`#0```
+M`_\```*T$``"1#0``_`"``#R,0`"./4``TJ4``/_```#870``_@#``-````#
+M_P```K0(``)@`0`"1`0``_`,``-("``#_P```K1```)@!``#:`@``TF8``*T
+M_0`"010``VF8``/H,``#P2X``V@P``(Q1``#Z````^@0``/H,``"L@,``V@P
+M``-````#_P```K6```)A$``"114``_`!``(W,``#2I0``_\```-A>``"O`$`
+M`C(]```",@`#_P```_\```*A#@`#\`(``^@```""!P`"+2X``T@```-(!0``
+M"B8```(J```2)0``*BP``#HH``/_```#:````V@%``-($``#2=T```HI```J
+M*P`#_P```V@0``-IW0`#27$``K(!``/H,``#P08``\$7``-H,``",40``^@`
+M``/H$``"L@,``K,```-H,````@L``_\```/_```"H`X``@*!``/T```!P```
+M``'E``-`$@`#0!4```H-``*@#@`#\`(``_0```'"G``"P1X``(H-``)KN@`"
+M95L``L9N``/P00`#!FX``V`5``*R#P`"1$(``J44``/P!P`#Z*```^BP``-@
+M$@`#Z````('E``/T```!P&L``T`L``/_```"M"```D!```/P`@`#]````<*H
+M``/H````@C$``C$I``#R,0`",2D``^@```"",0`",%X``/(Q``(P7@`#23T`
+M`TC```*V"``"1F0``_`"``*U,``"8B4``VC```-HQ``#2QT``T`H``*\$``"
+MOP0``DS```/P!0`"9W\``VL=``(Q1``"9WX``VL=``-`(``#_P```_\```+"
+M+@`#\$0``L,^``/P0@`"LO\``K/_``-@(``",;(``TE(``-`*@`"M#\``K6`
+M``*V0``"1F@``_!%``)#-``"8S4``VE(``)#-``#:4@``^@```/H$``#Z"``
+M`^@P``-DI``#9.0``_0```'````#0`0``&HQ``/H@``#Z)```^B@``/HL``"
+MH-X``_`#``-DJ@`#]````_!!``-DZ@``8>D``J#>``/P`P`#Z$```_0```/P
+M00`#A.H``]A```/<P```>>@``_@#``/4G@`#^P```P_^``("]P``(<,``J#>
+M``/P`P``8<(``_0```/P00``8<$``K\(``/<0``#V,```_@#``/4G@`#^P``
+M`P_^``(#!@`#^`,``^P````",@``:C$``_\```*@#@`#\`$``^P```-).``"
+MH-X``_!!``-).``"N/X``D(H``-I.``#2=```K0$``)A%``"L@$``K,2``*@
+MW@`#\$$``K,1``-H,``#27$``KCO``*Y!``#P08``F%Y``)#.``#:#```T@)
+M``*X_0`"1$@``V@)``(M"``#2:```K01``/!)``"L0\``VF@``-*1``"M/X`
+M`F$>``-J1``"010``VI$``*@W@`#\`,``T)A``/T```#\$$``T)=``/_```#
+M_P```^A@``-II0`#:&L``KH,``*XP``#W($``]BA``*P^``"L0<``^@@``/H
+M,``#_@```]0?``-H:P`#Z/```B/)``(CL@`"(]X``J'^``/P00`#8GH``T)X
+M``/_```#_P```J"```'#9P`"H)$``<-G``*@H@`!PV<``J"S``'#9P`"S_X`
+M`KP,``*A_``#\$(``_0```'#40``^<X``^CP``(CL@`"(\D``B/>``-">``#
+M_P```_\```*@@``!PWT``J"1``'#?0`"H*(``<-]``*@LP`!PWT``L_^``*\
+M#``"H?P``_!"``/T```!PVH``&'.``#YQ0`#_P```J7/``'#C0`"I?P``<.(
+M``/H\``#Z,```_0```'#D``##,\``ZS```/H\``#]````<.0``,/_``#K_``
+M`^C```(CR0`#P?P``B.R``-).``"H-X``_!!``-).``#_P```F(N``-I.``#
+M2=```K3[``)!%``"L@$``K,2``*@W@`#\$$``K,1``-H,``#27$``KCO``*Y
+M^P`#P08``D%Y``)#.``#:#```T@)``*X_0`"1$@``V@)``*P&``"(_T``BTN
+M``/L```#P0\``\$?``/!+P`#P3\``J#>``/P!0`#9+```V2T``-DN``#]```
+M`_!#``-D\``#9/0``V3X``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#
+M:,@``^P```/!#P`#P1\``\$O``/!/P`"H-X``_`$``-DK``#9+P``_0```/P
+M0@`#9.P``V3\``-(R``"M/,``K4$``)`!``"8`4``VC(``)`!``#:,@``^P`
+M``*P$``"(_T``TH<``(D#0`#P8P``TH@``(D#0`#C,8``FB,``-*)``")`T`
+M`\&<``-**``")`T``XS&``)IG``#2BP``B0-``/!K``#2C```B0-``.,Q@`"
+M:JP``THT``(D#0`#P;P``THX``(D#0`#C,8``FN\``/L```#:&L``KD(``*X
+MP``#W(```]B0``/H$``#Z"```^@P``/^```#U!X``VAK``/!CP`"OQ```BT$
+M``/!^``#[````^C```.'/``#IW8``X8L``.F:``#A1P``Z5:``.$#``#I$P`
+M`FS'``)LQ@`";,4``FS$``/L```#0"0``&HQ``/_```#H`8``J$.``/P`0``
+M@?D``TFA``-)I``"NT```KJ_``)%I0`"H-X``_`#``)#HP`#]````_!!``)C
+MLP`#::0``VFA``(R8``#Z````^@@``/H,``"H-X``_`#```)^P`#]````_!!
+M```)^@`"N,```VAK``/8```#W(```]0>``*_"``"+00``X#@``"!]@``@?4`
+M`^@```"!]```@?,``/'R``-(5``"H-X``_`#``.$Z``#]````_!!``.$Z@`"
+M8B0``VA4``-)=0`#B.8``F!H``/!%P`#P2X``\$^``*@W@`#\`$``X,P``-H
+M,``#2%0``J#>``/P`P`#A.@``_0```/P00`#A.H``\!$``)")``#:%0``&(+
+M``*_`@`"+00``J#.``/P`@`#]````@2#``(NJ``#Z'```X3F``)&2P`"H&0`
+M`_!*``-)T@`#Z&```XJR``.JJ@`"H:X``_`"``,!K@`")?<``_0```'%(@`"
+MOP@``D_Y``.O]``#B[(``ZN\``(E.P`#]````<4B``-`#``#_P```K\(``)/
+M\``#\$(``_0```'$E``"OP```KL!``(E.P```@0``_\```/_```"H`X``_!"
+M``/T```!Q2(``/'T``#Q\P`"H-X``_`#``!Y^``#]````_!!``!Y]P`#C>(`
+M`]S0``/8\``#B>8``FF>``#QXP``0?D``^C0``./X``#P:@``XSM``#AYP``
+MXC```BX1``*W`0``0?D``^B@``#1XP`"H'X``_`!``.H@``##]\``\'9``/!
+MJ``#C.T``.'G``#B,``"+A$``BY2``/!!``#P28``V)P``*_`0`#0!$``XC@
+M``*@_@`#\`0``D1(``/P`@`#]````@4(``*W`0``0?D``_\```*@?@`#\`$`
+M`ZB```/HT``#C^```\&H``.,[0``X><``.(P``(N$0`"+E(``T)P``.,ZP`#
+MC.H``^CP``+(0``#J(```"H)``+*8@`#JJ```J9>``($Y0``:C$``/()``/!
+M6``#P7H``V)Q``/T```"!)\``J%>``/P#@``:C$``\&1``/!LP`"H-X``_`#
+M``-A+@`#]````_!!``-A,@`"P($``Z@```+"HP`#JB```X50``"J"0`#@>``
+M`P"$``/P)``"H80``_`!``+$00`#!$X``\%4``,"I@`#\"0``J&F``/P`0`"
+MQF$``P9N``/!=@`#U%X``F`"``($]P``:C$``K\"``(M!``#27$``X'D``/!
+M!@`#HFP``J`N``(%(@`"87$``\$N``/!/@`"H-X``_`!``.#,``#AF```_!'
+M``-H,``#C^T``BT$``./[0`"+00``X_M``(M!``#C^T``BT$``-)=0`#P2X`
+M`\$&``/!%P`#P3X``J#>``/P`0`#@S```V@P```!Y0`#_P```_\```*E#@`#
+M\$@``T`1``*@W@`#\`,``F9N``/T```#\$$``F=^``-@$0`#Z````('E``/L
+M```"H/X``<5'``*P#P`"L0\``K(/``*S#P`"H-X``_`#``-C*``#]````_!!
+M``-C:``",40``TI```!!\@``2?8``%'U``*\,P`"1`P``D4<``)D10`"1BP`
+M`D<\``)F9P`"9$8``J%.``/P`0`"M`$``J".``/P!0`"I$D``_!#``*D2P`#
+M\$$``/'T``"A]@`"O,P``D0,``)%'``"1BP``D<\``)D10`"9$8``F1'``*A
+M3@`#\`$``K0!``*@C@`#\`4``J1*``/P0P`"I$L``_!!``#Q\P``H?4``^A`
+M``"A\@```?0``!'S``*Q#P`"LP4``J7^``(%G0`"H/X``_!!``/H\``"H`X`
+M`_`!``+/_@`"L1```J`N``/P`0`"S_$``K.0``*F\P`#\$(``/'E``/L```"
+M0P(``_!#``(EW0`#]````<5'``*T$0`##_0``J#>``/P`P``^?$``_0$``/P
+M`0``^?```T,I``*@W@`#\$$``T-I``*_=P`");P``^P```-(Y0`"H-X``_!!
+M``-)!0`"N!$``J`.``/P`0`"Q$@``DE!``*DDP`#\`$``/'T``*@+@`#\`$`
+M`L58``))40`"I),``_`!``#Q\P`"H-X``_`#``-HY0`#]````_!!``-I!0`"
+M0`(``J`.``(%1P`"L0(``B7W``/L```"H?X``_!!``/L```#H?8``X_V``.@
+M]@`"H0X``_`'``*\"0`"H$P``_!!``*\#P`#P4P``\%<``,`#@`"H1X``_`'
+M``*\"0`"H&P``_!!``*\#P`#P6P``\%\``,!'@`"H-X``_`#``-C*0`#]```
+M`_!!``-C:0`"8@$``@7"``/L```#0RD``J#>``/P00`#0VD``J`.``/P!0`"
+MM`\``DS^``/P`0`"M`D``\%4``*@+@`#\`8``K8/``.L]@`"3,X``_`!``*V
+M"0`#P78``J#>``/P`P`#8RD``_0```/P00`#8VD``^P```-(Y0`"H-X``_!!
+M``-)!0`"L!$``L1```+%4``"H-X``_`#``-HY0`#]````_!!``-I!0`#`1X`
+M`@7[``/L````:C$``^@```(N@@``\>\``^@```"![@`#0`P``T`M``*X$``"
+MN0@``DH8``.JI@`"2TD``ZNT``*S!``";ZL``_!!``*S`@`"3ZL``_`!``*S
+M!@`#0"T```H$``*P0``"0$```_!!``/H,``"01X``_`!``/H,```F>T``BT(
+M``*X$``"N?X``J#>``/P"0`#2"$``KH/``)&:@`"1WD``F9H``-H(0`#:HD`
+M`_0```/P1P`#2"4``KH/``)&:@`"1WD``F9H``-H)0`#:HT``C`H``*_`P`"
+M+_0``K]D``(M!```:C$``_\```/_```"H-X``_`#``*[```#]````_!!``*[
+M0```V>```\$.``*Q$0`"LA```VI$``*Q$``#Z"```VI$``*P_P`"L?\``K+]
+M``*S_P`#:&```TI@``*_]P`"L1,``D`/``)@#@`#:F```#'^```Y_0`"O`@`
+M`K_^``.&:@`"8B8``J1^``/P`0`"LP0``D`/``)@#``#:F```X_A``(M!``#
+M:&L``_\```/^````8B\``%HN``/_```#V,$``]RQ``./XP`"+00``]`?``.,
+M[P`#C^0``F_^``)``0`"0B,``D`"``),P``#^P$``]`?``,/_@`"!G@``J#>
+M``/P`P`#2"$``_0```/P00`#2"4``\#,``(&I``#C.8``L9L``/P00`"QWX`
+M`J#>``/P!``#:"$``VJ)``/T```#\$(``V@E``-JC0`"I7X``_`"``/T```!
+MQDH``T`1``*P"```\>4``J#>``/P`P`"9F```_0```/P00`"9W```V`1``/T
+M```"!]$``X#A``.!!@`"81X``X+G``-J1``#@08``^@@``-J1``","@``T`L
+M``!:'0`"M`0``^CP``)$0``#\`$``K\!``*DO@`#\`$``K\$``(O]```\AD`
+M`/(7``(R6@`","@```HM```1_@``&?T``K`"``*@W@`#\$$``K`$``."*@`"
+MI#X``_`!``*S!``#@18``F`!``*Q,P`#:F```T`*``*P`0`"L0(``K(```*S
+M`0`"H"L``_`"``/H(``#P3L``VIH``/!#@`"L@D``D`)``/P`0`#Z"```K`3
+M``*Q`@`#@B8``^@P``-J<``#0"T``&($```2&@`"OT```D]/``/P`P`"H,X`
+M`_`!``*R"``"L"$``K$"``*S`0`#:G0```H=``*P`0`#_P```J0>``/P!0`"
+ML00``K(```*S`@`#]`0``_`#``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`0`"L0(``K,$``-J?````>X``_\```/_```"P`X``('N``(O[P```AD``T`*
+M``-`#0`"H`X``_`%``*P`0`"0`4``X`&``/T!``#\`,``K`$``)`"0`#@`(`
+M`K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"
+M+LH```'O``/_```#_P```J`.``/P3@`#0"P``KP$``/<P``#C^H``J#>``/P
+M`0`#Z/```]CP``*\"0`"OS\``DL?``(MBP`#Z/```/GO```![@`#_P```_\`
+M``+`#@``@>X```GM``-`+@`#_P```J`!``('2@`"L`$``D$(``/P!0```C(`
+M`_\```/_```"H`X``@=*``-*=```>AH``_\```/_```#P2\``VIT``(O[P``
+M`AD``T`*``-`#0`"H`X``_`%``*P!``"0`4``X`"``/T!``#\`(``K`0``)`
+M"0`"L4,``F@!``-*9``"M(```!'@``)`!``"8`@``Z(B``/!/@`#:F0``BZ]
+M``(NR@``0@,``K`"``*@W@`#\$$``X`"``)`"``#\`(``_0```''>@`#0`X`
+M`K`0``/_```"00D``J`0``('>@```AD``_\```/_```"P`X``((9``*Q`@`"
+MI`$``@<```!!X````<,``_\```/_```#V(```]P```*_"0`"L````]P!``*P
+MP``#V`$``BZT```![@`#_P```_\```+`#@``@>X``B_O``-`"@`"L$```_\`
+M``)`"0`#H`(``K$#``)H`0`#2F0``K2````1X``"0`0``F`(``.B(@`"LP$`
+M`VID``(NO0`"+LH``T`E``!"`P`"L"```D`%``/P2``"L`(``J#>``/P00`#
+M@`(``D`(``/P`@`#]````<>_``-`+@`#_P```K`(``)!"``"H!```@>_``*P
+M@``"00@``_`%```",@`#_P```_\```*@#@`"![\```(7``/_```#_P```^@0
+M``"*%P`"I`X``@<R```!X```0<,``_\```/_```#V````]R```*_"0`"L,``
+M`]@!``*P```#W`$``C)@``-H:P``$=8``K/```/HT``#8G0``BVS``(P'@`#
+M[````&HQ``/_```#_P```J#>``/P`P`"NV(``_0```/P00`"NV@``_\```/_
+M````V>P``C"E``/H```"+H(``KL"``#:,``#Z````K%@``/H(``#Z#```VF@
+M``/H```"L1```^@@``/H,``#:D0``C`H``*_`@`"+_0``K#_``*Q_P`"LOT`
+M`K/_``-H8```"BT``!'^```9_0`"L`H``J#>``/P00`"L`P``X$6``)@`0`#
+M@BH``K$,``)B(0`"I#X``_`!``*S!``"L18``VI@``./X0`"+00``VAK``/_
+M```#_@```C`>``-*8```,?X``#G]``*T]@`"M0,``X9J``)B)@`"I'X``_`!
+M``*W!``"8S<``P$5``)`!``#:F```T`*``*P`0`"L0(``K(2``/H,``#:F@`
+M`K"```*R"0`"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP``*P(0`"
+ML0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P
+M`@`"L0(``K,$``-J?``",EH``^AP``-*9``"M(```D`$``/H(``#Z#```VID
+M``-*9``"M(```!'L``)`!``"M`,``F`$``*S$``#:F0``BZ]``-*9``"M`@`
+M`D1```)G=``"I7X``@AX``/H```"+H(``J#>``/P`P`#2"(``_0```/P00`#
+M2"8``_\```.,Y@`"RJP``_!!``++O@`"H-X``_`$``-H(@`#:HH``_0```/P
+M0@`#:"8``VJ.``/H<``"IKX``_`"``/T```!R#T``T`2``#QY0`"OP0``J#>
+M``/P`P`":J\``_0```/P00`":[\``V`2``/T```!R'@``C`>``/L````:C$`
+M`/'O``/H````@@8``T`(``-`+0`"N$```KD(``)*"``#JJH``DM)``.KM``"
+MLP0``F^K``/P00`"LP(``D^K``/P`0`"LP8``T`M```*!``"L$```D!```/P
+M00`#Z#```D$>``/P`0`#Z#```)H%```AY0`#Z%```_\```"B#```J>4``&HQ
+M``/_```#_P```J#>``/P`P``6<(``_0```/P0P``6<$``_\```/_````V>``
+M`T`L``!:'0`"M`0``^CP``)$0``#\`$``K\!``)+O@`"H+X``_`#``(O)0`#
+M]````<BW``*_RP`",8H``/(8``#R%P`",EH``C`H```*+0``$?X``!G]``*P
+M`@`"H-X``_!!``*P!``#@18``F`!``-`%0`#@BH``K&```)B(0`"I#X``_`!
+M``*S!``"MO```D1&``*Q"``"810``VI@``-`"@`"L`$``K$"``*R```"LP$`
+M`J`K``/P`@`#Z"```\$[``-J:``"L`$``K((``)`"0`#\`$``^@@``*P$P`"
+ML0(``X(F``/H,``#:G```T`M``!B!```$AH``K]```)/3P`#\`,``J#.``/P
+M`0`"L@@``K`A``*Q`@`"LP$``VIT```*'0`"L`$``_\```)!$``"I!X``_`%
+M``*Q!``"L@```K,"``/T!``#\`,``K$"``*R#P`"LP$``VIX``-*?``#_P``
+M`K`!``*Q`@`"LP0``VI\```*'0`#_P```_\```)!'@`"I!X``@E/```"!@`#
+M_P```_\```+`#@``@@8``B_O```"&``#0`H``T`-``*@#@`#\`4``K`"``)`
+M!0`#@`0``_0$``/P`P`"L`@``D`)``.````"L0,``F@!```"'0`#_P```_\`
+M``)`#@`"I`X``_`+```2&@`"L",``K$#``*S`0`#:G0``TI\``/_```"L`$`
+M`K$$``*S!``#:GP``TID``*T@```$>```D`$``)@"``#HB(``K,!``-J9``"
+M+KT``B[*```![P`#_P```_\```*@#@`#\$X``T`L``*\!``#W,```K_```*@
+MW@`#\`$``K^```/8\``#C.0``K\_``)+'P`"+8L``^CP``#Y[P```@8``_\`
+M``/_```"P`X``((&``!:'0``>A<``K@(``)*O@`"H*X``<EP``.JL``"2JX`
+M`_!#``(KQ``#]````<EO``-*<``"NH@``KEP``*@^``#\$,``\$J``/T```!
+MR6T``ZNR``)+O@`"H+X``_!!``/!*0`#:G```C%7``(R6@``"@4```(&``-`
+M+@`#_P```J`!``()A``"L`$``D$(``/P!0```C(``_\```/_```"H`X``@F$
+M``-*=```>AH``_\```/_```#P2\``VIT``(O[P```A@``T`*``-`#0`"H`X`
+M`_`%``*P"``"0`4``X````/T!``#\`,``K`@``)`"0`#H````K%#``)H`0`#
+M2F0``K2````1X``"0`0``F`(``.B(@`"LP$``VID``(NO0`"+LH``$(#``*P
+M`0`"H-X``_!!``.``@`"0`@``_`"``/T```!R;4``T`*``/_```"L$```D$(
+M``*@$``"";4```(8``/_```#_P```L`.``""&``"L0(``J0!``()#````>``
+M`$'#``/_```#_P```]@```/<@``"OP@``K#```/8`0`"L````]P!``(NM```
+M`@8``_\```/_```"P`X``((&``(O[P`#0`H``K"```/_```"0`D``Z`$``*Q
+M`P`":`$``TID``*T@```$>```D`$``)@"``#HB(``K,!``*Q```#:F0``BZ]
+M``(NR@``0@,``K`!``*@W@`#\$$``X`"``)`"``#\`(``_0```')]P`#0"X`
+M`_\```*P"``"00@``J`0``()]P`"L(```D$(``/P!0```C(``_\```/_```"
+MH`X``@GW```"%P`#_P```_\```/H$```BA<``J0.``()3P``8<,``%G@``/_
+M```#W,```]BP``*_"``"L,```]@!``*P```#W`$``C)@``-H:P``$=8``K/`
+M``/HT``#8G0``BVS``(P'@`#[````&HQ``/_```#_P```J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``_\```/_````V>P``T`0``*['P`#2"D``J#>``/P00`#
+M2"T``D`+``.O`@`#C/8``FS/``./]@`#2>@``J-,``/P!``#!$P``P5?``/T
+M```#\$(``P3$``,%]0`#P00``\$5``*@W@`#\`0``V@I``-IZ``#]````_!"
+M``-H+0`#:>P``^@```(NE@`#Z````K%```/H(``#Z#```VI$``(P*``"OP(`
+M`B\E```*+0``$?X``!G]``*P`@`"H-X``_!!``*P!``#@18``F`!``."*@`"
+ML80``F(A``*D/@`#\`$``K,$``*Q&``#:F```T`*``*P`0`"L0(``K(*``/H
+M,``#:F@``K"```*R"``"0`@``_`!``/H(``"L!,``K$"``.")@`#Z#```VIP
+M``*P(0`"L0(``K(!``*S`0`#:G0``K`!``*Q`@`"L@\``K,!``-J>``#2GP`
+M`_\```*P`@`"L0(``K,$``-J?``",EH``^AP``(O[P`#2F0``K2````1[``"
+M0`0``K0#``)@!``"LQ```VID``(NO0`#2F0``K0(``)$0``"9W0``J5^``(*
+MN0`#Z````BZ6``*@W@`#\`0``T@J``-)Z``#]````_!"``-(+@`#2>P``KP1
+M``*_$``"R9\``LB,``/P00`#Z(```\$(``/!&0`"H-X``_`$``-H*@`#:>@`
+M`_0```/P0@`#:"X``VGL``-*P``"OP<``DW>``/P`0`"OS@``J&.``/P0P`"
+M8`\``VK```-JQ``"NP$``-HP``/H<``"3_```_`#``*[_P`"H(L``_`"``/T
+M```!RG$``T`2``#QY0`"OR```J#>``/P`P`":J\``_0```/P00`":[\``V`2
+M``(P*``"+^\``^P```!J,0`#Z````(',``*@W@`#\`,``%G"``/T```#\$$`
+M`%G!``*P?P`"H?X``_!!``)+L```V>```C):``(P*```"BT``!'^```9_0`"
+ML`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&```)B(0`"I#X``_`!``*S
+M!``#0!4``K$(``*V\``"1$8``F$4``-J8``"L`$``K$"``*R```"LP(``VIH
+M``*R"``"L!,``K$"``.")@`#Z#```VIP```2&@`"L"$``K$"``*S`0`#:G0`
+M`K`!``*Q`@`"L@\``K,!``-J>``#2GP``_\```*P`0`"L0(``K,$``-J?``"
+MO`0``]S```!YX``"O`@``KL8``/8\``"+8L```',``-`)0`"OQ```L`.``"!
+MS``"3U\``_`#``(KQ``#]````<L6``*_"``"H`X``_`!``/!_@`",5<``TJ`
+M``*@_@`#\$$``VJ$``!AX``"L(```^CP``*AP``#\$$``\'^``(K=P`"+^\`
+M`!'@``/H$``"L",``Z(B``*S`0`#:F0``BZ]``!AS````>````G#``-`)@`"
+MLA```]@```/<$``"OP@``K#```/8`0`"L````]P!``)"*0`#\$4``Z_P``*@
+MS@`#\`(``_L```/[`0`#T)X``_L```*E+@`#\`$``_L```/4GP`#^P$``J4N
+M``/P`0`#^P$``P_^``(+.````<P``_\```/_```"P`X``(',``!AX``"L(``
+M`\'^``*AP``#\$$``^CP``(K=P`"+^\``!'@``*P`P`#Z!```Z(B``*S`0`#
+M:F0``BZ]``(NR@`#0"4```',``*Q`P`"L@@``K,0``)#-0`#\`(``D(E``/P
+M`@`"I0$``<L#``!APP``6>```_\```/<P``#V+```K#```/8`0`"L````]P!
+M``*_"``",F```VAK```1U@`"L\```^C0``-B=``"+;,``C`>``/L```"O!$`
+M`J#>``/P!``#2,P``TC1``/T```#\$(``TCL``-(\0`"*Z\``J#>``/P!``#
+M:,P``VC1``/T```#\$(``VCL``-H\0`"H-X``_`$``-(U``#2-D``_0```/P
+M0@`#2/0``TCY``(KKP`"H-X``_`$``-HU``#:-D``_0```/P0@`#:/0``VCY
+M``*@W@`#\`,``TC<``/T```#\$$``TC\``*@_@`#\`0``L`,``+!'``#]```
+M`_!"``,`#``#`1P``J#>``/P`P`#:-P``_0```/P00`#:/P``^P```*@_@`#
+M\`H``L`,``+!'``"PBP``L,\``+$3``"Q5P``L9L``+'?``#]````_!(``,`
+M#``#`1P``P(L``,#/``#!$P``P5<``,&;``#!WP``^P```*P?P`"L?\``K+_
+M``*S_P`#:&```VAK```)U@`#Z````Z`#``/<```#V!```T`Q``*_`P`"O`(`
+M`J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^``/P00`#
+MP00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""](``T`U``*_
+M`P`#_P```J;\``/P00`#P0<``J#\``/P00`#P08``J#^``/P00`#P04``J'^
+M``/P00`#P00``\$0``/!(``#P3```_X```/4'@`#:&L``_L```,/_@`""^H`
+M`T`X``-`/0`#_P```VJ$``-J@0`#[````TA5``/_```"M\```VA5``-H:P`#
+M2`H``K]_``)H^``"LN\``Z"!``*_PP`"0`\``T`E``*S_P`"L?\``D]>``/P
+M`@`"N?,``D(I``*\`@`"3%P``_`!``*S^P`#:&```TA```./\@`"O/L``D$<
+M``)A'P`#:$```VAK``-)?``"M`0``F$4``-I?``#2I0``_\```-A?``#:&L`
+M`C%$``/_```#_@```_\```-!20`#_P```_\```-(9``#B$0``ZB```/H\``#
+MW/```KQ```+,R``#V,```]0>``(R9@`#84D``TAD``*T$``"1B0``_`"``/T
+M```!S)D``TAD``-(-@`"M$```K4$``)$0``"15@``F1%``',60`"M#P``D1`
+M``/P0P`".KT``_0```',*P`#0!0``_\```/_```"PSX``_!!``,#/@`#8!0`
+M`K#_``*Q_P`"LO\``K/_``-JD``#^`,``TAD``.,Z@``\@@``DP,``',=0`#
+M2#0``KP$``),P``"#&0``.((``-)/0`"OQ```D1/``/P!``"O_\``BT$``*_
+M4``"+00``K\(``(M!``#]````<R&``-(0@`#2=0``#(S``*U$```FC,``KQ`
+M``)%4P`#\`D``DS)``/P!P`"H&,``_!%``#R`@`"-&L``VAK``/T```!P$$`
+M`TA4``*U/P`"0U,``K</``)C-P`#:%0``C)@``/H````@@(``T)Q``(R9@`#
+M8G$``T@(``*T@``"1$```_`"``/T```!UNP``^P```/X`P`#2`@``K2```)$
+M0``#\`(``_0```'6[``#2=```K@(``)).``"H)@``@SP``-)U``"M!```D,T
+M``*@-``"#,X``T@(``*X"``"8`@``V@(``-(*``"N"```F,X``-(+0`#:"@`
+M`VGH``)G>``#:"T``VGM``-(R``"N/L``D(H``-HR``#2)@``K@@``)@"``#
+M2+$``VB8``)D2``#:+$``\$.``/!'@`#P2X``\$^``-C,``#8W```V,T``-C
+M=``#8S@``V-X``/T```!S/```T@(``*X]P`"0`@``V@(``-(*``"N-\``D,X
+M``-(+0`#:"@``VGH``)'>``#:"T``VGM``-(R``"N`0``F(H``-HR``#2)@`
+M`KC?``)`"``#2+$``VB8``)$2``#:+$``K`#``/!$``#P2```\$P``-C,``#
+M8W```V,T``-C=``#8S@``V-X``-)?``"M/L``D$4``-I?``#:&L``_0```',
+M*P`#2,H``K`$``*Q0``#P2@``F@@``-HR@`#P8(``VC*``)H(0`#:,H``\&"
+M``-HR@`#[````_@#``,/_@`"#04``^P```(R8``#:&L``\$.``/H$``#Z"``
+M`^@P``.D$P`#V!```]Q```/^```#U!X``VAK``-II``#Z````_X```/4'@`#
+M:&L``VFD``*@W@`#\`,``T)@``/T```#\$$``T)<``-"60`"H-X``VFD``/P
+M`P`#0F@``_0```/P00`#0F0``VFA``/^```#U!X``VAK``-H:P`#[````C)@
+M``-H:P`#0E8``\$.``/H$``#Z"```^@P``.D$P`#V!```]Q```/4'@`"OP(`
+M`BT$``-H:P`#::0``VFB``/H```#_P```]0>``*_`@`"+00``VAK``-II``"
+M,F```VAK``/L```#:&L``C)@``*Q#``#Z````Z`#``/<```#V!```^@```/H
+M$``#Z"```^@P``/^```#U!X``VAK``/[```#^P```XCC``/X`P`#_@```]0>
+M``-H:P`#^P```PB.``(-6@`#[````"'K``/H4``#Z&```^AP``*Y"``"N,``
+M`]R!``/8D0`#0E```_@#``/_```#:D0``^@@``,!'@`#:D0``_X```/47P`#
+M:&L``\&/``*_$``"+00``K09``/^```#U%\``VAK``*_$``"+00``\'X``-)
+MI0`#_P```_\```/!!``#P14``X+@``)B)@`#P3<``VFD``*Y"``#"9X``@V'
+M``-II0`#[````J&^``/P#@`#T!X``P^^``*Z/P`#``X``D`*``,!'@`"01H`
+M`P(N``)"*@`#`SX``D,Z``/4'@`##_X``@V0``/[```##,X``@V+``/L```"
+MH;X``_`.``/0'@`##[X``KH_``+`#@`"0`H``L$>``)!&@`"PBX``D(J``+#
+M/@`"0SH``]0>``,/_@`"#:0``_L```,,S@`"#9\``^P```/0G@`#T!\``KP_
+M``)(C``"29P``DJL``)+O``"1`P``D4<``)&+``"1SP``KP@``+`A``#H```
+M`J-(``/P00`"P`P``L&5``.A$``"HUD``_!!``+!'``"PJ8``Z(@``*C:@`#
+M\$$``L(L``+#MP`#HS```J-[``/P00`"PSP``KP'``*CW``#\$X``W)T``-2
+M=@`#_P```_\```/^```#U!X``VAK``/[```#<G8``U)T``/_```#_P```_0$
+M``/P"``"O`@``J3<``/P`0`#:H0``KP)``*DW``#\`$``VJ```(R6@`#^P``
+M`_L!``+-W@`"IM\``@VS``(O[P`"L````K$```*R```"LP$``VIT``*P,0`"
+ML08``K($``*S```#:G@``TI\``/_```"L`$``K$!``*S```#:GP``TID``*T
+M@``"0`0``K0#``)@!``#:F0``BZ]``-*9``"M(```D`$``-J9```:C$``C&R
+M``/L````6><``&(P``/_```"H;X``_!"``#QY0`#[````J'.``/P00`#"[X`
+M`PS.``#9YP``XC```TI```!:"0`#_P```_\```*@O@`#\$(``Z````.B(``#
+MT%X``&'\``!9XP`#H@(``D`)``)"*0`"I8X``@X\``,(C@`"H`T``_`+``!!
+M^0`"Q$\``\%4``*@O@`#\$8``]1>``+$3P`#P50``]1>``+$3P`#P50``J6N
+M``(.3``#"JX``J`M``/P"P``4?D``L9O``/!=@`"H+X``_!&``/47@`"QF\`
+M`\%V``/47@`"QF\``\%V``/47@`##,X``@Y-``)KB@`"#A$``^P```-"<```
+M4@D``X_L``.(Z@`#JJ```J2N``/P!@`"H4@``_!!``+$2``"H6@``_!!``+&
+M:``#BN```J9/``/P0P`#!$@``P`(``,!&``"IF\``_!#``,&:``#`B@``P,X
+M``,*K@`"#F```\%4``/!=@`#U%X``V)P``/L```#P6(``P9N``/<$``#V```
+M`]">``/_```#_P```DB%``)H@P`#P9@``\&H``/!N``#U)X``_L```,&;@`"
+M#G4``^P```/!$``#P2```\$P``*@W@`#\`@``VD(``-I#``#:1```VD4``-I
+M&``#:1P``_0```/P1@`#:2```VDD``-I*``#:2P``VDP``-I-``#[````\$0
+M``/!(``#P3```J#>``/P!P`#:,P``VC0``-HU``#:-@``VC<``/T```#\$4`
+M`VCL``-H\``#:/0``VCX``-H_``#[````TG4``/_```#@.4``D$#``-)T@`#
+M_P```D`*``-)P@`"I1```_`!``-)Q@`#[````]">``/[```#_P```_\```/4
+MGP`#^P$``P_^``(.M``#[````_@!``*_!``#2F0``_\```/_```"00\``@Z_
+M``/X`P`#:&L``_\```/_```#_@```^P```-*9``#_P```K\(``)!#P`"H!\`
+M`@[K``-`$@`"M1```J4E``/P!``"OP(``FJO``/T```!SN@``L15``*E)``#
+M\`0``K\"``)KOP`#]````<[H``+$10`"I20``_`$``*_$``":J\``_0```'.
+MZ``"OQ```FN_``#QY0`#8!(``B[L``/L```#2G```_\```/!P@`#0"X``K`!
+M``-JJ``#_P```_\```/_```#2JP``K0"``-JJ0`#P````\`1``/`(@`#P#,`
+M`TJM``*_D``"H,\``_`%``/`1``"OP\``D]/``/T```#\$$``\#T``*@W@`#
+M\`L``T`9``/_```#_P```F1```)E40`"9F(``F=S``-@&0`":J\``_0```/P
+M20`#0!T``_\```/_```"9$```F51``)F8@`"9W,``V`=``)KOP`#8"X``^P`
+M``+$1@`#:JD``_\```/_```#_P```TJL``/L```",F```VAK```)U@`"L,``
+M`]P```/8$``"H/X``_`$``/H```#Z!```^@@``/H,``"H/X``_!$``*P50`#
+MP1```\$@``/!,``"H/X``_`$``*T_P`#P50``\%D``/!=``"H/X``_!$``*T
+MJ@`#P50``\%D``/!=``"O`<``J/^``(/G@``0?\``_\```/_```"H(X``@]D
+M``*@W@`#\`,``T!"``/T!``#\`$``T!&``#J,0``:@```J3>``/P!``#P(@`
+M`\"9``/`J@`#P+L``F`(``)A&0`"8BH``F,[``)D2``"95D``F9J``)G>P``
+M:C$``_\```/_```#_@```]0>``-H:P`#^P```PS.``/^```#U%X``VAK``/[
+M```##,X``@]D``!!_P``8@```_\```*@C@`"#XD``T!*``*DS@`#\`0``\"(
+M``/`F0`#P*H``\"[``*DW@`#\`(``\&*``/!FP`"N@\``DJH``.+I@`":JL`
+M`KOP``)+N``#I[8``FNW``/T!``#\`,``^A@``/HH``#Z+```K3P``)@2@`#
+MP1```\$@``/!,``#:H0``J#^``/P`P`"M/```_0$``/P`0`"M`\``F!+``/!
+M$``#P2```\$P``-J@``#[````_X```/4'@`#:&L``_L```,,S@`"N0,``J#Y
+M``/P1``#Z$```^A0``/H8``#Z'```_X```/47@`#:&L``_L```,,S@`"#ZH`
+M`K#P``*Q_P`"H/D``_!"``/H```#Z!```\$A``/!,0`#:H0``VJ```/L```"
+M,F```VAK```)U@`"L,```]P```/8$``"M/\``\%D``/!=``"O`<``_X```*U
+M_P`#U%X``VAK``/[```##,X``_X```*U[P`#U%X``VAK``/[```##,X``@_%
+M``*U_P`#:H4``K#P``/!$``#P2```\$P``-J@``#2F(``B_O``/H\``"+_L`
+M`VIB```)U@`"L,```]P```/8$``"M/\``\%4``/!9``#P70``KP'``/^```#
+MU%X``VAK``/[```##,X``@_G``(R6@`#[````TID``*T@``"0`0``VID``/L
+M```"L`0``J#P``/P`P`"+R4``_0$``/P`0`"*\0``^@```/````#P1```K+]
+M``*S_P`#:&````HM```Q_@``&?T``K`*``*@W@`#\$$``K`,``.!%@`"8`$`
+M`K$6``*D/@`#\`$``K,$``.&:@`"L@(``K0$``*C_@`#\`,``J#T``/P`0`"
+ML@0``F(F``-J8``#C^$``BT$``-H:P`#_P```_X```/L```#2F```_\```/H
+M,``"8`X``VI@``-*9``"M/(``D`$``-J9``#[````K`!``/H$``#Z"```^@P
+M``-J8``#[````&HQ``-`!``#_P```K@$``)%X``"H%X``_!$``*@W@`#\$(`
+M`T`D``/_````8>D``_\```/_```#W,```X_J``*@W@`#\`$``^CP``/8\``#
+MC.0``\&R``-)/0`"H-X``_!!``-)00`#_P```D1N``/P`0`"O`<``D`(``/P
+M0P`"+8L``_0```/P00`"+9\``D1N``/P"0`#Z,```ZMB``.E8``"15X``_!#
+M``(MBP`#]````_!!``(MGP`#[````&HQ``-`*``#0"$``KA```)(@``#\`,`
+M`D9N``/P`0`#[````%'#``*@W@`#\`,``%G"``/T```#\$$``%G!``/_```#
+MW*```]BP``-`!@`#_P```_\```)`Z``#\`,``J#>``/P00`#0"8``_\```/_
+M```#24$``J`.``/P0P`"H-X``_!!``/!10`"14X``_!#``.,Y``#]````_!!
+M``.,XP`#B9@``ZJ<``*@K@`#\`,``BV+``/T```#\$$``BV?``-`!@`#_P``
+M`_\```-)00`"0(X``J`.``/P0P`"H-X``_!!``/!10`#Z,```ZM"``)%3@`#
+M\`<``Z5```)%7@`#\$,``BV+``/T```#\$$``BV?``/L```"H-X``_`#``-(
+M(0`#]````_!!``-()0`#_P```KL!``.B9@`#@68``Z$6``.'=@`"8"<``P`+
+M``.G!@`#@@8``F8A``*@W@`#\`0``V@A``-JB0`#]````_!"``-H)0`#:HT`
+M`^P```./[0`"+00``^@P``."X``#Z!```^@```-H,``#C^T``BT$``-)G``#
+M2=4``T`J``*T$``"1$<``K4"``)%6@`#A50``D1%``.D0``"MO<``D(F``)B
+M)``#:9P``^CP``-)<``#Z'```K8!``/!40`#P4```V@Q``*X_``#P5,``\%"
+M``)%6``#270``C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29@`
+M`C%$``-H,0`#P5$``\%```(Q1``#:#$``\%3``/!0@`#29P``C%$``-H,0`#
+MP5$``\%```(Q1``#:#$``\%3``/!0@`#2.@``C%$``-H,0`#P5$``\%```*W
+M$``",40``V@Q``/!4P`#P4(``C%$``-H,0`#[````KP#``-)/0`#2,```J#>
+M``/P00`#2,0``K8$``)&9``#\`0``X;*``/!?``"8B8``F$7``*@W@`#\`,`
+M`VC```/T```#\$$``VC$``-`*@`"M@@``X?&``)&:``#\`$``F,W``*@W@`#
+M\`,``VC```/T```#\$$``VC$``/L```","X``TD]``-`*``"OP@``KP$``)/
+M#P`"3$P``F#\``/P00`#[````K0!``(R`@`",0D``J'^``/P"0`",<,``C`H
+M``-`*``"O`@``_\```)"+``#\$(``_0```/P0@`#Z$```C("``/L```#_P``
+M`_\```/_```#[````V%(``-A00`#848``V)_``/!#@`#Z!```^@@``/H,``#
+M:.@``^@```/_```#:.@``T%(``/_```#[````C)@``-H:P``"=8``^@```.@
+M`P`#W````]@0``*\`P`"L/<``J#^``/P00`"L'\``\$0``/!(``#P3```K3_
+M``/!5``#P60``\%T``/^```#U!X``VAK``.@`0`#H1$``Z(A``.C,0`#^P``
+M`_X```/47@`#:&L``_L```,,S@`"$6H``K#_``*\"``#P1```\$@``/!,``#
+M:H```J3^``'1A``"H/P``_`"``-JA``#[````K#W``.A`0`#HA$``Z,A``-J
+MA``#[````TD]``/_```"N(```F1(``-I/0`"L`$``K$"``*R/P`"0B\``K,`
+M``-J:``"L````K$```*R```"LP(``VIT``*Q`0`"L@@``K,```-J>``"L`$`
+M`K(```-J?```$>```K#```)`#P`#H`(``F`.``*Q```#HB(``K,!``-J9``"
+M,EH``_\```/_```"+KT``KA_``)$2``#:3T``^P```/H```#Z!```K(#``*S
+M```#:#```^P```-`+``#_P```_\```/H(``#Z#```V`L``/H```#Z!```V`8
+M``-@'``#[````&HQ``*P`0`#Z!```^@@``/H,``#:F```K\!``(O]``"OQ``
+M`BT$``*\%``#2F```K_W``*Q$P`"0`\``F`.``-J8```,?X``#G]``*\B``"
+MM?X``X9J``)B)@`"I'X``_`!``*S!``"0`4``F`,``-J8``#2I8``T`I``*\
+M!P`#_P```D1,``.%1``"Q5X``\'%``/H0``#Z&```^AP``-JD0`"M/\``K5_
+M``*V_P`"M_\``VAA``-H:P`#_P```_X```,)G``#\$4``\"9``,*K@`#\$(`
+M`\"J``,+O@`#:I(``X````.@```#:F```K\0``(M!``#[````T`J``-'+``"
+MH-X``_!!``-';``"MG\``X5,``)`!@`"29X``_`!``)@!0`#P1```\$@``/!
+M,``"H-X``_!$``-G+``#9S```_0```/P0@`#9VP``V=P``-'-``"H-X``_!!
+M``-'=``"MM\``X5(``)`!@`"8`4``\$0``/!(``#P3```J#>``/P1``#9S0`
+M`V<X``/T```#\$(``V=T``-G>``#2,```J#>``/P00`#2,0``K8_``)")@`"
+MML```J!.``/P`0`#Z&```F(F``*@W@`#\`,``VC```/T```#\$$``VC$``/L
+M```#29@``K@/``*Y]0`#Z#```\$N``*@S@`#\`(``F`(``)!&0`#:#```T@(
+M``*X0``"H,X``_`"``)@"``#:`@``^P```-A4``#854``V%:``-A7P`"+`4`
+M`T%0``-!50`#05H``T%?``/_```#_P```^P```*P_P`"L;\``K+_``*S_P`#
+M:&```^P```*P?P`"L?\``K+_``*S_P`#:&```^P```+$3@`#\$H``L5>``/P
+M2``"QFX``_!&``+'?@`#\$0``K3_``*U_P`"MO\``K?_``/L```"H<X``_`'
+M``,,S@`"OWP``BT$``/_```#_P```PS.``(2=@`#[````^@```"",0`"(N``
+M`/(Q``(BX``",O@``BSW``-)F``"M/<``K4/``)!%``"8`4``VF8``/!+@`#
+MZ#```V@P```""@`#@>```^A```*@`0`#\`$``\%.``(T7@`#2`@``KC^``)!
+M&``#:`@``KP```(T"0`"-#H``T`!``/H````@C$``D1.``/P`0`")!L``T`!
+M``/_````\C$``D5>``/P`0`")!L```(*``.!X``#_P```J00``/P`@`#P4X`
+M`C1>``*\`0`"-`D``C0Z``*_`P`"-N0``C-%``(NJ``"OQ```D_[``'2X```
+M><L``_\```/_```"H/X``_`&``*]```"-IX``KT!``(VG@`#]````=+H``-`
+M```"O````.(Q``*A#@`#\`$``C20``-````#_P```/(Q``*A'@`#\`$``C20
+M``-`!``#0`$``KP(``),P0`#\`H``KT```)$3@`#\`$``C;$``*]`0`"15X`
+M`_`!``(VQ``"OP```/G+``/T```!TN@``TG0``*\@``"3,,``_`$``*]```"
+M-GX``KT!``(V?@`#0"P``KA```*Y@``"N_\``TJE``)(&``#\`$``KO/``))
+M&0`#\`(``KH_``)+N@`"15L``VJE``/T```!PEP``TG1``(NJ``#Z(```J40
+M``/P`0`"N$```D1X``.$0``#2)P``K4$``)D10`"MG\``D`&``)@!``#:)P`
+M`VB@``-HM``#:+@``TDX``*U_``"0B4``K4,``)B)0`#:3@``^@```/HT``"
+M+H(``\'>``(N@@`"+J@``X3B``/!R0`#Z````K$#``*R"@`"LRT``D1)``/P
+M`0`"LR\``^A0``(N<0`#@.H``BYQ``*X+P`"M`(``D1,``/P`0`"N"T``\&8
+M``/!J``#P;@``V,J``-C:@`"+J@``X'B``.@X0`#HY8``X+D``+"+@`#Z%``
+M`BYQ``.@XP`"+G$``BZH``.`Y0`"0*```\$0``/!(``#P3```V2H``-DZ``#
+M@.```H((``)"`@`#@B0``)'4``/L```"+J@``TEP``)$C@`#\$,``K7S``)"
+M)0`#:7```^AP``/!;@`#P5,``\%"``-H,0`"1)X``_`&``-)G``#I.$``F(D
+M``/!4P`#P4(``V@Q``)$C@`#\$T``TF<``.$Y0`#I><``D`$``)!%0`#I(@`
+M`X1```.%1@`"8`4``F$4``/H,``#P2X``V@P``-#I```(=0``K7/``)`!0`"
+M8`0``\$0``/!(``#P3```V.D``-CY``"1$0``_`!``(VWP`#@80``Z`8``."
+M!@`"8`(``^C0``(NE@`#P=X``BZ6``-)T0`"+J@``^A@``*E$``#\`$``K9`
+M``)&=@`#IFH``TB0``.DN@`"H$X``_!!``*T!``"M0,``J!%``/P00`"M`$`
+M`K7P``)!%0`"810``K?^``)`!P`"8`8``VB0``-HJ``#:)0``VBL``.@I@`#
+MP1```\$@``/!,``#9"0``V1D``.*M@`#2"$``K@#``)F:``"N0\``KO^``)&
+M:0`"9FH``D=[``-H(0`#:HD``V@E``-JC0`#2`@``T@A``)A'@`#:`@``TC(
+M``*X0``"N3\``F`(``-HR``"0`D``VC(``/L```#0"P``KA```*Y@``#Z+``
+M`TJE``)(&``#\`$``KLP``))&0`#\`(``KK```)KN@`"95L``VJE``-(G``"
+MO'L``D`,``-HG``#:*```VBT``-HN``#2)```X3B``.EYP`"014``F$4``*U
+M_@`"0`4``VB0``-HJ``#:)0``VBL``-).``"M0,``F(E``*U\P`"0B4``VDX
+M``/HP``"-`D``C0Z``/H```"L0,``K()``/H,``#Z%```BYQ``.`Z@`"+G$`
+M`K`$``/!$``#P2```\$P``-C)``#8V0``K`@``/!$``#P2```\$P``-C*``#
+M8V@``C;?``-("``#2"$``ZCM``)!&``#:`@``ZCK``)&:``#P#X``D53``-H
+M(0`#:HD``V@E``-JC0`#Z$```C1>``/H\``"/B(``K\!``(^(@`#[````T`I
+M``/_```"N"H``D)>``/P`0`"N&0``J#.``/P00`"N!```\&8``/!J``#P;@`
+M`V<N``-G,@`#9VX``V=R``*X*@`"0EX``_`!``*XY``"H,X``_!!``*X$``#
+MP9@``\&H``/!N``#8ZX``V/N``-(G@`#P!0``Z$<``.!%``"L/<``DB```)H
+M@0`#:)X``VBB``-HM@`#:+H``TKJ``*P^P`#@2(``DJ@``)JH0`#:NH``VKN
+M``-J\@`#:O8``^P```-`*0`#1S8``K`'``*Q"``"0EX``_`!``*Q&``"H,X`
+M`_!!``*Q```"2(```FB!``/!F``#P:@``\&X``-G-@`#9SH``V=V``-G>@`#
+M0[(``K`'``*Q*``"0EX``_`!``*Q.``"H,X``_!!``*Q```"2(```FB!``/!
+MF``#P:@``\&X``-CL@`#8_(``^P```-)=``#P6X``^AP``.(2``#P%X``X59
+M``)")0`"8B@``VET``/!0@`#P5,``V@Q``/L```"OP,``C;D``-("``"N/X`
+M`D$8``-H"``#0"@``KP$``*_`P`"3,(``_`#``(]RP`#]````=2+``-(5``"
+MO&```F(L``-H5``#278``KP0``)DK``#P5L``\%N``/H<``#:#$``C%$``-(
+M5``"O)\``D(L``-H5``#P4H``V@Q``(SJP`#0D4``C)F``-B10`#[````&HQ
+M``(M"```\>4``C`H``(KQ``#0`0``T`*``*\`P`"OP0``D$<``,&\0`"0`\`
+M`_`!``/!:@`"Q&X``K4(``(XK@`#0`0``^CP``#Z!@`"LD```D(@``'4\0`#
+MCP0``Z_X``#Z`P`#2<$``KP/``)(SP`#J(```XF"``*ZXP`"1$H``F1)``))
+M_@`#B9(``KK[``)%6@`"95D``VG!``.!A@`"8($``BZ6``/H```"H-X``_!!
+M``*P0``"L0,``K()``*S"0`"1.\``_`!``*S#P`#Z%```BYQ``*C_``!U/$`
+M`^C```#AS@``X>X``C97``-`&``"H-X``_!!``-`'```0>X``&'.``)@`0`"
+M8`(``F`#``*A#@`#\$(``LB.``#![@`"N@(``KL?``+,R@``X<X``J7+``'4
+MS```2@8``'H#``/_```"H8D``=3L``,/_@`"L!```L_P``/H````@>4``_0`
+M``'4J@`"S_X``/H#``#"!@`#]````=2J``/HP```X@,``^@P``(V:P`#W.``
+M`K\(``/8\``"L"```\$0``/!(``#P3```K\1``/4'@`#_P```_L```,/_@`"
+M%/T``C97``!B`P`"L````]P```/<`0`#C\(``K!```+`#P`#V````K`_``)!
+M#P`"L,```L`!``/8`0`#U%X``]`?``*_$``"H<\``=4>``*@W@`#\`,``\$*
+M``/T!``#\`$``\$+``/4'P`#]````=4E``*@W@`#\`,``\$J``/T!``#\`$`
+M`\$K``/4'P`"-@\``T`&``*P'P`"L2```\$N``)!&``#\`$``L(N``+,P@``
+MX@,``J7```(5`@`#2I0``_\```-@O``#0`0``]S@``*_"``#V/```]SA``*_
+M+``#V/$``K\(``.L%@`"I<\``_!#``/`S``";,\``LS.``*_"``#T!X``]!?
+M``/!B0`#P9H``\&K``+$0``#H$```L`,``/!L``"Q5$``Z%0``+!'``"IAL`
+M`_`!``/!L0`"QF(``Z)@``+"+``"IBL``_`!``/!L@`"QW,``Z-P``+#/``"
+MICL``_`!``/!LP`#U!X``]2?``/[```#^P$``P_^``(50P`#03@``T%)``-!
+M*@`"O`X``J,!``/P`0`#P0$``J,"``/P`0`#P0(``J,#``/P`0`#P0,``J,(
+M``/P`0`#P0@``J,)``/P`0`#P0D``^@0``*F#``#\`,``\````.`!@`#H08`
+M`\$!``*C10`#\`$``\%%``*C1@`#\`$``\%&``*C1P`#\`$``\%'``*C2@`#
+M\`$``\%*``*C2P`#\`$``\%+``/H(``"IDP``_`#``/`1``#A$8``Z)&``/!
+M,@`"H-X``_`#``-DJ``#]`0``_`!``-DZ``#W.```K\(``/8\``#T%X``K\$
+M``/<\0`"OX```J#>``/P00`"O\```]CQ``*\$``"N`$``KD#``*Z#P`"H4P`
+M`_!%``/`1``"1$H``P0$``/T!``#\`(``P1*``+$0``"H5P``_!%``/`50`"
+M15H``P4%``/T!``#\`(``P5:``+%4``"H6P``_!%``/`9@`"1FH``P8&``/T
+M!``#\`(``P9J``+&8``"H7P``_!%``/`=P`"1WH``P<'``/T!``#\`(``P=Z
+M``+'<``#U%\``_L```/[`0`#T%X``PB.``(5J0`"N`$``\$!``/!$@`#P2,`
+M`PF>``(5J0`#1*@``J#>``/P00`#1.@``J%,``/P10`#P$0``D1*``,$!``#
+M]`0``_`"``,$2@`"Q$```J%<``/P10`#P%4``D5:``,%%0`#]`0``_`"``,%
+M6@`"Q5$``J%L``/P10`#P&8``D9J``,&)@`#]`0``_`"``,&:@`"QF(``J%\
+M``/P10`#P'<``D=Z``,'-P`#]`0``_`"``,'>@`"QW,``]1?``(L]P`"-&L`
+M`C`H``(O[P`#[````BZH``.CE@`"-FL``X#E``)#H``"-G0``_0```'6`@`#
+MP9```J'/``/P`0`#P9(``V)U``#)S@`#W.```K\(``/8\``#W.$``K\L``/8
+M\0`"OP$``\$$``(V,0`#0G4``K\!``/_```#P04``C8Q``-"=0`"OP$``_\`
+M``/!!@`"-C$``T)U``*_`0`#_P```\$'``(V,0```<X``K\```(V,0`#[```
+M`K(@``/07@`#T)\``D$.``/P1``"H$(``_!!``/!3``#P8P``Z````)!#@`#
+M\$0``J!2``/P00`#P5P``\&<``.@```"00X``_!$``*@8@`#\$$``\%L``/!
+MK``#H````D$.``/P1``"H'(``_!!``/!?``#P;P``]1>``/4GP`#^P```_L!
+M``.@```##_X``A8R``/L```"LQ```J7#``/P!@`#P#P``X,V``.C-@`"-G0`
+M`_0```'69``"LP\``LS.``)#/``"-FL``C&X``(L]P`"-&L``K\8``(X7``"
+M+NP``^P```*Q!``"L(```J#>``/P00`"L,```K()``/H4``"+G$``^P```/!
+M`P`#P1,``\$C``*@W@`#\`,``V2H``/T!``#\`$``V3H``/L```#0`0``KR`
+M``/_```"3,```=:>``-!`0`"H-X``_!!``-!!0`"L00``K"```*@W@`#\$$`
+M`K#```/<$``#V````\&$``(VNP`#P84``C:[``/!A@`"-KL``\&'``(VNP`"
+MH-X``_`#``-DH0`#]`0``_`!``-DX0`#]````=:X``*Q!``"L(```J#>``/P
+M00`"L,```]P1``/8`0`"L0$``K`(``*@W@`#\$$``K`L``/<$``#V````K\(
+M``(NM``#00$``J#>``/P00`#004``J#>``/P`P`#9*D``_0$``/P`0`#9.D`
+M`BSW``(T:P`#[````\&8``/!J``#P;@``K(!``/4G@`#^P```P(N``(6OP`#
+M[````K$$``*P@``"H-X``_!!``*PP``#W!```]@```*Q`0`"L`@``J#>``/P
+M00`"L"P``]P1``/8`0`"OP@``BZT``-$J``"H-X``_!!``-$Z``"H-X``_`#
+M``-A```#]`0``_`!``-A!``#[````TL,``*U_``"014``VL,``/L```#2PX`
+M`\#/``)JKP`#:PX``C%$``)*K``#:PX``^P```*_`P`"-N0``TG```-)U0`"
+M3`X``_!"``/T```!URD``TG```.'=@`"IG```_!"``/!$@`#Z````Z(6``.!
+M%@`#H18``TB1``*\\``"15P``F52``*\!``"0PP``Z,R``*\_@`"1$P``F1#
+M``-HD0`#:)4``VBI``-HK0`#P4$``\%1``/!80`#P7$``V0A``-D)0`#9&$`
+M`V1E``*\`@`"0@P``X(J``-(G0`"LW\``D1#``)D0@`#:)T``VBA``-HM0`#
+M:+D``J$.``/P`@`"-M\``K`0``/!$``#P2```\$P``-CH``#8Z0``V/@``-C
+MY``#27P``K3[``)!%``#:7P``VAK``/T```!S`4``C`H``(O[P`#0````_\`
+M``/_```#H`P``Z$<``.!$``"81```P\>``/HT``"H/X``_!!``*]`0`#P<X`
+M`T@(``/_```#A.@``F`$``-H"``#29@``K7[``)!%0`#:9@``K0/``)@!``#
+MZ#```\$N``-H,``#27$``X'A``/!!@`"87$``\$N``/H,``#:#```BU(``/X
+M`0`#0`T``_\```*P`0`"0`8``A=I``*@_@`#\`(``J#M``/P!0`"NSX``DNV
+M``.KL``#]`0``_`&``.F:@`"QFX``PNF``/T!``#\`$``^BP``-(&0`"LN``
+M`D9B``)F:P`#:!D``TGE``/_```"1F(``F9K``-IY0`#P:L``BT(``(M80`"
+MM`\``C%$``-*0``#^`$``J1```/P!@`"I$$``_`$``*D0@`#\`(``J!#``(7
+ME@`"RJX``K`@``*@H``#\$$``^B@``*@JP`"%\```T@9``*RX``"1F(``F9J
+M``-H&0`#2>4``_\```)&8@`"9FH``VGE``/T!``"%W8``J/^``(7R@``T=``
+M`J#>``(7GP``T=$``LW>``/T!``"%U4``$'1``/_```#_P```J"H``(7R@`"
+MH:@``_!(``-((0`#`XH``X,P``)G<P`#:"$``VJ)``/T!``"%\H``T@9``*R
+MX``"1F(``F9H``-H&0`#2>4``_\```)&8@`"9F@``VGE``-()0`#`Z@``X,P
+M``)G<P`#:"4``VJ-``/T!``"%\H``T`1``/HP```\>4``KB```)G>``#8!$`
+M`TF8``*U!``"814``VF8``-("``#_P```X3(``)@!``#:`@``_@#``/L````
+M:C$``^@```""#```@<\``CC*``-`)``#_P```_\```)`#@`#\$L``T`0``*\
+M!``#W,```X_J``*@W@`#\`$``^CP``/8\``"O`D``\&Q``(MBP`#0"0``_\`
+M``*\`@`"0`P``_!+``-`$``"O`0``]S```*_P``"H-X``_`!``*_@``#V/``
+M`XSD``/!L0`"+8L``BO$``*T!@`"M0@``K8$``(XK@`"OQ@``CA<``(X@P`"
+MOP```B_T``-*<``#_P```_\```*RD``#:G```K\3``(X7``".(,``T`D``/_
+M```#_P```D`.``/P2P`#0!```KP$``/<P``#C^H``J#>``/P`0`#Z/```]CP
+M``*\"0`#BQ```BV?``-`)``#_P```KP"``)`#``#\$L``T`0``*\!``#W,``
+M`K_```*@W@`#\`$``K^```/8\``#C.0``XL0``(MGP`#2G```_\```/_```"
+MLH```VIP``*_&``".%P``CB#``*_```"+_0``TIP``/_```#_P```K*0``-J
+M<``"OQ,``CA<``(X@P`#0"0``_\```/_```"0`X``_!+``-`$``"O`0``]S`
+M``./Z@`"H-X``_`!``/H\``#V/```KP)``/!L0`"+8L``T`D``/_```"O`(`
+M`D`,``/P2P`#0!(``KP$``/<P``"O\```J#>``/P`0`"OX```]CP``.,Y``#
+MP;D``BV+``(X[``#[````^@```/````"L;\``\$@``*S_P`#:&```C`H``(O
+M[P``"BT``!'^```9_0`"L`(``J#>``/P00`"L`0``X$6``)@`0`#@BH``K&$
+M``)B(0`"I#X``_`!``*S!``#P1\``VI@``-*9``"M(```!'L``)`!``"M`,`
+M`F`$``*S$``#:F0``BZ]``*_"``"3_```_`!``#R#``#[`````(,``/_```#
+M_P```J4.``/P`0`#[````^@```""#``#0!(``_\```/_```"1(X``J!.``/P
+M`0``\>4``K]```*@W@`#\`,``FJO``/T```#\$$``FN_``-@$@`"+NP``'G/
+M``/_```#0"```J#^``/P00`#[````J#>``/P!0`"P`X``_!!``*P_P`#]```
+M`_!#``+!'@`#\$$``K'_``-@(```\<\``^P```*P`0`"L0(``\$D``/H,``#
+M:F@``\$E``*P$P`"L0(``X(F``/H,``#:G```K`A``*Q`@`#P28``K,!``-J
+M=``"L`$``K$"``*R#P`"LP$``VIX``-*?``#_P```K````*Q```"LP0``VI\
+M``/L```"L`$``K$1``*R$``#:D0``K$0``/H(``#:D0``J#>``/P`P`"NU,`
+M`_0```/P00`"NUL``-GL``-("``"M$```('F``)@!``#:`@``T@!``*POP`"
+M1$```V@!``/H```"L4```^@@``/H,``#:D0``K`!``/H$``#Z"```^@P``-J
+M8``#[````C`H``(O[P``(>8``_\```-("``#_P```\$$``-H"``#[`````HR
+M``!J,0`#_P```D`>``/P00`#[````CC*``*_```"+_0``#(:``/_```"M0D`
+M`Z9B``+&;@`"Q&X``CBN``-`*``#Z/```J#>``/P00`"OT```/G@``.@#```
+M@<4``T`8``-`'0`#0"X``&'E``/_```#_P```V%0``-A50`#85H``.''``-`
+M$```>>```KP$``/<P``#V/```KP)``/!L0`"+8L``^C```#AS@`"L!```K$`
+M``*R$``"LP```V)T``*P@``#V`$``K````/<`0`"L!(``K$"``*R$@`"LP(`
+M`V)T``*P$``"L1(``K(0``*S$@`#8G```V)$``-B3``#8D@``\&,``/!G``#
+MP:P``\&\``(YVP`",;@``K\3``(X7``"+NP``&'.``/_```"L````]P```*P
+M0``#C\(``L`/``/8```#0!@``J#>``/P00`#0!P``T`M``/_```#U!X``]1?
+M``*_`0`#W/```K\```.(P@`"S_@``]CP``/$```#Q!$``\0B``/$,P`"H-X`
+M`_!!``/!9P`"M1$``D1E``/$1``"P`0``K4B``)$90`#Q$0``L$4``*U1``"
+M1&4``\1$``+")``"M8@``D1E``/$1``"PS0``]0>``!YQ0`#0G4``T)R``)/
+M_@`#\$(``L`!``+"(P`"H00``_!&``*E"0`#\`0``\&,``/!D``#P:P``\&P
+M``*C"0`#\$(``\&L``/!L``#8G(``T)&``*A)@`#\$8``J4I``/P!``#P8P`
+M`\&2``/!K``#P;(``J,I``/P0@`#P:P``\&R``-B1@`"H/X``=FN``-"3@`"
+MH14``_!&``*E&0`#\`0``\&,``/!D0`#P:P``\&Q``*C&0`#\$(``\&L``/!
+ML0`#8DX``T)*``*A-P`#\$8``J4Y``/P!``#P8P``\&3``/!K``#P;,``J,Y
+M``/P0@`#P:P``\&S``-B2@`#8G0``_L!``*Q$``"S,X``.'.``*@P0`!V3<`
+M`T)P``-"10`#_P```L@"``.H@``"RD8``ZJ@``-"3``#0DD``_\```+)`@`#
+MJ9```LM&``.KL``".=L``T`0``!YX``"O`0``]S```/8\``"O`D``\&Q``(M
+MGP`","@``B_O``-!4``#054``T%:``!AQP`#_P```_\```-@&``#8!T``V`N
+M``#AY0`#[````KLA``*[$````<4``_\```/_```"0`X``=H3``.IA``#JZ0`
+M`KP/``.(@``"2(P``XJ@``)*K``#2)P``TBA``*@W@`#\$(``TBT``-(N0`#
+MP1@``\%:``.,%@`#CU8``F$<``)E7P`"H-X``_`$``-HG``#:*$``_0```/P
+M0@`#:+0``VBY``-*Z``#2NT``J#>``/P0@`#2O```TKU``*\[@`"0`P``D1,
+M``.(E@`";)@``F`,``.*M@`";+H``F1,``*@W@`#\`0``VKH``-J[0`#]```
+M`_!"``-J\``#:O4``^P```*_!0`"O````J#>``/P00`"O$```]SP``/8P``"
+MO(```FB,``)IG``":JP``FN\``/!"``".BL``\$)``(Z*P`#P0H``CHK``/!
+M"P`".BL``]2>``/[```#U)X``^P```/!$``#P2```\$P``/4'@`#^P```]0>
+M``/[```#[````&HQ``(M"``#Z````K%@``/H(``#Z#```VF@``-)F``"N`\`
+M`K7U``*S```#P2X``F`(``)!%0`#:#```K\!``(M!``".,H``C`H``-`+``"
+MOP0``_\```)/\``#K_(``^CP``(O]```,AH``_\```*U"0`"Q&X``CBN``/H
+M\``"H-X``_!!``*_0```^>```%G'``!YX``"O`0``]S```/8\``"O`D``BV+
+M``/HP```X<X``.'&``/H@``#Z*```CG;``*_0``"O````]S!``/8\0`"OT``
+M`]S@``/8\``",;@``K\3``(X7``"+NP``J#>``/P00`#P:L``&'.``!YQ@`#
+MU%\``_L!``/07@`"NP(``J'^``/P00`#P4H``J#^``/P00`#P5H``J#[``/P
+M00`#P6H``J;[``/P00`#P7H``]1>``/[```"L!```LS.``*EP``#\`8``.'.
+M``/!C``#P:P``CG;``/T```!VFL``K$$``+/_@``^<8``J'Q``':I@`#Z+``
+M`-G.``/!BP`#P:L``CG;``!YX``"O`0``]S```/8\``"O`D``\&^``(MBP`#
+MW.```KM```/8L``#]````=IK``(X[``"N`@``KH(``(YVP``6<<``'G@``*\
+M!``#W,```]CP``*\`P`"R[P``KP)``(MGP`#2`@``K1@``)@!``#:`@``TF8
+M``/_```"L@$``^@P``-H,``#[````K0$``)&-``"H&0``=K*``/H\``"/?0`
+M`K\!``(]]``#:&L``T))``(R9@`#8DD``^P```-"30`",F8``V)-``-(9``#
+M^`$``KT,``))T@`"H-D``_!&``*_`P`".RD``K\#``*]```".PH``^P```*]
+M!``"2=(``_`&``*_`0`".RD``K\!``*]```".PH``^P```*]"``"2=(``_`&
+M``*_`@`".RD``K\"``*]```".PH``^P```*]8``"2=(``J#9``/P1P`"OP,`
+M`CNP``*_`P`"O0$``KP!``(["@`#[````KT@``))T@`#\`<``K\!``([L``"
+MOP$``KT!``*\`0`".PH``^P```*]0``"2=(``_`'``*_`@`".[```K\"``*]
+M`0`"O`$``CL*``/L```#2&(``DS.``(;'``#@/(``\````.!^``#P!$``DW>
+M``/P10`#P````FJ@``)*H0`#]`0``_`#``/`$0`"2J```FJA``-H8@`"L/(`
+M`FJ@``*@"@`#\$<``TA```*T"``"M?<``F$4``-H0``"014``VA```-H:P`#
+M[````TA4``/H@``"N0,``DO^``/P`0`":(D``KH"``*Y#``"2_H``_`!``)H
+MB0`"8S@``VA4``/HD``"M`0``DO^``/P`0`":9H``DOZ``/P`0`":90``TE@
+M``-H:P`#_P```_\```-(90`#_P```DO6``*@O0`!VZ<``DN3``';/@`#0"@`
+M`X3P``"B`@`#HB8``C%$``,"+@`!VTT``T@$``*T[P``BBP``D$4``-H!``"
+MM8```DO^``/P!0`#2)@``K2_``)#-``"8S4``VB8``)+^@`#\`4``TBP``*T
+MOP`"0S0``F,U``-HL``"/>@``K8$``-H,0`#0"@``C%$``)!&@`"&Y```$H!
+M``/_```"N(```\"9``.)G``"2_X``_`&``-)/``#2)D``F,X``)D20`#:3P`
+M`VB9``)+^@`#\`8``TE```-(L0`"8S@``F1)``-I0``#:+$``DO^``/P!@`#
+M2)```TB5``)@"``"9$@``VB0``-HE0`"2_H``_`&``-(J``#2*T``F`(``)D
+M2``#:*@``VBM``-`*``#_P```K@$``)!&``#\`$``CQH``-`*``#_P```K@(
+M``)!&``#\`$``CTJ``-(0``"N(```DO^``/P`0`"81@``DOZ``/P`0`"8B@`
+M`VA```*\`0`#[````TA4``/`B``"0S@``VA4``-"20`",F8``V))``*\```#
+M[````T`H``#YNP`"N`@``D$8``/P`0`"/4$``T`H``/_```"N`0``D$8``/P
+M`0`"/+<``T`H``/_```"N`(``D$8``(;YP`"2_X``AO*``-)/``#2)D``KA_
+M``)#.``"1$@``VD\``-HF0`"O`(``DO\``(;U``#24```TBQ``*X?P`"0S@`
+M`D1(``-I0``#:+$``DO^``(;W0`#2)```TB5``*X?P`"0`@``D1(``-HD``#
+M:)4``KP"``)+_``"&^<``TBH``-(K0`"N'\``D`(``)$2``#:*@``VBM``-`
+M*``#_P```K@.``)!&``"'`<``CT4``)!%P`#:,@``T@(``*X$``"01@``=P'
+M``)+_@`"&_P``T@@``*T`0`"M?P``F$4``-H(``"014``V@@``*\`@`"2_P`
+M`AP&``-()``"M`$``K7\``)A%``#:"0``D$5``-H)``"-N0``DO^``(<#@`#
+M2)@``K3```)C-``"0S0``VB8``*\`@`"2_P``AP6``-(L``"M,```F,T``)#
+M-``#:+```KP#``(]R``#2$```KA_``)+_@`#\`$``D(H``*\`@`"2_P``_`!
+M``)!&``#:$```T@(``*X$``"01@``=PQ``-`*``"O`0``_\```),P@`#\`,`
+M`CU8``/T```#\$$``CW+``).[@`!W#,``KP(``(]R```>;L``_\```/_```"
+M2_X``_`$``-(F``"M#\``D,T``-HF``"O`(``DO\``/P!``#2+```K0_``)#
+M-``#:+```TA```*X(``"2($``AQ*``(]Z``"M@(``V@Q``-)?``"N`(``DB`
+M``(<40`#27$``CWH``-H,0`#2`0``"(L``/_```#_P```\$4``-H!```>;L`
+M`K@```*\`@`#2%0``DO^``/P`0`"N`,``DO\``/P`@`"O`P``FB,``/`B``"
+M0S@``VA4``.`^```@@(``^P```-("``"N!```D$8``'<>0`"2_X``_`$``-*
+M5``"M`\``F`$``-J5``"NP(``DO[``/P!``#2E@``K0/``)@!``#:E@``DO^
+M``/P!``#2E0``K3P``)@!``#:E0``KL"``)+^P`#\`0``TI8``*T\``"8`0`
+M`VI8``-("``"N!```D$8``'<EP`"2_X``_`$``-*5``"M`\``F$4``-J5``"
+MNP(``DO[``/P!``#2E@``K0/``)A%``#:E@``DO^``/P!``#2E0``K3P``)A
+M%``#:E0``KL"``)+^P`#\`0``TI8``*T\``"810``VI8``-("``"N!```D$8
+M``/P`0`#[````DO^``/P!``#2E0``K0!``)B)``#:E0``KL"``)+^P`#\`0`
+M`TI8``*T`0`"8B0``VI8``/L```#2`@``K@0``)!&``!W,@``DO^``/P!``#
+M2E0``K3^``)")``#:E0``KP"``)+_``"',@``TI8``*T_@`"0B0``VI8``)+
+M_@`#\`0``TI4``*T#P`"010``VI4``*\`@`"2_P``AS5``-*6``"M`\``D$4
+M``-J6``#2`@``K@0``/_```"01@``=SG``)+_@`#\`0``TI4``*T\``"010`
+M`VI4``*\`@`"2_P``ASG``-*6``"M/```D$4``-J6``"2_X``_`$``-*5``"
+MM`\``D`$``-J5``"O`(``DO\``(<]``#2E@``K0/``)`!``#:E@``T@(``*X
+M$``"01@``=T%``)+_@`#\`0``TI4``*T\``"0`0``VI4``*\`@`"2_P``_`$
+M``-*6``"M/```D`$``-J6``"O`@``CW(``(]%``#P=\``DO>``/P`@`"OP``
+M`CWT``*\`@`"2]P``_`"``*_`0`"/?0``\']``/L```"M_P``K8S``*U1``"
+MM````TC(``*@_@`#\$$``K0!``*\`@`"H/P``_!!``*T`@`"810``VC(``)@
+M!0`#:,@``_\```)`!@`#:,@``KP"``(]R``#[````T@(``*X$``"01@``=T[
+M``)+_@`#\`0``TB8``*T?P`"0B0``VB8``*[`@`"2[\``_`$``-(L``"M'\`
+M`D(D``-HL``#23@``X3R``/`1``"0B0``VDX``/L```#23@``X3R``)B)``#
+M:3@``T@(``*X$``"01@``_`!``/L```"2_X``_`$``-(F``"M(```F(D``-H
+MF``"NP(``DN_``/P!``#2+```K2```)B)``#:+```^P```-"20`",F8``V))
+M``)!_@`"'64``T.N``*P[P`#_P```DNP``)*L``"2;```DBP``-CK@`"L0(`
+M`D'Q``(=<``#0^X``K#O``/_```"2[```DJP``))L``"2+```V/N``-(5``#
+MC/@``F(L``-H5``#270``KS?``)$+``#P5,``CWH``-H,0`",40``KP0``)D
+M3``#:#$``C%$``-(5``"O)\``D(L``-H5``#270``_\```/!0@`#P5,``CWH
+M``-H,0`"0?X``AV3``-#K@`"L!```_\```)KL``":K```FFP``)HL``#8ZX`
+M`K$"``)!\0`"'9X``T/N``*P$``#_P```FNP``)JL``":;```FBP``-C[@`"
+MO`(``D?^``),_``";,<``K<#``*@?P`#\$$``^C```-(R``"N$```KD_``)@
+M"``"81P``VC(``)`"0`#:,@``\#,``)!'``#:,@``KO\``)*_@`#\`@``T@A
+M``/_```"95X``V@A``-JB0`"15L``V@A``-JB0`"N@(``DJO``/P"``#2"4`
+M`_\```)E7@`#:"4``VJ-``)%6P`#:"4``VJ-``/L```##,X``=W(``/L```"
+M/>@``K8"``-H,0`"M@$``TF>``*\$``"9*P``\%;``-H,0`#29H``KP"``)D
+MK``#P5L``V@Q``/_```#270``KP0``)D+``#P5,``V@Q``(Q1``#P,P``D1,
+M``-H,0`",40``\%*``/!6P`#:#$``^P```/!;@`"MP,``DW^``/P`@`"O0(`
+M`D=]``*]`@`"3?T``_`"``*]`0`"1WT``^P```*X!``"L0(``K"```)/_@`#
+M\`$``K#```(^0@`"L0,``K````)/_@`#\`$``K!```(^0@`"L0,``K"```)/
+M_@`#\`$``K#```(^0@`"L00``K````)/_@`#\`$``K!```(^0@`"L00``K"`
+M``)/_@`#\`$``K#```(^0@`"3_X``_!'``-'-``#1SD``_\```-G-``#9SD`
+M`_0$``/P!0`#1W0``T=Y``/_```#9W0``V=Y``/L```"N`0``^@```/H$``#
+MZ"```^@P``)/_@`"'C```V4L``-E,``#930``V4X``-E/``#]````=XU``-E
+M;``#97```V5T``-E>``#97P``K$&``*P```"3_X``_`!``*P0``"/D(``K$&
+M``*P@``"3_X``_`!``*PP``"/D(``^P```+""``#W!```]@```/<$0`#V"$`
+M`]`>``/07P`"O`<``]0>``/47P`#^P```_L```/[`0`#^P$``]`>``/07P`#
+:#,X``=Y*``/L```#_P```_\```/_```#_P``
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/VERDE_me.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_me.bin.uu
new file mode 100644
index 0000000..ad4aba2
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_me.bin.uu
@@ -0,0 +1,194 @@
+begin 644 VERDE_me.bin
+M?$"``8@```#40`!_?$"``8@```!\0,`!S$``*,Q``"E\0(`!B````-A``![$
+M$``A)1```I4`__Y\00`!Q!P`)L0@`"38```<S(``"\W!H-G.`:#:V$``',04
+M``>50``"V4&BI,0;``+8```;S8``&L`^``3,`:'TS#T@!,0]``',```%V$``
+M&]A``!]\0(`!B````,Q!+@',02X"S$$N`\Q!+@!\0(`!B````'Q`P`&,``4G
+MS$$N`<Q!+@+,02X#C``%*\Q!+@!\0(`!B````'Q`P`'$&``PQ!P`,7W90`)\
+MU@`.Q"0`%9I`__^:```#S,``%(````#`*(``SH$P2L0\`'\DD``"P"H``7Q`
+MP`&5```#Q!0`,'S4P`$4S``"S,$EQ]1I)<A\0(`!B````'Q`P`$8T`'H),P`
+M?WQ!0`%06``@?5E`&GQ!@`%07``@?9V`&GQ!P`%08``@?>'`&GQ"``$E)``!
+MS,``(]%``"31@``ET<``)MA``">60``,Q"@`+)J`___()``M?EZ`#)J`_YP2
+M+``&!NP``0KL``&:P/__V$``)X```&#$*``LFH#__WQ`@`&(````?$#``<00
+M`##,027,?04``<Q!)<_-`27.?$%``230`'\56``0)50`_\T!)=/-@271S4$E
+MT,Q!)=)\04`!?$&``1C<`#`8X``Q&.0`,ACH`#,8[``TS$$EULQ!)=?-@275
+MS4$EU,`R``260``AEL```LPQ)=G,,278EH``!);```+,,27;S#$EVGP#`!&6
+MP``#Q#$``5,P`"#$-0`!?S<`&M,``!:6@``(?`.`$9;```/$.0`!4[@`(,0]
+M``%_OX`:TX``%Y7`_V":P``$?7<`#)<`_^2`````4;@`('^7@!I_.X`,EX#_
+MWX````"6`/]6S#$ES<R```O$-0`!ET#__'Q`@`&(````Q"``)GQ!0`'&)P/D
+ME4```LP```',```)"F0``<Y@`^1\0(`!B````'Q`P`'`%@`$)-#__WT5``K,
+M@``+S!$``!C8`#X4W``?Q"$``7Q"0`&5P``%?E:`"LP```O,*0``Q"4``7XF
+M``E\0L`!E8``!7[7``K,```+S#$``,0M``%^+@`*)1#__\P```O.$0``@```
+M`'Q`P`',0```@````,R```O-02)=S0$B7,Q!H?Q\0(`!B````,R```O,02)7
+M?$"``8@```#,02)<S$&A_'Q`@`&(````P`X``<Q!(ES,0:'\U$VA_7Q`@`&(
+M````S(``"\Q!(EU\0(`!B`````A,``%\00`!S(``"WQ!0`$E6/__&5P#\!5@
+M`!7-@:$"S<$B5LX!(ER4P``$S0&A_`C,``&```#TS0&A_,P!H0)\0(`!B```
+M`'Q`@`'`*@`"?$#``7Q!``%]*0`*))0``228``8DG`,`%=P`"'Q"``%\0D`!
+MP"X`!,R```N50``,!?`B6'\O``K,,0``Q"D``<S!(6G-`2%JSH$A:S&T``+,
+M`2%LET``"H```2XQM``"ET``!\`N``0%\")8?R\`"LPQ``#$*0`!@``!+C&T
+M``"70``#?@*``8```2XQM``$ET#^UR)D`##.`2%MSD$A;L0J``#$+``),?``
+M`#'T``$Q^``"FL```HP``R/:@:*DEP```\Z!HK>`````ET```\Z!HKN`````
+MEX```\Z!HK^`````SH&BPX`````$&```@``!0P08``'$)``F?$#``<9K`^08
+MT``P)-0`_P:H``'.I`/DFD``$L0X``?80``>Q#P`(2?\``*7P/_^S(``"Y>`
+M``+90:*DQ#\``L_``!K`/@`$S`&A],P](`3$.0`!S```!=A``!_-0:#:S(``
+M"\U!+A29@``"S````LU```A\0(`!B````'Q`P`$8T`'H&-0`,!C8`#0%*`%K
+M?$(``7Q"0`&5```'AH```(```86```&I@``!OX``!2.```%[$50`$'X6``K,
+M@``+U&$``)6`_HO`.@`$S#DA0,0Y``%\0(`!B````!%4`!!29``@?B8`&LU`
+M`!W48@``E8#^@,0@`!V:`/__?$"``8@```#<.@``F4``&R><``&5P``-"[@`
+M`<X!(6G.02%JS$$A:\P!(6R;@``#E8#^<8```9U29``@?B8`&D8@``16)``@
+M(F0`,LX!(6G.02%J"[@``LQ!(6O,02%LFX#__96`_F3$,``9EP#__WQ`@`&(
+M````"[@``<X!(6G.02%JS$$A:\P!(6R;@/_[E8#^68```9U29``@?B8`&IE`
+M``K2```KU$``+-A``"V,``4TE8#^4,0X`"^;@/__?$"``8@```#<-@``"W0`
+M`=(``"O,0``LV$``+8P`!32;0/_[F8#_]7Q`@`&(````Q!P`,,`J``%^'@`!
+M%B```LX!)<?4:27(E8#^.\`Z``3,.27+Q#D``7Q`@`&(````?$#``7Q!``$9
+M%``]F4``"L0<``V5P/__S,$A`,T!(0',P2$"S0$A`]D!HJ1\0(`!B````,S!
+M(77-`2%VQ"``#I8`__\R*``",BP``YJ```2:P``%S```#(````#,```,@``!
+MV,`^``3,/3!^Q#T``3/H``&7P/X8FH`#/00X0`#,```!SX$P2H``!29\0,`!
+M?$$``4#4``/-02)<S0&A_,`>``%\0@`!",P``08D``$&*``"SAVA_<Y=H?W.
+MG:']F,#_^7Q`@`&(````?$#``230``$4S``!?$%``7Q!@`',@``+E0``!B&8
+M`##-02%MS8$A;L0>``"```(.P"(`!'X6``K,(0``Q!T``7Q"0`%\0H`!F,``
+M`\WE``"`````SD$A:<Z!(6K-P2%KS`$A;'Q`@`&(````?$#``7Q!``%\04`!
+M?$&``7Q!P`$8I!_H,F@`/`0@``&6@``(?$(``3HP``-"(``"FP```@0@`$`$
+M)``!@``"*GX"0`$*9``!FD#__R3L`!#,@``+FL``"<`J``3$+``0?I*`"LP`
+M``',*0``SL``$,0Q``&```([(50`,,T!(6W-02%NQ#(``'\?``DD]``'!W@"
+M/Y=``">'@```@``"1X```DR```)1@``"5H```EN```)@@``"97\;@`\4I``(
+MEX``'29D`/^```)V?QN`#A2D``B7@``8)F0`_X```G9_&X`,%*0`")N``!,F
+M9`#_@``"=G\;@`T4I``(FX``#B9D`/^```)V?QN`#Q2D``B;@``))F0`_X``
+M`G9_&X`.%*0`")N```0F9`#_@``"=A2D``@F9`#_,F@`/!3L``B:@/V7?$-`
+M`7Q#@`%\0\`!S```"Y;```;/02%ISX$A:L_!(6O,`2%L@````,_U``"`````
+M,F@`/)J`_[/40`!_@````'Q`P`%\00`!P!X``144`!+`(@`"P"8`!)5```3`
+M)__[?24`"<`F``!]TH`)?A+`"7TE``I\04`!?$&``<S!(6G-`2%JFH``!\U!
+M(6O-@2%LEL#]<L0P`!F7`/__@````,@4`!A56``@S4$A:\V!(6R6P/UJ@``"
+MCWQ!``%\04`!S$```\Q```3,``/DS``#Y<P``^;`#H``?$)``7Q"@`&`````
+M?$#``1C0`>@%*`*I',S^",R```N5```)AH```(```K2```+#@``"RH```M&`
+M``+7@``"XX```P',P:*D?$"``8@```#`$@@`?$%``7Q"``%]#,`*P!(`!!58
+M``,57``-?='`"1(@`!-^'D`*?DZ`"LZ!HJ3-@:'^?$"``8@````$$"$8Q!0`
+M"Y5`___440``S,&BI'Q`@`&(````!!`A!L04``R50/__U%$``,S!HJ1\0(`!
+MB````-A```_,P:*DQ!``#YD`__]\0(`!B````!C0`#01%``4Q"0`#99`___,
+M02$`?45`"LU!(0',02$"S$$A`\S!HJ1\0(`!B````"38``%\00`!?$%``1&<
+M`!!\0@`!?5U`"A5D`!TF9``"E8``"<0\`!^7P/__FD``#<0H`#`6J``"?BH`
+M`<P``!6```+[Q#P`()?`__^:0``%Q"@`,!:H``)^*@`!S```%<T!(5C-02%9
+MS@$A6LS!HJ1\0(`!B````!C0`#01%``4)-@`/Y4`_ZW$)``-ED#__S6<``;,
+M`2$`S4$A`<P!(0+,`2$#F<```]D!HJ2`````!"``%,X!HJ1\0(`!B````'Q`
+MP`$4T``=&-0`/"38``'$'``EF0```H````"90``#E8```LW```C-0``<@```
+M`'Q`P`&,``,C?$"``8@```#80``>Q#P`(2?\``*7P/_^S(``"]E!HJ3$/P`"
+MS\``&L`^``3,`:'TS#T@!,0]``',```%V$``'Y````!\0,`!!#P`(LR```O/
+MP:*DS```!GQ`@`&(````P!(``7Q10`K,@``+U%4``'Q`@`&(````?$#``5!0
+M`"!\T,`:51P`/WQ!0`%\08`!S(``"]#``(.5P``#P!R``,W!(!"5@/RVC``%
+M)]V#```%7"``S```"]1=``"```4O?$#``5!0`"!\T,`:?$%``7Q!@`',@``+
+MT,``A)6`_*B,``4GW8,```5<H`#470``@``%+WQ`P`%04``@?-#`&GQ!0`%\
+M08`!S(``"]#``(65@/R;C``%)]V#```%7"P`U%T``(``!2_,@``+U$,@`'Q`
+M@`&(````S(``"]1#H`!\0(`!B````,R```O40RP`?$"``8@```!\0,`!C``%
+M)WQ!``%\04`!E,```GQ!@`%\0<`!?$(``8P`!2N5```*E4``"<R```O,0RP`
+MS<,L`,R```O,0RP`S@,L`'Q`@`&(````Q"0`'LQ``'_,0`!_&F@`,'Q`@`%\
+M0,`!EH#\<-B``"Y\0(`!B````,R```O,0Z``?$#``008``'=@P``C``%)]1#
+MH`"```4O)(S__\R```O430``?$"``<R```N(````?$#``1C4`#`8T`'H&/P`
+M-"3,``\$Z`.K?$&``7Q!P`&4P`!*AH```(```\.```/+@``#U(```^.```.V
+M@``#N8```[N```.]@``#OX```\%1W``@?9X`&H``!`+((``M@``$`L@@`!:`
+M``0"R"``%X``!`+((``8@``$`L@@`#*```0"F4```R'<`#"```/'(=P`4,V!
+M(6W-P2%NR"(``(``!`)1W``@?9V`&M@``"/1@``DV$``)\0H`"R:@/__R"``
+M+H``!`+$'``PP#(`!'V=@`$5F``"S8$EPLPQ)<.50``#S(``"\PQ)</$(0`!
+ME4``),0E``%29``@?B8`&H``!`(QK`@`Q#0`$);```/,```!@``#]3FL"GP]
+ML`IWFL``!)<```/,```!@``#]3FL"MP]L`K9FL```Y<```+,```!@``#]<0T
+M`!#,@``+P#H`!'VY@`K,&0``E4```P68``',&0``Q"$``95```7$)0`!4F0`
+M('XF`!K/0``0!2@$!GQ!@`%\0<`!E0``!X:```"```0W@``$08``!$^```0:
+M@``$+,0T`!#,@``+SAD``)5```0%F``!5B``(,X9``"7P/OMP#H`!,PY(4#$
+M.0`!ST``$'Q`@`&(````,:P(`,0T`!"6P``#S````8``!`TYK`I\/;`*=\0T
+M`!":P``$EP```\P```&```0-.:P*W#VP"MF:P``#EP```LP```&```0-4=P`
+M('V=@!K8```=SAH``)5```0%F``$5B``(,X:``";P`"0?$"``8@```"50``"
+M(=P`,E8D`"#-@2%IS<$A:LX!(6O.02%LF\#^47Q`@`&(````4=P`('V=@!K1
+M@``KS@``+)5```-6)``@SD``+-A``"V,``4TE\#[ML0X`"^;@/__?$"``8@`
+M``#$'``PP"H``7V=@`$5F``"S8$EQ\XI)<B50``#5B0`(,YI)<B7P/NHP#H`
+M!,PY)<O$.0`!?$"``8@```#$%``</5@`!)F`__[,```-?$#``2A0@``5%``?
+M&1@`?1D<`'3$(``P,9@``3'<``&5@``"?.#``7Q"0`&5P``"?F)``<S!(8#-
+M`2&!SD$A@LQ!(8/,02&$E4#[C,04`!R90/__?$"``8@```#`%@`$Q!``)LR`
+M``O,52%`Q!D``<P0`_=\0(`!B````,0@`";8```>Q`P`(23,``&4P/_^QB<#
+MY'Q`P`',@``+S,$A?,Q!(7W$&``D?$$``7Q!0`&60``"S8$A>LT!(7[`-@#`
+MP"H`!']/0`D17``!!=P``9=``!3,*2%_Q"4``1IL`#Z6P``'$5P``07<``$)
+MW``!F<#__\R```N```27%W0`%R@L`&";0``"*"P`0,[``"/80``GQ#0`+)M`
+M__^```2O"=P``9G`___,@``+S"DA?\0E``$6;``?$5P``07<``&:P/_X%/P`
+M']@``!^;P/M+Q!``)LP0`_=\0(`!B````'Q`P`%\00`!%1@`'U$4`"`9'``Q
+MF8``",T``!U]34`:U%8``)7`^SW$(``=F@#__X````#<.@``P"8`!,S!(6E]
+M)0`*S0$A:@NX``+,02%KS$$A;)N`__V9P/V_?$"``8@````D3`#_S$P#`'Q`
+M@`&(````Q"``)L1/`P#,@``+S.$A18````#,@``+VL&BI'Q`P`%\0(`!B```
+M`,0,`!J8P``#V$``+X``!.'80``P?$$``7T!0`$55``!)50``9E```DE$``!
+ME0#[%,@4`#250``%R!@`&Y6```-]E<`.E<#[#L@@`#/2```RV```'L0@`"$F
+M(``!E@#__L`F"$#.02%\S`$A?<0H`"3.@2%ZS`$A?L`J``0$%``$05P`""@L
+M`$#.P``CV$``)PG<``&9P/__S(``"\PI(7_$)0`!%FP`'T%<``*:P/_YQ#0`
+M+)M`___8```??$"``8@```#$#``3,-```94```/,@``+VP&BI,Q```[$#``2
+MQ!``$S#4```]&``!?5G`"MA``#&9P/_ZV$``$]```#)\0(`!B````,`.`0#,
+M```!S,$P2H``!2;80``1Q#P`$9?`__V0````V```$<0\`!&;P/_YD````-@`
+M`!'$/``1F\#_]7Q`@`&(````V(``'L0\`"$G_``$E\#__L`X`"_`/@`$SX$A
+M^,P](?G$.``F!#P`!7_[@`+$/0`!?_O`!2?\``&;P/_VV(``'Y``````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````0.<`!```@`1``4`$@`*`!4`)0`6`"L`%P"Q`!L`-``<`$$`'0!O`!X`
+M3``A`+L`)`#9`"4`V0`G`.,`*`#6`"H`WP`L`-D`+0#C`"X`YP`O`.T`,`#Q
+M`#(!0@`T`0,`-0#C`#<!8P`X`-D`.0'+`#H![@`[`?X`/`(9`#T">@`_`4``
+M0`.B`$$$7@!"!'D`0P2!`$0"F`!%`AD`1@*C`$<"HP!(`J,`2@,3`%(#'P!3
+M`S(`5P,Y`%\#7@!@`S\`80-1`&@#:P!I`V\`<@-W`',#E`!V`W,`=P-S`'H$
+MN@!]!-,`?@37`(4$W`"&!.$`B@42`(L%$@`/!2,`#P4C``\%(P`/!2,`#P4C
+M``\%(P`/!2,`#P4C``\%(P`/!2,`#P4C``\%(P`/!2,`#P4C``\%(P`/!2,`
+M#P4C``\%(P`/!2,`#P4C``\%(P`/!2,`#P4C``\%(P`/!2,`#P4C``\%(P`/
+:!2,`#P4C``\%(P`/!2,`#P4C``\%(P`/!2,`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/VERDE_pfp.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_pfp.bin.uu
new file mode 100644
index 0000000..0e91860
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_pfp.bin.uu
@@ -0,0 +1,194 @@
+begin 644 VERDE_pfp.bin
+M?$"``8@```#,@```U$```'Q`@`&(````S(```,S```#40```?$"``8@````D
+M3``/,.@``B20``*:@``,?$%``5!8`"!]E<`:F,```]'``!F`````F0```]'`
+M`!J`````T<``&X````#$(``5QB0`"I9``6M\00`!?$%``<R```#,P```S0``
+M`,U```#-```MS4``+GQ`@`&(````S(```,Q```#,```2@``#E,Q``"A\0(`!
+MB````,@,`!M\Q0`1T0```]C```/,@```S````,Q```!\0(`!B````,@,`!I\
+MQ0`1T0```]D```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L
+M`'XB[$Y(EH```MB``"+.P```V````,Q```#,0```'(@`$,R```#,0```?$"`
+M`8@```#(#``:?,4`$7Q!0`%\08`!?$'``7Q"``%\0D`!E<#_J=$```/9```#
+MQ"@`$,P``!2:@``$Q"@`!<Z```#,````Q"@`"1JH`#`@+`!^(NQ.2):```+8
+M@``BSL```-@```#-0```S8```!R(`!`)W``!S(```,Y```"5P/^2?2$`$8``
+M`%C(#``:?,4`$<46``"50`,=*!@`!'T9@!'%E@``E4`#&<P``";1```GT0``
+M`]E```/$'``0S```%)G```3$'``%S<```,P```#$*``)&J@`,"`L`'XB[$Y(
+MEH```MB``"+.P```V$```,Q```#,0```'(@`$,R```#,0```?$"``8@```#(
+M#``:?,4`$<46``"50`+\*!@`!'T9@!'%E@``E4`"^'Q!0`%\08`!?$'``7Q"
+M``%\0D`!E<#_8<P``";1```GT0```]E```/$*``0S```%)J```3$*``%SH``
+M`,P```#$*``)&J@`,"`L`'XB[$Y(EH```MB``"+.P```V$```,U```#-@```
+M'(@`$`G<``',@```SD```)7`_TA](0`1@```H,08``@EF``!V```'7Q"0`%\
+M0H`!E8`"T5*L`"!^YL`:?$#``7Q!``'$'``1F<#__QR(`!`@B`!P$-0``G[5
+M0!'10``#S0```\R```#.0```SH```,S```#<.@``S0```)>`_RU\0,`!?$$`
+M`8```,G$$``/Q!P`!)D```3,```2S<```,P```#$&``()9@``H```+TDC``"
+MQ!``$,08``B8P``(F0``!<0<``7,```3S<```,P````9F``P@```O1F8`#B`
+M``"]Q!P`!,W```#,````S(```-1```!\0(`!B````,0<``3-P```S````,@,
+M`!G,@```S$```!!0``)]#0`1510`(-$```/80``#S````'Q`@`&(````Q!P`
+M!<W```#,````S(```-1```!\0(`!B````,0<``7-P```S````,0D`"3(#``<
+MQE,#Z,R```#,0```41``('S0P!I\Q0`1510`('U%@`K-````S8```'Q`@`&(
+M````?$#``5!0`"!]#4`:T4``&,P``"5\0(`!B````'Q#0`'('``8Q!@`%QR(
+M`!`@B``P?$%``7U8P`1\W,`15-``('Q!0`',@```ST.BGLS#H?K-`Z'YS4.B
+MG<U```#,0```?$"``8@```!\0T`!'(@`$""(`#!\0,`!?$$``7Q!0`',@```
+MST.BGLS#H?K-`Z'YS4.BG<U```#,0```?$"``8@```!\0,`!)-```<S#HI_8
+M0``7E0```MB``!?,@```S,```'Q`@`&(````?$#``<R```#,PZ*BS,```'Q`
+M@`&(````Q!P`'7Q`P`$QX```%-0`'WUA0`G,@```?$$``95```+,P``?%1@`
+M'\S```#-````E8```LT``"#,``!_@``#E"`(`'X@B`?HQ"``%1RH`!#.H``$
+M?$$``5!4`"!\08`!!B0``<Y``!45G``8?14`&LW@``G-H``+T2```<V@``'$
+M+``D53``(-$``!S/+`/HF@``",0D`"/$(``=?D)`'B9D``%^8D`*ED```B'<
+M`##-P```@``#E,0@`!7&#``*'*@`$)3```/.H``&@``!:,P```B```&(Q"``
+M%7Q!@`$*(``!QA0`#<88``I]68`*S@``%96```3,H``&S6``!H```Y3,H``$
+MS6``!(```Y1\0,`!%-``'C$4``&5`/YLE4`!]AC0`>@8U``P&-@`-`4H`:-\
+M0@`!?$)``94```>&@```@``#F(```YB```.8@``#F(```;$15``0?A8`"LU`
+M`"'480``E8#^4\0Y(4!\0(`!B````!%4`!!29``@?B8`&LU``"'48@``E8#^
+M2L0@`!.:`/__?$"``8@```!\0,`!?$$``7Q#@`%\0\`!41``(%/\`"!_OX`:
+M?-#`&@0<`!#3@``"V(```M#```+-P``"!!P`!`0@``%\`D`!Q!<``\0;``-1
+MF``@?5E`&L0K``/$+P`#Q#,``\0W``,)W``!4NP`('ZN@!I3=``@?S<`&G\K
+M0!)^=D`15J@`/U<P`#]^LH`)?BH`"9G`__&6@/_D4_0`('][0!I]94`155@`
+M(,P``"'-=@``S;8``,0@`!.:`/__?$"``8@```#$(``D?$#``7Q!``',X`/]
+MS2`#^E$4`"!\U,`:T,```A44`!\9&`#PF4```@0T```O7``!?78`"7U>0`F9
+M@``$S````LP```V```.4%9@``14L``@F[``!F8``,Q4P``R6```#S````H``
+M`Y0$%``0S4```B<P``$H*``!!#@`$`0\``3$%P`#Q!L``\0?``/$(P`#?5U`
+M#7VAP`U]74`*%A``'Q6<`!]]'0`)?1=`"7Z2@`D+N``$"_P``9M``!*;P/_Q
+MQ"``),8/`_W&$P/ZFH``"<P```V;``%S410`('S4P!H$%``0T,```LU```*`
+M``()S```#9;``6O,```.@``#E,P```V:P``"S```#I>`_=$+N``!Q#\``YN`
+M__V`````S```#I9```/,```"@``#E-H```+$"P`#Q`\``\03``/$%P`#Q!L`
+M`\0?``/$)P`#Q"L``Q7\`!\6L``??_/`"13P`!]_\\`)%7``'W_SP`E]B(`"
+M?<S``I?```Q^40`"?I5``GR0@`Q\U,`,?(]`"9K```(LM``!S```#9M``4',
+M```.@``#E,0@`"3&#P/]QA,#^E$4`"!\U,`:T,```H```CA\0,`!%-``'C$4
+M``&5`/VFE4`!,!C4`#`8T`'H&/P`-"3,``\$Z`)J?$&``7Q!P`&4P``2AH``
+M`(```G2```.8@``#F(```YB```)Q@``#F%'<`"!]G@`:@``"@5'<`"!]G8`:
+MF4```\6B``"```*!R:(``(```H'%H0``E4``!068``'%I0``4F0`('XF`!H%
+M*`*%?$&``7Q!P`&5```'AH```(```YB```.8@``#F(```YB```*5V```(<X9
+M``"50``$!9@``58@`"#.&0``E\#];\0Y(4!\0(`!B````%'<`"!]G8`:V```
+M(<X:``"50``$!9@`!%8@`"#.&@``F\#_&GQ`@`&(````?$#``7Q!``$9%``[
+ME4``&\04`!(]6``"F8#__AD<`'T9(`!TQ!0`)3'<``$R(``!S```(<P``",I
+M$(``E<```GS4P`%\0D`!E@```GY60`',P2&%S0$AAA44`!_.02&'S$$AB,Q!
+M(8F50/U&Q!0`$IE`__^`````S(```,S```#-````U$```'Q`@`&(````Q"@`
+M)-AH`_?,@```S$```,:/`_>8P/__?$"``8@```#$*``DQ#``#\0T``2:@``%
+MFP``!,P``!+/0```S````'Q`P`'8:`/WS(```,S```#40```%-``'YD``+J`
+M``+(S(```,Q```#,0```S$```'Q`P`',P``6S,```-1```!\0(`!B````'Q`
+MP`'$%``=%-P`'1C8`#Q\U,`*S(```,S```"9P``#F8#]$H```Y3-@``D@``#
+ME'Q`P`%04``@C``#%WS0P!K$)``5Q!0`)'Q#@`&60``(Q-8``)E``!G?@P``
+MSZ0`#XP``QO40`!_@````,5?`^Z5P/__V%0#\<5;`_25@``#V!0#\9F`__S%
+M7P/N/>```IH```?%8P/KF@``!=^#``#/I``/C``#&]1``'\)W``!S=0#[M@4
+M`_&,``,;?$"``8@```#8```>Q#P`'IO``'^0````V$``'L0\`!Z7P`![D```
+M`(P``Q?$(``5?$#``<`V_P#$$``6P#`__WSU0`E]48`)?8&`'7SS@`F9@``&
+MWX,``,^@``^,``,;U$``?X````",``,;?$"``8@```!\0,`!%-P`")7``!DD
+MW``0?$$``5!4`""9P``#Q1T``(```SU]%0`:Q1X``'Q"``%\0D`!?$&``7WE
+MP`E]XH`/0:P``IJ`_+T&[``#"NP``9K`__\DW``0F<```\4=``"```-`Q1X`
+M`(```T#,@```S,```-1```!\0(`!B````,0<``3-P```S````,R```#40```
+M?$"``8@```!\0,`!)-``!C$0``;$%``/F0``",P``!+$)`!^ED``.)E```3$
+M'``$S<```,P```#,@```S,```-1```!\0(`!B````'Q`P`%\00`!%1@`'\T`
+M`"%1%``@F8```]1-``"`````?4U`&AD<`#'45@``E<#\B\0@`!.:`/__?$"`
+M`8@```!\0,`!?$$``134`!XQ6``")-P`_Y5```29@/R`S1P#`(````#,@```
+MS,```,T```!\0(`!B````,0@`"1\0,`!Q-,#`,R```#,P```S```(<TA(4%\
+M0(`!B````-1``']\0(`!B````,0D`'Z60``#?$"``8@```"```.8````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````P-2``4!8P`&`.T`!P#T``@!`@`)`0D`$`.1`!$`"P`2`"<`$P`K`!8`
+M+@`D`#<`)0!Q`"8!&@`7`8D`(@+R`",#'P`G`30`'P&[`"`!ZP`H`5,`*@%#
+M`"P`4``O`4T`,0.1`#(!@0`S`Y$`-`-9`#4!(0`X`)(`-P&7`#P#,@`_`64`
+M0`)=`$$"H`!"`L0`0P+,`$0"W`!*`N8`50-5`%\`X`!@`+L`80#7`&D`\`!S
+M`/<`=@$%`'<!#`![`VH`?0-Z`'X#B`!_`Y$````"`````@````(````"````
+M`@````(````"`````@````(````"`````@````(````"`````@````(````"
+M`````@````(````"`````@````(````"`````@````(````"`````@````(`
+M```"`````@````(````"`````@````(````"`````@````(````"`````@``
+:``(````"`````@````(````"`````@````(`
+`
+end
diff --git a/sys/contrib/dev/drm2/radeonkmsfw/VERDE_rlc.bin.uu b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_rlc.bin.uu
new file mode 100644
index 0000000..85f70b5
--- /dev/null
+++ b/sys/contrib/dev/drm2/radeonkmsfw/VERDE_rlc.bin.uu
@@ -0,0 +1,186 @@
+begin 644 VERDE_rlc.bin
+MQ`@`)S",``*8P```,(P``9C`!<@PC``#F,```(``!]4$&``!S8``#LV``"V,
+M``%&S````LP```O,```CP#`PXB@L``/.\0``P`@Q`,2)```DC``$F,``!L`^
+M`-`K_`#_P#O__\`W__^,``&!)(P`")C```;`/@"P*_P`_\`[___`-___C``!
+M@22,`!"8P``&P#X`<"O\`/_`.___P#?__XP``8'`/A``*_P0_\`[___`-___
+MP#`@`(P``8'`/A``*_P0$\`Z@`#`-@``P#`A`(P``8',`P`(S`,`!LP#`"W,
+M`P`NQ`P`UR3@``'.`P`)).0``C)D``+.0P`*SD,`!\P#``#,`P`BS`,`(\P#
+M`!W,`P`DS`,`',P#``O`#``?$,P`""C,`!_,PP`"P!PB;XP`!8S.@P`B?H+`
+M"L`<(G",``6,SH,`(WZN@`K.@P`!EH``",`\"?_`$#$%Q14``!54``@E;`#_
+MP"0``(P``Z7`##$,Q,T``,S#``7$#P`"P!`Q`\S1``#,PP`/S`,`#<`0``#,
+M$P`0S!,`%,P3`!@%$``!,0P`!)3`__O$#3$#Q`P`.L0C``F6```%Q"<`"II`
+M``.,``'JS```+<0(``.8@/__S8``$,V``!',```2S```#L0(`#;$*``!EH``
+M!LV```XH"``!Q`P`(<R```&```"RQ`@`$)2``-C$"``1E(``UL0H``"6@``-
+MS8``#B@(``'$#``@S(```#*(`;N4@``#S`,``(```+HRB`&\E(``(LP#``"`
+M``#TQ"<``)9```/,`P``@```NL0K``Z6@``#C``$)H```'C$"``0E(#_W,0(
+M`!&4@/_:Q`@`+Y2```;$"`#7)(@`")2```B,``,$@```>,0+``V4@``$C``#
+MA(P`!4&```!XQ`@`UR2(``24@/_+Q`@`+I2`_\F,``-2@```>":H`/\4Y``$
+M$F0`""3<``]^7,`*S,``(\Z```R```!XS```+<V```[,`P``P#`P2<<)``#`
+M,@`0?+'`"97`_[?`,#$!QPD``"2<``&5P``;%*P`"";L`/_`)``!P"```(P`
+M!:R6```#S8,``(```'B,``$5EX```\0,`!"4P``#S8,``(```'C$#``<E,``
+M`\V#``"```#TP#`Q`<<)```DG``"E<``!8P``3&6```#S8,``(```/3`###7
+MQ,D``"2(``&4@/^5P`PQ#<3)```DC``!E,#_D12L``,F[/__P"```,`D``",
+M``6LE@```\V#``"```#TC``!J<0G``":0``"@```>,V```[-@``MQ`@`$I2`
+M``*,``$#Q`@`$)B```.,``%&C``%@\0(`!&8@``"C``!UL0G``":0`!=@```
+M>,0K``*,``7`P`Z``'^/@`K`#@``?T]`"B@\`*`3_``0*_P`_XP``8'`'#$%
+MQ>T``!+L`!@F[`#_P"0``(P`!9_,```2D````"@,``&,``%H*#@``8P``74H
+M.```C``!<9>```[`.#$!Q[D``!>X`!`GK`?_EL```\`D``",``6?S8```L00
+M``.5`/__S```$,`X``&0````Q`P`$93```4H.```C``!=2@,``",``%HP#@`
+M`)````#$"``/E(#__\0K``*,``7`P`Z``'^/@`K`#@``?T]`"B@\`)`3_``0
+M*_P`_XP``8'`'#$%Q>T``!+L`!@F[`#_P"0``<`@``",``6?S8``$I````#$
+M"``3E(#__\P```+$"``/Q!```YD`___`+#$>QNT``,`D``",``6?Q#@`$9>`
+M``<H.```C``!=2@X``&,``%Q*`P``(P``6C-@``0D````,0(`!R4@/\=S8,`
+M`(```/0H.```C``!=2@X``&,``%Q*`P``(P``6A\"(`)C``"TLP``"V```!X
+MP#`#D,<Y``#`"__^?XN`"1#,`!!_CX`*S[$``,<Y``"0````P#`@`\^Q``#'
+M.0``D````,`P,'C/L0``D````)>```3`$#$9Q1T``)G`__Z70``$P!`Q&L4=
+M``"9P/_^D````(P``7C`%#$5SY4``,`4,1;/50``P!0Q&,\5``#`$#$=Q1$`
+M`"40``&9```$P!0Q%\_5``"0````)]``_S$0`/^9```$P!0Q%\_5``"0````
+MP!0`",`>@`!]^<`)E<```L`4`!8)5``!?\$`"L`=_P!]'0`)?14`"L`<,1?-
+M'0``E4``!\`<,1?%W0``?='`#)7`__V,``%X@``!FI````",``+-F0``*LV`
+M`"W$#``2E,```HP``0/$#``0F,```HP``48H.```C``!=2@X``&,``%QP!PB
+M<(P`!8S.@P`CQ`\``L03`")^D0`*?-#`"<S#``&,``(4F<``%8P``M;`,"&V
+MP`H4`(P``M(H#``!C``!:"@X``&,``%U*#@``(P``7&7@``*C``%*\P``!&:
+M```'C``%>HP``167@``$S```+<P#``"```'5S8,``)````",``1[C``%#HP`
+M`N8H.``"C``!<8P``NW`#"37Q!,`((P`!"R,``+TS8``$2@X``",``%U?`B`
+M"8P``M(H.``!C``!<2@,``",``%HD````,0X`,13N``(*`@`D,>.```PU``#
+MF4``"##4``290``*E,``'LS+``!'N``$!(@``<>.``#,RP``1[@`!`2(``&`
+M``'ME,``%<`0``/,RP``1[@`!`2(``''C@``S,L```D0``&9`/_[1[@`!`2(
+M``''D@``S0L```C,``&8P/_[1[@`!`2(``''C@``P!```Y3```*```(!S`L`
+M``2(``',@P`&D````'W!P`G$$P`(Q`\`"IC```:9```#*`@`D(```AS$"P`M
+M@``"*\03``B9```(P`PPQ,3)``"8@``#P!P``9````!0B``(@``"4L0+`"Y0
+MB``(Q`\`+7R,@`J```)2Q(\``)3``"0PT``#E0``!LV#``@$B``!S(,`+<2/
+M``"```(V,-``!)D```8$B``!Q-4``,U+```$B``!@``"*P2(``'`/```Q(\`
+M``2(``&4P``1Q),```2(``'$EP``!(@``<_-```'_``!Q1T``,W+``#/S0``
+M!_P``<4A``#."P``!(@``GU_``R7`/_V@``"/7W!P`F0````Q(X``)3`__TP
+MT``#E0``"<V#``A$B``$))``_\T#`"T4D``(S0,`+L2.``"```)@,-``!)D`
+M``9$B``$Q-4``,U*``!$B``$@``"4D2(``1]P<`)D````,2/```$B``!E,``
+M&##0``.9`/_\,-``!)D```7$EP``S4T```2(``&```)HQ(\```2(``&4P``-
+MQ),```2(``'$EP``P#P``,_-```'_``!Q)\``,W1```$B``!?]8`#)8`__J`
+M``)SD````,2.``!$B``$E,``"3#0``.9`/_\,-``!)D```7$E@``S4T``$2(
+M``2```*#D````,0X`,A3N``(FX```\`<``&0````Q`L`!@2(``''C@``S,L`
+M`,>.``3,RP`!QXX`",S+``+-@P`'D````,>B``#`##!QS@T``,>B``3`##!P
+MS@T``,>B``C`##!RS@T``)````#$.P`&![@``<`,,'''HP``S@T``,`,,'#'
+MHP`!S@T``,`,,'+'HP`"S@T``)````",``+!D````,`((8'."0``P`@A@\P)
+M``#`""&`S,D``,`((8+-"0``P`@AA,U)``"0````P`@AH,2-```4S``6),P`
+M`9C`__V0````P`@AH,2-```4S``"),P``9C`__V0````P`PAML31``#`"A0`
+M?0D`"9````#`,"&VS+$``,<)``"0````*#"``!,P`!",``+@*#"@`!,P`!",
+M``+@*##``!,P`!",``+@D````"LT(8W-M0``*S0ACL`-___,]0``D````,`P
+M(`C`"/_ZS+$``,<-``#,,0``QPT``)````#$)P`*FD```R@(`)"```)HQ`@`
+MQ%"(``B```*#Q#@`R)>```[$.P`'FX```HP``H\H.``!C``!<<0G``K$.`#(
+MFD``!,0[``:,``*H@``#`U.X``B,``*>D````,V```[`'")PC``%C,Z#`"/$
+M(P`B?J*`"LZ#``&,``/0Q`@`UR2(``24@``&C``$0Y2``$'$(P`!?>'`"8``
+M`Q;/0P`%Q!\``8P``]O`%```S!<`%`54``$Q2``$E(#__8P``^2,``/SC``$
+M&L0G``]^I(`+F(```H```U%\IL`)Q`\`))3```3`,```S`,`)(```RI\JP`)
+MP`@Q`\2A``!^,@`*S@D``'YR0`K.0P`/Q`L`"Y2```7`#"37C``$-GT)``J,
+M``0LSL,`"\\#``PVR```S(,`#<`D``"7```/?P*`"L`\"O_`+#$%QNT``";L
+M`/^,``.EC``$SL`H`!",``2OP`PDUXP`!#;$,P`,?3$`"HP`!"S`#"37C``$
+M-L0O``M^P4`>?14`"8P`!"R,``.$D````,V```[`$#$$Q0D``,03``)\D(`)
+MP"`Q`\8-``!\T,`)?(U`"WU.P`E]2P`)P`PDUXP`!#9_$P`)SL,`"\\#``Q^
+MPD`>Q@T``'SDP`E\T,`)S.$``,`D``"7```,?P*`"L`\"O_`+#$%QNT``";L
+M`/^,``.EP!`Q`\4-``#$,P`,?/#`"LS1``#`)```Q"L`"Y:```G`/`G_P"PQ
+M!<;M```6[``()NP`_XP``Z7`*``8@``#@,`H`!",``3.C``$K\P#``.0````
+MS8``#L03``O`"#$&Q(T``'S`P!Y]#H`)EH``&GTI0`O-0P`+?2B`#)2```+,
+M`P`-P`@Q`\2-``!^@0`>?-#`"<S)``#$%P`/?5%`"<U#``_`)```P#P)_\`L
+M,07&[0``%NP`"";L`/^,``.EQ`L`#9B```2,``3.P"@`&(P`!*^0````C``%
+MP'^"@`K/0P`4P#```,`T``#`.```P`@``,`,``&6@``;?HU`"95``!6;```#
+M?,.`"H```[1\PT`*)]0"`)E```/-@``X@``#N<V``#F,``&!ST,`&L^#`!O`
+M(```C``%K"?4`@"90``#S```.(```\/,```YF@``"@2(``$0S``!,)0`"I5`
+M_^>;```%Q"L`%)J```,',``!@``#J<0W`!K$.P`;D````,0?``+`##$+Q/D`
+M`'^?@`G`'``*P`PQ#,3U``!_7,`.E,```GW#0`J0````?X#``<`4```DT``?
+MS1<`$!3,``@%5``!,4@``I2`__N0````?X#``<`@`"#`)``!P"@``'SD@`E^
+MBH`!%,P``0H@``&:`/_\?K2`#Y2```/`)```@``#\G]J0`*0````)=``_\T#
+M`!@5W``()=``_\T#`!D5W``()=``_\T#`!H5W``()=``_\T#`!O`#```P!0`
+M`,`@``'`'```Q=,`&'TA``F9```.Q=,`$'T@@`F8@``$?D"`#I2```D*9``!
+MQ>L`%'ZB@`K.GP`4!,P``7ST@`^4@``"D`````7<``$]R``"E(#_[@54``$2
+M(``!/4@`!92`_^F0````P!P``@G<``'`(``(P"@``,7G`!1^IH`*E<``!7ZB
+M@`0&(``("=P``8``!!Z0````S8``#L03`![`#"35C``$+,P#``Z0````)10`
+M_\`*B`!\C(`*S4D``!44``@E5`#_P`J(0'R,@`K-20``D````,`0``#`"HA`
+M?(R`"L25```E5``??14`"A$0``C`"H@`?(R`"L25```E5``??14`"I````#$
+M$P`%ST,`!7]10`^90``@?38``L`(,0/$E0``?4"`'L0/``)\C(`)E(``&<03
+M``]]%,`+E,``%L`4``#`$``!P`P``'R1P`E\W,`!%(@``054``$Q7``0E<#_
+M^WSA``^5```%?@"`"HP`!&A\@(`)D````'S`@`I^#H`"C``$:,`T``I_:T`"
+MS8,`),`(``&0````Q!,`#\`<,0/%W0``P!0``7W6``F:```'?19`"99```5]
+MU<`*?4)`'GTE``D(B``!$50``95```*8@/_VS0,`#\`,)->,``0LD````,0K
+M``+$)P`!?D)`'GZF@`G`"##7Q(T``,`(``@HB``$?,C`"13,``($S`2'A,``
+M`(``!(N```2.@``$DX``!*C.@P`@SH,`(8``!*W.@P`@P`@Q`\2I``#.@P`A
+M@``$K<0(`"^8@``#Q"L`#X``!*2,``/0ST,`!8P``]O`'```S!\`%`7<``$Q
+MR``"E(#__8P``^3$'P`!C``#\XP`!!K.@P`/Q!,``LT#`"'.@P`@@``$K<03
+M``_-`P`@P`@Q`\2I``#.@P`AC``%P)````#`##$1SPT``,`,`__,P``QP`@`
+M!,`0`!`)$``!F0#__X``!+V60``%Q"``')8```/,```QD````,04`#250``)
+ME(``!0B(``'`#`/_S,``,8``!,?,```QP"```)````#`##$2Q-$``'TI``R5
+M`/_JP"```,P``#&0````P!P``,`*@`!_B,`)F,``.'](P`F8P``VP`@``<`,
+M``#`$```?X%`"GU*``F:```,!1```03,``$0B``!,.``"I8`__I_04`*P`P`
+M`#$@``J6`/_VP!P``9`````%(`3GA@```(``!/&```3S@``$]8``!/>```3Y
+M@``$^X``!/V```3_@``%`8``!0/`,``(@``%!<`P``>```4%P#``!X``!07`
+M,``'@``%!<`P``B```4%P#``"(``!07`,``'@``%!<`P``>```4%P#``!X``
+M!07`,``(@``%!0LP``$3,``&?Q,`"H``!0W`,``6"S```1,P``8K,``*D```
+M`,Z#`!7`+#$%QNT``";L`/_`)```P#P._XP``Z7`/`;_Q"L`%7Z"@![$.P`"
+M?KJ`"8P``Z7`/`[_P#8``)=```3`.```C``!@8P`!:S`-```P#J``(P``8&,
+M``6LP"P`@8P`!,[`*``0P"0``(P`!*^0````P"PQ!<;I```6J``()JP`_\`D
+M``#`/`W_Q"L``HP``Z7`.```P#8``)=```.,``&!C``%K,`T``#`.H``C``!
+M@<`L`(&,``3.P"@`&L`D``&,``2OD````,0+``V4@``VP`@P[\2-``"4P``S
+MP`@PT,V)``#`"##.Q)4``,03`!R9```#S4,`')````!]4(`"?(R`#YB```*0
+M````P`PDUXP`!#9\$D`*Q!<``L`,,0O$R0``?("`'GR4@`E]",`)Q`L`"\`0
+M``#`%```P!P``7W*``F6```"!50``1'<``$%$``!/2``$)8`__K`"```P!``
+M`<`<``!]#(`)E(```WW1P`H)5``!$1```9E`__O$(P`+?F)`"GW!0![$$P`"
+M?5%`"7Y5``G`#"37C``$+,W#``O,`P`<D````,`(,0'$C0``)-```9D```4H
+MS``!S,D``,V#`!W$C0``D````,0/`!V4P``'P`@Q`<2-``#`$?_^?-#`"<S)
+M``#,`P`=D````,`,`!_`"H@`?<D`"L45```55``0?4%`'GU.@`G`"HA`?<D`
+M"L45```55``0?4%`'GU-0`D15``(?I:`"GZ"@![$%P`"?I:`"9````"6P``,
+M*NP``<[``#"60``%Q"``')8```/,```PD````,0<`#.5P/_ZS```,,`@``"0
+M````EL``$W[!``K`'##0S9T``,`<,,[%U0``%2P`!);```2,``6?E@```I``
+M``#`'##0S9T``,`<,,[%W0``?=7``GW1P`^5P/_V?0+`"I`````FN``?%IP`
+M""7<`!\1W``%?Y^`"A:<`!`E]``?%=P`""7<`!\1W``%?U]`"I````",``7X
+MS```#L0(`!&4@/_^Q`@`-Y2```7-@``.P`@Q!L2-``#,PP!CQ`@`.I2```/-
+M@``.C``'RL0(`#.4@``#S8``#HP`!L;$"``TE(``",V```[`"##7Q(D``"2(
+M``24@``#C``'D(P`![7$"``UE(```LV```[$"``JE(```\V```Z,``90Q`@`
+M*Y2```+-@``.Q`@`*)2`_]O-@``.C``&JXP`!M>,``?*@``%S<`8``',`P`.
+MP`W__\S#`![,PP!AP`@Q!,S)``#,`P`#S`,`8XP`!X?`"`4`*`P``,R/`$'`
+M"B`@*(@/!03,``',CP!!P`HP,"B('@\$S``!S(\`0<`*0$`HB"@>!,P``<R/
+M`$'`"D!`*(@R*`3,``',CP!!P`I@8"B(/#($S``!S(\`0<`*<'`HB%`\!,P`
+M`<R/`$'`"H"`*(A:4`3,``',CP!!P`J`@"B(7UH$S``!S(\`0<`*@(`HB&1?
+M!,P``<R/`$'`"H"`*(AI9`3,``',CP!!P`J`@"B(;FD$S``!S(\`0<`*@(`H
+MB'-N!,P``<R/`$'`"L#`*(AX<P3,``',CP!!P`K`P"B(?7@$S``!S(\`0<`*
+M__\HB(!]!,P``<R/`$'`"`"`S(,`7L`(`__,@``PP`@Q"<2-```4S``0*,P`
+M`<S``#'`"`/_S(``,LP#`%7,`P!=S`,`7Y````#,`P!5S`,`7\`(,,;$B0``
+MP`PPQ<3-``!\R(`"C``&I,U#`&"0````*`P``,`0``4DE``!"1```7S4P`$4
+MB``!F0#__)````#`&"35Q9D``"@<```H$```P"``!95```PDR``!E(``!7R0
+M@`1]B8`*"50``07<``$*(``!%,P``040``&:`/_V)9@`'Y````#`&"35Q9D`
+M`'T!`!Y]D,`)*!P``"@D``#`(``%E4``#"3(``&4@``%?*2`!'V)@`L)5``!
+M!=P``0H@``$4S``!!F0``9H`__8EF``?D````,0?`&`)W``'*"``$)H```,H
+M%`!`@``&H\37```$S``!"B```2@8`/]]E8`)?9&`$'V=@`1\F8`/E8#_]2@8
+M_P!]E8`)%9@`"'V1@!!]G8`$?)F`#IF`_^X55``0ED```A54``@H&`#_?95`
+M"9`````H%``??)3`!23,``&8P``#"50``9E`__R0````P`@PU\2)```DB``$
+MF(``!<`(,03`#?__S,D``(``!KG$"P`#F(``!<`(,1O$C0``E,```LS#`&&0
+M````P`@DU\`.B`!\C,`*Q-4``"54`/_`#HA`?(S`"L31```E$`#_$1``"'U1
+M0`J0````P`@Q"<2-```DT``!F0``#230`/[$%P!?!50``<U#`%]]44`/E4``
+M!XP`!O'$"P!5?0B`#LR#`%W-`P!5S`,`7Y````",``<*C``&_,`(`!1\L(`0
+MP`P`07PM``K`)```C``&B,U#`%;`"``%?+2`$,`,`$%\+0`*P"0``8P`!HC-
+M0P!7Q`L`5GR4P`^8P``"?!2`"L`,,1O$S0``F,```HP`!S'`&``!D````,`*
+MG``HB"34P`P``<S)``#`"HP`*(@DUL2-```DT/__%,P`$'S1``&0````P`J<
+M`"B,(YC`$``'S0T``,`*C``HC".9Q/$``"B,(YK$]0``*(PCF\3Y```HC".<
+MQ/T``)````#`'H@`C``'&7P4@`I\%H`*C``&6GP.P`K`'HA`C``'&7P4@`H1
+M5``(?I:`"HP`!EI^SL`!SH,`6I````",``<F*<PDU<3-``!]34`)D````,`>
+MB`",``<F?!<`"L`>B$",``<F$50`"'\7``J0````*<@B;\2)```IS")PQ,T`
+M`'R-0`I]04`>%50`$"G,)-?$S0``?4U`"9`````PC`!`F,``,SB,`$"4P``4
+M"(@`0'RMP!`5W``&C``''GZ"@!Y^LH`)C``'9B:,`/]_`4`*C``&8GP:0`H6
+MJ``()HP`_W]!0`J,``9B$9@`"'Y:0`K.0P!A@``'9<`,,0G$S0``)-```9D`
+M``?$#P!=Q!,`7L07`%5]40`.?-$`"ID``!3`'`!`?<B``GRMP!`5W``&?<+`
+M"HP`!V;`+#$+QNT``";0`/]_`4`*C``&='P:@`H6[``()M``_W]!0`J,``9T
+M$9@`"'Z:@`K.@P!AD````,`P```FB`#_C``&6GS!@`K`-```%H@`""2(`/^,
+M``9:?,'`"I;```^,``=_E4``#3%(``&4@``$!S```0F8``&```=\,4@``I2`
+M``0'=``!"=P``8``!WP*[``!@``';Y````!]@,`*P!0``'V!0`U]S0`.E0``
+M`WW`P`K`%``"D````,`,``K`$``!?-#`$,`0``#,$P!D!1```0C,``&8P/_]
+MD````,0+`&/`#``*P!```7S0P!#`$```P#```,`<``#`)#$)QF4``"9D_P`6
+M9``(P"@`'Q*H``@JJ``??I+`!2;L``&:P``#!1```8``!YY\D4`%)50``<`@
+M``"90``(QR,`9`8@``%^)4`/E4``!'U10`1]7<`*"B```<XS`&0%$``!!S``
+M`0C,``&8P/_LS<,`8I````#$"P`#F(``$XP`!KK$"P!BQ`\`8<`0,0O%$0``
+MP#___\`_``!]/0`)?("`'GS(P`I]#4`*P`@Q!,2-``!\U0`,F0``!,U)``#`
+M&``!S8,``Y````#$"P`>Q`\`8<`0,0/%$0``?-#`"7R-``R9```$S,,`'L`8
+M``'-@P`.D````,@)/3;(#3TWE,#X,<@1/3C(%3TYR!T].L@A/3O()3TU!*@`
+M,,Z!/8+,P3V#S0$]A,U!/87-P3V&S@$]AQ"(``,$C``8R)8`/)5`^"'(T@`H
+M?24``@E4``$$S``HF0#_^\B2`#@%$`!`?0K``<C6``3`'``$R.(`%,CF`"3.
+M"@%,SFX!3`C,``0(B``$"NP`!`G<``&9P/_XS0H!8,P*`63-03U'@```"```
+"````
+`
+end
diff --git a/sys/dev/drm2/ati_pcigart.c b/sys/dev/drm2/ati_pcigart.c
new file mode 100644
index 0000000..5d3033f
--- /dev/null
+++ b/sys/dev/drm2/ati_pcigart.c
@@ -0,0 +1,210 @@
+/**
+ * \file ati_pcigart.c
+ * ATI PCI GART support
+ *
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/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, 0xFFFFFFFFUL);
+ 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;
+#ifdef __linux__
+ unsigned long pages;
+ int i;
+ int max_pages;
+#endif
+
+ /* we need to support large memory configurations */
+ if (!entry) {
+ DRM_ERROR("no scatter/gather memory!\n");
+ return 0;
+ }
+
+ if (gart_info->bus_addr) {
+#ifdef __linux__
+
+ 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);
+ }
+#endif
+
+ 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;
+}
+
+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");
+
+#ifdef __linux__
+ 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;
+ }
+#endif
+
+ 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++) {
+#ifdef __linux__
+ /* 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;
+ }
+#endif
+ 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(__amd64)
+ wbinvd();
+#else
+ mb();
+#endif
+
+ done:
+ gart_info->addr = address;
+ gart_info->bus_addr = bus_address;
+ return ret;
+}
diff --git a/sys/dev/drm2/radeon/ObjectID.h b/sys/dev/drm2/radeon/ObjectID.h
new file mode 100644
index 0000000..db559da
--- /dev/null
+++ b/sys/dev/drm2/radeon/ObjectID.h
@@ -0,0 +1,699 @@
+/*
+* 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/README b/sys/dev/drm2/radeon/README
new file mode 100644
index 0000000..fad030f
--- /dev/null
+++ b/sys/dev/drm2/radeon/README
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+== Updates to reg_srcs/ files ==
+
+When a file in the "reg_srcs" subdirectory in updated, be sure to regen
+headers by running "make" in tools/tools/drm/radeon/mkregtable.
diff --git a/sys/dev/drm2/radeon/atom-bits.h b/sys/dev/drm2/radeon/atom-bits.h
new file mode 100644
index 0000000..ab099f9
--- /dev/null
+++ b/sys/dev/drm2/radeon/atom-bits.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+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/sys/dev/drm2/radeon/atom-names.h b/sys/dev/drm2/radeon/atom-names.h
new file mode 100644
index 0000000..737ea7d
--- /dev/null
+++ b/sys/dev/drm2/radeon/atom-names.h
@@ -0,0 +1,103 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/atom-types.h b/sys/dev/drm2/radeon/atom-types.h
new file mode 100644
index 0000000..7009de7
--- /dev/null
+++ b/sys/dev/drm2/radeon/atom-types.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/atom.c b/sys/dev/drm2/radeon/atom.c
new file mode 100644
index 0000000..f5c557c
--- /dev/null
+++ b/sys/dev/drm2/radeon/atom.c
@@ -0,0 +1,1403 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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);
+
+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--)
+ printf(" ");
+}
+
+#define DEBUG(...) do if (atom_debug) { printf(__FILE__ __VA_ARGS__); } while (0)
+#define SDEBUG(...) do if (atom_debug) { printf(__FILE__); debug_print_spaces(debug_depth); printf(__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:
+ DRM_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:
+ DRM_INFO(
+ "PCI registers are not implemented.\n");
+ return 0;
+ case ATOM_IO_SYSIO:
+ DRM_INFO(
+ "SYSIO registers are not implemented.\n");
+ return 0;
+ default:
+ if (!(gctx->io_mode & 0x80)) {
+ DRM_INFO("Bad IO mode.\n");
+ return 0;
+ }
+ if (!gctx->iio[gctx->io_mode & 0x7F]) {
+ DRM_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:
+ DRM_INFO(
+ "PCI registers are not implemented.\n");
+ return;
+ case ATOM_IO_SYSIO:
+ DRM_INFO(
+ "SYSIO registers are not implemented.\n");
+ return;
+ default:
+ if (!(gctx->io_mode & 0x80)) {
+ DRM_INFO("Bad IO mode.\n");
+ return;
+ }
+ if (!gctx->iio[gctx->io_mode & 0xFF]) {
+ DRM_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)
+{
+ DRM_INFO("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)
+ DRM_UDELAY(count);
+ else if (!drm_can_sleep())
+ DRM_MDELAY(count);
+ else
+ DRM_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)
+{
+ DRM_INFO("unimplemented!\n");
+}
+
+static void atom_op_restorereg(atom_exec_context *ctx, int *ptr, int arg)
+{
+ DRM_INFO("unimplemented!\n");
+}
+
+static void atom_op_savereg(atom_exec_context *ctx, int *ptr, int arg)
+{
+ DRM_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 {
+ DRM_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)
+{
+ DRM_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 = malloc(4 * ws, DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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)
+ free(ectx.ws, DRM_MEM_DRIVER);
+ return ret;
+}
+
+int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
+{
+ int r;
+
+ sx_xlock(&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);
+ sx_xunlock(&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 = malloc(2 * 256, DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 =
+ malloc(sizeof(struct atom_context), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ char *str;
+ char name[512];
+ int i;
+
+ if (!ctx)
+ return NULL;
+
+ ctx->card = card;
+ ctx->bios = bios;
+
+ if (CU16(0) != ATOM_BIOS_MAGIC) {
+ DRM_INFO("Invalid BIOS magic.\n");
+ free(ctx, DRM_MEM_DRIVER);
+ return NULL;
+ }
+ if (strncmp
+ (CSTR(ATOM_ATI_MAGIC_PTR), ATOM_ATI_MAGIC,
+ strlen(ATOM_ATI_MAGIC))) {
+ DRM_INFO("Invalid ATI magic.\n");
+ free(ctx, DRM_MEM_DRIVER);
+ return NULL;
+ }
+
+ base = CU16(ATOM_ROM_TABLE_PTR);
+ if (strncmp
+ (CSTR(base + ATOM_ROM_MAGIC_PTR), ATOM_ROM_MAGIC,
+ strlen(ATOM_ROM_MAGIC))) {
+ DRM_INFO("Invalid ATOM magic.\n");
+ free(ctx, DRM_MEM_DRIVER);
+ 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;
+ }
+ }
+ DRM_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)
+ free(ctx->iio, DRM_MEM_DRIVER);
+ free(ctx, DRM_MEM_DRIVER);
+}
+
+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 *)((char *)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 *)((char *)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 *)((char *)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 = malloc(usage_bytes, DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (!ctx->scratch)
+ return -ENOMEM;
+ ctx->scratch_size_bytes = usage_bytes;
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/atom.h b/sys/dev/drm2/radeon/atom.h
new file mode 100644
index 0000000..dbca87b
--- /dev/null
+++ b/sys/dev/drm2/radeon/atom.h
@@ -0,0 +1,161 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef ATOM_H
+#define ATOM_H
+
+#include <dev/drm2/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 sx 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/sys/dev/drm2/radeon/atombios.h b/sys/dev/drm2/radeon/atombios.h
new file mode 100644
index 0000000..8ef8196
--- /dev/null
+++ b/sys/dev/drm2/radeon/atombios.h
@@ -0,0 +1,8013 @@
+/*
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+/****************************************************************************/
+/*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<char*>(&(static_cast<ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*>(0))->FieldName)-static_cast<char*>(0))/sizeof(USHORT))
+
+#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) (((static_cast<ATOM_COMMON_TABLE_HEADER*>(TABLE_HEADER_OFFSET))->ucTableFormatRevision )&0x3F)
+#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) (((static_cast<ATOM_COMMON_TABLE_HEADER*>(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/sys/dev/drm2/radeon/atombios_crtc.c b/sys/dev/drm2/radeon/atombios_crtc.c
new file mode 100644
index 0000000..c4c5c46
--- /dev/null
+++ b/sys/dev/drm2/radeon/atombios_crtc.c
@@ -0,0 +1,1938 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include <dev/drm2/drm_fixed.h>
+#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);
+ struct radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ /* fixme - fill in enc_priv for atom dac */
+ enum radeon_tv_std tv_std = TV_STD_NTSC;
+ bool is_tv = false, is_cv = false;
+
+ if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
+ return;
+
+ 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);
+ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+ 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;
+ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+ atombios_powergate_crtc(crtc, ATOM_ENABLE);
+ /* 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,
+ int crtc_id,
+ struct radeon_atom_ss *ss)
+{
+ unsigned i;
+ int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
+ union atom_enable_ss args;
+
+ if (!enable) {
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->mode_info.crtcs[i] &&
+ rdev->mode_info.crtcs[i]->enabled &&
+ i != crtc_id &&
+ pll_id == rdev->mode_info.crtcs[i]->pll_id) {
+ /* one other crtc is using this pll don't turn
+ * off spread spectrum as it might turn off
+ * display on active crtc
+ */
+ return;
+ }
+ }
+ }
+
+ 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;
+ break;
+ case ATOM_PPLL2:
+ args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
+ break;
+ case ATOM_DCPLL:
+ args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
+ break;
+ case ATOM_PPLL_INVALID:
+ return;
+ }
+ args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+ args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
+ 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;
+ break;
+ case ATOM_PPLL2:
+ args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
+ break;
+ case ATOM_DCPLL:
+ args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
+ break;
+ case ATOM_PPLL_INVALID:
+ return;
+ }
+ args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount);
+ args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step);
+ 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_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_encoder *encoder = radeon_crtc->encoder;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ u32 adjusted_clock = mode->clock;
+ int encoder_mode = atombios_get_encoder_mode(encoder);
+ u32 dp_clock = mode->clock;
+ int bpc = radeon_get_monitor_bpc(connector);
+ bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
+
+ /* reset the pll flags */
+ radeon_crtc->pll_flags = 0;
+
+ if (ASIC_IS_AVIVO(rdev)) {
+ if ((rdev->family == CHIP_RS600) ||
+ (rdev->family == CHIP_RS690) ||
+ (rdev->family == CHIP_RS740))
+ radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
+ RADEON_PLL_PREFER_CLOSEST_LOWER);
+
+ if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+
+ if (rdev->family < CHIP_RV770)
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
+ /* use frac fb div on APUs */
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ } else {
+ radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
+
+ if (mode->clock > 200000) /* range limits??? */
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ }
+
+ 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 (radeon_crtc->ss_enabled) {
+ if (radeon_crtc->ss.refdiv) {
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
+ if (ASIC_IS_AVIVO(rdev))
+ radeon_crtc->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))
+ radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
+ } else {
+ if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
+ radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+ if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ }
+
+ /* 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 (radeon_crtc->ss_enabled && radeon_crtc->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 (radeon_crtc->ss_enabled && radeon_crtc->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) {
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
+ radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
+ }
+ if (args.v3.sOutput.ucPostDiv) {
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
+ radeon_crtc->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;
+ if (crtc_id == ATOM_CRTC2)
+ args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
+ else
+ args.v3.ucMiscInfo = PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1;
+ 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 bool atombios_crtc_prepare_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 radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
+
+ radeon_crtc->bpc = 8;
+ radeon_crtc->ss_enabled = false;
+
+ if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
+ (radeon_encoder_get_dp_bridge_encoder_id(radeon_crtc->encoder) != ENCODER_OBJECT_ID_NONE)) {
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ struct drm_connector *connector =
+ radeon_get_connector_for_encoder(radeon_crtc->encoder);
+ struct radeon_connector *radeon_connector =
+ to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_connector->con_priv;
+ int dp_clock;
+ radeon_crtc->bpc = radeon_get_monitor_bpc(connector);
+
+ 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))
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
+ ASIC_INTERNAL_SS_ON_DP,
+ dp_clock);
+ else {
+ if (dp_clock == 16200) {
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
+ ATOM_DP_SS_ID2);
+ if (!radeon_crtc->ss_enabled)
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
+ ATOM_DP_SS_ID1);
+ } else
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
+ ATOM_DP_SS_ID1);
+ }
+ break;
+ case ATOM_ENCODER_MODE_LVDS:
+ if (ASIC_IS_DCE4(rdev))
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
+ dig->lcd_ss_id,
+ mode->clock / 10);
+ else
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_ppll_ss_info(rdev,
+ &radeon_crtc->ss,
+ dig->lcd_ss_id);
+ break;
+ case ATOM_ENCODER_MODE_DVI:
+ if (ASIC_IS_DCE4(rdev))
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
+ ASIC_INTERNAL_SS_ON_TMDS,
+ mode->clock / 10);
+ break;
+ case ATOM_ENCODER_MODE_HDMI:
+ if (ASIC_IS_DCE4(rdev))
+ radeon_crtc->ss_enabled =
+ radeon_atombios_get_asic_ss_info(rdev,
+ &radeon_crtc->ss,
+ ASIC_INTERNAL_SS_ON_HDMI,
+ mode->clock / 10);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* adjust pixel clock as needed */
+ radeon_crtc->adjusted_clock = atombios_adjust_pll(crtc, mode);
+
+ return true;
+}
+
+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 radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ u32 pll_clock = mode->clock;
+ u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
+ struct radeon_pll *pll;
+ int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
+
+ 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;
+ }
+
+ /* update pll params */
+ pll->flags = radeon_crtc->pll_flags;
+ pll->reference_div = radeon_crtc->pll_reference_div;
+ pll->post_div = radeon_crtc->pll_post_div;
+
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+ /* TV seems to prefer the legacy algo on some boards */
+ radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
+ else if (ASIC_IS_AVIVO(rdev))
+ radeon_compute_pll_avivo(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
+ else
+ radeon_compute_pll_legacy(pll, radeon_crtc->adjusted_clock, &pll_clock,
+ &fb_div, &frac_fb_div, &ref_div, &post_div);
+
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id,
+ radeon_crtc->crtc_id, &radeon_crtc->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,
+ radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
+
+ if (radeon_crtc->ss_enabled) {
+ /* calculate ss amount and step size */
+ if (ASIC_IS_DCE4(rdev)) {
+ u32 step_size;
+ u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000;
+ radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
+ radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
+ ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
+ if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
+ step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
+ (125 * 25 * pll->reference_freq / 100);
+ else
+ step_size = (2 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
+ (125 * 25 * pll->reference_freq / 100);
+ radeon_crtc->ss.step = step_size;
+ }
+
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id,
+ radeon_crtc->crtc_id, &radeon_crtc->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_TAHITI)
+ tmp = rdev->config.si.tile_config;
+ else 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);
+
+ if ((rdev->family == CHIP_TAHITI) ||
+ (rdev->family == CHIP_PITCAIRN))
+ fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
+ else if (rdev->family == CHIP_VERDE)
+ fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
+
+ 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;
+ }
+}
+
+/**
+ * radeon_get_pll_use_mask - look up a mask of which pplls are in use
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the mask of which PPLLs (Pixel PLLs) are in use.
+ */
+static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+ u32 pll_in_use = 0;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << test_radeon_crtc->pll_id);
+ }
+ return pll_in_use;
+}
+
+/**
+ * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
+ * also in DP mode. For DP, a single PPLL can be used for all DP
+ * crtcs/encoders.
+ */
+static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* for DP use the same PLL for all */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ return test_radeon_crtc->pll_id;
+ }
+ }
+ return ATOM_PPLL_INVALID;
+}
+
+/**
+ * radeon_get_shared_nondp_ppll - return the PPLL used by another non-DP crtc
+ *
+ * @crtc: drm crtc
+ * @encoder: drm encoder
+ *
+ * Returns the PPLL (Pixel PLL) used by another non-DP crtc/encoder which can
+ * be shared (i.e., same clock).
+ */
+static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *test_radeon_crtc;
+ u32 adjusted_clock, test_adjusted_clock;
+
+ adjusted_clock = radeon_crtc->adjusted_clock;
+
+ if (adjusted_clock == 0)
+ return ATOM_PPLL_INVALID;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+ test_radeon_crtc = to_radeon_crtc(test_crtc);
+ if (test_radeon_crtc->encoder &&
+ !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_radeon_crtc->encoder))) {
+ /* check if we are already driving this connector with another crtc */
+ if (test_radeon_crtc->connector == radeon_crtc->connector) {
+ /* if we are, return that pll */
+ if (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID)
+ return test_radeon_crtc->pll_id;
+ }
+ /* for non-DP check the clock */
+ test_adjusted_clock = test_radeon_crtc->adjusted_clock;
+ if ((crtc->mode.clock == test_crtc->mode.clock) &&
+ (adjusted_clock == test_adjusted_clock) &&
+ (radeon_crtc->ss_enabled == test_radeon_crtc->ss_enabled) &&
+ (test_radeon_crtc->pll_id != ATOM_PPLL_INVALID))
+ return test_radeon_crtc->pll_id;
+ }
+ }
+ return ATOM_PPLL_INVALID;
+}
+
+/**
+ * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
+ * a single PPLL can be used for all DP crtcs/encoders. For non-DP
+ * monitors a dedicated PPLL must be used. If a particular board has
+ * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
+ * as there is no need to program the PLL itself. If we are not able to
+ * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
+ * avoid messing up an existing monitor.
+ *
+ * Asic specific PLL information
+ *
+ * DCE 6.1
+ * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
+ * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
+ *
+ * DCE 6.0
+ * - PPLL0 is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 5.0
+ * - DCPLL is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 3.0/4.0/4.1
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ */
+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 radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ u32 pll_in_use;
+ int pll;
+
+ if (ASIC_IS_DCE61(rdev)) {
+ struct radeon_encoder_atom_dig *dig =
+ radeon_encoder->enc_priv;
+
+ if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
+ (dig->linkb == false))
+ /* UNIPHY A uses PPLL2 */
+ return ATOM_PPLL2;
+ else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+ /* UNIPHY B/C/D/E/F */
+ if (rdev->clock.dp_extclk)
+ /* skip PPLL programming if using ext clock */
+ return ATOM_PPLL_INVALID;
+ else {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ /* UNIPHY B/C/D/E/F */
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL0)))
+ return ATOM_PPLL0;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* 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: PPLL, DCPLL, or ext clock
+ * DCE6: PPLL, PPLL0, 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(radeon_crtc->encoder))) {
+ if (rdev->clock.dp_extclk)
+ /* skip PPLL programming if using ext clock */
+ return ATOM_PPLL_INVALID;
+ else if (ASIC_IS_DCE6(rdev))
+ /* use PPLL0 for all DP */
+ return ATOM_PPLL0;
+ else if (ASIC_IS_DCE5(rdev))
+ /* use DCPLL for all DP */
+ return ATOM_DCPLL;
+ else {
+ /* use the same PPLL for all DP monitors */
+ pll = radeon_get_shared_dp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ } else {
+ /* use the same PPLL for all monitors with the same clock */
+ pll = radeon_get_shared_nondp_ppll(crtc);
+ if (pll != ATOM_PPLL_INVALID)
+ return pll;
+ }
+ /* all other cases */
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
+ } else {
+ /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
+ /* some atombios (observed in some DCE2/DCE3) code have a bug,
+ * the matching btw pll and crtc is done through
+ * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the
+ * pll (1 or 2) to select which register to write. ie if using
+ * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2
+ * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to
+ * choose which value to write. Which is reverse order from
+ * register logic. So only case that works is when pllid is
+ * same as crtcid or when both pll and crtc are enabled and
+ * both use same clock.
+ *
+ * So just return crtc id as if crtc and pll were hard linked
+ * together even if they aren't
+ */
+ 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, -1, &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, -1, &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 radeon_encoder *radeon_encoder =
+ to_radeon_encoder(radeon_crtc->encoder);
+ bool is_tvcv = false;
+
+ 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,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_encoder *encoder;
+
+ /* assign the encoder to the radeon crtc to avoid repeated lookups later */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->crtc == crtc) {
+ radeon_crtc->encoder = encoder;
+ radeon_crtc->connector = radeon_get_connector_for_encoder(encoder);
+ break;
+ }
+ }
+ if ((radeon_crtc->encoder == NULL) || (radeon_crtc->connector == NULL)) {
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
+ return false;
+ }
+ if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode))
+ return false;
+ if (!atombios_crtc_prepare_pll(crtc, adjusted_mode))
+ return false;
+ /* pick pll */
+ radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
+ /* if we can't get a PPLL for a non-DP encoder, fail */
+ if ((radeon_crtc->pll_id == ATOM_PPLL_INVALID) &&
+ !ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder)))
+ return false;
+
+ return true;
+}
+
+static void atombios_crtc_prepare(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;
+
+ radeon_crtc->in_mode_set = true;
+
+ /* disable crtc pair power gating before programming */
+ if (ASIC_IS_DCE6(rdev))
+ atombios_powergate_crtc(crtc, ATOM_DISABLE);
+
+ atombios_lock_crtc(crtc, ATOM_ENABLE);
+ atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void atombios_crtc_commit(struct drm_crtc *crtc)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+ atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+ atombios_lock_crtc(crtc, ATOM_DISABLE);
+ radeon_crtc->in_mode_set = false;
+}
+
+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;
+ int i;
+
+ atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->mode_info.crtcs[i] &&
+ rdev->mode_info.crtcs[i]->enabled &&
+ i != radeon_crtc->crtc_id &&
+ radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
+ /* one other crtc is using this pll don't turn
+ * off the pll
+ */
+ goto done;
+ }
+ }
+
+ 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;
+ }
+done:
+ radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+ radeon_crtc->adjusted_clock = 0;
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
+}
+
+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 = ATOM_PPLL_INVALID;
+ radeon_crtc->adjusted_clock = 0;
+ radeon_crtc->encoder = NULL;
+ radeon_crtc->connector = NULL;
+ drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
+}
diff --git a/sys/dev/drm2/radeon/atombios_dp.c b/sys/dev/drm2/radeon/atombios_dp.c
new file mode 100644
index 0000000..3c0f7f5
--- /dev/null
+++ b/sys/dev/drm2/radeon/atombios_dp.c
@@ -0,0 +1,893 @@
+/*
+ * 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
+ * Jerome Glisse
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+
+#include "atom.h"
+#include "atom-bits.h"
+#include <dev/drm2/drm_dp_helper.h>
+
+/* move these to drm_dp_helper.c/h */
+#define DP_LINK_CONFIGURATION_SIZE 9
+#define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
+
+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)
+ DRM_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)
+ DRM_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(device_t dev, int mode, u8 write_byte, u8 *read_byte)
+{
+ struct iic_dp_aux_data *algo_data = device_get_softc(dev);
+ struct radeon_i2c_chan *auxch = algo_data->priv;
+ 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");
+ DRM_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");
+ DRM_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 *****/
+
+#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 = drm_dp_get_adjust_request_voltage(link_status, lane);
+ u8 this_p = drm_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 (bpc == 0)
+ return 24;
+ else
+ return bpc * 3;
+}
+
+/* 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;
+}
+
+/***** 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(radeon_get_monitor_bpc(connector));
+ int max_link_rate = drm_dp_max_link_rate(dpcd);
+ int max_lane_num = drm_dp_max_lane_count(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(radeon_get_monitor_bpc(connector));
+ 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 drm_dp_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);
+}
+
+static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
+{
+ struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+ u8 buf[3];
+
+ if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
+ return;
+
+ if (radeon_dp_aux_native_read(radeon_connector, DP_SINK_OUI, buf, 3, 0))
+ DRM_DEBUG_KMS("Sink OUI: %02hhx%02hhx%02hhx\n",
+ buf[0], buf[1], buf[2]);
+
+ if (radeon_dp_aux_native_read(radeon_connector, DP_BRANCH_OUI, buf, 3, 0))
+ DRM_DEBUG_KMS("Branch OUI: %02hhx%02hhx%02hhx\n",
+ buf[0], buf[1], buf[2]);
+}
+
+bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
+{
+ struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+ u8 msg[DP_DPCD_SIZE];
+ int ret, i;
+
+ ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg,
+ DP_DPCD_SIZE, 0);
+ if (ret > 0) {
+ memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
+ DRM_DEBUG_KMS("DPCD: ");
+ for (i = 0; i < DP_DPCD_SIZE; i++)
+ DRM_DEBUG_KMS("%02x ", msg[i]);
+ DRM_DEBUG_KMS("\n");
+
+ radeon_dp_probe_oui(radeon_connector);
+
+ 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;
+ u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
+ u8 tmp;
+
+ if (!ASIC_IS_DCE4(rdev))
+ return panel_mode;
+
+ if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
+ /* DP bridge chips */
+ tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
+ if (tmp & 1)
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
+ (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+ else
+ panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+ } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ /* eDP */
+ 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,
+ const 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) {
+ return false;
+ }
+
+ DRM_DEBUG_KMS("link status %*ph\n", 6, link_status);
+ 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 (drm_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;
+ bool tp3_supported;
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
+ 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 = drm_dp_link_rate_to_bw_code(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)
+{
+ DRM_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);
+
+ DRM_UDELAY(400);
+
+ /* clock recovery loop */
+ clock_recovery = false;
+ dp_info->tries = 0;
+ voltage = 0xff;
+ while (1) {
+ drm_dp_link_train_clock_recovery_delay(dp_info->dpcd);
+
+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
+ DRM_ERROR("displayport link status failed\n");
+ break;
+ }
+
+ if (drm_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) {
+ drm_dp_link_train_channel_eq_delay(dp_info->dpcd);
+
+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
+ DRM_ERROR("displayport link status failed\n");
+ break;
+ }
+
+ if (drm_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;
+
+ 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, DP_RECEIVER_CAP_SIZE);
+ 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/sys/dev/drm2/radeon/atombios_encoders.c b/sys/dev/drm2/radeon/atombios_encoders.c
new file mode 100644
index 0000000..db23f13
--- /dev/null
+++ b/sys/dev/drm2/radeon/atombios_encoders.c
@@ -0,0 +1,2660 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.h" /* Declares several prototypes; clang is pleased. */
+#include "atom.h"
+
+static u8
+radeon_atom_get_backlight_level_from_reg(struct radeon_device *rdev)
+{
+ u8 backlight_level;
+ u32 bios_2_scratch;
+
+ if (rdev->family >= CHIP_R600)
+ bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
+ else
+ bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
+
+ backlight_level = ((bios_2_scratch & ATOM_S2_CURRENT_BL_LEVEL_MASK) >>
+ ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
+
+ return backlight_level;
+}
+
+static void
+radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev,
+ u8 backlight_level)
+{
+ u32 bios_2_scratch;
+
+ if (rdev->family >= CHIP_R600)
+ bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
+ else
+ bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
+
+ bios_2_scratch &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
+ bios_2_scratch |= ((backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &
+ ATOM_S2_CURRENT_BL_LEVEL_MASK);
+
+ if (rdev->family >= CHIP_R600)
+ WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ else
+ WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+}
+
+u8
+atombios_get_backlight_level(struct radeon_encoder *radeon_encoder)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return 0;
+
+ return radeon_atom_get_backlight_level_from_reg(rdev);
+}
+
+void
+atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)
+{
+ struct drm_encoder *encoder = &radeon_encoder->base;
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder_atom_dig *dig;
+ DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
+ int index;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ radeon_encoder->enc_priv) {
+ dig = radeon_encoder->enc_priv;
+ dig->backlight_level = level;
+ radeon_atom_set_backlight_level_to_reg(rdev, dig->backlight_level);
+
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+ if (dig->backlight_level == 0) {
+ args.ucAction = ATOM_LCD_BLOFF;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ } else {
+ args.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ args.ucAction = ATOM_LCD_BLON;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ }
+ break;
+ 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 (dig->backlight_level == 0)
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
+ else {
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL, 0, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+static u8 radeon_atom_bl_level(struct backlight_device *bd)
+{
+ u8 level;
+
+ /* Convert brightness to hardware level */
+ if (bd->props.brightness < 0)
+ level = 0;
+ else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)
+ level = RADEON_MAX_BL_LEVEL;
+ else
+ level = bd->props.brightness;
+
+ return level;
+}
+
+static int radeon_atom_backlight_update_status(struct backlight_device *bd)
+{
+ struct radeon_backlight_privdata *pdata = bl_get_data(bd);
+ struct radeon_encoder *radeon_encoder = pdata->encoder;
+
+ atombios_set_backlight_level(radeon_encoder, radeon_atom_bl_level(bd));
+
+ return 0;
+}
+
+static int radeon_atom_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;
+
+ return radeon_atom_get_backlight_level_from_reg(rdev);
+}
+
+static const struct backlight_ops radeon_atom_backlight_ops = {
+ .get_brightness = radeon_atom_backlight_get_brightness,
+ .update_status = radeon_atom_backlight_update_status,
+};
+
+void radeon_atom_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;
+ struct radeon_encoder_atom_dig *dig;
+ u8 backlight_level;
+ char bl_name[16];
+
+ if (!radeon_encoder->enc_priv)
+ return;
+
+ if (!rdev->is_atom_bios)
+ return;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ pdata = malloc(sizeof(struct radeon_backlight_privdata), DRM_MEM_DRIVER, M_WAITOK);
+ if (!pdata) {
+ DRM_ERROR("Memory allocation failed\n");
+ goto error;
+ }
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = RADEON_MAX_BL_LEVEL;
+ props.type = BACKLIGHT_RAW;
+ snprintf(bl_name, sizeof(bl_name),
+ "radeon_bl%d", dev->primary->index);
+ bd = backlight_device_register(bl_name, &drm_connector->kdev,
+ pdata, &radeon_atom_backlight_ops, &props);
+ if (IS_ERR(bd)) {
+ DRM_ERROR("Backlight registration failed\n");
+ goto error;
+ }
+
+ pdata->encoder = radeon_encoder;
+
+ backlight_level = radeon_atom_get_backlight_level_from_reg(rdev);
+
+ dig = radeon_encoder->enc_priv;
+ dig->bl_dev = bd;
+
+ bd->props.brightness = radeon_atom_backlight_get_brightness(bd);
+ bd->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(bd);
+
+ DRM_INFO("radeon atom DIG backlight initialized\n");
+
+ return;
+
+error:
+ free(pdata, DRM_MEM_DRIVER);
+ return;
+}
+
+static void radeon_atom_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;
+ struct radeon_encoder_atom_dig *dig;
+
+ if (!radeon_encoder->enc_priv)
+ return;
+
+ if (!rdev->is_atom_bios)
+ return;
+
+ if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
+ return;
+
+ dig = radeon_encoder->enc_priv;
+ bd = dig->bl_dev;
+ dig->bl_dev = NULL;
+
+ if (bd) {
+ struct radeon_legacy_backlight_privdata *pdata;
+
+ pdata = bl_get_data(bd);
+ backlight_device_unregister(bd);
+ free(pdata, DRM_MEM_DRIVER);
+
+ DRM_INFO("radeon atom LVDS backlight unloaded\n");
+ }
+}
+
+#else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector)
+{
+}
+
+static void radeon_atom_backlight_exit(struct radeon_encoder *encoder)
+{
+}
+
+#endif
+
+
+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,
+ const 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, adjusted_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);
+
+}
+
+static u8 radeon_atom_get_bpc(struct drm_encoder *encoder)
+{
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ int bpc = 8;
+
+ if (connector)
+ bpc = radeon_get_monitor_bpc(connector);
+
+ switch (bpc) {
+ case 0:
+ return PANEL_BPC_UNDEFINE;
+ case 6:
+ return PANEL_6BIT_PER_COLOR;
+ case 8:
+ default:
+ return PANEL_8BIT_PER_COLOR;
+ case 10:
+ return PANEL_10BIT_PER_COLOR;
+ case 12:
+ return PANEL_12BIT_PER_COLOR;
+ case 16:
+ return PANEL_16BIT_PER_COLOR;
+ }
+}
+
+
+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 == ENCODER_OBJECT_ID_INTERNAL_DVO1) ||
+ (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))
+ 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;
+
+ 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;
+ }
+
+ /* 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.v3.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.v3.ucEncoderMode) && (dp_clock == 270000))
+ args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
+ args.v3.acConfig.ucDigSel = dig->dig_encoder;
+ args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder);
+ 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.v4.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.v4.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;
+ args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
+ 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;
+ DRM_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;
+
+ 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;
+ }
+
+ 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;
+ }
+ args.v3.sExtEncoder.ucBitPerColor = radeon_atom_get_bpc(encoder);
+ 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_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+ 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 = 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:
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ 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);
+ 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);
+ }
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* 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);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ } else {
+ /* 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);
+ /* some early dce3.2 boards have a bug in their transmitter control table */
+ if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730))
+ 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)) {
+ /* disable the transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* disable the transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ 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_OUTPUT, 0, 0);
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 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->pci_device == 0x71C5) &&
+ (dev->pci_subvendor == 0x106b) &&
+ (dev->pci_subdevice == 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 = radeon_encoder->enc_priv;
+ uint32_t dig_enc_in_use = 0;
+
+ if (ASIC_IS_DCE6(rdev)) {
+ /* DCE6 */
+ 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;
+ }
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* DCE4/5 */
+ if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(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);
+
+ radeon_encoder->pixel_clock = adjusted_mode->clock;
+
+ /* need to call this here rather than in prepare() since we need some crtc info */
+ radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+ 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:
+ /* handled in dpms */
+ 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;
+ }
+
+ atombios_apply_encoder_quirks(encoder, adjusted_mode);
+
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+ r600_hdmi_enable(encoder);
+ if (ASIC_IS_DCE6(rdev))
+ ; /* TODO (use pointers instead of if-s?) */
+ else if (ASIC_IS_DCE4(rdev))
+ evergreen_hdmi_setmode(encoder, adjusted_mode);
+ else
+ 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_device *rdev = encoder->dev->dev_private;
+ 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);
+ if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) {
+ if (rdev->family >= CHIP_R600)
+ dig->afmt = rdev->mode_info.afmt[dig->dig_encoder];
+ else
+ /* RS600/690/740 have only 1 afmt block */
+ dig->afmt = rdev->mode_info.afmt[0];
+ }
+ }
+ }
+
+ radeon_atom_output_lock(encoder, true);
+
+ 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)
+{
+ /* need to call this here as we need the crtc set up */
+ 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:
+ /* handled in dpms */
+ 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,
+ const 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);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ radeon_atom_backlight_exit(radeon_encoder);
+ free(radeon_encoder->enc_priv, DRM_MEM_DRIVER);
+ drm_encoder_cleanup(encoder);
+ free(radeon_encoder, DRM_MEM_DRIVER);
+}
+
+static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
+ .destroy = radeon_enc_destroy,
+};
+
+static 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 = malloc(sizeof(struct radeon_encoder_atom_dac),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ if (!dac)
+ return NULL;
+
+ dac->tv_std = radeon_atombios_get_tv_info(rdev);
+ return dac;
+}
+
+static 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 = malloc(sizeof(struct radeon_encoder_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ 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 = malloc(sizeof(struct radeon_encoder),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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/sys/dev/drm2/radeon/atombios_i2c.c b/sys/dev/drm2/radeon/atombios_i2c.c
new file mode 100644
index 0000000..40ba15b
--- /dev/null
+++ b/sys/dev/drm2/radeon/atombios_i2c.c
@@ -0,0 +1,203 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include <dev/iicbus/iic.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include "radeon.h"
+#include "atom.h"
+#include "iicbus_if.h"
+#include "iicbb_if.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);
+ }
+
+ 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;
+}
+
+static int
+radeon_atom_hw_i2c_xfer(device_t dev, struct iic_msg *msgs, u_int num)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ struct iic_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->slave, HW_I2C_WRITE,
+ &buf, 1);
+ if (ret)
+ return ret;
+ else
+ return (0);
+ }
+
+ 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 & IIC_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->slave, flags,
+ &p->buf[buffer_offset], current_count);
+ if (ret)
+ return ret;
+ remaining -= current_count;
+ buffer_offset += current_count;
+ }
+ }
+
+ return (0);
+}
+
+static int
+radeon_atom_hw_i2c_probe(device_t dev)
+{
+
+ return (BUS_PROBE_SPECIFIC);
+}
+
+static int
+radeon_atom_hw_i2c_attach(device_t dev)
+{
+ struct radeon_i2c_chan *i2c;
+ device_t iic_dev;
+
+ i2c = device_get_softc(dev);
+ device_set_desc(dev, i2c->name);
+
+ /* add generic bit-banging code */
+ iic_dev = device_add_child(dev, "iicbus", -1);
+ if (iic_dev == NULL)
+ return (ENXIO);
+ device_quiet(iic_dev);
+
+ /* attach and probe added child */
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static int
+radeon_atom_hw_i2c_detach(device_t dev)
+{
+ /* detach bit-banding code. */
+ bus_generic_detach(dev);
+
+ /* delete bit-banding code. */
+ device_delete_children(dev);
+ return (0);
+}
+
+static int
+radeon_atom_hw_i2c_reset(device_t dev, u_char speed,
+ u_char addr, u_char *oldaddr)
+{
+
+ return (0);
+}
+
+static device_method_t radeon_atom_hw_i2c_methods[] = {
+ DEVMETHOD(device_probe, radeon_atom_hw_i2c_probe),
+ DEVMETHOD(device_attach, radeon_atom_hw_i2c_attach),
+ DEVMETHOD(device_detach, radeon_atom_hw_i2c_detach),
+ DEVMETHOD(iicbus_reset, radeon_atom_hw_i2c_reset),
+ DEVMETHOD(iicbus_transfer, radeon_atom_hw_i2c_xfer),
+ DEVMETHOD_END
+};
+
+static driver_t radeon_atom_hw_i2c_driver = {
+ "radeon_atom_hw_i2c",
+ radeon_atom_hw_i2c_methods,
+ 0
+};
+
+static devclass_t radeon_atom_hw_i2c_devclass;
+DRIVER_MODULE_ORDERED(radeon_atom_hw_i2c, drmn, radeon_atom_hw_i2c_driver,
+ radeon_atom_hw_i2c_devclass, 0, 0, SI_ORDER_ANY);
diff --git a/sys/dev/drm2/radeon/avivod.h b/sys/dev/drm2/radeon/avivod.h
new file mode 100644
index 0000000..4f792eb
--- /dev/null
+++ b/sys/dev/drm2/radeon/avivod.h
@@ -0,0 +1,65 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#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/sys/dev/drm2/radeon/cayman_blit_shaders.c b/sys/dev/drm2/radeon/cayman_blit_shaders.c
new file mode 100644
index 0000000..779f305
--- /dev/null
+++ b/sys/dev/drm2/radeon/cayman_blit_shaders.c
@@ -0,0 +1,375 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+
+/*
+ * 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 = DRM_ARRAY_SIZE(cayman_ps);
+const u32 cayman_vs_size = DRM_ARRAY_SIZE(cayman_vs);
+const u32 cayman_default_size = DRM_ARRAY_SIZE(cayman_default_state);
diff --git a/sys/dev/drm2/radeon/cayman_blit_shaders.h b/sys/dev/drm2/radeon/cayman_blit_shaders.h
new file mode 100644
index 0000000..621019b
--- /dev/null
+++ b/sys/dev/drm2/radeon/cayman_blit_shaders.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+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/sys/dev/drm2/radeon/cayman_reg_safe.h b/sys/dev/drm2/radeon/cayman_reg_safe.h
new file mode 100644
index 0000000..2802df6
--- /dev/null
+++ b/sys/dev/drm2/radeon/cayman_reg_safe.h
@@ -0,0 +1,517 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned cayman_reg_safe_bm[2047] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFEF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0xCFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFDDEFFF, 0xCF3FFFFF, 0xFFFFE00F,
+ 0xFEFFFFDF, 0xFFFFFFFF, 0xFFFFFFEF, 0xEFFFFFFF,
+ 0xFFFFFFCC, 0xFFFFFFFF, 0xFFFFFFFF, 0xBFFFFFD7,
+ 0xFFFBF8FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF7FFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFDF0FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xC0000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFC3E4, 0xFFFFFFFF, 0x0000FFFF, 0x00000000,
+ 0x000CC000, 0x00000000, 0xFF500000, 0x00000000,
+ 0x00000E00, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFFCF8, 0xFE07FF00,
+ 0x3CF1F003, 0xE39E7BCF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xE7020000, 0xDDD898DD, 0x279FA3FD, 0x011FFFF0,
+ 0xBFFF0000, 0xEFC3DF87, 0x7BF0F7E1, 0x1EFC3DF8,
+ 0xDFBF0F7E, 0xFFFFF7EF, 0xFFFFFFFF, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xCFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8,
+};
diff --git a/sys/dev/drm2/radeon/evergreen.c b/sys/dev/drm2/radeon/evergreen.c
new file mode 100644
index 0000000..3c98d53
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen.c
@@ -0,0 +1,3759 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include <dev/drm2/radeon/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 const u32 crtc_offsets[6] =
+{
+ EVERGREEN_CRTC0_REGISTER_OFFSET,
+ EVERGREEN_CRTC1_REGISTER_OFFSET,
+ EVERGREEN_CRTC2_REGISTER_OFFSET,
+ EVERGREEN_CRTC3_REGISTER_OFFSET,
+ EVERGREEN_CRTC4_REGISTER_OFFSET,
+ EVERGREEN_CRTC5_REGISTER_OFFSET
+};
+
+static void evergreen_gpu_init(struct radeon_device *rdev);
+void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+
+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 err, cap;
+
+ err = pci_find_cap(rdev->dev, PCIY_EXPRESS, &cap);
+ if (err)
+ return;
+
+ cap += PCIER_DEVICE_CTL;
+
+ ctl = pci_read_config(rdev->dev, cap, 2);
+
+ v = (ctl & PCIEM_CTL_MAX_READ_REQUEST) >> 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 &= ~PCIEM_CTL_MAX_READ_REQUEST;
+ ctl |= (2 << 12);
+ pci_write_config(rdev->dev, cap, ctl, 2);
+ }
+}
+
+/**
+ * dce4_wait_for_vblank - vblank wait asic callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to wait for vblank on
+ *
+ * Wait for vblank on the requested crtc (evergreen+).
+ */
+void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+ int i;
+
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK))
+ break;
+ DRM_UDELAY(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
+ break;
+ DRM_UDELAY(1);
+ }
+ }
+}
+
+/**
+ * radeon_irq_kms_pflip_irq_get - pre-pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to prepare for pageflip on
+ *
+ * Pre-pageflip callback (evergreen+).
+ * Enables the pageflip irq (vblank irq).
+ */
+void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
+{
+ /* enable the pflip int */
+ radeon_irq_kms_pflip_irq_get(rdev, crtc);
+}
+
+/**
+ * evergreen_post_page_flip - pos-pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to cleanup pageflip on
+ *
+ * Post-pageflip callback (evergreen+).
+ * Disables the pageflip irq (vblank irq).
+ */
+void evergreen_post_page_flip(struct radeon_device *rdev, int crtc)
+{
+ /* disable the pflip int */
+ radeon_irq_kms_pflip_irq_put(rdev, crtc);
+}
+
+/**
+ * evergreen_page_flip - pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc_id: crtc to cleanup pageflip on
+ * @crtc_base: new address of the crtc (GPU MC address)
+ *
+ * Does the actual pageflip (evergreen+).
+ * During vblank we take the crtc lock and wait for the update_pending
+ * bit to go high, when it does, we release the lock, and allow the
+ * double buffered update to take place.
+ * Returns the current update pending status.
+ */
+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;
+ DRM_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;
+}
+
+/**
+ * sumo_pm_init_profile - Initialize power profiles callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the power states used in profile mode
+ * (sumo, trinity, SI).
+ * Used for profile mode only.
+ */
+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;
+}
+
+/**
+ * btc_pm_init_profile - Initialize power profiles callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the power states used in profile mode
+ * (BTC, cayman).
+ * Used for profile mode only.
+ */
+void btc_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 = 2;
+ /* starting with BTC, there is one state that is used for both
+ * MH and SH. Difference is that we always use the high clock index for
+ * mclk.
+ */
+ 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);
+ /* low sh */
+ 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 */
+ 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 */
+ 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 */
+ 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;
+}
+
+/**
+ * evergreen_pm_misc - set additional pm hw parameters callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set non-clock parameters associated with a power state
+ * (voltage, etc.) (evergreen+).
+ */
+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);
+ }
+ }
+}
+
+/**
+ * evergreen_pm_prepare - pre-power state change callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Prepare for a power state change (evergreen+).
+ */
+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);
+ }
+ }
+}
+
+/**
+ * evergreen_pm_finish - post-power state change callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Clean up after a power state change (evergreen+).
+ */
+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);
+ }
+ }
+}
+
+/**
+ * evergreen_hpd_sense - hpd sense callback.
+ *
+ * @rdev: radeon_device pointer
+ * @hpd: hpd (hotplug detect) pin
+ *
+ * Checks if a digital monitor is connected (evergreen+).
+ * Returns true if connected, false if not connected.
+ */
+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;
+}
+
+/**
+ * evergreen_hpd_set_polarity - hpd set polarity callback.
+ *
+ * @rdev: radeon_device pointer
+ * @hpd: hpd (hotplug detect) pin
+ *
+ * Set the polarity of the hpd pin (evergreen+).
+ */
+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;
+ }
+}
+
+/**
+ * evergreen_hpd_init - hpd setup callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Setup the hpd pins used by the card (evergreen+).
+ * Enable the pin, set the polarity, and enable the hpd interrupts.
+ */
+void evergreen_hpd_init(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned enabled = 0;
+ 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);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HPD2_CONTROL, tmp);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HPD3_CONTROL, tmp);
+ break;
+ case RADEON_HPD_4:
+ WREG32(DC_HPD4_CONTROL, tmp);
+ break;
+ case RADEON_HPD_5:
+ WREG32(DC_HPD5_CONTROL, tmp);
+ break;
+ case RADEON_HPD_6:
+ WREG32(DC_HPD6_CONTROL, tmp);
+ break;
+ default:
+ break;
+ }
+ radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+ enabled |= 1 << radeon_connector->hpd.hpd;
+ }
+ radeon_irq_kms_enable_hpd(rdev, enabled);
+}
+
+/**
+ * evergreen_hpd_fini - hpd tear down callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the hpd pins used by the card (evergreen+).
+ * Disable the hpd interrupts.
+ */
+void evergreen_hpd_fini(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned disabled = 0;
+
+ 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);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HPD2_CONTROL, 0);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HPD3_CONTROL, 0);
+ break;
+ case RADEON_HPD_4:
+ WREG32(DC_HPD4_CONTROL, 0);
+ break;
+ case RADEON_HPD_5:
+ WREG32(DC_HPD5_CONTROL, 0);
+ break;
+ case RADEON_HPD_6:
+ WREG32(DC_HPD6_CONTROL, 0);
+ break;
+ default:
+ break;
+ }
+ disabled |= 1 << radeon_connector->hpd.hpd;
+ }
+ radeon_irq_kms_disable_hpd(rdev, disabled);
+}
+
+/* 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);
+
+}
+
+/**
+ * evergreen_bandwidth_update - update display watermarks callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Update the display watermarks based on the requested mode(s)
+ * (evergreen+).
+ */
+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);
+ }
+}
+
+/**
+ * evergreen_mc_wait_for_idle - wait for MC idle callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Wait for the MC (memory controller) to be idle.
+ * (evergreen+).
+ * Returns 0 if the MC is idle, -1 if not.
+ */
+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;
+ DRM_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) {
+ DRM_ERROR("[drm] r600 flush TLB failed\n");
+ return;
+ }
+ if (tmp) {
+ return;
+ }
+ DRM_UDELAY(1);
+ }
+}
+
+static 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;
+}
+
+static 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);
+}
+
+static void evergreen_pcie_gart_fini(struct radeon_device *rdev)
+{
+ evergreen_pcie_gart_disable(rdev);
+ radeon_gart_table_vram_free(rdev);
+ radeon_gart_fini(rdev);
+}
+
+
+static 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)
+{
+ u32 crtc_enabled, tmp, frame_count, blackout;
+ int i, j;
+
+ save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
+ save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+
+ /* disable VGA render */
+ WREG32(VGA_RENDER_CONTROL, 0);
+ /* blank the display controllers */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
+ if (crtc_enabled) {
+ save->crtc_enabled[i] = true;
+ if (ASIC_IS_DCE6(rdev)) {
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
+ if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
+ }
+ } else {
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
+ if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
+ }
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ DRM_UDELAY(1);
+ }
+ } else {
+ save->crtc_enabled[i] = false;
+ }
+ }
+
+ radeon_mc_wait_for_idle(rdev);
+
+ blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+ if ((blackout & BLACKOUT_MODE_MASK) != 1) {
+ /* Block CPU access */
+ WREG32(BIF_FB_EN, 0);
+ /* blackout the MC */
+ blackout &= ~BLACKOUT_MODE_MASK;
+ WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
+ }
+ /* wait for the MC to settle */
+ DRM_UDELAY(100);
+}
+
+void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
+{
+ u32 tmp, frame_count;
+ int i, j;
+
+ /* update crtc base addresses */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
+ upper_32_bits(rdev->mc.vram_start));
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
+ upper_32_bits(rdev->mc.vram_start));
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
+ (u32)rdev->mc.vram_start);
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
+ (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);
+
+ /* unblackout the MC */
+ tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
+ tmp &= ~BLACKOUT_MODE_MASK;
+ WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
+ /* allow CPU access */
+ WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
+
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (save->crtc_enabled[i]) {
+ if (ASIC_IS_DCE6(rdev)) {
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
+ } else {
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
+ tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
+ WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ DRM_UDELAY(1);
+ }
+ }
+ }
+ /* Unlock vga access */
+ WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
+ DRM_MDELAY(1);
+ 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->ring];
+ u32 next_rptr;
+
+ /* set to DX10/11 mode */
+ radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
+ radeon_ring_write(ring, 1);
+
+ if (ring->rptr_save_reg) {
+ next_rptr = ring->wptr + 3 + 4;
+ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+ radeon_ring_write(ring, ((ring->rptr_save_reg -
+ PACKET3_SET_CONFIG_REG_START) >> 2));
+ radeon_ring_write(ring, next_rptr);
+ } else if (rdev->wb.enabled) {
+ next_rptr = ring->wptr + 5 + 4;
+ radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
+ radeon_ring_write(ring, next_rptr);
+ radeon_ring_write(ring, 0);
+ }
+
+ 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;
+}
+
+static 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);
+ DRM_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 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);
+ }
+
+ DRM_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 void evergreen_gpu_init(struct radeon_device *rdev)
+{
+ u32 gb_addr_config;
+ u32 mc_shared_chmap, mc_arb_ramcfg;
+ 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;
+ u32 disabled_rb_mask;
+ 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;
+ gb_addr_config = CYPRESS_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = JUNIPER_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_SUMO:
+ rdev->config.evergreen.num_ses = 1;
+ rdev->config.evergreen.max_pipes = 4;
+ rdev->config.evergreen.max_tile_pipes = 4;
+ if (rdev->ddev->pci_device == 0x9648)
+ rdev->config.evergreen.max_simds = 3;
+ else if ((rdev->ddev->pci_device == 0x9647) ||
+ (rdev->ddev->pci_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;
+ gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = BARTS_GB_ADDR_CONFIG_GOLDEN;
+ 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;
+ gb_addr_config = TURKS_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_CAICOS:
+ 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;
+ gb_addr_config = CAICOS_GB_ADDR_CONFIG_GOLDEN;
+ 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);
+ 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);
+
+ /* 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 {
+ switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+ case 0: /* four banks */
+ rdev->config.evergreen.tile_config |= 0 << 4;
+ break;
+ case 1: /* eight banks */
+ rdev->config.evergreen.tile_config |= 1 << 4;
+ break;
+ case 2: /* sixteen banks */
+ default:
+ rdev->config.evergreen.tile_config |= 2 << 4;
+ break;
+ }
+ }
+ rdev->config.evergreen.tile_config |= 0 << 8;
+ rdev->config.evergreen.tile_config |=
+ ((gb_addr_config & 0x30000000) >> 28) << 12;
+
+ num_shader_engines = (gb_addr_config & NUM_SHADER_ENGINES(3) >> 12) + 1;
+
+ if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) {
+ u32 efuse_straps_4;
+ u32 efuse_straps_3;
+
+ WREG32(RCU_IND_INDEX, 0x204);
+ efuse_straps_4 = RREG32(RCU_IND_DATA);
+ WREG32(RCU_IND_INDEX, 0x203);
+ efuse_straps_3 = RREG32(RCU_IND_DATA);
+ tmp = (((efuse_straps_4 & 0xf) << 4) |
+ ((efuse_straps_3 & 0xf0000000) >> 28));
+ } else {
+ tmp = 0;
+ for (i = (rdev->config.evergreen.num_ses - 1); i >= 0; i--) {
+ u32 rb_disable_bitmap;
+
+ WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
+ WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
+ rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
+ tmp <<= 4;
+ tmp |= rb_disable_bitmap;
+ }
+ }
+ /* enabled rb are just the one not disabled :) */
+ disabled_rb_mask = tmp;
+
+ WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
+ WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
+
+ WREG32(GB_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
+ WREG32(HDP_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMA_TILING_CONFIG, gb_addr_config);
+
+ if ((rdev->config.evergreen.max_backends == 1) &&
+ (rdev->flags & RADEON_IS_IGP)) {
+ if ((disabled_rb_mask & 3) == 1) {
+ /* RB0 disabled, RB1 enabled */
+ tmp = 0x11111111;
+ } else {
+ /* RB1 disabled, RB0 enabled */
+ tmp = 0x00000000;
+ }
+ } else {
+ tmp = gb_addr_config & NUM_PIPES_MASK;
+ tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
+ EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
+ }
+ WREG32(GB_BACKEND_MAP, tmp);
+
+ 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));
+
+ DRM_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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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;
+
+ 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)) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force CP activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev)
+{
+ u32 grbm_reset = 0;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ return;
+
+ 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, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+
+ /* 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);
+ DRM_UDELAY(50);
+ WREG32(GRBM_SOFT_RESET, 0);
+ (void)RREG32(GRBM_SOFT_RESET);
+
+ 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, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+}
+
+static void evergreen_gpu_soft_reset_dma(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ return;
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+
+ /* Disable DMA */
+ tmp = RREG32(DMA_RB_CNTL);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL, tmp);
+
+ /* Reset dma */
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+}
+
+static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
+{
+ struct evergreen_mc_save save;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE);
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ reset_mask &= ~RADEON_RESET_DMA;
+
+ if (reset_mask == 0)
+ return 0;
+
+ dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+
+ evergreen_mc_stop(rdev, &save);
+ if (evergreen_mc_wait_for_idle(rdev)) {
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+ }
+
+ if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE))
+ evergreen_gpu_soft_reset_gfx(rdev);
+
+ if (reset_mask & RADEON_RESET_DMA)
+ evergreen_gpu_soft_reset_dma(rdev);
+
+ /* Wait a little for things to settle down */
+ DRM_UDELAY(50);
+
+ evergreen_mc_resume(rdev, &save);
+ return 0;
+}
+
+int evergreen_asic_reset(struct radeon_device *rdev)
+{
+ return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
+ RADEON_RESET_COMPUTE |
+ RADEON_RESET_DMA));
+}
+
+/* Interrupts */
+
+u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
+{
+ if (crtc >= rdev->num_crtc)
+ return 0;
+ else
+ return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
+}
+
+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);
+ tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
+ WREG32(CAYMAN_DMA1_CNTL, tmp);
+ } else
+ WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+ tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
+ WREG32(DMA_CNTL, tmp);
+ 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;
+ u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
+ u32 dma_cntl, dma_cntl1 = 0;
+
+ if (!rdev->irq.installed) {
+ dev_warn(rdev->dev, "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;
+
+ afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ afmt3 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ afmt4 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+
+ dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
+
+ if (rdev->family >= CHIP_CAYMAN) {
+ /* enable CP interrupts on all rings */
+ if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
+ DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
+ cp_int_cntl |= TIME_STAMP_INT_ENABLE;
+ }
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
+ DRM_DEBUG("evergreen_irq_set: sw int cp1\n");
+ cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
+ }
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
+ DRM_DEBUG("evergreen_irq_set: sw int cp2\n");
+ cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
+ }
+ } else {
+ if (atomic_read(&rdev->irq.ring_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 (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
+ DRM_DEBUG("r600_irq_set: sw int dma\n");
+ dma_cntl |= TRAP_ENABLE;
+ }
+
+ if (rdev->family >= CHIP_CAYMAN) {
+ dma_cntl1 = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
+ DRM_DEBUG("r600_irq_set: sw int dma1\n");
+ dma_cntl1 |= TRAP_ENABLE;
+ }
+ }
+
+ if (rdev->irq.crtc_vblank_int[0] ||
+ atomic_read(&rdev->irq.pflip[0])) {
+ DRM_DEBUG("evergreen_irq_set: vblank 0\n");
+ crtc1 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[1] ||
+ atomic_read(&rdev->irq.pflip[1])) {
+ DRM_DEBUG("evergreen_irq_set: vblank 1\n");
+ crtc2 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[2] ||
+ atomic_read(&rdev->irq.pflip[2])) {
+ DRM_DEBUG("evergreen_irq_set: vblank 2\n");
+ crtc3 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[3] ||
+ atomic_read(&rdev->irq.pflip[3])) {
+ DRM_DEBUG("evergreen_irq_set: vblank 3\n");
+ crtc4 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[4] ||
+ atomic_read(&rdev->irq.pflip[4])) {
+ DRM_DEBUG("evergreen_irq_set: vblank 4\n");
+ crtc5 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[5] ||
+ atomic_read(&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.afmt[0]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 0\n");
+ afmt1 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[1]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 1\n");
+ afmt2 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[2]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 2\n");
+ afmt3 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[3]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 3\n");
+ afmt4 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[4]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 4\n");
+ afmt5 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[5]) {
+ DRM_DEBUG("evergreen_irq_set: hdmi 5\n");
+ afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK;
+ }
+
+ 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(DMA_CNTL, dma_cntl);
+
+ if (rdev->family >= CHIP_CAYMAN)
+ WREG32(CAYMAN_DMA1_CNTL, dma_cntl1);
+
+ 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);
+
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, afmt3);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, afmt4);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6);
+
+ 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);
+ }
+
+ rdev->irq.stat_regs.evergreen.afmt_status1 = RREG32(AFMT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.afmt_status2 = RREG32(AFMT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.afmt_status3 = RREG32(AFMT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.afmt_status4 = RREG32(AFMT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.afmt_status5 = RREG32(AFMT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.afmt_status6 = RREG32(AFMT_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);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp);
+ }
+ if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp);
+ }
+}
+
+static void evergreen_irq_disable(struct radeon_device *rdev)
+{
+ r600_disable_interrupts(rdev);
+ /* Wait and acknowledge irq */
+ DRM_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);
+}
+
+irqreturn_t evergreen_irq_process(struct radeon_device *rdev)
+{
+ u32 wptr;
+ u32 rptr;
+ u32 src_id, src_data;
+ u32 ring_index;
+ bool queue_hotplug = false;
+ bool queue_hdmi = false;
+
+ if (!rdev->ih.enabled || rdev->shutdown)
+ return IRQ_NONE;
+
+ wptr = evergreen_get_ih_wptr(rdev);
+
+restart_ih:
+ /* is somebody else already processing irqs? */
+ if (atomic_xchg(&rdev->ih.lock, 1))
+ return IRQ_NONE;
+
+ rptr = rdev->ih.rptr;
+ DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
+ /* Order reading of wptr vs. reading of IH ring data */
+ rmb();
+
+ /* display interrupts */
+ evergreen_irq_ack(rdev);
+
+ 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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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 44: /* hdmi */
+ switch (src_data) {
+ case 0:
+ if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI0\n");
+ }
+ break;
+ case 1:
+ if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI1\n");
+ }
+ break;
+ case 2:
+ if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI2\n");
+ }
+ break;
+ case 3:
+ if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI3\n");
+ }
+ break;
+ case 4:
+ if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI4\n");
+ }
+ break;
+ case 5:
+ if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI5\n");
+ }
+ break;
+ default:
+ DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
+ break;
+ }
+ break;
+ case 146:
+ case 147:
+ dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
+ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+ /* reset addr and status */
+ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+ 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 224: /* DMA trap event */
+ DRM_DEBUG("IH: DMA trap\n");
+ radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
+ break;
+ case 233: /* GUI IDLE */
+ DRM_DEBUG("IH: GUI idle\n");
+ break;
+ case 244: /* DMA trap event */
+ if (rdev->family >= CHIP_CAYMAN) {
+ DRM_DEBUG("IH: DMA1 trap\n");
+ radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+ }
+ 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;
+ }
+ if (queue_hotplug)
+ taskqueue_enqueue(rdev->tq, &rdev->hotplug_work);
+ if (queue_hdmi)
+ taskqueue_enqueue(rdev->tq, &rdev->audio_work);
+ rdev->ih.rptr = rptr;
+ WREG32(IH_RB_RPTR, rdev->ih.rptr);
+ atomic_set(&rdev->ih.lock, 0);
+
+ /* make sure wptr hasn't changed while processing */
+ wptr = evergreen_get_ih_wptr(rdev);
+ if (wptr != rptr)
+ goto restart_ih;
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * evergreen_dma_fence_ring_emit - emit a fence on the DMA ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Add a DMA fence packet to the ring to write
+ * the fence seq number and DMA trap packet to generate
+ * an interrupt if needed (evergreen-SI).
+ */
+void evergreen_dma_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;
+ /* write the fence */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0));
+ radeon_ring_write(ring, addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(addr) & 0xff));
+ radeon_ring_write(ring, fence->seq);
+ /* generate an interrupt */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0));
+ /* flush HDP */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
+ radeon_ring_write(ring, 1);
+}
+
+/**
+ * evergreen_dma_ring_ib_execute - schedule an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ *
+ * Schedule an IB in the DMA ring (evergreen).
+ */
+void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
+ struct radeon_ib *ib)
+{
+ struct radeon_ring *ring = &rdev->ring[ib->ring];
+
+ if (rdev->wb.enabled) {
+ u32 next_rptr = ring->wptr + 4;
+ while ((next_rptr & 7) != 5)
+ next_rptr++;
+ next_rptr += 3;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
+ * Pad as necessary with NOPs.
+ */
+ while ((ring->wptr & 7) != 5)
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_INDIRECT_BUFFER, 0, 0, 0));
+ radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
+ radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
+
+}
+
+/**
+ * evergreen_copy_dma - copy pages using the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the DMA engine (evergreen-cayman).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int evergreen_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence)
+{
+ struct radeon_semaphore *sem = NULL;
+ int ring_index = rdev->asic->copy.dma_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ring_index];
+ u32 size_in_dw, cur_size_in_dw;
+ int i, num_loops;
+ int r = 0;
+
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ return r;
+ }
+
+ size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
+ num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff);
+ r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ radeon_semaphore_free(rdev, &sem, NULL);
+ return r;
+ }
+
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
+
+ for (i = 0; i < num_loops; i++) {
+ cur_size_in_dw = size_in_dw;
+ if (cur_size_in_dw > 0xFFFFF)
+ cur_size_in_dw = 0xFFFFF;
+ size_in_dw -= cur_size_in_dw;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw));
+ radeon_ring_write(ring, dst_offset & 0xfffffffc);
+ radeon_ring_write(ring, src_offset & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
+ radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff);
+ src_offset += cur_size_in_dw * 4;
+ dst_offset += cur_size_in_dw * 4;
+ }
+
+ r = radeon_fence_emit(rdev, fence, ring->idx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, *fence);
+
+ return r;
+}
+
+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;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA 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;
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+ DMA_RB_RPTR, DMA_RB_WPTR,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ if (r)
+ return r;
+
+ r = evergreen_cp_load_microcode(rdev);
+ if (r)
+ return r;
+ r = evergreen_cp_resume(rdev);
+ if (r)
+ return r;
+ r = r600_dma_resume(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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)
+{
+ r600_audio_fini(rdev);
+ r700_cp_stop(rdev);
+ r600_dma_stop(rdev);
+ 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;
+
+ /* 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->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
+ r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
+
+ rdev->ih.ring_obj = NULL;
+ r600_ih_ring_init(rdev, 64 * 1024);
+
+ r = r600_pcie_gart_init(rdev);
+ if (r)
+ return r;
+
+ rdev->accel_working = true;
+ r = evergreen_startup(rdev);
+ if (r) {
+ dev_err(rdev->dev, "disabling GPU acceleration\n");
+ r700_cp_fini(rdev);
+ r600_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_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_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ evergreen_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
+ radeon_gem_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_agp_fini(rdev);
+ radeon_bo_fini(rdev);
+ radeon_atombios_fini(rdev);
+ if (ASIC_IS_DCE5(rdev))
+ ni_fini_microcode(rdev);
+ else
+ r600_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ rdev->bios = NULL;
+}
+
+void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
+{
+ u32 link_width_cntl, speed_cntl, mask;
+ int ret;
+
+ 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;
+
+ ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+ if (ret != 0)
+ return;
+
+ if (!(mask & DRM_PCIE_SPEED_50))
+ return;
+
+ speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ }
+
+ DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
+
+ 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/sys/dev/drm2/radeon/evergreen_blit_kms.c b/sys/dev/drm2/radeon/evergreen_blit_kms.c
new file mode 100644
index 0000000..1012f3f
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_blit_kms.c
@@ -0,0 +1,733 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.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 = roundup2(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 = roundup2(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 = 8; /* sync semaphore */
+ 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;
+
+ 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 = roundup2(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 = roundup2(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 = roundup2(obj_size, 256);
+
+ /* pin copy shader into vram if not already initialized */
+ if (!rdev->r600_blit.shader_obj) {
+ r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_VRAM,
+ NULL, &rdev->r600_blit.shader_obj);
+ if (r) {
+ DRM_ERROR("evergreen failed to allocate shader\n");
+ return r;
+ }
+
+ 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;
+ }
+ }
+
+ 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((char *)ptr + rdev->r600_blit.state_offset,
+ evergreen_default_state, rdev->r600_blit.state_len * 4);
+
+ if (num_packet2s)
+ memcpy_toio((char *)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((char *)ptr + rdev->r600_blit.state_offset,
+ cayman_default_state, rdev->r600_blit.state_len * 4);
+
+ if (num_packet2s)
+ memcpy_toio((char *)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);
+
+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/evergreen_blit_shaders.c b/sys/dev/drm2/radeon/evergreen_blit_shaders.c
new file mode 100644
index 0000000..6db3cef
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_blit_shaders.c
@@ -0,0 +1,358 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+
+/*
+ * 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 = DRM_ARRAY_SIZE(evergreen_ps);
+const u32 evergreen_vs_size = DRM_ARRAY_SIZE(evergreen_vs);
+const u32 evergreen_default_size = DRM_ARRAY_SIZE(evergreen_default_state);
diff --git a/sys/dev/drm2/radeon/evergreen_blit_shaders.h b/sys/dev/drm2/radeon/evergreen_blit_shaders.h
new file mode 100644
index 0000000..a5e2dc3
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_blit_shaders.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/evergreen_cs.c b/sys/dev/drm2/radeon/evergreen_cs.c
new file mode 100644
index 0000000..693c38c
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_cs.c
@@ -0,0 +1,3727 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "evergreend.h"
+#include "evergreen_reg_safe.h"
+#include "cayman_reg_safe.h"
+#include "r600_cs.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 = roundup(nbx, 16 * 8);
+ /* height is npipes htiles aligned == npipes * 8 pixel aligned */
+ nby = roundup(nby, track->npipes * 8);
+ } else {
+ /* always assume 8x8 htile */
+ /* align is htile align * 8, htile align vary according to
+ * number of pipe and tile width and nby
+ */
+ switch (track->npipes) {
+ case 8:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup(nbx, 64 * 8);
+ nby = roundup(nby, 64 * 8);
+ break;
+ case 4:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup(nbx, 64 * 8);
+ nby = roundup(nby, 32 * 8);
+ break;
+ case 2:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup(nbx, 32 * 8);
+ nby = roundup(nby, 32 * 8);
+ break;
+ case 1:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup(nbx, 32 * 8);
+ nby = roundup(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 >> 3;
+ nby = nby >> 3;
+ /* size must be aligned on npipes * 2K boundary */
+ size = roundup(nbx * nby * 4, track->npipes * (2 << 10));
+ 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;
+ break;
+ case V_030000_SQ_TEX_DIM_2D_MSAA:
+ case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA:
+ surf.nsamples = 1 << llevel;
+ llevel = 0;
+ depth = 1;
+ break;
+ 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 = roundup(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;
+ }
+
+ if (!mipmap) {
+ if (llevel) {
+ dev_warn(p->dev, "%s:%i got NULL MIP_ADDRESS relocation\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ } else {
+ return 0; /* everything's ok */
+ }
+ }
+
+ /* 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 = roundup(surf.nbx, surf.palign);
+ surf.nby = roundup(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%jx, 0x%lx\n",
+ i, (uintmax_t)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_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID &&
+ G_028800_STENCIL_ENABLE(track->db_depth_control)) {
+ r = evergreen_cs_track_validate_stencil(p);
+ if (r)
+ return r;
+ }
+ /* Check depth buffer */
+ if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID &&
+ 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.
+ **/
+static 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_is_pkt3_nop() - test if the next packet is NOP
+ * @p: structure holding the parser context.
+ *
+ * Check if the next packet is a relocation packet3.
+ **/
+static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_packet p3reloc;
+ int r;
+
+ r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
+ if (r) {
+ return false;
+ }
+ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * 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:
+ DRM_ERROR("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 = DRM_ARRAY_SIZE(cayman_reg_safe_bm);
+ else
+ last_reg = DRM_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);
+ /* force 8x8 htile width and height */
+ ib[idx] |= 3;
+ 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 = DRM_ARRAY_SIZE(cayman_reg_safe_bm);
+ else
+ last_reg = DRM_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_CP_DMA:
+ {
+ u32 command, size, info;
+ u64 offset, tmp;
+ if (pkt->count != 4) {
+ DRM_ERROR("bad CP DMA\n");
+ return -EINVAL;
+ }
+ command = radeon_get_ib_value(p, idx+4);
+ size = command & 0x1fffff;
+ info = radeon_get_ib_value(p, idx+1);
+ if ((((info & 0x60000000) >> 29) != 0) || /* src = GDS or DATA */
+ (((info & 0x00300000) >> 20) != 0) || /* dst = GDS */
+ ((((info & 0x00300000) >> 20) == 0) &&
+ (command & PACKET3_CP_DMA_CMD_DAS)) || /* dst = register */
+ ((((info & 0x60000000) >> 29) == 0) &&
+ (command & PACKET3_CP_DMA_CMD_SAS))) { /* src = register */
+ /* non mem to mem copies requires dw aligned count */
+ if (size % 4) {
+ DRM_ERROR("CP DMA command requires dw count alignment\n");
+ return -EINVAL;
+ }
+ }
+ if (command & PACKET3_CP_DMA_CMD_SAS) {
+ /* src address space is register */
+ /* GDS is ok */
+ if (((info & 0x60000000) >> 29) != 1) {
+ DRM_ERROR("CP DMA SAS not supported\n");
+ return -EINVAL;
+ }
+ } else {
+ if (command & PACKET3_CP_DMA_CMD_SAIC) {
+ DRM_ERROR("CP DMA SAIC only supported for registers\n");
+ return -EINVAL;
+ }
+ /* src address space is memory */
+ if (((info & 0x60000000) >> 29) == 0) {
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad CP DMA SRC\n");
+ return -EINVAL;
+ }
+
+ tmp = radeon_get_ib_value(p, idx) +
+ ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
+
+ offset = reloc->lobj.gpu_offset + tmp;
+
+ if ((tmp + size) > radeon_bo_size(reloc->robj)) {
+ dev_warn(p->dev, "CP DMA src buffer too small (%ju %lu)\n",
+ (uintmax_t)tmp + size, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+
+ ib[idx] = offset;
+ ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
+ } else if (((info & 0x60000000) >> 29) != 2) {
+ DRM_ERROR("bad CP DMA SRC_SEL\n");
+ return -EINVAL;
+ }
+ }
+ if (command & PACKET3_CP_DMA_CMD_DAS) {
+ /* dst address space is register */
+ /* GDS is ok */
+ if (((info & 0x00300000) >> 20) != 1) {
+ DRM_ERROR("CP DMA DAS not supported\n");
+ return -EINVAL;
+ }
+ } else {
+ /* dst address space is memory */
+ if (command & PACKET3_CP_DMA_CMD_DAIC) {
+ DRM_ERROR("CP DMA DAIC only supported for registers\n");
+ return -EINVAL;
+ }
+ if (((info & 0x00300000) >> 20) == 0) {
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad CP DMA DST\n");
+ return -EINVAL;
+ }
+
+ tmp = radeon_get_ib_value(p, idx+2) +
+ ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);
+
+ offset = reloc->lobj.gpu_offset + tmp;
+
+ if ((tmp + size) > radeon_bo_size(reloc->robj)) {
+ dev_warn(p->dev, "CP DMA dst buffer too small (%ju %lu)\n",
+ (uintmax_t)tmp + size, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+
+ ib[idx+2] = offset;
+ ib[idx+3] = upper_32_bits(offset) & 0xff;
+ } else {
+ DRM_ERROR("bad CP DMA DST_SEL\n");
+ return -EINVAL;
+ }
+ }
+ 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, mip_address, tex_dim;
+
+ 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 */
+ tex_dim = ib[idx+1+(i*8)+0] & 0x7;
+ mip_address = ib[idx+1+(i*8)+3];
+
+ if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) &&
+ !mip_address &&
+ !evergreen_cs_packet_next_is_pkt3_nop(p)) {
+ /* MIP_ADDRESS should point to FMASK for an MSAA texture.
+ * It should be 0 if FMASK is disabled. */
+ moffset = 0;
+ mipmap = NULL;
+ } else {
+ 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%jx, 0x%lx\n",
+ (uintmax_t)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%jx, 0x%lx\n",
+ (uintmax_t)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_MEM_WRITE:
+ {
+ u64 offset;
+
+ if (pkt->count != 3) {
+ DRM_ERROR("bad MEM_WRITE (invalid count)\n");
+ return -EINVAL;
+ }
+ r = evergreen_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
+ return -EINVAL;
+ }
+ offset = radeon_get_ib_value(p, idx+0);
+ offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
+ if (offset & 0x7) {
+ DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
+ return -EINVAL;
+ }
+ if ((offset + 8) > radeon_bo_size(reloc->robj)) {
+ DRM_ERROR("bad MEM_WRITE bo too small: 0x%jx, 0x%lx\n",
+ (uintmax_t)offset + 8, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+ offset += reloc->lobj.gpu_offset;
+ ib[idx+0] = offset;
+ ib[idx+1] = 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%jx, 0x%lx\n",
+ (uintmax_t)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%jx, 0x%lx\n",
+ (uintmax_t)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 = malloc(sizeof(*track), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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) {
+ free(p->track, DRM_MEM_DRIVER);
+ 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);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return -EINVAL;
+ }
+ if (r) {
+ free(p->track, DRM_MEM_DRIVER);
+ 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++) {
+ DRM_INFO("%05d 0x%08X\n", r, p->ib.ptr[r]);
+ mdelay(1);
+ }
+#endif
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return 0;
+}
+
+/*
+ * DMA
+ */
+
+#define GET_DMA_CMD(h) (((h) & 0xf0000000) >> 28)
+#define GET_DMA_COUNT(h) ((h) & 0x000fffff)
+#define GET_DMA_T(h) (((h) & 0x00800000) >> 23)
+#define GET_DMA_NEW(h) (((h) & 0x04000000) >> 26)
+#define GET_DMA_MISC(h) (((h) & 0x0700000) >> 20)
+
+/**
+ * evergreen_dma_cs_parse() - parse the DMA IB
+ * @p: parser structure holding parsing context.
+ *
+ * Parses the DMA IB from the CS ioctl and updates
+ * the GPU addresses based on the reloc information and
+ * checks for errors. (Evergreen-Cayman)
+ * Returns 0 for success and an error on failure.
+ **/
+int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
+ struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc;
+ u32 header, cmd, count, tiled, new_cmd, misc;
+ volatile u32 *ib = p->ib.ptr;
+ u32 idx, idx_value;
+ u64 src_offset, dst_offset, dst2_offset;
+ int r;
+
+ do {
+ if (p->idx >= ib_chunk->length_dw) {
+ DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
+ p->idx, ib_chunk->length_dw);
+ return -EINVAL;
+ }
+ idx = p->idx;
+ header = radeon_get_ib_value(p, idx);
+ cmd = GET_DMA_CMD(header);
+ count = GET_DMA_COUNT(header);
+ tiled = GET_DMA_T(header);
+ new_cmd = GET_DMA_NEW(header);
+ misc = GET_DMA_MISC(header);
+
+ switch (cmd) {
+ case DMA_PACKET_WRITE:
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_WRITE\n");
+ return -EINVAL;
+ }
+ if (tiled) {
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ p->idx += count + 7;
+ } else {
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += count + 3;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA write buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset, radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ break;
+ case DMA_PACKET_COPY:
+ r = r600_dma_cs_next_reloc(p, &src_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ if (tiled) {
+ idx_value = radeon_get_ib_value(p, idx + 2);
+ if (new_cmd) {
+ switch (misc) {
+ case 0:
+ /* L2T, frame to fields */
+ if (idx_value & (1 << 31)) {
+ DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst2_reloc);
+ if (r) {
+ DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ dst2_offset = radeon_get_ib_value(p, idx+2);
+ dst2_offset <<= 8;
+ src_offset = radeon_get_ib_value(p, idx+8);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%ju %lu)\n",
+ (uintmax_t)dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8);
+ ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 10;
+ break;
+ case 1:
+ /* L2T, T2L partial */
+ if (p->family < CHIP_CAYMAN) {
+ DRM_ERROR("L2T, T2L Partial is cayman only !\n");
+ return -EINVAL;
+ }
+ /* detile bit */
+ if (idx_value & (1 << 31)) {
+ /* tiled src, linear dst */
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
+
+ ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ } else {
+ /* linear src, tiled dst */
+ ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ }
+ p->idx += 12;
+ break;
+ case 3:
+ /* L2T, broadcast */
+ if (idx_value & (1 << 31)) {
+ DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst2_reloc);
+ if (r) {
+ DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ dst2_offset = radeon_get_ib_value(p, idx+2);
+ dst2_offset <<= 8;
+ src_offset = radeon_get_ib_value(p, idx+8);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%ju %lu)\n",
+ (uintmax_t)dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8);
+ ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 10;
+ break;
+ case 4:
+ /* L2T, T2L */
+ /* detile bit */
+ if (idx_value & (1 << 31)) {
+ /* tiled src, linear dst */
+ src_offset = radeon_get_ib_value(p, idx+1);
+ src_offset <<= 8;
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
+
+ dst_offset = radeon_get_ib_value(p, idx+7);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
+ ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ } else {
+ /* linear src, tiled dst */
+ src_offset = radeon_get_ib_value(p, idx+7);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
+ ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ }
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, T2L src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, T2L dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ p->idx += 9;
+ break;
+ case 5:
+ /* T2T partial */
+ if (p->family < CHIP_CAYMAN) {
+ DRM_ERROR("L2T, T2L Partial is cayman only !\n");
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
+ ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ p->idx += 13;
+ break;
+ case 7:
+ /* L2T, broadcast */
+ if (idx_value & (1 << 31)) {
+ DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst2_reloc);
+ if (r) {
+ DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ dst2_offset = radeon_get_ib_value(p, idx+2);
+ dst2_offset <<= 8;
+ src_offset = radeon_get_ib_value(p, idx+8);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%ju %lu)\n",
+ (uintmax_t)dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8);
+ ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 10;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ } else {
+ switch (misc) {
+ case 0:
+ /* detile bit */
+ if (idx_value & (1 << 31)) {
+ /* tiled src, linear dst */
+ src_offset = radeon_get_ib_value(p, idx+1);
+ src_offset <<= 8;
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
+
+ dst_offset = radeon_get_ib_value(p, idx+7);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
+ ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ } else {
+ /* linear src, tiled dst */
+ src_offset = radeon_get_ib_value(p, idx+7);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
+ ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ }
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ p->idx += 9;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ }
+ } else {
+ if (new_cmd) {
+ switch (misc) {
+ case 0:
+ /* L2L, byte */
+ src_offset = radeon_get_ib_value(p, idx+2);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
+ if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, byte src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + count, radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + count) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, byte dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + count, radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff);
+ ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff);
+ ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 5;
+ break;
+ case 1:
+ /* L2L, partial */
+ if (p->family < CHIP_CAYMAN) {
+ DRM_ERROR("L2L Partial is cayman only !\n");
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff);
+ ib[idx+2] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff);
+ ib[idx+5] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+
+ p->idx += 9;
+ break;
+ case 4:
+ /* L2L, dw, broadcast */
+ r = r600_dma_cs_next_reloc(p, &dst2_reloc);
+ if (r) {
+ DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+ dst2_offset = radeon_get_ib_value(p, idx+2);
+ dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32;
+ src_offset = radeon_get_ib_value(p, idx+3);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, dw, broadcast dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, dw, broadcast dst2 buffer too small (%ju %lu)\n",
+ (uintmax_t)dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+4] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+5] += upper_32_bits(dst2_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+6] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 7;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ } else {
+ /* L2L, dw */
+ src_offset = radeon_get_ib_value(p, idx+2);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, dw src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA L2L, dw dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 5;
+ }
+ }
+ break;
+ case DMA_PACKET_CONSTANT_FILL:
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_CONSTANT_FILL\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA constant fill buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset, radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) << 16) & 0x00ff0000;
+ p->idx += 4;
+ break;
+ case DMA_PACKET_NOP:
+ p->idx += 1;
+ break;
+ default:
+ DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
+ return -EINVAL;
+ }
+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+#if 0
+ for (r = 0; r < p->ib->length_dw; r++) {
+ DRM_INFO("%05d 0x%08X\n", r, p->ib.ptr[r]);
+ mdelay(1);
+ }
+#endif
+ 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 WAIT_UNTIL:
+ case GRBM_GFX_INDEX:
+ case CP_STRMOUT_CNTL:
+ case CP_COHER_CNTL:
+ case CP_COHER_SIZE:
+ 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:
+ DRM_ERROR("Invalid register 0x%x in CS\n", reg);
+ 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;
+ u32 command, info;
+
+ 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;
+ case PACKET3_CP_DMA:
+ command = ib[idx + 4];
+ info = ib[idx + 1];
+ if ((((info & 0x60000000) >> 29) != 0) || /* src = GDS or DATA */
+ (((info & 0x00300000) >> 20) != 0) || /* dst = GDS */
+ ((((info & 0x00300000) >> 20) == 0) &&
+ (command & PACKET3_CP_DMA_CMD_DAS)) || /* dst = register */
+ ((((info & 0x60000000) >> 29) == 0) &&
+ (command & PACKET3_CP_DMA_CMD_SAS))) { /* src = register */
+ /* non mem to mem copies requires dw aligned count */
+ if ((command & 0x1fffff) % 4) {
+ DRM_ERROR("CP DMA command requires dw count alignment\n");
+ return -EINVAL;
+ }
+ }
+ if (command & PACKET3_CP_DMA_CMD_SAS) {
+ /* src address space is register */
+ if (((info & 0x60000000) >> 29) == 0) {
+ start_reg = idx_value << 2;
+ if (command & PACKET3_CP_DMA_CMD_SAIC) {
+ reg = start_reg;
+ if (!evergreen_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad SRC register\n");
+ return -EINVAL;
+ }
+ } else {
+ for (i = 0; i < (command & 0x1fffff); i++) {
+ reg = start_reg + (4 * i);
+ if (!evergreen_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad SRC register\n");
+ return -EINVAL;
+ }
+ }
+ }
+ }
+ }
+ if (command & PACKET3_CP_DMA_CMD_DAS) {
+ /* dst address space is register */
+ if (((info & 0x00300000) >> 20) == 0) {
+ start_reg = ib[idx + 2];
+ if (command & PACKET3_CP_DMA_CMD_DAIC) {
+ reg = start_reg;
+ if (!evergreen_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad DST register\n");
+ return -EINVAL;
+ }
+ } else {
+ for (i = 0; i < (command & 0x1fffff); i++) {
+ reg = start_reg + (4 * i);
+ if (!evergreen_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad DST register\n");
+ 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;
+}
+
+/**
+ * evergreen_dma_ib_parse() - parse the DMA IB for VM
+ * @rdev: radeon_device pointer
+ * @ib: radeon_ib pointer
+ *
+ * Parses the DMA IB from the VM CS ioctl
+ * checks for errors. (Cayman-SI)
+ * Returns 0 for success and an error on failure.
+ **/
+int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+ u32 idx = 0;
+ u32 header, cmd, count, tiled, new_cmd, misc;
+
+ do {
+ header = ib->ptr[idx];
+ cmd = GET_DMA_CMD(header);
+ count = GET_DMA_COUNT(header);
+ tiled = GET_DMA_T(header);
+ new_cmd = GET_DMA_NEW(header);
+ misc = GET_DMA_MISC(header);
+
+ switch (cmd) {
+ case DMA_PACKET_WRITE:
+ if (tiled)
+ idx += count + 7;
+ else
+ idx += count + 3;
+ break;
+ case DMA_PACKET_COPY:
+ if (tiled) {
+ if (new_cmd) {
+ switch (misc) {
+ case 0:
+ /* L2T, frame to fields */
+ idx += 10;
+ break;
+ case 1:
+ /* L2T, T2L partial */
+ idx += 12;
+ break;
+ case 3:
+ /* L2T, broadcast */
+ idx += 10;
+ break;
+ case 4:
+ /* L2T, T2L */
+ idx += 9;
+ break;
+ case 5:
+ /* T2T partial */
+ idx += 13;
+ break;
+ case 7:
+ /* L2T, broadcast */
+ idx += 10;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ } else {
+ switch (misc) {
+ case 0:
+ idx += 9;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ }
+ } else {
+ if (new_cmd) {
+ switch (misc) {
+ case 0:
+ /* L2L, byte */
+ idx += 5;
+ break;
+ case 1:
+ /* L2L, partial */
+ idx += 9;
+ break;
+ case 4:
+ /* L2L, dw, broadcast */
+ idx += 7;
+ break;
+ default:
+ DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
+ return -EINVAL;
+ }
+ } else {
+ /* L2L, dw */
+ idx += 5;
+ }
+ }
+ break;
+ case DMA_PACKET_CONSTANT_FILL:
+ idx += 4;
+ break;
+ case DMA_PACKET_NOP:
+ idx += 1;
+ break;
+ default:
+ DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
+ return -EINVAL;
+ }
+ } while (idx < ib->length_dw);
+
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/evergreen_hdmi.c b/sys/dev/drm2/radeon/evergreen_hdmi.c
new file mode 100644
index 0000000..e4702da
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_hdmi.c
@@ -0,0 +1,217 @@
+/*
+ * 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
+ * Rafał Miłecki
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "evergreend.h"
+#include "atom.h"
+
+/*
+ * update the N and CTS parameters for a given pixel clock rate
+ */
+static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->offset;
+
+ WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz));
+ WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz);
+
+ WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr.cts_44_1khz));
+ WREG32(HDMI_ACR_44_1 + offset, acr.n_44_1khz);
+
+ WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz));
+ WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz);
+}
+
+/*
+ * calculate the crc for a given info frame
+ */
+static void evergreen_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 evergreen_hdmi_videoinfoframe(
+ struct drm_encoder *encoder,
+ uint8_t 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;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->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);
+
+ evergreen_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(AFMT_AVI_INFO0 + offset,
+ frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
+ WREG32(AFMT_AVI_INFO1 + offset,
+ frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
+ WREG32(AFMT_AVI_INFO2 + offset,
+ frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
+ WREG32(AFMT_AVI_INFO3 + offset,
+ frame[0xC] | (frame[0xD] << 8));
+}
+
+/*
+ * update the info frames with the data from the current display mode
+ */
+void evergreen_hdmi_setmode(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_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
+
+ /* Silent, r600_hdmi_enable will raise WARN for us */
+ if (!dig->afmt->enabled)
+ return;
+ offset = dig->afmt->offset;
+
+ r600_audio_set_clock(encoder, mode->clock);
+
+ WREG32(HDMI_VBI_PACKET_CONTROL + offset,
+ HDMI_NULL_SEND); /* send null packets when required */
+
+ WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000);
+
+ WREG32(HDMI_AUDIO_PACKET_CONTROL + offset,
+ HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
+ HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
+
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
+ AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */
+ AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+
+ WREG32(HDMI_ACR_PACKET_CONTROL + offset,
+ HDMI_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */
+ HDMI_ACR_SOURCE); /* select SW CTS value */
+
+ WREG32(HDMI_VBI_PACKET_CONTROL + offset,
+ HDMI_NULL_SEND | /* send null packets when required */
+ HDMI_GC_SEND | /* send general control packets */
+ HDMI_GC_CONT); /* send general control packets every frame */
+
+ WREG32(HDMI_INFOFRAME_CONTROL0 + offset,
+ HDMI_AVI_INFO_SEND | /* enable AVI info frames */
+ HDMI_AVI_INFO_CONT | /* send AVI info frames every frame/field */
+ HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
+ HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
+
+ WREG32(AFMT_INFOFRAME_CONTROL0 + offset,
+ AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
+
+ WREG32(HDMI_INFOFRAME_CONTROL1 + offset,
+ HDMI_AVI_INFO_LINE(2) | /* anything other than 0 */
+ HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
+
+ WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */
+
+ evergreen_hdmi_videoinfoframe(encoder, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0);
+
+ evergreen_hdmi_update_ACR(encoder, mode->clock);
+
+ /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
+ WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF);
+ WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
+ WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001);
+ WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001);
+}
diff --git a/sys/dev/drm2/radeon/evergreen_reg.h b/sys/dev/drm2/radeon/evergreen_reg.h
new file mode 100644
index 0000000..7603168
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_reg.h
@@ -0,0 +1,241 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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_BLANK_CONTROL 0x6e74
+# define EVERGREEN_CRTC_BLANK_DATA_EN (1 << 8)
+#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
+
+#endif
diff --git a/sys/dev/drm2/radeon/evergreen_reg_safe.h b/sys/dev/drm2/radeon/evergreen_reg_safe.h
new file mode 100644
index 0000000..9d56fe7
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreen_reg_safe.h
@@ -0,0 +1,517 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned evergreen_reg_safe_bm[2047] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFF0F7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0xCFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFDDEFFF, 0xCF3FFFFF, 0xFFFFF40F,
+ 0xFEFFFFDF, 0xFFFFFFFF, 0xFFFFFFEF, 0xEFFFFFFF,
+ 0xFFFFF800, 0xFFFFFFFF, 0xFFFFFFFF, 0xBFFFFF07,
+ 0xFFFBF0FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFDF, 0xFFFFFFFF, 0xFFFF7FFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFDE, 0xFFFFFFFF,
+ 0xFFDF0FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xC0000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFC3E4, 0xFFFFFFFF, 0x0000FFFF, 0x00000000,
+ 0x000CC000, 0x00000000, 0xFFD00000, 0x00000000,
+ 0x00000E00, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xC0000000, 0xFFFFF8FF, 0xFE07FF00,
+ 0x3CF1B003, 0xE39E7BCF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xF7020000, 0xDDD89CDD, 0x201FA3FD, 0xFFFFFFF0,
+ 0xBFFF0002, 0xEFC3DF87, 0x7BF0F7E1, 0x1EFC3DF8,
+ 0xDFBF0F7E, 0xFFFFF7EF, 0xFFFFFFFF, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xCFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8,
+};
diff --git a/sys/dev/drm2/radeon/evergreend.h b/sys/dev/drm2/radeon/evergreend.h
new file mode 100644
index 0000000..3fd74ce
--- /dev/null
+++ b/sys/dev/drm2/radeon/evergreend.h
@@ -0,0 +1,2046 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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
+
+#define CYPRESS_GB_ADDR_CONFIG_GOLDEN 0x02011003
+#define BARTS_GB_ADDR_CONFIG_GOLDEN 0x02011003
+#define CAYMAN_GB_ADDR_CONFIG_GOLDEN 0x02011003
+#define JUNIPER_GB_ADDR_CONFIG_GOLDEN 0x02010002
+#define REDWOOD_GB_ADDR_CONFIG_GOLDEN 0x02010002
+#define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002
+#define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001
+#define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001
+#define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002
+#define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002
+
+/* 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 NUM_PIPES_MASK 0x0000000f
+#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 BIF_FB_EN 0x5490
+#define FB_READ_EN (1 << 0)
+#define FB_WRITE_EN (1 << 1)
+
+#define CP_STRMOUT_CNTL 0x84FC
+
+#define CP_COHER_CNTL 0x85F0
+#define CP_COHER_SIZE 0x85F4
+#define CP_COHER_BASE 0x85F8
+#define CP_STALLED_STAT1 0x8674
+#define CP_STALLED_STAT2 0x8678
+#define CP_BUSY_STAT 0x867C
+#define CP_STAT 0x8680
+#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
+
+/* Audio clocks */
+#define DCCG_AUDIO_DTO_SOURCE 0x05ac
+# define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */
+# define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */
+
+#define DCCG_AUDIO_DTO0_PHASE 0x05b0
+#define DCCG_AUDIO_DTO0_MODULE 0x05b4
+#define DCCG_AUDIO_DTO0_LOAD 0x05b8
+#define DCCG_AUDIO_DTO0_CNTL 0x05bc
+
+#define DCCG_AUDIO_DTO1_PHASE 0x05c0
+#define DCCG_AUDIO_DTO1_MODULE 0x05c4
+#define DCCG_AUDIO_DTO1_LOAD 0x05c8
+#define DCCG_AUDIO_DTO1_CNTL 0x05cc
+
+/* DCE 4.0 AFMT */
+#define HDMI_CONTROL 0x7030
+# define HDMI_KEEPOUT_MODE (1 << 0)
+# define HDMI_PACKET_GEN_VERSION (1 << 4) /* 0 = r6xx compat */
+# define HDMI_ERROR_ACK (1 << 8)
+# define HDMI_ERROR_MASK (1 << 9)
+# define HDMI_DEEP_COLOR_ENABLE (1 << 24)
+# define HDMI_DEEP_COLOR_DEPTH (((x) & 3) << 28)
+# define HDMI_24BIT_DEEP_COLOR 0
+# define HDMI_30BIT_DEEP_COLOR 1
+# define HDMI_36BIT_DEEP_COLOR 2
+#define HDMI_STATUS 0x7034
+# define HDMI_ACTIVE_AVMUTE (1 << 0)
+# define HDMI_AUDIO_PACKET_ERROR (1 << 16)
+# define HDMI_VBI_PACKET_ERROR (1 << 20)
+#define HDMI_AUDIO_PACKET_CONTROL 0x7038
+# define HDMI_AUDIO_DELAY_EN(x) (((x) & 3) << 4)
+# define HDMI_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16)
+#define HDMI_ACR_PACKET_CONTROL 0x703c
+# define HDMI_ACR_SEND (1 << 0)
+# define HDMI_ACR_CONT (1 << 1)
+# define HDMI_ACR_SELECT(x) (((x) & 3) << 4)
+# define HDMI_ACR_HW 0
+# define HDMI_ACR_32 1
+# define HDMI_ACR_44 2
+# define HDMI_ACR_48 3
+# define HDMI_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */
+# define HDMI_ACR_AUTO_SEND (1 << 12)
+# define HDMI_ACR_N_MULTIPLE(x) (((x) & 7) << 16)
+# define HDMI_ACR_X1 1
+# define HDMI_ACR_X2 2
+# define HDMI_ACR_X4 4
+# define HDMI_ACR_AUDIO_PRIORITY (1 << 31)
+#define HDMI_VBI_PACKET_CONTROL 0x7040
+# define HDMI_NULL_SEND (1 << 0)
+# define HDMI_GC_SEND (1 << 4)
+# define HDMI_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */
+#define HDMI_INFOFRAME_CONTROL0 0x7044
+# define HDMI_AVI_INFO_SEND (1 << 0)
+# define HDMI_AVI_INFO_CONT (1 << 1)
+# define HDMI_AUDIO_INFO_SEND (1 << 4)
+# define HDMI_AUDIO_INFO_CONT (1 << 5)
+# define HDMI_MPEG_INFO_SEND (1 << 8)
+# define HDMI_MPEG_INFO_CONT (1 << 9)
+#define HDMI_INFOFRAME_CONTROL1 0x7048
+# define HDMI_AVI_INFO_LINE(x) (((x) & 0x3f) << 0)
+# define HDMI_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8)
+# define HDMI_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16)
+#define HDMI_GENERIC_PACKET_CONTROL 0x704c
+# define HDMI_GENERIC0_SEND (1 << 0)
+# define HDMI_GENERIC0_CONT (1 << 1)
+# define HDMI_GENERIC1_SEND (1 << 4)
+# define HDMI_GENERIC1_CONT (1 << 5)
+# define HDMI_GENERIC0_LINE(x) (((x) & 0x3f) << 16)
+# define HDMI_GENERIC1_LINE(x) (((x) & 0x3f) << 24)
+#define HDMI_GC 0x7058
+# define HDMI_GC_AVMUTE (1 << 0)
+# define HDMI_GC_AVMUTE_CONT (1 << 2)
+#define AFMT_AUDIO_PACKET_CONTROL2 0x705c
+# define AFMT_AUDIO_LAYOUT_OVRD (1 << 0)
+# define AFMT_AUDIO_LAYOUT_SELECT (1 << 1)
+# define AFMT_60958_CS_SOURCE (1 << 4)
+# define AFMT_AUDIO_CHANNEL_ENABLE(x) (((x) & 0xff) << 8)
+# define AFMT_DP_AUDIO_STREAM_ID(x) (((x) & 0xff) << 16)
+#define AFMT_AVI_INFO0 0x7084
+# define AFMT_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_AVI_INFO_S(x) (((x) & 3) << 8)
+# define AFMT_AVI_INFO_B(x) (((x) & 3) << 10)
+# define AFMT_AVI_INFO_A(x) (((x) & 1) << 12)
+# define AFMT_AVI_INFO_Y(x) (((x) & 3) << 13)
+# define AFMT_AVI_INFO_Y_RGB 0
+# define AFMT_AVI_INFO_Y_YCBCR422 1
+# define AFMT_AVI_INFO_Y_YCBCR444 2
+# define AFMT_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8)
+# define AFMT_AVI_INFO_R(x) (((x) & 0xf) << 16)
+# define AFMT_AVI_INFO_M(x) (((x) & 0x3) << 20)
+# define AFMT_AVI_INFO_C(x) (((x) & 0x3) << 22)
+# define AFMT_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16)
+# define AFMT_AVI_INFO_SC(x) (((x) & 0x3) << 24)
+# define AFMT_AVI_INFO_Q(x) (((x) & 0x3) << 26)
+# define AFMT_AVI_INFO_EC(x) (((x) & 0x3) << 28)
+# define AFMT_AVI_INFO_ITC(x) (((x) & 0x1) << 31)
+# define AFMT_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24)
+#define AFMT_AVI_INFO1 0x7088
+# define AFMT_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */
+# define AFMT_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */
+# define AFMT_AVI_INFO_CN(x) (((x) & 0x3) << 12)
+# define AFMT_AVI_INFO_YQ(x) (((x) & 0x3) << 14)
+# define AFMT_AVI_INFO_TOP(x) (((x) & 0xffff) << 16)
+#define AFMT_AVI_INFO2 0x708c
+# define AFMT_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0)
+# define AFMT_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16)
+#define AFMT_AVI_INFO3 0x7090
+# define AFMT_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0)
+# define AFMT_AVI_INFO_VERSION(x) (((x) & 3) << 24)
+#define AFMT_MPEG_INFO0 0x7094
+# define AFMT_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_MPEG_INFO_MB0(x) (((x) & 0xff) << 8)
+# define AFMT_MPEG_INFO_MB1(x) (((x) & 0xff) << 16)
+# define AFMT_MPEG_INFO_MB2(x) (((x) & 0xff) << 24)
+#define AFMT_MPEG_INFO1 0x7098
+# define AFMT_MPEG_INFO_MB3(x) (((x) & 0xff) << 0)
+# define AFMT_MPEG_INFO_MF(x) (((x) & 3) << 8)
+# define AFMT_MPEG_INFO_FR(x) (((x) & 1) << 12)
+#define AFMT_GENERIC0_HDR 0x709c
+#define AFMT_GENERIC0_0 0x70a0
+#define AFMT_GENERIC0_1 0x70a4
+#define AFMT_GENERIC0_2 0x70a8
+#define AFMT_GENERIC0_3 0x70ac
+#define AFMT_GENERIC0_4 0x70b0
+#define AFMT_GENERIC0_5 0x70b4
+#define AFMT_GENERIC0_6 0x70b8
+#define AFMT_GENERIC1_HDR 0x70bc
+#define AFMT_GENERIC1_0 0x70c0
+#define AFMT_GENERIC1_1 0x70c4
+#define AFMT_GENERIC1_2 0x70c8
+#define AFMT_GENERIC1_3 0x70cc
+#define AFMT_GENERIC1_4 0x70d0
+#define AFMT_GENERIC1_5 0x70d4
+#define AFMT_GENERIC1_6 0x70d8
+#define HDMI_ACR_32_0 0x70dc
+# define HDMI_ACR_CTS_32(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_32_1 0x70e0
+# define HDMI_ACR_N_32(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_44_0 0x70e4
+# define HDMI_ACR_CTS_44(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_44_1 0x70e8
+# define HDMI_ACR_N_44(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_48_0 0x70ec
+# define HDMI_ACR_CTS_48(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_48_1 0x70f0
+# define HDMI_ACR_N_48(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_STATUS_0 0x70f4
+#define HDMI_ACR_STATUS_1 0x70f8
+#define AFMT_AUDIO_INFO0 0x70fc
+# define AFMT_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_AUDIO_INFO_CC(x) (((x) & 7) << 8)
+# define AFMT_AUDIO_INFO_CT(x) (((x) & 0xf) << 11)
+# define AFMT_AUDIO_INFO_CHECKSUM_OFFSET(x) (((x) & 0xff) << 16)
+# define AFMT_AUDIO_INFO_CXT(x) (((x) & 0x1f) << 24)
+#define AFMT_AUDIO_INFO1 0x7100
+# define AFMT_AUDIO_INFO_CA(x) (((x) & 0xff) << 0)
+# define AFMT_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11)
+# define AFMT_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15)
+# define AFMT_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8)
+# define AFMT_AUDIO_INFO_LFEBPL(x) (((x) & 3) << 16)
+#define AFMT_60958_0 0x7104
+# define AFMT_60958_CS_A(x) (((x) & 1) << 0)
+# define AFMT_60958_CS_B(x) (((x) & 1) << 1)
+# define AFMT_60958_CS_C(x) (((x) & 1) << 2)
+# define AFMT_60958_CS_D(x) (((x) & 3) << 3)
+# define AFMT_60958_CS_MODE(x) (((x) & 3) << 6)
+# define AFMT_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8)
+# define AFMT_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16)
+# define AFMT_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20)
+# define AFMT_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24)
+# define AFMT_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28)
+#define AFMT_60958_1 0x7108
+# define AFMT_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0)
+# define AFMT_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4)
+# define AFMT_60958_CS_VALID_L(x) (((x) & 1) << 16)
+# define AFMT_60958_CS_VALID_R(x) (((x) & 1) << 18)
+# define AFMT_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20)
+#define AFMT_AUDIO_CRC_CONTROL 0x710c
+# define AFMT_AUDIO_CRC_EN (1 << 0)
+#define AFMT_RAMP_CONTROL0 0x7110
+# define AFMT_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0)
+# define AFMT_RAMP_DATA_SIGN (1 << 31)
+#define AFMT_RAMP_CONTROL1 0x7114
+# define AFMT_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0)
+# define AFMT_AUDIO_TEST_CH_DISABLE(x) (((x) & 0xff) << 24)
+#define AFMT_RAMP_CONTROL2 0x7118
+# define AFMT_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0)
+#define AFMT_RAMP_CONTROL3 0x711c
+# define AFMT_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0)
+#define AFMT_60958_2 0x7120
+# define AFMT_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0)
+# define AFMT_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4)
+# define AFMT_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8)
+# define AFMT_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12)
+# define AFMT_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16)
+# define AFMT_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20)
+#define AFMT_STATUS 0x7128
+# define AFMT_AUDIO_ENABLE (1 << 4)
+# define AFMT_AUDIO_HBR_ENABLE (1 << 8)
+# define AFMT_AZ_FORMAT_WTRIG (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30)
+#define AFMT_AUDIO_PACKET_CONTROL 0x712c
+# define AFMT_AUDIO_SAMPLE_SEND (1 << 0)
+# define AFMT_RESET_FIFO_WHEN_AUDIO_DIS (1 << 11) /* set to 1 */
+# define AFMT_AUDIO_TEST_EN (1 << 12)
+# define AFMT_AUDIO_CHANNEL_SWAP (1 << 24)
+# define AFMT_60958_CS_UPDATE (1 << 26)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27)
+# define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30)
+#define AFMT_VBI_PACKET_CONTROL 0x7130
+# define AFMT_GENERIC0_UPDATE (1 << 2)
+#define AFMT_INFOFRAME_CONTROL0 0x7134
+# define AFMT_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - afmt regs */
+# define AFMT_AUDIO_INFO_UPDATE (1 << 7)
+# define AFMT_MPEG_INFO_UPDATE (1 << 10)
+#define AFMT_GENERIC0_7 0x7138
+
+/* DCE4/5 ELD audio interface */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0 0x5f84 /* LPCM */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1 0x5f88 /* AC3 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2 0x5f8c /* MPEG1 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3 0x5f90 /* MP3 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4 0x5f94 /* MPEG2 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5 0x5f98 /* AAC */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6 0x5f9c /* DTS */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7 0x5fa0 /* ATRAC */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR8 0x5fa4 /* one bit audio - leave at 0 (default) */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9 0x5fa8 /* Dolby Digital */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10 0x5fac /* DTS-HD */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11 0x5fb0 /* MAT-MLP */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR12 0x5fb4 /* DTS */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13 0x5fb8 /* WMA Pro */
+# define MAX_CHANNELS(x) (((x) & 0x7) << 0)
+/* max channels minus one. 7 = 8 channels */
+# define SUPPORTED_FREQUENCIES(x) (((x) & 0xff) << 8)
+# define DESCRIPTOR_BYTE_2(x) (((x) & 0xff) << 16)
+# define SUPPORTED_FREQUENCIES_STEREO(x) (((x) & 0xff) << 24) /* LPCM only */
+/* SUPPORTED_FREQUENCIES, SUPPORTED_FREQUENCIES_STEREO
+ * bit0 = 32 kHz
+ * bit1 = 44.1 kHz
+ * bit2 = 48 kHz
+ * bit3 = 88.2 kHz
+ * bit4 = 96 kHz
+ * bit5 = 176.4 kHz
+ * bit6 = 192 kHz
+ */
+
+#define AZ_HOT_PLUG_CONTROL 0x5e78
+# define AZ_FORCE_CODEC_WAKE (1 << 0)
+# define PIN0_JACK_DETECTION_ENABLE (1 << 4)
+# define PIN1_JACK_DETECTION_ENABLE (1 << 5)
+# define PIN2_JACK_DETECTION_ENABLE (1 << 6)
+# define PIN3_JACK_DETECTION_ENABLE (1 << 7)
+# define PIN0_UNSOLICITED_RESPONSE_ENABLE (1 << 8)
+# define PIN1_UNSOLICITED_RESPONSE_ENABLE (1 << 9)
+# define PIN2_UNSOLICITED_RESPONSE_ENABLE (1 << 10)
+# define PIN3_UNSOLICITED_RESPONSE_ENABLE (1 << 11)
+# define CODEC_HOT_PLUG_ENABLE (1 << 12)
+# define PIN0_AUDIO_ENABLED (1 << 24)
+# define PIN1_AUDIO_ENABLED (1 << 25)
+# define PIN2_AUDIO_ENABLED (1 << 26)
+# define PIN3_AUDIO_ENABLED (1 << 27)
+# define AUDIO_ENABLED (1 << 31)
+
+
+#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_SHARED_BLACKOUT_CNTL 0x20ac
+#define BLACKOUT_MODE_MASK 0x00000007
+
+#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_CONTEXT1_CNTL2 0x1434
+#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 VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
+#define VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
+
+#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_DMA (1 << 20)
+#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)
+
+/* ASYNC DMA */
+#define DMA_RB_RPTR 0xd008
+#define DMA_RB_WPTR 0xd00c
+
+#define DMA_CNTL 0xd02c
+# define TRAP_ENABLE (1 << 0)
+# define SEM_INCOMPLETE_INT_ENABLE (1 << 1)
+# define SEM_WAIT_INT_ENABLE (1 << 2)
+# define DATA_SWAP_ENABLE (1 << 3)
+# define FENCE_SWAP_ENABLE (1 << 4)
+# define CTXEMPTY_INT_ENABLE (1 << 28)
+#define DMA_TILING_CONFIG 0xD0B8
+
+#define CAYMAN_DMA1_CNTL 0xd82c
+
+/* async DMA packets */
+#define DMA_PACKET(cmd, t, s, n) ((((cmd) & 0xF) << 28) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((n) & 0xFFFFF) << 0))
+/* async DMA Packet types */
+#define DMA_PACKET_WRITE 0x2
+#define DMA_PACKET_COPY 0x3
+#define DMA_PACKET_INDIRECT_BUFFER 0x4
+#define DMA_PACKET_SEMAPHORE 0x5
+#define DMA_PACKET_FENCE 0x6
+#define DMA_PACKET_TRAP 0x7
+#define DMA_PACKET_SRBM_WRITE 0x9
+#define DMA_PACKET_CONSTANT_FILL 0xd
+#define DMA_PACKET_NOP 0xf
+
+/* 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_CP_DMA 0x41
+/* 1. header
+ * 2. SRC_ADDR_LO or DATA [31:0]
+ * 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] |
+ * SRC_ADDR_HI [7:0]
+ * 4. DST_ADDR_LO [31:0]
+ * 5. DST_ADDR_HI [7:0]
+ * 6. COMMAND [29:22] | BYTE_COUNT [20:0]
+ */
+# define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20)
+ /* 0 - SRC_ADDR
+ * 1 - GDS
+ */
+# define PACKET3_CP_DMA_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR
+ * 1 - GDS
+ * 2 - DATA
+ */
+# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
+/* COMMAND */
+# define PACKET3_CP_DMA_DIS_WC (1 << 21)
+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
+# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
+#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 V_028044_STENCIL_INVALID 0
+#define V_028044_STENCIL_8 1
+#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
+
+/* DMA regs common on r6xx/r7xx/evergreen/ni */
+#define DMA_RB_CNTL 0xd000
+# define DMA_RB_ENABLE (1 << 0)
+# define DMA_RB_SIZE(x) ((x) << 1) /* log2 */
+# define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_ENABLE (1 << 12)
+# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
+#define DMA_STATUS_REG 0xd034
+# define DMA_IDLE (1 << 0)
+
+#endif
diff --git a/sys/dev/drm2/radeon/ni.c b/sys/dev/drm2/radeon/ni.c
new file mode 100644
index 0000000..7995684
--- /dev/null
+++ b/sys/dev/drm2/radeon/ni.c
@@ -0,0 +1,1980 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "nid.h"
+#include "atom.h"
+#include "ni_reg.h"
+#include "cayman_blit_shaders.h"
+
+extern void evergreen_pcie_gen2_enable(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
+
+#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;
+ DRM_UDELAY(1);
+ }
+
+ if (running)
+ WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+ }
+
+ return 0;
+}
+
+int ni_init_microcode(struct radeon_device *rdev)
+{
+ 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");
+
+ 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: panic("%s: Unsupported family %d", __func__, rdev->family);
+ }
+
+ DRM_INFO("Loading %s Microcode\n", chip_name);
+ err = 0;
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
+ rdev->pfp_fw = firmware_get(fw_name);
+ if (rdev->pfp_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->pfp_fw->datasize != pfp_req_size) {
+ DRM_ERROR(
+ "ni_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->pfp_fw->datasize, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
+ rdev->me_fw = firmware_get(fw_name);
+ if (rdev->me_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->me_fw->datasize != me_req_size) {
+ DRM_ERROR(
+ "ni_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", rlc_chip_name);
+ rdev->rlc_fw = firmware_get(fw_name);
+ if (rdev->rlc_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->rlc_fw->datasize != rlc_req_size) {
+ DRM_ERROR(
+ "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->rlc_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ /* no MC ucode on TN */
+ if (!(rdev->flags & RADEON_IS_IGP)) {
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
+ rdev->mc_fw = firmware_get(fw_name);
+ if (rdev->mc_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->mc_fw->datasize != mc_req_size) {
+ DRM_ERROR(
+ "ni_mc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->mc_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+ }
+out:
+ if (err) {
+ if (err != -EINVAL)
+ DRM_ERROR(
+ "ni_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+ if (rdev->mc_fw != NULL) {
+ firmware_put(rdev->mc_fw, FIRMWARE_UNLOAD);
+ rdev->mc_fw = NULL;
+ }
+ }
+ return err;
+}
+
+/**
+ * ni_fini_microcode - drop the firmwares image references
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Drop the pfp, me, mc and rlc firmwares image references.
+ * Called at driver shutdown.
+ */
+void ni_fini_microcode(struct radeon_device *rdev)
+{
+
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+
+ if (rdev->mc_fw != NULL) {
+ firmware_put(rdev->mc_fw, FIRMWARE_UNLOAD);
+ rdev->mc_fw = NULL;
+ }
+}
+
+
+/*
+ * Core functions
+ */
+static void cayman_gpu_init(struct radeon_device *rdev)
+{
+ u32 gb_addr_config = 0;
+ u32 mc_shared_chmap, mc_arb_ramcfg;
+ u32 cgts_tcc_disable;
+ u32 sx_debug_1;
+ u32 smx_dc_ctl0;
+ u32 cgts_sm_ctrl_reg;
+ u32 hdp_host_path_cntl;
+ u32 tmp;
+ u32 disabled_rb_mask;
+ 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;
+ gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
+ 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->ddev->pci_device == 0x9900) ||
+ (rdev->ddev->pci_device == 0x9901) ||
+ (rdev->ddev->pci_device == 0x9905) ||
+ (rdev->ddev->pci_device == 0x9906) ||
+ (rdev->ddev->pci_device == 0x9907) ||
+ (rdev->ddev->pci_device == 0x9908) ||
+ (rdev->ddev->pci_device == 0x9909) ||
+ (rdev->ddev->pci_device == 0x9910) ||
+ (rdev->ddev->pci_device == 0x9917)) {
+ rdev->config.cayman.max_simds_per_se = 6;
+ rdev->config.cayman.max_backends_per_se = 2;
+ } else if ((rdev->ddev->pci_device == 0x9903) ||
+ (rdev->ddev->pci_device == 0x9904) ||
+ (rdev->ddev->pci_device == 0x990A) ||
+ (rdev->ddev->pci_device == 0x9913) ||
+ (rdev->ddev->pci_device == 0x9918)) {
+ rdev->config.cayman.max_simds_per_se = 4;
+ rdev->config.cayman.max_backends_per_se = 2;
+ } else if ((rdev->ddev->pci_device == 0x9919) ||
+ (rdev->ddev->pci_device == 0x9990) ||
+ (rdev->ddev->pci_device == 0x9991) ||
+ (rdev->ddev->pci_device == 0x9994) ||
+ (rdev->ddev->pci_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;
+ gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
+ 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);
+
+ 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;
+
+ 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;
+
+
+ /* 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 {
+ switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+ case 0: /* four banks */
+ rdev->config.cayman.tile_config |= 0 << 4;
+ break;
+ case 1: /* eight banks */
+ rdev->config.cayman.tile_config |= 1 << 4;
+ break;
+ case 2: /* sixteen banks */
+ default:
+ rdev->config.cayman.tile_config |= 2 << 4;
+ break;
+ }
+ }
+ 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;
+
+ tmp = 0;
+ for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
+ u32 rb_disable_bitmap;
+
+ WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
+ WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
+ rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
+ tmp <<= 4;
+ tmp |= rb_disable_bitmap;
+ }
+ /* enabled rb are just the one not disabled :) */
+ disabled_rb_mask = tmp;
+
+ WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
+ WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
+
+ WREG32(GB_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
+ WREG32(HDP_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
+ WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
+
+ tmp = gb_addr_config & NUM_PIPES_MASK;
+ tmp = r6xx_remap_render_backend(rdev, tmp,
+ rdev->config.cayman.max_backends_per_se *
+ rdev->config.cayman.max_shader_engines,
+ CAYMAN_MAX_BACKENDS, disabled_rb_mask);
+ WREG32(GB_BACKEND_MAP, tmp);
+
+ cgts_tcc_disable = 0xffff0000;
+ for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
+ cgts_tcc_disable &= ~(1 << (16 + i));
+ WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
+ WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
+ 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));
+
+ DRM_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);
+}
+
+static 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 */
+ /* Assign the pt base to something valid for now; the pts used for
+ * the VMs are determined by the application and setup and assigned
+ * on the fly in the vm part of radeon_gart.c
+ */
+ 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), rdev->vm_manager.max_pfn);
+ 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, 4);
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
+ RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+ PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
+ VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
+ READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ READ_PROTECTION_FAULT_ENABLE_DEFAULT |
+ WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ WRITE_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;
+}
+
+static 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);
+}
+
+static 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->ring];
+
+ /* set to DX10/11 mode */
+ radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
+ radeon_ring_write(ring, 1);
+
+ if (ring->rptr_save_reg) {
+ uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
+ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+ radeon_ring_write(ring, ((ring->rptr_save_reg -
+ PACKET3_SET_CONFIG_REG_START) >> 2));
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ 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 ? (ib->vm->id << 24) : 0));
+
+ /* 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 ? ib->vm->id : 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 */
+}
+
+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);
+ rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
+ }
+}
+
+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)
+{
+ struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ cayman_cp_enable(rdev, false);
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+}
+
+static int cayman_cp_resume(struct radeon_device *rdev)
+{
+ static const int ridx[] = {
+ RADEON_RING_TYPE_GFX_INDEX,
+ CAYMAN_RING_TYPE_CP1_INDEX,
+ CAYMAN_RING_TYPE_CP2_INDEX
+ };
+ static const unsigned cp_rb_cntl[] = {
+ CP_RB0_CNTL,
+ CP_RB1_CNTL,
+ CP_RB2_CNTL,
+ };
+ static const unsigned cp_rb_rptr_addr[] = {
+ CP_RB0_RPTR_ADDR,
+ CP_RB1_RPTR_ADDR,
+ CP_RB2_RPTR_ADDR
+ };
+ static const unsigned cp_rb_rptr_addr_hi[] = {
+ CP_RB0_RPTR_ADDR_HI,
+ CP_RB1_RPTR_ADDR_HI,
+ CP_RB2_RPTR_ADDR_HI
+ };
+ static const unsigned cp_rb_base[] = {
+ CP_RB0_BASE,
+ CP_RB1_BASE,
+ CP_RB2_BASE
+ };
+ struct radeon_ring *ring;
+ int i, 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);
+ DRM_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));
+
+ /* set the wb address whether it's enabled or not */
+ WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
+ WREG32(SCRATCH_UMSK, 0xff);
+
+ for (i = 0; i < 3; ++i) {
+ uint32_t rb_cntl;
+ uint64_t addr;
+
+ /* Set ring buffer size */
+ ring = &rdev->ring[ridx[i]];
+ rb_cntl = drm_order(ring->ring_size / 8);
+ rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
+#ifdef __BIG_ENDIAN
+ rb_cntl |= BUF_SWAP_32BIT;
+#endif
+ WREG32(cp_rb_cntl[i], rb_cntl);
+
+ /* set the wb address whether it's enabled or not */
+ addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
+ WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
+ WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
+ }
+
+ /* set the rb base addr, this causes an internal reset of ALL rings */
+ for (i = 0; i < 3; ++i) {
+ ring = &rdev->ring[ridx[i]];
+ WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
+ }
+
+ for (i = 0; i < 3; ++i) {
+ /* Initialize the ring buffer's read and write pointers */
+ ring = &rdev->ring[ridx[i]];
+ WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
+
+ ring->rptr = ring->wptr = 0;
+ WREG32(ring->rptr_reg, ring->rptr);
+ WREG32(ring->wptr_reg, ring->wptr);
+
+ DRM_MDELAY(1);
+ WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
+ }
+
+ /* 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;
+}
+
+/*
+ * DMA
+ * Starting with R600, the GPU has an asynchronous
+ * DMA engine. The programming model is very similar
+ * to the 3D engine (ring buffer, IBs, etc.), but the
+ * DMA controller has it's own packet format that is
+ * different form the PM4 format used by the 3D engine.
+ * It supports copying data, writing embedded data,
+ * solid fills, and a number of other things. It also
+ * has support for tiling/detiling of buffers.
+ * Cayman and newer support two asynchronous DMA engines.
+ */
+/**
+ * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ *
+ * Schedule an IB in the DMA ring (cayman-SI).
+ */
+void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
+ struct radeon_ib *ib)
+{
+ struct radeon_ring *ring = &rdev->ring[ib->ring];
+
+ if (rdev->wb.enabled) {
+ u32 next_rptr = ring->wptr + 4;
+ while ((next_rptr & 7) != 5)
+ next_rptr++;
+ next_rptr += 3;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
+ * Pad as necessary with NOPs.
+ */
+ while ((ring->wptr & 7) != 5)
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
+ radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
+ radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
+
+}
+
+/**
+ * cayman_dma_stop - stop the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the async dma engines (cayman-SI).
+ */
+void cayman_dma_stop(struct radeon_device *rdev)
+{
+ u32 rb_cntl;
+
+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
+
+ /* dma0 */
+ rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
+ rb_cntl &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl);
+
+ /* dma1 */
+ rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
+ rb_cntl &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl);
+
+ rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
+ rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
+}
+
+/**
+ * cayman_dma_resume - setup and start the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the DMA ring buffers and enable them. (cayman-SI).
+ * Returns 0 for success, error for failure.
+ */
+int cayman_dma_resume(struct radeon_device *rdev)
+{
+ struct radeon_ring *ring;
+ u32 rb_cntl, dma_cntl, ib_cntl;
+ u32 rb_bufsz;
+ u32 reg_offset, wb_offset;
+ int i, r;
+
+ /* Reset dma */
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ reg_offset = DMA0_REGISTER_OFFSET;
+ wb_offset = R600_WB_DMA_RPTR_OFFSET;
+ } else {
+ ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+ reg_offset = DMA1_REGISTER_OFFSET;
+ wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
+ }
+
+ WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
+ WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
+
+ /* Set ring buffer size in dwords */
+ rb_bufsz = drm_order(ring->ring_size / 4);
+ rb_cntl = rb_bufsz << 1;
+#ifdef __BIG_ENDIAN
+ rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
+#endif
+ WREG32(DMA_RB_CNTL + reg_offset, rb_cntl);
+
+ /* Initialize the ring buffer's read and write pointers */
+ WREG32(DMA_RB_RPTR + reg_offset, 0);
+ WREG32(DMA_RB_WPTR + reg_offset, 0);
+
+ /* set the wb address whether it's enabled or not */
+ WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset,
+ upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF);
+ WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset,
+ ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
+
+ if (rdev->wb.enabled)
+ rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
+
+ WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
+
+ /* enable DMA IBs */
+ ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
+#ifdef __BIG_ENDIAN
+ ib_cntl |= DMA_IB_SWAP_ENABLE;
+#endif
+ WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
+
+ dma_cntl = RREG32(DMA_CNTL + reg_offset);
+ dma_cntl &= ~CTXEMPTY_INT_ENABLE;
+ WREG32(DMA_CNTL + reg_offset, dma_cntl);
+
+ ring->wptr = 0;
+ WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
+
+ ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
+
+ WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
+
+ ring->ready = true;
+
+ r = radeon_ring_test(rdev, ring->idx, ring);
+ if (r) {
+ ring->ready = false;
+ return r;
+ }
+ }
+
+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
+
+ return 0;
+}
+
+/**
+ * cayman_dma_fini - tear down the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the async dma engines and free the rings (cayman-SI).
+ */
+void cayman_dma_fini(struct radeon_device *rdev)
+{
+ cayman_dma_stop(rdev);
+ radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
+ radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
+}
+
+static void cayman_gpu_soft_reset_gfx(struct radeon_device *rdev)
+{
+ u32 grbm_reset = 0;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ return;
+
+ 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, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+
+ /* 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);
+ DRM_UDELAY(50);
+ WREG32(GRBM_SOFT_RESET, 0);
+ (void)RREG32(GRBM_SOFT_RESET);
+
+ 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, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+
+}
+
+static void cayman_gpu_soft_reset_dma(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ return;
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+
+ /* dma0 */
+ tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
+
+ /* dma1 */
+ tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
+
+ /* Reset dma */
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+
+}
+
+static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
+{
+ struct evergreen_mc_save save;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE);
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ reset_mask &= ~RADEON_RESET_DMA;
+
+ if (reset_mask == 0)
+ return 0;
+
+ dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+
+ 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");
+ }
+
+ if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE))
+ cayman_gpu_soft_reset_gfx(rdev);
+
+ if (reset_mask & RADEON_RESET_DMA)
+ cayman_gpu_soft_reset_dma(rdev);
+
+ /* Wait a little for things to settle down */
+ DRM_UDELAY(50);
+
+ evergreen_mc_resume(rdev, &save);
+ return 0;
+}
+
+int cayman_asic_reset(struct radeon_device *rdev)
+{
+ return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
+ RADEON_RESET_COMPUTE |
+ RADEON_RESET_DMA));
+}
+
+/**
+ * cayman_dma_is_lockup - Check if the DMA engine is locked up
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Check if the async DMA engine is locked up (cayman-SI).
+ * Returns true if the engine appears to be locked up, false if not.
+ */
+bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ u32 dma_status_reg;
+
+ if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+ dma_status_reg = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
+ else
+ dma_status_reg = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
+ if (dma_status_reg & DMA_IDLE) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force ring activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+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;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
+ return r;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA 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;
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+ DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
+ DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ if (r)
+ return r;
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
+ DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
+ DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ if (r)
+ return r;
+
+ r = cayman_cp_load_microcode(rdev);
+ if (r)
+ return r;
+ r = cayman_cp_resume(rdev);
+ if (r)
+ return r;
+
+ r = cayman_dma_resume(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = radeon_vm_manager_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = r600_audio_init(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)
+{
+ r600_audio_fini(rdev);
+ cayman_cp_enable(rdev, false);
+ cayman_dma_stop(rdev);
+ 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;
+
+ /* 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);
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 64 * 1024);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 64 * 1024);
+
+ rdev->ih.ring_obj = NULL;
+ r600_ih_ring_init(rdev, 64 * 1024);
+
+ r = r600_pcie_gart_init(rdev);
+ if (r)
+ return r;
+
+ rdev->accel_working = true;
+ r = cayman_startup(rdev);
+ if (r) {
+ dev_err(rdev->dev, "disabling GPU acceleration\n");
+ cayman_cp_fini(rdev);
+ cayman_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ if (rdev->flags & RADEON_IS_IGP)
+ si_rlc_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_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);
+ cayman_dma_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);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ cayman_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
+ radeon_gem_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_bo_fini(rdev);
+ radeon_atombios_fini(rdev);
+ ni_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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)
+{
+}
+
+#define R600_ENTRY_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, uint32_t flags)
+{
+ uint32_t r600_flags = 0;
+ r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_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;
+}
+
+/**
+ * cayman_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (cayman-si).
+ */
+void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ uint64_t value;
+ unsigned ndw;
+
+ if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+ while (count) {
+ ndw = 1 + count * 2;
+ if (ndw > 0x3FFF)
+ ndw = 0x3FFF;
+
+ radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+ for (; ndw > 1; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
+ }
+ } else {
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ /* for non-physically contiguous pages (system) */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+ for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
+ }
+ }
+}
+
+/**
+ * cayman_vm_flush - vm flush using the CP
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Update the page table base and flush the VM TLB
+ * using the CP (cayman-si).
+ */
+void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+ struct radeon_ring *ring = &rdev->ring[ridx];
+
+ if (vm == NULL)
+ return;
+
+ radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+ /* flush hdp cache */
+ radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
+ radeon_ring_write(ring, 0x1);
+
+ /* bits 0-7 are the VM contexts0-7 */
+ radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
+ radeon_ring_write(ring, 1 << vm->id);
+
+ /* sync PFP to ME, otherwise we might get invalid PFP reads */
+ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+ radeon_ring_write(ring, 0x0);
+}
+
+void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+ struct radeon_ring *ring = &rdev->ring[ridx];
+
+ if (vm == NULL)
+ return;
+
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+ /* flush hdp cache */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
+ radeon_ring_write(ring, 1);
+
+ /* bits 0-7 are the VM contexts0-7 */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
+ radeon_ring_write(ring, 1 << vm->id);
+}
+
diff --git a/sys/dev/drm2/radeon/ni_reg.h b/sys/dev/drm2/radeon/ni_reg.h
new file mode 100644
index 0000000..f72c01c
--- /dev/null
+++ b/sys/dev/drm2/radeon/ni_reg.h
@@ -0,0 +1,89 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/nid.h b/sys/dev/drm2/radeon/nid.h
new file mode 100644
index 0000000..afe7a32
--- /dev/null
+++ b/sys/dev/drm2/radeon/nid.h
@@ -0,0 +1,680 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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 CAYMAN_GB_ADDR_CONFIG_GOLDEN 0x02011003
+#define ARUBA_GB_ADDR_CONFIG_GOLDEN 0x12010001
+
+#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 SRBM_SOFT_RESET 0x0E60
+#define SOFT_RESET_BIF (1 << 1)
+#define SOFT_RESET_CG (1 << 2)
+#define SOFT_RESET_DC (1 << 5)
+#define SOFT_RESET_DMA1 (1 << 6)
+#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_DMA (1 << 20)
+#define SOFT_RESET_TST (1 << 21)
+#define SOFT_RESET_REGBB (1 << 22)
+#define SOFT_RESET_ORB (1 << 23)
+
+#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_INTERRUPT (1 << 3)
+#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
+#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 6)
+#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 7)
+#define PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 9)
+#define PDE0_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 10)
+#define VALID_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 12)
+#define VALID_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 13)
+#define READ_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 15)
+#define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16)
+#define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18)
+#define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19)
+#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 RLC_GFX_INDEX 0x3FC4
+
+#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 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 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_STALLED_STAT1 0x8674
+#define CP_STALLED_STAT2 0x8678
+#define CP_BUSY_STAT 0x867C
+#define CP_STAT 0x8680
+#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_PFP_SYNC_ME 0x42
+#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
+#define PACKET3_ME_WRITE 0x7A
+
+/* ASYNC DMA - first instance at 0xd000, second at 0xd800 */
+#define DMA0_REGISTER_OFFSET 0x0 /* not a register */
+#define DMA1_REGISTER_OFFSET 0x800 /* not a register */
+
+#define DMA_RB_CNTL 0xd000
+# define DMA_RB_ENABLE (1 << 0)
+# define DMA_RB_SIZE(x) ((x) << 1) /* log2 */
+# define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_ENABLE (1 << 12)
+# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
+#define DMA_RB_BASE 0xd004
+#define DMA_RB_RPTR 0xd008
+#define DMA_RB_WPTR 0xd00c
+
+#define DMA_RB_RPTR_ADDR_HI 0xd01c
+#define DMA_RB_RPTR_ADDR_LO 0xd020
+
+#define DMA_IB_CNTL 0xd024
+# define DMA_IB_ENABLE (1 << 0)
+# define DMA_IB_SWAP_ENABLE (1 << 4)
+# define CMD_VMID_FORCE (1 << 31)
+#define DMA_IB_RPTR 0xd028
+#define DMA_CNTL 0xd02c
+# define TRAP_ENABLE (1 << 0)
+# define SEM_INCOMPLETE_INT_ENABLE (1 << 1)
+# define SEM_WAIT_INT_ENABLE (1 << 2)
+# define DATA_SWAP_ENABLE (1 << 3)
+# define FENCE_SWAP_ENABLE (1 << 4)
+# define CTXEMPTY_INT_ENABLE (1 << 28)
+#define DMA_STATUS_REG 0xd034
+# define DMA_IDLE (1 << 0)
+#define DMA_SEM_INCOMPLETE_TIMER_CNTL 0xd044
+#define DMA_SEM_WAIT_FAIL_TIMER_CNTL 0xd048
+#define DMA_TILING_CONFIG 0xd0b8
+#define DMA_MODE 0xd0bc
+
+#define DMA_PACKET(cmd, t, s, n) ((((cmd) & 0xF) << 28) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((n) & 0xFFFFF) << 0))
+
+#define DMA_IB_PACKET(cmd, vmid, n) ((((cmd) & 0xF) << 28) | \
+ (((vmid) & 0xF) << 20) | \
+ (((n) & 0xFFFFF) << 0))
+
+/* async DMA Packet types */
+#define DMA_PACKET_WRITE 0x2
+#define DMA_PACKET_COPY 0x3
+#define DMA_PACKET_INDIRECT_BUFFER 0x4
+#define DMA_PACKET_SEMAPHORE 0x5
+#define DMA_PACKET_FENCE 0x6
+#define DMA_PACKET_TRAP 0x7
+#define DMA_PACKET_SRBM_WRITE 0x9
+#define DMA_PACKET_CONSTANT_FILL 0xd
+#define DMA_PACKET_NOP 0xf
+
+#endif
diff --git a/sys/dev/drm2/radeon/r100.c b/sys/dev/drm2/radeon/r100.c
new file mode 100644
index 0000000..595f922
--- /dev/null
+++ b/sys/dev/drm2/radeon/r100.c
@@ -0,0 +1,4201 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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 "r100_reg_safe.h"
+#include "rn50_reg_safe.h"
+
+/* Firmware Names */
+#define FIRMWARE_R100 "radeonkmsfw_R100_cp"
+#define FIRMWARE_R200 "radeonkmsfw_R200_cp"
+#define FIRMWARE_R300 "radeonkmsfw_R300_cp"
+#define FIRMWARE_R420 "radeonkmsfw_R420_cp"
+#define FIRMWARE_RS690 "radeonkmsfw_RS690_cp"
+#define FIRMWARE_RS600 "radeonkmsfw_RS600_cp"
+#define FIRMWARE_R520 "radeonkmsfw_R520_cp"
+
+#include "r100_track.h"
+
+/* This files gather functions specifics to:
+ * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
+ * and others in some cases.
+ */
+
+/**
+ * r100_wait_for_vblank - vblank wait asic callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to wait for vblank on
+ *
+ * Wait for vblank on the requested crtc (r1xx-r4xx).
+ */
+void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+ int i;
+
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (crtc == 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;
+ DRM_UDELAY(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)
+ break;
+ DRM_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;
+ DRM_UDELAY(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)
+ break;
+ DRM_UDELAY(1);
+ }
+ }
+ }
+}
+
+/**
+ * r100_pre_page_flip - pre-pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to prepare for pageflip on
+ *
+ * Pre-pageflip callback (r1xx-r4xx).
+ * Enables the pageflip irq (vblank irq).
+ */
+void r100_pre_page_flip(struct radeon_device *rdev, int crtc)
+{
+ /* enable the pflip int */
+ radeon_irq_kms_pflip_irq_get(rdev, crtc);
+}
+
+/**
+ * r100_post_page_flip - pos-pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc: crtc to cleanup pageflip on
+ *
+ * Post-pageflip callback (r1xx-r4xx).
+ * Disables the pageflip irq (vblank irq).
+ */
+void r100_post_page_flip(struct radeon_device *rdev, int crtc)
+{
+ /* disable the pflip int */
+ radeon_irq_kms_pflip_irq_put(rdev, crtc);
+}
+
+/**
+ * r100_page_flip - pageflip callback.
+ *
+ * @rdev: radeon_device pointer
+ * @crtc_id: crtc to cleanup pageflip on
+ * @crtc_base: new address of the crtc (GPU MC address)
+ *
+ * Does the actual pageflip (r1xx-r4xx).
+ * During vblank we take the crtc lock and wait for the update_pending
+ * bit to go high, when it does, we release the lock, and allow the
+ * double buffered update to take place.
+ * Returns the current update pending status.
+ */
+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;
+ DRM_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;
+}
+
+/**
+ * r100_pm_get_dynpm_state - look up dynpm power state callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Look up the optimal power state based on the
+ * current state of the GPU (r1xx-r5xx).
+ * Used for dynpm only.
+ */
+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);
+}
+
+/**
+ * r100_pm_init_profile - Initialize power profiles callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the power states used in profile mode
+ * (r1xx-r3xx).
+ * Used for profile mode only.
+ */
+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;
+}
+
+/**
+ * r100_pm_misc - set additional pm hw parameters callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set non-clock parameters associated with a power state
+ * (voltage, pcie lanes, etc.) (r1xx-r4xx).
+ */
+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)
+ DRM_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)
+ DRM_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);
+ }
+}
+
+/**
+ * r100_pm_prepare - pre-power state change callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Prepare for a power state change (r1xx-r4xx).
+ */
+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);
+ }
+ }
+ }
+}
+
+/**
+ * r100_pm_finish - post-power state change callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Clean up after a power state change (r1xx-r4xx).
+ */
+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);
+ }
+ }
+ }
+}
+
+/**
+ * r100_gui_idle - gui idle callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check of the GUI (2D/3D engines) are idle (r1xx-r5xx).
+ * Returns true if idle, false if not.
+ */
+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 */
+/**
+ * r100_hpd_sense - hpd sense callback.
+ *
+ * @rdev: radeon_device pointer
+ * @hpd: hpd (hotplug detect) pin
+ *
+ * Checks if a digital monitor is connected (r1xx-r4xx).
+ * Returns true if connected, false if not connected.
+ */
+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;
+}
+
+/**
+ * r100_hpd_set_polarity - hpd set polarity callback.
+ *
+ * @rdev: radeon_device pointer
+ * @hpd: hpd (hotplug detect) pin
+ *
+ * Set the polarity of the hpd pin (r1xx-r4xx).
+ */
+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;
+ }
+}
+
+/**
+ * r100_hpd_init - hpd setup callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Setup the hpd pins used by the card (r1xx-r4xx).
+ * Set the polarity, and enable the hpd interrupts.
+ */
+void r100_hpd_init(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned enable = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ enable |= 1 << radeon_connector->hpd.hpd;
+ radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+ }
+ radeon_irq_kms_enable_hpd(rdev, enable);
+}
+
+/**
+ * r100_hpd_fini - hpd tear down callback.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the hpd pins used by the card (r1xx-r4xx).
+ * Disable the hpd interrupts.
+ */
+void r100_hpd_fini(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ disable |= 1 << radeon_connector->hpd.hpd;
+ }
+ radeon_irq_kms_disable_hpd(rdev, disable);
+}
+
+/*
+ * 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) {
+ DRM_ERROR("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);
+}
+
+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("PCI 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) {
+ DRM_ERROR("Can't enable IRQ/MSI because no handler is installed\n");
+ WREG32(R_000040_GEN_INT_CNTL, 0);
+ return -EINVAL;
+ }
+ if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
+ tmp |= RADEON_SW_INT_ENABLE;
+ }
+ if (rdev->irq.crtc_vblank_int[0] ||
+ atomic_read(&rdev->irq.pflip[0])) {
+ tmp |= RADEON_CRTC_VBLANK_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[1] ||
+ atomic_read(&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 */
+ DRM_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;
+
+ if (irqs) {
+ WREG32(RADEON_GEN_INT_STATUS, irqs);
+ }
+ return irqs & irq_mask;
+}
+
+irqreturn_t r100_irq_process(struct radeon_device *rdev)
+{
+ uint32_t status, msi_rearm;
+ bool queue_hotplug = 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);
+ }
+ /* 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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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);
+ }
+ if (queue_hotplug)
+ taskqueue_enqueue(rdev->tq, &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 */
+ panic("%s: Unused on older asics", __func__);
+}
+
+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_TYPE_GFX_INDEX);
+ }
+ 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;
+ }
+ DRM_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)
+{
+ const char *fw_name = NULL;
+ int err;
+
+ DRM_DEBUG_KMS("\n");
+
+ 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 = 0;
+ rdev->me_fw = firmware_get(fw_name);
+ if (rdev->me_fw == NULL) {
+ DRM_ERROR("radeon_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ err = -ENOENT;
+ } else if (rdev->me_fw->datasize % 8) {
+ DRM_ERROR(
+ "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+ return err;
+}
+
+/**
+ * r100_cp_fini_microcode - drop the firmware image reference
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Drop the me firmware image reference.
+ * Called at driver shutdown.
+ */
+static void r100_cp_fini_microcode (struct radeon_device *rdev)
+{
+
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+}
+
+static void r100_cp_load_microcode(struct radeon_device *rdev)
+{
+ const __be32 *fw_data;
+ int i, size;
+
+ if (r100_gui_wait_for_idle(rdev)) {
+ DRM_ERROR("Failed to wait GUI idle while "
+ "programming pipes. Bad things might happen.\n");
+ }
+
+ if (rdev->me_fw) {
+ size = rdev->me_fw->datasize / 4;
+ fw_data = (const __be32 *)rdev->me_fw->data;
+ 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);
+ DRM_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);
+
+ /* at this point everything should be setup correctly to enable master */
+ pci_enable_busmaster(rdev->dev);
+
+ 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);
+
+ if (!ring->rptr_save_reg /* not resuming from suspend */
+ && radeon_ring_supports_scratch_reg(rdev, ring)) {
+ r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
+ if (r) {
+ DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
+ ring->rptr_save_reg = 0;
+ }
+ }
+ 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_scratch_free(rdev, rdev->ring[RADEON_RING_TYPE_GFX_INDEX].rptr_save_reg);
+ 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)) {
+ DRM_ERROR("Failed to wait GUI idle while "
+ "programming pipes. Bad things might happen.\n");
+ }
+}
+
+/*
+ * CS functions
+ */
+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;
+}
+
+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:
+ DRM_ERROR("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 = malloc(sizeof(*track), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (!track)
+ return -ENOMEM;
+ r100_cs_track_clear(p->rdev, track);
+ p->track = track;
+ do {
+ r = r100_cs_packet_parse(p, &pkt, p->idx);
+ if (r) {
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ 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);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return -EINVAL;
+ }
+ if (r) {
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return r;
+ }
+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return 0;
+}
+
+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;
+ }
+ }
+}
+
+/*
+ * Global GPU functions
+ */
+static 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;
+ }
+}
+
+static 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)) {
+ DRM_ERROR("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;
+}
+
+bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ u32 rbbm_status;
+
+ rbbm_status = RREG32(R_000E40_RBBM_STATUS);
+ if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force CP activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+/* 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);
+}
+
+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);
+ DRM_MDELAY(1);
+ WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042);
+ DRM_MDELAY(1);
+ WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
+ tmp = RREG32(RADEON_BUS_CNTL);
+ DRM_MDELAY(1);
+ pci_disable_busmaster(rdev->dev);
+ DRM_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->dev);
+ /* 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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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->dev);
+ 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");
+ 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->pci_device) {
+ /* RN50 */
+ case 0x515e:
+ case 0x5969:
+ force_dac2 = true;
+ break;
+ /* RV100*/
+ case 0x5159:
+ case 0x515a:
+ /* DELL triple head servers */
+ if ((dev->pci_subvendor == 0x1028 /* DELL */) &&
+ ((dev->pci_subdevice == 0x016c) ||
+ (dev->pci_subdevice == 0x016d) ||
+ (dev->pci_subdevice == 0x016e) ||
+ (dev->pci_subdevice == 0x016f) ||
+ (dev->pci_subdevice == 0x0170) ||
+ (dev->pci_subdevice == 0x017d) ||
+ (dev->pci_subdevice == 0x017e) ||
+ (dev->pci_subdevice == 0x0183) ||
+ (dev->pci_subdevice == 0x018a) ||
+ (dev->pci_subdevice == 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
+ */
+ byte = pci_read_config(rdev->dev, 0xe, 1);
+ 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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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);
+}
+
+static 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) {
+ DRM_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);
+}
+
+static 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 = DRM_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 = DRM_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));
+ }
+}
+
+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];
+
+ if (ring->rptr_save_reg) {
+ u32 next_rptr = ring->wptr + 2 + 3;
+ radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0));
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ 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, NULL, 256);
+ if (r) {
+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+ goto free_scratch;
+ }
+ 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, NULL);
+ if (r) {
+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+ goto free_ib;
+ }
+ r = radeon_fence_wait(ib.fence, false);
+ if (r) {
+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+ goto free_ib;
+ }
+ 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;
+ }
+free_ib:
+ radeon_ib_free(rdev, &ib);
+free_scratch:
+ radeon_scratch_free(rdev, scratch);
+ return r;
+}
+
+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);
+}
+
+static 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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ r100_cp_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_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,
+ bool always_indirect)
+{
+ if (reg < rdev->rmmio_size && !always_indirect)
+ return bus_read_4(rdev->rmmio, reg);
+ else {
+ unsigned long flags;
+ uint32_t ret;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->mmio_idx_lock, flags);
+ bus_write_4(rdev->rmmio, RADEON_MM_INDEX, reg);
+ ret = bus_read_4(rdev->rmmio, RADEON_MM_DATA);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->mmio_idx_lock, flags);
+
+ return ret;
+ }
+}
+
+void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
+ bool always_indirect)
+{
+ if (reg < rdev->rmmio_size && !always_indirect)
+ bus_write_4(rdev->rmmio, reg, v);
+ else {
+ unsigned long flags;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->mmio_idx_lock, flags);
+ bus_write_4(rdev->rmmio, RADEON_MM_INDEX, reg);
+ bus_write_4(rdev->rmmio, RADEON_MM_DATA, v);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->mmio_idx_lock, flags);
+ }
+}
+
+u32 r100_io_rreg(struct radeon_device *rdev, u32 reg)
+{
+ if (reg < rdev->rio_mem_size)
+ return bus_read_4(rdev->rio_mem, reg);
+ else {
+ /* XXX No locking? -- dumbbell@ */
+ bus_write_4(rdev->rio_mem, RADEON_MM_INDEX, reg);
+ return bus_read_4(rdev->rio_mem, RADEON_MM_DATA);
+ }
+}
+
+void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+ if (reg < rdev->rio_mem_size)
+ bus_write_4(rdev->rio_mem, reg, v);
+ else {
+ /* XXX No locking? -- dumbbell@ */
+ bus_write_4(rdev->rio_mem, RADEON_MM_INDEX, reg);
+ bus_write_4(rdev->rio_mem, RADEON_MM_DATA, v);
+ }
+}
diff --git a/sys/dev/drm2/radeon/r100_reg_safe.h b/sys/dev/drm2/radeon/r100_reg_safe.h
new file mode 100644
index 0000000..23049ad
--- /dev/null
+++ b/sys/dev/drm2/radeon/r100_reg_safe.h
@@ -0,0 +1,31 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned r100_reg_safe_bm[102] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFCF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFF9F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x38E7FE1F, 0xFFC3FF8E, 0x7FF8FFFF, 0xFFFF803C,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFEFFFF, 0xFFFFFFFF,
+ 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFCFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFEF,
+};
diff --git a/sys/dev/drm2/radeon/r100_track.h b/sys/dev/drm2/radeon/r100_track.h
new file mode 100644
index 0000000..c4c5d8e
--- /dev/null
+++ b/sys/dev/drm2/radeon/r100_track.h
@@ -0,0 +1,103 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/r100d.h b/sys/dev/drm2/radeon/r100d.h
new file mode 100644
index 0000000..96418ca
--- /dev/null
+++ b/sys/dev/drm2/radeon/r100d.h
@@ -0,0 +1,883 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/r200.c b/sys/dev/drm2/radeon/r200.c
new file mode 100644
index 0000000..fe8b768
--- /dev/null
+++ b/sys/dev/drm2/radeon/r200.c
@@ -0,0 +1,552 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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_TYPE_GFX_INDEX);
+ }
+ 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:
+ DRM_ERROR("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 = DRM_ARRAY_SIZE(r200_reg_safe_bm);
+}
diff --git a/sys/dev/drm2/radeon/r200_reg_safe.h b/sys/dev/drm2/radeon/r200_reg_safe.h
new file mode 100644
index 0000000..3ef5980
--- /dev/null
+++ b/sys/dev/drm2/radeon/r200_reg_safe.h
@@ -0,0 +1,31 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned r200_reg_safe_bm[102] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFE7FE1F, 0xF003FFFF, 0x7EFFFFFF, 0xFFFF803C,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFEFCE, 0xFFFEFFFF, 0xFFFFFFFE,
+ 0x020E0FF0, 0xFFCC83FD, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFBFFFF, 0xEFFCFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xDFDFDFDF, 0x3FFDDFDF, 0xFFFFFFFF, 0xFFFFFF7F,
+ 0xFFFFFFFF, 0x00FFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFE3F, 0xFFFFFFEF,
+};
diff --git a/sys/dev/drm2/radeon/r300.c b/sys/dev/drm2/radeon/r300.c
new file mode 100644
index 0000000..b8fdefc
--- /dev/null
+++ b/sys/dev/drm2/radeon/r300.c
@@ -0,0 +1,1566 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include <dev/drm2/radeon/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)
+{
+ volatile uint32_t *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 */
+ ptr += i;
+ *ptr = (uint32_t)addr;
+ return 0;
+}
+
+int rv370_pcie_gart_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->gart.robj) {
+ DRM_ERROR("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);
+}
+
+static 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;
+}
+
+static void r300_gpu_init(struct radeon_device *rdev)
+{
+ uint32_t gb_tile_config, tmp;
+
+ if ((rdev->family == CHIP_R300 && rdev->ddev->pci_device != 0x4144) ||
+ (rdev->family == CHIP_R350 && rdev->ddev->pci_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)) {
+ DRM_ERROR("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)) {
+ DRM_ERROR("Failed to wait GUI idle while "
+ "programming pipes. Bad things might happen.\n");
+ }
+ if (r300_mc_wait_for_idle(rdev)) {
+ DRM_ERROR("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);
+}
+
+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->dev);
+ /* 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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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->dev);
+ 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");
+ 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:
+ DRM_ERROR("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 = malloc(sizeof(*track), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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) {
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ 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);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return -EINVAL;
+ }
+ if (r) {
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return r;
+ }
+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ 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 = DRM_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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_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/sys/dev/drm2/radeon/r300_cmdbuf.c b/sys/dev/drm2/radeon/r300_cmdbuf.c
new file mode 100644
index 0000000..4f41b13
--- /dev/null
+++ b/sys/dev/drm2/radeon/r300_cmdbuf.c
@@ -0,0 +1,1185 @@
+/* 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 <prefect_@gmx.net>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_buffer.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_drv.h"
+#include "r300_reg.h"
+
+#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->masterp->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->masterp, 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/sys/dev/drm2/radeon/r300_reg.h b/sys/dev/drm2/radeon/r300_reg.h
new file mode 100644
index 0000000..3478d00
--- /dev/null
+++ b/sys/dev/drm2/radeon/r300_reg.h
@@ -0,0 +1,1792 @@
+/*
+ * 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_
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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)<<R300_TX_FORMAT_B_SHIFT) \
+ | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \
+ | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \
+ | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \
+ | (R300_TX_FORMAT_##FMT) \
+ )
+ /* These can be ORed with result of R300_EASY_TX_FORMAT()
+ We don't really know what they do. Take values from a
+ constant color ? */
+# define R300_TX_FORMAT_CONST_X (1<<5)
+# define R300_TX_FORMAT_CONST_Y (2<<5)
+# define R300_TX_FORMAT_CONST_Z (4<<5)
+# define R300_TX_FORMAT_CONST_W (8<<5)
+
+# define R300_TX_FORMAT_YUV_MODE 0x00800000
+
+#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */
+#define R300_TX_OFFSET_0 0x4540
+ /* BEGIN: Guess from R200 */
+# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
+# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
+# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
+# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
+# define R300_TXO_MACRO_TILE (1 << 2)
+# define R300_TXO_MICRO_TILE (1 << 3)
+# define R300_TXO_MICRO_TILE_SQUARE (2 << 3)
+# define R300_TXO_OFFSET_MASK 0xffffffe0
+# define R300_TXO_OFFSET_SHIFT 5
+ /* END: Guess from R200 */
+
+/* 32 bit chroma key */
+#define R300_TX_CHROMA_KEY_0 0x4580
+/* ff00ff00 == { 0, 1.0, 0, 1.0 } */
+#define R300_TX_BORDER_COLOR_0 0x45C0
+
+/* END: Texture specification */
+
+/* BEGIN: Fragment program instruction set */
+
+/* Fragment programs are written directly into register space.
+ * There are separate instruction streams for texture instructions and ALU
+ * instructions.
+ * In order to synchronize these streams, the program is divided into up
+ * to 4 nodes. Each node begins with a number of TEX operations, followed
+ * by a number of ALU operations.
+ * The first node can have zero TEX ops, all subsequent nodes must have at
+ * least
+ * one TEX ops.
+ * All nodes must have at least one ALU op.
+ *
+ * The index of the last node is stored in PFS_CNTL_0: A value of 0 means
+ * 1 node, a value of 3 means 4 nodes.
+ * The total amount of instructions is defined in PFS_CNTL_2. The offsets are
+ * offsets into the respective instruction streams, while *_END points to the
+ * last instruction relative to this offset.
+ */
+#define R300_PFS_CNTL_0 0x4600
+# define R300_PFS_CNTL_LAST_NODES_SHIFT 0
+# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0)
+# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3)
+#define R300_PFS_CNTL_1 0x4604
+/* There is an unshifted value here which has so far always been equal to the
+ * index of the highest used temporary register.
+ */
+#define R300_PFS_CNTL_2 0x4608
+# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0
+# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0)
+# define R300_PFS_CNTL_ALU_END_SHIFT 6
+# define R300_PFS_CNTL_ALU_END_MASK (63 << 6)
+# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
+# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
+# define R300_PFS_CNTL_TEX_END_SHIFT 18
+# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
+
+/* gap */
+
+/* Nodes are stored backwards. The last active node is always stored in
+ * PFS_NODE_3.
+ * Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
+ * first node is stored in NODE_2, the second node is stored in NODE_3.
+ *
+ * Offsets are relative to the master offset from PFS_CNTL_2.
+ */
+#define R300_PFS_NODE_0 0x4610
+#define R300_PFS_NODE_1 0x4614
+#define R300_PFS_NODE_2 0x4618
+#define R300_PFS_NODE_3 0x461C
+# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0
+# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0)
+# define R300_PFS_NODE_ALU_END_SHIFT 6
+# define R300_PFS_NODE_ALU_END_MASK (63 << 6)
+# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12
+# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
+# define R300_PFS_NODE_TEX_END_SHIFT 17
+# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
+# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
+# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
+
+/* TEX
+ * As far as I can tell, texture instructions cannot write into output
+ * registers directly. A subsequent ALU instruction is always necessary,
+ * even if it's just MAD o0, r0, 1, 0
+ */
+#define R300_PFS_TEXI_0 0x4620
+# define R300_FPITX_SRC_SHIFT 0
+# define R300_FPITX_SRC_MASK (31 << 0)
+ /* GUESS */
+# define R300_FPITX_SRC_CONST (1 << 5)
+# define R300_FPITX_DST_SHIFT 6
+# define R300_FPITX_DST_MASK (31 << 6)
+# define R300_FPITX_IMAGE_SHIFT 11
+ /* GUESS based on layout and native limits */
+# define R300_FPITX_IMAGE_MASK (15 << 11)
+/* Unsure if these are opcodes, or some kind of bitfield, but this is how
+ * they were set when I checked
+ */
+# define R300_FPITX_OPCODE_SHIFT 15
+# define R300_FPITX_OP_TEX 1
+# define R300_FPITX_OP_KIL 2
+# define R300_FPITX_OP_TXP 3
+# define R300_FPITX_OP_TXB 4
+# define R300_FPITX_OPCODE_MASK (7 << 15)
+
+/* ALU
+ * The ALU instructions register blocks are enumerated according to the order
+ * in which fglrx. I assume there is space for 64 instructions, since
+ * each block has space for a maximum of 64 DWORDs, and this matches reported
+ * native limits.
+ *
+ * The basic functional block seems to be one MAD for each color and alpha,
+ * and an adder that adds all components after the MUL.
+ * - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
+ * - DP4: Use OUTC_DP4, OUTA_DP4
+ * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
+ * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
+ * - CMPH: If ARG2 > 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/sys/dev/drm2/radeon/r300_reg_safe.h b/sys/dev/drm2/radeon/r300_reg_safe.h
new file mode 100644
index 0000000..0b5e1eb3b
--- /dev/null
+++ b/sys/dev/drm2/radeon/r300_reg_safe.h
@@ -0,0 +1,45 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned r300_reg_safe_bm[159] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
+ 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFC48, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE00BFF,
+ 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00000000, 0x0000C100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0003FC0B, 0xFFFFFCFF, 0xFFBFFB99,
+};
diff --git a/sys/dev/drm2/radeon/r300d.h b/sys/dev/drm2/radeon/r300d.h
new file mode 100644
index 0000000..76511a9
--- /dev/null
+++ b/sys/dev/drm2/radeon/r300d.h
@@ -0,0 +1,357 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/r420.c b/sys/dev/drm2/radeon/r420.c
new file mode 100644
index 0000000..e422f9d
--- /dev/null
+++ b/sys/dev/drm2/radeon/r420.c
@@ -0,0 +1,491 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/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 = DRM_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)) {
+ DRM_ERROR("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->ddev->pci_device == 0x5e4c) ||
+ (rdev->ddev->pci_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)) {
+ DRM_ERROR("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)) {
+ DRM_ERROR("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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ }
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_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/sys/dev/drm2/radeon/r420_reg_safe.h b/sys/dev/drm2/radeon/r420_reg_safe.h
new file mode 100644
index 0000000..c929b0b
--- /dev/null
+++ b/sys/dev/drm2/radeon/r420_reg_safe.h
@@ -0,0 +1,45 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned r420_reg_safe_bm[159] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
+ 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFC48, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE00BFF,
+ 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xFF800000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0003FC0B, 0xFFFFFCFF, 0xFFBFFB99,
+};
diff --git a/sys/dev/drm2/radeon/r420d.h b/sys/dev/drm2/radeon/r420d.h
new file mode 100644
index 0000000..78ea066
--- /dev/null
+++ b/sys/dev/drm2/radeon/r420d.h
@@ -0,0 +1,252 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/r500_reg.h b/sys/dev/drm2/radeon/r500_reg.h
new file mode 100644
index 0000000..c56088b
--- /dev/null
+++ b/sys/dev/drm2/radeon/r500_reg.h
@@ -0,0 +1,804 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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_NB_CNTL 0x0
+# define RS690_HIDE_MMCFG_BAR (1 << 3)
+# define RS690_AGPMODE30 (1 << 4)
+# define RS690_AGP30ENHANCED (1 << 5)
+#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/sys/dev/drm2/radeon/r520.c b/sys/dev/drm2/radeon/r520.c
new file mode 100644
index 0000000..523c94a
--- /dev/null
+++ b/sys/dev/drm2/radeon/r520.c
@@ -0,0 +1,330 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/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)) {
+ DRM_ERROR("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;
+}
+
+static 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);
+}
+
+static 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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_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/sys/dev/drm2/radeon/r520d.h b/sys/dev/drm2/radeon/r520d.h
new file mode 100644
index 0000000..6fbd54c
--- /dev/null
+++ b/sys/dev/drm2/radeon/r520d.h
@@ -0,0 +1,190 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/r600.c b/sys/dev/drm2/radeon/r600.c
new file mode 100644
index 0000000..b9d41bc
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600.c
@@ -0,0 +1,4384 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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
+
+#ifdef DUMBBELL_WIP
+/* 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");
+#endif /* DUMBBELL_WIP */
+
+int r600_debugfs_mc_info_init(struct radeon_device *rdev);
+
+/* r600,rv610,rv630,rv620,rv635,rv670 */
+static void r600_gpu_init(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;
+ unsigned enable = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+ connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+ /* don't try to enable hpd on eDP or LVDS avoid breaking the
+ * aux dp channel on imac and help (but not completely fix)
+ * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+ */
+ continue;
+ }
+ 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);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HPD2_CONTROL, tmp);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HPD3_CONTROL, tmp);
+ break;
+ case RADEON_HPD_4:
+ WREG32(DC_HPD4_CONTROL, tmp);
+ break;
+ /* DCE 3.2 */
+ case RADEON_HPD_5:
+ WREG32(DC_HPD5_CONTROL, tmp);
+ break;
+ case RADEON_HPD_6:
+ WREG32(DC_HPD6_CONTROL, tmp);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (radeon_connector->hpd.hpd) {
+ case RADEON_HPD_1:
+ WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
+ break;
+ default:
+ break;
+ }
+ }
+ enable |= 1 << radeon_connector->hpd.hpd;
+ radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+ }
+ radeon_irq_kms_enable_hpd(rdev, enable);
+}
+
+void r600_hpd_fini(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+ 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)) {
+ switch (radeon_connector->hpd.hpd) {
+ case RADEON_HPD_1:
+ WREG32(DC_HPD1_CONTROL, 0);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HPD2_CONTROL, 0);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HPD3_CONTROL, 0);
+ break;
+ case RADEON_HPD_4:
+ WREG32(DC_HPD4_CONTROL, 0);
+ break;
+ /* DCE 3.2 */
+ case RADEON_HPD_5:
+ WREG32(DC_HPD5_CONTROL, 0);
+ break;
+ case RADEON_HPD_6:
+ WREG32(DC_HPD6_CONTROL, 0);
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (radeon_connector->hpd.hpd) {
+ case RADEON_HPD_1:
+ WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
+ break;
+ case RADEON_HPD_2:
+ WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
+ break;
+ case RADEON_HPD_3:
+ WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ disable |= 1 << radeon_connector->hpd.hpd;
+ }
+ radeon_irq_kms_disable_hpd(rdev, disable);
+}
+
+/*
+ * 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)) {
+ volatile uint32_t *ptr = 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 = *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) {
+ DRM_ERROR("[drm] r600 flush TLB failed\n");
+ return;
+ }
+ if (tmp) {
+ return;
+ }
+ DRM_UDELAY(1);
+ }
+}
+
+int r600_pcie_gart_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->gart.robj) {
+ DRM_ERROR("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);
+}
+
+static 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;
+}
+
+static 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);
+}
+
+static void r600_pcie_gart_fini(struct radeon_device *rdev)
+{
+ radeon_gart_fini(rdev);
+ r600_pcie_gart_disable(rdev);
+ radeon_gart_table_vram_free(rdev);
+}
+
+static 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;
+ DRM_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: %juM 0x%08jX - 0x%08jX (%juM used)\n",
+ (uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start,
+ (uintmax_t)mc->vram_end, (uintmax_t)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);
+ }
+}
+
+static 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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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;
+ void *vram_scratch_ptr_ptr;
+
+ if (rdev->vram_scratch.robj == NULL) {
+ r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
+ PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+ NULL, &rdev->vram_scratch.robj);
+ if (r) {
+ return r;
+ }
+ }
+
+ r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+ if (unlikely(r != 0)) {
+ radeon_bo_unref(&rdev->vram_scratch.robj);
+ 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);
+ radeon_bo_unref(&rdev->vram_scratch.robj);
+ return r;
+ }
+ vram_scratch_ptr_ptr = &rdev->vram_scratch.ptr;
+ r = radeon_bo_kmap(rdev->vram_scratch.robj,
+ vram_scratch_ptr_ptr);
+ if (r)
+ radeon_bo_unpin(rdev->vram_scratch.robj);
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+ if (r)
+ radeon_bo_unref(&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.
+ */
+static void r600_gpu_soft_reset_gfx(struct radeon_device *rdev)
+{
+ 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;
+
+ 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));
+ dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+
+ /* 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);
+ DRM_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);
+ DRM_MDELAY(15);
+ WREG32(R_008020_GRBM_SOFT_RESET, 0);
+
+ 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));
+ dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT1));
+ dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
+ RREG32(CP_STALLED_STAT2));
+ dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
+ RREG32(CP_BUSY_STAT));
+ dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
+ RREG32(CP_STAT));
+
+}
+
+static void r600_gpu_soft_reset_dma(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ return;
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+
+ /* Disable DMA */
+ tmp = RREG32(DMA_RB_CNTL);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL, tmp);
+
+ /* Reset dma */
+ if (rdev->family >= CHIP_RV770)
+ WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA);
+ else
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+}
+
+static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
+{
+ struct rv515_mc_save save;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE);
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ reset_mask &= ~RADEON_RESET_DMA;
+
+ if (reset_mask == 0)
+ return 0;
+
+ dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+
+ rv515_mc_stop(rdev, &save);
+ if (r600_mc_wait_for_idle(rdev)) {
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+ }
+
+ if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE))
+ r600_gpu_soft_reset_gfx(rdev);
+
+ if (reset_mask & RADEON_RESET_DMA)
+ r600_gpu_soft_reset_dma(rdev);
+
+ /* Wait a little for things to settle down */
+ DRM_MDELAY(1);
+
+ 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;
+
+ 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)) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force CP activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+/**
+ * r600_dma_is_lockup - Check if the DMA engine is locked up
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Check if the async DMA engine is locked up (r6xx-evergreen).
+ * Returns true if the engine appears to be locked up, false if not.
+ */
+bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ u32 dma_status_reg;
+
+ dma_status_reg = RREG32(DMA_STATUS_REG);
+ if (dma_status_reg & DMA_IDLE) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force ring activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+int r600_asic_reset(struct radeon_device *rdev)
+{
+ return r600_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
+ RADEON_RESET_COMPUTE |
+ RADEON_RESET_DMA));
+}
+
+u32 r6xx_remap_render_backend(struct radeon_device *rdev,
+ u32 tiling_pipe_num,
+ u32 max_rb_num,
+ u32 total_max_rb_num,
+ u32 disabled_rb_mask)
+{
+ u32 rendering_pipe_num, rb_num_width, req_rb_num;
+ u32 pipe_rb_ratio, pipe_rb_remain, tmp;
+ u32 data = 0, mask = 1 << (max_rb_num - 1);
+ unsigned i, j;
+
+ /* mask out the RBs that don't exist on that asic */
+ tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff);
+ /* make sure at least one RB is available */
+ if ((tmp & 0xff) != 0xff)
+ disabled_rb_mask = tmp;
+
+ rendering_pipe_num = 1 << tiling_pipe_num;
+ req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask);
+ KASSERT(rendering_pipe_num >= req_rb_num, ("rendering_pipe_num < req_rb_num"));
+
+ pipe_rb_ratio = rendering_pipe_num / req_rb_num;
+ pipe_rb_remain = rendering_pipe_num - pipe_rb_ratio * req_rb_num;
+
+ if (rdev->family <= CHIP_RV740) {
+ /* r6xx/r7xx */
+ rb_num_width = 2;
+ } else {
+ /* eg+ */
+ rb_num_width = 4;
+ }
+
+ for (i = 0; i < max_rb_num; i++) {
+ if (!(mask & disabled_rb_mask)) {
+ for (j = 0; j < pipe_rb_ratio; j++) {
+ data <<= rb_num_width;
+ data |= max_rb_num - i - 1;
+ }
+ if (pipe_rb_remain) {
+ data <<= rb_num_width;
+ data |= max_rb_num - i - 1;
+ pipe_rb_remain--;
+ }
+ }
+ mask >>= 1;
+ }
+
+ return data;
+}
+
+int r600_count_pipe_bits(uint32_t val)
+{
+ return hweight32(val);
+}
+
+static void r600_gpu_init(struct radeon_device *rdev)
+{
+ u32 tiling_config;
+ u32 ramcfg;
+ 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;
+ u32 disabled_rb_mask;
+
+ rdev->config.r600.tiling_group_size = 256;
+ 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);
+
+ 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;
+ tmp = R6XX_MAX_BACKENDS -
+ r600_count_pipe_bits((cc_rb_backend_disable >> 16) & R6XX_MAX_BACKENDS_MASK);
+ if (tmp < rdev->config.r600.max_backends) {
+ rdev->config.r600.max_backends = tmp;
+ }
+
+ cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0x00ffff00;
+ tmp = R6XX_MAX_PIPES -
+ r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R6XX_MAX_PIPES_MASK);
+ if (tmp < rdev->config.r600.max_pipes) {
+ rdev->config.r600.max_pipes = tmp;
+ }
+ tmp = R6XX_MAX_SIMDS -
+ r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK);
+ if (tmp < rdev->config.r600.max_simds) {
+ rdev->config.r600.max_simds = tmp;
+ }
+
+ disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R6XX_MAX_BACKENDS_MASK;
+ tmp = (tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT;
+ tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.r600.max_backends,
+ R6XX_MAX_BACKENDS, disabled_rb_mask);
+ tiling_config |= tmp << 16;
+ rdev->config.r600.backend_map = tmp;
+
+ rdev->config.r600.tile_config = tiling_config;
+ WREG32(GB_TILING_CONFIG, tiling_config);
+ WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
+ WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
+ WREG32(DMA_TILING_CONFIG, tiling_config & 0xffff);
+
+ 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);
+ rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
+}
+
+int r600_init_microcode(struct radeon_device *rdev)
+{
+ 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");
+
+ 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: panic("%s: Unsupported family %d", __func__, rdev->family);
+ }
+
+ 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);
+ err = 0;
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
+ rdev->pfp_fw = firmware_get(fw_name);
+ if (rdev->pfp_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->pfp_fw->datasize != pfp_req_size) {
+ DRM_ERROR(
+ "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->pfp_fw->datasize, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
+ rdev->me_fw = firmware_get(fw_name);
+ if (rdev->me_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->me_fw->datasize != me_req_size) {
+ DRM_ERROR(
+ "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", rlc_chip_name);
+ rdev->rlc_fw = firmware_get(fw_name);
+ if (rdev->rlc_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->rlc_fw->datasize != rlc_req_size) {
+ DRM_ERROR(
+ "r600_rlc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->rlc_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+out:
+ if (err) {
+ if (err != -EINVAL)
+ DRM_ERROR(
+ "r600_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+ }
+ return err;
+}
+
+/**
+ * r600_fini_microcode - drop the firmwares image references
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Drop the pfp, me and rlc firmwares image references.
+ * Called at driver shutdown.
+ */
+void r600_fini_microcode(struct radeon_device *rdev)
+{
+
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+}
+
+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);
+ DRM_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);
+ DRM_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);
+ }
+
+ DRM_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;
+ int r;
+
+ /* 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;
+
+ if (radeon_ring_supports_scratch_reg(rdev, ring)) {
+ r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
+ if (r) {
+ DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
+ ring->rptr_save_reg = 0;
+ }
+ }
+}
+
+void r600_cp_fini(struct radeon_device *rdev)
+{
+ struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ r600_cp_stop(rdev);
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+}
+
+/*
+ * DMA
+ * Starting with R600, the GPU has an asynchronous
+ * DMA engine. The programming model is very similar
+ * to the 3D engine (ring buffer, IBs, etc.), but the
+ * DMA controller has it's own packet format that is
+ * different form the PM4 format used by the 3D engine.
+ * It supports copying data, writing embedded data,
+ * solid fills, and a number of other things. It also
+ * has support for tiling/detiling of buffers.
+ */
+/**
+ * r600_dma_stop - stop the async dma engine
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the async dma engine (r6xx-evergreen).
+ */
+void r600_dma_stop(struct radeon_device *rdev)
+{
+ u32 rb_cntl = RREG32(DMA_RB_CNTL);
+
+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
+
+ rb_cntl &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL, rb_cntl);
+
+ rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
+}
+
+/**
+ * r600_dma_resume - setup and start the async dma engine
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the DMA ring buffer and enable it. (r6xx-evergreen).
+ * Returns 0 for success, error for failure.
+ */
+int r600_dma_resume(struct radeon_device *rdev)
+{
+ struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ u32 rb_cntl, dma_cntl, ib_cntl;
+ u32 rb_bufsz;
+ int r;
+
+ /* Reset dma */
+ if (rdev->family >= CHIP_RV770)
+ WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA);
+ else
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL, 0);
+ WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL, 0);
+
+ /* Set ring buffer size in dwords */
+ rb_bufsz = drm_order(ring->ring_size / 4);
+ rb_cntl = rb_bufsz << 1;
+#ifdef __BIG_ENDIAN
+ rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
+#endif
+ WREG32(DMA_RB_CNTL, rb_cntl);
+
+ /* Initialize the ring buffer's read and write pointers */
+ WREG32(DMA_RB_RPTR, 0);
+ WREG32(DMA_RB_WPTR, 0);
+
+ /* set the wb address whether it's enabled or not */
+ WREG32(DMA_RB_RPTR_ADDR_HI,
+ upper_32_bits(rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFF);
+ WREG32(DMA_RB_RPTR_ADDR_LO,
+ ((rdev->wb.gpu_addr + R600_WB_DMA_RPTR_OFFSET) & 0xFFFFFFFC));
+
+ if (rdev->wb.enabled)
+ rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
+
+ WREG32(DMA_RB_BASE, ring->gpu_addr >> 8);
+
+ /* enable DMA IBs */
+ ib_cntl = DMA_IB_ENABLE;
+#ifdef __BIG_ENDIAN
+ ib_cntl |= DMA_IB_SWAP_ENABLE;
+#endif
+ WREG32(DMA_IB_CNTL, ib_cntl);
+
+ dma_cntl = RREG32(DMA_CNTL);
+ dma_cntl &= ~CTXEMPTY_INT_ENABLE;
+ WREG32(DMA_CNTL, dma_cntl);
+
+ if (rdev->family >= CHIP_RV770)
+ WREG32(DMA_MODE, 1);
+
+ ring->wptr = 0;
+ WREG32(DMA_RB_WPTR, ring->wptr << 2);
+
+ ring->rptr = RREG32(DMA_RB_RPTR) >> 2;
+
+ WREG32(DMA_RB_CNTL, rb_cntl | DMA_RB_ENABLE);
+
+ ring->ready = true;
+
+ r = radeon_ring_test(rdev, R600_RING_TYPE_DMA_INDEX, ring);
+ if (r) {
+ ring->ready = false;
+ return r;
+ }
+
+ radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
+
+ return 0;
+}
+
+/**
+ * r600_dma_fini - tear down the async dma engine
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the async dma engine and free the ring (r6xx-evergreen).
+ */
+void r600_dma_fini(struct radeon_device *rdev)
+{
+ r600_dma_stop(rdev);
+ radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_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;
+ 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", ring->idx, 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", ring->idx, i);
+ } else {
+ DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
+ ring->idx, scratch, tmp);
+ r = -EINVAL;
+ }
+ radeon_scratch_free(rdev, scratch);
+ return r;
+}
+
+/**
+ * r600_dma_ring_test - simple async dma engine test
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Test the DMA engine by writing using it to write an
+ * value to memory. (r6xx-SI).
+ * Returns 0 for success, error for failure.
+ */
+int r600_dma_ring_test(struct radeon_device *rdev,
+ struct radeon_ring *ring)
+{
+ unsigned i;
+ int r;
+ volatile uint32_t *ptr = rdev->vram_scratch.ptr;
+ u32 tmp;
+
+ if (!ptr) {
+ DRM_ERROR("invalid vram scratch pointer\n");
+ return -EINVAL;
+ }
+
+ tmp = 0xCAFEDEAD;
+ *ptr = tmp;
+
+ r = radeon_ring_lock(rdev, ring, 4);
+ if (r) {
+ DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r);
+ return r;
+ }
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
+ radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff);
+ radeon_ring_write(ring, 0xDEADBEEF);
+ radeon_ring_unlock_commit(rdev, ring);
+
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ tmp = *ptr;
+ if (tmp == 0xDEADBEEF)
+ break;
+ DRM_UDELAY(1);
+ }
+
+ if (i < rdev->usec_timeout) {
+ DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
+ } else {
+ DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
+ ring->idx, tmp);
+ r = -EINVAL;
+ }
+ return r;
+}
+
+/*
+ * CP fences/semaphores
+ */
+
+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);
+}
+
+/*
+ * DMA fences/semaphores
+ */
+
+/**
+ * r600_dma_fence_ring_emit - emit a fence on the DMA ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Add a DMA fence packet to the ring to write
+ * the fence seq number and DMA trap packet to generate
+ * an interrupt if needed (r6xx-r7xx).
+ */
+void r600_dma_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;
+
+ /* write the fence */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0));
+ radeon_ring_write(ring, addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(addr) & 0xff));
+ radeon_ring_write(ring, lower_32_bits(fence->seq));
+ /* generate an interrupt */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0));
+}
+
+/**
+ * r600_dma_semaphore_ring_emit - emit a semaphore on the dma ring
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ * @semaphore: radeon semaphore object
+ * @emit_wait: wait or signal semaphore
+ *
+ * Add a DMA semaphore packet to the ring wait on or signal
+ * other rings (r6xx-SI).
+ */
+void r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
+ struct radeon_ring *ring,
+ struct radeon_semaphore *semaphore,
+ bool emit_wait)
+{
+ u64 addr = semaphore->gpu_addr;
+ u32 s = emit_wait ? 0 : 1;
+
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SEMAPHORE, 0, s, 0));
+ radeon_ring_write(ring, addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(addr) & 0xff);
+}
+
+int r600_copy_blit(struct radeon_device *rdev,
+ uint64_t src_offset,
+ uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence)
+{
+ struct radeon_semaphore *sem = NULL;
+ struct radeon_sa_bo *vb = NULL;
+ int r;
+
+ r = r600_blit_prepare_copy(rdev, num_gpu_pages, fence, &vb, &sem);
+ if (r) {
+ return r;
+ }
+ r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages, vb);
+ r600_blit_done_copy(rdev, fence, vb, sem);
+ return 0;
+}
+
+/**
+ * r600_copy_dma - copy pages using the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the DMA engine (r6xx).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int r600_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence)
+{
+ struct radeon_semaphore *sem = NULL;
+ int ring_index = rdev->asic->copy.dma_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ring_index];
+ u32 size_in_dw, cur_size_in_dw;
+ int i, num_loops;
+ int r = 0;
+
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ return r;
+ }
+
+ size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
+ num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE);
+ r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ radeon_semaphore_free(rdev, &sem, NULL);
+ return r;
+ }
+
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
+
+ for (i = 0; i < num_loops; i++) {
+ cur_size_in_dw = size_in_dw;
+ if (cur_size_in_dw > 0xFFFE)
+ cur_size_in_dw = 0xFFFE;
+ size_in_dw -= cur_size_in_dw;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw));
+ radeon_ring_write(ring, dst_offset & 0xfffffffc);
+ radeon_ring_write(ring, src_offset & 0xfffffffc);
+ radeon_ring_write(ring, (((upper_32_bits(dst_offset) & 0xff) << 16) |
+ (upper_32_bits(src_offset) & 0xff)));
+ src_offset += cur_size_in_dw * 4;
+ dst_offset += cur_size_in_dw * 4;
+ }
+
+ r = radeon_fence_emit(rdev, fence, ring->idx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, *fence);
+
+ return r;
+}
+
+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 */
+}
+
+static int r600_startup(struct radeon_device *rdev)
+{
+ struct radeon_ring *ring;
+ 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;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA 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);
+
+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ 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;
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+ DMA_RB_RPTR, DMA_RB_WPTR,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ if (r)
+ return r;
+
+ r = r600_cp_load_microcode(rdev);
+ if (r)
+ return r;
+ r = r600_cp_resume(rdev);
+ if (r)
+ return r;
+
+ r = r600_dma_resume(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ DRM_ERROR("radeon: audio init failed\n");
+ 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;
+ }
+
+ return r;
+}
+
+int r600_suspend(struct radeon_device *rdev)
+{
+ r600_audio_fini(rdev);
+ r600_cp_stop(rdev);
+ r600_dma_stop(rdev);
+ 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");
+ }
+ /* 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->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
+ r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
+
+ rdev->ih.ring_obj = NULL;
+ r600_ih_ring_init(rdev, 64 * 1024);
+
+ r = r600_pcie_gart_init(rdev);
+ if (r)
+ return r;
+
+ rdev->accel_working = true;
+ r = r600_startup(rdev);
+ if (r) {
+ dev_err(rdev->dev, "disabling GPU acceleration\n");
+ r600_cp_fini(rdev);
+ r600_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ r600_pcie_gart_fini(rdev);
+ rdev->accel_working = false;
+ }
+
+ return 0;
+}
+
+void r600_fini(struct radeon_device *rdev)
+{
+ r600_audio_fini(rdev);
+ r600_blit_fini(rdev);
+ r600_cp_fini(rdev);
+ r600_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_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_fence_driver_fini(rdev);
+ radeon_bo_fini(rdev);
+ radeon_atombios_fini(rdev);
+ r600_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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->ring];
+ u32 next_rptr;
+
+ if (ring->rptr_save_reg) {
+ next_rptr = ring->wptr + 3 + 4;
+ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+ radeon_ring_write(ring, ((ring->rptr_save_reg -
+ PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
+ radeon_ring_write(ring, next_rptr);
+ } else if (rdev->wb.enabled) {
+ next_rptr = ring->wptr + 5 + 4;
+ radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
+ radeon_ring_write(ring, next_rptr);
+ radeon_ring_write(ring, 0);
+ }
+
+ 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;
+
+ 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->idx, &ib, NULL, 256);
+ if (r) {
+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+ goto free_scratch;
+ }
+ 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, NULL);
+ if (r) {
+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+ goto free_ib;
+ }
+ r = radeon_fence_wait(ib.fence, false);
+ if (r) {
+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+ goto free_ib;
+ }
+ 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;
+ }
+free_ib:
+ radeon_ib_free(rdev, &ib);
+free_scratch:
+ radeon_scratch_free(rdev, scratch);
+ return r;
+}
+
+/**
+ * r600_dma_ib_test - test an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Test a simple IB in the DMA ring (r6xx-SI).
+ * Returns 0 on success, error on failure.
+ */
+int r600_dma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ struct radeon_ib ib;
+ unsigned i;
+ int r;
+ volatile uint32_t *ptr = rdev->vram_scratch.ptr;
+ u32 tmp = 0;
+
+ if (!ptr) {
+ DRM_ERROR("invalid vram scratch pointer\n");
+ return -EINVAL;
+ }
+
+ tmp = 0xCAFEDEAD;
+ *ptr = tmp;
+
+ r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
+ if (r) {
+ DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+ return r;
+ }
+
+ ib.ptr[0] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1);
+ ib.ptr[1] = rdev->vram_scratch.gpu_addr & 0xfffffffc;
+ ib.ptr[2] = upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff;
+ ib.ptr[3] = 0xDEADBEEF;
+ ib.length_dw = 4;
+
+ r = radeon_ib_schedule(rdev, &ib, NULL);
+ if (r) {
+ 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) {
+ radeon_ib_free(rdev, &ib);
+ DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+ return r;
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ tmp = *ptr;
+ 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 (0x%08X)\n", tmp);
+ r = -EINVAL;
+ }
+ radeon_ib_free(rdev, &ib);
+ return r;
+}
+
+/**
+ * r600_dma_ring_ib_execute - Schedule an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ *
+ * Schedule an IB in the DMA ring (r6xx-r7xx).
+ */
+void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+ struct radeon_ring *ring = &rdev->ring[ib->ring];
+
+ if (rdev->wb.enabled) {
+ u32 next_rptr = ring->wptr + 4;
+ while ((next_rptr & 7) != 5)
+ next_rptr++;
+ next_rptr += 3;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
+ * Pad as necessary with NOPs.
+ */
+ while ((ring->wptr & 7) != 5)
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_INDIRECT_BUFFER, 0, 0, 0));
+ radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
+ radeon_ring_write(ring, (ib->length_dw << 16) | (upper_32_bits(ib->gpu_addr) & 0xFF));
+
+}
+
+/*
+ * 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;
+ void *ring_ptr;
+
+ /* 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,
+ NULL, &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)) {
+ radeon_bo_unref(&rdev->ih.ring_obj);
+ 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);
+ radeon_bo_unref(&rdev->ih.ring_obj);
+ DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
+ return r;
+ }
+ ring_ptr = &rdev->ih.ring;
+ r = radeon_bo_kmap(rdev->ih.ring_obj,
+ ring_ptr);
+ if (r)
+ radeon_bo_unpin(rdev->ih.ring_obj);
+ radeon_bo_unreserve(rdev->ih.ring_obj);
+ if (r) {
+ DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
+ radeon_bo_unref(&rdev->ih.ring_obj);
+ 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);
+ DRM_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.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);
+ tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
+ WREG32(DMA_CNTL, tmp);
+ 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);
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp);
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp);
+ } else {
+ tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
+ tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(DCE3_HDMI1_AUDIO_PACKET_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);
+ tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
+ tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ WREG32(HDMI1_AUDIO_PACKET_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);
+
+ /* at this point everything should be setup correctly to enable master */
+ pci_enable_busmaster(rdev->dev);
+
+ /* 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 hdmi0, hdmi1;
+ u32 d1grph = 0, d2grph = 0;
+ u32 dma_cntl;
+
+ if (!rdev->irq.installed) {
+ DRM_ERROR("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;
+ }
+
+ if (ASIC_IS_DCE3(rdev)) {
+ 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;
+ hdmi0 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ hdmi1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
+ } else {
+ hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ hdmi1 = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ }
+ } else {
+ 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;
+ hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
+ }
+ dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
+
+ if (atomic_read(&rdev->irq.ring_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 (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
+ DRM_DEBUG("r600_irq_set: sw int dma\n");
+ dma_cntl |= TRAP_ENABLE;
+ }
+
+ if (rdev->irq.crtc_vblank_int[0] ||
+ atomic_read(&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] ||
+ atomic_read(&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.afmt[0]) {
+ DRM_DEBUG("r600_irq_set: hdmi 0\n");
+ hdmi0 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
+ }
+ if (rdev->irq.afmt[1]) {
+ DRM_DEBUG("r600_irq_set: hdmi 0\n");
+ hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
+ }
+
+ WREG32(CP_INT_CNTL, cp_int_cntl);
+ WREG32(DMA_CNTL, dma_cntl);
+ WREG32(DxMODE_INT_MASK, mode_int);
+ WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph);
+ WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph);
+ WREG32(GRBM_INT_CNTL, grbm_int_cntl);
+ if (ASIC_IS_DCE3(rdev)) {
+ 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);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, hdmi0);
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, hdmi1);
+ } else {
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
+ WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
+ }
+ } else {
+ WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
+ WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
+ WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
+ WREG32(HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
+ }
+
+ 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);
+ if (ASIC_IS_DCE32(rdev)) {
+ rdev->irq.stat_regs.r600.hdmi0_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET0);
+ rdev->irq.stat_regs.r600.hdmi1_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET1);
+ } else {
+ rdev->irq.stat_regs.r600.hdmi0_status = RREG32(HDMI0_STATUS);
+ rdev->irq.stat_regs.r600.hdmi1_status = RREG32(DCE3_HDMI1_STATUS);
+ }
+ } 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.hdmi0_status = RREG32(HDMI0_STATUS);
+ rdev->irq.stat_regs.r600.hdmi1_status = RREG32(HDMI1_STATUS);
+ }
+ 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 (rdev->irq.stat_regs.r600.hdmi0_status & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp);
+ }
+ if (rdev->irq.stat_regs.r600.hdmi1_status & AFMT_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1);
+ tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp);
+ }
+ } else {
+ if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
+ tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL);
+ tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
+ }
+ if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
+ if (ASIC_IS_DCE3(rdev)) {
+ tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL);
+ tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
+ WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, tmp);
+ } else {
+ tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL);
+ tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
+ WREG32(HDMI1_AUDIO_PACKET_CONTROL, tmp);
+ }
+ }
+ }
+}
+
+void r600_irq_disable(struct radeon_device *rdev)
+{
+ r600_disable_interrupts(rdev);
+ /* Wait and acknowledge irq */
+ DRM_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
+ */
+
+irqreturn_t r600_irq_process(struct radeon_device *rdev)
+{
+ u32 wptr;
+ u32 rptr;
+ u32 src_id, src_data;
+ u32 ring_index;
+ bool queue_hotplug = false;
+ bool queue_hdmi = 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);
+
+restart_ih:
+ /* is somebody else already processing irqs? */
+ if (atomic_xchg(&rdev->ih.lock, 1))
+ return IRQ_NONE;
+
+ rptr = rdev->ih.rptr;
+ DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
+ /* Order reading of wptr vs. reading of IH ring data */
+ rmb();
+
+ /* display interrupts */
+ r600_irq_ack(rdev);
+
+ 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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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 */
+ switch (src_data) {
+ case 4:
+ if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI0\n");
+ }
+ break;
+ case 5:
+ if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
+ rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
+ queue_hdmi = true;
+ DRM_DEBUG("IH: HDMI1\n");
+ }
+ break;
+ default:
+ DRM_ERROR("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");
+ radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
+ break;
+ case 224: /* DMA trap event */
+ DRM_DEBUG("IH: DMA trap\n");
+ radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
+ break;
+ case 233: /* GUI IDLE */
+ DRM_DEBUG("IH: GUI idle\n");
+ 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;
+ }
+ if (queue_hotplug)
+ taskqueue_enqueue(rdev->tq, &rdev->hotplug_work);
+ if (queue_hdmi)
+ taskqueue_enqueue(rdev->tq, &rdev->audio_work);
+ rdev->ih.rptr = rptr;
+ WREG32(IH_RB_RPTR, rdev->ih.rptr);
+ atomic_set(&rdev->ih.lock, 0);
+
+ /* make sure wptr hasn't changed while processing */
+ wptr = r600_get_ih_wptr(rdev);
+ if (wptr != rptr)
+ goto restart_ih;
+
+ 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)) {
+ volatile uint32_t *ptr = rdev->vram_scratch.ptr;
+ u32 tmp;
+
+ WREG32(HDP_DEBUG1, 0);
+ tmp = *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;
+ u32 mask;
+ int ret;
+
+ 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;
+
+ ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+ if (ret != 0)
+ return;
+
+ if (!(mask & DRM_PCIE_SPEED_50))
+ return;
+
+ speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ }
+
+ DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
+
+ /* 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);
+ }
+}
+
+/**
+ * r600_get_gpu_clock - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (R6xx-cayman).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t r600_get_gpu_clock(struct radeon_device *rdev)
+{
+ uint64_t clock;
+
+ sx_xlock(&rdev->gpu_clock_mutex);
+ WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+ clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+ ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+ sx_xunlock(&rdev->gpu_clock_mutex);
+ return clock;
+}
diff --git a/sys/dev/drm2/radeon/r600_audio.c b/sys/dev/drm2/radeon/r600_audio.c
new file mode 100644
index 0000000..bf14b60
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_audio.c
@@ -0,0 +1,258 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+/*
+ * check if enc_priv stores radeon_encoder_atom_dig
+ */
+static bool radeon_dig_encoder(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;
+ }
+ return false;
+}
+
+/*
+ * check if the chipset is supported
+ */
+static int r600_audio_chipset_supported(struct radeon_device *rdev)
+{
+ return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev))
+ || rdev->family == CHIP_RS600
+ || rdev->family == CHIP_RS690
+ || rdev->family == CHIP_RS740;
+}
+
+struct r600_audio r600_audio_status(struct radeon_device *rdev)
+{
+ struct r600_audio status;
+ uint32_t value;
+
+ value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
+
+ /* number of channels */
+ status.channels = (value & 0x7) + 1;
+
+ /* bits per sample */
+ switch ((value & 0xF0) >> 4) {
+ case 0x0:
+ status.bits_per_sample = 8;
+ break;
+ case 0x1:
+ status.bits_per_sample = 16;
+ break;
+ case 0x2:
+ status.bits_per_sample = 20;
+ break;
+ case 0x3:
+ status.bits_per_sample = 24;
+ break;
+ case 0x4:
+ status.bits_per_sample = 32;
+ break;
+ default:
+ dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n",
+ (int)value);
+ status.bits_per_sample = 16;
+ }
+
+ /* current sampling rate in HZ */
+ if (value & 0x4000)
+ status.rate = 44100;
+ else
+ status.rate = 48000;
+ status.rate *= ((value >> 11) & 0x7) + 1;
+ status.rate /= ((value >> 8) & 0x7) + 1;
+
+ value = RREG32(R600_AUDIO_STATUS_BITS);
+
+ /* iec 60958 status bits */
+ status.status_bits = value & 0xff;
+
+ /* iec 60958 category code */
+ status.category_code = (value >> 8) & 0xff;
+
+ return status;
+}
+
+/*
+ * update all hdmi interfaces with current audio parameters
+ */
+void r600_audio_update_hdmi(void *arg, int pending)
+{
+ struct radeon_device *rdev = arg;
+ struct drm_device *dev = rdev->ddev;
+ struct r600_audio audio_status = r600_audio_status(rdev);
+ struct drm_encoder *encoder;
+ bool changed = false;
+
+ if (rdev->audio_status.channels != audio_status.channels ||
+ rdev->audio_status.rate != audio_status.rate ||
+ rdev->audio_status.bits_per_sample != audio_status.bits_per_sample ||
+ rdev->audio_status.status_bits != audio_status.status_bits ||
+ rdev->audio_status.category_code != audio_status.category_code) {
+ rdev->audio_status = audio_status;
+ changed = true;
+ }
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (!radeon_dig_encoder(encoder))
+ continue;
+ if (changed || r600_hdmi_buffer_status_changed(encoder))
+ r600_hdmi_update_audio_settings(encoder);
+ }
+}
+
+/*
+ * 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
+ */
+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_status.channels = -1;
+ rdev->audio_status.rate = -1;
+ rdev->audio_status.bits_per_sample = -1;
+ rdev->audio_status.status_bits = 0;
+ rdev->audio_status.category_code = 0;
+
+ return 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;
+
+ r600_audio_engine_enable(rdev, false);
+}
diff --git a/sys/dev/drm2/radeon/r600_blit.c b/sys/dev/drm2/radeon/r600_blit.c
new file mode 100644
index 0000000..f9658d4
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_blit.c
@@ -0,0 +1,876 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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 = roundup2(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();
+}
+
+/* 23 bits of float fractional data */
+#define I2F_FRAC_BITS 23
+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
+
+/*
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
+ * Will be exact from 0 to 2^24. Above that, we round towards zero
+ * as the fractional bits will not fit in a float. (It would be better to
+ * round towards even as the fpu does, but that is slower.)
+ */
+__pure uint32_t int2float(uint32_t x)
+{
+ uint32_t msb, exponent, fraction;
+
+ /* Zero is special */
+ if (!x) return 0;
+
+ /* Get location of the most significant bit */
+ msb = fls(x);
+
+ /*
+ * Use a rotate instead of a shift because that works both leftwards
+ * and rightwards due to the mod(32) behaviour. This means we don't
+ * need to check to see if we are above 2^24 or not.
+ */
+ fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
+ exponent = (127 + msb) << I2F_FRAC_BITS;
+
+ return fraction + exponent;
+}
+
+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->masterp, 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] = int2float(dst_x);
+ vb[1] = 0;
+ vb[2] = int2float(src_x);
+ vb[3] = 0;
+
+ vb[4] = int2float(dst_x);
+ vb[5] = int2float(h);
+ vb[6] = int2float(src_x);
+ vb[7] = int2float(h);
+
+ vb[8] = int2float(dst_x + cur_size);
+ vb[9] = int2float(h);
+ vb[10] = int2float(src_x + cur_size);
+ vb[11] = int2float(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] = int2float(dst_x / 4);
+ vb[1] = 0;
+ vb[2] = int2float(src_x / 4);
+ vb[3] = 0;
+
+ vb[4] = int2float(dst_x / 4);
+ vb[5] = int2float(h);
+ vb[6] = int2float(src_x / 4);
+ vb[7] = int2float(h);
+
+ vb[8] = int2float((dst_x + cur_size) / 4);
+ vb[9] = int2float(h);
+ vb[10] = int2float((src_x + cur_size) / 4);
+ vb[11] = int2float(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] = int2float(dx);
+ vb[1] = int2float(dy);
+ vb[2] = int2float(sx);
+ vb[3] = int2float(sy);
+
+ vb[4] = int2float(dx);
+ vb[5] = int2float(dy2);
+ vb[6] = int2float(sx);
+ vb[7] = int2float(sy2);
+
+ vb[8] = int2float(dx2);
+ vb[9] = int2float(dy2);
+ vb[10] = int2float(sx2);
+ vb[11] = int2float(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/sys/dev/drm2/radeon/r600_blit_kms.c b/sys/dev/drm2/radeon/r600_blit_kms.c
new file mode 100644
index 0000000..e2ace69
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_blit_kms.c
@@ -0,0 +1,758 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.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 = roundup2(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 = roundup2(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);
+}
+
+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 = 8; /* sync semaphore */
+ rdev->r600_blit.ring_size_common += 40; /* shaders + def state */
+ 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;
+
+ 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 = roundup2(obj_size, 256);
+
+ rdev->r600_blit.vs_offset = obj_size;
+ obj_size += r6xx_vs_size * 4;
+ obj_size = roundup2(obj_size, 256);
+
+ rdev->r600_blit.ps_offset = obj_size;
+ obj_size += r6xx_ps_size * 4;
+ obj_size = roundup2(obj_size, 256);
+
+ /* pin copy shader into vram if not already initialized */
+ if (rdev->r600_blit.shader_obj == NULL) {
+ r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_VRAM,
+ NULL, &rdev->r600_blit.shader_obj);
+ if (r) {
+ DRM_ERROR("r600 failed to allocate shader\n");
+ return r;
+ }
+
+ 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;
+ }
+ }
+
+ 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((char *)ptr + rdev->r600_blit.state_offset,
+ r7xx_default_state, rdev->r600_blit.state_len * 4);
+ else
+ memcpy_toio((char *)ptr + rdev->r600_blit.state_offset,
+ r6xx_default_state, rdev->r600_blit.state_len * 4);
+ if (num_packet2s)
+ memcpy_toio((char *)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);
+
+ 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 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;
+ DRM_ERROR("%s: called with no pages", __func__);
+ } 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);
+ KASSERT(pages != 0, ("r600_blit_create_rect: 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_fence **fence, struct radeon_sa_bo **vb,
+ struct radeon_semaphore **sem)
+{
+ 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 = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, vb,
+ (num_loops*48)+256, 256, true);
+ if (r) {
+ return r;
+ }
+
+ r = radeon_semaphore_create(rdev, sem);
+ if (r) {
+ radeon_sa_bo_free(rdev, vb, NULL);
+ 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) {
+ radeon_sa_bo_free(rdev, vb, NULL);
+ radeon_semaphore_free(rdev, sem, NULL);
+ return r;
+ }
+
+ if (radeon_fence_need_sync(*fence, RADEON_RING_TYPE_GFX_INDEX)) {
+ radeon_semaphore_sync_rings(rdev, *sem, (*fence)->ring,
+ RADEON_RING_TYPE_GFX_INDEX);
+ radeon_fence_note_sync(*fence, RADEON_RING_TYPE_GFX_INDEX);
+ } else {
+ radeon_semaphore_free(rdev, sem, NULL);
+ }
+
+ 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,
+ struct radeon_sa_bo *vb, struct radeon_semaphore *sem)
+{
+ struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ int r;
+
+ r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return;
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_sa_bo_free(rdev, &vb, *fence);
+ radeon_semaphore_free(rdev, &sem, *fence);
+}
+
+void r600_kms_blit_copy(struct radeon_device *rdev,
+ u64 src_gpu_addr, u64 dst_gpu_addr,
+ unsigned num_gpu_pages,
+ struct radeon_sa_bo *vb)
+{
+ u64 vb_gpu_addr;
+ u32 *vb_cpu_addr;
+
+ DRM_DEBUG("emitting copy %16jx %16jx %d\n",
+ (uintmax_t)src_gpu_addr, (uintmax_t)dst_gpu_addr, num_gpu_pages);
+ vb_cpu_addr = (u32 *)radeon_sa_bo_cpu_addr(vb);
+ vb_gpu_addr = radeon_sa_bo_gpu_addr(vb);
+
+ 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);
+
+ vb_cpu_addr[0] = 0;
+ vb_cpu_addr[1] = 0;
+ vb_cpu_addr[2] = 0;
+ vb_cpu_addr[3] = 0;
+
+ vb_cpu_addr[4] = 0;
+ vb_cpu_addr[5] = int2float(h);
+ vb_cpu_addr[6] = 0;
+ vb_cpu_addr[7] = int2float(h);
+
+ vb_cpu_addr[8] = int2float(w);
+ vb_cpu_addr[9] = int2float(h);
+ vb_cpu_addr[10] = int2float(w);
+ vb_cpu_addr[11] = int2float(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);
+ 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_cpu_addr += 12;
+ vb_gpu_addr += 4*12;
+ src_gpu_addr += size_in_bytes;
+ dst_gpu_addr += size_in_bytes;
+ num_gpu_pages -= pages_per_loop;
+ }
+}
diff --git a/sys/dev/drm2/radeon/r600_blit_shaders.c b/sys/dev/drm2/radeon/r600_blit_shaders.c
new file mode 100644
index 0000000..1095a2c
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_blit_shaders.c
@@ -0,0 +1,720 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+
+/*
+ * 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 = DRM_ARRAY_SIZE(r6xx_ps);
+const u32 r6xx_vs_size = DRM_ARRAY_SIZE(r6xx_vs);
+const u32 r6xx_default_size = DRM_ARRAY_SIZE(r6xx_default_state);
+const u32 r7xx_default_size = DRM_ARRAY_SIZE(r7xx_default_state);
diff --git a/sys/dev/drm2/radeon/r600_blit_shaders.h b/sys/dev/drm2/radeon/r600_blit_shaders.h
new file mode 100644
index 0000000..591b756
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_blit_shaders.h
@@ -0,0 +1,42 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+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;
+
+__pure uint32_t int2float(uint32_t x);
+#endif
diff --git a/sys/dev/drm2/radeon/r600_cp.c b/sys/dev/drm2/radeon/r600_cp.c
new file mode 100644
index 0000000..2907bdb
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_cp.c
@@ -0,0 +1,2645 @@
+/*
+ * 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 <airlied@redhat.com>
+ * Alex Deucher <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_drv.h"
+#include "r600_cp.h"
+
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+# 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;
+#ifdef __linux__
+ int max_pages;
+ int pages;
+ int i;
+#endif
+
+ if (!entry)
+ return;
+
+ if (gart_info->bus_addr) {
+#ifdef __linux__
+ 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);
+ }
+#endif
+ 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++) {
+#ifdef __linux__
+ 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;
+ }
+#endif
+ 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;
+#ifdef __linux__
+done:
+#endif
+ 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)
+{
+ const char *chip_name;
+ size_t pfp_req_size, me_req_size;
+ char fw_name[30];
+ int err;
+
+ 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: panic("%s: Unsupported family %d", __func__, dev_priv->flags & RADEON_FAMILY_MASK);
+ }
+
+ 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);
+ err = 0;
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
+ dev_priv->pfp_fw = firmware_get(fw_name);
+ if (dev_priv->pfp_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (dev_priv->pfp_fw->datasize != pfp_req_size) {
+ DRM_ERROR(
+ "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+ dev_priv->pfp_fw->datasize, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
+ dev_priv->me_fw = firmware_get(fw_name);
+ if (dev_priv->me_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (dev_priv->me_fw->datasize != me_req_size) {
+ DRM_ERROR(
+ "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+ dev_priv->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+out:
+ if (err) {
+ if (err != -EINVAL)
+ DRM_ERROR(
+ "r600_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ if (dev_priv->pfp_fw != NULL) {
+ firmware_put(dev_priv->pfp_fw, FIRMWARE_UNLOAD);
+ dev_priv->pfp_fw = NULL;
+ }
+ if (dev_priv->me_fw != NULL) {
+ firmware_put(dev_priv->me_fw, FIRMWARE_UNLOAD);
+ 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);
+ DRM_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);
+ DRM_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)
+{
+ return hweight32(val);
+}
+
+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);
+ DRM_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->vaddr)
+ + 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->vaddr>
+ + 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->masterp->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->masterp->driver_priv;
+
+ DRM_DEBUG("\n");
+
+ sx_init(&dev_priv->cs_mutex, "drm__radeon_private__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->vaddr
+ + 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->masterp;
+ 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->masterp, 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->masterp, 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;
+ }
+ sx_xlock(&dev_priv->cs_mutex);
+ /* get ib */
+ l = 0;
+ r = r600_ib_get(dev, fpriv, &buf);
+ if (r) {
+ DRM_ERROR("ib_get failed\n");
+ goto out;
+ }
+ ib = (u32 *)((uintptr_t)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;
+ sx_xunlock(&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/sys/dev/drm2/radeon/r600_cp.h b/sys/dev/drm2/radeon/r600_cp.h
new file mode 100644
index 0000000..b1611ba
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_cp.h
@@ -0,0 +1,15 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __R600_CP_H__
+#define __R600_CP_H__
+
+void r600_cs_legacy_get_tiling_conf(struct drm_device *dev,
+ u32 *npipes, u32 *nbanks, u32 *group_size);
+
+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);
+
+#endif /* !defined(__R600_CP_H__) */
diff --git a/sys/dev/drm2/radeon/r600_cs.c b/sys/dev/drm2/radeon/r600_cs.c
new file mode 100644
index 0000000..6ba4614
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_cs.c
@@ -0,0 +1,2761 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "r600d.h"
+#include "r600_reg_safe.h"
+#include "r600_cp.h"
+#include "r600_cs.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;
+
+
+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 log_nsamples;
+ u32 nsamples;
+ u32 cb_color_base_last[8];
+ struct radeon_bo *cb_color_bo[8];
+ u64 cb_color_bo_mc[8];
+ u64 cb_color_bo_offset[8];
+ struct radeon_bo *cb_color_frag_bo[8];
+ u64 cb_color_frag_offset[8];
+ struct radeon_bo *cb_color_tile_bo[8];
+ u64 cb_color_tile_offset[8];
+ u32 cb_color_mask[8];
+ 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 */
+ bool is_resolve;
+ 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 >= DRM_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 >= DRM_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 >= DRM_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 >= DRM_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 >= DRM_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_color_frag_bo[i] = NULL;
+ track->cb_color_frag_offset[i] = 0xFFFFFFFF;
+ track->cb_color_tile_bo[i] = NULL;
+ track->cb_color_tile_offset[i] = 0xFFFFFFFF;
+ track->cb_color_mask[i] = 0xFFFFFFFF;
+ }
+ track->is_resolve = false;
+ track->nsamples = 16;
+ track->log_nsamples = 4;
+ 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;
+ /* When resolve is used, the second colorbuffer has always 1 sample. */
+ unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;
+
+ 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 = 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%jx 0x%jx, %d not aligned\n", __func__, i,
+ (uintmax_t)base_offset, (uintmax_t)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) * nsamples;
+ 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 %ju %d %lu too big (%d %d) (%d %d %d)\n",
+ __func__, i, array_mode,
+ (uintmax_t)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;
+
+ /* FMASK/CMASK */
+ switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
+ case V_0280A0_TILE_DISABLE:
+ break;
+ case V_0280A0_FRAG_ENABLE:
+ if (track->nsamples > 1) {
+ uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]);
+ /* the tile size is 8x8, but the size is in units of bits.
+ * for bytes, do just * 8. */
+ uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1);
+
+ if (bytes + track->cb_color_frag_offset[i] >
+ radeon_bo_size(track->cb_color_frag_bo[i])) {
+ dev_warn(p->dev, "%s FMASK_TILE_MAX too large "
+ "(tile_max=%u, bytes=%u, offset=%ju, bo_size=%lu)\n",
+ __func__, tile_max, bytes,
+ (uintmax_t)track->cb_color_frag_offset[i],
+ radeon_bo_size(track->cb_color_frag_bo[i]));
+ return -EINVAL;
+ }
+ }
+ /* fall through */
+ case V_0280A0_CLEAR_ENABLE:
+ {
+ uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]);
+ /* One block = 128x128 pixels, one 8x8 tile has 4 bits..
+ * (128*128) / (8*8) / 2 = 128 bytes per block. */
+ uint32_t bytes = (block_max + 1) * 128;
+
+ if (bytes + track->cb_color_tile_offset[i] >
+ radeon_bo_size(track->cb_color_tile_bo[i])) {
+ dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large "
+ "(block_max=%u, bytes=%u, offset=%ju, bo_size=%lu)\n",
+ __func__, block_max, bytes,
+ (uintmax_t)track->cb_color_tile_offset[i],
+ radeon_bo_size(track->cb_color_tile_bo[i]));
+ return -EINVAL;
+ }
+ break;
+ }
+ default:
+ dev_warn(p->dev, "%s invalid tile mode\n", __func__);
+ return -EINVAL;
+ }
+ 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%jx, 0x%jx, %d not aligned\n", __func__,
+ (uintmax_t)base_offset, (uintmax_t)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 * track->nsamples;
+ 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 = roundup2(nbx, 16 * 8);
+ /* nby is npipes htiles aligned == npipes * 8 pixel aligned */
+ nby = roundup(nby, track->npipes * 8);
+ } else {
+ /* always assume 8x8 htile */
+ /* align is htile align * 8, htile align vary according to
+ * number of pipe and tile width and nby
+ */
+ switch (track->npipes) {
+ case 8:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup2(nbx, 64 * 8);
+ nby = roundup2(nby, 64 * 8);
+ break;
+ case 4:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup2(nbx, 64 * 8);
+ nby = roundup2(nby, 32 * 8);
+ break;
+ case 2:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup2(nbx, 32 * 8);
+ nby = roundup2(nby, 32 * 8);
+ break;
+ case 1:
+ /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+ nbx = roundup2(nbx, 32 * 8);
+ nby = roundup2(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 >> 3;
+ nby = nby >> 3;
+ /* size must be aligned on npipes * 2K boundary */
+ size = roundup(nbx * nby * 4, track->npipes * (2 << 10));
+ 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%jx, 0x%lx\n",
+ i, (uintmax_t)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;
+
+ /* We must check both colorbuffers for RESOLVE. */
+ if (track->is_resolve) {
+ tmp |= 0xff;
+ }
+
+ 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_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID &&
+ (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.
+ **/
+static 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:
+ DRM_ERROR("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 >= DRM_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->log_nsamples = tmp;
+ track->nsamples = 1 << tmp;
+ track->cb_dirty = true;
+ break;
+ case R_028808_CB_COLOR_CONTROL:
+ tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx));
+ track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX;
+ 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;
+ }
+ track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
+ track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp];
+ ib[idx] = track->cb_color_base_last[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;
+ }
+ track->cb_color_frag_bo[tmp] = reloc->robj;
+ track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8;
+ ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ }
+ if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+ track->cb_dirty = true;
+ }
+ 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;
+ }
+ track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
+ track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp];
+ ib[idx] = track->cb_color_base_last[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;
+ }
+ track->cb_color_tile_bo[tmp] = reloc->robj;
+ track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8;
+ ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ }
+ if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+ track->cb_dirty = true;
+ }
+ break;
+ case R_028100_CB_COLOR0_MASK:
+ case R_028104_CB_COLOR1_MASK:
+ case R_028108_CB_COLOR2_MASK:
+ case R_02810C_CB_COLOR3_MASK:
+ case R_028110_CB_COLOR4_MASK:
+ case R_028114_CB_COLOR5_MASK:
+ case R_028118_CB_COLOR6_MASK:
+ case R_02811C_CB_COLOR7_MASK:
+ tmp = (reg - R_028100_CB_COLOR0_MASK) / 4;
+ track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx);
+ if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {
+ track->cb_dirty = true;
+ }
+ 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);
+ /* force 8x8 htile width and height */
+ ib[idx] |= 3;
+ 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 nsamples, 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 = roundup(nbx, block_align);
+
+ height = r600_mip_minify(h0, i);
+ nby = r600_fmt_get_nblocksy(format, height);
+ nby = roundup(nby, height_align);
+
+ depth = r600_mip_minify(d0, i);
+
+ size = nbx * nby * blocksize * nsamples;
+ if (nfaces)
+ size *= nfaces;
+ else
+ size *= depth;
+
+ if (i == 0)
+ *l0_size = size;
+
+ if (i == 0 || i == 1)
+ offset = roundup(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 dim, nfaces, llevel, blevel, w0, h0, d0;
+ u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5;
+ u32 height_align, pitch, pitch_align, depth_align;
+ u32 barray, larray;
+ u64 base_align;
+ struct array_mode_checker array_check;
+ u32 format;
+ bool is_array;
+
+ /* 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);
+ word2 = radeon_get_ib_value(p, idx + 2) << 8;
+ word3 = radeon_get_ib_value(p, idx + 3) << 8;
+ word4 = radeon_get_ib_value(p, idx + 4);
+ word5 = radeon_get_ib_value(p, idx + 5);
+ dim = G_038000_DIM(word0);
+ w0 = G_038000_TEX_WIDTH(word0) + 1;
+ pitch = (G_038000_PITCH(word0) + 1) * 8;
+ h0 = G_038004_TEX_HEIGHT(word1) + 1;
+ d0 = G_038004_TEX_DEPTH(word1);
+ format = G_038004_DATA_FORMAT(word1);
+ blevel = G_038010_BASE_LEVEL(word4);
+ llevel = G_038014_LAST_LEVEL(word5);
+ /* pitch in texels */
+ 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);
+ nfaces = 1;
+ is_array = false;
+ switch (dim) {
+ 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:
+ is_array = true;
+ break;
+ case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA:
+ is_array = true;
+ /* fall through */
+ case V_038000_SQ_TEX_DIM_2D_MSAA:
+ array_check.nsamples = 1 << llevel;
+ llevel = 0;
+ break;
+ default:
+ dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0));
+ return -EINVAL;
+ }
+ 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;
+ }
+
+ 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%jx, 0x%jx, %d) invalid\n",
+ __func__, __LINE__, (uintmax_t)base_offset, (uintmax_t)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%jx, 0x%jx, %d) invalid\n",
+ __func__, __LINE__, (uintmax_t)mip_offset, (uintmax_t)base_align, G_038000_TILE_MODE(word0));
+ return -EINVAL;
+ }
+
+ if (blevel > llevel) {
+ dev_warn(p->dev, "texture blevel %d > llevel %d\n",
+ blevel, llevel);
+ }
+ if (is_array) {
+ barray = G_038014_BASE_ARRAY(word5);
+ larray = G_038014_LAST_ARRAY(word5);
+
+ nfaces = larray - barray + 1;
+ }
+ r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, 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 %jd\n", pitch, pitch_align, height_align, (uintmax_t)base_align);
+ return -EINVAL;
+ }
+ /* using get ib will give us the offset into the mipmap bo */
+ 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 >= DRM_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_CP_DMA:
+ {
+ u32 command, size;
+ u64 offset, tmp;
+ if (pkt->count != 4) {
+ DRM_ERROR("bad CP DMA\n");
+ return -EINVAL;
+ }
+ command = radeon_get_ib_value(p, idx+4);
+ size = command & 0x1fffff;
+ if (command & PACKET3_CP_DMA_CMD_SAS) {
+ /* src address space is register */
+ DRM_ERROR("CP DMA SAS not supported\n");
+ return -EINVAL;
+ } else {
+ if (command & PACKET3_CP_DMA_CMD_SAIC) {
+ DRM_ERROR("CP DMA SAIC only supported for registers\n");
+ return -EINVAL;
+ }
+ /* src address space is memory */
+ r = r600_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad CP DMA SRC\n");
+ return -EINVAL;
+ }
+
+ tmp = radeon_get_ib_value(p, idx) +
+ ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
+
+ offset = reloc->lobj.gpu_offset + tmp;
+
+ if ((tmp + size) > radeon_bo_size(reloc->robj)) {
+ dev_warn(p->dev, "CP DMA src buffer too small (%ju %lu)\n",
+ (uintmax_t)tmp + size, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+
+ ib[idx] = offset;
+ ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
+ }
+ if (command & PACKET3_CP_DMA_CMD_DAS) {
+ /* dst address space is register */
+ DRM_ERROR("CP DMA DAS not supported\n");
+ return -EINVAL;
+ } else {
+ /* dst address space is memory */
+ if (command & PACKET3_CP_DMA_CMD_DAIC) {
+ DRM_ERROR("CP DMA DAIC only supported for registers\n");
+ return -EINVAL;
+ }
+ r = r600_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad CP DMA DST\n");
+ return -EINVAL;
+ }
+
+ tmp = radeon_get_ib_value(p, idx+2) +
+ ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);
+
+ offset = reloc->lobj.gpu_offset + tmp;
+
+ if ((tmp + size) > radeon_bo_size(reloc->robj)) {
+ dev_warn(p->dev, "CP DMA dst buffer too small (%ju %lu)\n",
+ (uintmax_t)tmp + size, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+
+ ib[idx+2] = offset;
+ ib[idx+3] = 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_STRMOUT_BASE_UPDATE:
+ /* RS780 and RS880 also need this */
+ if (p->family < CHIP_RS780) {
+ DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n");
+ return -EINVAL;
+ }
+ if (pkt->count != 1) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n");
+ return -EINVAL;
+ }
+ if (idx_value > 3) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n");
+ return -EINVAL;
+ }
+ {
+ u64 offset;
+
+ r = r600_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n");
+ return -EINVAL;
+ }
+
+ if (reloc->robj != track->vgt_strmout_bo[idx_value]) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n");
+ return -EINVAL;
+ }
+
+ offset = radeon_get_ib_value(p, idx+1) << 8;
+ if (offset != track->vgt_strmout_bo_offset[idx_value]) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%jx, 0x%x\n",
+ (uintmax_t)offset, track->vgt_strmout_bo_offset[idx_value]);
+ return -EINVAL;
+ }
+
+ if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+ DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%jx, 0x%lx\n",
+ (uintmax_t)offset + 4, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+ }
+ 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%jx, 0x%lx\n",
+ (uintmax_t)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%jx, 0x%lx\n",
+ (uintmax_t)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_MEM_WRITE:
+ {
+ u64 offset;
+
+ if (pkt->count != 3) {
+ DRM_ERROR("bad MEM_WRITE (invalid count)\n");
+ return -EINVAL;
+ }
+ r = r600_cs_packet_next_reloc(p, &reloc);
+ if (r) {
+ DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
+ return -EINVAL;
+ }
+ offset = radeon_get_ib_value(p, idx+0);
+ offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
+ if (offset & 0x7) {
+ DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
+ return -EINVAL;
+ }
+ if ((offset + 8) > radeon_bo_size(reloc->robj)) {
+ DRM_ERROR("bad MEM_WRITE bo too small: 0x%jx, 0x%lx\n",
+ (uintmax_t)offset + 8, radeon_bo_size(reloc->robj));
+ return -EINVAL;
+ }
+ offset += reloc->lobj.gpu_offset;
+ ib[idx+0] = offset;
+ ib[idx+1] = 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%jx, 0x%lx\n",
+ (uintmax_t)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%jx, 0x%lx\n",
+ (uintmax_t)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 = malloc(sizeof(*track),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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) {
+ free(p->track, DRM_MEM_DRIVER);
+ 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);
+ free(p->track, DRM_MEM_DRIVER);
+ p->track = NULL;
+ return -EINVAL;
+ }
+ if (r) {
+ free(p->track, DRM_MEM_DRIVER);
+ 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++) {
+ DRM_INFO("%05d 0x%08X\n", r, p->ib.ptr[r]);
+ DRM_MDELAY(1);
+ }
+#endif
+ free(p->track, DRM_MEM_DRIVER);
+ 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 = malloc(sizeof(struct radeon_cs_reloc),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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;
+
+ free(parser->relocs, DRM_MEM_DRIVER);
+ for (i = 0; i < parser->nchunks; i++) {
+ free(parser->chunks[i].kdata, DRM_MEM_DRIVER);
+ if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) {
+ free(parser->chunks[i].kpage[0], DRM_MEM_DRIVER);
+ free(parser->chunks[i].kpage[1], DRM_MEM_DRIVER);
+ }
+ }
+ free(parser->chunks, DRM_MEM_DRIVER);
+ free(parser->chunks_array, DRM_MEM_DRIVER);
+ free(parser->track, DRM_MEM_DRIVER);
+}
+
+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 r600_cs_track *track;
+ int r;
+
+ /* initialize tracker */
+ track = malloc(sizeof(*track), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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->device;
+ parser.rdev = NULL;
+ parser.family = family;
+ parser.track = track;
+ parser.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;
+}
+
+/*
+ * DMA
+ */
+/**
+ * r600_dma_cs_next_reloc() - parse next reloc
+ * @p: parser structure holding parsing context.
+ * @cs_reloc: reloc informations
+ *
+ * Return the next reloc, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
+ struct radeon_cs_reloc **cs_reloc)
+{
+ struct radeon_cs_chunk *relocs_chunk;
+ unsigned idx;
+
+ *cs_reloc = NULL;
+ if (p->chunk_relocs_idx == -1) {
+ DRM_ERROR("No relocation chunk !\n");
+ return -EINVAL;
+ }
+ relocs_chunk = &p->chunks[p->chunk_relocs_idx];
+ idx = p->dma_reloc_idx;
+ if (idx >= p->nrelocs) {
+ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
+ idx, p->nrelocs);
+ return -EINVAL;
+ }
+ *cs_reloc = p->relocs_ptr[idx];
+ p->dma_reloc_idx++;
+ return 0;
+}
+
+#define GET_DMA_CMD(h) (((h) & 0xf0000000) >> 28)
+#define GET_DMA_COUNT(h) ((h) & 0x0000ffff)
+#define GET_DMA_T(h) (((h) & 0x00800000) >> 23)
+
+/**
+ * r600_dma_cs_parse() - parse the DMA IB
+ * @p: parser structure holding parsing context.
+ *
+ * Parses the DMA IB from the CS ioctl and updates
+ * the GPU addresses based on the reloc information and
+ * checks for errors. (R6xx-R7xx)
+ * Returns 0 for success and an error on failure.
+ **/
+int r600_dma_cs_parse(struct radeon_cs_parser *p)
+{
+ struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
+ struct radeon_cs_reloc *src_reloc, *dst_reloc;
+ u32 header, cmd, count, tiled;
+ volatile u32 *ib = p->ib.ptr;
+ u32 idx, idx_value;
+ u64 src_offset, dst_offset;
+ int r;
+
+ do {
+ if (p->idx >= ib_chunk->length_dw) {
+ DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
+ p->idx, ib_chunk->length_dw);
+ return -EINVAL;
+ }
+ idx = p->idx;
+ header = radeon_get_ib_value(p, idx);
+ cmd = GET_DMA_CMD(header);
+ count = GET_DMA_COUNT(header);
+ tiled = GET_DMA_T(header);
+
+ switch (cmd) {
+ case DMA_PACKET_WRITE:
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_WRITE\n");
+ return -EINVAL;
+ }
+ if (tiled) {
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ p->idx += count + 5;
+ } else {
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += count + 3;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA write buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ break;
+ case DMA_PACKET_COPY:
+ r = r600_dma_cs_next_reloc(p, &src_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_COPY\n");
+ return -EINVAL;
+ }
+ if (tiled) {
+ idx_value = radeon_get_ib_value(p, idx + 2);
+ /* detile bit */
+ if (idx_value & (1 << 31)) {
+ /* tiled src, linear dst */
+ src_offset = radeon_get_ib_value(p, idx+1);
+ src_offset <<= 8;
+ ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
+
+ dst_offset = radeon_get_ib_value(p, idx+5);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;
+ ib[idx+5] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+6] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ } else {
+ /* linear src, tiled dst */
+ src_offset = radeon_get_ib_value(p, idx+5);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;
+ ib[idx+5] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+6] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset <<= 8;
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
+ }
+ p->idx += 7;
+ } else {
+ if (p->family >= CHIP_RV770) {
+ src_offset = radeon_get_ib_value(p, idx+2);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ p->idx += 5;
+ } else {
+ src_offset = radeon_get_ib_value(p, idx+2);
+ src_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff0000)) << 16;
+
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
+ ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff) << 16;
+ p->idx += 4;
+ }
+ }
+ if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
+ dev_warn(p->dev, "DMA copy src buffer too small (%ju %lu)\n",
+ (uintmax_t)src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
+ return -EINVAL;
+ }
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA write dst buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ break;
+ case DMA_PACKET_CONSTANT_FILL:
+ if (p->family < CHIP_RV770) {
+ DRM_ERROR("Constant Fill is 7xx only !\n");
+ return -EINVAL;
+ }
+ r = r600_dma_cs_next_reloc(p, &dst_reloc);
+ if (r) {
+ DRM_ERROR("bad DMA_PACKET_WRITE\n");
+ return -EINVAL;
+ }
+ dst_offset = radeon_get_ib_value(p, idx+1);
+ dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;
+ if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
+ dev_warn(p->dev, "DMA constant fill buffer too small (%ju %lu)\n",
+ (uintmax_t)dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
+ return -EINVAL;
+ }
+ ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
+ ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) << 16) & 0x00ff0000;
+ p->idx += 4;
+ break;
+ case DMA_PACKET_NOP:
+ p->idx += 1;
+ break;
+ default:
+ DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
+ return -EINVAL;
+ }
+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+#if 0
+ for (r = 0; r < p->ib->length_dw; r++) {
+ DRM_INFO("%05d 0x%08X\n", r, p->ib.ptr[r]);
+ DRM_MDELAY(1);
+ }
+#endif
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/r600_cs.h b/sys/dev/drm2/radeon/r600_cs.h
new file mode 100644
index 0000000..9db545e
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_cs.h
@@ -0,0 +1,11 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __R600_CS_H__
+#define __R600_CS_H__
+
+int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
+ struct radeon_cs_reloc **cs_reloc);
+
+#endif /* !defined(__R600_CS_H__) */
diff --git a/sys/dev/drm2/radeon/r600_hdmi.c b/sys/dev/drm2/radeon/r600_hdmi.c
new file mode 100644
index 0000000..46a72fb
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_hdmi.c
@@ -0,0 +1,589 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "r600d.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
+};
+
+static const struct radeon_hdmi_acr r600_hdmi_predefined_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);
+}
+
+struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
+{
+ struct radeon_hdmi_acr res;
+ u8 i;
+
+ for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
+ r600_hdmi_predefined_acr[i].clock != 0; i++)
+ ;
+ res = r600_hdmi_predefined_acr[i];
+
+ /* In case some CTS are missing */
+ r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
+ r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
+ r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
+
+ return res;
+}
+
+/*
+ * 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;
+ struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->offset;
+
+ WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
+ WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);
+
+ WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
+ WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);
+
+ WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
+ WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
+}
+
+/*
+ * 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;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->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(HDMI0_AVI_INFO0 + offset,
+ frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
+ WREG32(HDMI0_AVI_INFO1 + offset,
+ frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
+ WREG32(HDMI0_AVI_INFO2 + offset,
+ frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
+ WREG32(HDMI0_AVI_INFO3 + offset,
+ 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;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->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(HDMI0_AUDIO_INFO0 + offset,
+ frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
+ WREG32(HDMI0_AUDIO_INFO1 + offset,
+ frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
+}
+
+/*
+ * test if audio buffer is filled enough to start playing
+ */
+static bool r600_hdmi_is_audio_buffer_filled(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;
+ uint32_t offset = dig->afmt->offset;
+
+ return (RREG32(HDMI0_STATUS + offset) & 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);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ int status, result;
+
+ if (!dig->afmt || !dig->afmt->enabled)
+ return 0;
+
+ status = r600_hdmi_is_audio_buffer_filled(encoder);
+ result = dig->afmt->last_buffer_filled_status != status;
+ dig->afmt->last_buffer_filled_status = status;
+
+ return result;
+}
+
+/*
+ * write the audio workaround status to the hardware
+ */
+static 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);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset = dig->afmt->offset;
+ bool hdmi_audio_workaround = false; /* FIXME */
+ u32 value;
+
+ if (!hdmi_audio_workaround ||
+ r600_hdmi_is_audio_buffer_filled(encoder))
+ value = 0; /* disable workaround */
+ else
+ value = HDMI0_AUDIO_TEST_EN; /* enable workaround */
+ WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
+ value, ~HDMI0_AUDIO_TEST_EN);
+}
+
+
+/*
+ * 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;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
+
+ /* Silent, r600_hdmi_enable will raise WARN for us */
+ if (!dig->afmt->enabled)
+ return;
+ offset = dig->afmt->offset;
+
+ r600_audio_set_clock(encoder, mode->clock);
+
+ WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
+ HDMI0_NULL_SEND); /* send null packets when required */
+
+ WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
+
+ if (ASIC_IS_DCE32(rdev)) {
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
+ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
+ HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
+ WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
+ AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */
+ AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+ } else {
+ WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
+ HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
+ HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
+ HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */
+ HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+ }
+
+ WREG32(HDMI0_ACR_PACKET_CONTROL + offset,
+ HDMI0_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */
+ HDMI0_ACR_SOURCE); /* select SW CTS value */
+
+ WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
+ HDMI0_NULL_SEND | /* send null packets when required */
+ HDMI0_GC_SEND | /* send general control packets */
+ HDMI0_GC_CONT); /* send general control packets every frame */
+
+ /* TODO: HDMI0_AUDIO_INFO_UPDATE */
+ WREG32(HDMI0_INFOFRAME_CONTROL0 + offset,
+ HDMI0_AVI_INFO_SEND | /* enable AVI info frames */
+ HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */
+ HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
+ HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */
+
+ WREG32(HDMI0_INFOFRAME_CONTROL1 + offset,
+ HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */
+ HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */
+
+ WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */
+
+ r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ r600_hdmi_update_ACR(encoder, mode->clock);
+
+ /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
+ WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
+ WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF);
+ WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001);
+ WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
+
+ r600_hdmi_audio_workaround(encoder);
+}
+
+/*
+ * 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;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ struct r600_audio audio = r600_audio_status(rdev);
+ uint32_t offset;
+ uint32_t iec;
+
+ if (!dig->afmt || !dig->afmt->enabled)
+ return;
+ offset = dig->afmt->offset;
+
+ DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
+ r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
+ audio.channels, audio.rate, audio.bits_per_sample);
+ DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
+ (int)audio.status_bits, (int)audio.category_code);
+
+ iec = 0;
+ if (audio.status_bits & AUDIO_STATUS_PROFESSIONAL)
+ iec |= 1 << 0;
+ if (audio.status_bits & AUDIO_STATUS_NONAUDIO)
+ iec |= 1 << 1;
+ if (audio.status_bits & AUDIO_STATUS_COPYRIGHT)
+ iec |= 1 << 2;
+ if (audio.status_bits & AUDIO_STATUS_EMPHASIS)
+ iec |= 1 << 3;
+
+ iec |= HDMI0_60958_CS_CATEGORY_CODE(audio.category_code);
+
+ switch (audio.rate) {
+ case 32000:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x3);
+ break;
+ case 44100:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x0);
+ break;
+ case 48000:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x2);
+ break;
+ case 88200:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x8);
+ break;
+ case 96000:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xa);
+ break;
+ case 176400:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xc);
+ break;
+ case 192000:
+ iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xe);
+ break;
+ }
+
+ WREG32(HDMI0_60958_0 + offset, iec);
+
+ iec = 0;
+ switch (audio.bits_per_sample) {
+ case 16:
+ iec |= HDMI0_60958_CS_WORD_LENGTH(0x2);
+ break;
+ case 20:
+ iec |= HDMI0_60958_CS_WORD_LENGTH(0x3);
+ break;
+ case 24:
+ iec |= HDMI0_60958_CS_WORD_LENGTH(0xb);
+ break;
+ }
+ if (audio.status_bits & AUDIO_STATUS_V)
+ iec |= 0x5 << 16;
+ WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
+
+ r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0,
+ 0);
+
+ r600_hdmi_audio_workaround(encoder);
+}
+
+/*
+ * 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);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
+ u32 hdmi;
+
+ if (ASIC_IS_DCE6(rdev))
+ return;
+
+ /* Silent, r600_hdmi_enable will raise WARN for us */
+ if (dig->afmt->enabled)
+ return;
+ offset = dig->afmt->offset;
+
+ /* Older chipsets require setting HDMI and routing manually */
+ if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
+ hdmi = HDMI0_ERROR_ACK | HDMI0_ENABLE;
+ 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);
+ hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN,
+ ~AVIVO_LVTMA_CNTL_HDMI_EN);
+ hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_DDI:
+ WREG32_P(DDIA_CNTL, DDIA_HDMI_EN, ~DDIA_HDMI_EN);
+ hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);
+ break;
+ default:
+ dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+ radeon_encoder->encoder_id);
+ break;
+ }
+ WREG32(HDMI0_CONTROL + offset, hdmi);
+ }
+
+ if (rdev->irq.installed) {
+ /* if irq is available use it */
+ radeon_irq_kms_enable_afmt(rdev, dig->afmt->id);
+ }
+
+ dig->afmt->enabled = true;
+
+ DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ 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);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ uint32_t offset;
+
+ if (ASIC_IS_DCE6(rdev))
+ return;
+
+ /* Called for ATOM_ENCODER_MODE_HDMI only */
+ if (!dig || !dig->afmt) {
+ DRM_ERROR("%s: !dig || !dig->afmt", __func__);
+ return;
+ }
+ if (!dig->afmt->enabled)
+ return;
+ offset = dig->afmt->offset;
+
+ DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ offset, radeon_encoder->encoder_id);
+
+ /* disable irq */
+ radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);
+
+ /* Older chipsets not handled by AtomBIOS */
+ 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);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ WREG32_P(AVIVO_LVTMA_CNTL, 0,
+ ~AVIVO_LVTMA_CNTL_HDMI_EN);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_DDI:
+ WREG32_P(DDIA_CNTL, 0, ~DDIA_HDMI_EN);
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ break;
+ default:
+ dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
+ radeon_encoder->encoder_id);
+ break;
+ }
+ WREG32(HDMI0_CONTROL + offset, HDMI0_ERROR_ACK);
+ }
+
+ dig->afmt->enabled = false;
+}
diff --git a/sys/dev/drm2/radeon/r600_reg.h b/sys/dev/drm2/radeon/r600_reg.h
new file mode 100644
index 0000000..e0578cc
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_reg.h
@@ -0,0 +1,177 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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_BIF_FB_EN 0x5490
+#define R600_FB_READ_EN (1 << 0)
+#define R600_FB_WRITE_EN (1 << 1)
+
+#define R600_CITF_CNTL 0x200c
+#define R600_BLACKOUT_MASK 0x00000003
+
+#define R700_MC_CITF_CNTL 0x25c0
+
+#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
+
+#define DCE2_HDMI_OFFSET0 (0x7400 - 0x7400)
+#define DCE2_HDMI_OFFSET1 (0x7700 - 0x7400)
+/* DCE3.2 second instance starts at 0x7800 */
+#define DCE3_HDMI_OFFSET0 (0x7400 - 0x7400)
+#define DCE3_HDMI_OFFSET1 (0x7800 - 0x7400)
+
+#endif
diff --git a/sys/dev/drm2/radeon/r600_reg_safe.h b/sys/dev/drm2/radeon/r600_reg_safe.h
new file mode 100644
index 0000000..003a40de
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600_reg_safe.h
@@ -0,0 +1,493 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned r600_reg_safe_bm[1952] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFEFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFEF, 0xFFFFFFFF, 0xCFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFBD1EFFF, 0xCF3FFFFF, 0xFFFFFFFF,
+ 0xFFFFFFDF, 0xFFFFFFFF, 0xFFF0FEEF, 0xEFFFFFFF,
+ 0xFFFFFFC1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF7,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFDF, 0xFFFFFFFF, 0xFFFF7FFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0xFFFFFFF0, 0xFFFFFFFB, 0xFFFFFFFF,
+ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFDE, 0xFFFFFFFF,
+ 0xFFFFAFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF,
+ 0xFFFC0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFC3FF, 0xFFFFFFFF, 0x0000F0FF, 0x00000000,
+ 0x000CE000, 0x00000000, 0xFFD00000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xFFFF8000,
+ 0x0001801F, 0xFC000000, 0xFFFFFFFF, 0xFFFFFE00,
+ 0x7BCFFE05, 0xFE07FDEF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xF7E20000, 0xDDDF9CDD, 0xFFFFE3FD, 0xFFFFFFFF,
+ 0xFFFB0E02, 0xFFFFFFFF, 0xFFFDC3E7, 0x3FFFFFFF,
+ 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xDFFFFFFF,
+};
diff --git a/sys/dev/drm2/radeon/r600d.h b/sys/dev/drm2/radeon/r600d.h
new file mode 100644
index 0000000..41cc7c6
--- /dev/null
+++ b/sys/dev/drm2/radeon/r600d.h
@@ -0,0 +1,1932 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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 R_028808_CB_COLOR_CONTROL 0x28808
+#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4)
+#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7)
+#define C_028808_SPECIAL_OP 0xFFFFFF8F
+#define V_028808_SPECIAL_NORMAL 0x00
+#define V_028808_SPECIAL_DISABLE 0x01
+#define V_028808_SPECIAL_RESOLVE_BOX 0x07
+
+#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 R_028100_CB_COLOR0_MASK 0x028100
+#define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0)
+#define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF)
+#define C_028100_CMASK_BLOCK_MAX 0xFFFFF000
+#define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12)
+#define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF)
+#define C_028100_FMASK_TILE_MAX 0x00000FFF
+#define R_028104_CB_COLOR1_MASK 0x028104
+#define R_028108_CB_COLOR2_MASK 0x028108
+#define R_02810C_CB_COLOR3_MASK 0x02810C
+#define R_028110_CB_COLOR4_MASK 0x028110
+#define R_028114_CB_COLOR5_MASK 0x028114
+#define R_028118_CB_COLOR6_MASK 0x028118
+#define R_02811C_CB_COLOR7_MASK 0x02811C
+#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_STALLED_STAT1 0x8674
+#define CP_STALLED_STAT2 0x8678
+#define CP_BUSY_STAT 0x867C
+#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 PIPE_TILING__SHIFT 1
+#define PIPE_TILING__MASK 0x0000000e
+
+#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)
+
+/* async DMA */
+#define DMA_TILING_CONFIG 0x3ec4
+#define DMA_CONFIG 0x3e4c
+
+#define DMA_RB_CNTL 0xd000
+# define DMA_RB_ENABLE (1 << 0)
+# define DMA_RB_SIZE(x) ((x) << 1) /* log2 */
+# define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_ENABLE (1 << 12)
+# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
+#define DMA_RB_BASE 0xd004
+#define DMA_RB_RPTR 0xd008
+#define DMA_RB_WPTR 0xd00c
+
+#define DMA_RB_RPTR_ADDR_HI 0xd01c
+#define DMA_RB_RPTR_ADDR_LO 0xd020
+
+#define DMA_IB_CNTL 0xd024
+# define DMA_IB_ENABLE (1 << 0)
+# define DMA_IB_SWAP_ENABLE (1 << 4)
+#define DMA_IB_RPTR 0xd028
+#define DMA_CNTL 0xd02c
+# define TRAP_ENABLE (1 << 0)
+# define SEM_INCOMPLETE_INT_ENABLE (1 << 1)
+# define SEM_WAIT_INT_ENABLE (1 << 2)
+# define DATA_SWAP_ENABLE (1 << 3)
+# define FENCE_SWAP_ENABLE (1 << 4)
+# define CTXEMPTY_INT_ENABLE (1 << 28)
+#define DMA_STATUS_REG 0xd034
+# define DMA_IDLE (1 << 0)
+#define DMA_SEM_INCOMPLETE_TIMER_CNTL 0xd044
+#define DMA_SEM_WAIT_FAIL_TIMER_CNTL 0xd048
+#define DMA_MODE 0xd0bc
+
+/* async DMA packets */
+#define DMA_PACKET(cmd, t, s, n) ((((cmd) & 0xF) << 28) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((n) & 0xFFFF) << 0))
+/* async DMA Packet types */
+#define DMA_PACKET_WRITE 0x2
+#define DMA_PACKET_COPY 0x3
+#define DMA_PACKET_INDIRECT_BUFFER 0x4
+#define DMA_PACKET_SEMAPHORE 0x5
+#define DMA_PACKET_FENCE 0x6
+#define DMA_PACKET_TRAP 0x7
+#define DMA_PACKET_CONSTANT_FILL 0xd /* 7xx only */
+#define DMA_PACKET_NOP 0xf
+
+#define IH_RB_CNTL 0x3e00
+# define IH_RB_ENABLE (1 << 0)
+# define IH_RB_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_GPU_CLOCK_COUNT_LSB 0x3f38
+#define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c
+#define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40
+#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_DMA (1 << 12)
+# define SOFT_RESET_RLC (1 << 13)
+# define RV770_SOFT_RESET_DMA (1 << 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 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)
+
+/* Audio clocks */
+#define DCCG_AUDIO_DTO0_PHASE 0x0514
+#define DCCG_AUDIO_DTO0_MODULE 0x0518
+#define DCCG_AUDIO_DTO0_LOAD 0x051c
+# define DTO_LOAD (1 << 31)
+#define DCCG_AUDIO_DTO0_CNTL 0x0520
+
+#define DCCG_AUDIO_DTO1_PHASE 0x0524
+#define DCCG_AUDIO_DTO1_MODULE 0x0528
+#define DCCG_AUDIO_DTO1_LOAD 0x052c
+#define DCCG_AUDIO_DTO1_CNTL 0x0530
+
+#define DCCG_AUDIO_DTO_SELECT 0x0534
+
+/* digital blocks */
+#define TMDSA_CNTL 0x7880
+# define TMDSA_HDMI_EN (1 << 2)
+#define LVTMA_CNTL 0x7a80
+# define LVTMA_HDMI_EN (1 << 2)
+#define DDIA_CNTL 0x7200
+# define DDIA_HDMI_EN (1 << 2)
+#define DIG0_CNTL 0x75a0
+# define DIG_MODE(x) (((x) & 7) << 8)
+# define DIG_MODE_DP 0
+# define DIG_MODE_LVDS 1
+# define DIG_MODE_TMDS_DVI 2
+# define DIG_MODE_TMDS_HDMI 3
+# define DIG_MODE_SDVO 4
+#define DIG1_CNTL 0x79a0
+
+/* rs6xx/rs740 and r6xx share the same HDMI blocks, however, rs6xx has only one
+ * instance of the blocks while r6xx has 2. DCE 3.0 cards are slightly
+ * different due to the new DIG blocks, but also have 2 instances.
+ * DCE 3.0 HDMI blocks are part of each DIG encoder.
+ */
+
+/* rs6xx/rs740/r6xx/dce3 */
+#define HDMI0_CONTROL 0x7400
+/* rs6xx/rs740/r6xx */
+# define HDMI0_ENABLE (1 << 0)
+# define HDMI0_STREAM(x) (((x) & 3) << 2)
+# define HDMI0_STREAM_TMDSA 0
+# define HDMI0_STREAM_LVTMA 1
+# define HDMI0_STREAM_DVOA 2
+# define HDMI0_STREAM_DDIA 3
+/* rs6xx/r6xx/dce3 */
+# define HDMI0_ERROR_ACK (1 << 8)
+# define HDMI0_ERROR_MASK (1 << 9)
+#define HDMI0_STATUS 0x7404
+# define HDMI0_ACTIVE_AVMUTE (1 << 0)
+# define HDMI0_AUDIO_ENABLE (1 << 4)
+# define HDMI0_AZ_FORMAT_WTRIG (1 << 28)
+# define HDMI0_AZ_FORMAT_WTRIG_INT (1 << 29)
+#define HDMI0_AUDIO_PACKET_CONTROL 0x7408
+# define HDMI0_AUDIO_SAMPLE_SEND (1 << 0)
+# define HDMI0_AUDIO_DELAY_EN(x) (((x) & 3) << 4)
+# define HDMI0_AUDIO_SEND_MAX_PACKETS (1 << 8)
+# define HDMI0_AUDIO_TEST_EN (1 << 12)
+# define HDMI0_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16)
+# define HDMI0_AUDIO_CHANNEL_SWAP (1 << 24)
+# define HDMI0_60958_CS_UPDATE (1 << 26)
+# define HDMI0_AZ_FORMAT_WTRIG_MASK (1 << 28)
+# define HDMI0_AZ_FORMAT_WTRIG_ACK (1 << 29)
+#define HDMI0_AUDIO_CRC_CONTROL 0x740c
+# define HDMI0_AUDIO_CRC_EN (1 << 0)
+#define HDMI0_VBI_PACKET_CONTROL 0x7410
+# define HDMI0_NULL_SEND (1 << 0)
+# define HDMI0_GC_SEND (1 << 4)
+# define HDMI0_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */
+#define HDMI0_INFOFRAME_CONTROL0 0x7414
+# define HDMI0_AVI_INFO_SEND (1 << 0)
+# define HDMI0_AVI_INFO_CONT (1 << 1)
+# define HDMI0_AUDIO_INFO_SEND (1 << 4)
+# define HDMI0_AUDIO_INFO_CONT (1 << 5)
+# define HDMI0_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - hmdi regs */
+# define HDMI0_AUDIO_INFO_UPDATE (1 << 7)
+# define HDMI0_MPEG_INFO_SEND (1 << 8)
+# define HDMI0_MPEG_INFO_CONT (1 << 9)
+# define HDMI0_MPEG_INFO_UPDATE (1 << 10)
+#define HDMI0_INFOFRAME_CONTROL1 0x7418
+# define HDMI0_AVI_INFO_LINE(x) (((x) & 0x3f) << 0)
+# define HDMI0_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8)
+# define HDMI0_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16)
+#define HDMI0_GENERIC_PACKET_CONTROL 0x741c
+# define HDMI0_GENERIC0_SEND (1 << 0)
+# define HDMI0_GENERIC0_CONT (1 << 1)
+# define HDMI0_GENERIC0_UPDATE (1 << 2)
+# define HDMI0_GENERIC1_SEND (1 << 4)
+# define HDMI0_GENERIC1_CONT (1 << 5)
+# define HDMI0_GENERIC0_LINE(x) (((x) & 0x3f) << 16)
+# define HDMI0_GENERIC1_LINE(x) (((x) & 0x3f) << 24)
+#define HDMI0_GC 0x7428
+# define HDMI0_GC_AVMUTE (1 << 0)
+#define HDMI0_AVI_INFO0 0x7454
+# define HDMI0_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define HDMI0_AVI_INFO_S(x) (((x) & 3) << 8)
+# define HDMI0_AVI_INFO_B(x) (((x) & 3) << 10)
+# define HDMI0_AVI_INFO_A(x) (((x) & 1) << 12)
+# define HDMI0_AVI_INFO_Y(x) (((x) & 3) << 13)
+# define HDMI0_AVI_INFO_Y_RGB 0
+# define HDMI0_AVI_INFO_Y_YCBCR422 1
+# define HDMI0_AVI_INFO_Y_YCBCR444 2
+# define HDMI0_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8)
+# define HDMI0_AVI_INFO_R(x) (((x) & 0xf) << 16)
+# define HDMI0_AVI_INFO_M(x) (((x) & 0x3) << 20)
+# define HDMI0_AVI_INFO_C(x) (((x) & 0x3) << 22)
+# define HDMI0_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16)
+# define HDMI0_AVI_INFO_SC(x) (((x) & 0x3) << 24)
+# define HDMI0_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24)
+#define HDMI0_AVI_INFO1 0x7458
+# define HDMI0_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */
+# define HDMI0_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */
+# define HDMI0_AVI_INFO_TOP(x) (((x) & 0xffff) << 16)
+#define HDMI0_AVI_INFO2 0x745c
+# define HDMI0_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0)
+# define HDMI0_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16)
+#define HDMI0_AVI_INFO3 0x7460
+# define HDMI0_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0)
+# define HDMI0_AVI_INFO_VERSION(x) (((x) & 3) << 24)
+#define HDMI0_MPEG_INFO0 0x7464
+# define HDMI0_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define HDMI0_MPEG_INFO_MB0(x) (((x) & 0xff) << 8)
+# define HDMI0_MPEG_INFO_MB1(x) (((x) & 0xff) << 16)
+# define HDMI0_MPEG_INFO_MB2(x) (((x) & 0xff) << 24)
+#define HDMI0_MPEG_INFO1 0x7468
+# define HDMI0_MPEG_INFO_MB3(x) (((x) & 0xff) << 0)
+# define HDMI0_MPEG_INFO_MF(x) (((x) & 3) << 8)
+# define HDMI0_MPEG_INFO_FR(x) (((x) & 1) << 12)
+#define HDMI0_GENERIC0_HDR 0x746c
+#define HDMI0_GENERIC0_0 0x7470
+#define HDMI0_GENERIC0_1 0x7474
+#define HDMI0_GENERIC0_2 0x7478
+#define HDMI0_GENERIC0_3 0x747c
+#define HDMI0_GENERIC0_4 0x7480
+#define HDMI0_GENERIC0_5 0x7484
+#define HDMI0_GENERIC0_6 0x7488
+#define HDMI0_GENERIC1_HDR 0x748c
+#define HDMI0_GENERIC1_0 0x7490
+#define HDMI0_GENERIC1_1 0x7494
+#define HDMI0_GENERIC1_2 0x7498
+#define HDMI0_GENERIC1_3 0x749c
+#define HDMI0_GENERIC1_4 0x74a0
+#define HDMI0_GENERIC1_5 0x74a4
+#define HDMI0_GENERIC1_6 0x74a8
+#define HDMI0_ACR_32_0 0x74ac
+# define HDMI0_ACR_CTS_32(x) (((x) & 0xfffff) << 12)
+#define HDMI0_ACR_32_1 0x74b0
+# define HDMI0_ACR_N_32(x) (((x) & 0xfffff) << 0)
+#define HDMI0_ACR_44_0 0x74b4
+# define HDMI0_ACR_CTS_44(x) (((x) & 0xfffff) << 12)
+#define HDMI0_ACR_44_1 0x74b8
+# define HDMI0_ACR_N_44(x) (((x) & 0xfffff) << 0)
+#define HDMI0_ACR_48_0 0x74bc
+# define HDMI0_ACR_CTS_48(x) (((x) & 0xfffff) << 12)
+#define HDMI0_ACR_48_1 0x74c0
+# define HDMI0_ACR_N_48(x) (((x) & 0xfffff) << 0)
+#define HDMI0_ACR_STATUS_0 0x74c4
+#define HDMI0_ACR_STATUS_1 0x74c8
+#define HDMI0_AUDIO_INFO0 0x74cc
+# define HDMI0_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define HDMI0_AUDIO_INFO_CC(x) (((x) & 7) << 8)
+#define HDMI0_AUDIO_INFO1 0x74d0
+# define HDMI0_AUDIO_INFO_CA(x) (((x) & 0xff) << 0)
+# define HDMI0_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11)
+# define HDMI0_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15)
+# define HDMI0_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8)
+#define HDMI0_60958_0 0x74d4
+# define HDMI0_60958_CS_A(x) (((x) & 1) << 0)
+# define HDMI0_60958_CS_B(x) (((x) & 1) << 1)
+# define HDMI0_60958_CS_C(x) (((x) & 1) << 2)
+# define HDMI0_60958_CS_D(x) (((x) & 3) << 3)
+# define HDMI0_60958_CS_MODE(x) (((x) & 3) << 6)
+# define HDMI0_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8)
+# define HDMI0_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20)
+# define HDMI0_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24)
+# define HDMI0_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28)
+#define HDMI0_60958_1 0x74d8
+# define HDMI0_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0)
+# define HDMI0_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4)
+# define HDMI0_60958_CS_VALID_L(x) (((x) & 1) << 16)
+# define HDMI0_60958_CS_VALID_R(x) (((x) & 1) << 18)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20)
+#define HDMI0_ACR_PACKET_CONTROL 0x74dc
+# define HDMI0_ACR_SEND (1 << 0)
+# define HDMI0_ACR_CONT (1 << 1)
+# define HDMI0_ACR_SELECT(x) (((x) & 3) << 4)
+# define HDMI0_ACR_HW 0
+# define HDMI0_ACR_32 1
+# define HDMI0_ACR_44 2
+# define HDMI0_ACR_48 3
+# define HDMI0_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */
+# define HDMI0_ACR_AUTO_SEND (1 << 12)
+#define HDMI0_RAMP_CONTROL0 0x74e0
+# define HDMI0_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0)
+#define HDMI0_RAMP_CONTROL1 0x74e4
+# define HDMI0_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0)
+#define HDMI0_RAMP_CONTROL2 0x74e8
+# define HDMI0_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0)
+#define HDMI0_RAMP_CONTROL3 0x74ec
+# define HDMI0_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0)
+/* HDMI0_60958_2 is r7xx only */
+#define HDMI0_60958_2 0x74f0
+# define HDMI0_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16)
+# define HDMI0_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20)
+/* r6xx only; second instance starts at 0x7700 */
+#define HDMI1_CONTROL 0x7700
+#define HDMI1_STATUS 0x7704
+#define HDMI1_AUDIO_PACKET_CONTROL 0x7708
+/* DCE3; second instance starts at 0x7800 NOT 0x7700 */
+#define DCE3_HDMI1_CONTROL 0x7800
+#define DCE3_HDMI1_STATUS 0x7804
+#define DCE3_HDMI1_AUDIO_PACKET_CONTROL 0x7808
+/* DCE3.2 (for interrupts) */
+#define AFMT_STATUS 0x7600
+# define AFMT_AUDIO_ENABLE (1 << 4)
+# define AFMT_AZ_FORMAT_WTRIG (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30)
+#define AFMT_AUDIO_PACKET_CONTROL 0x7604
+# define AFMT_AUDIO_SAMPLE_SEND (1 << 0)
+# define AFMT_AUDIO_TEST_EN (1 << 12)
+# define AFMT_AUDIO_CHANNEL_SWAP (1 << 24)
+# define AFMT_60958_CS_UPDATE (1 << 26)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27)
+# define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30)
+
+/*
+ * 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_CP_DMA 0x41
+/* 1. header
+ * 2. SRC_ADDR_LO [31:0]
+ * 3. CP_SYNC [31] | SRC_ADDR_HI [7:0]
+ * 4. DST_ADDR_LO [31:0]
+ * 5. DST_ADDR_HI [7:0]
+ * 6. COMMAND [29:22] | BYTE_COUNT [20:0]
+ */
+# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
+/* COMMAND */
+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
+# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
+#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_STRMOUT_BASE_UPDATE 0x72 /* r7xx */
+#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 V_0280A0_TILE_DISABLE 0
+#define V_0280A0_CLEAR_ENABLE 1
+#define V_0280A0_FRAG_ENABLE 2
+#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/sys/dev/drm2/radeon/radeon.h b/sys/dev/drm2/radeon/radeon.h
new file mode 100644
index 0000000..88a5c5a
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon.h
@@ -0,0 +1,2050 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+
+#include <dev/drm2/ttm/ttm_bo_api.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_execbuf_util.h>
+
+#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;
+extern int radeon_lockup_timeout;
+
+/*
+ * 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 (DRM_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 5
+
+/* fence seq are set to this number when signaled */
+#define RADEON_FENCE_SIGNALED_SEQ 0LL
+
+/* 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
+
+/* R600+ has an async dma ring */
+#define R600_RING_TYPE_DMA_INDEX 3
+/* cayman add a second async dma ring */
+#define CAYMAN_RING_TYPE_DMA1_INDEX 4
+
+/* hardcode those limit for now */
+#define RADEON_VA_IB_OFFSET (1 << 20)
+#define RADEON_VA_RESERVED_SIZE (8 << 20)
+#define RADEON_IB_VM_MAX_SIZE (64 << 10)
+
+/* reset flags */
+#define RADEON_RESET_GFX (1 << 0)
+#define RADEON_RESET_COMPUTE (1 << 1)
+#define RADEON_RESET_DMA (1 << 2)
+
+/*
+ * 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.
+ */
+bool radeon_get_bios(struct radeon_device *rdev);
+
+/*
+ * Dummy page
+ */
+struct radeon_dummy_page {
+ drm_dma_handle_t *dmah;
+ 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;
+ /* sync_seq is protected by ring emission lock */
+ uint64_t sync_seq[RADEON_NUM_RINGS];
+ atomic64_t last_seq;
+ unsigned long last_activity;
+ bool initialized;
+};
+
+struct radeon_fence {
+ struct radeon_device *rdev;
+ unsigned int kref;
+ /* protected by radeon_fence.lock */
+ uint64_t seq;
+ /* RB, DMA, etc. */
+ unsigned ring;
+};
+
+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);
+void radeon_fence_driver_force_completion(struct radeon_device *rdev);
+int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring);
+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_locked(struct radeon_device *rdev, int ring);
+int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
+int radeon_fence_wait_any(struct radeon_device *rdev,
+ struct radeon_fence **fences,
+ bool intr);
+struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
+void radeon_fence_unref(struct radeon_fence **fence);
+unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring);
+bool radeon_fence_need_sync(struct radeon_fence *fence, int ring);
+void radeon_fence_note_sync(struct radeon_fence *fence, int ring);
+static inline struct radeon_fence *radeon_fence_later(struct radeon_fence *a,
+ struct radeon_fence *b)
+{
+ if (!a) {
+ return b;
+ }
+
+ if (!b) {
+ return a;
+ }
+
+ KASSERT(a->ring == b->ring, ("\"a\" and \"b\" belongs to different rings"));
+
+ if (a->seq > b->seq) {
+ return a;
+ } else {
+ return b;
+ }
+}
+
+static inline bool radeon_fence_is_earlier(struct radeon_fence *a,
+ struct radeon_fence *b)
+{
+ if (!a) {
+ return false;
+ }
+
+ if (!b) {
+ return true;
+ }
+
+ KASSERT(a->ring == b->ring, ("\"a\" and \"b\" belongs to different rings"));
+
+ return a->seq < b->seq;
+}
+
+/*
+ * 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 {
+ /* protected by bo being reserved */
+ struct list_head bo_list;
+ uint64_t soffset;
+ uint64_t eoffset;
+ uint32_t flags;
+ bool valid;
+ unsigned ref_count;
+
+ /* protected by vm mutex */
+ struct list_head vm_list;
+
+ /* constant after initialization */
+ struct radeon_vm *vm;
+ struct radeon_bo *bo;
+};
+
+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;
+
+ struct ttm_bo_kmap_obj dma_buf_vmap;
+ int vmapping_count;
+};
+#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 cv wq;
+ struct sx wq_lock;
+ struct radeon_bo *bo;
+ struct list_head *hole;
+ struct list_head flist[RADEON_NUM_RINGS];
+ struct list_head olist;
+ 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 olist;
+ struct list_head flist;
+ struct radeon_sa_manager *manager;
+ unsigned soffset;
+ unsigned eoffset;
+ struct radeon_fence *fence;
+};
+
+/*
+ * GEM objects.
+ */
+struct radeon_gem {
+ struct sx 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.
+ */
+/* everything here is constant */
+struct radeon_semaphore {
+ struct radeon_sa_bo *sa_bo;
+ signed waiters;
+ uint64_t gpu_addr;
+};
+
+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);
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+ struct radeon_semaphore *semaphore,
+ int signaler, int waiter);
+void radeon_semaphore_free(struct radeon_device *rdev,
+ struct radeon_semaphore **semaphore,
+ struct radeon_fence *fence);
+
+/*
+ * 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 {
+ drm_dma_handle_t *dmah;
+ dma_addr_t table_addr;
+ struct radeon_bo *robj;
+ void *ptr;
+ unsigned num_gpu_pages;
+ unsigned num_cpu_pages;
+ unsigned table_size;
+ vm_page_t *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, vm_page_t *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 task 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;
+ u32 hdmi0_status;
+};
+
+struct r600_irq_stat_regs {
+ u32 disp_int;
+ u32 disp_int_cont;
+ u32 disp_int_cont2;
+ u32 d1grph_int;
+ u32 d2grph_int;
+ u32 hdmi0_status;
+ u32 hdmi1_status;
+};
+
+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;
+ u32 afmt_status1;
+ u32 afmt_status2;
+ u32 afmt_status3;
+ u32 afmt_status4;
+ u32 afmt_status5;
+ u32 afmt_status6;
+};
+
+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_AFMT_BLOCKS 6
+
+struct radeon_irq {
+ bool installed;
+ struct mtx lock;
+ atomic_t ring_int[RADEON_NUM_RINGS];
+ bool crtc_vblank_int[RADEON_MAX_CRTCS];
+ atomic_t pflip[RADEON_MAX_CRTCS];
+ wait_queue_head_t vblank_queue;
+ bool hpd[RADEON_MAX_HPD_PINS];
+ bool afmt[RADEON_MAX_AFMT_BLOCKS];
+ union radeon_irq_stat_regs stat_regs;
+};
+
+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);
+void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block);
+void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block);
+void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask);
+void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask);
+
+/*
+ * CP & rings.
+ */
+
+struct radeon_ib {
+ struct radeon_sa_bo *sa_bo;
+ uint32_t length_dw;
+ uint64_t gpu_addr;
+ uint32_t *ptr;
+ int ring;
+ struct radeon_fence *fence;
+ struct radeon_vm *vm;
+ bool is_const_ib;
+ struct radeon_fence *sync_to[RADEON_NUM_RINGS];
+ struct radeon_semaphore *semaphore;
+};
+
+struct radeon_ring {
+ struct radeon_bo *ring_obj;
+ volatile uint32_t *ring;
+ unsigned rptr;
+ unsigned rptr_offs;
+ unsigned rptr_reg;
+ unsigned rptr_save_reg;
+ u64 next_rptr_gpu_addr;
+ volatile u32 *next_rptr_cpu_addr;
+ unsigned wptr;
+ unsigned wptr_old;
+ unsigned wptr_reg;
+ unsigned ring_size;
+ unsigned ring_free_dw;
+ int count_dw;
+ unsigned long last_activity;
+ unsigned last_rptr;
+ uint64_t gpu_addr;
+ uint32_t align_mask;
+ uint32_t ptr_mask;
+ bool ready;
+ u32 ptr_reg_shift;
+ u32 ptr_reg_mask;
+ u32 nop;
+ u32 idx;
+ u64 last_semaphore_signal_addr;
+ u64 last_semaphore_wait_addr;
+};
+
+/*
+ * VM
+ */
+
+/* maximum number of VMIDs */
+#define RADEON_NUM_VM 16
+
+/* defines number of bits in page table versus page directory,
+ * a page is 4KB so we have 12 bits offset, 9 bits in the page
+ * table and the remaining 19 bits are in the page directory */
+#define RADEON_VM_BLOCK_SIZE 9
+
+/* number of entries in page table */
+#define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE)
+
+struct radeon_vm {
+ struct list_head list;
+ struct list_head va;
+ unsigned id;
+
+ /* contains the page directory */
+ struct radeon_sa_bo *page_directory;
+ uint64_t pd_gpu_addr;
+
+ /* array of page tables, one for each page directory entry */
+ struct radeon_sa_bo **page_tables;
+
+ struct sx mutex;
+ /* last fence for cs using this vm */
+ struct radeon_fence *fence;
+ /* last flush or NULL if we still need to flush */
+ struct radeon_fence *last_flush;
+};
+
+struct radeon_vm_manager {
+ struct sx lock;
+ struct list_head lru_vm;
+ struct radeon_fence *active[RADEON_NUM_VM];
+ struct radeon_sa_manager sa_manager;
+ uint32_t max_pfn;
+ /* 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 ring_size;
+ uint64_t gpu_addr;
+ uint32_t ptr_mask;
+ atomic_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 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;
+};
+
+/*
+ * 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, struct radeon_vm *vm,
+ unsigned size);
+void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib);
+int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
+ struct radeon_ib *const_ib);
+int radeon_ib_pool_init(struct radeon_device *rdev);
+void radeon_ib_pool_fini(struct radeon_device *rdev);
+int radeon_ib_ring_tests(struct radeon_device *rdev);
+/* Ring access between begin & end cannot sleep */
+bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
+ struct radeon_ring *ring);
+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_undo(struct radeon_ring *ring);
+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);
+void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring);
+void radeon_ring_lockup_update(struct radeon_ring *ring);
+bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring,
+ uint32_t **data);
+int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
+ unsigned size, uint32_t *data);
+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);
+
+
+/* r600 async dma */
+void r600_dma_stop(struct radeon_device *rdev);
+int r600_dma_resume(struct radeon_device *rdev);
+void r600_dma_fini(struct radeon_device *rdev);
+
+void cayman_dma_stop(struct radeon_device *rdev);
+int cayman_dma_resume(struct radeon_device *rdev);
+void cayman_dma_fini(struct radeon_device *rdev);
+
+/*
+ * 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 {
+ device_t 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;
+ unsigned dma_reloc_idx;
+ /* 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_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_RING0_NEXT_RPTR 256
+#define RADEON_WB_CP_RPTR_OFFSET 1024
+#define RADEON_WB_CP1_RPTR_OFFSET 1280
+#define RADEON_WB_CP2_RPTR_OFFSET 1536
+#define R600_WB_DMA_RPTR_OFFSET 1792
+#define R600_WB_IH_WPTR_OFFSET 2048
+#define CAYMAN_WB_DMA1_RPTR_OFFSET 2304
+#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 sx mutex;
+ /* write locked while reprogramming mclk */
+ struct sx mclk_lock;
+ u32 active_crtcs;
+ int active_crtc_count;
+ int req_vblank;
+ bool vblank_sync;
+ 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 */
+#ifdef DUMBBELL_WIP
+ struct delayed_work dynpm_idle_work;
+#endif /* DUMBBELL_WIP */
+ 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;
+#ifdef DUMBBELL_WIP
+ struct device *int_hwmon_dev;
+#endif /* DUMBBELL_WIP */
+};
+
+int radeon_pm_get_type_index(struct radeon_device *rdev,
+ enum radeon_pm_state_type ps_type,
+ int instance);
+
+struct r600_audio {
+ int channels;
+ int rate;
+ int bits_per_sample;
+ u8 status_bits;
+ u8 category_code;
+};
+
+/*
+ * 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);
+ 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;
+ struct {
+ int (*init)(struct radeon_device *rdev);
+ void (*fini)(struct radeon_device *rdev);
+
+ u32 pt_ring_index;
+ void (*set_page)(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+ } vm;
+ /* 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);
+ bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp);
+ void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+ } ring[RADEON_NUM_RINGS];
+ /* irqs */
+ struct {
+ int (*set)(struct radeon_device *rdev);
+ irqreturn_t (*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);
+ /* set backlight level */
+ void (*set_backlight_level)(struct radeon_encoder *radeon_encoder, u8 level);
+ /* get backlight level */
+ u8 (*get_backlight_level)(struct radeon_encoder *radeon_encoder);
+ } 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_asic {
+ const unsigned *reg_safe_bm;
+ unsigned reg_safe_bm_size;
+ u32 hdp_cntl;
+};
+
+struct r300_asic {
+ const unsigned *reg_safe_bm;
+ unsigned reg_safe_bm_size;
+ u32 resync_scratch;
+ u32 hdp_cntl;
+};
+
+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 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 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 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 si_asic {
+ unsigned max_shader_engines;
+ unsigned max_tile_pipes;
+ unsigned max_cu_per_sh;
+ unsigned max_sh_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_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;
+};
+
+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
+ */
+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;
+};
+
+/*
+ * ACPI
+ */
+struct radeon_atif_notification_cfg {
+ bool enabled;
+ int command_code;
+};
+
+struct radeon_atif_notifications {
+ bool display_switch;
+ bool expansion_mode_change;
+ bool thermal_state;
+ bool forced_power_state;
+ bool system_power_state;
+ bool display_conf_change;
+ bool px_gfx_switch;
+ bool brightness_change;
+ bool dgpu_display_event;
+};
+
+struct radeon_atif_functions {
+ bool system_params;
+ bool sbios_requests;
+ bool select_active_disp;
+ bool lid_state;
+ bool get_tv_standard;
+ bool set_tv_standard;
+ bool get_panel_expansion_mode;
+ bool set_panel_expansion_mode;
+ bool temperature_change;
+ bool graphics_device_types;
+};
+
+struct radeon_atif {
+ struct radeon_atif_notifications notifications;
+ struct radeon_atif_functions functions;
+ struct radeon_atif_notification_cfg notification_cfg;
+ struct radeon_encoder *encoder_for_bl;
+};
+
+struct radeon_atcs_functions {
+ bool get_ext_state;
+ bool pcie_perf_req;
+ bool pcie_dev_rdy;
+ bool pcie_bus_width;
+};
+
+struct radeon_atcs {
+ struct radeon_atcs_functions functions;
+};
+
+/*
+ * 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 {
+ device_t dev;
+ struct drm_device *ddev;
+ struct sx exclusive_lock;
+ /* 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;
+ /* protects concurrent MM_INDEX/DATA based register access */
+ struct mtx mmio_idx_lock;
+ int rmmio_rid;
+ struct resource *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 */
+ int rio_rid;
+ struct resource *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;
+ struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
+ struct cv fence_queue;
+ struct mtx fence_queue_mtx;
+ struct sx ring_lock;
+ struct radeon_ring ring[RADEON_NUM_RINGS];
+ bool ib_pool_ready;
+ struct radeon_sa_manager ring_tmp_bo;
+ 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_wb wb;
+ struct radeon_dummy_page dummy_page;
+ bool shutdown;
+ bool suspend;
+ bool need_dma32;
+ bool accel_working;
+ bool fictitious_range_registered;
+ 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 taskqueue *tq;
+ struct task hotplug_work;
+ struct task audio_work;
+ int num_crtc; /* number of crtcs */
+ struct sx dc_hw_i2c_mutex; /* display controller hw i2c mutex */
+ bool audio_enabled;
+ struct r600_audio audio_status; /* audio stuff */
+ struct {
+ ACPI_HANDLE handle;
+ ACPI_NOTIFY_HANDLER notifier_call;
+ } acpi;
+ /* 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;
+ struct sx gpu_clock_mutex;
+ /* ACPI interface */
+ struct radeon_atif atif;
+ struct radeon_atcs atcs;
+};
+
+int radeon_device_init(struct radeon_device *rdev,
+ struct drm_device *ddev,
+ 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,
+ bool always_indirect);
+void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
+ bool always_indirect);
+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) bus_read_1((rdev->rmmio), (reg))
+#define WREG8(reg, v) bus_write_1((rdev->rmmio), (reg), v)
+#define RREG16(reg) bus_read_2((rdev->rmmio), (reg))
+#define WREG16(reg, v) bus_write_2((rdev->rmmio), (reg), v)
+#define RREG32(reg) r100_mm_rreg(rdev, (reg), false)
+#define RREG32_IDX(reg) r100_mm_rreg(rdev, (reg), true)
+#define DREG32(reg) DRM_INFO("REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg)))
+#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v), false)
+#define WREG32_IDX(reg, v) r100_mm_wreg(rdev, (reg), (v), true)
+#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), false))
+#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->ddev->pci_device == 0x515e) || \
+ (rdev->ddev->pci_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->pci_device == 0x9441) || \
+ (rdev->ddev->pci_device == 0x9443) || \
+ (rdev->ddev->pci_device == 0x944B) || \
+ (rdev->ddev->pci_device == 0x9506) || \
+ (rdev->ddev->pci_device == 0x9509) || \
+ (rdev->ddev->pci_device == 0x950F) || \
+ (rdev->ddev->pci_device == 0x689C) || \
+ (rdev->ddev->pci_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 !defined(DRM_DEBUG_CODE) || 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_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_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
+#define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
+#define radeon_asic_vm_set_page(rdev, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (pe), (addr), (count), (incr), (flags)))
+#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_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
+#define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm))
+#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_set_backlight_level(rdev, e, l) (rdev)->asic->display.set_backlight_level((e), (l))
+#define radeon_get_backlight_level(rdev, e) (rdev)->asic->display.get_backlight_level((e))
+#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_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);
+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);
+void 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_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm);
+void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm);
+struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
+ struct radeon_vm *vm, int ring);
+void radeon_vm_fence(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_fence *fence);
+uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
+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);
+struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
+ struct radeon_bo *bo);
+struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo);
+int radeon_vm_bo_set_addr(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va,
+ uint64_t offset,
+ uint32_t flags);
+int radeon_vm_bo_rmv(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va);
+
+/* audio */
+void r600_audio_update_hdmi(void *arg, int pending);
+
+/*
+ * 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
+ */
+struct radeon_hdmi_acr {
+ u32 clock;
+
+ int n_32khz;
+ int cts_32khz;
+
+ int n_44_1khz;
+ int cts_44_1khz;
+
+ int n_48khz;
+ int cts_48khz;
+
+};
+
+extern struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock);
+
+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 u32 r6xx_remap_render_backend(struct radeon_device *rdev,
+ u32 tiling_pipe_num,
+ u32 max_rb_num,
+ u32 total_max_rb_num,
+ u32 enabled_rb_mask);
+
+/*
+ * evergreen functions used by radeon_encoder.c
+ */
+
+extern void evergreen_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);
+extern void ni_fini_microcode(struct radeon_device *rdev);
+
+/* radeon_acpi.c */
+extern int radeon_acpi_init(struct radeon_device *rdev);
+extern void radeon_acpi_fini(struct radeon_device *rdev);
+
+/* Prototypes added by @dumbbell. */
+
+/* atombios_encoders.c */
+void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector);
+void radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
+ uint32_t supported_device, u16 caps);
+
+/* radeon_atombios.c */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+ struct drm_display_mode *mode);
+
+/* radeon_combios.c */
+void radeon_combios_connected_scratch_regs(struct drm_connector *connector,
+ struct drm_encoder *encoder, bool connected);
+
+/* radeon_connectors.c */
+void radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
+ struct drm_encoder *encoder, bool connected);
+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);
+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);
+
+/* radeon_encoders.c */
+uint32_t radeon_get_encoder_enum(struct drm_device *dev,
+ uint32_t supported_device, uint8_t dac);
+void radeon_link_encoder_connector(struct drm_device *dev);
+
+/* radeon_legacy_encoders.c */
+void radeon_add_legacy_encoder(struct drm_device *dev,
+ uint32_t encoder_enum, uint32_t supported_device);
+void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
+ struct drm_connector *drm_connector);
+
+/* radeon_pm.c */
+void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
+
+/* radeon_ttm.c */
+int radeon_ttm_init(struct radeon_device *rdev);
+void radeon_ttm_fini(struct radeon_device *rdev);
+
+/* r600.c */
+int r600_ih_ring_alloc(struct radeon_device *rdev);
+void r600_ih_ring_fini(struct radeon_device *rdev);
+
+#include "radeon_object.h"
+
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_acpi.c b/sys/dev/drm2/radeon/radeon_acpi.c
new file mode 100644
index 0000000..176e160
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_acpi.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright 2012 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include "radeon.h"
+#include "radeon_acpi.h"
+#include "atom.h"
+
+#define ACPI_AC_CLASS "ac_adapter"
+
+struct atif_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 notification_mask; /* supported notifications mask */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
+struct atif_system_params {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 valid_mask; /* valid flags mask */
+ u32 flags; /* flags */
+ u8 command_code; /* notify command code */
+} __packed;
+
+struct atif_sbios_requests {
+ u16 size; /* structure size in bytes (includes size field) */
+ u32 pending; /* pending sbios requests */
+ u8 panel_exp_mode; /* panel expansion mode */
+ u8 thermal_gfx; /* thermal state: target gfx controller */
+ u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */
+ u8 forced_power_gfx; /* forced power state: target gfx controller */
+ u8 forced_power_state; /* forced power state: state id */
+ u8 system_power_src; /* system power source */
+ u8 backlight_level; /* panel backlight level (0-255) */
+} __packed;
+
+#define ATIF_NOTIFY_MASK 0x3
+#define ATIF_NOTIFY_NONE 0
+#define ATIF_NOTIFY_81 1
+#define ATIF_NOTIFY_N 2
+
+struct atcs_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
+/* Call the ATIF method
+ */
+/**
+ * radeon_atif_call - call an ATIF method
+ *
+ * @handle: acpi handle
+ * @function: the ATIF function to execute
+ * @params: ATIF function params
+ *
+ * Executes the requested ATIF function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+static ACPI_OBJECT *radeon_atif_call(ACPI_HANDLE handle, int function,
+ ACPI_BUFFER *params)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT atif_arg_elements[2];
+ ACPI_OBJECT_LIST atif_arg;
+ 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 = function;
+
+ if (params) {
+ atif_arg_elements[1].Type = ACPI_TYPE_BUFFER;
+ atif_arg_elements[1].Buffer.Length = params->Length;
+ atif_arg_elements[1].Buffer.Pointer = params->Pointer;
+ } else {
+ /* We need a second fake parameter */
+ atif_arg_elements[1].Type = ACPI_TYPE_INTEGER;
+ atif_arg_elements[1].Integer.Value = 0;
+ }
+
+ status = AcpiEvaluateObject(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",
+ AcpiFormatException(status));
+ AcpiOsFree(buffer.Pointer);
+ return NULL;
+ }
+
+ return buffer.Pointer;
+}
+
+/**
+ * radeon_atif_parse_notification - parse supported notifications
+ *
+ * @n: supported notifications struct
+ * @mask: supported notifications mask from ATIF
+ *
+ * Use the supported notifications mask from ATIF function
+ * ATIF_FUNCTION_VERIFY_INTERFACE to determine what notifications
+ * are supported (all asics).
+ */
+static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask)
+{
+ n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED;
+ n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED;
+ n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED;
+ n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED;
+ n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED;
+ n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED;
+ n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED;
+ n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED;
+}
+
+/**
+ * radeon_atif_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATIF
+ *
+ * Use the supported functions mask from ATIF function
+ * ATIF_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask)
+{
+ f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED;
+ f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED;
+ f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED;
+ f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED;
+ f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED;
+ f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED;
+ f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED;
+ f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED;
+ f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED;
+ f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED;
+}
+
+/**
+ * radeon_atif_verify_interface - verify ATIF
+ *
+ * @handle: acpi handle
+ * @atif: radeon atif struct
+ *
+ * Execute the ATIF_FUNCTION_VERIFY_INTERFACE ATIF function
+ * to initialize ATIF and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atif_verify_interface(ACPI_HANDLE handle,
+ struct radeon_atif *atif)
+{
+ ACPI_OBJECT *info;
+ struct atif_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->Buffer.Pointer;
+ if (size < 12) {
+ DRM_INFO("ATIF buffer is too small: %zu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->Buffer.Pointer, size);
+
+ /* TODO: check version? */
+ DRM_DEBUG_DRIVER("ATIF version %u\n", output.version);
+
+ radeon_atif_parse_notification(&atif->notifications, output.notification_mask);
+ radeon_atif_parse_functions(&atif->functions, output.function_bits);
+
+out:
+ AcpiOsFree(info);
+ return err;
+}
+
+/**
+ * radeon_atif_get_notification_params - determine notify configuration
+ *
+ * @handle: acpi handle
+ * @n: atif notification configuration struct
+ *
+ * Execute the ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ATIF function
+ * to determine if a notifier is used and if so which one
+ * (all asics). This is either Notify(VGA, 0x81) or Notify(VGA, n)
+ * where n is specified in the result if a notifier is used.
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atif_get_notification_params(ACPI_HANDLE handle,
+ struct radeon_atif_notification_cfg *n)
+{
+ ACPI_OBJECT *info;
+ struct atif_system_params params;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
+ if (!info) {
+ err = -EIO;
+ goto out;
+ }
+
+ size = *(u16 *) info->Buffer.Pointer;
+ if (size < 10) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ memset(&params, 0, sizeof(params));
+ size = min(sizeof(params), size);
+ memcpy(&params, info->Buffer.Pointer, size);
+
+ DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n",
+ params.flags, params.valid_mask);
+ params.flags = params.flags & params.valid_mask;
+
+ if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
+ n->enabled = false;
+ n->command_code = 0;
+ } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
+ n->enabled = true;
+ n->command_code = 0x81;
+ } else {
+ if (size < 11) {
+ err = -EINVAL;
+ goto out;
+ }
+ n->enabled = true;
+ n->command_code = params.command_code;
+ }
+
+out:
+ DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n",
+ (n->enabled ? "enabled" : "disabled"),
+ n->command_code);
+ AcpiOsFree(info);
+ return err;
+}
+
+/**
+ * radeon_atif_get_sbios_requests - get requested sbios event
+ *
+ * @handle: acpi handle
+ * @req: atif sbios request struct
+ *
+ * Execute the ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ATIF function
+ * to determine what requests the sbios is making to the driver
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atif_get_sbios_requests(ACPI_HANDLE handle,
+ struct atif_sbios_requests *req)
+{
+ ACPI_OBJECT *info;
+ size_t size;
+ int count = 0;
+
+ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL);
+ if (!info)
+ return -EIO;
+
+ size = *(u16 *)info->Buffer.Pointer;
+ if (size < 0xd) {
+ count = -EINVAL;
+ goto out;
+ }
+ memset(req, 0, sizeof(*req));
+
+ size = min(sizeof(*req), size);
+ memcpy(req, info->Buffer.Pointer, size);
+ DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending);
+
+ count = hweight32(req->pending);
+
+out:
+ AcpiOsFree(info);
+ return count;
+}
+
+/**
+ * radeon_atif_handler - handle ATIF notify requests
+ *
+ * @rdev: radeon_device pointer
+ * @event: atif sbios request struct
+ *
+ * Checks the acpi event and if it matches an atif event,
+ * handles it.
+ * Returns NOTIFY code
+ */
+void radeon_atif_handler(struct radeon_device *rdev,
+ UINT32 type)
+{
+ struct radeon_atif *atif = &rdev->atif;
+ struct atif_sbios_requests req;
+ ACPI_HANDLE handle;
+ int count;
+
+ DRM_DEBUG_DRIVER("event, type = %#x\n",
+ type);
+
+ if (!atif->notification_cfg.enabled ||
+ type != atif->notification_cfg.command_code)
+ /* Not our event */
+ return;
+
+ /* Check pending SBIOS requests */
+ handle = rdev->acpi.handle;
+ count = radeon_atif_get_sbios_requests(handle, &req);
+
+ if (count <= 0)
+ return;
+
+ DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
+
+ if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
+ struct radeon_encoder *enc = atif->encoder_for_bl;
+
+ if (enc) {
+ DRM_DEBUG_DRIVER("Changing brightness to %d\n",
+ req.backlight_level);
+
+ radeon_set_backlight_level(rdev, enc, req.backlight_level);
+
+#ifdef DUMBBELL_WIP
+ if (rdev->is_atom_bios) {
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+ backlight_force_update(dig->bl_dev,
+ BACKLIGHT_UPDATE_HOTKEY);
+ } else {
+ struct radeon_encoder_lvds *dig = enc->enc_priv;
+ backlight_force_update(dig->bl_dev,
+ BACKLIGHT_UPDATE_HOTKEY);
+ }
+#endif /* DUMBBELL_WIP */
+ }
+ }
+ /* TODO: check other events */
+
+ /* We've handled the event, stop the notifier chain. The ACPI interface
+ * overloads ACPI_VIDEO_NOTIFY_PROBE, we don't want to send that to
+ * userspace if the event was generated only to signal a SBIOS
+ * request.
+ */
+}
+
+/* Call the ATCS method
+ */
+/**
+ * radeon_atcs_call - call an ATCS method
+ *
+ * @handle: acpi handle
+ * @function: the ATCS function to execute
+ * @params: ATCS function params
+ *
+ * Executes the requested ATCS function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+static union acpi_object *radeon_atcs_call(ACPI_HANDLE handle, int function,
+ ACPI_BUFFER *params)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT atcs_arg_elements[2];
+ ACPI_OBJECT_LIST atcs_arg;
+ ACPI_BUFFER buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ atcs_arg.Count = 2;
+ atcs_arg.Pointer = &atcs_arg_elements[0];
+
+ atcs_arg_elements[0].Type = ACPI_TYPE_INTEGER;
+ atcs_arg_elements[0].Integer.Value = function;
+
+ if (params) {
+ atcs_arg_elements[1].Type = ACPI_TYPE_BUFFER;
+ atcs_arg_elements[1].Buffer.Length = params->Length;
+ atcs_arg_elements[1].Buffer.Pointer = params->Pointer;
+ } else {
+ /* We need a second fake parameter */
+ atcs_arg_elements[1].Type = ACPI_TYPE_INTEGER;
+ atcs_arg_elements[1].Integer.Value = 0;
+ }
+
+ status = AcpiEvaluateObject(handle, "ATCS", &atcs_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 ATCS got %s\n",
+ AcpiFormatException(status));
+ AcpiOsFree(buffer.Pointer);
+ return NULL;
+ }
+
+ return buffer.Pointer;
+}
+
+/**
+ * radeon_atcs_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATCS
+ *
+ * Use the supported functions mask from ATCS function
+ * ATCS_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atcs_parse_functions(struct radeon_atcs_functions *f, u32 mask)
+{
+ f->get_ext_state = mask & ATCS_GET_EXTERNAL_STATE_SUPPORTED;
+ f->pcie_perf_req = mask & ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED;
+ f->pcie_dev_rdy = mask & ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED;
+ f->pcie_bus_width = mask & ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED;
+}
+
+/**
+ * radeon_atcs_verify_interface - verify ATCS
+ *
+ * @handle: acpi handle
+ * @atcs: radeon atcs struct
+ *
+ * Execute the ATCS_FUNCTION_VERIFY_INTERFACE ATCS function
+ * to initialize ATCS and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atcs_verify_interface(ACPI_HANDLE handle,
+ struct radeon_atcs *atcs)
+{
+ ACPI_OBJECT *info;
+ struct atcs_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->Buffer.Pointer;
+ if (size < 8) {
+ DRM_INFO("ATCS buffer is too small: %zu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->Buffer.Pointer, size);
+
+ /* TODO: check version? */
+ DRM_DEBUG_DRIVER("ATCS version %u\n", output.version);
+
+ radeon_atcs_parse_functions(&atcs->functions, output.function_bits);
+
+out:
+ AcpiOsFree(info);
+ return err;
+}
+
+/**
+ * radeon_acpi_event - handle notify events
+ *
+ * @nb: notifier block
+ * @val: val
+ * @data: acpi event
+ *
+ * Calls relevant radeon functions in response to various
+ * acpi events.
+ * Returns NOTIFY code
+ */
+static void radeon_acpi_event(ACPI_HANDLE handle, UINT32 type,
+ void *context)
+{
+ struct radeon_device *rdev = (struct radeon_device *)context;
+
+#ifdef DUMBBELL_WIP
+ 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");
+
+ radeon_pm_acpi_event_handler(rdev);
+ }
+#endif /* DUMBBELL_WIP */
+
+ /* Check for pending SBIOS requests */
+ radeon_atif_handler(rdev, type);
+}
+
+/* Call all ACPI methods here */
+/**
+ * radeon_acpi_init - init driver acpi support
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Verifies the AMD ACPI interfaces and registers with the acpi
+ * notifier chain (all asics).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_acpi_init(struct radeon_device *rdev)
+{
+ ACPI_HANDLE handle;
+ struct radeon_atif *atif = &rdev->atif;
+ struct radeon_atcs *atcs = &rdev->atcs;
+ int ret;
+
+ /* Get the device handle */
+ handle = acpi_get_handle(rdev->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 ATCS method */
+ ret = radeon_atcs_verify_interface(handle, atcs);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
+ }
+
+ /* Call the ATIF method */
+ ret = radeon_atif_verify_interface(handle, atif);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
+ goto out;
+ }
+
+ if (atif->notifications.brightness_change) {
+ struct drm_encoder *tmp;
+ struct radeon_encoder *target = NULL;
+
+ /* Find the encoder controlling the brightness */
+ list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
+ head) {
+ struct radeon_encoder *enc = to_radeon_encoder(tmp);
+
+ if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
+ enc->enc_priv) {
+ if (rdev->is_atom_bios) {
+ struct radeon_encoder_atom_dig *dig = enc->enc_priv;
+ if (dig->bl_dev) {
+ target = enc;
+ break;
+ }
+ } else {
+ struct radeon_encoder_lvds *dig = enc->enc_priv;
+ if (dig->bl_dev) {
+ target = enc;
+ break;
+ }
+ }
+ }
+ }
+
+ atif->encoder_for_bl = target;
+ if (!target) {
+ /* Brightness change notification is enabled, but we
+ * didn't find a backlight controller, this should
+ * never happen.
+ */
+ DRM_ERROR("Cannot find a backlight controller\n");
+ }
+ }
+
+ if (atif->functions.sbios_requests && !atif->functions.system_params) {
+ /* XXX check this workraround, if sbios request function is
+ * present we have to see how it's configured in the system
+ * params
+ */
+ atif->functions.system_params = true;
+ }
+
+ if (atif->functions.system_params) {
+ ret = radeon_atif_get_notification_params(handle,
+ &atif->notification_cfg);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
+ ret);
+ /* Disable notification */
+ atif->notification_cfg.enabled = false;
+ }
+ }
+
+out:
+ rdev->acpi.handle = handle;
+ rdev->acpi.notifier_call = radeon_acpi_event;
+ AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
+ rdev->acpi.notifier_call, rdev);
+
+ return ret;
+}
+
+/**
+ * radeon_acpi_fini - tear down driver acpi support
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Unregisters with the acpi notifier chain (all asics).
+ */
+void radeon_acpi_fini(struct radeon_device *rdev)
+{
+ AcpiRemoveNotifyHandler(rdev->acpi.handle, ACPI_DEVICE_NOTIFY,
+ rdev->acpi.notifier_call);
+}
diff --git a/sys/dev/drm2/radeon/radeon_acpi.h b/sys/dev/drm2/radeon/radeon_acpi.h
new file mode 100644
index 0000000..300be6c
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_acpi.h
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2012 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef RADEON_ACPI_H
+#define RADEON_ACPI_H
+
+struct radeon_device;
+
+void radeon_atif_handler(struct radeon_device *rdev, UINT32 type);
+
+/* AMD hw uses four ACPI control methods:
+ * 1. ATIF
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATIF provides an entry point for the gfx driver to interact with the sbios.
+ * The AMD ACPI notification mechanism uses Notify (VGA, 0x81) or a custom
+ * notification. Which notification is used as indicated by the ATIF Control
+ * Method GET_SYSTEM_PARAMETERS. When the driver receives Notify (VGA, 0x81) or
+ * a custom notification it invokes ATIF Control Method GET_SYSTEM_BIOS_REQUESTS
+ * to identify pending System BIOS requests and associated parameters. For
+ * example, if one of the pending requests is DISPLAY_SWITCH_REQUEST, the driver
+ * will perform display device detection and invoke ATIF Control Method
+ * SELECT_ACTIVE_DISPLAYS.
+ *
+ * 2. ATPX
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATPX methods are used on PowerXpress systems to handle mux switching and
+ * discrete GPU power control.
+ *
+ * 3. ATRM
+ * ARG0: (ACPI_INTEGER) offset of vbios rom data
+ * ARG1: (ACPI_BUFFER) size of the buffer to fill (up to 4K).
+ * OUTPUT: (ACPI_BUFFER) output buffer
+ * ATRM provides an interfacess to access the discrete GPU vbios image on
+ * PowerXpress systems with multiple GPUs.
+ *
+ * 4. ATCS
+ * ARG0: (ACPI_INTEGER) function code
+ * ARG1: (ACPI_BUFFER) parameter buffer, 256 bytes
+ * OUTPUT: (ACPI_BUFFER) output buffer, 256 bytes
+ * ATCS provides an interface to AMD chipset specific functionality.
+ *
+ */
+/* ATIF */
+#define ATIF_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATIF_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported notifications mask
+ * DWORD - supported functions bit vector
+ */
+/* Notifications mask */
+# define ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED (1 << 0)
+# define ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED (1 << 1)
+# define ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED (1 << 2)
+# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED (1 << 3)
+# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED (1 << 4)
+# define ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED (1 << 5)
+# define ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED (1 << 6)
+# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED (1 << 7)
+# define ATIF_DGPU_DISPLAY_EVENT_SUPPORTED (1 << 8)
+/* supported functions vector */
+# define ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED (1 << 0)
+# define ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED (1 << 1)
+# define ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED (1 << 2)
+# define ATIF_GET_LID_STATE_SUPPORTED (1 << 3)
+# define ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED (1 << 4)
+# define ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED (1 << 5)
+# define ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED (1 << 6)
+# define ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED (1 << 7)
+# define ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED (1 << 12)
+# define ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED (1 << 14)
+#define ATIF_FUNCTION_GET_SYSTEM_PARAMETERS 0x1
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ *
+ * OR
+ *
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ * BYTE - notify command code
+ *
+ * flags
+ * bits 1:0:
+ * 0 - Notify(VGA, 0x81) is not used for notification
+ * 1 - Notify(VGA, 0x81) is used for notification
+ * 2 - Notify(VGA, n) is used for notification where
+ * n (0xd0-0xd9) is specified in notify command code.
+ * bit 2:
+ * 1 - lid changes not reported though int10
+ */
+#define ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS 0x2
+/* ARG0: ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - pending sbios requests
+ * BYTE - panel expansion mode
+ * BYTE - thermal state: target gfx controller
+ * BYTE - thermal state: state id (0: exit state, non-0: state)
+ * BYTE - forced power state: target gfx controller
+ * BYTE - forced power state: state id
+ * BYTE - system power source
+ * BYTE - panel backlight level (0-255)
+ */
+/* pending sbios requests */
+# define ATIF_DISPLAY_SWITCH_REQUEST (1 << 0)
+# define ATIF_EXPANSION_MODE_CHANGE_REQUEST (1 << 1)
+# define ATIF_THERMAL_STATE_CHANGE_REQUEST (1 << 2)
+# define ATIF_FORCED_POWER_STATE_CHANGE_REQUEST (1 << 3)
+# define ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST (1 << 4)
+# define ATIF_DISPLAY_CONF_CHANGE_REQUEST (1 << 5)
+# define ATIF_PX_GFX_SWITCH_REQUEST (1 << 6)
+# define ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST (1 << 7)
+# define ATIF_DGPU_DISPLAY_EVENT (1 << 8)
+/* panel expansion mode */
+# define ATIF_PANEL_EXPANSION_DISABLE 0
+# define ATIF_PANEL_EXPANSION_FULL 1
+# define ATIF_PANEL_EXPANSION_ASPECT 2
+/* target gfx controller */
+# define ATIF_TARGET_GFX_SINGLE 0
+# define ATIF_TARGET_GFX_PX_IGPU 1
+# define ATIF_TARGET_GFX_PX_DGPU 2
+/* system power source */
+# define ATIF_POWER_SOURCE_AC 1
+# define ATIF_POWER_SOURCE_DC 2
+# define ATIF_POWER_SOURCE_RESTRICTED_AC_1 3
+# define ATIF_POWER_SOURCE_RESTRICTED_AC_2 4
+#define ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS 0x3
+/* ARG0: ATIF_FUNCTION_SELECT_ACTIVE_DISPLAYS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - selected displays
+ * WORD - connected displays
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - selected displays
+ */
+# define ATIF_LCD1 (1 << 0)
+# define ATIF_CRT1 (1 << 1)
+# define ATIF_TV (1 << 2)
+# define ATIF_DFP1 (1 << 3)
+# define ATIF_CRT2 (1 << 4)
+# define ATIF_LCD2 (1 << 5)
+# define ATIF_DFP2 (1 << 7)
+# define ATIF_CV (1 << 8)
+# define ATIF_DFP3 (1 << 9)
+# define ATIF_DFP4 (1 << 10)
+# define ATIF_DFP5 (1 << 11)
+# define ATIF_DFP6 (1 << 12)
+#define ATIF_FUNCTION_GET_LID_STATE 0x4
+/* ARG0: ATIF_FUNCTION_GET_LID_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - lid state (0: open, 1: closed)
+ *
+ * GET_LID_STATE only works at boot and resume, for general lid
+ * status, use the kernel provided status
+ */
+#define ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS 0x5
+/* ARG0: ATIF_FUNCTION_GET_TV_STANDARD_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - 0
+ * BYTE - TV standard
+ */
+# define ATIF_TV_STD_NTSC 0
+# define ATIF_TV_STD_PAL 1
+# define ATIF_TV_STD_PALM 2
+# define ATIF_TV_STD_PAL60 3
+# define ATIF_TV_STD_NTSCJ 4
+# define ATIF_TV_STD_PALCN 5
+# define ATIF_TV_STD_PALN 6
+# define ATIF_TV_STD_SCART_RGB 9
+#define ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS 0x6
+/* ARG0: ATIF_FUNCTION_SET_TV_STANDARD_IN_CMOS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - 0
+ * BYTE - TV standard
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS 0x7
+/* ARG0: ATIF_FUNCTION_GET_PANEL_EXPANSION_MODE_FROM_CMOS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - panel expansion mode
+ */
+#define ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS 0x8
+/* ARG0: ATIF_FUNCTION_SET_PANEL_EXPANSION_MODE_IN_CMOS
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - panel expansion mode
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION 0xD
+/* ARG0: ATIF_FUNCTION_TEMPERATURE_CHANGE_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - gfx controller id
+ * BYTE - current temperature (degress Celsius)
+ * OUTPUT: none
+ */
+#define ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES 0xF
+/* ARG0: ATIF_FUNCTION_GET_GRAPHICS_DEVICE_TYPES
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of gfx devices
+ * WORD - device structure size in bytes (excludes device size field)
+ * DWORD - flags \
+ * WORD - bus number } repeated structure
+ * WORD - device number /
+ */
+/* flags */
+# define ATIF_PX_REMOVABLE_GRAPHICS_DEVICE (1 << 0)
+# define ATIF_XGP_PORT (1 << 1)
+# define ATIF_VGA_ENABLED_GRAPHICS_DEVICE (1 << 2)
+# define ATIF_XGP_PORT_IN_DOCK (1 << 3)
+
+/* ATPX */
+#define ATPX_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATPX_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+# define ATPX_GET_PX_PARAMETERS_SUPPORTED (1 << 0)
+# define ATPX_POWER_CONTROL_SUPPORTED (1 << 1)
+# define ATPX_DISPLAY_MUX_CONTROL_SUPPORTED (1 << 2)
+# define ATPX_I2C_MUX_CONTROL_SUPPORTED (1 << 3)
+# define ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED (1 << 4)
+# define ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED (1 << 5)
+# define ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED (1 << 7)
+# define ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED (1 << 8)
+#define ATPX_FUNCTION_GET_PX_PARAMETERS 0x1
+/* ARG0: ATPX_FUNCTION_GET_PX_PARAMETERS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags
+ */
+/* flags */
+# define ATPX_LVDS_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 0)
+# define ATPX_CRT1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 1)
+# define ATPX_DVI1_I2C_AVAILABLE_TO_BOTH_GPUS (1 << 2)
+# define ATPX_CRT1_RGB_SIGNAL_MUXED (1 << 3)
+# define ATPX_TV_SIGNAL_MUXED (1 << 4)
+# define ATPX_DFP_SIGNAL_MUXED (1 << 5)
+# define ATPX_SEPARATE_MUX_FOR_I2C (1 << 6)
+# define ATPX_DYNAMIC_PX_SUPPORTED (1 << 7)
+# define ATPX_ACF_NOT_SUPPORTED (1 << 8)
+# define ATPX_FIXED_NOT_SUPPORTED (1 << 9)
+# define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10)
+# define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11)
+#define ATPX_FUNCTION_POWER_CONTROL 0x2
+/* ARG0: ATPX_FUNCTION_POWER_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - dGPU power state (0: power off, 1: power on)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_DISPLAY_MUX_CONTROL 0x3
+/* ARG0: ATPX_FUNCTION_DISPLAY_MUX_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - display mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+# define ATPX_INTEGRATED_GPU 0
+# define ATPX_DISCRETE_GPU 1
+#define ATPX_FUNCTION_I2C_MUX_CONTROL 0x4
+/* ARG0: ATPX_FUNCTION_I2C_MUX_CONTROL
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - i2c/aux/hpd mux control (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION 0x5
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION 0x6
+/* ARG0: ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - target gpu (0: iGPU, 1: dGPU)
+ * OUTPUT: none
+ */
+#define ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING 0x8
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_CONNECTORS_MAPPING
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of display connectors
+ * WORD - connector structure size in bytes (excludes connector size field)
+ * BYTE - flags \
+ * BYTE - ATIF display vector bit position } repeated
+ * BYTE - adapter id (0: iGPU, 1-n: dGPU ordered by pcie bus number) } structure
+ * WORD - connector ACPI id /
+ */
+/* flags */
+# define ATPX_DISPLAY_OUTPUT_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 0)
+# define ATPX_DISPLAY_HPD_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 1)
+# define ATPX_DISPLAY_I2C_SUPPORTED_BY_ADAPTER_ID_DEVICE (1 << 2)
+#define ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS 0x9
+/* ARG0: ATPX_FUNCTION_GET_DISPLAY_DETECTION_PORTS
+ * ARG1: none
+ * OUTPUT:
+ * WORD - number of HPD/DDC ports
+ * WORD - port structure size in bytes (excludes port size field)
+ * BYTE - ATIF display vector bit position \
+ * BYTE - hpd id } reapeated structure
+ * BYTE - ddc id /
+ *
+ * available on A+A systems only
+ */
+/* hpd id */
+# define ATPX_HPD_NONE 0
+# define ATPX_HPD1 1
+# define ATPX_HPD2 2
+# define ATPX_HPD3 3
+# define ATPX_HPD4 4
+# define ATPX_HPD5 5
+# define ATPX_HPD6 6
+/* ddc id */
+# define ATPX_DDC_NONE 0
+# define ATPX_DDC1 1
+# define ATPX_DDC2 2
+# define ATPX_DDC3 3
+# define ATPX_DDC4 4
+# define ATPX_DDC5 5
+# define ATPX_DDC6 6
+# define ATPX_DDC7 7
+# define ATPX_DDC8 8
+
+/* ATCS */
+#define ATCS_FUNCTION_VERIFY_INTERFACE 0x0
+/* ARG0: ATCS_FUNCTION_VERIFY_INTERFACE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - version
+ * DWORD - supported functions bit vector
+ */
+/* supported functions vector */
+# define ATCS_GET_EXTERNAL_STATE_SUPPORTED (1 << 0)
+# define ATCS_PCIE_PERFORMANCE_REQUEST_SUPPORTED (1 << 1)
+# define ATCS_PCIE_DEVICE_READY_NOTIFICATION_SUPPORTED (1 << 2)
+# define ATCS_SET_PCIE_BUS_WIDTH_SUPPORTED (1 << 3)
+#define ATCS_FUNCTION_GET_EXTERNAL_STATE 0x1
+/* ARG0: ATCS_FUNCTION_GET_EXTERNAL_STATE
+ * ARG1: none
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * DWORD - valid flags mask
+ * DWORD - flags (0: undocked, 1: docked)
+ */
+/* flags */
+# define ATCS_DOCKED (1 << 0)
+#define ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST 0x2
+/* ARG0: ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * WORD - valid flags mask
+ * WORD - flags
+ * BYTE - request type
+ * BYTE - performance request
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - return value
+ */
+/* flags */
+# define ATCS_ADVERTISE_CAPS (1 << 0)
+# define ATCS_WAIT_FOR_COMPLETION (1 << 1)
+/* request type */
+# define ATCS_PCIE_LINK_SPEED 1
+/* performance request */
+# define ATCS_REMOVE 0
+# define ATCS_FORCE_LOW_POWER 1
+# define ATCS_PERF_LEVEL_1 2 /* PCIE Gen 1 */
+# define ATCS_PERF_LEVEL_2 3 /* PCIE Gen 2 */
+# define ATCS_PERF_LEVEL_3 4 /* PCIE Gen 3 */
+/* return value */
+# define ATCS_REQUEST_REFUSED 1
+# define ATCS_REQUEST_COMPLETE 2
+# define ATCS_REQUEST_IN_PROGRESS 3
+#define ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION 0x3
+/* ARG0: ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION
+ * ARG1: none
+ * OUTPUT: none
+ */
+#define ATCS_FUNCTION_SET_PCIE_BUS_WIDTH 0x4
+/* ARG0: ATCS_FUNCTION_SET_PCIE_BUS_WIDTH
+ * ARG1:
+ * WORD - structure size in bytes (includes size field)
+ * WORD - client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num)
+ * BYTE - number of active lanes
+ * OUTPUT:
+ * WORD - structure size in bytes (includes size field)
+ * BYTE - number of active lanes
+ */
+
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_agp.c b/sys/dev/drm2/radeon/radeon_agp.c
new file mode 100644
index 0000000..dec4045
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_agp.c
@@ -0,0 +1,289 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include <dev/drm2/radeon/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 RV250 Needs AGPMode 1 (lp #296617) */
+ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66,
+ PCI_VENDOR_ID_DELL, 0x0149, 1},
+ /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */
+ { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
+ PCI_VENDOR_ID_IBM, 0x0531, 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->info.ai_aperture_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->info.ai_aperture_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->ddev->pci_vendor == p->chip_vendor &&
+ rdev->ddev->pci_device == p->chip_device &&
+ rdev->ddev->pci_subvendor == p->subsys_vendor &&
+ rdev->ddev->pci_subdevice == 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->info.ai_aperture_base;
+ rdev->mc.gtt_size = rdev->ddev->agp->info.ai_aperture_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: %juM 0x%08jX - 0x%08jX\n",
+ (uintmax_t)rdev->mc.gtt_size >> 20, (uintmax_t)rdev->mc.gtt_start, (uintmax_t)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/sys/dev/drm2/radeon/radeon_asic.c b/sys/dev/drm2/radeon/radeon_asic.c
new file mode 100644
index 0000000..3743805
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_asic.c
@@ -0,0 +1,1961 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+/*
+ * Registers accessors functions.
+ */
+/**
+ * radeon_invalid_rreg - dummy reg read function
+ *
+ * @rdev: radeon device pointer
+ * @reg: offset of register
+ *
+ * Dummy register read function. Used for register blocks
+ * that certain asics don't have (all asics).
+ * Returns the value in the register.
+ */
+static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
+{
+ panic("Invalid callback to read register 0x%04X\n", reg);
+ return 0;
+}
+
+/**
+ * radeon_invalid_wreg - dummy reg write function
+ *
+ * @rdev: radeon device pointer
+ * @reg: offset of register
+ * @v: value to write to the register
+ *
+ * Dummy register read function. Used for register blocks
+ * that certain asics don't have (all asics).
+ */
+static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+{
+ panic("Invalid callback to write register 0x%04X with 0x%08X\n",
+ reg, v);
+}
+
+/**
+ * radeon_register_accessor_init - sets up the register accessor callbacks
+ *
+ * @rdev: radeon device pointer
+ *
+ * Sets up the register accessor callbacks for various register
+ * apertures. Not all asics have all apertures (all asics).
+ */
+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 */
+/**
+ * radeon_agp_disable - AGP disable helper function
+ *
+ * @rdev: radeon device pointer
+ *
+ * Removes AGP flags and changes the gart callbacks on AGP
+ * cards when using the internal gart rather than AGP (all asics).
+ */
+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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &radeon_legacy_set_backlight_level,
+ .get_backlight_level = &radeon_legacy_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r100_gpu_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .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,
+ .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,
+ .is_lockup = &r600_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &r600_dma_ring_ib_execute,
+ .emit_fence = &r600_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &r600_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &r600_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &r600_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ .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,
+ .is_lockup = &r600_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &r600_dma_ring_ib_execute,
+ .emit_fence = &r600_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &r600_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &r600_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &r600_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ .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,
+ .is_lockup = &r600_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &r600_dma_ring_ib_execute,
+ .emit_fence = &r600_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &r600_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &rv770_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &rv770_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ .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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &evergreen_dma_ring_ib_execute,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &evergreen_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &evergreen_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ .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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &evergreen_dma_ring_ib_execute,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &evergreen_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &evergreen_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ .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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &evergreen_dma_ring_ib_execute,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &r600_dma_is_lockup,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &evergreen_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &evergreen_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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 = &btc_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 cayman_asic = {
+ .init = &cayman_init,
+ .fini = &cayman_fini,
+ .suspend = &cayman_suspend,
+ .resume = &cayman_resume,
+ .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,
+ },
+ .vm = {
+ .init = &cayman_vm_init,
+ .fini = &cayman_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &cayman_vm_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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &cayman_dma_vm_flush,
+ },
+ [CAYMAN_RING_TYPE_DMA1_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &cayman_dma_vm_flush,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &evergreen_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &evergreen_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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 = &btc_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,
+ .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,
+ },
+ .vm = {
+ .init = &cayman_vm_init,
+ .fini = &cayman_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &cayman_vm_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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [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,
+ .is_lockup = &evergreen_gpu_is_lockup,
+ .vm_flush = &cayman_vm_flush,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &cayman_dma_vm_flush,
+ },
+ [CAYMAN_RING_TYPE_DMA1_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = &evergreen_dma_cs_parse,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &cayman_dma_vm_flush,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = &r600_copy_blit,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &evergreen_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &evergreen_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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 si_asic = {
+ .init = &si_init,
+ .fini = &si_fini,
+ .suspend = &si_suspend,
+ .resume = &si_resume,
+ .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,
+ },
+ .vm = {
+ .init = &si_vm_init,
+ .fini = &si_vm_fini,
+ .pt_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .set_page = &si_vm_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,
+ .is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
+ },
+ [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,
+ .is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
+ },
+ [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,
+ .is_lockup = &si_gpu_is_lockup,
+ .vm_flush = &si_vm_flush,
+ },
+ [R600_RING_TYPE_DMA_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = NULL,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &si_dma_vm_flush,
+ },
+ [CAYMAN_RING_TYPE_DMA1_INDEX] = {
+ .ib_execute = &cayman_dma_ring_ib_execute,
+ .ib_parse = &evergreen_dma_ib_parse,
+ .emit_fence = &evergreen_dma_fence_ring_emit,
+ .emit_semaphore = &r600_dma_semaphore_ring_emit,
+ .cs_parse = NULL,
+ .ring_test = &r600_dma_ring_test,
+ .ib_test = &r600_dma_ib_test,
+ .is_lockup = &cayman_dma_is_lockup,
+ .vm_flush = &si_dma_vm_flush,
+ }
+ },
+ .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,
+ .set_backlight_level = &atombios_set_backlight_level,
+ .get_backlight_level = &atombios_get_backlight_level,
+ },
+ .copy = {
+ .blit = NULL,
+ .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+ .dma = &si_copy_dma,
+ .dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+ .copy = &si_copy_dma,
+ .copy_ring_index = R600_RING_TYPE_DMA_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,
+ },
+};
+
+/**
+ * radeon_asic_init - register asic specific callbacks
+ *
+ * @rdev: radeon device pointer
+ *
+ * Registers the appropriate asic specific callbacks for each
+ * chip family. Also sets other asics specific info like the number
+ * of crtcs and the register aperture accessors (all asics).
+ * Returns 0 for success.
+ */
+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;
+ rdev->asic->display.set_backlight_level = &radeon_legacy_set_backlight_level;
+ }
+ 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;
+ break;
+ case CHIP_ARUBA:
+ rdev->asic = &trinity_asic;
+ /* set num crtcs */
+ rdev->num_crtc = 4;
+ break;
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ rdev->asic = &si_asic;
+ /* set num crtcs */
+ rdev->num_crtc = 6;
+ 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/sys/dev/drm2/radeon/radeon_asic.h b/sys/dev/drm2/radeon/radeon_asic.h
new file mode 100644
index 0000000..f3b85f8
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_asic.h
@@ -0,0 +1,532 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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);
+
+void atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
+u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder);
+void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
+u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
+
+
+/*
+ * 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);
+irqreturn_t 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);
+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 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);
+
+/*
+ * 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);
+irqreturn_t 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 vga_render_control;
+ u32 vga_hdp_control;
+ bool crtc_enabled[2];
+};
+
+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);
+int r600_dma_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);
+void r600_dma_fence_ring_emit(struct radeon_device *rdev,
+ struct radeon_fence *fence);
+void r600_dma_semaphore_ring_emit(struct radeon_device *rdev,
+ struct radeon_ring *ring,
+ struct radeon_semaphore *semaphore,
+ bool emit_wait);
+void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
+bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
+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);
+int r600_dma_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_dma_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);
+int r600_copy_dma(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);
+void r600_fini_microcode(struct radeon_device *rdev);
+/* r600 irq */
+irqreturn_t 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);
+void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
+struct r600_audio r600_audio_status(struct radeon_device *rdev);
+void r600_audio_fini(struct radeon_device *rdev);
+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,
+ struct radeon_fence **fence, struct radeon_sa_bo **vb,
+ struct radeon_semaphore **sem);
+void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence **fence,
+ struct radeon_sa_bo *vb, struct radeon_semaphore *sem);
+void r600_kms_blit_copy(struct radeon_device *rdev,
+ u64 src_gpu_addr, u64 dst_gpu_addr,
+ unsigned num_gpu_pages,
+ struct radeon_sa_bo *vb);
+uint64_t r600_get_gpu_clock(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);
+int rv770_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence);
+
+/*
+ * evergreen
+ */
+struct evergreen_mc_save {
+ u32 vga_render_control;
+ u32 vga_hdp_control;
+ bool crtc_enabled[RADEON_MAX_CRTCS];
+};
+
+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);
+irqreturn_t evergreen_irq_process(struct radeon_device *rdev);
+extern int evergreen_cs_parse(struct radeon_cs_parser *p);
+extern int evergreen_dma_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 btc_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);
+void evergreen_dma_fence_ring_emit(struct radeon_device *rdev,
+ struct radeon_fence *fence);
+void evergreen_dma_ring_ib_execute(struct radeon_device *rdev,
+ struct radeon_ib *ib);
+int evergreen_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence);
+void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
+u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
+void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
+void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
+void evergreen_mc_program(struct radeon_device *rdev);
+int evergreen_mc_init(struct radeon_device *rdev);
+void evergreen_irq_suspend(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);
+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);
+void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags);
+void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
+int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
+void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
+ struct radeon_ib *ib);
+bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
+void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
+ int ring, u32 cp_int_cntl);
+
+/* 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);
+irqreturn_t si_irq_process(struct radeon_device *rdev);
+int si_vm_init(struct radeon_device *rdev);
+void si_vm_fini(struct radeon_device *rdev);
+void si_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
+uint64_t si_get_gpu_clock(struct radeon_device *rdev);
+int si_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence);
+void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+void si_rlc_fini(struct radeon_device *rdev);
+int si_rlc_init(struct radeon_device *rdev);
+
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_atombios.c b/sys/dev/drm2/radeon/radeon_atombios.c
new file mode 100644
index 0000000..309f147
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_atombios.c
@@ -0,0 +1,3190 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.h" /* Declares several prototypes; clang is pleased. */
+
+#include "atom.h"
+#include "atom-bits.h"
+
+/* 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 *)((char *)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 *)((char *)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 *)((char *)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->pci_device == 0x791e) &&
+ (dev->pci_subvendor == 0x1043) &&
+ (dev->pci_subdevice == 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->pci_device == 0x7941) &&
+ (dev->pci_subvendor == 0x1849) &&
+ (dev->pci_subdevice == 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->pci_device == 0x796e) &&
+ (dev->pci_subvendor == 0x1462) &&
+ (dev->pci_subdevice == 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->pci_device == 0x7941) &&
+ (dev->pci_subvendor == 0x147b) &&
+ (dev->pci_subdevice == 0x2412)) {
+ if (*connector_type == DRM_MODE_CONNECTOR_DVII)
+ return false;
+ }
+
+ /* Falcon NW laptop lists vga ddc line for LVDS */
+ if ((dev->pci_device == 0x5653) &&
+ (dev->pci_subvendor == 0x1462) &&
+ (dev->pci_subdevice == 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->pci_device == 0x7146) &&
+ (dev->pci_subvendor == 0x17af) &&
+ (dev->pci_subdevice == 0x2058)) {
+ if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+ return false;
+ }
+
+ /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */
+ if ((dev->pci_device == 0x7142) &&
+ (dev->pci_subvendor == 0x1458) &&
+ (dev->pci_subdevice == 0x2134)) {
+ if (supported_device == ATOM_DEVICE_DFP1_SUPPORT)
+ return false;
+ }
+
+
+ /* Funky macbooks */
+ if ((dev->pci_device == 0x71C5) &&
+ (dev->pci_subvendor == 0x106b) &&
+ (dev->pci_subdevice == 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->pci_device == 0x9598) &&
+ (dev->pci_subvendor == 0x1043) &&
+ (dev->pci_subdevice == 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->pci_device == 0x9598) &&
+ (dev->pci_subvendor == 0x1043) &&
+ (dev->pci_subdevice == 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->pci_device == 0x95C5) &&
+ (dev->pci_subvendor == 0x1043) &&
+ (dev->pci_subdevice == 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->pci_device == 0x95c4) || (dev->pci_device == 0x9591)) &&
+ (dev->pci_subvendor == 0x1025) &&
+ (dev->pci_subdevice == 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->pci_device == 0x9498) &&
+ (dev->pci_subvendor == 0x1682) &&
+ (dev->pci_subdevice == 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->pci_device == 0x9802) || (dev->pci_device == 0x9806)) &&
+ (dev->pci_subvendor == 0x1734) &&
+ (dev->pci_subdevice == 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 *) ((char *)ctx->bios + data_offset);
+ path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
+ ((char *)ctx->bios + data_offset +
+ le16_to_cpu(obj_header->usDisplayPathTableOffset));
+ con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
+ ((char *)ctx->bios + data_offset +
+ le16_to_cpu(obj_header->usConnectorObjectTableOffset));
+ enc_obj = (ATOM_ENCODER_OBJECT_TABLE *)
+ ((char *)ctx->bios + data_offset +
+ le16_to_cpu(obj_header->usEncoderObjectTableOffset));
+ router_obj = (ATOM_OBJECT_TABLE *)
+ ((char *)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
+ *) ((char *)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 *)
+ ((char *)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 *)
+ ((char *)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 *)
+ ((char *)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
+ *)
+ ((char *)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 *)((char *)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 = malloc(bc_size, DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (!bios_connectors)
+ return false;
+
+ if (!atom_parse_data_header(ctx, index, &size, &frev, &crev,
+ &data_offset)) {
+ free(bios_connectors, DRM_MEM_DRIVER);
+ return false;
+ }
+
+ supported_devices =
+ (union atom_supported_devices *)((char *)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);
+
+ free(bios_connectors, DRM_MEM_DRIVER);
+ 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 *)((char *)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;
+
+ /* not technically a clock, but... */
+ rdev->mode_info.firmware_flags =
+ le16_to_cpu(firmware_info->info.usFirmwareCapability.susAccess);
+
+ return true;
+ }
+
+ return false;
+}
+
+union igp_info {
+ struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+ struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+ struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
+ struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
+};
+
+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 *)((char *)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 *)((char *)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 *)((char *)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;
+ union igp_info *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 = (union igp_info *)
+ ((char *)mode_info->atom_context->bios + data_offset);
+ switch (crev) {
+ case 6:
+ switch (id) {
+ case ASIC_INTERNAL_SS_ON_TMDS:
+ percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage);
+ rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz);
+ break;
+ case ASIC_INTERNAL_SS_ON_HDMI:
+ percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage);
+ rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz);
+ break;
+ case ASIC_INTERNAL_SS_ON_LVDS:
+ percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage);
+ rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz);
+ break;
+ }
+ break;
+ case 7:
+ switch (id) {
+ case ASIC_INTERNAL_SS_ON_TMDS:
+ percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage);
+ rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz);
+ break;
+ case ASIC_INTERNAL_SS_ON_HDMI:
+ percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage);
+ rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz);
+ break;
+ case ASIC_INTERNAL_SS_ON_LVDS:
+ percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage);
+ rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz);
+ break;
+ }
+ break;
+ default:
+ DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
+ 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 *)((char *)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 *)((char *)mode_info->atom_context->bios + data_offset);
+ lvds =
+ malloc(sizeof(struct radeon_encoder_atom_dig),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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 *)((char *)mode_info->atom_context->bios +
+ le16_to_cpu(lvds_info->info.usModePatchTableOffset));
+ else
+ /* relative */
+ record = (u8 *)((char *)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 = malloc(edid_size, DRM_MEM_KMS, M_WAITOK);
+ 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
+ free(edid, DRM_MEM_KMS);
+ }
+ }
+ 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 *)
+ ((char *)mode_info->atom_context->bios + data_offset);
+
+ p_dac = malloc(sizeof(struct radeon_encoder_primary_dac),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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 *)((char *)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 *)((char *)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 *)
+ ((char *)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 *)
+ ((char *)mode_info->atom_context->bios + data_offset);
+
+ tv_dac = malloc(sizeof(struct radeon_encoder_tv_dac),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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 *)((char *)mode_info->atom_context->bios + data_offset);
+
+ /* add the i2c bus for thermal/fan chip */
+ if ((power_info->info.ucOverdriveThermalController > 0) &&
+ (power_info->info.ucOverdriveThermalController < DRM_ARRAY_SIZE(thermal_controller_names))) {
+ 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);
+#ifdef DUMBBELL_WIP
+ 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);
+ }
+#endif /* DUMBBELL_WIP */
+ }
+ 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 = malloc(sizeof(struct radeon_power_state) * num_modes,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 =
+ malloc(sizeof(struct radeon_pm_clock_info) * 1,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 if (controller->ucType < DRM_ARRAY_SIZE(pp_lib_thermal_controller_names)) {
+ 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);
+#ifdef DUMBBELL_WIP
+ 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);
+ }
+#endif /* DUMBBELL_WIP */
+ } else {
+ DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
+ controller->ucType,
+ controller->ucI2cAddress >> 1,
+ (controller->ucFanParameters &
+ ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+ }
+ }
+}
+
+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 *)((char *)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 *)((char *)mode_info->atom_context->bios + data_offset);
+
+ radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
+ rdev->pm.power_state = malloc(sizeof(struct radeon_power_state) *
+ power_info->pplib.ucNumStates,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 *)
+ ((char *)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 *)
+ ((char *)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 = malloc(sizeof(struct radeon_pm_clock_info) *
+ ((power_info->pplib.ucStateEntrySize - 1) ?
+ (power_info->pplib.ucStateEntrySize - 1) : 1),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 *)
+ ((char *)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 *)((char *)mode_info->atom_context->bios + data_offset);
+
+ radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
+ state_array = (struct _StateArray *)
+ ((char *)mode_info->atom_context->bios + data_offset +
+ le16_to_cpu(power_info->pplib.usStateArrayOffset));
+ clock_info_array = (struct _ClockInfoArray *)
+ ((char *)mode_info->atom_context->bios + data_offset +
+ le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
+ non_clock_info_array = (struct _NonClockInfoArray *)
+ ((char *)mode_info->atom_context->bios + data_offset +
+ le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
+ rdev->pm.power_state = malloc(sizeof(struct radeon_power_state) *
+ state_array->ucNumEntries,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 = malloc(sizeof(struct radeon_pm_clock_info) *
+ (power_state->v2.ucNumDPMLevels ?
+ power_state->v2.ucNumDPMLevels : 1),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 = malloc(sizeof(struct radeon_power_state),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->pm.power_state) {
+ rdev->pm.power_state[0].clock_info =
+ malloc(sizeof(struct radeon_pm_clock_info) * 1,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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/sys/dev/drm2/radeon/radeon_atpx_handler.c b/sys/dev/drm2/radeon/radeon_atpx_handler.c
new file mode 100644
index 0000000..4cfd743
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_atpx_handler.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2010 Red Hat Inc.
+ * Author : Dave Airlie <airlied@redhat.com>
+ *
+ * Licensed under GPLv2
+ *
+ * ATPX support for both Intel/ATI
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/linker.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_acpi.h"
+#include "radeon_drv.h"
+
+#ifdef DUMBBELL_WIP
+struct radeon_atpx_functions {
+ bool px_params;
+ bool power_cntl;
+ bool disp_mux_cntl;
+ bool i2c_mux_cntl;
+ bool switch_start;
+ bool switch_end;
+ bool disp_connectors_mapping;
+ bool disp_detetion_ports;
+};
+
+struct radeon_atpx {
+ ACPI_HANDLE handle;
+ struct radeon_atpx_functions functions;
+};
+
+static struct radeon_atpx_priv {
+ bool atpx_detected;
+ /* handle for device - and atpx */
+ ACPI_HANDLE dhandle;
+ struct radeon_atpx atpx;
+} radeon_atpx_priv;
+
+struct atpx_verify_interface {
+ u16 size; /* structure size in bytes (includes size field) */
+ u16 version; /* version */
+ u32 function_bits; /* supported functions bit vector */
+} __packed;
+
+struct atpx_power_control {
+ u16 size;
+ u8 dgpu_state;
+} __packed;
+
+struct atpx_mux {
+ u16 size;
+ u16 mux;
+} __packed;
+
+/**
+ * radeon_atpx_call - call an ATPX method
+ *
+ * @handle: acpi handle
+ * @function: the ATPX function to execute
+ * @params: ATPX function params
+ *
+ * Executes the requested ATPX function (all asics).
+ * Returns a pointer to the acpi output buffer.
+ */
+static ACPI_OBJECT *radeon_atpx_call(ACPI_HANDLE handle, int function,
+ ACPI_BUFFER *params)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT atpx_arg_elements[2];
+ ACPI_OBJECT_LIST atpx_arg;
+ 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 = function;
+
+ if (params) {
+ atpx_arg_elements[1].Type = ACPI_TYPE_BUFFER;
+ atpx_arg_elements[1].Buffer.Length = params->Length;
+ atpx_arg_elements[1].Buffer.Pointer = params->Pointer;
+ } else {
+ /* We need a second fake parameter */
+ atpx_arg_elements[1].Type = ACPI_TYPE_INTEGER;
+ atpx_arg_elements[1].Integer.Value = 0;
+ }
+
+ status = AcpiEvaluateObject(handle, NULL, &atpx_arg, &buffer);
+
+ /* Fail only if calling the method fails and ATPX is supported */
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ DRM_ERROR("failed to evaluate ATPX got %s\n",
+ AcpiFormatException(status));
+ AcpiOsFree(buffer.Pointer);
+ return NULL;
+ }
+
+ return buffer.Pointer;
+}
+
+/**
+ * radeon_atpx_parse_functions - parse supported functions
+ *
+ * @f: supported functions struct
+ * @mask: supported functions mask from ATPX
+ *
+ * Use the supported functions mask from ATPX function
+ * ATPX_FUNCTION_VERIFY_INTERFACE to determine what functions
+ * are supported (all asics).
+ */
+static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mask)
+{
+ f->px_params = mask & ATPX_GET_PX_PARAMETERS_SUPPORTED;
+ f->power_cntl = mask & ATPX_POWER_CONTROL_SUPPORTED;
+ f->disp_mux_cntl = mask & ATPX_DISPLAY_MUX_CONTROL_SUPPORTED;
+ f->i2c_mux_cntl = mask & ATPX_I2C_MUX_CONTROL_SUPPORTED;
+ f->switch_start = mask & ATPX_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION_SUPPORTED;
+ f->switch_end = mask & ATPX_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION_SUPPORTED;
+ f->disp_connectors_mapping = mask & ATPX_GET_DISPLAY_CONNECTORS_MAPPING_SUPPORTED;
+ f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
+}
+
+/**
+ * radeon_atpx_verify_interface - verify ATPX
+ *
+ * @handle: acpi handle
+ * @atpx: radeon atpx struct
+ *
+ * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
+ * to initialize ATPX and determine what features are supported
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+static int radeon_atpx_verify_interface(struct radeon_atpx *atpx)
+{
+ ACPI_OBJECT *info;
+ struct atpx_verify_interface output;
+ size_t size;
+ int err = 0;
+
+ info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
+ if (!info)
+ return -EIO;
+
+ memset(&output, 0, sizeof(output));
+
+ size = *(u16 *) info->Buffer.Pointer;
+ if (size < 8) {
+ DRM_ERROR("ATPX buffer is too small: %zu\n", size);
+ err = -EINVAL;
+ goto out;
+ }
+ size = min(sizeof(output), size);
+
+ memcpy(&output, info->Buffer.Pointer, size);
+
+ /* TODO: check version? */
+ DRM_INFO("ATPX version %u\n", output.version);
+
+ radeon_atpx_parse_functions(&atpx->functions, output.function_bits);
+
+out:
+ AcpiOsFree(info);
+ return err;
+}
+
+/**
+ * radeon_atpx_set_discrete_state - power up/down discrete GPU
+ *
+ * @atpx: atpx info struct
+ * @state: discrete GPU state (0 = power down, 1 = power up)
+ *
+ * Execute the ATPX_FUNCTION_POWER_CONTROL ATPX function to
+ * power down/up the discrete GPU (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_set_discrete_state(struct radeon_atpx *atpx, u8 state)
+{
+ ACPI_BUFFER params;
+ ACPI_OBJECT *info;
+ struct atpx_power_control input;
+
+ if (atpx->functions.power_cntl) {
+ input.size = 3;
+ input.dgpu_state = state;
+ params.Length = input.size;
+ params.Pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_POWER_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ AcpiOsFree(info);
+ }
+ return 0;
+}
+
+/**
+ * radeon_atpx_switch_disp_mux - switch display mux
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_DISPLAY_MUX_CONTROL ATPX function to
+ * switch the display mux between the discrete GPU and integrated GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_disp_mux(struct radeon_atpx *atpx, u16 mux_id)
+{
+ ACPI_BUFFER params;
+ ACPI_OBJECT *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.disp_mux_cntl) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.Length = input.size;
+ params.Pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ AcpiOsFree(info);
+ }
+ return 0;
+}
+
+/**
+ * radeon_atpx_switch_i2c_mux - switch i2c/hpd mux
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_I2C_MUX_CONTROL ATPX function to
+ * switch the i2c/hpd mux between the discrete GPU and integrated GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_i2c_mux(struct radeon_atpx *atpx, u16 mux_id)
+{
+ ACPI_BUFFER params;
+ ACPI_OBJECT *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.i2c_mux_cntl) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.Length = input.size;
+ params.Pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_I2C_MUX_CONTROL,
+ &params);
+ if (!info)
+ return -EIO;
+ AcpiOsFree(info);
+ }
+ return 0;
+}
+
+/**
+ * radeon_atpx_switch_start - notify the sbios of a GPU switch
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION ATPX
+ * function to notify the sbios that a switch between the discrete GPU and
+ * integrated GPU has begun (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_start(struct radeon_atpx *atpx, u16 mux_id)
+{
+ ACPI_BUFFER params;
+ ACPI_OBJECT *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.switch_start) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.Length = input.size;
+ params.Pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
+ &params);
+ if (!info)
+ return -EIO;
+ AcpiOsFree(info);
+ }
+ return 0;
+}
+
+/**
+ * radeon_atpx_switch_end - notify the sbios of a GPU switch
+ *
+ * @atpx: atpx info struct
+ * @mux_id: mux state (0 = integrated GPU, 1 = discrete GPU)
+ *
+ * Execute the ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION ATPX
+ * function to notify the sbios that a switch between the discrete GPU and
+ * integrated GPU has ended (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switch_end(struct radeon_atpx *atpx, u16 mux_id)
+{
+ ACPI_BUFFER params;
+ ACPI_OBJECT *info;
+ struct atpx_mux input;
+
+ if (atpx->functions.switch_end) {
+ input.size = 4;
+ input.mux = mux_id;
+ params.Length = input.size;
+ params.Pointer = &input;
+ info = radeon_atpx_call(atpx->handle,
+ ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
+ &params);
+ if (!info)
+ return -EIO;
+ AcpiOsFree(info);
+ }
+ return 0;
+}
+
+/**
+ * radeon_atpx_switchto - switch to the requested GPU
+ *
+ * @id: GPU to switch to
+ *
+ * Execute the necessary ATPX functions to switch between the discrete GPU and
+ * integrated GPU (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
+{
+ u16 gpu_id;
+
+ if (id == VGA_SWITCHEROO_IGD)
+ gpu_id = ATPX_INTEGRATED_GPU;
+ else
+ gpu_id = ATPX_DISCRETE_GPU;
+
+ radeon_atpx_switch_start(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_disp_mux(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_i2c_mux(&radeon_atpx_priv.atpx, gpu_id);
+ radeon_atpx_switch_end(&radeon_atpx_priv.atpx, gpu_id);
+
+ return 0;
+}
+
+/**
+ * radeon_atpx_power_state - power down/up the requested GPU
+ *
+ * @id: GPU to power down/up
+ * @state: requested power state (0 = off, 1 = on)
+ *
+ * Execute the necessary ATPX function to power down/up the discrete GPU
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+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, state);
+ return 0;
+}
+
+/**
+ * radeon_atpx_pci_probe_handle - look up the ATPX handle
+ *
+ * @pdev: pci device
+ *
+ * Look up the ATPX handles (all asics).
+ * Returns true if the handles are found, false if not.
+ */
+static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
+{
+ ACPI_HANDLE dhandle, atpx_handle;
+ ACPI_STATUS status;
+
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ return false;
+
+ status = AcpiGetHandle(dhandle, "ATPX", &atpx_handle);
+ if (ACPI_FAILURE(status))
+ return false;
+
+ radeon_atpx_priv.dhandle = dhandle;
+ radeon_atpx_priv.atpx.handle = atpx_handle;
+ return true;
+}
+
+/**
+ * radeon_atpx_init - verify the ATPX interface
+ *
+ * Verify the ATPX interface (all asics).
+ * Returns 0 on success, error on failure.
+ */
+static int radeon_atpx_init(void)
+{
+ /* set up the ATPX handle */
+ return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
+}
+
+/**
+ * radeon_atpx_get_client_id - get the client id
+ *
+ * @pdev: pci device
+ *
+ * look up whether we are the integrated or discrete GPU (all asics).
+ * Returns the client id.
+ */
+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,
+};
+
+/**
+ * radeon_atpx_detect - detect whether we have PX
+ *
+ * Check if we have a PX system (all asics).
+ * Returns true if we have a PX system, false if not.
+ */
+static bool radeon_atpx_detect(void)
+{
+ char acpi_method_name[255] = { 0 };
+ 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) {
+ AcpiGetName(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
+ DRM_INFO("VGA switcheroo: detected switching method %s handle\n",
+ acpi_method_name);
+ radeon_atpx_priv.atpx_detected = true;
+ return true;
+ }
+ return false;
+}
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_register_atpx_handler - register with vga_switcheroo
+ *
+ * Register the PX callbacks with vga_switcheroo (all asics).
+ */
+void radeon_register_atpx_handler(void)
+{
+#ifdef DUMBBELL_WIP
+ 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);
+#endif /* DUMBBELL_WIP */
+}
+
+/**
+ * radeon_unregister_atpx_handler - unregister with vga_switcheroo
+ *
+ * Unregister the PX callbacks with vga_switcheroo (all asics).
+ */
+void radeon_unregister_atpx_handler(void)
+{
+#ifdef DUMBBELL_WIP
+ vga_switcheroo_unregister_handler();
+#endif /* DUMBBELL_WIP */
+}
diff --git a/sys/dev/drm2/radeon/radeon_benchmark.c b/sys/dev/drm2/radeon/radeon_benchmark.c
new file mode 100644
index 0000000..ce39748
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_benchmark.c
@@ -0,0 +1,255 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#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_copy_dma(rdev, saddr, daddr,
+ size / RADEON_GPU_PAGE_SIZE,
+ &fence);
+ break;
+ case RADEON_BENCHMARK_COPY_BLIT:
+ 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, NULL, &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, NULL, &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/sys/dev/drm2/radeon/radeon_bios.c b/sys/dev/drm2/radeon/radeon_bios.c
new file mode 100644
index 0000000..b9ee4d1
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_bios.c
@@ -0,0 +1,728 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "atom.h"
+
+/*
+ * 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)
+{
+ drm_local_map_t bios_map;
+ uint8_t __iomem *bios;
+ resource_size_t vram_base;
+ resource_size_t size = 256 * 1024; /* ??? */
+
+ DRM_INFO("%s: ===> Try IGP's VRAM...\n", __func__);
+
+ if (!(rdev->flags & RADEON_IS_IGP))
+ if (!radeon_card_posted(rdev)) {
+ DRM_INFO("%s: not POSTed discrete card detected, skipping this method...\n",
+ __func__);
+ return false;
+ }
+
+ rdev->bios = NULL;
+ vram_base = drm_get_resource_start(rdev->ddev, 0);
+ DRM_INFO("%s: VRAM base address: 0x%jx\n", __func__, (uintmax_t)vram_base);
+
+ bios_map.offset = vram_base;
+ bios_map.size = size;
+ bios_map.type = 0;
+ bios_map.flags = 0;
+ bios_map.mtrr = 0;
+ drm_core_ioremap(&bios_map, rdev->ddev);
+ if (bios_map.virtual == NULL) {
+ DRM_INFO("%s: failed to ioremap\n", __func__);
+ return false;
+ }
+ bios = bios_map.virtual;
+ size = bios_map.size;
+ DRM_INFO("%s: Map address: %p (%ju bytes)\n", __func__, bios, (uintmax_t)size);
+
+ if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+ if (size == 0) {
+ DRM_INFO("%s: Incorrect BIOS size\n", __func__);
+ } else {
+ DRM_INFO("%s: Incorrect BIOS signature: 0x%02X%02X\n",
+ __func__, bios[0], bios[1]);
+ }
+ drm_core_ioremapfree(&bios_map, rdev->ddev);
+ return false;
+ }
+ rdev->bios = malloc(size, DRM_MEM_DRIVER, M_WAITOK);
+ if (rdev->bios == NULL) {
+ drm_core_ioremapfree(&bios_map, rdev->ddev);
+ return false;
+ }
+ memcpy_fromio(rdev->bios, bios, size);
+ drm_core_ioremapfree(&bios_map, rdev->ddev);
+ return true;
+}
+
+static bool radeon_read_bios(struct radeon_device *rdev)
+{
+ uint8_t __iomem *bios;
+ size_t size;
+
+ DRM_INFO("%s: ===> Try PCI Expansion ROM...\n", __func__);
+
+ rdev->bios = NULL;
+ /* XXX: some cards may return 0 for rom size? ddx has a workaround */
+ bios = vga_pci_map_bios(rdev->dev, &size);
+ if (!bios) {
+ return false;
+ }
+ DRM_INFO("%s: Map address: %p (%zu bytes)\n", __func__, bios, size);
+
+ if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+ if (size == 0) {
+ DRM_INFO("%s: Incorrect BIOS size\n", __func__);
+ } else {
+ DRM_INFO("%s: Incorrect BIOS signature: 0x%02X%02X\n",
+ __func__, bios[0], bios[1]);
+ }
+ vga_pci_unmap_bios(rdev->dev, bios);
+ }
+ rdev->bios = malloc(size, DRM_MEM_DRIVER, M_WAITOK);
+ memcpy(rdev->bios, bios, size);
+ vga_pci_unmap_bios(rdev->dev, bios);
+ return true;
+}
+
+/* ATRM is used to get the BIOS on the discrete cards in
+ * dual-gpu systems.
+ */
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(ACPI_HANDLE atrm_handle, uint8_t *bios,
+ int offset, int len)
+{
+ ACPI_STATUS status;
+ ACPI_OBJECT atrm_arg_elements[2], *obj;
+ ACPI_OBJECT_LIST atrm_arg;
+ 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 = AcpiEvaluateObject(atrm_handle, NULL, &atrm_arg, &buffer);
+ if (ACPI_FAILURE(status)) {
+ DRM_ERROR("failed to evaluate ATRM got %s\n", AcpiFormatException(status));
+ return -ENODEV;
+ }
+
+ obj = (ACPI_OBJECT *)buffer.Pointer;
+ memcpy(bios+offset, obj->Buffer.Pointer, obj->Buffer.Length);
+ len = obj->Buffer.Length;
+ AcpiOsFree(buffer.Pointer);
+ return len;
+}
+
+static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+ int ret;
+ int size = 256 * 1024;
+ int i;
+ device_t dev;
+ ACPI_HANDLE dhandle, atrm_handle;
+ ACPI_STATUS status;
+ bool found = false;
+
+ DRM_INFO("%s: ===> Try ATRM...\n", __func__);
+
+ /* ATRM is for the discrete card only */
+ if (rdev->flags & RADEON_IS_IGP) {
+ DRM_INFO("%s: IGP card detected, skipping this method...\n",
+ __func__);
+ return false;
+ }
+
+#ifdef DUMBBELL_WIP
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+#endif /* DUMBBELL_WIP */
+ if ((dev = pci_find_class(PCIC_DISPLAY, PCIS_DISPLAY_VGA)) != NULL) {
+ DRM_INFO("%s: pci_find_class() found: %d:%d:%d:%d, vendor=%04x, device=%04x\n",
+ __func__,
+ pci_get_domain(dev),
+ pci_get_bus(dev),
+ pci_get_slot(dev),
+ pci_get_function(dev),
+ pci_get_vendor(dev),
+ pci_get_device(dev));
+ DRM_INFO("%s: Get ACPI device handle\n", __func__);
+ dhandle = acpi_get_handle(dev);
+#ifdef DUMBBELL_WIP
+ if (!dhandle)
+ continue;
+#endif /* DUMBBELL_WIP */
+ if (!dhandle)
+ return false;
+
+ DRM_INFO("%s: Get ACPI handle for \"ATRM\"\n", __func__);
+ status = AcpiGetHandle(dhandle, "ATRM", &atrm_handle);
+ if (!ACPI_FAILURE(status)) {
+ found = true;
+#ifdef DUMBBELL_WIP
+ break;
+#endif /* DUMBBELL_WIP */
+ } else {
+ DRM_INFO("%s: Failed to get \"ATRM\" handle: %s\n",
+ __func__, AcpiFormatException(status));
+ }
+ }
+
+ if (!found)
+ return false;
+
+ rdev->bios = malloc(size, DRM_MEM_DRIVER, M_WAITOK);
+ if (!rdev->bios) {
+ DRM_ERROR("Unable to allocate bios\n");
+ return false;
+ }
+
+ for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
+ DRM_INFO("%s: Call radeon_atrm_call()\n", __func__);
+ ret = radeon_atrm_call(atrm_handle,
+ 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) {
+ if (i == 0) {
+ DRM_INFO("%s: Incorrect BIOS size\n", __func__);
+ } else {
+ DRM_INFO("%s: Incorrect BIOS signature: 0x%02X%02X\n",
+ __func__, rdev->bios[0], rdev->bios[1]);
+ }
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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;
+
+ DRM_INFO("%s: ===> Try disabled BIOS (ni)...\n", __func__);
+
+ 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;
+
+ DRM_INFO("%s: ===> Try disabled BIOS (r700)...\n", __func__);
+
+ 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;
+
+ DRM_INFO("%s: ===> Try disabled BIOS (r600)...\n", __func__);
+
+ 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;
+
+ DRM_INFO("%s: ===> Try disabled BIOS (avivo)...\n", __func__);
+
+ 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;
+
+ DRM_INFO("%s: ===> Try disabled BIOS (legacy)...\n", __func__);
+
+ 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;
+
+#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159
+
+ 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);
+}
+
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ ACPI_TABLE_HEADER *hdr;
+ ACPI_SIZE tbl_size;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+ ACPI_STATUS status;
+
+ DRM_INFO("%s: ===> Try VFCT...\n", __func__);
+
+ DRM_INFO("%s: Get \"VFCT\" ACPI table\n", __func__);
+ status = AcpiGetTable("VFCT", 1, &hdr);
+ if (!ACPI_SUCCESS(status)) {
+ DRM_INFO("%s: Failed to get \"VFCT\" table: %s\n",
+ __func__, AcpiFormatException(status));
+ return false;
+ }
+ tbl_size = hdr->Length;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->ddev->pci_bus ||
+ vhdr->PCIDevice != rdev->ddev->pci_slot ||
+ vhdr->PCIFunction != rdev->ddev->pci_func ||
+ vhdr->VendorID != rdev->ddev->pci_vendor ||
+ vhdr->DeviceID != rdev->ddev->pci_device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = malloc(vhdr->ImageLength, DRM_MEM_DRIVER, M_WAITOK);
+ memcpy(rdev->bios, &vbios->VbiosContent, vhdr->ImageLength);
+ ret = !!rdev->bios;
+
+out_unmap:
+ return ret;
+}
+
+bool radeon_get_bios(struct radeon_device *rdev)
+{
+ bool r;
+ uint16_t tmp;
+
+ r = radeon_atrm_get_bios(rdev);
+ if (r == false)
+ r = radeon_acpi_vfct_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) {
+ DRM_ERROR("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:
+ free(rdev->bios, DRM_MEM_DRIVER);
+ rdev->bios = NULL;
+ return false;
+}
diff --git a/sys/dev/drm2/radeon/radeon_blit_common.h b/sys/dev/drm2/radeon/radeon_blit_common.h
new file mode 100644
index 0000000..a8f6827
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_blit_common.h
@@ -0,0 +1,47 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/radeon_clocks.c b/sys/dev/drm2/radeon/radeon_clocks.c
new file mode 100644
index 0000000..9ecd18a
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_clocks.c
@@ -0,0 +1,917 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "radeon_asic.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);
+
+ DRM_UDELAY(10);
+
+ tmp = RREG32_PLL(RADEON_SPLL_CNTL);
+ tmp |= RADEON_SPLL_SLEEP;
+ WREG32_PLL(RADEON_SPLL_CNTL, tmp);
+
+ DRM_UDELAY(2);
+
+ tmp = RREG32_PLL(RADEON_SPLL_CNTL);
+ tmp |= RADEON_SPLL_RESET;
+ WREG32_PLL(RADEON_SPLL_CNTL, tmp);
+
+ DRM_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);
+
+ DRM_UDELAY(2);
+
+ tmp = RREG32_PLL(RADEON_SPLL_CNTL);
+ tmp &= ~RADEON_SPLL_RESET;
+ WREG32_PLL(RADEON_SPLL_CNTL, tmp);
+
+ DRM_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);
+
+ DRM_UDELAY(20);
+
+ tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
+ tmp |= RADEON_DONT_USE_XTALIN;
+ WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
+
+ DRM_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);
+ DRM_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);
+ DRM_MDELAY(15);
+
+ tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
+ tmp |= RADEON_SCLK_DYN_START_CNTL;
+ WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
+ DRM_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);
+ DRM_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);
+ }
+ DRM_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);
+ DRM_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);
+ DRM_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);
+
+ DRM_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);
+ DRM_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);
+ DRM_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);
+ DRM_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);
+ DRM_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/sys/dev/drm2/radeon/radeon_combios.c b/sys/dev/drm2/radeon/radeon_combios.c
new file mode 100644
index 0000000..caa8a00
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_combios.c
@@ -0,0 +1,3661 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "atom.h"
+
+#ifdef CONFIG_PPC_PMAC
+/* not sure which of these are needed */
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#endif /* CONFIG_PPC_PMAC */
+
+/* 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 = malloc(size, DRM_MEM_KMS, M_WAITOK);
+ if (edid == NULL)
+ return false;
+
+ memcpy((unsigned char *)edid, raw, size);
+
+ if (!drm_edid_is_valid(edid)) {
+ free(edid, DRM_MEM_KMS);
+ 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 = malloc(rdev->mode_info.bios_hardcoded_edid_size,
+ DRM_MEM_KMS, M_WAITOK);
+ 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;
+}
+
+static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct radeon_i2c_bus_rec i2c;
+ u16 offset;
+ u8 id, blocks, clk, data;
+ int i;
+
+ i2c.valid = false;
+
+ 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));
+ break;
+ }
+ }
+ }
+ 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) {
+ /* 0x68 */
+ i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
+ rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
+
+ /* gpiopad */
+ i2c = radeon_combios_get_i2c_info_from_table(rdev);
+ if (i2c.valid)
+ rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
+ } 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 = malloc(sizeof(struct radeon_encoder_primary_dac),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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 = malloc(sizeof(struct radeon_encoder_tv_dac),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 = malloc(sizeof(struct radeon_encoder_lvds),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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 = malloc(sizeof(struct radeon_encoder_lvds),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+
+ 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("PowerMac3,5")) {
+ /* PowerMac G4 Silver radeon 7500 */
+ rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
+ } 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 ((dev->pci_device == 0x4a48) &&
+ (dev->pci_subvendor == 0x1002) &&
+ (dev->pci_subdevice == 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")) &&
+ (dev->pci_device == 0x4150) &&
+ (dev->pci_subvendor == 0x1002) &&
+ (dev->pci_subdevice == 0x4150)) {
+ /* Mac G5 tower 9600 */
+ rdev->mode_info.connector_table = CT_MAC_G5_9600;
+ } else if ((dev->pci_device == 0x4c66) &&
+ (dev->pci_subvendor == 0x1002) &&
+ (dev->pci_subdevice == 0x4c66)) {
+ /* SAM440ep RV250 embedded board */
+ rdev->mode_info.connector_table = CT_SAM440EP;
+ } 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;
+ case CT_SAM440EP:
+ DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
+ rdev->mode_info.connector_table);
+ /* 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);
+ /* DVI-I - secondary 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, 1,
+ 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, 2,
+ 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, 3, ATOM_DEVICE_TV1_SUPPORT,
+ DRM_MODE_CONNECTOR_SVIDEO,
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO,
+ &hpd);
+ break;
+ case CT_MAC_G4_SILVER:
+ DRM_INFO("Connector Table: %d (mac g4 silver)\n",
+ rdev->mode_info.connector_table);
+ /* 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);
+ /* 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->pci_device == 0x515e &&
+ dev->pci_subvendor == 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->pci_device == 0x5B60 &&
+ dev->pci_subvendor == 0x17af &&
+ dev->pci_subdevice == 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->pci_device == 0x5975 &&
+ dev->pci_subvendor == 0x1025 &&
+ dev->pci_subdevice == 0x009f)
+ return false;
+
+ /* HP dc5750 has non-existent TV port */
+ if (dev->pci_device == 0x5974 &&
+ dev->pci_subvendor == 0x103c &&
+ dev->pci_subdevice == 0x280a)
+ return false;
+
+ /* MSI S270 has non-existent TV port */
+ if (dev->pci_device == 0x5955 &&
+ dev->pci_subvendor == 0x1462 &&
+ dev->pci_subdevice == 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;
+ if (ddc_type == 5)
+ ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
+ else
+ 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);
+ }
+ /* RV100 board with external TDMS bit mis-set.
+ * Actually uses internal TMDS, clear the bit.
+ */
+ if (dev->pci_device == 0x5159 &&
+ dev->pci_subvendor == 0x1014 &&
+ dev->pci_subdevice == 0x029A) {
+ tmp &= ~(1 << 4);
+ }
+ 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 = malloc(sizeof(struct radeon_power_state) * 2,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->pm.power_state) {
+ /* allocate 1 clock mode per state */
+ rdev->pm.power_state[0].clock_info =
+ malloc(sizeof(struct radeon_pm_clock_info) * 1,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ rdev->pm.power_state[1].clock_info =
+ malloc(sizeof(struct radeon_pm_clock_info) * 1,
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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) {
+#ifdef DUMBBELL_WIP
+ 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);
+#endif /* DUMBBELL_WIP */
+ }
+ }
+ } else {
+ /* boards with a thermal chip, but no overdrive table */
+
+ /* Asus 9600xt has an f75375 on the monid bus */
+ if ((dev->pci_device == 0x4152) &&
+ (dev->pci_subvendor == 0x1043) &&
+ (dev->pci_subdevice == 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) {
+#ifdef DUMBBELL_WIP
+ 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);
+#endif /* DUMBBELL_WIP */
+ }
+ }
+ }
+
+ 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;
+ DRM_UDELAY(val);
+ break;
+ case 4:
+ val = RBIOS16(index);
+ index += 2;
+ DRM_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;
+ DRM_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;
+ DRM_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:
+ DRM_UDELAY(150);
+ break;
+ case 2:
+ DRM_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);
+ DRM_MDELAY(10);
+#endif
+ WREG32_PLL
+ (RADEON_CLK_PWRMGT_CNTL,
+ tmp &
+ ~RADEON_CG_NO1_DEBUG_0);
+ DRM_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_IDX((addr) | RADEON_MM_APER, 0xdeadbeef);
+ /* read back and verify */
+ if (RREG32_IDX((addr) | RADEON_MM_APER) != 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_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 &&
+ dev->pci_subvendor == 0x103c &&
+ dev->pci_subdevice == 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 &&
+ dev->pci_subvendor == 0x103c &&
+ dev->pci_subdevice == 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 &&
+ dev->pci_subvendor == 0x103c &&
+ dev->pci_subdevice == 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/sys/dev/drm2/radeon/radeon_connectors.c b/sys/dev/drm2/radeon/radeon_connectors.c
new file mode 100644
index 0000000..57d7c26
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_connectors.c
@@ -0,0 +1,2040 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_edid.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/drm_fb_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "atom.h"
+
+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) {
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_connector->con_priv;
+
+ /* if existing sink type was not DP no need to retrain */
+ if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT)
+ return;
+
+ /* first get sink type as it may be reset after (un)plug */
+ dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
+ /* don't do anything if sink is not display port, i.e.,
+ * passive dp->(dvi|hdmi) adaptor
+ */
+ if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+ int saved_dpms = connector->dpms;
+ /* Only turn off the display if 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)) {
+ /* set it to OFF so that drm_helper_connector_dpms()
+ * won't return immediately since the current state
+ * is ON at this point.
+ */
+ connector->dpms = DRM_MODE_DPMS_OFF;
+ 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);
+ }
+}
+
+int radeon_get_monitor_bpc(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);
+ struct radeon_connector_atom_dig *dig_connector;
+ int bpc = 8;
+
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ if (radeon_connector->use_digital) {
+ if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (connector->display_info.bpc)
+ bpc = connector->display_info.bpc;
+ }
+ }
+ break;
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (connector->display_info.bpc)
+ bpc = connector->display_info.bpc;
+ }
+ 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) ||
+ drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (connector->display_info.bpc)
+ bpc = connector->display_info.bpc;
+ }
+ break;
+ case DRM_MODE_CONNECTOR_eDP:
+ case DRM_MODE_CONNECTOR_LVDS:
+ if (connector->display_info.bpc)
+ bpc = connector->display_info.bpc;
+ else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ struct drm_connector_helper_funcs *connector_funcs =
+ connector->helper_private;
+ struct drm_encoder *encoder = connector_funcs->best_encoder(connector);
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR)
+ bpc = 6;
+ else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR)
+ bpc = 8;
+ }
+ break;
+ }
+ return bpc;
+}
+
+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);
+
+ }
+}
+
+static 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;
+}
+
+static 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);
+ }
+}
+
+static 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)
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ free(radeon_connector->con_priv, DRM_MEM_DRIVER);
+#ifdef DUMBBELL_WIP
+ drm_sysfs_connector_remove(connector);
+#endif /* DUMBBELL_WIP */
+ drm_connector_cleanup(connector);
+ free(connector, DRM_MEM_DRIVER);
+}
+
+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;
+}
+
+
+static const 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,
+};
+
+static const 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, false);
+ if (dret) {
+ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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;
+}
+
+static const 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,
+};
+
+static const 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;
+}
+
+static const 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,
+};
+
+static const 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, broken_edid = false;
+
+ if (!force && radeon_check_hpd_status_unchanged(connector))
+ return connector->status;
+
+ if (radeon_connector->ddc_bus)
+ dret = radeon_ddc_probe(radeon_connector, false);
+ if (dret) {
+ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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 {
+ ret = connector_status_connected;
+ broken_edid = true; /* defer use_digital to later */
+ }
+ } 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) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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)) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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 (!broken_edid) {
+ if (ret != connector_status_connected) {
+ /* deal with analog monitors without DDC */
+ 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;
+ }
+ } else {
+ enum drm_connector_status lret;
+ /* assume digital unless load detected otherwise */
+ radeon_connector->use_digital = true;
+ lret = encoder_funcs->detect(encoder, connector);
+ DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
+ if (lret == connector_status_connected)
+ radeon_connector->use_digital = false;
+ }
+ 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 */
+static 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;
+}
+
+static const 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,
+};
+
+static const 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)
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ if (radeon_dig_connector->dp_i2c_bus)
+ radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
+ free(radeon_connector->con_priv, DRM_MEM_DRIVER);
+#ifdef DUMBBELL_WIP
+ drm_sysfs_connector_remove(connector);
+#endif /* DUMBBELL_WIP */
+ drm_connector_cleanup(connector);
+ free(connector, DRM_MEM_DRIVER);
+}
+
+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) {
+ free(radeon_connector->edid, DRM_MEM_KMS);
+ 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);
+ /* bridge chips are always aux */
+ if (radeon_ddc_probe(radeon_connector, true)) /* 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 {
+ /* try non-aux ddc (DP to DVI/HMDI/etc. adapter) */
+ if (radeon_ddc_probe(radeon_connector, false))
+ 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;
+ }
+}
+
+static const 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,
+};
+
+static const 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 = malloc(sizeof(struct radeon_connector),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(
+ sizeof(struct radeon_connector_atom_dig),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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;
+#ifdef DUMBBELL_WIP
+ drm_sysfs_connector_add(connector);
+#endif /* DUMBBELL_WIP */
+ return;
+
+failed:
+ drm_connector_cleanup(connector);
+ free(connector, DRM_MEM_DRIVER);
+}
+
+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 = malloc(sizeof(struct radeon_connector),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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;
+#ifdef DUMBBELL_WIP
+ drm_sysfs_connector_add(connector);
+#endif /* DUMBBELL_WIP */
+}
diff --git a/sys/dev/drm2/radeon/radeon_cp.c b/sys/dev/drm2/radeon/radeon_cp.c
new file mode 100644
index 0000000..4a03633
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_cp.c
@@ -0,0 +1,2245 @@
+/* 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 <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_drv.h"
+#include "r300_reg.h"
+
+#define RADEON_FIFO_DEBUG 0
+
+/* Firmware Names */
+#define FIRMWARE_R100 "radeonkmsfw_R100_cp"
+#define FIRMWARE_R200 "radeonkmsfw_R200_cp"
+#define FIRMWARE_R300 "radeonkmsfw_R300_cp"
+#define FIRMWARE_R420 "radeonkmsfw_R420_cp"
+#define FIRMWARE_RS690 "radeonkmsfw_RS690_cp"
+#define FIRMWARE_RS600 "radeonkmsfw_RS600_cp"
+#define FIRMWARE_R520 "radeonkmsfw_R520_cp"
+
+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);
+ }
+}
+
+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->pci_device == 0x5e4c) ||
+ (dev->pci_device == 0x5e4f))
+ dev_priv->num_gb_pipes = 1;
+ } else {
+ /* R3xx */
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+ dev->pci_device != 0x4144) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+ dev->pci_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)
+{
+ const char *fw_name = NULL;
+ int err;
+
+ DRM_DEBUG("\n");
+
+ 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 = 0;
+
+ dev_priv->me_fw = firmware_get(fw_name);
+ if (dev_priv->me_fw == NULL) {
+ err = -ENOENT;
+ DRM_ERROR("radeon_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ } else if (dev_priv->me_fw->datasize % 8) {
+ DRM_ERROR(
+ "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+ dev_priv->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ firmware_put(dev_priv->me_fw, FIRMWARE_UNLOAD);
+ 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->datasize / 4;
+ fw_data = (const __be32 *)dev_priv->me_fw->data;
+ 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->vaddr
+ + 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->vaddr)
+ + 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->masterp->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->masterp->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->vaddr
+ + 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 <http://cpbotha.net>
+ */
+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);
+ break;
+ 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 != NULL) {
+ firmware_put(dev_priv->me_fw, FIRMWARE_UNLOAD);
+ dev_priv->me_fw = NULL;
+ }
+ if (dev_priv->pfp_fw != NULL) {
+ firmware_put(dev_priv->pfp_fw, FIRMWARE_UNLOAD);
+ 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 = malloc(sizeof(drm_radeon_private_t),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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_enable_busmaster(dev->device);
+
+ if (drm_device_is_agp(dev))
+ dev_priv->flags |= RADEON_IS_AGP;
+ else if (drm_device_is_pcie(dev))
+ dev_priv->flags |= RADEON_IS_PCIE;
+ else
+ dev_priv->flags |= RADEON_IS_PCI;
+
+ ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
+ drm_get_resource_len(dev, 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 = malloc(sizeof(*master_priv),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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");
+ free(master_priv, DRM_MEM_DRIVER);
+ return ret;
+ }
+ master_priv->sarea_priv = (drm_radeon_sarea_t *)((char *)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)
+#ifdef __linux__
+ drm_rmmap_locked(dev, master_priv->sarea);
+#else
+ drm_rmmap(dev, master_priv->sarea);
+#endif
+
+ free(master_priv, DRM_MEM_DRIVER);
+
+ 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 = drm_get_resource_start(dev, 0);
+ ret = drm_addmap(dev, dev_priv->fb_aper_offset,
+ drm_get_resource_len(dev, 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);
+
+ free(dev_priv, DRM_MEM_DRIVER);
+
+ 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/sys/dev/drm2/radeon/radeon_cs.c b/sys/dev/drm2/radeon/radeon_cs.c
new file mode 100644
index 0000000..ee299fa
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_cs.c
@@ -0,0 +1,658 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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);
+
+static 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];
+ p->dma_reloc_idx = 0;
+ /* FIXME: we assume that each relocs use 4 dwords */
+ p->nrelocs = chunk->length_dw / 4;
+ p->relocs_ptr = malloc(p->nrelocs * sizeof(void *),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (p->relocs_ptr == NULL) {
+ return -ENOMEM;
+ }
+ p->relocs = malloc(p->nrelocs * sizeof(struct radeon_cs_reloc),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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;
+ case RADEON_CS_RING_DMA:
+ if (p->rdev->family >= CHIP_CAYMAN) {
+ if (p->priority > 0)
+ p->ring = R600_RING_TYPE_DMA_INDEX;
+ else
+ p->ring = CAYMAN_RING_TYPE_DMA1_INDEX;
+ } else if (p->rdev->family >= CHIP_R600) {
+ p->ring = R600_RING_TYPE_DMA_INDEX;
+ } else {
+ return -EINVAL;
+ }
+ break;
+ }
+ return 0;
+}
+
+static void radeon_cs_sync_to(struct radeon_cs_parser *p,
+ struct radeon_fence *fence)
+{
+ struct radeon_fence *other;
+
+ if (!fence)
+ return;
+
+ other = p->ib.sync_to[fence->ring];
+ p->ib.sync_to[fence->ring] = radeon_fence_later(fence, other);
+}
+
+static void radeon_cs_sync_rings(struct radeon_cs_parser *p)
+{
+ int i;
+
+ for (i = 0; i < p->nrelocs; i++) {
+ if (!p->relocs[i].robj)
+ continue;
+
+ radeon_cs_sync_to(p, p->relocs[i].robj->tbo.sync_obj);
+ }
+}
+
+/* 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->ib.sa_bo = NULL;
+ p->ib.semaphore = NULL;
+ p->const_ib.sa_bo = NULL;
+ p->const_ib.semaphore = NULL;
+ p->chunk_ib_idx = -1;
+ p->chunk_relocs_idx = -1;
+ p->chunk_flags_idx = -1;
+ p->chunk_const_ib_idx = -1;
+ p->chunks_array = malloc(cs->num_chunks * sizeof(uint64_t),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(p->nchunks * sizeof(struct radeon_cs_chunk),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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 = malloc(size, DRM_MEM_DRIVER, M_WAITOK);
+ 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;
+ }
+ if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) {
+ p->chunks[p->chunk_ib_idx].kpage[0] = malloc(PAGE_SIZE, DRM_MEM_DRIVER, M_WAITOK);
+ p->chunks[p->chunk_ib_idx].kpage[1] = malloc(PAGE_SIZE, DRM_MEM_DRIVER, M_WAITOK);
+ if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL ||
+ p->chunks[p->chunk_ib_idx].kpage[1] == NULL) {
+ free(p->chunks[p->chunk_ib_idx].kpage[0], DRM_MEM_DRIVER);
+ free(p->chunks[p->chunk_ib_idx].kpage[1], DRM_MEM_DRIVER);
+ 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) {
+ 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);
+ }
+ }
+ free(parser->track, DRM_MEM_DRIVER);
+ free(parser->relocs, DRM_MEM_DRIVER);
+ free(parser->relocs_ptr, DRM_MEM_DRIVER);
+ for (i = 0; i < parser->nchunks; i++) {
+ free(parser->chunks[i].kdata, DRM_MEM_DRIVER);
+ if ((parser->rdev->flags & RADEON_IS_AGP)) {
+ free(parser->chunks[i].kpage[0], DRM_MEM_DRIVER);
+ free(parser->chunks[i].kpage[1], DRM_MEM_DRIVER);
+ }
+ }
+ free(parser->chunks, DRM_MEM_DRIVER);
+ free(parser->chunks_array, DRM_MEM_DRIVER);
+ radeon_ib_free(parser->rdev, &parser->ib);
+ radeon_ib_free(parser->rdev, &parser->const_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,
+ NULL, 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;
+ }
+ radeon_cs_sync_rings(parser);
+ r = radeon_ib_schedule(rdev, &parser->ib, NULL);
+ if (r) {
+ DRM_ERROR("Failed to schedule IB !\n");
+ }
+ return r;
+}
+
+static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser,
+ struct radeon_vm *vm)
+{
+ struct radeon_device *rdev = parser->rdev;
+ struct radeon_bo_list *lobj;
+ struct radeon_bo *bo;
+ int r;
+
+ r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem);
+ if (r) {
+ return 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,
+ vm, 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,
+ vm, 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;
+ }
+
+ sx_xlock(&rdev->vm_manager.lock);
+ sx_xlock(&vm->mutex);
+ r = radeon_vm_alloc_pt(rdev, vm);
+ if (r) {
+ goto out;
+ }
+ r = radeon_bo_vm_update_pte(parser, vm);
+ if (r) {
+ goto out;
+ }
+ radeon_cs_sync_rings(parser);
+ radeon_cs_sync_to(parser, vm->fence);
+ radeon_cs_sync_to(parser, radeon_vm_grab_id(rdev, vm, parser->ring));
+
+ if ((rdev->family >= CHIP_TAHITI) &&
+ (parser->chunk_const_ib_idx != -1)) {
+ r = radeon_ib_schedule(rdev, &parser->ib, &parser->const_ib);
+ } else {
+ r = radeon_ib_schedule(rdev, &parser->ib, NULL);
+ }
+
+ if (!r) {
+ radeon_vm_fence(rdev, vm, parser->ib.fence);
+ }
+
+out:
+ radeon_vm_add_to_lru(rdev, vm);
+ sx_xunlock(&vm->mutex);
+ sx_xunlock(&rdev->vm_manager.lock);
+ return r;
+}
+
+static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r)
+{
+ if (r == -EDEADLK) {
+ r = radeon_gpu_reset(rdev);
+ if (!r)
+ r = -EAGAIN;
+ }
+ 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;
+
+ sx_slock(&rdev->exclusive_lock);
+ if (!rdev->accel_working) {
+ sx_sunlock(&rdev->exclusive_lock);
+ 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);
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_cs_handle_lockup(rdev, r);
+ 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);
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_cs_handle_lockup(rdev, r);
+ 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);
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_cs_handle_lockup(rdev, r);
+ 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)),
+ (char *)ibc->user_ptr + (i * PAGE_SIZE),
+ size))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static 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;
+ bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ?
+ false : true;
+
+ for (i = ibc->last_copied_page + 1; i < pg_idx; i++) {
+ if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)),
+ (char *)ibc->user_ptr + (i * PAGE_SIZE),
+ PAGE_SIZE)) {
+ p->parser_error = -EFAULT;
+ return 0;
+ }
+ }
+
+ if (pg_idx == ibc->last_page_index) {
+ size = (ibc->length_dw * 4) % PAGE_SIZE;
+ if (size == 0)
+ size = PAGE_SIZE;
+ }
+
+ new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1;
+ if (copy1)
+ ibc->kpage[new_page] = p->ib.ptr + (pg_idx * (PAGE_SIZE / 4));
+
+ if (DRM_COPY_FROM_USER(ibc->kpage[new_page],
+ (char *)ibc->user_ptr + (pg_idx * PAGE_SIZE),
+ size)) {
+ p->parser_error = -EFAULT;
+ return 0;
+ }
+
+ /* copy to IB for non single case */
+ if (!copy1)
+ 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;
+}
+
+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;
+}
diff --git a/sys/dev/drm2/radeon/radeon_cursor.c b/sys/dev/drm2/radeon/radeon_cursor.c
new file mode 100644
index 0000000..0b4e73e
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_cursor.c
@@ -0,0 +1,316 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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_IDX(EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset,
+ EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) |
+ EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2));
+ } else if (ASIC_IS_AVIVO(rdev)) {
+ WREG32_IDX(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
+ (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
+ } else {
+ u32 reg;
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ reg = RADEON_CRTC_GEN_CNTL;
+ break;
+ case 1:
+ reg = RADEON_CRTC2_GEN_CNTL;
+ break;
+ default:
+ return;
+ }
+ WREG32_IDX(reg, RREG32_IDX(reg) & ~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) |
+ EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2));
+ } 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;
+ }
+
+ /* fixed on DCE6 and newer */
+ if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(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;
+ cursor_end = x - xorigin + w;
+ if (!(cursor_end & 0x7f)) {
+ x--;
+ if (x < 0) {
+ DRM_ERROR("%s: x(%d) < 0", __func__, x);
+ }
+ }
+ }
+ }
+ }
+
+ 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/sys/dev/drm2/radeon/radeon_device.c b/sys/dev/drm2/radeon/radeon_device.c
new file mode 100644
index 0000000..5ed74fd
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_device.c
@@ -0,0 +1,1551 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#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",
+};
+
+/**
+ * radeon_surface_init - Clear GPU surface registers.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Clear GPU surface registers (r1xx-r5xx).
+ */
+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.
+ */
+/**
+ * radeon_scratch_init - Init scratch register driver information.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Init CP scratch register driver information (r1xx-r5xx)
+ */
+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);
+ }
+}
+
+/**
+ * radeon_scratch_get - Allocate a scratch register
+ *
+ * @rdev: radeon_device pointer
+ * @reg: scratch register mmio offset
+ *
+ * Allocate a CP scratch register for use by the driver (all asics).
+ * Returns 0 on success or -EINVAL on failure.
+ */
+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;
+}
+
+/**
+ * radeon_scratch_free - Free a scratch register
+ *
+ * @rdev: radeon_device pointer
+ * @reg: scratch register mmio offset
+ *
+ * Free a CP scratch register allocated for use by the driver (all asics)
+ */
+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;
+ }
+ }
+}
+
+/*
+ * radeon_wb_*()
+ * Writeback is the the method by which the the GPU updates special pages
+ * in memory with the status of certain GPU events (fences, ring pointers,
+ * etc.).
+ */
+
+/**
+ * radeon_wb_disable - Disable Writeback
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disables Writeback (all asics). Used for suspend.
+ */
+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;
+}
+
+/**
+ * radeon_wb_fini - Disable Writeback and free memory
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disables Writeback and frees the Writeback memory (all asics).
+ * Used at driver shutdown.
+ */
+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;
+ }
+}
+
+/**
+ * radeon_wb_init- Init Writeback driver info and allocate memory
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disables Writeback and frees the Writeback memory (all asics).
+ * Used at driver startup.
+ * Returns 0 on success or an -error on failure.
+ */
+int radeon_wb_init(struct radeon_device *rdev)
+{
+ int r;
+ void *wb_ptr;
+
+ if (rdev->wb.wb_obj == NULL) {
+ r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_GTT, NULL, &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;
+ }
+ wb_ptr = &rdev->wb.wb;
+ r = radeon_bo_kmap(rdev->wb.wb_obj, wb_ptr);
+ 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(*(void **)wb_ptr, 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)
+{
+ uint64_t limit = (uint64_t)radeon_vram_limit << 20;
+
+ 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 (limit && limit < mc->real_vram_size)
+ mc->real_vram_size = limit;
+ dev_info(rdev->dev, "VRAM: %juM 0x%016jX - 0x%016jX (%juM used)\n",
+ (uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start,
+ (uintmax_t)mc->vram_end, (uintmax_t)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: %juM 0x%016jX - 0x%016jX\n",
+ (uintmax_t)mc->gtt_size >> 20, (uintmax_t)mc->gtt_start, (uintmax_t)mc->gtt_end);
+}
+
+/*
+ * GPU helpers function.
+ */
+/**
+ * radeon_card_posted - check if the hw has already been initialized
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check if the asic has been initialized (all asics).
+ * Used at driver startup.
+ * Returns true if initialized or false if not.
+ */
+bool radeon_card_posted(struct radeon_device *rdev)
+{
+ uint32_t reg;
+
+#ifdef DUMBBELL_WIP
+ if (efi_enabled(EFI_BOOT) &&
+ rdev->dev->pci_subvendor == PCI_VENDOR_ID_APPLE)
+ return false;
+#endif /* DUMBBELL_WIP */
+
+ /* 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;
+
+}
+
+/**
+ * radeon_update_bandwidth_info - update display bandwidth params
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Used when sclk/mclk are switched or display modes are set.
+ * params are used to calculate display watermarks (all asics)
+ */
+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);
+ }
+}
+
+/**
+ * radeon_boot_test_post_card - check and possibly initialize the hw
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check if the asic is initialized and if not, attempt to initialize
+ * it (all asics).
+ * Returns true if initialized or false if not.
+ */
+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;
+ }
+}
+
+/**
+ * radeon_dummy_page_init - init dummy page used by the driver
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Allocate the dummy page used by the driver (all asics).
+ * This dummy page is used by the driver as a filler for gart entries
+ * when pages are taken out of the GART
+ * Returns 0 on sucess, -ENOMEM on failure.
+ */
+int radeon_dummy_page_init(struct radeon_device *rdev)
+{
+ if (rdev->dummy_page.dmah)
+ return 0;
+ rdev->dummy_page.dmah = drm_pci_alloc(rdev->ddev,
+ PAGE_SIZE, PAGE_SIZE, ~0);
+ if (rdev->dummy_page.dmah == NULL)
+ return -ENOMEM;
+ rdev->dummy_page.addr = (dma_addr_t)rdev->dummy_page.dmah->vaddr;
+ return 0;
+}
+
+/**
+ * radeon_dummy_page_fini - free dummy page used by the driver
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Frees the dummy page used by the driver (all asics).
+ */
+void radeon_dummy_page_fini(struct radeon_device *rdev)
+{
+ if (rdev->dummy_page.dmah == NULL)
+ return;
+ drm_pci_free(rdev->ddev, rdev->dummy_page.dmah);
+ rdev->dummy_page.dmah = NULL;
+ rdev->dummy_page.addr = 0;
+}
+
+
+/* ATOM accessor methods */
+/*
+ * ATOM is an interpreted byte code stored in tables in the vbios. The
+ * driver registers callbacks to access registers and the interpreter
+ * in the driver parses the tables and executes then to program specific
+ * actions (set display modes, asic init, etc.). See radeon_atombios.c,
+ * atombios.h, and atom.c
+ */
+
+/**
+ * cail_pll_read - read PLL register
+ *
+ * @info: atom card_info pointer
+ * @reg: PLL register offset
+ *
+ * Provides a PLL register accessor for the atom interpreter (r4xx+).
+ * Returns the value of the PLL register.
+ */
+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;
+}
+
+/**
+ * cail_pll_write - write PLL register
+ *
+ * @info: atom card_info pointer
+ * @reg: PLL register offset
+ * @val: value to write to the pll register
+ *
+ * Provides a PLL register accessor for the atom interpreter (r4xx+).
+ */
+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);
+}
+
+/**
+ * cail_mc_read - read MC (Memory Controller) register
+ *
+ * @info: atom card_info pointer
+ * @reg: MC register offset
+ *
+ * Provides an MC register accessor for the atom interpreter (r4xx+).
+ * Returns the value of the MC register.
+ */
+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;
+}
+
+/**
+ * cail_mc_write - write MC (Memory Controller) register
+ *
+ * @info: atom card_info pointer
+ * @reg: MC register offset
+ * @val: value to write to the pll register
+ *
+ * Provides a MC register accessor for the atom interpreter (r4xx+).
+ */
+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);
+}
+
+/**
+ * cail_reg_write - write MMIO register
+ *
+ * @info: atom card_info pointer
+ * @reg: MMIO register offset
+ * @val: value to write to the pll register
+ *
+ * Provides a MMIO register accessor for the atom interpreter (r4xx+).
+ */
+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);
+}
+
+/**
+ * cail_reg_read - read MMIO register
+ *
+ * @info: atom card_info pointer
+ * @reg: MMIO register offset
+ *
+ * Provides an MMIO register accessor for the atom interpreter (r4xx+).
+ * Returns the value of the MMIO register.
+ */
+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;
+}
+
+/**
+ * cail_ioreg_write - write IO register
+ *
+ * @info: atom card_info pointer
+ * @reg: IO register offset
+ * @val: value to write to the pll register
+ *
+ * Provides a IO register accessor for the atom interpreter (r4xx+).
+ */
+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);
+}
+
+/**
+ * cail_ioreg_read - read IO register
+ *
+ * @info: atom card_info pointer
+ * @reg: IO register offset
+ *
+ * Provides an IO register accessor for the atom interpreter (r4xx+).
+ * Returns the value of the IO register.
+ */
+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;
+}
+
+/**
+ * radeon_atombios_init - init the driver info and callbacks for atombios
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initializes the driver info and register access callbacks for the
+ * ATOM interpreter (r4xx+).
+ * Returns 0 on sucess, -ENOMEM on failure.
+ * Called at driver startup.
+ */
+int radeon_atombios_init(struct radeon_device *rdev)
+{
+ struct card_info *atom_card_info =
+ malloc(sizeof(struct card_info),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ 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);
+ sx_init(&rdev->mode_info.atom_context->mutex,
+ "drm__radeon_device__mode_info__atom_context__mutex");
+ radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
+ atom_allocate_fb_scratch(rdev->mode_info.atom_context);
+ return 0;
+}
+
+/**
+ * radeon_atombios_fini - free the driver info and callbacks for atombios
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Frees the driver info and register access callbacks for the ATOM
+ * interpreter (r4xx+).
+ * Called at driver shutdown.
+ */
+void radeon_atombios_fini(struct radeon_device *rdev)
+{
+ if (rdev->mode_info.atom_context) {
+ free(rdev->mode_info.atom_context->scratch, DRM_MEM_DRIVER);
+ atom_destroy(rdev->mode_info.atom_context);
+ }
+ free(rdev->mode_info.atom_card_info, DRM_MEM_DRIVER);
+}
+
+/* COMBIOS */
+/*
+ * COMBIOS is the bios format prior to ATOM. It provides
+ * command tables similar to ATOM, but doesn't have a unified
+ * parser. See radeon_combios.c
+ */
+
+/**
+ * radeon_combios_init - init the driver info for combios
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initializes the driver info for combios (r1xx-r3xx).
+ * Returns 0 on sucess.
+ * Called at driver startup.
+ */
+int radeon_combios_init(struct radeon_device *rdev)
+{
+ radeon_combios_initialize_bios_scratch_regs(rdev->ddev);
+ return 0;
+}
+
+/**
+ * radeon_combios_fini - free the driver info for combios
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Frees the driver info for combios (r1xx-r3xx).
+ * Called at driver shutdown.
+ */
+void radeon_combios_fini(struct radeon_device *rdev)
+{
+}
+
+#ifdef DUMBBELL_WIP
+/* if we get transitioned to only one device, take VGA back */
+/**
+ * radeon_vga_set_decode - enable/disable vga decode
+ *
+ * @cookie: radeon_device pointer
+ * @state: enable/disable vga decode
+ *
+ * Enable/disable vga decode (all asics).
+ * Returns VGA resource flags.
+ */
+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;
+}
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_check_pot_argument - check that argument is a power of two
+ *
+ * @arg: value to check
+ *
+ * Validates that a certain argument is a power of two (all asics).
+ * Returns true if argument is valid.
+ */
+static bool radeon_check_pot_argument(int arg)
+{
+ return (arg & (arg - 1)) == 0;
+}
+
+/**
+ * radeon_check_arguments - validate module params
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Validates certain module parameters and updates
+ * the associated values used by the driver (all asics).
+ */
+static void radeon_check_arguments(struct radeon_device *rdev)
+{
+ /* vramlimit must be a power of two */
+ if (!radeon_check_pot_argument(radeon_vram_limit)) {
+ dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
+ radeon_vram_limit);
+ radeon_vram_limit = 0;
+ }
+
+ /* gtt size must be power of two and greater or equal to 32M */
+ if (radeon_gart_size < 32) {
+ dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n",
+ radeon_gart_size);
+ radeon_gart_size = 512;
+
+ } else if (!radeon_check_pot_argument(radeon_gart_size)) {
+ dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n",
+ radeon_gart_size);
+ radeon_gart_size = 512;
+ }
+ rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20;
+
+ /* 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;
+ }
+}
+
+/**
+ * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is
+ * needed for waking up.
+ *
+ * @pdev: pci dev pointer
+ */
+#ifdef DUMBBELL_WIP
+static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
+{
+
+ /* 6600m in a macbook pro */
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
+ pdev->subsystem_device == 0x00e2) {
+ printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n");
+ return true;
+ }
+
+ return false;
+}
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_switcheroo_set_state - set switcheroo state
+ *
+ * @pdev: pci dev pointer
+ * @state: vga switcheroo state
+ *
+ * Callback for the switcheroo driver. Suspends or resumes the
+ * the asics before or after it is powered up using ACPI methods.
+ */
+#ifdef DUMBBELL_WIP
+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) {
+ unsigned d3_delay = dev->pdev->d3_delay;
+
+ printk(KERN_INFO "radeon: switched on\n");
+ /* don't suspend or resume card normally */
+ dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
+
+ if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev))
+ dev->pdev->d3_delay = 20;
+
+ radeon_resume_kms(dev);
+
+ dev->pdev->d3_delay = d3_delay;
+
+ 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;
+ }
+}
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_switcheroo_can_switch - see if switcheroo state can change
+ *
+ * @pdev: pci dev pointer
+ *
+ * Callback for the switcheroo driver. Check of the switcheroo
+ * state can be changed.
+ * Returns true if the state can be changed, false if not.
+ */
+#ifdef DUMBBELL_WIP
+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;
+}
+
+static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
+ .set_gpu_state = radeon_switcheroo_set_state,
+ .reprobe = NULL,
+ .can_switch = radeon_switcheroo_can_switch,
+};
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_device_init - initialize the driver
+ *
+ * @rdev: radeon_device pointer
+ * @pdev: drm dev pointer
+ * @flags: driver flags
+ *
+ * Initializes the driver info and hw (all asics).
+ * Returns 0 for success or an error on failure.
+ * Called at driver startup.
+ */
+int radeon_device_init(struct radeon_device *rdev,
+ struct drm_device *ddev,
+ uint32_t flags)
+{
+ int r, i;
+ int dma_bits;
+
+ rdev->shutdown = false;
+ rdev->dev = ddev->device;
+ rdev->ddev = ddev;
+ 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->accel_working = false;
+ rdev->fictitious_range_registered = false;
+ /* set up ring ids */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ rdev->ring[i].idx = i;
+ }
+
+ DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n",
+ radeon_family_name[rdev->family], ddev->pci_vendor, ddev->pci_device,
+ ddev->pci_subvendor, ddev->pci_subdevice);
+
+ /* mutex initialization are all done here so we
+ * can recall function without having locking issues */
+ sx_init(&rdev->ring_lock, "drm__radeon_device__ring_lock");
+ sx_init(&rdev->dc_hw_i2c_mutex, "drm__radeon_device__dc_hw_i2c_mutex");
+ atomic_set(&rdev->ih.lock, 0);
+ sx_init(&rdev->gem.mutex, "drm__radeon_device__gem__mutex");
+ sx_init(&rdev->pm.mutex, "drm__radeon_device__pm__mutex");
+ sx_init(&rdev->gpu_clock_mutex, "drm__radeon_device__gpu_clock_mutex");
+ sx_init(&rdev->pm.mclk_lock, "drm__radeon_device__pm__mclk_lock");
+ sx_init(&rdev->exclusive_lock, "drm__radeon_device__exclusive_lock");
+ DRM_INIT_WAITQUEUE(&rdev->irq.vblank_queue);
+ r = radeon_gem_init(rdev);
+ if (r)
+ return r;
+ /* initialize vm here */
+ sx_init(&rdev->vm_manager.lock, "drm__radeon_device__vm_manager__lock");
+ /* Adjust VM size here.
+ * Currently set to 4GB ((1 << 20) 4k pages).
+ * Max GPUVM size for cayman and SI is 40 bits.
+ */
+ 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_RS740))
+ rdev->need_dma32 = true;
+
+ dma_bits = rdev->need_dma32 ? 32 : 40;
+#ifdef DUMBBELL_WIP
+ 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");
+ }
+#endif /* DUMBBELL_WIP */
+
+ /* Registers mapping */
+ /* TODO: block userspace mapping of io register */
+ DRM_SPININIT(&rdev->mmio_idx_lock, "drm__radeon_device__mmio_idx_lock");
+ rdev->rmmio_rid = PCIR_BAR(2);
+ rdev->rmmio = bus_alloc_resource_any(rdev->dev, SYS_RES_MEMORY,
+ &rdev->rmmio_rid, RF_ACTIVE | RF_SHAREABLE);
+ if (rdev->rmmio == NULL) {
+ return -ENOMEM;
+ }
+ rdev->rmmio_base = rman_get_start(rdev->rmmio);
+ rdev->rmmio_size = rman_get_size(rdev->rmmio);
+ 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 < DRM_MAX_PCI_RESOURCE; i++) {
+ uint32_t data;
+
+ data = pci_read_config(rdev->dev, PCIR_BAR(i), 4);
+ if (PCI_BAR_IO(data)) {
+ rdev->rio_rid = PCIR_BAR(i);
+ rdev->rio_mem = bus_alloc_resource_any(rdev->dev,
+ SYS_RES_IOPORT, &rdev->rio_rid,
+ RF_ACTIVE | RF_SHAREABLE);
+ break;
+ }
+ }
+ if (rdev->rio_mem == NULL)
+ DRM_ERROR("Unable to find PCI I/O BAR\n");
+
+ rdev->tq = taskqueue_create("radeonkms", M_WAITOK,
+ taskqueue_thread_enqueue, &rdev->tq);
+ taskqueue_start_threads(&rdev->tq, 1, PWAIT, "radeon taskq");
+
+#ifdef DUMBBELL_WIP
+ /* 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_ops);
+#endif /* DUMBBELL_WIP */
+
+ r = radeon_init(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_ring_tests(rdev);
+ if (r)
+ DRM_ERROR("ib ring test failed (%d).\n", 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;
+ }
+
+ DRM_INFO("%s: Taking over the fictitious range 0x%jx-0x%jx\n",
+ __func__, (uintmax_t)rdev->mc.aper_base,
+ (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size);
+ r = vm_phys_fictitious_reg_range(
+ rdev->mc.aper_base,
+ rdev->mc.aper_base + rdev->mc.visible_vram_size,
+ VM_MEMATTR_WRITE_COMBINING);
+ if (r != 0) {
+ DRM_ERROR("Failed to register fictitious range "
+ "0x%jx-0x%jx (%d).\n", (uintmax_t)rdev->mc.aper_base,
+ (uintmax_t)rdev->mc.aper_base + rdev->mc.visible_vram_size, r);
+ return (-r);
+ }
+ rdev->fictitious_range_registered = true;
+
+ 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;
+}
+
+#ifdef DUMBBELL_WIP
+static void radeon_debugfs_remove_files(struct radeon_device *rdev);
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_device_fini - tear down the driver
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the driver info (all asics).
+ * Called at driver shutdown.
+ */
+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);
+
+ if (rdev->fictitious_range_registered) {
+ vm_phys_fictitious_unreg_range(
+ rdev->mc.aper_base,
+ rdev->mc.aper_base + rdev->mc.visible_vram_size);
+ }
+
+ radeon_fini(rdev);
+#ifdef DUMBBELL_WIP
+ vga_switcheroo_unregister_client(rdev->pdev);
+ vga_client_register(rdev->pdev, NULL, NULL, NULL);
+#endif /* DUMBBELL_WIP */
+
+ if (rdev->tq != NULL) {
+ taskqueue_free(rdev->tq);
+ rdev->tq = NULL;
+ }
+
+ if (rdev->rio_mem)
+ bus_release_resource(rdev->dev, SYS_RES_IOPORT, rdev->rio_rid,
+ rdev->rio_mem);
+ rdev->rio_mem = NULL;
+ bus_release_resource(rdev->dev, SYS_RES_MEMORY, rdev->rmmio_rid,
+ rdev->rmmio);
+ rdev->rmmio = NULL;
+#ifdef DUMBBELL_WIP
+ radeon_debugfs_remove_files(rdev);
+#endif /* DUMBBELL_WIP */
+}
+
+
+/*
+ * Suspend & resume.
+ */
+/**
+ * radeon_suspend_kms - initiate device suspend
+ *
+ * @pdev: drm dev pointer
+ * @state: suspend state
+ *
+ * Puts the hw in the suspend state (all asics).
+ * Returns 0 for success or an error on failure.
+ * Called at driver suspend.
+ */
+int radeon_suspend_kms(struct drm_device *dev)
+{
+ struct radeon_device *rdev;
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
+ int i, r;
+ bool force_completion = false;
+
+ if (dev == NULL || dev->dev_private == NULL) {
+ return -ENODEV;
+ }
+#ifdef DUMBBELL_WIP
+ if (state.event == PM_EVENT_PRETHAW) {
+ return 0;
+ }
+#endif /* DUMBBELL_WIP */
+ 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);
+
+ sx_xlock(&rdev->ring_lock);
+ /* wait for gpu to finish processing current batch */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ r = radeon_fence_wait_empty_locked(rdev, i);
+ if (r) {
+ /* delay GPU reset to resume */
+ force_completion = true;
+ }
+ }
+ if (force_completion) {
+ radeon_fence_driver_force_completion(rdev);
+ }
+ sx_xunlock(&rdev->ring_lock);
+
+ 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->device);
+#ifdef DUMBBELL_WIP
+ if (state.event == PM_EVENT_SUSPEND) {
+ /* Shut down the device */
+ pci_disable_device(dev->pdev);
+#endif /* DUMBBELL_WIP */
+ pci_set_powerstate(dev->device, PCI_POWERSTATE_D3);
+#ifdef DUMBBELL_WIP
+ }
+ console_lock();
+#endif /* DUMBBELL_WIP */
+ radeon_fbdev_set_suspend(rdev, 1);
+#ifdef DUMBBELL_WIP
+ console_unlock();
+#endif /* DUMBBELL_WIP */
+ return 0;
+}
+
+/**
+ * radeon_resume_kms - initiate device resume
+ *
+ * @pdev: drm dev pointer
+ *
+ * Bring the hw back to operating state (all asics).
+ * Returns 0 for success or an error on failure.
+ * Called at driver resume.
+ */
+int radeon_resume_kms(struct drm_device *dev)
+{
+ struct drm_connector *connector;
+ struct radeon_device *rdev = dev->dev_private;
+ int r;
+
+ if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+ return 0;
+
+#ifdef DUMBBELL_WIP
+ console_lock();
+#endif /* DUMBBELL_WIP */
+ pci_set_powerstate(dev->device, PCI_POWERSTATE_D0);
+ pci_restore_state(dev->device);
+#ifdef DUMBBELL_WIP
+ if (pci_enable_device(dev->pdev)) {
+ console_unlock();
+ return -1;
+ }
+#endif /* DUMBBELL_WIP */
+ /* resume AGP if in use */
+ radeon_agp_resume(rdev);
+ radeon_resume(rdev);
+
+ r = radeon_ib_ring_tests(rdev);
+ if (r)
+ DRM_ERROR("ib ring test failed (%d).\n", r);
+
+ radeon_pm_resume(rdev);
+ radeon_restore_bios_scratch_regs(rdev);
+
+ radeon_fbdev_set_suspend(rdev, 0);
+#ifdef DUMBBELL_WIP
+ console_unlock();
+#endif /* DUMBBELL_WIP */
+
+ /* init dig PHYs, disp eng pll */
+ if (rdev->is_atom_bios) {
+ radeon_atom_encoder_init(rdev);
+ radeon_atom_disp_eng_pll_init(rdev);
+ /* turn on the BL */
+ if (rdev->mode_info.bl_encoder) {
+ u8 bl_level = radeon_get_backlight_level(rdev,
+ rdev->mode_info.bl_encoder);
+ radeon_set_backlight_level(rdev, rdev->mode_info.bl_encoder,
+ bl_level);
+ }
+ }
+ /* 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;
+}
+
+/**
+ * radeon_gpu_reset - reset the asic
+ *
+ * @rdev: radeon device pointer
+ *
+ * Attempt the reset the GPU if it has hung (all asics).
+ * Returns 0 for success or an error on failure.
+ */
+int radeon_gpu_reset(struct radeon_device *rdev)
+{
+ unsigned ring_sizes[RADEON_NUM_RINGS];
+ uint32_t *ring_data[RADEON_NUM_RINGS];
+
+ bool saved = false;
+
+ int i, r;
+ int resched;
+
+ sx_xlock(&rdev->exclusive_lock);
+ radeon_save_bios_scratch_regs(rdev);
+ /* block TTM */
+ resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
+ radeon_suspend(rdev);
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ ring_sizes[i] = radeon_ring_backup(rdev, &rdev->ring[i],
+ &ring_data[i]);
+ if (ring_sizes[i]) {
+ saved = true;
+ dev_info(rdev->dev, "Saved %d dwords of commands "
+ "on ring %d.\n", ring_sizes[i], i);
+ }
+ }
+
+retry:
+ r = radeon_asic_reset(rdev);
+ if (!r) {
+ dev_info(rdev->dev, "GPU reset succeeded, trying to resume\n");
+ radeon_resume(rdev);
+ }
+
+ radeon_restore_bios_scratch_regs(rdev);
+
+ if (!r) {
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ radeon_ring_restore(rdev, &rdev->ring[i],
+ ring_sizes[i], ring_data[i]);
+ ring_sizes[i] = 0;
+ ring_data[i] = NULL;
+ }
+
+ r = radeon_ib_ring_tests(rdev);
+ if (r) {
+ dev_err(rdev->dev, "ib ring test failed (%d).\n", r);
+ if (saved) {
+ saved = false;
+ radeon_suspend(rdev);
+ goto retry;
+ }
+ }
+ } else {
+ radeon_fence_driver_force_completion(rdev);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ free(ring_data[i], DRM_MEM_DRIVER);
+ }
+ }
+
+ drm_helper_resume_force_mode(rdev->ddev);
+
+ ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+ if (r) {
+ /* bad news, how to tell it to userspace ? */
+ dev_info(rdev->dev, "GPU reset failed\n");
+ }
+
+ sx_xunlock(&rdev->exclusive_lock);
+ return r;
+}
+
+
+/*
+ * Debugfs
+ */
+#ifdef DUMBBELL_WIP
+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 /* DUMBBELL_WIP */
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_display.c b/sys/dev/drm2/radeon/radeon_display.c
new file mode 100644
index 0000000..45c3b0c
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_display.c
@@ -0,0 +1,1691 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+
+#include "atom.h"
+
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/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);
+ free(radeon_crtc, DRM_MEM_DRIVER);
+}
+
+/*
+ * Handle unpin events outside the interrupt handler proper.
+ */
+static void radeon_unpin_work_func(void *arg, int pending)
+{
+ struct radeon_unpin_work *work = arg;
+ 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);
+ free(work, DRM_MEM_DRIVER);
+}
+
+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;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->ddev->event_lock, flags);
+ work = radeon_crtc->unpin_work;
+ if (work == NULL ||
+ (work->fence && !radeon_fence_signaled(work->fence))) {
+ DRM_SPINUNLOCK_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;
+ DRM_SPINUNLOCK_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);
+#ifdef DUMBBELL_WIP
+ wake_up_interruptible(&e->base.file_priv->event_wait);
+#endif /* DUMBBELL_WIP */
+ }
+ DRM_SPINUNLOCK_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);
+ taskqueue_enqueue(rdev->tq, &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 = malloc(sizeof *work, DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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);
+
+ mtx_lock(&rbo->tbo.bdev->fence_lock);
+ if (rbo->tbo.sync_obj)
+ work->fence = radeon_fence_ref(rbo->tbo.sync_obj);
+ mtx_unlock(&rbo->tbo.bdev->fence_lock);
+
+ TASK_INIT(&work->work, 0, radeon_unpin_work_func, work);
+
+ /* We borrow the event spin lock for protecting unpin_work */
+ DRM_SPINLOCK_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;
+ DRM_SPINUNLOCK_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;
+ }
+
+ DRM_SPINLOCK_IRQSAVE(&dev->event_lock, flags);
+ work->new_crtc_base = base;
+ DRM_SPINUNLOCK_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:
+ DRM_SPINLOCK_IRQSAVE(&dev->event_lock, flags);
+ radeon_crtc->unpin_work = NULL;
+unlock_free:
+ DRM_SPINUNLOCK_IRQRESTORE(&dev->event_lock, flags);
+ drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
+ radeon_fence_unref(&work->fence);
+ free(work, DRM_MEM_DRIVER);
+
+ 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 = malloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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 *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", drm_get_connector_name(connector));
+ 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_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_i2c_bus)
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ dig->dp_i2c_bus->adapter);
+ } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+ (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ 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 %ju %u %u\n", (uintmax_t)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);
+ free(radeon_fb, DRM_MEM_DRIVER);
+}
+
+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 int
+radeon_user_framebuffer_create(struct drm_device *dev,
+ struct drm_file *file_priv,
+ struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_framebuffer **res)
+{
+ 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->device, "No GEM object associated to handle 0x%08X, "
+ "can't create framebuffer\n", mode_cmd->handles[0]);
+ return -ENOENT;
+ }
+
+ radeon_fb = malloc(sizeof(*radeon_fb), DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (radeon_fb == NULL) {
+ drm_gem_object_unreference_unlocked(obj);
+ return (-ENOMEM);
+ }
+
+ ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+ if (ret) {
+ free(radeon_fb, DRM_MEM_DRIVER);
+ drm_gem_object_unreference_unlocked(obj);
+ return ret;
+ }
+
+ *res = &radeon_fb->base;
+ return 0;
+}
+
+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 = DRM_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 = DRM_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 = DRM_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;
+
+}
+
+/*
+ * Allocate hdmi structs and determine register offsets
+ */
+static void radeon_afmt_init(struct radeon_device *rdev)
+{
+ int i;
+
+ for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++)
+ rdev->mode_info.afmt[i] = NULL;
+
+ if (ASIC_IS_DCE6(rdev)) {
+ /* todo */
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* DCE4/5 has 6 audio blocks tied to DIG encoders */
+ /* DCE4.1 has 2 audio blocks tied to DIG encoders */
+ rdev->mode_info.afmt[0] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[0]) {
+ rdev->mode_info.afmt[0]->offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
+ rdev->mode_info.afmt[0]->id = 0;
+ }
+ rdev->mode_info.afmt[1] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[1]) {
+ rdev->mode_info.afmt[1]->offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
+ rdev->mode_info.afmt[1]->id = 1;
+ }
+ if (!ASIC_IS_DCE41(rdev)) {
+ rdev->mode_info.afmt[2] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[2]) {
+ rdev->mode_info.afmt[2]->offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
+ rdev->mode_info.afmt[2]->id = 2;
+ }
+ rdev->mode_info.afmt[3] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[3]) {
+ rdev->mode_info.afmt[3]->offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
+ rdev->mode_info.afmt[3]->id = 3;
+ }
+ rdev->mode_info.afmt[4] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[4]) {
+ rdev->mode_info.afmt[4]->offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
+ rdev->mode_info.afmt[4]->id = 4;
+ }
+ rdev->mode_info.afmt[5] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[5]) {
+ rdev->mode_info.afmt[5]->offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
+ rdev->mode_info.afmt[5]->id = 5;
+ }
+ }
+ } else if (ASIC_IS_DCE3(rdev)) {
+ /* DCE3.x has 2 audio blocks tied to DIG encoders */
+ rdev->mode_info.afmt[0] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[0]) {
+ rdev->mode_info.afmt[0]->offset = DCE3_HDMI_OFFSET0;
+ rdev->mode_info.afmt[0]->id = 0;
+ }
+ rdev->mode_info.afmt[1] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[1]) {
+ rdev->mode_info.afmt[1]->offset = DCE3_HDMI_OFFSET1;
+ rdev->mode_info.afmt[1]->id = 1;
+ }
+ } else if (ASIC_IS_DCE2(rdev)) {
+ /* DCE2 has at least 1 routable audio block */
+ rdev->mode_info.afmt[0] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[0]) {
+ rdev->mode_info.afmt[0]->offset = DCE2_HDMI_OFFSET0;
+ rdev->mode_info.afmt[0]->id = 0;
+ }
+ /* r6xx has 2 routable audio blocks */
+ if (rdev->family >= CHIP_R600) {
+ rdev->mode_info.afmt[1] = malloc(sizeof(struct radeon_afmt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (rdev->mode_info.afmt[1]) {
+ rdev->mode_info.afmt[1]->offset = DCE2_HDMI_OFFSET1;
+ rdev->mode_info.afmt[1]->id = 1;
+ }
+ }
+ }
+}
+
+static void radeon_afmt_fini(struct radeon_device *rdev)
+{
+ int i;
+
+ for (i = 0; i < RADEON_MAX_AFMT_BLOCKS; i++) {
+ free(rdev->mode_info.afmt[i], DRM_MEM_DRIVER);
+ rdev->mode_info.afmt[i] = NULL;
+ }
+}
+
+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 = &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);
+
+ /* setup afmt */
+ radeon_afmt_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);
+ free(rdev->mode_info.bios_hardcoded_edid, DRM_MEM_KMS);
+ radeon_pm_fini(rdev);
+
+ if (rdev->mode_info.mode_config_initialized) {
+ radeon_afmt_fini(rdev);
+ drm_kms_helper_poll_fini(rdev->ddev);
+ radeon_hpd_fini(rdev);
+ DRM_UNLOCK(rdev->ddev); /* Work around lock recursion. dumbbell@ */
+ drm_mode_config_cleanup(rdev->ddev);
+ DRM_LOCK(rdev->ddev);
+ rdev->mode_info.mode_config_initialized = false;
+ }
+ /* free i2c buses */
+ radeon_i2c_fini(rdev);
+}
+
+static bool is_hdtv_mode(const 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,
+ const 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/sys/dev/drm2/radeon/radeon_drm.h b/sys/dev/drm2/radeon/radeon_drm.h
new file mode 100644
index 0000000..e84500c
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_drm.h
@@ -0,0 +1,985 @@
+/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*-
+ *
+ * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
+ * Copyright 2002 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, sublicense,
+ * and/or sell copies of the Software, and to 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 <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_DRM_H__
+#define __RADEON_DRM_H__
+
+#include <dev/drm2/drm.h>
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the X server file (radeon_sarea.h)
+ */
+#ifndef __RADEON_SAREA_DEFINES__
+#define __RADEON_SAREA_DEFINES__
+
+/* Old style state flags, required for sarea interface (1.1 and 1.2
+ * clears) and 1.2 drm_vertex2 ioctl.
+ */
+#define RADEON_UPLOAD_CONTEXT 0x00000001
+#define RADEON_UPLOAD_VERTFMT 0x00000002
+#define RADEON_UPLOAD_LINE 0x00000004
+#define RADEON_UPLOAD_BUMPMAP 0x00000008
+#define RADEON_UPLOAD_MASKS 0x00000010
+#define RADEON_UPLOAD_VIEWPORT 0x00000020
+#define RADEON_UPLOAD_SETUP 0x00000040
+#define RADEON_UPLOAD_TCL 0x00000080
+#define RADEON_UPLOAD_MISC 0x00000100
+#define RADEON_UPLOAD_TEX0 0x00000200
+#define RADEON_UPLOAD_TEX1 0x00000400
+#define RADEON_UPLOAD_TEX2 0x00000800
+#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
+#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
+#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
+#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
+#define RADEON_REQUIRE_QUIESCENCE 0x00010000
+#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
+#define RADEON_UPLOAD_ALL 0x003effff
+#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff
+
+/* New style per-packet identifiers for use in cmd_buffer ioctl with
+ * the RADEON_EMIT_PACKET command. Comments relate new packets to old
+ * state bits and the packet size:
+ */
+#define RADEON_EMIT_PP_MISC 0 /* context/7 */
+#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
+#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
+#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
+#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
+#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
+#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
+#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
+#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
+#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
+#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
+#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
+#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
+#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
+#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
+#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
+#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
+#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
+#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
+#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
+#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
+#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
+#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
+#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
+#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
+#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
+#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
+#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
+#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
+#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
+#define R200_EMIT_VAP_CTL 32 /* vap/1 */
+#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
+#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
+#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
+#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
+#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
+#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
+#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
+#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
+#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
+#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
+#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
+#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
+#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
+#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
+#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
+#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
+#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
+#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
+#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
+#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
+#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
+#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
+#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
+#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
+#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
+#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
+#define R200_EMIT_PP_CUBIC_FACES_0 61
+#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
+#define R200_EMIT_PP_CUBIC_FACES_1 63
+#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
+#define R200_EMIT_PP_CUBIC_FACES_2 65
+#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
+#define R200_EMIT_PP_CUBIC_FACES_3 67
+#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
+#define R200_EMIT_PP_CUBIC_FACES_4 69
+#define R200_EMIT_PP_CUBIC_OFFSETS_4 70
+#define R200_EMIT_PP_CUBIC_FACES_5 71
+#define R200_EMIT_PP_CUBIC_OFFSETS_5 72
+#define RADEON_EMIT_PP_TEX_SIZE_0 73
+#define RADEON_EMIT_PP_TEX_SIZE_1 74
+#define RADEON_EMIT_PP_TEX_SIZE_2 75
+#define R200_EMIT_RB3D_BLENDCOLOR 76
+#define R200_EMIT_TCL_POINT_SPRITE_CNTL 77
+#define RADEON_EMIT_PP_CUBIC_FACES_0 78
+#define RADEON_EMIT_PP_CUBIC_OFFSETS_T0 79
+#define RADEON_EMIT_PP_CUBIC_FACES_1 80
+#define RADEON_EMIT_PP_CUBIC_OFFSETS_T1 81
+#define RADEON_EMIT_PP_CUBIC_FACES_2 82
+#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83
+#define R200_EMIT_PP_TRI_PERF_CNTL 84
+#define R200_EMIT_PP_AFS_0 85
+#define R200_EMIT_PP_AFS_1 86
+#define R200_EMIT_ATF_TFACTOR 87
+#define R200_EMIT_PP_TXCTLALL_0 88
+#define R200_EMIT_PP_TXCTLALL_1 89
+#define R200_EMIT_PP_TXCTLALL_2 90
+#define R200_EMIT_PP_TXCTLALL_3 91
+#define R200_EMIT_PP_TXCTLALL_4 92
+#define R200_EMIT_PP_TXCTLALL_5 93
+#define R200_EMIT_VAP_PVS_CNTL 94
+#define RADEON_MAX_STATE_PACKETS 95
+
+/* Commands understood by cmd_buffer ioctl. More can be added but
+ * obviously these can't be removed or changed:
+ */
+#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
+#define RADEON_CMD_SCALARS 2 /* emit scalar data */
+#define RADEON_CMD_VECTORS 3 /* emit vector data */
+#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
+#define RADEON_CMD_PACKET3 5 /* emit hw packet */
+#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
+#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
+#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
+ * doesn't make the cpu wait, just
+ * the graphics hardware */
+#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */
+
+typedef union {
+ int i;
+ struct {
+ unsigned char cmd_type, pad0, pad1, pad2;
+ } header;
+ struct {
+ unsigned char cmd_type, packet_id, pad0, pad1;
+ } packet;
+ struct {
+ unsigned char cmd_type, offset, stride, count;
+ } scalars;
+ struct {
+ unsigned char cmd_type, offset, stride, count;
+ } vectors;
+ struct {
+ unsigned char cmd_type, addr_lo, addr_hi, count;
+ } veclinear;
+ struct {
+ unsigned char cmd_type, buf_idx, pad0, pad1;
+ } dma;
+ struct {
+ unsigned char cmd_type, flags, pad0, pad1;
+ } wait;
+} drm_radeon_cmd_header_t;
+
+#define RADEON_WAIT_2D 0x1
+#define RADEON_WAIT_3D 0x2
+
+/* Allowed parameters for R300_CMD_PACKET3
+ */
+#define R300_CMD_PACKET3_CLEAR 0
+#define R300_CMD_PACKET3_RAW 1
+
+/* Commands understood by cmd_buffer ioctl for R300.
+ * The interface has not been stabilized, so some of these may be removed
+ * and eventually reordered before stabilization.
+ */
+#define R300_CMD_PACKET0 1
+#define R300_CMD_VPU 2 /* emit vertex program upload */
+#define R300_CMD_PACKET3 3 /* emit a packet3 */
+#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
+#define R300_CMD_CP_DELAY 5
+#define R300_CMD_DMA_DISCARD 6
+#define R300_CMD_WAIT 7
+# define R300_WAIT_2D 0x1
+# define R300_WAIT_3D 0x2
+/* these two defines are DOING IT WRONG - however
+ * we have userspace which relies on using these.
+ * The wait interface is backwards compat new
+ * code should use the NEW_WAIT defines below
+ * THESE ARE NOT BIT FIELDS
+ */
+# define R300_WAIT_2D_CLEAN 0x3
+# define R300_WAIT_3D_CLEAN 0x4
+
+# define R300_NEW_WAIT_2D_3D 0x3
+# define R300_NEW_WAIT_2D_2D_CLEAN 0x4
+# define R300_NEW_WAIT_3D_3D_CLEAN 0x6
+# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8
+
+#define R300_CMD_SCRATCH 8
+#define R300_CMD_R500FP 9
+
+typedef union {
+ unsigned int u;
+ struct {
+ unsigned char cmd_type, pad0, pad1, pad2;
+ } header;
+ struct {
+ unsigned char cmd_type, count, reglo, reghi;
+ } packet0;
+ struct {
+ unsigned char cmd_type, count, adrlo, adrhi;
+ } vpu;
+ struct {
+ unsigned char cmd_type, packet, pad0, pad1;
+ } packet3;
+ struct {
+ unsigned char cmd_type, packet;
+ unsigned short count; /* amount of packet2 to emit */
+ } delay;
+ struct {
+ unsigned char cmd_type, buf_idx, pad0, pad1;
+ } dma;
+ struct {
+ unsigned char cmd_type, flags, pad0, pad1;
+ } wait;
+ struct {
+ unsigned char cmd_type, reg, n_bufs, flags;
+ } scratch;
+ struct {
+ unsigned char cmd_type, count, adrlo, adrhi_flags;
+ } r500fp;
+} drm_r300_cmd_header_t;
+
+#define RADEON_FRONT 0x1
+#define RADEON_BACK 0x2
+#define RADEON_DEPTH 0x4
+#define RADEON_STENCIL 0x8
+#define RADEON_CLEAR_FASTZ 0x80000000
+#define RADEON_USE_HIERZ 0x40000000
+#define RADEON_USE_COMP_ZBUF 0x20000000
+
+#define R500FP_CONSTANT_TYPE (1 << 1)
+#define R500FP_CONSTANT_CLAMP (1 << 2)
+
+/* Primitive types
+ */
+#define RADEON_POINTS 0x1
+#define RADEON_LINES 0x2
+#define RADEON_LINE_STRIP 0x3
+#define RADEON_TRIANGLES 0x4
+#define RADEON_TRIANGLE_FAN 0x5
+#define RADEON_TRIANGLE_STRIP 0x6
+
+/* Vertex/indirect buffer size
+ */
+#define RADEON_BUFFER_SIZE 65536
+
+/* Byte offsets for indirect buffer data
+ */
+#define RADEON_INDEX_PRIM_OFFSET 20
+
+#define RADEON_SCRATCH_REG_OFFSET 32
+
+#define R600_SCRATCH_REG_OFFSET 256
+
+#define RADEON_NR_SAREA_CLIPRECTS 12
+
+/* There are 2 heaps (local/GART). Each region within a heap is a
+ * minimum of 64k, and there are at most 64 of them per heap.
+ */
+#define RADEON_LOCAL_TEX_HEAP 0
+#define RADEON_GART_TEX_HEAP 1
+#define RADEON_NR_TEX_HEAPS 2
+#define RADEON_NR_TEX_REGIONS 64
+#define RADEON_LOG_TEX_GRANULARITY 16
+
+#define RADEON_MAX_TEXTURE_LEVELS 12
+#define RADEON_MAX_TEXTURE_UNITS 3
+
+#define RADEON_MAX_SURFACES 8
+
+/* Blits have strict offset rules. All blit offset must be aligned on
+ * a 1K-byte boundary.
+ */
+#define RADEON_OFFSET_SHIFT 10
+#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
+#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
+
+#endif /* __RADEON_SAREA_DEFINES__ */
+
+typedef struct {
+ unsigned int red;
+ unsigned int green;
+ unsigned int blue;
+ unsigned int alpha;
+} radeon_color_regs_t;
+
+typedef struct {
+ /* Context state */
+ unsigned int pp_misc; /* 0x1c14 */
+ unsigned int pp_fog_color;
+ unsigned int re_solid_color;
+ unsigned int rb3d_blendcntl;
+ unsigned int rb3d_depthoffset;
+ unsigned int rb3d_depthpitch;
+ unsigned int rb3d_zstencilcntl;
+
+ unsigned int pp_cntl; /* 0x1c38 */
+ unsigned int rb3d_cntl;
+ unsigned int rb3d_coloroffset;
+ unsigned int re_width_height;
+ unsigned int rb3d_colorpitch;
+ unsigned int se_cntl;
+
+ /* Vertex format state */
+ unsigned int se_coord_fmt; /* 0x1c50 */
+
+ /* Line state */
+ unsigned int re_line_pattern; /* 0x1cd0 */
+ unsigned int re_line_state;
+
+ unsigned int se_line_width; /* 0x1db8 */
+
+ /* Bumpmap state */
+ unsigned int pp_lum_matrix; /* 0x1d00 */
+
+ unsigned int pp_rot_matrix_0; /* 0x1d58 */
+ unsigned int pp_rot_matrix_1;
+
+ /* Mask state */
+ unsigned int rb3d_stencilrefmask; /* 0x1d7c */
+ unsigned int rb3d_ropcntl;
+ unsigned int rb3d_planemask;
+
+ /* Viewport state */
+ unsigned int se_vport_xscale; /* 0x1d98 */
+ unsigned int se_vport_xoffset;
+ unsigned int se_vport_yscale;
+ unsigned int se_vport_yoffset;
+ unsigned int se_vport_zscale;
+ unsigned int se_vport_zoffset;
+
+ /* Setup state */
+ unsigned int se_cntl_status; /* 0x2140 */
+
+ /* Misc state */
+ unsigned int re_top_left; /* 0x26c0 */
+ unsigned int re_misc;
+} drm_radeon_context_regs_t;
+
+typedef struct {
+ /* Zbias state */
+ unsigned int se_zbias_factor; /* 0x1dac */
+ unsigned int se_zbias_constant;
+} drm_radeon_context2_regs_t;
+
+/* Setup registers for each texture unit
+ */
+typedef struct {
+ unsigned int pp_txfilter;
+ unsigned int pp_txformat;
+ unsigned int pp_txoffset;
+ unsigned int pp_txcblend;
+ unsigned int pp_txablend;
+ unsigned int pp_tfactor;
+ unsigned int pp_border_color;
+} drm_radeon_texture_regs_t;
+
+typedef struct {
+ unsigned int start;
+ unsigned int finish;
+ unsigned int prim:8;
+ unsigned int stateidx:8;
+ unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
+ unsigned int vc_format; /* vertex format */
+} drm_radeon_prim_t;
+
+typedef struct {
+ drm_radeon_context_regs_t context;
+ drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
+ drm_radeon_context2_regs_t context2;
+ unsigned int dirty;
+} drm_radeon_state_t;
+
+typedef struct {
+ /* The channel for communication of state information to the
+ * kernel on firing a vertex buffer with either of the
+ * obsoleted vertex/index ioctls.
+ */
+ drm_radeon_context_regs_t context_state;
+ drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
+ unsigned int dirty;
+ unsigned int vertsize;
+ unsigned int vc_format;
+
+ /* The current cliprects, or a subset thereof.
+ */
+ struct drm_clip_rect boxes[RADEON_NR_SAREA_CLIPRECTS];
+ unsigned int nbox;
+
+ /* Counters for client-side throttling of rendering clients.
+ */
+ unsigned int last_frame;
+ unsigned int last_dispatch;
+ unsigned int last_clear;
+
+ struct drm_tex_region tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS +
+ 1];
+ unsigned int tex_age[RADEON_NR_TEX_HEAPS];
+ int ctx_owner;
+ int pfState; /* number of 3d windows (0,1,2ormore) */
+ int pfCurrentPage; /* which buffer is being displayed? */
+ int crtc2_base; /* CRTC2 frame offset */
+ int tiling_enabled; /* set by drm, read by 2d + 3d clients */
+} drm_radeon_sarea_t;
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmRadeon.h)
+ *
+ * KW: actually it's illegal to change any of this (backwards compatibility).
+ */
+
+/* Radeon specific ioctls
+ * The device specific ioctl range is 0x40 to 0x79.
+ */
+#define DRM_RADEON_CP_INIT 0x00
+#define DRM_RADEON_CP_START 0x01
+#define DRM_RADEON_CP_STOP 0x02
+#define DRM_RADEON_CP_RESET 0x03
+#define DRM_RADEON_CP_IDLE 0x04
+#define DRM_RADEON_RESET 0x05
+#define DRM_RADEON_FULLSCREEN 0x06
+#define DRM_RADEON_SWAP 0x07
+#define DRM_RADEON_CLEAR 0x08
+#define DRM_RADEON_VERTEX 0x09
+#define DRM_RADEON_INDICES 0x0A
+#define DRM_RADEON_NOT_USED
+#define DRM_RADEON_STIPPLE 0x0C
+#define DRM_RADEON_INDIRECT 0x0D
+#define DRM_RADEON_TEXTURE 0x0E
+#define DRM_RADEON_VERTEX2 0x0F
+#define DRM_RADEON_CMDBUF 0x10
+#define DRM_RADEON_GETPARAM 0x11
+#define DRM_RADEON_FLIP 0x12
+#define DRM_RADEON_ALLOC 0x13
+#define DRM_RADEON_FREE 0x14
+#define DRM_RADEON_INIT_HEAP 0x15
+#define DRM_RADEON_IRQ_EMIT 0x16
+#define DRM_RADEON_IRQ_WAIT 0x17
+#define DRM_RADEON_CP_RESUME 0x18
+#define DRM_RADEON_SETPARAM 0x19
+#define DRM_RADEON_SURF_ALLOC 0x1a
+#define DRM_RADEON_SURF_FREE 0x1b
+/* KMS ioctl */
+#define DRM_RADEON_GEM_INFO 0x1c
+#define DRM_RADEON_GEM_CREATE 0x1d
+#define DRM_RADEON_GEM_MMAP 0x1e
+#define DRM_RADEON_GEM_PREAD 0x21
+#define DRM_RADEON_GEM_PWRITE 0x22
+#define DRM_RADEON_GEM_SET_DOMAIN 0x23
+#define DRM_RADEON_GEM_WAIT_IDLE 0x24
+#define DRM_RADEON_CS 0x26
+#define DRM_RADEON_INFO 0x27
+#define DRM_RADEON_GEM_SET_TILING 0x28
+#define DRM_RADEON_GEM_GET_TILING 0x29
+#define DRM_RADEON_GEM_BUSY 0x2a
+#define DRM_RADEON_GEM_VA 0x2b
+
+#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
+#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
+#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
+#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESET)
+#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_IDLE)
+#define DRM_IOCTL_RADEON_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_RESET)
+#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FULLSCREEN, drm_radeon_fullscreen_t)
+#define DRM_IOCTL_RADEON_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_SWAP)
+#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CLEAR, drm_radeon_clear_t)
+#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX, drm_radeon_vertex_t)
+#define DRM_IOCTL_RADEON_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INDICES, drm_radeon_indices_t)
+#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_STIPPLE, drm_radeon_stipple_t)
+#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INDIRECT, drm_radeon_indirect_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_TEXTURE, drm_radeon_texture_t)
+#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX2, drm_radeon_vertex2_t)
+#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CMDBUF, drm_radeon_cmd_buffer_t)
+#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GETPARAM, drm_radeon_getparam_t)
+#define DRM_IOCTL_RADEON_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_FLIP)
+#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_ALLOC, drm_radeon_mem_alloc_t)
+#define DRM_IOCTL_RADEON_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FREE, drm_radeon_mem_free_t)
+#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INIT_HEAP, drm_radeon_mem_init_heap_t)
+#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_IRQ_EMIT, drm_radeon_irq_emit_t)
+#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
+#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME)
+#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
+#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
+#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+/* KMS */
+#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
+#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
+#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
+#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
+#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
+#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
+#define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle)
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+#define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
+#define DRM_IOCTL_RADEON_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling)
+#define DRM_IOCTL_RADEON_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling)
+#define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy)
+#define DRM_IOCTL_RADEON_GEM_VA DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_VA, struct drm_radeon_gem_va)
+
+typedef struct drm_radeon_init {
+ enum {
+ RADEON_INIT_CP = 0x01,
+ RADEON_CLEANUP_CP = 0x02,
+ RADEON_INIT_R200_CP = 0x03,
+ RADEON_INIT_R300_CP = 0x04,
+ RADEON_INIT_R600_CP = 0x05
+ } func;
+ unsigned long 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;
+
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long ring_offset;
+ unsigned long ring_rptr_offset;
+ unsigned long buffers_offset;
+ unsigned long gart_textures_offset;
+} drm_radeon_init_t;
+
+typedef struct drm_radeon_cp_stop {
+ int flush;
+ int idle;
+} drm_radeon_cp_stop_t;
+
+typedef struct drm_radeon_fullscreen {
+ enum {
+ RADEON_INIT_FULLSCREEN = 0x01,
+ RADEON_CLEANUP_FULLSCREEN = 0x02
+ } func;
+} drm_radeon_fullscreen_t;
+
+#define CLEAR_X1 0
+#define CLEAR_Y1 1
+#define CLEAR_X2 2
+#define CLEAR_Y2 3
+#define CLEAR_DEPTH 4
+
+typedef union drm_radeon_clear_rect {
+ float f[5];
+ unsigned int ui[5];
+} drm_radeon_clear_rect_t;
+
+typedef struct drm_radeon_clear {
+ unsigned int flags;
+ unsigned int clear_color;
+ unsigned int clear_depth;
+ unsigned int color_mask;
+ unsigned int depth_mask; /* misnamed field: should be stencil */
+ drm_radeon_clear_rect_t __user *depth_boxes;
+} drm_radeon_clear_t;
+
+typedef struct drm_radeon_vertex {
+ int prim;
+ int idx; /* Index of vertex buffer */
+ int count; /* Number of vertices in buffer */
+ int discard; /* Client finished with buffer? */
+} drm_radeon_vertex_t;
+
+typedef struct drm_radeon_indices {
+ int prim;
+ int idx;
+ int start;
+ int end;
+ int discard; /* Client finished with buffer? */
+} drm_radeon_indices_t;
+
+/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
+ * - allows multiple primitives and state changes in a single ioctl
+ * - supports driver change to emit native primitives
+ */
+typedef struct drm_radeon_vertex2 {
+ int idx; /* Index of vertex buffer */
+ int discard; /* Client finished with buffer? */
+ int nr_states;
+ drm_radeon_state_t __user *state;
+ int nr_prims;
+ drm_radeon_prim_t __user *prim;
+} drm_radeon_vertex2_t;
+
+/* v1.3 - obsoletes drm_radeon_vertex2
+ * - allows arbitrarily large cliprect list
+ * - allows updating of tcl packet, vector and scalar state
+ * - allows memory-efficient description of state updates
+ * - allows state to be emitted without a primitive
+ * (for clears, ctx switches)
+ * - allows more than one dma buffer to be referenced per ioctl
+ * - supports tcl driver
+ * - may be extended in future versions with new cmd types, packets
+ */
+typedef struct drm_radeon_cmd_buffer {
+ int bufsz;
+ char __user *buf;
+ int nbox;
+ struct drm_clip_rect __user *boxes;
+} drm_radeon_cmd_buffer_t;
+
+typedef struct drm_radeon_tex_image {
+ unsigned int x, y; /* Blit coordinates */
+ unsigned int width, height;
+ const void __user *data;
+} drm_radeon_tex_image_t;
+
+typedef struct drm_radeon_texture {
+ unsigned int offset;
+ int pitch;
+ int format;
+ int width; /* Texture image coordinates */
+ int height;
+ drm_radeon_tex_image_t __user *image;
+} drm_radeon_texture_t;
+
+typedef struct drm_radeon_stipple {
+ unsigned int __user *mask;
+} drm_radeon_stipple_t;
+
+typedef struct drm_radeon_indirect {
+ int idx;
+ int start;
+ int end;
+ int discard;
+} drm_radeon_indirect_t;
+
+/* enum for card type parameters */
+#define RADEON_CARD_PCI 0
+#define RADEON_CARD_AGP 1
+#define RADEON_CARD_PCIE 2
+
+/* 1.3: An ioctl to get parameters that aren't available to the 3d
+ * client any other way.
+ */
+#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
+#define RADEON_PARAM_LAST_FRAME 2
+#define RADEON_PARAM_LAST_DISPATCH 3
+#define RADEON_PARAM_LAST_CLEAR 4
+/* Added with DRM version 1.6. */
+#define RADEON_PARAM_IRQ_NR 5
+#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
+/* Added with DRM version 1.8. */
+#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
+#define RADEON_PARAM_STATUS_HANDLE 8
+#define RADEON_PARAM_SAREA_HANDLE 9
+#define RADEON_PARAM_GART_TEX_HANDLE 10
+#define RADEON_PARAM_SCRATCH_OFFSET 11
+#define RADEON_PARAM_CARD_TYPE 12
+#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
+#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
+#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
+#define RADEON_PARAM_DEVICE_ID 16
+#define RADEON_PARAM_NUM_Z_PIPES 17 /* num Z pipes */
+
+typedef struct drm_radeon_getparam {
+ int param;
+ void __user *value;
+} drm_radeon_getparam_t;
+
+/* 1.6: Set up a memory manager for regions of shared memory:
+ */
+#define RADEON_MEM_REGION_GART 1
+#define RADEON_MEM_REGION_FB 2
+
+typedef struct drm_radeon_mem_alloc {
+ int region;
+ int alignment;
+ int size;
+ int __user *region_offset; /* offset from start of fb or GART */
+} drm_radeon_mem_alloc_t;
+
+typedef struct drm_radeon_mem_free {
+ int region;
+ int region_offset;
+} drm_radeon_mem_free_t;
+
+typedef struct drm_radeon_mem_init_heap {
+ int region;
+ int size;
+ int start;
+} drm_radeon_mem_init_heap_t;
+
+/* 1.6: Userspace can request & wait on irq's:
+ */
+typedef struct drm_radeon_irq_emit {
+ int __user *irq_seq;
+} drm_radeon_irq_emit_t;
+
+typedef struct drm_radeon_irq_wait {
+ int irq_seq;
+} drm_radeon_irq_wait_t;
+
+/* 1.10: Clients tell the DRM where they think the framebuffer is located in
+ * the card's address space, via a new generic ioctl to set parameters
+ */
+
+typedef struct drm_radeon_setparam {
+ unsigned int param;
+ int64_t value;
+} drm_radeon_setparam_t;
+
+#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
+#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
+#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
+#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
+#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
+#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
+/* 1.14: Clients can allocate/free a surface
+ */
+typedef struct drm_radeon_surface_alloc {
+ unsigned int address;
+ unsigned int size;
+ unsigned int flags;
+} drm_radeon_surface_alloc_t;
+
+typedef struct drm_radeon_surface_free {
+ unsigned int address;
+} drm_radeon_surface_free_t;
+
+#define DRM_RADEON_VBLANK_CRTC1 1
+#define DRM_RADEON_VBLANK_CRTC2 2
+
+/*
+ * Kernel modesetting world below.
+ */
+#define RADEON_GEM_DOMAIN_CPU 0x1
+#define RADEON_GEM_DOMAIN_GTT 0x2
+#define RADEON_GEM_DOMAIN_VRAM 0x4
+
+struct drm_radeon_gem_info {
+ uint64_t gart_size;
+ uint64_t vram_size;
+ uint64_t vram_visible;
+};
+
+#define RADEON_GEM_NO_BACKING_STORE 1
+
+struct drm_radeon_gem_create {
+ uint64_t size;
+ uint64_t alignment;
+ uint32_t handle;
+ uint32_t initial_domain;
+ uint32_t flags;
+};
+
+#define RADEON_TILING_MACRO 0x1
+#define RADEON_TILING_MICRO 0x2
+#define RADEON_TILING_SWAP_16BIT 0x4
+#define RADEON_TILING_SWAP_32BIT 0x8
+/* this object requires a surface when mapped - i.e. front buffer */
+#define RADEON_TILING_SURFACE 0x10
+#define RADEON_TILING_MICRO_SQUARE 0x20
+#define RADEON_TILING_EG_BANKW_SHIFT 8
+#define RADEON_TILING_EG_BANKW_MASK 0xf
+#define RADEON_TILING_EG_BANKH_SHIFT 12
+#define RADEON_TILING_EG_BANKH_MASK 0xf
+#define RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT 16
+#define RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK 0xf
+#define RADEON_TILING_EG_TILE_SPLIT_SHIFT 24
+#define RADEON_TILING_EG_TILE_SPLIT_MASK 0xf
+#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT 28
+#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf
+
+struct drm_radeon_gem_set_tiling {
+ uint32_t handle;
+ uint32_t tiling_flags;
+ uint32_t pitch;
+};
+
+struct drm_radeon_gem_get_tiling {
+ uint32_t handle;
+ uint32_t tiling_flags;
+ uint32_t pitch;
+};
+
+struct drm_radeon_gem_mmap {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+};
+
+struct drm_radeon_gem_set_domain {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+};
+
+struct drm_radeon_gem_wait_idle {
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_radeon_gem_busy {
+ uint32_t handle;
+ uint32_t domain;
+};
+
+struct drm_radeon_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /** Pointer to write the data into. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+struct drm_radeon_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /** Pointer to read the data from. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+#define RADEON_VA_MAP 1
+#define RADEON_VA_UNMAP 2
+
+#define RADEON_VA_RESULT_OK 0
+#define RADEON_VA_RESULT_ERROR 1
+#define RADEON_VA_RESULT_VA_EXIST 2
+
+#define RADEON_VM_PAGE_VALID (1 << 0)
+#define RADEON_VM_PAGE_READABLE (1 << 1)
+#define RADEON_VM_PAGE_WRITEABLE (1 << 2)
+#define RADEON_VM_PAGE_SYSTEM (1 << 3)
+#define RADEON_VM_PAGE_SNOOPED (1 << 4)
+
+struct drm_radeon_gem_va {
+ uint32_t handle;
+ uint32_t operation;
+ uint32_t vm_id;
+ uint32_t flags;
+ uint64_t offset;
+};
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB 0x02
+#define RADEON_CHUNK_ID_FLAGS 0x03
+#define RADEON_CHUNK_ID_CONST_IB 0x04
+
+/* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */
+#define RADEON_CS_KEEP_TILING_FLAGS 0x01
+#define RADEON_CS_USE_VM 0x02
+#define RADEON_CS_END_OF_FRAME 0x04 /* a hint from userspace which CS is the last one */
+/* The second dword of RADEON_CHUNK_ID_FLAGS is a uint32 that sets the ring type */
+#define RADEON_CS_RING_GFX 0
+#define RADEON_CS_RING_COMPUTE 1
+#define RADEON_CS_RING_DMA 2
+/* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */
+/* 0 = normal, + = higher priority, - = lower priority */
+
+struct drm_radeon_cs_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ uint64_t chunk_data;
+};
+
+/* drm_radeon_cs_reloc.flags */
+
+struct drm_radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+
+struct drm_radeon_cs {
+ uint32_t num_chunks;
+ uint32_t cs_id;
+ /* this points to uint64_t * which point to cs chunks */
+ uint64_t chunks;
+ /* updates to the limits after this CS ioctl */
+ uint64_t gart_limit;
+ uint64_t vram_limit;
+};
+
+#define RADEON_INFO_DEVICE_ID 0x00
+#define RADEON_INFO_NUM_GB_PIPES 0x01
+#define RADEON_INFO_NUM_Z_PIPES 0x02
+#define RADEON_INFO_ACCEL_WORKING 0x03
+#define RADEON_INFO_CRTC_FROM_ID 0x04
+#define RADEON_INFO_ACCEL_WORKING2 0x05
+#define RADEON_INFO_TILING_CONFIG 0x06
+#define RADEON_INFO_WANT_HYPERZ 0x07
+#define RADEON_INFO_WANT_CMASK 0x08 /* get access to CMASK on r300 */
+#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */
+#define RADEON_INFO_NUM_BACKENDS 0x0a /* DB/backends for r600+ - need for OQ */
+#define RADEON_INFO_NUM_TILE_PIPES 0x0b /* tile pipes for r600+ */
+#define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before this */
+#define RADEON_INFO_BACKEND_MAP 0x0d /* pipe to backend map, needed by mesa */
+/* virtual address start, va < start are reserved by the kernel */
+#define RADEON_INFO_VA_START 0x0e
+/* maximum size of ib using the virtual memory cs */
+#define RADEON_INFO_IB_VM_MAX_SIZE 0x0f
+/* max pipes - needed for compute shaders */
+#define RADEON_INFO_MAX_PIPES 0x10
+/* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */
+#define RADEON_INFO_TIMESTAMP 0x11
+/* max shader engines (SE) - needed for geometry shaders, etc. */
+#define RADEON_INFO_MAX_SE 0x12
+/* max SH per SE */
+#define RADEON_INFO_MAX_SH_PER_SE 0x13
+
+struct drm_radeon_info {
+ uint32_t request;
+ uint32_t pad;
+ uint64_t value;
+};
+
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_drv.c b/sys/dev/drm2/radeon/radeon_drv.c
new file mode 100644
index 0000000..2ef5426
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_drv.c
@@ -0,0 +1,514 @@
+/**
+ * \file radeon_drv.c
+ * ATI Radeon driver
+ *
+ * \author Gareth Hughes <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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_drv.h"
+#include "radeon_gem.h"
+#include "radeon_kms.h"
+#include "radeon_irq_kms.h"
+
+#include <dev/drm2/drm_pciids.h>
+
+
+/*
+ * 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
+ * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx
+ * 2.18.0 - r600-eg: allow "invalid" DB formats
+ * 2.19.0 - r600-eg: MSAA textures
+ * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query
+ * 2.21.0 - r600-r700: FMASK and CMASK
+ * 2.22.0 - r600 only: RESOLVE_BOX allowed
+ * 2.23.0 - allow STRMOUT_BASE_UPDATE on RS780 and RS880
+ * 2.24.0 - eg only: allow MIP_ADDRESS=0 for MSAA textures
+ * 2.25.0 - eg+: new info request for num SE and num SH
+ * 2.26.0 - r600-eg: fix htile size computation
+ * 2.27.0 - r600-SI: Add CS ioctl support for async DMA
+ * 2.28.0 - r600-eg: Add MEM_WRITE packet support
+ * 2.29.0 - R500 FP16 color clear registers
+ */
+#define KMS_DRIVER_MAJOR 2
+#define KMS_DRIVER_MINOR 29
+#define KMS_DRIVER_PATCHLEVEL 0
+int radeon_suspend_kms(struct drm_device *dev);
+int radeon_resume_kms(struct drm_device *dev);
+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;
+#ifdef DUMBBELL_WIP
+int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
+#endif /* DUMBBELL_WIP */
+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);
+struct dma_buf *radeon_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags);
+struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev,
+ struct dma_buf *dma_buf);
+
+#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 = -1;
+int radeon_msi = -1;
+int radeon_lockup_timeout = 10000;
+
+#ifdef DUMBBELL_WIP
+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 = auto, 0 = disable, 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);
+
+MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 10000 = 10 seconds, 0 = disable)");
+module_param_named(lockup_timeout, radeon_lockup_timeout, 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;
+}
+#endif /* DUMBBELL_WIP */
+
+static drm_pci_id_list_t pciidlist[] = {
+ radeon_PCI_IDS
+};
+
+#ifdef DUMBBELL_WIP
+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,
+#ifdef DUMBBELL_WIP
+ .suspend = radeon_suspend,
+ .resume = radeon_resume,
+#endif /* DUMBBELL_WIP */
+ .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,
+ .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,
+};
+#endif /* DUMBBELL_WIP */
+
+static struct drm_driver_info kms_driver;
+
+#ifdef DUMBBELL_WIP
+static int radeon_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+ struct apertures_struct *ap;
+ bool primary = false;
+
+ ap = alloc_apertures(1);
+ if (!ap)
+ return -ENOMEM;
+
+ 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);
+
+ return 0;
+}
+
+static int radeon_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int ret;
+
+ /* Get rid of things like offb */
+ ret = radeon_kick_out_firmware_fb(pdev);
+ if (ret)
+ return ret;
+
+ 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
+};
+#endif /* DUMBBELL_WIP */
+
+static struct drm_driver_info 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 |
+ DRIVER_PRIME /* | DRIVE_MODESET */,
+#ifdef DUMBBELL_WIP
+ .dev_priv_size = 0,
+#endif /* DUMBBELL_WIP */
+ .load = radeon_driver_load_kms,
+ .use_msi = radeon_msi_ok,
+ .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,
+#ifdef DUMBBELL_WIP
+ .suspend = radeon_suspend_kms,
+ .resume = radeon_resume_kms,
+#endif /* DUMBBELL_WIP */
+ .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,
+ .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,
+ .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,
+#ifdef DUMBBELL_WIP
+ .fops = &radeon_driver_kms_fops,
+#endif /* DUMBBELL_WIP */
+
+#ifdef DUMBBELL_WIP
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = radeon_gem_prime_export,
+ .gem_prime_import = radeon_gem_prime_import,
+#endif /* DUMBBELL_WIP */
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = KMS_DRIVER_MAJOR,
+ .minor = KMS_DRIVER_MINOR,
+ .patchlevel = KMS_DRIVER_PATCHLEVEL,
+};
+
+#ifdef DUMBBELL_WIP
+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();
+}
+#endif /* DUMBBELL_WIP */
+
+/* =================================================================== */
+
+static int
+radeon_probe(device_t kdev)
+{
+
+ return drm_probe(kdev, pciidlist);
+}
+
+static int
+radeon_attach(device_t kdev)
+{
+ struct drm_device *dev;
+
+ dev = device_get_softc(kdev);
+ if (radeon_modeset == 1) {
+ kms_driver.driver_features |= DRIVER_MODESET;
+ kms_driver.max_ioctl = radeon_max_kms_ioctl;
+ radeon_register_atpx_handler();
+ }
+ dev->driver = &kms_driver;
+ return (drm_attach(kdev, pciidlist));
+}
+
+static int
+radeon_suspend(device_t kdev)
+{
+ struct drm_device *dev;
+ int ret;
+
+ dev = device_get_softc(kdev);
+ ret = radeon_suspend_kms(dev);
+
+ return (-ret);
+}
+
+static int
+radeon_resume(device_t kdev)
+{
+ struct drm_device *dev;
+ int ret;
+
+ dev = device_get_softc(kdev);
+ ret = radeon_resume_kms(dev);
+
+ return (-ret);
+}
+
+static device_method_t radeon_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, radeon_probe),
+ DEVMETHOD(device_attach, radeon_attach),
+ DEVMETHOD(device_suspend, radeon_suspend),
+ DEVMETHOD(device_resume, radeon_resume),
+ DEVMETHOD(device_detach, drm_detach),
+ DEVMETHOD_END
+};
+
+static driver_t radeon_driver = {
+ "drmn",
+ radeon_methods,
+ sizeof(struct drm_device)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE_ORDERED(radeonkms, vgapci, radeon_driver, drm_devclass,
+ NULL, NULL, SI_ORDER_ANY);
+MODULE_DEPEND(radeonkms, drmn, 1, 1, 1);
+MODULE_DEPEND(radeonkms, agp, 1, 1, 1);
+MODULE_DEPEND(radeonkms, iicbus, 1, 1, 1);
+MODULE_DEPEND(radeonkms, iic, 1, 1, 1);
+MODULE_DEPEND(radeonkms, iicbb, 1, 1, 1);
diff --git a/sys/dev/drm2/radeon/radeon_drv.h b/sys/dev/drm2/radeon/radeon_drv.h
new file mode 100644
index 0000000..f33ea18
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_drv.h
@@ -0,0 +1,2165 @@
+/* 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 <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_DRV_H__
+#define __RADEON_DRV_H__
+
+#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 sx 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 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 */
+void radeon_register_atpx_handler(void);
+void radeon_unregister_atpx_handler(void);
+
+/* 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->masterp->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/sys/dev/drm2/radeon/radeon_encoders.c b/sys/dev/drm2/radeon/radeon_encoders.c
new file mode 100644
index 0000000..be7ad34
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_encoders.c
@@ -0,0 +1,381 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/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 radeon_device *rdev = dev->dev_private;
+ 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);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ if (rdev->is_atom_bios)
+ radeon_atom_backlight_init(radeon_encoder, connector);
+ else
+ radeon_legacy_backlight_init(radeon_encoder, connector);
+ rdev->mode_info.bl_encoder = radeon_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/sys/dev/drm2/radeon/radeon_family.h b/sys/dev/drm2/radeon/radeon_family.h
new file mode 100644
index 0000000..7ac4937
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_family.h
@@ -0,0 +1,117 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/radeon_fb.c b/sys/dev/drm2/radeon/radeon_fb.c
new file mode 100644
index 0000000..fc247e2
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_fb.c
@@ -0,0 +1,433 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+
+#include <dev/drm2/drm_fb_helper.h>
+
+/* 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;
+};
+
+#ifdef DUMBBELL_WIP
+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,
+};
+#endif /* DUMBBELL_WIP */
+
+
+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 = roundup2(mode_cmd->height, 8);
+ size = mode_cmd->pitches[0] * height;
+ aligned_size = roundup2(size, PAGE_SIZE);
+ ret = radeon_gem_object_create(rdev, aligned_size, 0,
+ RADEON_GEM_DOMAIN_VRAM,
+ false, true,
+ &gobj);
+ if (ret) {
+ DRM_ERROR("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;
+#ifdef DUMBBELL_WIP
+ struct fb_info *info;
+#endif /* DUMBBELL_WIP */
+ struct drm_framebuffer *fb = NULL;
+ struct drm_mode_fb_cmd2 mode_cmd;
+ struct drm_gem_object *gobj = NULL;
+ struct radeon_bo *rbo = NULL;
+#ifdef DUMBBELL_WIP
+ device_t device = rdev->dev;
+#endif /* DUMBBELL_WIP */
+ int ret;
+#ifdef DUMBBELL_WIP
+ unsigned long tmp;
+#endif /* DUMBBELL_WIP */
+
+ 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);
+
+#ifdef DUMBBELL_WIP
+ /* 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;
+#endif /* DUMBBELL_WIP */
+
+ 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;
+#ifdef DUMBBELL_WIP
+ 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);
+#endif /* DUMBBELL_WIP */
+ return 0;
+
+out_unref:
+ if (rbo) {
+
+ }
+ if (fb && ret) {
+ drm_gem_object_unreference(gobj);
+ drm_framebuffer_cleanup(fb);
+ free(fb, DRM_MEM_DRIVER); /* XXX malloc'd in radeon_user_framebuffer_create? */
+ }
+ 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;
+}
+
+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)
+{
+#ifdef DUMBBELL_WIP
+ struct fb_info *info;
+#endif /* DUMBBELL_WIP */
+ struct radeon_framebuffer *rfb = &rfbdev->rfb;
+
+#ifdef DUMBBELL_WIP
+ if (rfbdev->helper.fbdev) {
+ info = rfbdev->helper.fbdev;
+
+ unregister_framebuffer(info);
+ if (info->cmap.len)
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+ }
+#endif /* DUMBBELL_WIP */
+
+ if (rfb->obj) {
+ DRM_UNLOCK(dev); /* Work around lock recursion. dumbbell@ */
+ radeonfb_destroy_pinned_object(rfb->obj);
+ DRM_LOCK(dev);
+ 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 = malloc(sizeof(struct radeon_fbdev),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ 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) {
+ free(rfbdev, DRM_MEM_DRIVER);
+ 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);
+ free(rdev->mode_info.rfbdev, DRM_MEM_DRIVER);
+ rdev->mode_info.rfbdev = NULL;
+}
+
+void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
+{
+#ifdef DUMBBELL_WIP
+ fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state);
+#endif /* DUMBBELL_WIP */
+}
+
+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/sys/dev/drm2/radeon/radeon_fence.c b/sys/dev/drm2/radeon/radeon_fence.c
new file mode 100644
index 0000000..07b1a64
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_fence.c
@@ -0,0 +1,983 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ * Dave Airlie
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#ifdef DUMBBELL_WIP
+#include "radeon_trace.h"
+#endif /* DUMBBELL_WIP */
+
+/*
+ * Fences
+ * Fences mark an event in the GPUs pipeline and are used
+ * for GPU/CPU synchronization. When the fence is written,
+ * it is expected that all buffers associated with that fence
+ * are no longer in use by the associated ring on the GPU and
+ * that the the relevant GPU caches have been flushed. Whether
+ * we use a scratch register or memory location depends on the asic
+ * and whether writeback is enabled.
+ */
+
+/**
+ * radeon_fence_write - write a fence value
+ *
+ * @rdev: radeon_device pointer
+ * @seq: sequence number to write
+ * @ring: ring index the fence is associated with
+ *
+ * Writes a fence value to memory or a scratch register (all asics).
+ */
+static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring)
+{
+ struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
+ if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+ *drv->cpu_addr = cpu_to_le32(seq);
+ } else {
+ WREG32(drv->scratch_reg, seq);
+ }
+}
+
+/**
+ * radeon_fence_read - read a fence value
+ *
+ * @rdev: radeon_device pointer
+ * @ring: ring index the fence is associated with
+ *
+ * Reads a fence value from memory or a scratch register (all asics).
+ * Returns the value of the fence read from memory or register.
+ */
+static u32 radeon_fence_read(struct radeon_device *rdev, int ring)
+{
+ struct radeon_fence_driver *drv = &rdev->fence_drv[ring];
+ u32 seq = 0;
+
+ if (likely(rdev->wb.enabled || !drv->scratch_reg)) {
+ seq = le32_to_cpu(*drv->cpu_addr);
+ } else {
+ seq = RREG32(drv->scratch_reg);
+ }
+ return seq;
+}
+
+/**
+ * radeon_fence_emit - emit a fence on the requested ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ * @ring: ring index the fence is associated with
+ *
+ * Emits a fence command on the requested ring (all asics).
+ * Returns 0 on success, -ENOMEM on failure.
+ */
+int radeon_fence_emit(struct radeon_device *rdev,
+ struct radeon_fence **fence,
+ int ring)
+{
+ /* we are protected by the ring emission mutex */
+ *fence = malloc(sizeof(struct radeon_fence), DRM_MEM_DRIVER, M_WAITOK);
+ if ((*fence) == NULL) {
+ return -ENOMEM;
+ }
+ refcount_init(&((*fence)->kref), 1);
+ (*fence)->rdev = rdev;
+ (*fence)->seq = ++rdev->fence_drv[ring].sync_seq[ring];
+ (*fence)->ring = ring;
+ radeon_fence_ring_emit(rdev, ring, *fence);
+ CTR2(KTR_DRM, "radeon fence: emit (ring=%d, seq=%d)", ring, (*fence)->seq);
+ return 0;
+}
+
+/**
+ * radeon_fence_process - process a fence
+ *
+ * @rdev: radeon_device pointer
+ * @ring: ring index the fence is associated with
+ *
+ * Checks the current fence value and wakes the fence queue
+ * if the sequence number has increased (all asics).
+ */
+void radeon_fence_process(struct radeon_device *rdev, int ring)
+{
+ uint64_t seq, last_seq, last_emitted;
+ unsigned count_loop = 0;
+ bool wake = false;
+
+ /* Note there is a scenario here for an infinite loop but it's
+ * very unlikely to happen. For it to happen, the current polling
+ * process need to be interrupted by another process and another
+ * process needs to update the last_seq btw the atomic read and
+ * xchg of the current process.
+ *
+ * More over for this to go in infinite loop there need to be
+ * continuously new fence signaled ie radeon_fence_read needs
+ * to return a different value each time for both the currently
+ * polling process and the other process that xchg the last_seq
+ * btw atomic read and xchg of the current process. And the
+ * value the other process set as last seq must be higher than
+ * the seq value we just read. Which means that current process
+ * need to be interrupted after radeon_fence_read and before
+ * atomic xchg.
+ *
+ * To be even more safe we count the number of time we loop and
+ * we bail after 10 loop just accepting the fact that we might
+ * have temporarly set the last_seq not to the true real last
+ * seq but to an older one.
+ */
+ last_seq = atomic_load_acq_64(&rdev->fence_drv[ring].last_seq);
+ do {
+ last_emitted = rdev->fence_drv[ring].sync_seq[ring];
+ seq = radeon_fence_read(rdev, ring);
+ seq |= last_seq & 0xffffffff00000000LL;
+ if (seq < last_seq) {
+ seq &= 0xffffffff;
+ seq |= last_emitted & 0xffffffff00000000LL;
+ }
+
+ if (seq <= last_seq || seq > last_emitted) {
+ break;
+ }
+ /* If we loop over we don't want to return without
+ * checking if a fence is signaled as it means that the
+ * seq we just read is different from the previous on.
+ */
+ wake = true;
+ last_seq = seq;
+ if ((count_loop++) > 10) {
+ /* We looped over too many time leave with the
+ * fact that we might have set an older fence
+ * seq then the current real last seq as signaled
+ * by the hw.
+ */
+ break;
+ }
+ } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq);
+
+ if (wake) {
+ rdev->fence_drv[ring].last_activity = jiffies;
+ cv_broadcast(&rdev->fence_queue);
+ }
+}
+
+/**
+ * radeon_fence_destroy - destroy a fence
+ *
+ * @kref: fence kref
+ *
+ * Frees the fence object (all asics).
+ */
+static void radeon_fence_destroy(struct radeon_fence *fence)
+{
+
+ free(fence, DRM_MEM_DRIVER);
+}
+
+/**
+ * radeon_fence_seq_signaled - check if a fence sequeuce number has signaled
+ *
+ * @rdev: radeon device pointer
+ * @seq: sequence number
+ * @ring: ring index the fence is associated with
+ *
+ * Check if the last singled fence sequnce number is >= the requested
+ * sequence number (all asics).
+ * Returns true if the fence has signaled (current fence value
+ * is >= requested value) or false if it has not (current fence
+ * value is < the requested value. Helper function for
+ * radeon_fence_signaled().
+ */
+static bool radeon_fence_seq_signaled(struct radeon_device *rdev,
+ u64 seq, unsigned ring)
+{
+ if (atomic_load_acq_64(&rdev->fence_drv[ring].last_seq) >= seq) {
+ return true;
+ }
+ /* poll new last sequence at least once */
+ radeon_fence_process(rdev, ring);
+ if (atomic_load_acq_64(&rdev->fence_drv[ring].last_seq) >= seq) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * radeon_fence_signaled - check if a fence has signaled
+ *
+ * @fence: radeon fence object
+ *
+ * Check if the requested fence has signaled (all asics).
+ * Returns true if the fence has signaled or false if it has not.
+ */
+bool radeon_fence_signaled(struct radeon_fence *fence)
+{
+ if (!fence) {
+ return true;
+ }
+ if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) {
+ return true;
+ }
+ if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) {
+ fence->seq = RADEON_FENCE_SIGNALED_SEQ;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * radeon_fence_wait_seq - wait for a specific sequence number
+ *
+ * @rdev: radeon device pointer
+ * @target_seq: sequence number we want to wait for
+ * @ring: ring index the fence is associated with
+ * @intr: use interruptable sleep
+ * @lock_ring: whether the ring should be locked or not
+ *
+ * Wait for the requested sequence number to be written (all asics).
+ * @intr selects whether to use interruptable (true) or non-interruptable
+ * (false) sleep when waiting for the sequence number. Helper function
+ * for radeon_fence_wait(), et al.
+ * Returns 0 if the sequence number has passed, error for all other cases.
+ * -EDEADLK is returned when a GPU lockup has been detected and the ring is
+ * marked as not ready so no further jobs get scheduled until a successful
+ * reset.
+ */
+static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq,
+ unsigned ring, bool intr, bool lock_ring)
+{
+ unsigned long timeout, last_activity;
+ uint64_t seq;
+ unsigned i;
+ bool signaled, fence_queue_locked;
+ int r;
+
+ while (target_seq > atomic_load_acq_64(&rdev->fence_drv[ring].last_seq)) {
+ if (!rdev->ring[ring].ready) {
+ return -EBUSY;
+ }
+
+ timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+ if (time_after(rdev->fence_drv[ring].last_activity, timeout)) {
+ /* the normal case, timeout is somewhere before last_activity */
+ timeout = rdev->fence_drv[ring].last_activity - timeout;
+ } else {
+ /* either jiffies wrapped around, or no fence was signaled in the last 500ms
+ * anyway we will just wait for the minimum amount and then check for a lockup
+ */
+ timeout = 1;
+ }
+ seq = atomic_load_acq_64(&rdev->fence_drv[ring].last_seq);
+ /* Save current last activity valuee, used to check for GPU lockups */
+ last_activity = rdev->fence_drv[ring].last_activity;
+
+ CTR2(KTR_DRM, "radeon fence: wait begin (ring=%d, seq=%d)",
+ ring, seq);
+
+ radeon_irq_kms_sw_irq_get(rdev, ring);
+ fence_queue_locked = false;
+ r = 0;
+ while (!(signaled = radeon_fence_seq_signaled(rdev,
+ target_seq, ring))) {
+ if (!fence_queue_locked) {
+ mtx_lock(&rdev->fence_queue_mtx);
+ fence_queue_locked = true;
+ }
+ if (intr) {
+ r = cv_timedwait_sig(&rdev->fence_queue,
+ &rdev->fence_queue_mtx,
+ timeout);
+ } else {
+ r = cv_timedwait(&rdev->fence_queue,
+ &rdev->fence_queue_mtx,
+ timeout);
+ }
+ if (r != 0) {
+ if (r == EWOULDBLOCK) {
+ signaled =
+ radeon_fence_seq_signaled(
+ rdev, target_seq, ring);
+ }
+ break;
+ }
+ }
+ if (fence_queue_locked) {
+ mtx_unlock(&rdev->fence_queue_mtx);
+ }
+ radeon_irq_kms_sw_irq_put(rdev, ring);
+ if (unlikely(r == EINTR || r == ERESTART)) {
+ return -r;
+ }
+ CTR2(KTR_DRM, "radeon fence: wait end (ring=%d, seq=%d)",
+ ring, seq);
+
+ if (unlikely(!signaled)) {
+#ifndef __FreeBSD__
+ /* we were interrupted for some reason and fence
+ * isn't signaled yet, resume waiting */
+ if (r) {
+ continue;
+ }
+#endif
+
+ /* check if sequence value has changed since last_activity */
+ if (seq != atomic_load_acq_64(&rdev->fence_drv[ring].last_seq)) {
+ continue;
+ }
+
+ if (lock_ring) {
+ sx_xlock(&rdev->ring_lock);
+ }
+
+ /* test if somebody else has already decided that this is a lockup */
+ if (last_activity != rdev->fence_drv[ring].last_activity) {
+ if (lock_ring) {
+ sx_xunlock(&rdev->ring_lock);
+ }
+ continue;
+ }
+
+ if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
+ /* good news we believe it's a lockup */
+ dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016jx last fence id 0x%016jx)\n",
+ (uintmax_t)target_seq, (uintmax_t)seq);
+
+ /* change last activity so nobody else think there is a lockup */
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ rdev->fence_drv[i].last_activity = jiffies;
+ }
+
+ /* mark the ring as not ready any more */
+ rdev->ring[ring].ready = false;
+ if (lock_ring) {
+ sx_xunlock(&rdev->ring_lock);
+ }
+ return -EDEADLK;
+ }
+
+ if (lock_ring) {
+ sx_xunlock(&rdev->ring_lock);
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * radeon_fence_wait - wait for a fence to signal
+ *
+ * @fence: radeon fence object
+ * @intr: use interruptable sleep
+ *
+ * Wait for the requested fence to signal (all asics).
+ * @intr selects whether to use interruptable (true) or non-interruptable
+ * (false) sleep when waiting for the fence.
+ * Returns 0 if the fence has passed, error for all other cases.
+ */
+int radeon_fence_wait(struct radeon_fence *fence, bool intr)
+{
+ int r;
+
+ if (fence == NULL) {
+ DRM_ERROR("Querying an invalid fence : %p !\n", fence);
+ return -EINVAL;
+ }
+
+ r = radeon_fence_wait_seq(fence->rdev, fence->seq,
+ fence->ring, intr, true);
+ if (r) {
+ return r;
+ }
+ fence->seq = RADEON_FENCE_SIGNALED_SEQ;
+ return 0;
+}
+
+static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq)
+{
+ unsigned i;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * radeon_fence_wait_any_seq - wait for a sequence number on any ring
+ *
+ * @rdev: radeon device pointer
+ * @target_seq: sequence number(s) we want to wait for
+ * @intr: use interruptable sleep
+ *
+ * Wait for the requested sequence number(s) to be written by any ring
+ * (all asics). Sequnce number array is indexed by ring id.
+ * @intr selects whether to use interruptable (true) or non-interruptable
+ * (false) sleep when waiting for the sequence number. Helper function
+ * for radeon_fence_wait_any(), et al.
+ * Returns 0 if the sequence number has passed, error for all other cases.
+ */
+static int radeon_fence_wait_any_seq(struct radeon_device *rdev,
+ u64 *target_seq, bool intr)
+{
+ unsigned long timeout, last_activity, tmp;
+ unsigned i, ring = RADEON_NUM_RINGS;
+ bool signaled, fence_queue_locked;
+ int r;
+
+ for (i = 0, last_activity = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (!target_seq[i]) {
+ continue;
+ }
+
+ /* use the most recent one as indicator */
+ if (time_after(rdev->fence_drv[i].last_activity, last_activity)) {
+ last_activity = rdev->fence_drv[i].last_activity;
+ }
+
+ /* For lockup detection just pick the lowest ring we are
+ * actively waiting for
+ */
+ if (i < ring) {
+ ring = i;
+ }
+ }
+
+ /* nothing to wait for ? */
+ if (ring == RADEON_NUM_RINGS) {
+ return -ENOENT;
+ }
+
+ while (!radeon_fence_any_seq_signaled(rdev, target_seq)) {
+ timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT;
+ if (time_after(last_activity, timeout)) {
+ /* the normal case, timeout is somewhere before last_activity */
+ timeout = last_activity - timeout;
+ } else {
+ /* either jiffies wrapped around, or no fence was signaled in the last 500ms
+ * anyway we will just wait for the minimum amount and then check for a lockup
+ */
+ timeout = 1;
+ }
+
+ CTR2(KTR_DRM, "radeon fence: wait begin (ring=%d, target_seq=%d)",
+ ring, target_seq[ring]);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (target_seq[i]) {
+ radeon_irq_kms_sw_irq_get(rdev, i);
+ }
+ }
+ fence_queue_locked = false;
+ r = 0;
+ while (!(signaled = radeon_fence_any_seq_signaled(rdev,
+ target_seq))) {
+ if (!fence_queue_locked) {
+ mtx_lock(&rdev->fence_queue_mtx);
+ fence_queue_locked = true;
+ }
+ if (intr) {
+ r = cv_timedwait_sig(&rdev->fence_queue,
+ &rdev->fence_queue_mtx,
+ timeout);
+ } else {
+ r = cv_timedwait(&rdev->fence_queue,
+ &rdev->fence_queue_mtx,
+ timeout);
+ }
+ if (r != 0) {
+ if (r == EWOULDBLOCK) {
+ signaled =
+ radeon_fence_any_seq_signaled(
+ rdev, target_seq);
+ }
+ break;
+ }
+ }
+ if (fence_queue_locked) {
+ mtx_unlock(&rdev->fence_queue_mtx);
+ }
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (target_seq[i]) {
+ radeon_irq_kms_sw_irq_put(rdev, i);
+ }
+ }
+ if (unlikely(r == EINTR || r == ERESTART)) {
+ return -r;
+ }
+ CTR2(KTR_DRM, "radeon fence: wait end (ring=%d, target_seq=%d)",
+ ring, target_seq[ring]);
+
+ if (unlikely(!signaled)) {
+#ifndef __FreeBSD__
+ /* we were interrupted for some reason and fence
+ * isn't signaled yet, resume waiting */
+ if (r) {
+ continue;
+ }
+#endif
+
+ sx_xlock(&rdev->ring_lock);
+ for (i = 0, tmp = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (time_after(rdev->fence_drv[i].last_activity, tmp)) {
+ tmp = rdev->fence_drv[i].last_activity;
+ }
+ }
+ /* test if somebody else has already decided that this is a lockup */
+ if (last_activity != tmp) {
+ last_activity = tmp;
+ sx_xunlock(&rdev->ring_lock);
+ continue;
+ }
+
+ if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) {
+ /* good news we believe it's a lockup */
+ dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016jx)\n",
+ (uintmax_t)target_seq[ring]);
+
+ /* change last activity so nobody else think there is a lockup */
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ rdev->fence_drv[i].last_activity = jiffies;
+ }
+
+ /* mark the ring as not ready any more */
+ rdev->ring[ring].ready = false;
+ sx_xunlock(&rdev->ring_lock);
+ return -EDEADLK;
+ }
+ sx_xunlock(&rdev->ring_lock);
+ }
+ }
+ return 0;
+}
+
+/**
+ * radeon_fence_wait_any - wait for a fence to signal on any ring
+ *
+ * @rdev: radeon device pointer
+ * @fences: radeon fence object(s)
+ * @intr: use interruptable sleep
+ *
+ * Wait for any requested fence to signal (all asics). Fence
+ * array is indexed by ring id. @intr selects whether to use
+ * interruptable (true) or non-interruptable (false) sleep when
+ * waiting for the fences. Used by the suballocator.
+ * Returns 0 if any fence has passed, error for all other cases.
+ */
+int radeon_fence_wait_any(struct radeon_device *rdev,
+ struct radeon_fence **fences,
+ bool intr)
+{
+ uint64_t seq[RADEON_NUM_RINGS];
+ unsigned i;
+ int r;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ seq[i] = 0;
+
+ if (!fences[i]) {
+ continue;
+ }
+
+ if (fences[i]->seq == RADEON_FENCE_SIGNALED_SEQ) {
+ /* something was allready signaled */
+ return 0;
+ }
+
+ seq[i] = fences[i]->seq;
+ }
+
+ r = radeon_fence_wait_any_seq(rdev, seq, intr);
+ if (r) {
+ return r;
+ }
+ return 0;
+}
+
+/**
+ * radeon_fence_wait_next_locked - wait for the next fence to signal
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring index the fence is associated with
+ *
+ * Wait for the next fence on the requested ring to signal (all asics).
+ * Returns 0 if the next fence has passed, error for all other cases.
+ * Caller must hold ring lock.
+ */
+int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring)
+{
+ uint64_t seq;
+
+ seq = atomic_load_acq_64(&rdev->fence_drv[ring].last_seq) + 1ULL;
+ if (seq >= rdev->fence_drv[ring].sync_seq[ring]) {
+ /* nothing to wait for, last_seq is
+ already the last emited fence */
+ return -ENOENT;
+ }
+ return radeon_fence_wait_seq(rdev, seq, ring, false, false);
+}
+
+/**
+ * radeon_fence_wait_empty_locked - wait for all fences to signal
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring index the fence is associated with
+ *
+ * Wait for all fences on the requested ring to signal (all asics).
+ * Returns 0 if the fences have passed, error for all other cases.
+ * Caller must hold ring lock.
+ */
+int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
+{
+ uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
+ int r;
+
+ r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
+ if (r) {
+ if (r == -EDEADLK) {
+ return -EDEADLK;
+ }
+ dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n",
+ ring, r);
+ }
+ return 0;
+}
+
+/**
+ * radeon_fence_ref - take a ref on a fence
+ *
+ * @fence: radeon fence object
+ *
+ * Take a reference on a fence (all asics).
+ * Returns the fence.
+ */
+struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence)
+{
+ refcount_acquire(&fence->kref);
+ return fence;
+}
+
+/**
+ * radeon_fence_unref - remove a ref on a fence
+ *
+ * @fence: radeon fence object
+ *
+ * Remove a reference on a fence (all asics).
+ */
+void radeon_fence_unref(struct radeon_fence **fence)
+{
+ struct radeon_fence *tmp = *fence;
+
+ *fence = NULL;
+ if (tmp) {
+ if (refcount_release(&tmp->kref)) {
+ radeon_fence_destroy(tmp);
+ }
+ }
+}
+
+/**
+ * radeon_fence_count_emitted - get the count of emitted fences
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring index the fence is associated with
+ *
+ * Get the number of fences emitted on the requested ring (all asics).
+ * Returns the number of emitted fences on the ring. Used by the
+ * dynpm code to ring track activity.
+ */
+unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring)
+{
+ uint64_t emitted;
+
+ /* We are not protected by ring lock when reading the last sequence
+ * but it's ok to report slightly wrong fence count here.
+ */
+ radeon_fence_process(rdev, ring);
+ emitted = rdev->fence_drv[ring].sync_seq[ring]
+ - atomic_load_acq_64(&rdev->fence_drv[ring].last_seq);
+ /* to avoid 32bits warp around */
+ if (emitted > 0x10000000) {
+ emitted = 0x10000000;
+ }
+ return (unsigned)emitted;
+}
+
+/**
+ * radeon_fence_need_sync - do we need a semaphore
+ *
+ * @fence: radeon fence object
+ * @dst_ring: which ring to check against
+ *
+ * Check if the fence needs to be synced against another ring
+ * (all asics). If so, we need to emit a semaphore.
+ * Returns true if we need to sync with another ring, false if
+ * not.
+ */
+bool radeon_fence_need_sync(struct radeon_fence *fence, int dst_ring)
+{
+ struct radeon_fence_driver *fdrv;
+
+ if (!fence) {
+ return false;
+ }
+
+ if (fence->ring == dst_ring) {
+ return false;
+ }
+
+ /* we are protected by the ring mutex */
+ fdrv = &fence->rdev->fence_drv[dst_ring];
+ if (fence->seq <= fdrv->sync_seq[fence->ring]) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * radeon_fence_note_sync - record the sync point
+ *
+ * @fence: radeon fence object
+ * @dst_ring: which ring to check against
+ *
+ * Note the sequence number at which point the fence will
+ * be synced with the requested ring (all asics).
+ */
+void radeon_fence_note_sync(struct radeon_fence *fence, int dst_ring)
+{
+ struct radeon_fence_driver *dst, *src;
+ unsigned i;
+
+ if (!fence) {
+ return;
+ }
+
+ if (fence->ring == dst_ring) {
+ return;
+ }
+
+ /* we are protected by the ring mutex */
+ src = &fence->rdev->fence_drv[fence->ring];
+ dst = &fence->rdev->fence_drv[dst_ring];
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (i == dst_ring) {
+ continue;
+ }
+ dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]);
+ }
+}
+
+/**
+ * radeon_fence_driver_start_ring - make the fence driver
+ * ready for use on the requested ring.
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring index to start the fence driver on
+ *
+ * Make the fence driver ready for processing (all asics).
+ * Not all asics have all rings, so each asic will only
+ * start the fence driver on the rings it has.
+ * Returns 0 for success, errors for failure.
+ */
+int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
+{
+ uint64_t index;
+ int r;
+
+ radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
+ if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) {
+ 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");
+ 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_load_acq_64(&rdev->fence_drv[ring].last_seq), ring);
+ rdev->fence_drv[ring].initialized = true;
+ dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016jx and cpu addr 0x%p\n",
+ ring, (uintmax_t)rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr);
+ return 0;
+}
+
+/**
+ * radeon_fence_driver_init_ring - init the fence driver
+ * for the requested ring.
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring index to start the fence driver on
+ *
+ * Init the fence driver for the requested ring (all asics).
+ * Helper function for radeon_fence_driver_init().
+ */
+static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring)
+{
+ int i;
+
+ rdev->fence_drv[ring].scratch_reg = -1;
+ rdev->fence_drv[ring].cpu_addr = NULL;
+ rdev->fence_drv[ring].gpu_addr = 0;
+ for (i = 0; i < RADEON_NUM_RINGS; ++i)
+ rdev->fence_drv[ring].sync_seq[i] = 0;
+ atomic_store_rel_64(&rdev->fence_drv[ring].last_seq, 0);
+ rdev->fence_drv[ring].last_activity = jiffies;
+ rdev->fence_drv[ring].initialized = false;
+}
+
+/**
+ * radeon_fence_driver_init - init the fence driver
+ * for all possible rings.
+ *
+ * @rdev: radeon device pointer
+ *
+ * Init the fence driver for all possible rings (all asics).
+ * Not all asics have all rings, so each asic will only
+ * start the fence driver on the rings it has using
+ * radeon_fence_driver_start_ring().
+ * Returns 0 for success.
+ */
+int radeon_fence_driver_init(struct radeon_device *rdev)
+{
+ int ring;
+
+ mtx_init(&rdev->fence_queue_mtx,
+ "drm__radeon_device__fence_queue_mtx", NULL, MTX_DEF);
+ cv_init(&rdev->fence_queue, "drm__radeon_device__fence_queue");
+ for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
+ radeon_fence_driver_init_ring(rdev, ring);
+ }
+ if (radeon_debugfs_fence_init(rdev)) {
+ dev_err(rdev->dev, "fence debugfs file creation failed\n");
+ }
+ return 0;
+}
+
+/**
+ * radeon_fence_driver_fini - tear down the fence driver
+ * for all possible rings.
+ *
+ * @rdev: radeon device pointer
+ *
+ * Tear down the fence driver for all possible rings (all asics).
+ */
+void radeon_fence_driver_fini(struct radeon_device *rdev)
+{
+ int ring, r;
+
+ sx_xlock(&rdev->ring_lock);
+ for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
+ if (!rdev->fence_drv[ring].initialized)
+ continue;
+ r = radeon_fence_wait_empty_locked(rdev, ring);
+ if (r) {
+ /* no need to trigger GPU reset as we are unloading */
+ radeon_fence_driver_force_completion(rdev);
+ }
+ cv_broadcast(&rdev->fence_queue);
+ radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
+ rdev->fence_drv[ring].initialized = false;
+ cv_destroy(&rdev->fence_queue);
+ }
+ sx_xunlock(&rdev->ring_lock);
+}
+
+/**
+ * radeon_fence_driver_force_completion - force all fence waiter to complete
+ *
+ * @rdev: radeon device pointer
+ *
+ * In case of GPU reset failure make sure no process keep waiting on fence
+ * that will never complete.
+ */
+void radeon_fence_driver_force_completion(struct radeon_device *rdev)
+{
+ int ring;
+
+ for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
+ if (!rdev->fence_drv[ring].initialized)
+ continue;
+ radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
+ }
+}
+
+
+/*
+ * 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;
+ int i, j;
+
+ 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%016llx\n",
+ (unsigned long long)atomic_load_acq_64(&rdev->fence_drv[i].last_seq));
+ seq_printf(m, "Last emitted 0x%016llx\n",
+ rdev->fence_drv[i].sync_seq[i]);
+
+ for (j = 0; j < RADEON_NUM_RINGS; ++j) {
+ if (i != j && rdev->fence_drv[j].initialized)
+ seq_printf(m, "Last sync to ring %d 0x%016llx\n",
+ j, rdev->fence_drv[i].sync_seq[j]);
+ }
+ }
+ 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/sys/dev/drm2/radeon/radeon_gart.c b/sys/dev/drm2/radeon/radeon_gart.c
new file mode 100644
index 0000000..36b4452
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_gart.c
@@ -0,0 +1,1304 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_reg.h"
+
+/*
+ * GART
+ * The GART (Graphics Aperture Remapping Table) is an aperture
+ * in the GPU's address space. System pages can be mapped into
+ * the aperture and look like contiguous pages from the GPU's
+ * perspective. A page table maps the pages in the aperture
+ * to the actual backing pages in system memory.
+ *
+ * Radeon GPUs support both an internal GART, as described above,
+ * and AGP. AGP works similarly, but the GART table is configured
+ * and maintained by the northbridge rather than the driver.
+ * Radeon hw has a separate AGP aperture that is programmed to
+ * point to the AGP aperture provided by the northbridge and the
+ * requests are passed through to the northbridge aperture.
+ * Both AGP and internal GART can be used at the same time, however
+ * that is not currently supported by the driver.
+ *
+ * This file handles the common internal GART management.
+ */
+
+/*
+ * Common GART table functions.
+ */
+/**
+ * radeon_gart_table_ram_alloc - allocate system ram for gart page table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Allocate system memory for GART page table
+ * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
+ * gart table to be in system memory.
+ * Returns 0 for success, -ENOMEM for failure.
+ */
+int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
+{
+ drm_dma_handle_t *dmah;
+
+ dmah = drm_pci_alloc(rdev->ddev, rdev->gart.table_size,
+ PAGE_SIZE, 0xFFFFFFFFUL);
+ if (dmah == NULL) {
+ return -ENOMEM;
+ }
+ rdev->gart.dmah = dmah;
+ rdev->gart.ptr = dmah->vaddr;
+#if defined(__i386) || defined(__amd64)
+ if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 ||
+ rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
+ pmap_change_attr((vm_offset_t)rdev->gart.ptr,
+ rdev->gart.table_size >> PAGE_SHIFT, PAT_UNCACHED);
+ }
+#endif
+ rdev->gart.table_addr = dmah->busaddr;
+ memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size);
+ return 0;
+}
+
+/**
+ * radeon_gart_table_ram_free - free system ram for gart page table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Free system memory for GART page table
+ * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
+ * gart table to be in system memory.
+ */
+void radeon_gart_table_ram_free(struct radeon_device *rdev)
+{
+ if (rdev->gart.ptr == NULL) {
+ return;
+ }
+#if defined(__i386) || defined(__amd64)
+ if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 ||
+ rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
+ pmap_change_attr((vm_offset_t)rdev->gart.ptr,
+ rdev->gart.table_size >> PAGE_SHIFT, PAT_WRITE_COMBINING);
+ }
+#endif
+ drm_pci_free(rdev->ddev, rdev->gart.dmah);
+ rdev->gart.dmah = NULL;
+ rdev->gart.ptr = NULL;
+ rdev->gart.table_addr = 0;
+}
+
+/**
+ * radeon_gart_table_vram_alloc - allocate vram for gart page table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Allocate video memory for GART page table
+ * (pcie r4xx, r5xx+). These asics require the
+ * gart table to be in video memory.
+ * Returns 0 for success, error for failure.
+ */
+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,
+ NULL, &rdev->gart.robj);
+ if (r) {
+ return r;
+ }
+ }
+ return 0;
+}
+
+/**
+ * radeon_gart_table_vram_pin - pin gart page table in vram
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Pin the GART page table in vram so it will not be moved
+ * by the memory manager (pcie r4xx, r5xx+). These asics require the
+ * gart table to be in video memory.
+ * Returns 0 for success, error for failure.
+ */
+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;
+}
+
+/**
+ * radeon_gart_table_vram_unpin - unpin gart page table in vram
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Unpin the GART page table in vram (pcie r4xx, r5xx+).
+ * These asics require the gart table to be in video memory.
+ */
+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;
+ }
+}
+
+/**
+ * radeon_gart_table_vram_free - free gart page table vram
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Free the video memory used for the GART page table
+ * (pcie r4xx, r5xx+). These asics require the gart table to
+ * be in video memory.
+ */
+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.
+ */
+/**
+ * radeon_gart_unbind - unbind pages from the gart page table
+ *
+ * @rdev: radeon_device pointer
+ * @offset: offset into the GPU's gart aperture
+ * @pages: number of pages to unbind
+ *
+ * Unbinds the requested pages from the gart page table and
+ * replaces them with the dummy page (all asics).
+ */
+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) {
+ DRM_ERROR("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);
+}
+
+/**
+ * radeon_gart_bind - bind pages into the gart page table
+ *
+ * @rdev: radeon_device pointer
+ * @offset: offset into the GPU's gart aperture
+ * @pages: number of pages to bind
+ * @pagelist: pages to bind
+ * @dma_addr: DMA addresses of pages
+ *
+ * Binds the requested pages to the gart page table
+ * (all asics).
+ * Returns 0 for success, -EINVAL for failure.
+ */
+int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
+ int pages, vm_page_t *pagelist, dma_addr_t *dma_addr)
+{
+ unsigned t;
+ unsigned p;
+ uint64_t page_base;
+ int i, j;
+
+ if (!rdev->gart.ready) {
+ DRM_ERROR("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;
+}
+
+/**
+ * radeon_gart_restore - bind all pages in the gart page table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Binds all pages in the gart page table (all asics).
+ * Used to rebuild the gart table on device startup or resume.
+ */
+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);
+}
+
+/**
+ * radeon_gart_init - init the driver info for managing the gart
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Allocate the dummy page and init the gart driver info (all asics).
+ * Returns 0 for success, error for failure.
+ */
+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 = malloc(sizeof(void *) * rdev->gart.num_cpu_pages,
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (rdev->gart.pages == NULL) {
+ radeon_gart_fini(rdev);
+ return -ENOMEM;
+ }
+ rdev->gart.pages_addr = malloc(sizeof(dma_addr_t) *
+ rdev->gart.num_cpu_pages,
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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;
+}
+
+/**
+ * radeon_gart_fini - tear down the driver info for managing the gart
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the gart driver info and free the dummy page (all asics).
+ */
+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;
+ free(rdev->gart.pages, DRM_MEM_DRIVER);
+ free(rdev->gart.pages_addr, DRM_MEM_DRIVER);
+ rdev->gart.pages = NULL;
+ rdev->gart.pages_addr = NULL;
+
+ radeon_dummy_page_fini(rdev);
+}
+
+/*
+ * GPUVM
+ * GPUVM is similar to the legacy gart on older asics, however
+ * rather than there being a single global gart table
+ * for the entire GPU, there are multiple VM page tables active
+ * at any given time. The VM page tables can contain a mix
+ * vram pages and system memory pages and system memory pages
+ * can be mapped as snooped (cached system pages) or unsnooped
+ * (uncached system pages).
+ * Each VM has an ID associated with it and there is a page table
+ * associated with each VMID. When execting a command buffer,
+ * the kernel tells the the ring what VMID to use for that command
+ * buffer. VMIDs are allocated dynamically as commands are submitted.
+ * The userspace drivers maintain their own address space and the kernel
+ * sets up their pages tables accordingly when they submit their
+ * command buffers and a VMID is assigned.
+ * Cayman/Trinity support up to 8 active VMs at any given time;
+ * SI supports 16.
+ */
+
+/*
+ * vm helpers
+ *
+ * TODO bind a default page at vm initialization for default address
+ */
+
+/**
+ * radeon_vm_num_pde - return the number of page directory entries
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Calculate the number of page directory entries (cayman+).
+ */
+static unsigned radeon_vm_num_pdes(struct radeon_device *rdev)
+{
+ return rdev->vm_manager.max_pfn >> RADEON_VM_BLOCK_SIZE;
+}
+
+/**
+ * radeon_vm_directory_size - returns the size of the page directory in bytes
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Calculate the size of the page directory in bytes (cayman+).
+ */
+static unsigned radeon_vm_directory_size(struct radeon_device *rdev)
+{
+ return RADEON_GPU_PAGE_ALIGN(radeon_vm_num_pdes(rdev) * 8);
+}
+
+/**
+ * radeon_vm_manager_init - init the vm manager
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Init the vm manager (cayman+).
+ * Returns 0 for success, error for failure.
+ */
+int radeon_vm_manager_init(struct radeon_device *rdev)
+{
+ struct radeon_vm *vm;
+ struct radeon_bo_va *bo_va;
+ int r;
+ unsigned size;
+
+ if (!rdev->vm_manager.enabled) {
+ /* allocate enough for 2 full VM pts */
+ size = radeon_vm_directory_size(rdev);
+ size += rdev->vm_manager.max_pfn * 8;
+ size *= 2;
+ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
+ RADEON_GPU_PAGE_ALIGN(size),
+ 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 = radeon_asic_vm_init(rdev);
+ if (r)
+ return r;
+
+ rdev->vm_manager.enabled = true;
+
+ r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
+ if (r)
+ return r;
+ }
+
+ /* restore page table */
+ list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
+ if (vm->page_directory == NULL)
+ continue;
+
+ list_for_each_entry(bo_va, &vm->va, vm_list) {
+ bo_va->valid = false;
+ }
+ }
+ return 0;
+}
+
+/**
+ * radeon_vm_free_pt - free the page table for a specific vm
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm to unbind
+ *
+ * Free the page table of a specific vm (cayman+).
+ *
+ * Global and local mutex must be lock!
+ */
+static void radeon_vm_free_pt(struct radeon_device *rdev,
+ struct radeon_vm *vm)
+{
+ struct radeon_bo_va *bo_va;
+ int i;
+
+ if (!vm->page_directory)
+ return;
+
+ list_del_init(&vm->list);
+ radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence);
+
+ list_for_each_entry(bo_va, &vm->va, vm_list) {
+ bo_va->valid = false;
+ }
+
+ if (vm->page_tables == NULL)
+ return;
+
+ for (i = 0; i < radeon_vm_num_pdes(rdev); i++)
+ radeon_sa_bo_free(rdev, &vm->page_tables[i], vm->fence);
+
+ free(vm->page_tables, DRM_MEM_DRIVER);
+}
+
+/**
+ * radeon_vm_manager_fini - tear down the vm manager
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the VM manager (cayman+).
+ */
+void radeon_vm_manager_fini(struct radeon_device *rdev)
+{
+ struct radeon_vm *vm, *tmp;
+ int i;
+
+ if (!rdev->vm_manager.enabled)
+ return;
+
+ sx_xlock(&rdev->vm_manager.lock);
+ /* free all allocated page tables */
+ list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) {
+ sx_xlock(&vm->mutex);
+ radeon_vm_free_pt(rdev, vm);
+ sx_xunlock(&vm->mutex);
+ }
+ for (i = 0; i < RADEON_NUM_VM; ++i) {
+ radeon_fence_unref(&rdev->vm_manager.active[i]);
+ }
+ radeon_asic_vm_fini(rdev);
+ sx_xunlock(&rdev->vm_manager.lock);
+
+ radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
+ radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager);
+ rdev->vm_manager.enabled = false;
+}
+
+/**
+ * radeon_vm_evict - evict page table to make room for new one
+ *
+ * @rdev: radeon_device pointer
+ * @vm: VM we want to allocate something for
+ *
+ * Evict a VM from the lru, making sure that it isn't @vm. (cayman+).
+ * Returns 0 for success, -ENOMEM for failure.
+ *
+ * Global and local mutex must be locked!
+ */
+static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm)
+{
+ struct radeon_vm *vm_evict;
+
+ if (list_empty(&rdev->vm_manager.lru_vm))
+ return -ENOMEM;
+
+ vm_evict = list_first_entry(&rdev->vm_manager.lru_vm,
+ struct radeon_vm, list);
+ if (vm_evict == vm)
+ return -ENOMEM;
+
+ sx_xlock(&vm_evict->mutex);
+ radeon_vm_free_pt(rdev, vm_evict);
+ sx_xunlock(&vm_evict->mutex);
+ return 0;
+}
+
+/**
+ * radeon_vm_alloc_pt - allocates a page table for a VM
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm to bind
+ *
+ * Allocate a page table for the requested vm (cayman+).
+ * Returns 0 for success, error for failure.
+ *
+ * Global and local mutex must be locked!
+ */
+int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm)
+{
+ unsigned pd_size, pts_size;
+ u64 *pd_addr;
+ int r;
+
+ if (vm == NULL) {
+ return -EINVAL;
+ }
+
+ if (vm->page_directory != NULL) {
+ return 0;
+ }
+
+retry:
+ pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
+ r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
+ &vm->page_directory, pd_size,
+ RADEON_GPU_PAGE_SIZE, false);
+ if (r == -ENOMEM) {
+ r = radeon_vm_evict(rdev, vm);
+ if (r)
+ return r;
+ goto retry;
+
+ } else if (r) {
+ return r;
+ }
+
+ vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory);
+
+ /* Initially clear the page directory */
+ pd_addr = radeon_sa_bo_cpu_addr(vm->page_directory);
+ memset(pd_addr, 0, pd_size);
+
+ pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *);
+ vm->page_tables = malloc(pts_size, DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ if (vm->page_tables == NULL) {
+ DRM_ERROR("Cannot allocate memory for page table array\n");
+ radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * radeon_vm_add_to_lru - add VMs page table to LRU list
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm to add to LRU
+ *
+ * Add the allocated page table to the LRU list (cayman+).
+ *
+ * Global mutex must be locked!
+ */
+void radeon_vm_add_to_lru(struct radeon_device *rdev, struct radeon_vm *vm)
+{
+ list_del_init(&vm->list);
+ list_add_tail(&vm->list, &rdev->vm_manager.lru_vm);
+}
+
+/**
+ * radeon_vm_grab_id - allocate the next free VMID
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm to allocate id for
+ * @ring: ring we want to submit job to
+ *
+ * Allocate an id for the vm (cayman+).
+ * Returns the fence we need to sync to (if any).
+ *
+ * Global and local mutex must be locked!
+ */
+struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev,
+ struct radeon_vm *vm, int ring)
+{
+ struct radeon_fence *best[RADEON_NUM_RINGS] = {};
+ unsigned choices[2] = {};
+ unsigned i;
+
+ /* check if the id is still valid */
+ if (vm->fence && vm->fence == rdev->vm_manager.active[vm->id])
+ return NULL;
+
+ /* we definately need to flush */
+ radeon_fence_unref(&vm->last_flush);
+
+ /* skip over VMID 0, since it is the system VM */
+ for (i = 1; i < rdev->vm_manager.nvm; ++i) {
+ struct radeon_fence *fence = rdev->vm_manager.active[i];
+
+ if (fence == NULL) {
+ /* found a free one */
+ vm->id = i;
+ return NULL;
+ }
+
+ if (radeon_fence_is_earlier(fence, best[fence->ring])) {
+ best[fence->ring] = fence;
+ choices[fence->ring == ring ? 0 : 1] = i;
+ }
+ }
+
+ for (i = 0; i < 2; ++i) {
+ if (choices[i]) {
+ vm->id = choices[i];
+ return rdev->vm_manager.active[choices[i]];
+ }
+ }
+
+ /* should never happen */
+ panic("%s: failed to allocate next VMID", __func__);
+ return NULL;
+}
+
+/**
+ * radeon_vm_fence - remember fence for vm
+ *
+ * @rdev: radeon_device pointer
+ * @vm: vm we want to fence
+ * @fence: fence to remember
+ *
+ * Fence the vm (cayman+).
+ * Set the fence used to protect page table and id.
+ *
+ * Global and local mutex must be locked!
+ */
+void radeon_vm_fence(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_fence *fence)
+{
+ radeon_fence_unref(&rdev->vm_manager.active[vm->id]);
+ rdev->vm_manager.active[vm->id] = radeon_fence_ref(fence);
+
+ radeon_fence_unref(&vm->fence);
+ vm->fence = radeon_fence_ref(fence);
+}
+
+/**
+ * radeon_vm_bo_find - find the bo_va for a specific vm & bo
+ *
+ * @vm: requested vm
+ * @bo: requested buffer object
+ *
+ * Find @bo inside the requested vm (cayman+).
+ * Search inside the @bos vm list for the requested vm
+ * Returns the found bo_va or NULL if none is found
+ *
+ * Object has to be reserved!
+ */
+struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
+ struct radeon_bo *bo)
+{
+ struct radeon_bo_va *bo_va;
+
+ list_for_each_entry(bo_va, &bo->va, bo_list) {
+ if (bo_va->vm == vm) {
+ return bo_va;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * radeon_vm_bo_add - add a bo to a specific vm
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ * @bo: radeon buffer object
+ *
+ * Add @bo into the requested vm (cayman+).
+ * Add @bo to the list of bos associated with the vm
+ * Returns newly added bo_va or NULL for failure
+ *
+ * Object has to be reserved!
+ */
+struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo)
+{
+ struct radeon_bo_va *bo_va;
+
+ bo_va = malloc(sizeof(struct radeon_bo_va),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (bo_va == NULL) {
+ return NULL;
+ }
+ bo_va->vm = vm;
+ bo_va->bo = bo;
+ bo_va->soffset = 0;
+ bo_va->eoffset = 0;
+ bo_va->flags = 0;
+ bo_va->valid = false;
+ bo_va->ref_count = 1;
+ INIT_LIST_HEAD(&bo_va->bo_list);
+ INIT_LIST_HEAD(&bo_va->vm_list);
+
+ sx_xlock(&vm->mutex);
+ list_add(&bo_va->vm_list, &vm->va);
+ list_add_tail(&bo_va->bo_list, &bo->va);
+ sx_xunlock(&vm->mutex);
+
+ return bo_va;
+}
+
+/**
+ * radeon_vm_bo_set_addr - set bos virtual address inside a vm
+ *
+ * @rdev: radeon_device pointer
+ * @bo_va: bo_va to store the address
+ * @soffset: requested offset of the buffer in the VM address space
+ * @flags: attributes of pages (read/write/valid/etc.)
+ *
+ * Set offset of @bo_va (cayman+).
+ * Validate and set the offset requested within the vm address space.
+ * Returns 0 for success, error for failure.
+ *
+ * Object has to be reserved!
+ */
+int radeon_vm_bo_set_addr(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va,
+ uint64_t soffset,
+ uint32_t flags)
+{
+ uint64_t size = radeon_bo_size(bo_va->bo);
+ uint64_t eoffset, last_offset = 0;
+ struct radeon_vm *vm = bo_va->vm;
+ struct radeon_bo_va *tmp;
+ struct list_head *head;
+ unsigned last_pfn;
+
+ if (soffset) {
+ /* make sure object fit at this offset */
+ eoffset = soffset + size;
+ if (soffset >= eoffset) {
+ return -EINVAL;
+ }
+
+ last_pfn = eoffset / RADEON_GPU_PAGE_SIZE;
+ if (last_pfn > rdev->vm_manager.max_pfn) {
+ dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n",
+ last_pfn, rdev->vm_manager.max_pfn);
+ return -EINVAL;
+ }
+
+ } else {
+ eoffset = last_pfn = 0;
+ }
+
+ sx_xlock(&vm->mutex);
+ head = &vm->va;
+ last_offset = 0;
+ list_for_each_entry(tmp, &vm->va, vm_list) {
+ if (bo_va == tmp) {
+ /* skip over currently modified bo */
+ continue;
+ }
+
+ if (soffset >= last_offset && eoffset <= tmp->soffset) {
+ /* bo can be added before this one */
+ break;
+ }
+ if (eoffset > tmp->soffset && 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_va->bo, (unsigned)bo_va->soffset, tmp->bo,
+ (unsigned)tmp->soffset, (unsigned)tmp->eoffset);
+ sx_xunlock(&vm->mutex);
+ return -EINVAL;
+ }
+ last_offset = tmp->eoffset;
+ head = &tmp->vm_list;
+ }
+
+ bo_va->soffset = soffset;
+ bo_va->eoffset = eoffset;
+ bo_va->flags = flags;
+ bo_va->valid = false;
+ list_move(&bo_va->vm_list, head);
+
+ sx_xunlock(&vm->mutex);
+ return 0;
+}
+
+/**
+ * radeon_vm_map_gart - get the physical address of a gart page
+ *
+ * @rdev: radeon_device pointer
+ * @addr: the unmapped addr
+ *
+ * Look up the physical address of the page that the pte resolves
+ * to (cayman+).
+ * Returns the physical address of the page.
+ */
+uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
+{
+ uint64_t result;
+
+ /* page table offset */
+ result = rdev->gart.pages_addr[addr >> PAGE_SHIFT];
+
+ /* in case cpu page size != gpu page size*/
+ result |= addr & (~PAGE_MASK);
+
+ return result;
+}
+
+/**
+ * radeon_vm_update_pdes - make sure that page directory is valid
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ * @start: start of GPU address range
+ * @end: end of GPU address range
+ *
+ * Allocates new page tables if necessary
+ * and updates the page directory (cayman+).
+ * Returns 0 for success, error for failure.
+ *
+ * Global and local mutex must be locked!
+ */
+static int radeon_vm_update_pdes(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ uint64_t start, uint64_t end)
+{
+ static const uint32_t incr = RADEON_VM_PTE_COUNT * 8;
+
+ uint64_t last_pde = ~0, last_pt = ~0;
+ unsigned count = 0;
+ uint64_t pt_idx;
+ int r;
+
+ start = (start / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE;
+ end = (end / RADEON_GPU_PAGE_SIZE) >> RADEON_VM_BLOCK_SIZE;
+
+ /* walk over the address space and update the page directory */
+ for (pt_idx = start; pt_idx <= end; ++pt_idx) {
+ uint64_t pde, pt;
+
+ if (vm->page_tables[pt_idx])
+ continue;
+
+retry:
+ r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
+ &vm->page_tables[pt_idx],
+ RADEON_VM_PTE_COUNT * 8,
+ RADEON_GPU_PAGE_SIZE, false);
+
+ if (r == -ENOMEM) {
+ r = radeon_vm_evict(rdev, vm);
+ if (r)
+ return r;
+ goto retry;
+ } else if (r) {
+ return r;
+ }
+
+ pde = vm->pd_gpu_addr + pt_idx * 8;
+
+ pt = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]);
+
+ if (((last_pde + 8 * count) != pde) ||
+ ((last_pt + incr * count) != pt)) {
+
+ if (count) {
+ radeon_asic_vm_set_page(rdev, last_pde,
+ last_pt, count, incr,
+ RADEON_VM_PAGE_VALID);
+ }
+
+ count = 1;
+ last_pde = pde;
+ last_pt = pt;
+ } else {
+ ++count;
+ }
+ }
+
+ if (count) {
+ radeon_asic_vm_set_page(rdev, last_pde, last_pt, count,
+ incr, RADEON_VM_PAGE_VALID);
+
+ }
+
+ return 0;
+}
+
+/**
+ * radeon_vm_update_ptes - make sure that page tables are valid
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ * @start: start of GPU address range
+ * @end: end of GPU address range
+ * @dst: destination address to map to
+ * @flags: mapping flags
+ *
+ * Update the page tables in the range @start - @end (cayman+).
+ *
+ * Global and local mutex must be locked!
+ */
+static void radeon_vm_update_ptes(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ uint64_t start, uint64_t end,
+ uint64_t dst, uint32_t flags)
+{
+ static const uint64_t mask = RADEON_VM_PTE_COUNT - 1;
+
+ uint64_t last_pte = ~0, last_dst = ~0;
+ unsigned count = 0;
+ uint64_t addr;
+
+ start = start / RADEON_GPU_PAGE_SIZE;
+ end = end / RADEON_GPU_PAGE_SIZE;
+
+ /* walk over the address space and update the page tables */
+ for (addr = start; addr < end; ) {
+ uint64_t pt_idx = addr >> RADEON_VM_BLOCK_SIZE;
+ unsigned nptes;
+ uint64_t pte;
+
+ if ((addr & ~mask) == (end & ~mask))
+ nptes = end - addr;
+ else
+ nptes = RADEON_VM_PTE_COUNT - (addr & mask);
+
+ pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]);
+ pte += (addr & mask) * 8;
+
+ if ((last_pte + 8 * count) != pte) {
+
+ if (count) {
+ radeon_asic_vm_set_page(rdev, last_pte,
+ last_dst, count,
+ RADEON_GPU_PAGE_SIZE,
+ flags);
+ }
+
+ count = nptes;
+ last_pte = pte;
+ last_dst = dst;
+ } else {
+ count += nptes;
+ }
+
+ addr += nptes;
+ dst += nptes * RADEON_GPU_PAGE_SIZE;
+ }
+
+ if (count) {
+ radeon_asic_vm_set_page(rdev, last_pte, last_dst, count,
+ RADEON_GPU_PAGE_SIZE, flags);
+ }
+}
+
+/**
+ * radeon_vm_bo_update_pte - map a bo into the vm page table
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ * @bo: radeon buffer object
+ * @mem: ttm mem
+ *
+ * Fill in the page table entries for @bo (cayman+).
+ * Returns 0 for success, -EINVAL for failure.
+ *
+ * Object have to be reserved & global and local mutex must be locked!
+ */
+int radeon_vm_bo_update_pte(struct radeon_device *rdev,
+ struct radeon_vm *vm,
+ struct radeon_bo *bo,
+ struct ttm_mem_reg *mem)
+{
+ unsigned ridx = rdev->asic->vm.pt_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ridx];
+ struct radeon_semaphore *sem = NULL;
+ struct radeon_bo_va *bo_va;
+ unsigned nptes, npdes, ndw;
+ uint64_t addr;
+ int r;
+
+ /* nothing to do if vm isn't bound */
+ if (vm->page_directory == NULL)
+ return 0;
+
+ bo_va = radeon_vm_bo_find(vm, bo);
+ if (bo_va == NULL) {
+ dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
+ return -EINVAL;
+ }
+
+ if (!bo_va->soffset) {
+ dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
+ bo, vm);
+ return -EINVAL;
+ }
+
+ if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL))
+ return 0;
+
+ bo_va->flags &= ~RADEON_VM_PAGE_VALID;
+ bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
+ if (mem) {
+ addr = mem->start << PAGE_SHIFT;
+ 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;
+ } else {
+ addr += rdev->vm_manager.vram_base_offset;
+ }
+ } else {
+ addr = 0;
+ bo_va->valid = false;
+ }
+
+ if (vm->fence && radeon_fence_signaled(vm->fence)) {
+ radeon_fence_unref(&vm->fence);
+ }
+
+ if (vm->fence && vm->fence->ring != ridx) {
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ return r;
+ }
+ }
+
+ nptes = radeon_bo_ngpu_pages(bo);
+
+ /* assume two extra pdes in case the mapping overlaps the borders */
+ npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2;
+
+ /* estimate number of dw needed */
+ /* semaphore, fence and padding */
+ ndw = 32;
+
+ if (RADEON_VM_BLOCK_SIZE > 11)
+ /* reserve space for one header for every 2k dwords */
+ ndw += (nptes >> 11) * 4;
+ else
+ /* reserve space for one header for
+ every (1 << BLOCK_SIZE) entries */
+ ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4;
+
+ /* reserve space for pte addresses */
+ ndw += nptes * 2;
+
+ /* reserve space for one header for every 2k dwords */
+ ndw += (npdes >> 11) * 4;
+
+ /* reserve space for pde addresses */
+ ndw += npdes * 2;
+
+ r = radeon_ring_lock(rdev, ring, ndw);
+ if (r) {
+ return r;
+ }
+
+ if (sem && radeon_fence_need_sync(vm->fence, ridx)) {
+ radeon_semaphore_sync_rings(rdev, sem, vm->fence->ring, ridx);
+ radeon_fence_note_sync(vm->fence, ridx);
+ }
+
+ r = radeon_vm_update_pdes(rdev, vm, bo_va->soffset, bo_va->eoffset);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ radeon_vm_update_ptes(rdev, vm, bo_va->soffset, bo_va->eoffset,
+ addr, bo_va->flags);
+
+ radeon_fence_unref(&vm->fence);
+ r = radeon_fence_emit(rdev, &vm->fence, ridx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, vm->fence);
+ radeon_fence_unref(&vm->last_flush);
+
+ return 0;
+}
+
+/**
+ * radeon_vm_bo_rmv - remove a bo to a specific vm
+ *
+ * @rdev: radeon_device pointer
+ * @bo_va: requested bo_va
+ *
+ * Remove @bo_va->bo from the requested vm (cayman+).
+ * Remove @bo_va->bo from the list of bos associated with the bo_va->vm and
+ * remove the ptes for @bo_va in the page table.
+ * Returns 0 for success.
+ *
+ * Object have to be reserved!
+ */
+int radeon_vm_bo_rmv(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va)
+{
+ int r;
+
+ sx_xlock(&rdev->vm_manager.lock);
+ sx_xlock(&bo_va->vm->mutex);
+ r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL);
+ sx_xunlock(&rdev->vm_manager.lock);
+ list_del(&bo_va->vm_list);
+ sx_xunlock(&bo_va->vm->mutex);
+ list_del(&bo_va->bo_list);
+
+ free(bo_va, DRM_MEM_DRIVER);
+ return r;
+}
+
+/**
+ * radeon_vm_bo_invalidate - mark the bo as invalid
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ * @bo: radeon buffer object
+ *
+ * Mark @bo as invalid (cayman+).
+ */
+void radeon_vm_bo_invalidate(struct radeon_device *rdev,
+ struct radeon_bo *bo)
+{
+ struct radeon_bo_va *bo_va;
+
+ list_for_each_entry(bo_va, &bo->va, bo_list) {
+ bo_va->valid = false;
+ }
+}
+
+/**
+ * radeon_vm_init - initialize a vm instance
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ *
+ * Init @vm fields (cayman+).
+ */
+void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
+{
+ vm->id = 0;
+ vm->fence = NULL;
+ sx_init(&vm->mutex, "drm__radeon_vm__mutex");
+ INIT_LIST_HEAD(&vm->list);
+ INIT_LIST_HEAD(&vm->va);
+}
+
+/**
+ * radeon_vm_fini - tear down a vm instance
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ *
+ * Tear down @vm (cayman+).
+ * Unbind the VM and remove all bos from the vm bo list
+ */
+void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
+{
+ struct radeon_bo_va *bo_va, *tmp;
+ int r;
+
+ sx_xlock(&rdev->vm_manager.lock);
+ sx_xlock(&vm->mutex);
+ radeon_vm_free_pt(rdev, vm);
+ sx_xunlock(&rdev->vm_manager.lock);
+
+ 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);
+ free(bo_va, DRM_MEM_DRIVER);
+ }
+ }
+ radeon_fence_unref(&vm->fence);
+ radeon_fence_unref(&vm->last_flush);
+ sx_xunlock(&vm->mutex);
+}
diff --git a/sys/dev/drm2/radeon/radeon_gem.c b/sys/dev/drm2/radeon/radeon_gem.c
new file mode 100644
index 0000000..390298e
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_gem.c
@@ -0,0 +1,585 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_gem.h"
+
+int radeon_gem_object_init(struct drm_gem_object *obj)
+{
+ panic("radeon_gem_object_init() must not be called");
+
+ return 0;
+}
+
+void radeon_gem_object_free(struct drm_gem_object *gobj)
+{
+ struct radeon_bo *robj = gem_to_radeon_bo(gobj);
+
+ if (robj) {
+#ifdef DUMBBELL_WIP
+ if (robj->gem_base.import_attach)
+ drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
+#endif /* DUMBBELL_WIP */
+ 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;
+ unsigned long max_size;
+ int r;
+
+ *obj = NULL;
+ /* At least align on page size */
+ if (alignment < PAGE_SIZE) {
+ alignment = PAGE_SIZE;
+ }
+
+ /* 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 (size > max_size) {
+ DRM_ERROR("%s:%d alloc size %dMb bigger than %ldMb limit\n",
+ __func__, __LINE__, size >> 20, max_size >> 20);
+ return -ENOMEM;
+ }
+
+retry:
+ r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj);
+ if (r) {
+ if (r != -ERESTART) {
+ if (initial_domain == RADEON_GEM_DOMAIN_VRAM) {
+ initial_domain |= RADEON_GEM_DOMAIN_GTT;
+ goto retry;
+ }
+ DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
+ size, initial_domain, alignment, r);
+ }
+ return r;
+ }
+ *obj = &robj->gem_base;
+
+ sx_xlock(&rdev->gem.mutex);
+ list_add_tail(&robj->list, &rdev->gem.objects);
+ sx_xunlock(&rdev->gem.mutex);
+
+ return 0;
+}
+
+static 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 */
+ DRM_ERROR("Set domain without 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) {
+ DRM_ERROR("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)
+{
+ 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;
+ int r;
+
+ if (rdev->family < CHIP_CAYMAN) {
+ return 0;
+ }
+
+ r = radeon_bo_reserve(rbo, false);
+ if (r) {
+ return r;
+ }
+
+ bo_va = radeon_vm_bo_find(vm, rbo);
+ if (!bo_va) {
+ bo_va = radeon_vm_bo_add(rdev, vm, rbo);
+ } else {
+ ++bo_va->ref_count;
+ }
+ radeon_bo_unreserve(rbo);
+
+ 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;
+ int r;
+
+ if (rdev->family < CHIP_CAYMAN) {
+ return;
+ }
+
+ r = radeon_bo_reserve(rbo, true);
+ if (r) {
+ dev_err(rdev->dev, "leaking bo va because "
+ "we fail to reserve bo (%d)\n", r);
+ return;
+ }
+ bo_va = radeon_vm_bo_find(vm, rbo);
+ if (bo_va) {
+ if (--bo_va->ref_count == 0) {
+ radeon_vm_bo_rmv(rdev, bo_va);
+ }
+ }
+ radeon_bo_unreserve(rbo);
+}
+
+static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r)
+{
+ if (r == -EDEADLK) {
+ r = radeon_gpu_reset(rdev);
+ if (!r)
+ r = -EAGAIN;
+ }
+ return r;
+}
+
+/*
+ * 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;
+
+ sx_slock(&rdev->exclusive_lock);
+ /* 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) {
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_gem_handle_lockup(rdev, r);
+ return r;
+ }
+ handle = 0;
+ r = drm_gem_handle_create(filp, gobj, &handle);
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(gobj);
+ if (r) {
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_gem_handle_lockup(rdev, r);
+ return r;
+ }
+ args->handle = handle;
+ sx_sunlock(&rdev->exclusive_lock);
+ 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 radeon_device *rdev = dev->dev_private;
+ 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 */
+ sx_slock(&rdev->exclusive_lock);
+
+ /* just do a BO wait for now */
+ gobj = drm_gem_object_lookup(dev, filp, args->handle);
+ if (gobj == NULL) {
+ sx_sunlock(&rdev->exclusive_lock);
+ 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);
+ sx_sunlock(&rdev->exclusive_lock);
+ r = radeon_gem_handle_lockup(robj->rdev, r);
+ 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 radeon_device *rdev = dev->dev_private;
+ 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);
+ r = radeon_gem_handle_lockup(rdev, r);
+ return r;
+}
+
+int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ 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 (rdev->asic->ioctl_wait_idle)
+ robj->rdev->asic->ioctl_wait_idle(rdev, robj);
+ drm_gem_object_unreference_unlocked(gobj);
+ r = radeon_gem_handle_lockup(rdev, r);
+ 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->device,
+ "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->device, "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->device, "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->device, "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;
+ }
+ bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
+ if (!bo_va) {
+ args->operation = RADEON_VA_RESULT_ERROR;
+ drm_gem_object_unreference_unlocked(gobj);
+ return -ENOENT;
+ }
+
+ switch (args->operation) {
+ case RADEON_VA_MAP:
+ if (bo_va->soffset) {
+ args->operation = RADEON_VA_RESULT_VA_EXIST;
+ args->offset = bo_va->soffset;
+ goto out;
+ }
+ r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags);
+ break;
+ case RADEON_VA_UNMAP:
+ r = radeon_vm_bo_set_addr(rdev, bo_va, 0, 0);
+ 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 = roundup2(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/sys/dev/drm2/radeon/radeon_gem.h b/sys/dev/drm2/radeon/radeon_gem.h
new file mode 100644
index 0000000..c7edd50
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_gem.h
@@ -0,0 +1,17 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_GEM_H__
+#define __RADEON_GEM_H__
+
+#include <dev/drm2/drmP.h>
+
+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);
+
+#endif /* !defined(__RADEON_GEM_H__) */
diff --git a/sys/dev/drm2/radeon/radeon_i2c.c b/sys/dev/drm2/radeon/radeon_i2c.c
new file mode 100644
index 0000000..917286a
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_i2c.c
@@ -0,0 +1,1384 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_edid.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include <dev/iicbus/iic.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include "radeon.h"
+#include "atom.h"
+#include "iicbus_if.h"
+#include "iicbb_if.h"
+
+/**
+ * radeon_ddc_probe
+ *
+ */
+bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux)
+{
+ u8 out = 0x0;
+ u8 buf[8];
+ int ret;
+ struct iic_msg msgs[] = {
+ {
+ .slave = DDC_ADDR << 1,
+ .flags = 0,
+ .len = 1,
+ .buf = &out,
+ },
+ {
+ .slave = DDC_ADDR << 1,
+ .flags = IIC_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);
+
+ if (use_aux) {
+ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+ ret = iicbus_transfer(dig->dp_i2c_bus->adapter, msgs, 2);
+ } else {
+ ret = iicbus_transfer(radeon_connector->ddc_bus->adapter, msgs, 2);
+ }
+
+ if (ret != 0)
+ /* 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 radeon_iicbb_pre_xfer(device_t dev)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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;
+
+ sx_xlock(&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)));
+ }
+ sx_xunlock(&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 radeon_iicbb_post_xfer(device_t dev)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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 radeon_iicbb_get_clock(device_t dev)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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 radeon_iicbb_get_data(device_t dev)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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 radeon_iicbb_set_clock(device_t dev, int clock)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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 radeon_iicbb_set_data(device_t dev, int data)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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);
+}
+
+static int
+radeon_iicbb_probe(device_t dev)
+{
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+radeon_iicbb_attach(device_t dev)
+{
+ struct radeon_i2c_chan *i2c;
+ device_t iic_dev;
+
+ i2c = device_get_softc(dev);
+ device_set_desc(dev, i2c->name);
+
+ /* add generic bit-banging code */
+ iic_dev = device_add_child(dev, "iicbb", -1);
+ if (iic_dev == NULL)
+ return (ENXIO);
+ device_quiet(iic_dev);
+
+ /* attach and probe added child */
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static int
+radeon_iicbb_detach(device_t dev)
+{
+
+ /* detach bit-banding code. */
+ bus_generic_detach(dev);
+
+ /* delete bit-banding code. */
+ device_delete_children(dev);
+ return (0);
+}
+
+static int
+radeon_iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+
+ /* Not sure what to do here. */
+ return 0;
+}
+
+static device_method_t radeon_iicbb_methods[] = {
+ DEVMETHOD(device_probe, radeon_iicbb_probe),
+ DEVMETHOD(device_attach, radeon_iicbb_attach),
+ DEVMETHOD(device_detach, radeon_iicbb_detach),
+
+ DEVMETHOD(bus_add_child, bus_generic_add_child),
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+ DEVMETHOD(iicbb_reset, radeon_iicbb_reset),
+ DEVMETHOD(iicbb_pre_xfer, radeon_iicbb_pre_xfer),
+ DEVMETHOD(iicbb_post_xfer, radeon_iicbb_post_xfer),
+ DEVMETHOD(iicbb_setsda, radeon_iicbb_set_data),
+ DEVMETHOD(iicbb_setscl, radeon_iicbb_set_clock),
+ DEVMETHOD(iicbb_getsda, radeon_iicbb_get_data),
+ DEVMETHOD(iicbb_getscl, radeon_iicbb_get_clock),
+ DEVMETHOD_END
+};
+
+static driver_t radeon_iicbb_driver = {
+ "radeon_iicbb",
+ radeon_iicbb_methods,
+ 0 /* softc will be allocated by parent */
+};
+static devclass_t radeon_iicbb_devclass;
+DRIVER_MODULE_ORDERED(radeon_iicbb, drmn, radeon_iicbb_driver,
+ radeon_iicbb_devclass, 0, 0, SI_ORDER_FIRST);
+DRIVER_MODULE(iicbb, radeon_iicbb, iicbb_driver, iicbb_devclass, 0, 0);
+
+/* 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 radeon_i2c_chan *i2c,
+ struct iic_msg *msgs, int num)
+{
+ struct radeon_device *rdev = i2c->dev->dev_private;
+ struct radeon_i2c_bus_rec *rec = &i2c->rec;
+ struct iic_msg *p;
+ int i, j, k, ret = 0;
+ u32 prescale;
+ u32 i2c_cntl_0, i2c_cntl_1, i2c_data;
+ u32 tmp, reg;
+
+ sx_xlock(&rdev->dc_hw_i2c_mutex);
+ /* take the pm lock since we need a constant sclk */
+ sx_xlock(&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->slave << 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++) {
+ DRM_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 & IIC_M_RD) {
+ WREG32(i2c_cntl_0, (RADEON_I2C_DONE |
+ RADEON_I2C_NACK |
+ RADEON_I2C_HALT |
+ RADEON_I2C_SOFT_RST));
+ WREG32(i2c_data, ((p->slave << 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++) {
+ DRM_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->slave << 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++) {
+ DRM_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);
+ }
+
+ sx_xunlock(&rdev->pm.mutex);
+ sx_xunlock(&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 radeon_i2c_chan *i2c,
+ struct iic_msg *msgs, int num)
+{
+ struct radeon_device *rdev = i2c->dev->dev_private;
+ struct radeon_i2c_bus_rec *rec = &i2c->rec;
+ struct iic_msg *p;
+ int i, j, remaining, current_count, buffer_offset, ret = 0;
+ u32 prescale;
+ u32 tmp, reg;
+ u32 saved1, saved2;
+
+ sx_xlock(&rdev->dc_hw_i2c_mutex);
+ /* take the pm lock since we need a constant sclk */
+ sx_xlock(&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++) {
+ DRM_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);
+ DRM_UDELAY(1);
+ WREG32(AVIVO_DC_I2C_RESET, 0);
+
+ WREG32(AVIVO_DC_I2C_DATA, (p->slave << 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++) {
+ DRM_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 & IIC_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);
+ DRM_UDELAY(1);
+ WREG32(AVIVO_DC_I2C_RESET, 0);
+
+ WREG32(AVIVO_DC_I2C_DATA, ((p->slave << 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++) {
+ DRM_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);
+ DRM_UDELAY(1);
+ WREG32(AVIVO_DC_I2C_RESET, 0);
+
+ WREG32(AVIVO_DC_I2C_DATA, (p->slave << 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++) {
+ DRM_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);
+ DRM_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);
+
+ sx_xunlock(&rdev->pm.mutex);
+ sx_xunlock(&rdev->dc_hw_i2c_mutex);
+
+ return ret;
+}
+
+static int radeon_hw_i2c_xfer(device_t dev,
+ struct iic_msg *msgs, uint32_t num)
+{
+ struct radeon_i2c_chan *i2c = device_get_softc(dev);
+ 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, 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, msgs, num);
+ else
+ ret = r500_hw_i2c_xfer(i2c, 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 int
+radeon_hw_i2c_probe(device_t dev)
+{
+
+ return (BUS_PROBE_SPECIFIC);
+}
+
+static int
+radeon_hw_i2c_attach(device_t dev)
+{
+ struct radeon_i2c_chan *i2c;
+ device_t iic_dev;
+
+ i2c = device_get_softc(dev);
+ device_set_desc(dev, i2c->name);
+
+ /* add generic bit-banging code */
+ iic_dev = device_add_child(dev, "iicbus", -1);
+ if (iic_dev == NULL)
+ return (ENXIO);
+ device_quiet(iic_dev);
+
+ /* attach and probe added child */
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static int
+radeon_hw_i2c_detach(device_t dev)
+{
+
+ /* detach bit-banding code. */
+ bus_generic_detach(dev);
+
+ /* delete bit-banding code. */
+ device_delete_children(dev);
+ return (0);
+}
+
+static int
+radeon_hw_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+
+ /* Not sure what to do here. */
+ return 0;
+}
+
+
+static device_method_t radeon_hw_i2c_methods[] = {
+ DEVMETHOD(device_probe, radeon_hw_i2c_probe),
+ DEVMETHOD(device_attach, radeon_hw_i2c_attach),
+ DEVMETHOD(device_detach, radeon_hw_i2c_detach),
+ DEVMETHOD(iicbus_reset, radeon_hw_i2c_reset),
+ DEVMETHOD(iicbus_transfer, radeon_hw_i2c_xfer),
+ DEVMETHOD_END
+};
+
+static driver_t radeon_hw_i2c_driver = {
+ "radeon_hw_i2c",
+ radeon_hw_i2c_methods,
+ 0 /* softc will be allocated by parent */
+};
+
+static devclass_t radeon_hw_i2c_devclass;
+DRIVER_MODULE_ORDERED(radeon_hw_i2c, drm, radeon_hw_i2c_driver,
+ radeon_hw_i2c_devclass, 0, 0, SI_ORDER_FIRST);
+DRIVER_MODULE(iicbus, radeon_hw_i2c, iicbus_driver, iicbus_devclass, 0, 0);
+
+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;
+ device_t iicbus_dev;
+ 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 = malloc(sizeof(struct radeon_i2c_chan),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (i2c == NULL)
+ return NULL;
+
+ /*
+ * Grab Giant before messing with newbus devices, just in case
+ * we do not hold it already.
+ */
+ mtx_lock(&Giant);
+
+ i2c->rec = *rec;
+ i2c->dev = dev;
+ 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->name, sizeof(i2c->name),
+ "Radeon i2c hw bus %s", name);
+ iicbus_dev = device_add_child(dev->device, "radeon_hw_i2c", -1);
+ if (iicbus_dev == NULL) {
+ DRM_ERROR("Failed to create bridge for hw i2c %s\n",
+ name);
+ goto out_free;
+ }
+ device_quiet(iicbus_dev);
+ device_set_softc(iicbus_dev, i2c);
+
+ ret = device_probe_and_attach(iicbus_dev);
+ if (ret != 0) {
+ DRM_ERROR("Attach failed for bridge for hw i2c %s\n",
+ name);
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+
+ i2c->adapter = device_find_child(iicbus_dev, "iicbus", -1);
+ if (i2c->adapter == NULL) {
+ DRM_ERROR("hw i2c bridge doesn't have iicbus child\n");
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+ } else if (rec->hw_capable &&
+ radeon_hw_i2c &&
+ ASIC_IS_DCE3(rdev)) {
+ /* hw i2c using atom */
+ snprintf(i2c->name, sizeof(i2c->name),
+ "Radeon i2c hw bus %s", name);
+ iicbus_dev = device_add_child(dev->device, "radeon_atom_hw_i2c", -1);
+ if (iicbus_dev == NULL) {
+ DRM_ERROR("Failed to create bridge for hw i2c %s\n",
+ name);
+ goto out_free;
+ }
+ device_quiet(iicbus_dev);
+ device_set_softc(iicbus_dev, i2c);
+
+ ret = device_probe_and_attach(iicbus_dev);
+ if (ret != 0) {
+ DRM_ERROR("Attach failed for bridge for hw i2c %s\n",
+ name);
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+
+ i2c->adapter = device_find_child(iicbus_dev, "iicbus", -1);
+ if (i2c->adapter == NULL) {
+ DRM_ERROR("hw i2c bridge doesn't have iicbus child\n");
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+ } else {
+ device_t iicbb_dev;
+
+ /* set the radeon bit adapter */
+ snprintf(i2c->name, sizeof(i2c->name),
+ "Radeon i2c bit bus %s", name);
+ iicbus_dev = device_add_child(dev->device, "radeon_iicbb", -1);
+ if (iicbus_dev == NULL) {
+ DRM_ERROR("Failed to create bridge for bb i2c %s\n",
+ name);
+ goto out_free;
+ }
+ device_quiet(iicbus_dev);
+ device_set_softc(iicbus_dev, i2c);
+
+ ret = device_probe_and_attach(iicbus_dev);
+ if (ret != 0) {
+ DRM_ERROR("Attach failed for bridge for bb i2c %s\n",
+ name);
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+
+ iicbb_dev = device_find_child(iicbus_dev, "iicbb", -1);
+ if (iicbb_dev == NULL) {
+ DRM_ERROR("bb i2c bridge doesn't have iicbb child\n");
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+
+ i2c->adapter = device_find_child(iicbb_dev, "iicbus", -1);
+ if (i2c->adapter == NULL) {
+ DRM_ERROR(
+ "bbbus bridge doesn't have iicbus grandchild\n");
+ device_delete_child(dev->device, iicbus_dev);
+ goto out_free;
+ }
+ }
+
+ i2c->iic_bus = iicbus_dev;
+
+ mtx_unlock(&Giant);
+
+ return i2c;
+out_free:
+ mtx_unlock(&Giant);
+ free(i2c, DRM_MEM_DRIVER);
+ 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 = malloc(sizeof(struct radeon_i2c_chan),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (i2c == NULL)
+ return NULL;
+
+ i2c->rec = *rec;
+ i2c->dev = dev;
+ snprintf(i2c->name, sizeof(i2c->name),
+ "Radeon aux bus %s", name);
+ ret = iic_dp_aux_add_bus(dev->device, i2c->name,
+ radeon_dp_i2c_aux_ch, i2c, &i2c->iic_bus,
+ &i2c->adapter);
+ if (ret) {
+ DRM_INFO("Failed to register i2c %s\n", name);
+ goto out_free;
+ }
+
+ return i2c;
+out_free:
+ free(i2c, DRM_MEM_DRIVER);
+ return NULL;
+
+}
+
+void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
+{
+ if (!i2c)
+ return;
+ if (i2c->iic_bus != NULL) {
+ int ret;
+
+ mtx_lock(&Giant);
+ ret = device_delete_child(i2c->dev->device, i2c->iic_bus);
+ mtx_unlock(&Giant);
+ KASSERT(ret == 0, ("unable to detach iic bus %s: %d",
+ i2c->name, ret));
+ }
+ free(i2c, DRM_MEM_DRIVER);
+}
+
+/* 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 iic_msg msgs[] = {
+ {
+ .slave = slave_addr << 1,
+ .flags = 0,
+ .len = 1,
+ .buf = out_buf,
+ },
+ {
+ .slave = slave_addr << 1,
+ .flags = IIC_M_RD,
+ .len = 1,
+ .buf = in_buf,
+ }
+ };
+
+ out_buf[0] = addr;
+ out_buf[1] = 0;
+
+ if (iicbus_transfer(i2c_bus->adapter, msgs, 2) == 0) {
+ *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 iic_msg msg = {
+ .slave = slave_addr << 1,
+ .flags = 0,
+ .len = 2,
+ .buf = out_buf,
+ };
+
+ out_buf[0] = addr;
+ out_buf[1] = val;
+
+ if (iicbus_transfer(i2c_bus->adapter, &msg, 1) != 0)
+ 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/sys/dev/drm2/radeon/radeon_ioc32.c b/sys/dev/drm2/radeon/radeon_ioc32.c
new file mode 100644
index 0000000..361d48c
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_ioc32.c
@@ -0,0 +1,428 @@
+/**
+ * \file radeon_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the Radeon DRM.
+ *
+ * \author Paul Mackerras <paulus@samba.org>
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <linux/compat.h>
+
+#include <drm/drmP.h>
+#include <drm/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 */
+
+static 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<n>.
+ *
+ * \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/sys/dev/drm2/radeon/radeon_irq.c b/sys/dev/drm2/radeon/radeon_irq.c
new file mode 100644
index 0000000..11e66e1
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_irq.c
@@ -0,0 +1,403 @@
+/* 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 <keith@tungstengraphics.com>
+ * Michel D�zer <michel@daenzer.net>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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/sys/dev/drm2/radeon/radeon_irq_kms.c b/sys/dev/drm2/radeon/radeon_irq_kms.c
new file mode 100644
index 0000000..a679ed1
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_irq_kms.c
@@ -0,0 +1,468 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_reg.h"
+#include "radeon_irq_kms.h"
+#include "radeon.h"
+#include "atom.h"
+
+#define RADEON_WAIT_IDLE_TIMEOUT 200
+
+/**
+ * radeon_driver_irq_handler_kms - irq handler for KMS
+ *
+ * @DRM_IRQ_ARGS: args
+ *
+ * This is the irq handler for the radeon KMS driver (all asics).
+ * radeon_irq_process is a macro that points to the per-asic
+ * irq handler callback.
+ */
+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.
+ */
+/**
+ * radeon_hotplug_work_func - display hotplug work handler
+ *
+ * @work: work struct
+ *
+ * This is the hot plug event work handler (all asics).
+ * The work gets scheduled from the irq handler if there
+ * was a hot plug interrupt. It walks the connector table
+ * and calls the hotplug handler for each one, then sends
+ * a drm hotplug event to alert userspace.
+ */
+static void radeon_hotplug_work_func(void *arg, int pending)
+{
+ struct radeon_device *rdev = arg;
+ 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);
+}
+
+/**
+ * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
+ *
+ * @dev: drm dev pointer
+ *
+ * Gets the hw ready to enable irqs (all asics).
+ * This function disables all interrupt sources on the GPU.
+ */
+void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ unsigned long irqflags;
+ unsigned i;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ /* Disable *all* interrupts */
+ for (i = 0; i < RADEON_NUM_RINGS; i++)
+ atomic_set(&rdev->irq.ring_int[i], 0);
+ 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;
+ atomic_set(&rdev->irq.pflip[i], 0);
+ rdev->irq.afmt[i] = false;
+ }
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+ /* Clear bits */
+ radeon_irq_process(rdev);
+}
+
+/**
+ * radeon_driver_irq_postinstall_kms - drm irq preinstall callback
+ *
+ * @dev: drm dev pointer
+ *
+ * Handles stuff to be done after enabling irqs (all asics).
+ * Returns 0 on success.
+ */
+int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
+{
+ dev->max_vblank_count = 0x001fffff;
+ return 0;
+}
+
+/**
+ * radeon_driver_irq_uninstall_kms - drm irq uninstall callback
+ *
+ * @dev: drm dev pointer
+ *
+ * This function disables all interrupt sources on the GPU (all asics).
+ */
+void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ unsigned long irqflags;
+ unsigned i;
+
+ if (rdev == NULL) {
+ return;
+ }
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ /* Disable *all* interrupts */
+ for (i = 0; i < RADEON_NUM_RINGS; i++)
+ atomic_set(&rdev->irq.ring_int[i], 0);
+ 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;
+ atomic_set(&rdev->irq.pflip[i], 0);
+ rdev->irq.afmt[i] = false;
+ }
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+}
+
+/**
+ * radeon_msi_ok - asic specific msi checks
+ *
+ * @rdev: radeon device pointer
+ *
+ * Handles asic specific MSI checks to determine if
+ * MSIs should be enabled on a particular chip (all asics).
+ * Returns true if MSIs should be enabled, false if MSIs
+ * should not be enabled.
+ */
+int radeon_msi_ok(struct drm_device *dev, unsigned long flags)
+{
+ int family;
+
+ family = flags & RADEON_FAMILY_MASK;
+
+ /* RV370/RV380 was first asic with MSI support */
+ if (family < CHIP_RV380)
+ return false;
+
+ /* MSIs don't work on AGP */
+ if (drm_device_is_agp(dev))
+ 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 ((dev->pci_device == 0x791f) &&
+ (dev->pci_subvendor == 0x103c) &&
+ (dev->pci_subdevice == 0x30c2))
+ return true;
+
+ /* Dell RS690 only seems to work with MSIs. */
+ if ((dev->pci_device == 0x791f) &&
+ (dev->pci_subvendor == 0x1028) &&
+ (dev->pci_subdevice == 0x01fc))
+ return true;
+
+ /* Dell RS690 only seems to work with MSIs. */
+ if ((dev->pci_device == 0x791f) &&
+ (dev->pci_subvendor == 0x1028) &&
+ (dev->pci_subdevice == 0x01fd))
+ return true;
+
+ /* Gateway RS690 only seems to work with MSIs. */
+ if ((dev->pci_device == 0x791f) &&
+ (dev->pci_subvendor == 0x107b) &&
+ (dev->pci_subdevice == 0x0185))
+ return true;
+
+ /* try and enable MSIs by default on all RS690s */
+ if (family == CHIP_RS690)
+ 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 (family == CHIP_RV515)
+ return false;
+ if (flags & RADEON_IS_IGP) {
+ /* APUs work fine with MSIs */
+ if (family >= CHIP_PALM)
+ return true;
+ /* lots of IGPs have problems with MSIs */
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * radeon_irq_kms_init - init driver interrupt info
+ *
+ * @rdev: radeon device pointer
+ *
+ * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics).
+ * Returns 0 for success, error for failure.
+ */
+int radeon_irq_kms_init(struct radeon_device *rdev)
+{
+ int r = 0;
+
+ TASK_INIT(&rdev->hotplug_work, 0, radeon_hotplug_work_func, rdev);
+ TASK_INIT(&rdev->audio_work, 0, r600_audio_update_hdmi, rdev);
+
+ DRM_SPININIT(&rdev->irq.lock, "drm__radeon_device__irq__lock");
+ r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
+ if (r) {
+ return r;
+ }
+ /* enable msi */
+ rdev->msi_enabled = rdev->ddev->msi_enabled;
+
+ rdev->irq.installed = true;
+ DRM_UNLOCK(rdev->ddev);
+ r = drm_irq_install(rdev->ddev);
+ DRM_LOCK(rdev->ddev);
+ if (r) {
+ rdev->irq.installed = false;
+ return r;
+ }
+ DRM_INFO("radeon: irq initialized.\n");
+ return 0;
+}
+
+/**
+ * radeon_irq_kms_fini - tear down driver interrrupt info
+ *
+ * @rdev: radeon device pointer
+ *
+ * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics).
+ */
+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;
+ }
+ taskqueue_drain(rdev->tq, &rdev->hotplug_work);
+}
+
+/**
+ * radeon_irq_kms_sw_irq_get - enable software interrupt
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring whose interrupt you want to enable
+ *
+ * Enables the software interrupt for a specific ring (all asics).
+ * The software interrupt is generally used to signal a fence on
+ * a particular ring.
+ */
+void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring)
+{
+ unsigned long irqflags;
+
+ if (!rdev->ddev->irq_enabled)
+ return;
+
+ if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) {
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+ }
+}
+
+/**
+ * radeon_irq_kms_sw_irq_put - disable software interrupt
+ *
+ * @rdev: radeon device pointer
+ * @ring: ring whose interrupt you want to disable
+ *
+ * Disables the software interrupt for a specific ring (all asics).
+ * The software interrupt is generally used to signal a fence on
+ * a particular ring.
+ */
+void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring)
+{
+ unsigned long irqflags;
+
+ if (!rdev->ddev->irq_enabled)
+ return;
+
+ if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) {
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+ }
+}
+
+/**
+ * radeon_irq_kms_pflip_irq_get - enable pageflip interrupt
+ *
+ * @rdev: radeon device pointer
+ * @crtc: crtc whose interrupt you want to enable
+ *
+ * Enables the pageflip interrupt for a specific crtc (all asics).
+ * For pageflips we use the vblank interrupt source.
+ */
+void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc)
+{
+ unsigned long irqflags;
+
+ if (crtc < 0 || crtc >= rdev->num_crtc)
+ return;
+
+ if (!rdev->ddev->irq_enabled)
+ return;
+
+ if (atomic_inc_return(&rdev->irq.pflip[crtc]) == 1) {
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+ }
+}
+
+/**
+ * radeon_irq_kms_pflip_irq_put - disable pageflip interrupt
+ *
+ * @rdev: radeon device pointer
+ * @crtc: crtc whose interrupt you want to disable
+ *
+ * Disables the pageflip interrupt for a specific crtc (all asics).
+ * For pageflips we use the vblank interrupt source.
+ */
+void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc)
+{
+ unsigned long irqflags;
+
+ if (crtc < 0 || crtc >= rdev->num_crtc)
+ return;
+
+ if (!rdev->ddev->irq_enabled)
+ return;
+
+ if (atomic_dec_and_test(&rdev->irq.pflip[crtc])) {
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+ }
+}
+
+/**
+ * radeon_irq_kms_enable_afmt - enable audio format change interrupt
+ *
+ * @rdev: radeon device pointer
+ * @block: afmt block whose interrupt you want to enable
+ *
+ * Enables the afmt change interrupt for a specific afmt block (all asics).
+ */
+void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block)
+{
+ unsigned long irqflags;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ rdev->irq.afmt[block] = true;
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+
+}
+
+/**
+ * radeon_irq_kms_disable_afmt - disable audio format change interrupt
+ *
+ * @rdev: radeon device pointer
+ * @block: afmt block whose interrupt you want to disable
+ *
+ * Disables the afmt change interrupt for a specific afmt block (all asics).
+ */
+void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block)
+{
+ unsigned long irqflags;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ rdev->irq.afmt[block] = false;
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+}
+
+/**
+ * radeon_irq_kms_enable_hpd - enable hotplug detect interrupt
+ *
+ * @rdev: radeon device pointer
+ * @hpd_mask: mask of hpd pins you want to enable.
+ *
+ * Enables the hotplug detect interrupt for a specific hpd pin (all asics).
+ */
+void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
+{
+ unsigned long irqflags;
+ int i;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
+ rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i));
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+}
+
+/**
+ * radeon_irq_kms_disable_hpd - disable hotplug detect interrupt
+ *
+ * @rdev: radeon device pointer
+ * @hpd_mask: mask of hpd pins you want to disable.
+ *
+ * Disables the hotplug detect interrupt for a specific hpd pin (all asics).
+ */
+void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
+{
+ unsigned long irqflags;
+ int i;
+
+ DRM_SPINLOCK_IRQSAVE(&rdev->irq.lock, irqflags);
+ for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
+ rdev->irq.hpd[i] &= !(hpd_mask & (1 << i));
+ radeon_irq_set(rdev);
+ DRM_SPINUNLOCK_IRQRESTORE(&rdev->irq.lock, irqflags);
+}
+
diff --git a/sys/dev/drm2/radeon/radeon_irq_kms.h b/sys/dev/drm2/radeon/radeon_irq_kms.h
new file mode 100644
index 0000000..6bfb988
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_irq_kms.h
@@ -0,0 +1,15 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_IRQ_KMS_H__
+#define __RADEON_IRQ_KMS_H__
+
+irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS);
+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);
+
+int radeon_msi_ok(struct drm_device *dev, unsigned long flags);
+
+#endif /* !defined(__RADEON_IRQ_KMS_H__) */
diff --git a/sys/dev/drm2/radeon/radeon_kms.c b/sys/dev/drm2/radeon/radeon_kms.c
new file mode 100644
index 0000000..8507d01
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_kms.c
@@ -0,0 +1,727 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_asic.h"
+#include "radeon_kms.h"
+
+/**
+ * radeon_driver_unload_kms - Main unload function for KMS.
+ *
+ * @dev: drm dev pointer
+ *
+ * This is the main unload function for KMS (all asics).
+ * It calls radeon_modeset_fini() to tear down the
+ * displays, and radeon_device_fini() to tear down
+ * the rest of the device (CP, writeback, etc.).
+ * Returns 0 on success.
+ */
+int radeon_driver_unload_kms(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev == NULL)
+ return 0;
+ radeon_acpi_fini(rdev);
+ radeon_modeset_fini(rdev);
+ radeon_device_fini(rdev);
+ free(rdev, DRM_MEM_DRIVER);
+ dev->dev_private = NULL;
+ return 0;
+}
+
+/**
+ * radeon_driver_load_kms - Main load function for KMS.
+ *
+ * @dev: drm dev pointer
+ * @flags: device flags
+ *
+ * This is the main load function for KMS (all asics).
+ * It calls radeon_device_init() to set up the non-display
+ * parts of the chip (asic init, CP, writeback, etc.), and
+ * radeon_modeset_init() to set up the display parts
+ * (crtcs, encoders, hotplug detect, etc.).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
+{
+ struct radeon_device *rdev;
+ int r, acpi_status;
+
+ rdev = malloc(sizeof(struct radeon_device), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (rdev == NULL) {
+ return -ENOMEM;
+ }
+ dev->dev_private = (void *)rdev;
+
+ /* update BUS flag */
+ if (drm_device_is_agp(dev)) {
+ DRM_INFO("RADEON_IS_AGP\n");
+ flags |= RADEON_IS_AGP;
+ } else if (drm_device_is_pcie(dev)) {
+ DRM_INFO("RADEON_IS_PCIE\n");
+ flags |= RADEON_IS_PCIE;
+ } else {
+ DRM_INFO("RADEON_IS_PCI\n");
+ 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, flags);
+ if (r) {
+ dev_err(dev->device, "Fatal error during GPU init\n");
+ goto out;
+ }
+
+ /* 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->device, "Fatal error during modeset init\n");
+
+ /* Call ACPI methods: require modeset init
+ * but failure is not fatal
+ */
+ if (!r) {
+ acpi_status = radeon_acpi_init(rdev);
+ if (acpi_status)
+ dev_dbg(dev->device,
+ "Error during ACPI methods call\n");
+ }
+
+out:
+ if (r)
+ radeon_driver_unload_kms(dev);
+ return r;
+}
+
+/**
+ * radeon_set_filp_rights - Set filp right.
+ *
+ * @dev: drm dev pointer
+ * @owner: drm file
+ * @applier: drm file
+ * @value: value
+ *
+ * Sets the filp rights for the device (all asics).
+ */
+static void radeon_set_filp_rights(struct drm_device *dev,
+ struct drm_file **owner,
+ struct drm_file *applier,
+ uint32_t *value)
+{
+ DRM_LOCK(dev);
+ 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;
+ DRM_UNLOCK(dev);
+}
+
+/*
+ * Userspace get information ioctl
+ */
+/**
+ * radeon_info_ioctl - answer a device specific request.
+ *
+ * @rdev: radeon device pointer
+ * @data: request object
+ * @filp: drm filp
+ *
+ * This function is used to pass device specific parameters to the userspace
+ * drivers. Examples include: pci device id, pipeline parms, tiling params,
+ * etc. (all asics).
+ * Returns 0 on success, -EINVAL on failure.
+ */
+static 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 = data;
+ struct radeon_mode_info *minfo = &rdev->mode_info;
+ uint32_t value, *value_ptr;
+ uint64_t value64, *value_ptr64;
+ struct drm_crtc *crtc;
+ int i, found;
+
+ /* TIMESTAMP is a 64-bit value, needs special handling. */
+ if (info->request == RADEON_INFO_TIMESTAMP) {
+ if (rdev->family >= CHIP_R600) {
+ value_ptr64 = (uint64_t*)((unsigned long)info->value);
+ if (rdev->family >= CHIP_TAHITI) {
+ value64 = si_get_gpu_clock(rdev);
+ } else {
+ value64 = r600_get_gpu_clock(rdev);
+ }
+
+ if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) {
+ DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+ } else {
+ DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
+ return -EINVAL;
+ }
+ }
+
+ value_ptr = (uint32_t *)((unsigned long)info->value);
+ if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) {
+ DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
+ 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_cu_per_sh;
+ 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;
+ case RADEON_INFO_MAX_SE:
+ if (rdev->family >= CHIP_TAHITI)
+ value = rdev->config.si.max_shader_engines;
+ else if (rdev->family >= CHIP_CAYMAN)
+ value = rdev->config.cayman.max_shader_engines;
+ else if (rdev->family >= CHIP_CEDAR)
+ value = rdev->config.evergreen.num_ses;
+ else
+ value = 1;
+ break;
+ case RADEON_INFO_MAX_SH_PER_SE:
+ if (rdev->family >= CHIP_TAHITI)
+ value = rdev->config.si.max_sh_per_se;
+ 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 %s:%u\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+}
+
+
+/*
+ * Outdated mess for old drm with Xorg being in charge (void function now).
+ */
+/**
+ * radeon_driver_firstopen_kms - drm callback for first open
+ *
+ * @dev: drm dev pointer
+ *
+ * Nothing to be done for KMS (all asics).
+ * Returns 0 on success.
+ */
+int radeon_driver_firstopen_kms(struct drm_device *dev)
+{
+ return 0;
+}
+
+/**
+ * radeon_driver_firstopen_kms - drm callback for last close
+ *
+ * @dev: drm dev pointer
+ *
+ * Switch vga switcheroo state after last close (all asics).
+ */
+void radeon_driver_lastclose_kms(struct drm_device *dev)
+{
+#ifdef DUMBBELL_WIP
+ vga_switcheroo_process_delayed_switch();
+#endif /* DUMBBELL_WIP */
+}
+
+/**
+ * radeon_driver_open_kms - drm callback for open
+ *
+ * @dev: drm dev pointer
+ * @file_priv: drm file
+ *
+ * On device open, init vm on cayman+ (all asics).
+ * Returns 0 on success, error on failure.
+ */
+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;
+ struct radeon_bo_va *bo_va;
+ int r;
+
+ fpriv = malloc(sizeof(*fpriv), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (unlikely(!fpriv)) {
+ return -ENOMEM;
+ }
+
+ radeon_vm_init(rdev, &fpriv->vm);
+
+ /* map the ib pool buffer read only into
+ * virtual address space */
+ bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
+ rdev->ring_tmp_bo.bo);
+ r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
+ RADEON_VM_PAGE_READABLE |
+ RADEON_VM_PAGE_SNOOPED);
+ if (r) {
+ radeon_vm_fini(rdev, &fpriv->vm);
+ free(fpriv, DRM_MEM_DRIVER);
+ return r;
+ }
+
+ file_priv->driver_priv = fpriv;
+ }
+ return 0;
+}
+
+/**
+ * radeon_driver_postclose_kms - drm callback for post close
+ *
+ * @dev: drm dev pointer
+ * @file_priv: drm file
+ *
+ * On device post close, tear down vm on cayman+ (all asics).
+ */
+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;
+ struct radeon_bo_va *bo_va;
+ int r;
+
+ r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
+ if (!r) {
+ bo_va = radeon_vm_bo_find(&fpriv->vm,
+ rdev->ring_tmp_bo.bo);
+ if (bo_va)
+ radeon_vm_bo_rmv(rdev, bo_va);
+ radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
+ }
+
+ radeon_vm_fini(rdev, &fpriv->vm);
+ free(fpriv, DRM_MEM_DRIVER);
+ file_priv->driver_priv = NULL;
+ }
+}
+
+/**
+ * radeon_driver_preclose_kms - drm callback for pre close
+ *
+ * @dev: drm dev pointer
+ * @file_priv: drm file
+ *
+ * On device pre close, tear down hyperz and cmask filps on r1xx-r5xx
+ * (all asics).
+ */
+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.
+ */
+/**
+ * radeon_get_vblank_counter_kms - get frame count
+ *
+ * @dev: drm dev pointer
+ * @crtc: crtc to get the frame count from
+ *
+ * Gets the frame count on the requested crtc (all asics).
+ * Returns frame count on success, -EINVAL on failure.
+ */
+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);
+}
+
+/**
+ * radeon_enable_vblank_kms - enable vblank interrupt
+ *
+ * @dev: drm dev pointer
+ * @crtc: crtc to enable vblank interrupt for
+ *
+ * Enable the interrupt on the requested crtc (all asics).
+ * Returns 0 on success, -EINVAL on failure.
+ */
+int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ int r;
+
+ if (crtc < 0 || crtc >= rdev->num_crtc) {
+ DRM_ERROR("Invalid crtc %d\n", crtc);
+ return -EINVAL;
+ }
+
+ mtx_lock(&rdev->irq.lock);
+ rdev->irq.crtc_vblank_int[crtc] = true;
+ r = radeon_irq_set(rdev);
+ mtx_unlock(&rdev->irq.lock);
+ return r;
+}
+
+/**
+ * radeon_disable_vblank_kms - disable vblank interrupt
+ *
+ * @dev: drm dev pointer
+ * @crtc: crtc to disable vblank interrupt for
+ *
+ * Disable the interrupt on the requested crtc (all asics).
+ */
+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;
+ }
+
+ mtx_lock(&rdev->irq.lock);
+ rdev->irq.crtc_vblank_int[crtc] = false;
+ radeon_irq_set(rdev);
+ mtx_unlock(&rdev->irq.lock);
+}
+
+/**
+ * radeon_get_vblank_timestamp_kms - get vblank timestamp
+ *
+ * @dev: drm dev pointer
+ * @crtc: crtc to get the timestamp for
+ * @max_error: max error
+ * @vblank_time: time value
+ * @flags: flags passed to the driver
+ *
+ * Gets the timestamp on the requested crtc based on the
+ * scanout position. (all asics).
+ * Returns postive status flags on success, negative error on failure.
+ */
+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) \
+static 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/sys/dev/drm2/radeon/radeon_kms.h b/sys/dev/drm2/radeon/radeon_kms.h
new file mode 100644
index 0000000..ff3bbbc
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_kms.h
@@ -0,0 +1,30 @@
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_KMS_H__
+#define __RADEON_KMS_H__
+
+#include <dev/drm2/drmP.h>
+
+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);
+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);
+int radeon_dma_ioctl_kms(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+#endif /* !defined(__RADEON_KMS_H__) */
diff --git a/sys/dev/drm2/radeon/radeon_legacy_crtc.c b/sys/dev/drm2/radeon/radeon_legacy_crtc.c
new file mode 100644
index 0000000..54f755a
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_legacy_crtc.c
@@ -0,0 +1,1085 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include <dev/drm2/drm_fixed.h>
+#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);
+}
+
+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;
+}
+
+static 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 crtc_ext_cntl = 0;
+ 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);
+
+ /*
+ * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC.
+ * Therefore it is set in the DAC DMPS function.
+ * This is different for GPU's with a single CRTC but a primary and a
+ * TV DAC: here it controls the single CRTC no matter where it is
+ * routed. Therefore we set it here.
+ */
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ crtc_ext_cntl = RADEON_CRTC_CRT_ON;
+
+ 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, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
+ }
+ 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 | crtc_ext_cntl));
+ }
+ 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));
+
+ DRM_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);
+
+ DRM_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,
+ const 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 radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *crtci;
+
+ radeon_crtc->in_mode_set = true;
+ /*
+ * 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 radeon_crtc *radeon_crtc = to_radeon_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);
+ }
+ radeon_crtc->in_mode_set = false;
+}
+
+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/sys/dev/drm2/radeon/radeon_legacy_encoders.c b/sys/dev/drm2/radeon/radeon_legacy_encoders.c
new file mode 100644
index 0000000..4a1ae16
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_legacy_encoders.c
@@ -0,0 +1,1817 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+
+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);
+ DRM_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;
+ DRM_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);
+ }
+ DRM_MDELAY(panel_pwr_delay);
+ WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+ WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
+ DRM_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,
+ const 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,
+};
+
+u8
+radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder)
+{
+ struct drm_device *dev = radeon_encoder->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ u8 backlight_level;
+
+ backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >>
+ RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff;
+
+ return backlight_level;
+}
+
+void
+radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)
+{
+ 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;
+ if (lvds->backlight_level > 0)
+ dpms_mode = lvds->dpms_mode;
+ else
+ dpms_mode = DRM_MODE_DPMS_OFF;
+ lvds->backlight_level = level;
+ } else {
+ struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv;
+ if (lvds->backlight_level > 0)
+ dpms_mode = lvds->dpms_mode;
+ else
+ dpms_mode = DRM_MODE_DPMS_OFF;
+ lvds->backlight_level = level;
+ }
+ }
+
+ radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode);
+}
+
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+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 > RADEON_MAX_BL_LEVEL)
+ level = RADEON_MAX_BL_LEVEL;
+ else
+ level = bd->props.brightness;
+
+ if (pdata->negative)
+ level = RADEON_MAX_BL_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;
+
+ radeon_legacy_set_backlight_level(radeon_encoder,
+ radeon_legacy_lvds_level(bd));
+
+ 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 ? RADEON_MAX_BL_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;
+ char bl_name[16];
+
+ if (!radeon_encoder->enc_priv)
+ return;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (!pmac_has_backlight_type("ati") &&
+ !pmac_has_backlight_type("mnca"))
+ return;
+#endif
+
+ pdata = malloc(sizeof(struct radeon_backlight_privdata),
+ DRM_MEM_DRIVER, M_WAITOK);
+ if (!pdata) {
+ DRM_ERROR("Memory allocation failed\n");
+ goto error;
+ }
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = RADEON_MAX_BL_LEVEL;
+ props.type = BACKLIGHT_RAW;
+ snprintf(bl_name, sizeof(bl_name),
+ "radeon_bl%d", dev->primary->index);
+ bd = backlight_device_register(bl_name, &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:
+ free(pdata, DRM_MEM_DRIVER);
+ 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_backlight_privdata *pdata;
+
+ pdata = bl_get_data(bd);
+ backlight_device_unregister(bd);
+ free(pdata, DRM_MEM_DRIVER);
+
+ DRM_INFO("radeon legacy LVDS backlight unloaded\n");
+ }
+}
+
+#else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */
+
+void radeon_legacy_backlight_init(struct radeon_encoder *encoder,
+ struct drm_connector *drm_connector)
+{
+}
+
+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);
+ free(radeon_encoder->enc_priv, DRM_MEM_DRIVER);
+ }
+ drm_encoder_cleanup(encoder);
+ free(radeon_encoder, DRM_MEM_DRIVER);
+}
+
+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;
+ }
+
+ /* handled in radeon_crtc_dpms() */
+ if (!(rdev->flags & RADEON_SINGLE_CRTC))
+ 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;
+
+ /* just don't bother on RN50 those chip are often connected to remoting
+ * console hw and often we get failure to load detect those. So to make
+ * everyone happy report the encoder as always connected.
+ */
+ if (ASIC_IS_RN50(rdev)) {
+ return connector_status_connected;
+ }
+
+ /* 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 if (ASIC_IS_RV100(rdev))
+ tmp |= (0x1ac << 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 = dac_macro_cntl;
+ tmp &= ~(RADEON_DAC_PDWN_R |
+ RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+
+ WREG32(RADEON_DAC_MACRO_CNTL, tmp);
+
+ DRM_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->pci_device == 0x4850) &&
+ (dev->pci_subvendor == 0x1028) &&
+ (dev->pci_subdevice == 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);
+ /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */
+ free(radeon_encoder->enc_priv, DRM_MEM_DRIVER);
+ drm_encoder_cleanup(encoder);
+ free(radeon_encoder, DRM_MEM_DRIVER);
+}
+
+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);
+ /* handled in radeon_crtc_dpms() */
+ else if (!(rdev->flags & RADEON_SINGLE_CRTC))
+ 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);
+ DRM_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);
+ DRM_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);
+
+ DRM_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 bool radeon_legacy_ext_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 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+ uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+ uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+ uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+ uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+ bool found = false;
+ int i;
+
+ /* save the regs we need */
+ gpio_monid = RREG32(RADEON_GPIO_MONID);
+ fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+ disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
+ disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
+ disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
+ disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
+ disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
+ disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
+ crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
+ crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
+ crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
+ crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ tmp = RREG32(RADEON_GPIO_MONID);
+ tmp &= ~RADEON_GPIO_A_0;
+ WREG32(RADEON_GPIO_MONID, tmp);
+
+ WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
+ RADEON_FP2_PANEL_FORMAT |
+ R200_FP2_SOURCE_SEL_TRANS_UNIT |
+ RADEON_FP2_DVO_EN |
+ R200_FP2_DVO_RATE_SEL_SDR));
+
+ WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
+ RADEON_DISP_TRANS_MATRIX_GRAPHICS));
+
+ WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
+ RADEON_CRTC2_DISP_REQ_EN_B));
+
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ tmp = RREG32(RADEON_GPIO_MONID);
+ if (tmp & RADEON_GPIO_Y_0)
+ found = true;
+
+ if (found)
+ break;
+
+ DRM_MDELAY(1);
+ if (!drm_can_sleep())
+ DRM_MDELAY(1);
+ else
+ DRM_MSLEEP(1);
+ }
+
+ /* restore the regs we used */
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+ WREG32(RADEON_GPIO_MONID, gpio_monid);
+
+ 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 = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+ uint32_t gpiopad_a = 0, pixclks_cntl, tmp;
+ uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0;
+ 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;
+ }
+
+ /* R200 uses an external DAC for secondary DAC */
+ if (rdev->family == CHIP_R200) {
+ if (radeon_legacy_ext_dac_detect(encoder, connector))
+ found = connector_status_connected;
+ return found;
+ }
+
+ /* save the regs we need */
+ pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
+
+ if (rdev->flags & RADEON_SINGLE_CRTC) {
+ crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
+ } else {
+ if (ASIC_IS_R300(rdev)) {
+ gpiopad_a = RREG32(RADEON_GPIOPAD_A);
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+ } else {
+ disp_hw_debug = 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 (rdev->flags & RADEON_SINGLE_CRTC) {
+ tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+ WREG32(RADEON_CRTC_EXT_CNTL, tmp);
+ } else {
+ 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)) {
+ WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
+ 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);
+
+ DRM_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);
+
+ if (rdev->flags & RADEON_SINGLE_CRTC) {
+ WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+ } else {
+ 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 = malloc(sizeof(struct radeon_encoder_int_tmds),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ 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 = malloc(sizeof(struct radeon_encoder_ext_tmds),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+
+ 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 = malloc(sizeof(struct radeon_encoder),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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/sys/dev/drm2/radeon/radeon_legacy_tv.c b/sys/dev/drm2/radeon/radeon_legacy_tv.c
new file mode 100644
index 0000000..5311a48
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_legacy_tv.c
@@ -0,0 +1,926 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_crtc_helper.h>
+#include "radeon.h"
+
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi@lycos.com>
+ */
+
+
+/*
+ * 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 DRM_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 < DRM_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/sys/dev/drm2/radeon/radeon_mem.c b/sys/dev/drm2/radeon/radeon_mem.c
new file mode 100644
index 0000000..9ff8791
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_mem.c
@@ -0,0 +1,304 @@
+/* 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 <keith@tungstengraphics.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/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 = malloc(sizeof(*newblock),
+ DRM_MEM_DRIVER, M_WAITOK);
+ 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 = malloc(sizeof(*newblock),
+ DRM_MEM_DRIVER, M_WAITOK);
+ 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;
+ free(q, DRM_MEM_DRIVER);
+ }
+
+ if (p->prev->file_priv == NULL) {
+ struct mem_block *q = p->prev;
+ q->size += p->size;
+ q->next = p->next;
+ q->next->prev = q;
+ free(p, DRM_MEM_DRIVER);
+ }
+}
+
+/* Initialize. How to check for an uninitialized heap?
+ */
+static int init_heap(struct mem_block **heap, int start, int size)
+{
+ struct mem_block *blocks = malloc(sizeof(*blocks),
+ DRM_MEM_DRIVER, M_WAITOK);
+
+ if (!blocks)
+ return -ENOMEM;
+
+ *heap = malloc(sizeof(**heap), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (!*heap) {
+ free(blocks, DRM_MEM_DRIVER);
+ 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;
+ free(q, DRM_MEM_DRIVER);
+ }
+ }
+}
+
+/* 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;
+ free(q, DRM_MEM_DRIVER);
+ }
+
+ free(*heap, DRM_MEM_DRIVER);
+ *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/sys/dev/drm2/radeon/radeon_mode.h b/sys/dev/drm2/radeon/radeon_mode.h
new file mode 100644
index 0000000..ac39bc3
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_mode.h
@@ -0,0 +1,738 @@
+/*
+ * 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
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef RADEON_MODE_H
+#define RADEON_MODE_H
+
+#include <dev/drm2/drm_crtc.h>
+#include <dev/drm2/drm_edid.h>
+#include <dev/drm2/drm_dp_helper.h>
+#include <dev/drm2/drm_fixed.h>
+#include <dev/drm2/drm_crtc_helper.h>
+
+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 {
+ device_t adapter;
+ device_t iic_bus;
+ struct drm_device *dev;
+ struct radeon_i2c_bus_rec rec;
+ char name[48];
+};
+
+/* 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,
+ CT_SAM440EP,
+ CT_MAC_G4_SILVER
+};
+
+enum radeon_dvo_chip {
+ DVO_SIL164,
+ DVO_SIL1178,
+};
+
+struct radeon_fbdev;
+
+struct radeon_afmt {
+ bool enabled;
+ int offset;
+ bool last_buffer_filled_status;
+ int id;
+};
+
+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];
+ struct radeon_afmt *afmt[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;
+ /* firmware flags */
+ u16 firmware_flags;
+ /* pointer to backlight encoder */
+ struct radeon_encoder *bl_encoder;
+};
+
+#define RADEON_MAX_BL_LEVEL 0xFF
+
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+struct radeon_backlight_privdata {
+ struct radeon_encoder *encoder;
+ uint8_t negative;
+};
+
+#endif
+
+#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_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_crtc {
+ struct drm_crtc base;
+ int crtc_id;
+ u16 lut_r[256], lut_g[256], lut_b[256];
+ bool enabled;
+ bool can_tile;
+ bool in_mode_set;
+ 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;
+ /* pll sharing */
+ struct radeon_atom_ss ss;
+ bool ss_enabled;
+ u32 adjusted_clock;
+ int bpc;
+ u32 pll_reference_div;
+ u32 pll_post_div;
+ u32 pll_flags;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+};
+
+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_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_afmt *afmt;
+};
+
+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;
+ 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[DP_RECEIVER_CAP_SIZE];
+ 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 int radeon_get_monitor_bpc(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,
+ const 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(device_t dev, 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, bool use_aux);
+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,
+ const 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/sys/dev/drm2/radeon/radeon_object.c b/sys/dev/drm2/radeon/radeon_object.c
new file mode 100644
index 0000000..30d3d81
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_object.c
@@ -0,0 +1,651 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Dave Airlie
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+#ifdef DUMBBELL_WIP
+#include "radeon_trace.h"
+#endif /* DUMBBELL_WIP */
+
+
+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.
+ */
+
+static 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 */
+ radeon_vm_bo_rmv(bo->rdev, 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);
+ sx_xlock(&bo->rdev->gem.mutex);
+ list_del_init(&bo->list);
+ sx_xunlock(&bo->rdev->gem.mutex);
+ radeon_bo_clear_surface_reg(bo);
+ radeon_bo_clear_va(bo);
+ drm_gem_object_release(&bo->gem_base);
+ free(bo, DRM_MEM_DRIVER);
+}
+
+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) {
+ if (rbo->rdev->flags & RADEON_IS_AGP) {
+ rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT;
+ } else {
+ rbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT;
+ }
+ }
+ if (domain & RADEON_GEM_DOMAIN_CPU) {
+ if (rbo->rdev->flags & RADEON_IS_AGP) {
+ rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM;
+ } else {
+ rbo->placements[c++] = TTM_PL_FLAG_CACHED | 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 sg_table *sg, struct radeon_bo **bo_ptr)
+{
+ struct radeon_bo *bo;
+ enum ttm_bo_type type;
+ unsigned long page_align = roundup2(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
+ size_t acc_size;
+ int r;
+
+ size = roundup2(size, PAGE_SIZE);
+
+ if (kernel) {
+ type = ttm_bo_type_kernel;
+ } else if (sg) {
+ type = ttm_bo_type_sg;
+ } else {
+ type = ttm_bo_type_device;
+ }
+ *bo_ptr = NULL;
+
+ acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size,
+ sizeof(struct radeon_bo));
+
+ bo = malloc(sizeof(struct radeon_bo),
+ DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ if (bo == NULL)
+ return -ENOMEM;
+ r = drm_gem_object_init(rdev->ddev, &bo->gem_base, size);
+ if (unlikely(r)) {
+ free(bo, DRM_MEM_DRIVER);
+ 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 */
+ sx_slock(&rdev->pm.mclk_lock);
+ r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
+ &bo->placement, page_align, !kernel, NULL,
+ acc_size, sg, &radeon_ttm_bo_destroy);
+ sx_sunlock(&rdev->pm.mclk_lock);
+ if (unlikely(r != 0)) {
+ return r;
+ }
+ *bo_ptr = bo;
+
+#ifdef DUMBBELL_WIP
+ trace_radeon_bo_create(bo);
+#endif /* DUMBBELL_WIP */
+
+ 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);
+ sx_slock(&rdev->pm.mclk_lock);
+ ttm_bo_unref(&tbo);
+ sx_sunlock(&rdev->pm.mclk_lock);
+ 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;
+ if (max_offset < (radeon_bo_gpu_offset(bo) - domain_start)) {
+ DRM_ERROR("radeon_bo_pin_restricted: "
+ "max_offset(%ju) < "
+ "(radeon_bo_gpu_offset(%ju) - "
+ "domain_start(%ju)",
+ (uintmax_t)max_offset, (uintmax_t)radeon_bo_gpu_offset(bo),
+ (uintmax_t)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);
+ 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);
+ 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) {
+ 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));
+ sx_xlock(&bo->rdev->gem.mutex);
+ list_del_init(&bo->list);
+ sx_xunlock(&bo->rdev->gem.mutex);
+ /* this should unref the ttm bo */
+ drm_gem_object_unreference(&bo->gem_base);
+ }
+}
+
+int radeon_bo_init(struct radeon_device *rdev)
+{
+ /* Add an MTRR for the VRAM */
+ rdev->mc.vram_mtrr = drm_mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
+ DRM_MTRR_WC);
+ DRM_INFO("Detected VRAM RAM=%juM, BAR=%juM\n",
+ (uintmax_t)rdev->mc.mc_vram_size >> 20,
+ (uintmax_t)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);
+ 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;
+}
+
+#ifdef DUMBBELL_WIP
+int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
+ struct vm_area_struct *vma)
+{
+ return ttm_fbdev_mmap(vma, &bo->tbo);
+}
+#endif /* DUMBBELL_WIP */
+
+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;
+
+ KASSERT(radeon_bo_is_reserved(bo),
+ ("radeon_bo_get_surface_reg: radeon_bo is not 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)
+{
+ KASSERT(radeon_bo_is_reserved(bo),
+ ("radeon_bo_get_tiling_flags: radeon_bo is not 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)
+{
+ KASSERT((radeon_bo_is_reserved(bo) || force_drop),
+ ("radeon_bo_check_tiling: radeon_bo is not reserved && !force_drop"));
+
+ 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, 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;
+ mtx_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);
+ mtx_unlock(&bo->tbo.bdev->fence_lock);
+ ttm_bo_unreserve(&bo->tbo);
+ return r;
+}
+
+
+/**
+ * radeon_bo_reserve - reserve bo
+ * @bo: bo structure
+ * @no_intr: don't return -ERESTARTSYS on pending signal
+ *
+ * Returns:
+ * -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_intr)
+{
+ int r;
+
+ r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, 0);
+ if (unlikely(r != 0)) {
+ if (r != -ERESTARTSYS)
+ dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
+ return r;
+ }
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/radeon_object.h b/sys/dev/drm2/radeon/radeon_object.h
new file mode 100644
index 0000000..efb7149
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_object.h
@@ -0,0 +1,193 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef __RADEON_OBJECT_H__
+#define __RADEON_OBJECT_H__
+
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon.h"
+
+/*
+ * Undefine max_offset (defined in vm/vm_map.h), because it conflicts
+ * with an argument of the function radeon_bo_pin_restricted().
+ */
+#undef max_offset
+
+/**
+ * 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_intr);
+
+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 ttm_bo_is_reserved(&bo->tbo);
+}
+
+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 sg_table *sg,
+ 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);
+#ifdef DUMBBELL_WIP
+extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
+ struct vm_area_struct *vma);
+#endif /* DUMBBELL_WIP */
+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);
+
+/*
+ * sub allocation
+ */
+
+static inline uint64_t radeon_sa_bo_gpu_addr(struct radeon_sa_bo *sa_bo)
+{
+ return sa_bo->manager->gpu_addr + sa_bo->soffset;
+}
+
+static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
+{
+ return (char *)sa_bo->manager->cpu_ptr + sa_bo->soffset;
+}
+
+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, bool block);
+extern void radeon_sa_bo_free(struct radeon_device *rdev,
+ struct radeon_sa_bo **sa_bo,
+ struct radeon_fence *fence);
+#if defined(CONFIG_DEBUG_FS)
+extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+ struct seq_file *m);
+#endif
+
+
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_pm.c b/sys/dev/drm2/radeon/radeon_pm.c
new file mode 100644
index 0000000..47042db
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_pm.c
@@ -0,0 +1,918 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to 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 <zajec5@gmail.com>
+ * Alex Deucher <alexdeucher@gmail.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "avivod.h"
+#include "atom.h"
+
+#define RADEON_IDLE_LOOP_MS 100
+#define RADEON_RECLOCK_DELAY_MS 200
+#define RADEON_WAIT_VBLANK_TIMEOUT 200
+
+static const char *radeon_pm_state_type_name[5] = {
+ "",
+ "Powersave",
+ "Battery",
+ "Balanced",
+ "Performance",
+};
+
+#ifdef DUMBBELL_WIP
+static void radeon_dynpm_idle_work_handler(struct work_struct *work);
+#endif /* DUMBBELL_WIP */
+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);
+
+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;
+}
+
+void radeon_pm_acpi_event_handler(struct radeon_device *rdev)
+{
+ if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
+ if (rdev->pm.profile == PM_PROFILE_AUTO) {
+ sx_xlock(&rdev->pm.mutex);
+ radeon_pm_update_profile(rdev);
+ radeon_pm_set_clocks(rdev);
+ sx_xunlock(&rdev->pm.mutex);
+ }
+ }
+}
+
+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:
+#ifdef DUMBBELL_WIP
+ 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;
+ }
+#endif /* DUMBBELL_WIP */
+ 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;
+#ifdef DUMBBELL_WIP
+ wait_event_timeout(
+ rdev->irq.vblank_queue, rdev->pm.vblank_sync,
+ msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+#endif /* DUMBBELL_WIP */
+ }
+}
+
+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;
+
+ /* starting with BTC, there is one state that is used for both
+ * MH and SH. Difference is that we always use the high clock index for
+ * mclk.
+ */
+ if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
+ (rdev->family >= CHIP_BARTS) &&
+ rdev->pm.active_crtc_count &&
+ ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
+ (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
+ mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index].
+ clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].mclk;
+ else
+ 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, r;
+
+ /* 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;
+
+ DRM_LOCK(rdev->ddev);
+ sx_xlock(&rdev->pm.mclk_lock);
+ sx_xlock(&rdev->ring_lock);
+
+ /* wait for the rings to drain */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ struct radeon_ring *ring = &rdev->ring[i];
+ if (!ring->ready) {
+ continue;
+ }
+ r = radeon_fence_wait_empty_locked(rdev, i);
+ if (r) {
+ /* needs a GPU reset dont reset here */
+ sx_xunlock(&rdev->ring_lock);
+ sx_xunlock(&rdev->pm.mclk_lock);
+ DRM_UNLOCK(rdev->ddev);
+ return;
+ }
+ }
+
+ 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;
+
+ sx_xunlock(&rdev->ring_lock);
+ sx_xunlock(&rdev->pm.mclk_lock);
+ DRM_UNLOCK(rdev->ddev);
+}
+
+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\n",
+ j,
+ clock_info->sclk * 10);
+ else
+ DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d\n",
+ j,
+ clock_info->sclk * 10,
+ clock_info->mclk * 10,
+ clock_info->voltage.voltage);
+ }
+ }
+}
+
+#ifdef DUMBBELL_WIP
+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;
+
+ sx_xlock(&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:
+ sx_xunlock(&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) {
+ sx_xlock(&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;
+ sx_xunlock(&rdev->pm.mutex);
+ } else if (strncmp("profile", buf, strlen("profile")) == 0) {
+ sx_xlock(&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;
+ sx_xunlock(&rdev->pm.mutex);
+#ifdef DUMBBELL_WIP
+ cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
+#endif /* DUMBBELL_WIP */
+ } 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,
+};
+#endif /* DUMBBELL_WIP */
+
+static int radeon_hwmon_init(struct radeon_device *rdev)
+{
+ int err = 0;
+
+#ifdef DUMBBELL_WIP
+ rdev->pm.int_hwmon_dev = NULL;
+#endif /* DUMBBELL_WIP */
+
+ 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;
+#ifdef DUMBBELL_WIP
+ 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);
+ }
+#endif /* DUMBBELL_WIP */
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+static void radeon_hwmon_fini(struct radeon_device *rdev)
+{
+#ifdef DUMBBELL_WIP
+ 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);
+ }
+#endif /* DUMBBELL_WIP */
+}
+
+void radeon_pm_suspend(struct radeon_device *rdev)
+{
+ sx_xlock(&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;
+ }
+ sx_xunlock(&rdev->pm.mutex);
+
+#ifdef DUMBBELL_WIP
+ cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
+#endif /* DUMBBELL_WIP */
+}
+
+void radeon_pm_resume(struct radeon_device *rdev)
+{
+ /* set up the default clocks if the MC ucode is loaded */
+ if ((rdev->family >= CHIP_BARTS) &&
+ (rdev->family <= CHIP_CAYMAN) &&
+ 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 */
+ sx_xlock(&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;
+#ifdef DUMBBELL_WIP
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+#endif /* DUMBBELL_WIP */
+ }
+ sx_xunlock(&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 ((rdev->family >= CHIP_BARTS) &&
+ (rdev->family <= CHIP_CAYMAN) &&
+ 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;
+
+#ifdef DUMBBELL_WIP
+ INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
+#endif /* DUMBBELL_WIP */
+
+ if (rdev->pm.num_power_states > 1) {
+ /* where's the best place to put these? */
+#ifdef DUMBBELL_WIP
+ ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+#endif /* DUMBBELL_WIP */
+ if (ret)
+ DRM_ERROR("failed to create device file for power profile\n");
+#ifdef DUMBBELL_WIP
+ ret = device_create_file(rdev->dev, &dev_attr_power_method);
+#endif /* DUMBBELL_WIP */
+ if (ret)
+ DRM_ERROR("failed to create device file for power method\n");
+
+ 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) {
+ DRM_UNLOCK(rdev->ddev); /* Work around LOR. */
+ sx_xlock(&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);
+ }
+ sx_xunlock(&rdev->pm.mutex);
+ DRM_LOCK(rdev->ddev);
+
+#ifdef DUMBBELL_WIP
+ 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);
+#endif /* DUMBBELL_WIP */
+ }
+
+ if (rdev->pm.power_state) {
+ int i;
+ for (i = 0; i < rdev->pm.num_power_states; ++i) {
+ free(rdev->pm.power_state[i].clock_info, DRM_MEM_DRIVER);
+ }
+ free(rdev->pm.power_state, DRM_MEM_DRIVER);
+ rdev->pm.power_state = NULL;
+ rdev->pm.num_power_states = 0;
+ }
+
+ 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;
+
+ sx_xlock(&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) {
+#ifdef DUMBBELL_WIP
+ cancel_delayed_work(&rdev->pm.dynpm_idle_work);
+#endif /* DUMBBELL_WIP */
+
+ 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);
+
+#ifdef DUMBBELL_WIP
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+#endif /* DUMBBELL_WIP */
+ } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) {
+ rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
+#ifdef DUMBBELL_WIP
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+#endif /* DUMBBELL_WIP */
+ DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n");
+ }
+ } else { /* count == 0 */
+ if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) {
+#ifdef DUMBBELL_WIP
+ cancel_delayed_work(&rdev->pm.dynpm_idle_work);
+#endif /* DUMBBELL_WIP */
+
+ 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);
+ }
+ }
+ }
+ }
+
+ sx_xunlock(&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;
+}
+
+#ifdef DUMBBELL_WIP
+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);
+ sx_xlock(&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) {
+ struct radeon_ring *ring = &rdev->ring[i];
+
+ if (ring->ready) {
+ 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));
+ }
+ sx_xunlock(&rdev->pm.mutex);
+ ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+}
+#endif /* DUMBBELL_WIP */
+
+/*
+ * 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/sys/dev/drm2/radeon/radeon_prime.c b/sys/dev/drm2/radeon/radeon_prime.c
new file mode 100644
index 0000000..c0c7a54
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_prime.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2012 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 nouveau_prime.c
+ *
+ * Authors: Alex Deucher
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <drm/drmP.h>
+
+#include "radeon.h"
+#include <drm/radeon_drm.h>
+
+#include <linux/dma-buf.h>
+
+static struct sg_table *radeon_gem_map_dma_buf(struct dma_buf_attachment *attachment,
+ enum dma_data_direction dir)
+{
+ struct radeon_bo *bo = attachment->dmabuf->priv;
+ struct drm_device *dev = bo->rdev->ddev;
+ int npages = bo->tbo.num_pages;
+ struct sg_table *sg;
+ int nents;
+
+ mutex_lock(&dev->struct_mutex);
+ sg = drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages);
+ nents = dma_map_sg(attachment->dev, sg->sgl, sg->nents, dir);
+ mutex_unlock(&dev->struct_mutex);
+ return sg;
+}
+
+static void radeon_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
+ struct sg_table *sg, enum dma_data_direction dir)
+{
+ dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
+ sg_free_table(sg);
+ kfree(sg);
+}
+
+static void radeon_gem_dmabuf_release(struct dma_buf *dma_buf)
+{
+ struct radeon_bo *bo = dma_buf->priv;
+
+ if (bo->gem_base.export_dma_buf == dma_buf) {
+ DRM_ERROR("unreference dmabuf %p\n", &bo->gem_base);
+ bo->gem_base.export_dma_buf = NULL;
+ drm_gem_object_unreference_unlocked(&bo->gem_base);
+ }
+}
+
+static void *radeon_gem_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
+{
+ return NULL;
+}
+
+static void radeon_gem_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
+{
+
+}
+static void *radeon_gem_kmap(struct dma_buf *dma_buf, unsigned long page_num)
+{
+ return NULL;
+}
+
+static void radeon_gem_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
+{
+
+}
+
+static int radeon_gem_prime_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
+{
+ return -EINVAL;
+}
+
+static void *radeon_gem_prime_vmap(struct dma_buf *dma_buf)
+{
+ struct radeon_bo *bo = dma_buf->priv;
+ struct drm_device *dev = bo->rdev->ddev;
+ int ret;
+
+ mutex_lock(&dev->struct_mutex);
+ if (bo->vmapping_count) {
+ bo->vmapping_count++;
+ goto out_unlock;
+ }
+
+ ret = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages,
+ &bo->dma_buf_vmap);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ERR_PTR(ret);
+ }
+ bo->vmapping_count = 1;
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return bo->dma_buf_vmap.virtual;
+}
+
+static void radeon_gem_prime_vunmap(struct dma_buf *dma_buf, void *vaddr)
+{
+ struct radeon_bo *bo = dma_buf->priv;
+ struct drm_device *dev = bo->rdev->ddev;
+
+ mutex_lock(&dev->struct_mutex);
+ bo->vmapping_count--;
+ if (bo->vmapping_count == 0) {
+ ttm_bo_kunmap(&bo->dma_buf_vmap);
+ }
+ mutex_unlock(&dev->struct_mutex);
+}
+const static struct dma_buf_ops radeon_dmabuf_ops = {
+ .map_dma_buf = radeon_gem_map_dma_buf,
+ .unmap_dma_buf = radeon_gem_unmap_dma_buf,
+ .release = radeon_gem_dmabuf_release,
+ .kmap = radeon_gem_kmap,
+ .kmap_atomic = radeon_gem_kmap_atomic,
+ .kunmap = radeon_gem_kunmap,
+ .kunmap_atomic = radeon_gem_kunmap_atomic,
+ .mmap = radeon_gem_prime_mmap,
+ .vmap = radeon_gem_prime_vmap,
+ .vunmap = radeon_gem_prime_vunmap,
+};
+
+static int radeon_prime_create(struct drm_device *dev,
+ size_t size,
+ struct sg_table *sg,
+ struct radeon_bo **pbo)
+{
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_bo *bo;
+ int ret;
+
+ ret = radeon_bo_create(rdev, size, PAGE_SIZE, false,
+ RADEON_GEM_DOMAIN_GTT, sg, pbo);
+ if (ret)
+ return ret;
+ bo = *pbo;
+ bo->gem_base.driver_private = bo;
+
+ mutex_lock(&rdev->gem.mutex);
+ list_add_tail(&bo->list, &rdev->gem.objects);
+ mutex_unlock(&rdev->gem.mutex);
+
+ return 0;
+}
+
+struct dma_buf *radeon_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags)
+{
+ struct radeon_bo *bo = gem_to_radeon_bo(obj);
+ int ret = 0;
+
+ ret = radeon_bo_reserve(bo, false);
+ if (unlikely(ret != 0))
+ return ERR_PTR(ret);
+
+ /* pin buffer into GTT */
+ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL);
+ if (ret) {
+ radeon_bo_unreserve(bo);
+ return ERR_PTR(ret);
+ }
+ radeon_bo_unreserve(bo);
+ return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags);
+}
+
+struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev,
+ struct dma_buf *dma_buf)
+{
+ struct dma_buf_attachment *attach;
+ struct sg_table *sg;
+ struct radeon_bo *bo;
+ int ret;
+
+ if (dma_buf->ops == &radeon_dmabuf_ops) {
+ bo = dma_buf->priv;
+ if (bo->gem_base.dev == dev) {
+ drm_gem_object_reference(&bo->gem_base);
+ dma_buf_put(dma_buf);
+ return &bo->gem_base;
+ }
+ }
+
+ /* need to attach */
+ attach = dma_buf_attach(dma_buf, dev->dev);
+ if (IS_ERR(attach))
+ return ERR_CAST(attach);
+
+ sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sg)) {
+ ret = PTR_ERR(sg);
+ goto fail_detach;
+ }
+
+ ret = radeon_prime_create(dev, dma_buf->size, sg, &bo);
+ if (ret)
+ goto fail_unmap;
+
+ bo->gem_base.import_attach = attach;
+
+ return &bo->gem_base;
+
+fail_unmap:
+ dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
+fail_detach:
+ dma_buf_detach(dma_buf, attach);
+ return ERR_PTR(ret);
+}
diff --git a/sys/dev/drm2/radeon/radeon_reg.h b/sys/dev/drm2/radeon/radeon_reg.h
new file mode 100644
index 0000000..8697e0f
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_reg.h
@@ -0,0 +1,3713 @@
+/*
+ * 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 <martin@xfree86.org>
+ * Rickard E. Faith <faith@valinux.com>
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * 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! */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/radeon_ring.c b/sys/dev/drm2/radeon/radeon_ring.c
new file mode 100644
index 0000000..37d0ade
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_ring.c
@@ -0,0 +1,884 @@
+/*
+ * 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
+ * Christian König
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+#include "atom.h"
+
+#ifdef DUMBBELL_WIP
+/*
+ * IB
+ * IBs (Indirect Buffers) and areas of GPU accessible memory where
+ * commands are stored. You can put a pointer to the IB in the
+ * command ring and the hw will fetch the commands from the IB
+ * and execute them. Generally userspace acceleration drivers
+ * produce command buffers which are send to the kernel and
+ * put in IBs for execution by the requested ring.
+ */
+static int radeon_debugfs_sa_init(struct radeon_device *rdev);
+#endif /* DUMBBELL_WIP */
+
+/**
+ * radeon_ib_get - request an IB (Indirect Buffer)
+ *
+ * @rdev: radeon_device pointer
+ * @ring: ring index the IB is associated with
+ * @ib: IB object returned
+ * @size: requested IB size
+ *
+ * Request an IB (all asics). IBs are allocated using the
+ * suballocator.
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ib_get(struct radeon_device *rdev, int ring,
+ struct radeon_ib *ib, struct radeon_vm *vm,
+ unsigned size)
+{
+ int i, r;
+
+ r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true);
+ if (r) {
+ dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
+ return r;
+ }
+
+ r = radeon_semaphore_create(rdev, &ib->semaphore);
+ if (r) {
+ return r;
+ }
+
+ ib->ring = ring;
+ ib->fence = NULL;
+ ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo);
+ ib->vm = vm;
+ if (vm) {
+ /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
+ * space and soffset is the offset inside the pool bo
+ */
+ ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
+ } else {
+ ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
+ }
+ ib->is_const_ib = false;
+ for (i = 0; i < RADEON_NUM_RINGS; ++i)
+ ib->sync_to[i] = NULL;
+
+ return 0;
+}
+
+/**
+ * radeon_ib_free - free an IB (Indirect Buffer)
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to free
+ *
+ * Free an IB (all asics).
+ */
+void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+ radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
+ radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
+ radeon_fence_unref(&ib->fence);
+}
+
+/**
+ * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ * @const_ib: Const IB to schedule (SI only)
+ *
+ * Schedule an IB on the associated ring (all asics).
+ * Returns 0 on success, error on failure.
+ *
+ * On SI, there are two parallel engines fed from the primary ring,
+ * the CE (Constant Engine) and the DE (Drawing Engine). Since
+ * resource descriptors have moved to memory, the CE allows you to
+ * prime the caches while the DE is updating register state so that
+ * the resource descriptors will be already in cache when the draw is
+ * processed. To accomplish this, the userspace driver submits two
+ * IBs, one for the CE and one for the DE. If there is a CE IB (called
+ * a CONST_IB), it will be put on the ring prior to the DE IB. Prior
+ * to SI there was just a DE IB.
+ */
+int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
+ struct radeon_ib *const_ib)
+{
+ struct radeon_ring *ring = &rdev->ring[ib->ring];
+ bool need_sync = false;
+ int i, r = 0;
+
+ if (!ib->length_dw || !ring->ready) {
+ /* TODO: Nothings in the ib we should report. */
+ dev_err(rdev->dev, "couldn't schedule ib\n");
+ return -EINVAL;
+ }
+
+ /* 64 dwords should be enough for fence too */
+ r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8);
+ if (r) {
+ dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
+ return r;
+ }
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ struct radeon_fence *fence = ib->sync_to[i];
+ if (radeon_fence_need_sync(fence, ib->ring)) {
+ need_sync = true;
+ radeon_semaphore_sync_rings(rdev, ib->semaphore,
+ fence->ring, ib->ring);
+ radeon_fence_note_sync(fence, ib->ring);
+ }
+ }
+ /* immediately free semaphore when we don't need to sync */
+ if (!need_sync) {
+ radeon_semaphore_free(rdev, &ib->semaphore, NULL);
+ }
+ /* if we can't remember our last VM flush then flush now! */
+ if (ib->vm && !ib->vm->last_flush) {
+ radeon_ring_vm_flush(rdev, ib->ring, ib->vm);
+ }
+ if (const_ib) {
+ radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
+ radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
+ }
+ radeon_ring_ib_execute(rdev, ib->ring, ib);
+ r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
+ if (r) {
+ dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r);
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+ if (const_ib) {
+ const_ib->fence = radeon_fence_ref(ib->fence);
+ }
+ /* we just flushed the VM, remember that */
+ if (ib->vm && !ib->vm->last_flush) {
+ ib->vm->last_flush = radeon_fence_ref(ib->fence);
+ }
+ radeon_ring_unlock_commit(rdev, ring);
+ return 0;
+}
+
+/**
+ * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the suballocator to manage a pool of memory
+ * for use as IBs (all asics).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ib_pool_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->ib_pool_ready) {
+ return 0;
+ }
+ r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
+ RADEON_IB_POOL_SIZE*64*1024,
+ RADEON_GEM_DOMAIN_GTT);
+ if (r) {
+ return r;
+ }
+
+ r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo);
+ if (r) {
+ return r;
+ }
+
+ rdev->ib_pool_ready = true;
+#ifdef DUMBBELL_WIP
+ if (radeon_debugfs_sa_init(rdev)) {
+ dev_err(rdev->dev, "failed to register debugfs file for SA\n");
+ }
+#endif /* DUMBBELL_WIP */
+ return 0;
+}
+
+/**
+ * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the suballocator managing the pool of memory
+ * for use as IBs (all asics).
+ */
+void radeon_ib_pool_fini(struct radeon_device *rdev)
+{
+ if (rdev->ib_pool_ready) {
+ radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo);
+ radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo);
+ rdev->ib_pool_ready = false;
+ }
+}
+
+/**
+ * radeon_ib_ring_tests - test IBs on the rings
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Test an IB (Indirect Buffer) on each ring.
+ * If the test fails, disable the ring.
+ * Returns 0 on success, error if the primary GFX ring
+ * IB test fails.
+ */
+int radeon_ib_ring_tests(struct radeon_device *rdev)
+{
+ unsigned i;
+ int r;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ struct radeon_ring *ring = &rdev->ring[i];
+
+ if (!ring->ready)
+ continue;
+
+ r = radeon_ib_test(rdev, i, ring);
+ if (r) {
+ ring->ready = false;
+
+ if (i == RADEON_RING_TYPE_GFX_INDEX) {
+ /* oh, oh, that's really bad */
+ DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r);
+ rdev->accel_working = false;
+ return r;
+
+ } else {
+ /* still not good, but we can live with it */
+ DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r);
+ }
+ }
+ }
+ return 0;
+}
+
+#ifdef DUMBBELL_WIP
+/*
+ * Rings
+ * Most engines on the GPU are fed via ring buffers. Ring
+ * buffers are areas of GPU accessible memory that the host
+ * writes commands into and the GPU reads commands out of.
+ * There is a rptr (read pointer) that determines where the
+ * GPU is currently reading, and a wptr (write pointer)
+ * which determines where the host has written. When the
+ * pointers are equal, the ring is idle. When the host
+ * writes commands to the ring buffer, it increments the
+ * wptr. The GPU then starts fetching commands and executes
+ * them until the pointers are equal again.
+ */
+static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring);
+#endif /* DUMBBELL_WIP */
+
+#if defined(DRM_DEBUG_CODE) && DRM_DEBUG_CODE != 0
+/**
+ * radeon_ring_write - write a value to the ring
+ *
+ * @ring: radeon_ring structure holding ring information
+ * @v: dword (dw) value to write
+ *
+ * Write a value to the requested ring buffer (all asics).
+ */
+void radeon_ring_write(struct radeon_ring *ring, uint32_t v)
+{
+#if DRM_DEBUG_CODE
+ if (ring->count_dw <= 0) {
+ DRM_ERROR("radeon: writing more dwords to the ring than expected!\n");
+ }
+#endif
+ ring->ring[ring->wptr++] = v;
+ ring->wptr &= ring->ptr_mask;
+ ring->count_dw--;
+ ring->ring_free_dw--;
+}
+#endif
+
+/**
+ * radeon_ring_supports_scratch_reg - check if the ring supports
+ * writing to scratch registers
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Check if a specific ring supports writing to scratch registers (all asics).
+ * Returns true if the ring supports writing to scratch regs, false if not.
+ */
+bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
+ struct radeon_ring *ring)
+{
+ switch (ring->idx) {
+ case RADEON_RING_TYPE_GFX_INDEX:
+ case CAYMAN_RING_TYPE_CP1_INDEX:
+ case CAYMAN_RING_TYPE_CP2_INDEX:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * radeon_ring_free_size - update the free size
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Update the free dw slots in the ring buffer (all asics).
+ */
+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;
+ }
+}
+
+/**
+ * radeon_ring_alloc - allocate space on the ring buffer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ * @ndw: number of dwords to allocate in the ring buffer
+ *
+ * Allocate @ndw dwords in the ring buffer (all asics).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
+{
+ int r;
+
+ /* make sure we aren't trying to allocate more space than there is on the ring */
+ if (ndw > (ring->ring_size / 4))
+ return -ENOMEM;
+ /* 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_locked(rdev, ring->idx);
+ if (r)
+ return r;
+ }
+ ring->count_dw = ndw;
+ ring->wptr_old = ring->wptr;
+ return 0;
+}
+
+/**
+ * radeon_ring_lock - lock the ring and allocate space on it
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ * @ndw: number of dwords to allocate in the ring buffer
+ *
+ * Lock the ring and allocate @ndw dwords in the ring buffer
+ * (all asics).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw)
+{
+ int r;
+
+ sx_xlock(&rdev->ring_lock);
+ r = radeon_ring_alloc(rdev, ring, ndw);
+ if (r) {
+ sx_xunlock(&rdev->ring_lock);
+ return r;
+ }
+ return 0;
+}
+
+/**
+ * radeon_ring_commit - tell the GPU to execute the new
+ * commands on the ring buffer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Update the wptr (write pointer) to tell the GPU to
+ * execute new commands on the ring buffer (all asics).
+ */
+void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ /* We pad to match fetch size */
+ while (ring->wptr & ring->align_mask) {
+ 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);
+}
+
+/**
+ * radeon_ring_unlock_commit - tell the GPU to execute the new
+ * commands on the ring buffer and unlock it
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Call radeon_ring_commit() then unlock the ring (all asics).
+ */
+void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ radeon_ring_commit(rdev, ring);
+ sx_xunlock(&rdev->ring_lock);
+}
+
+/**
+ * radeon_ring_undo - reset the wptr
+ *
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Reset the driver's copy of the wptr (all asics).
+ */
+void radeon_ring_undo(struct radeon_ring *ring)
+{
+ ring->wptr = ring->wptr_old;
+}
+
+/**
+ * radeon_ring_unlock_undo - reset the wptr and unlock the ring
+ *
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Call radeon_ring_undo() then unlock the ring (all asics).
+ */
+void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ radeon_ring_undo(ring);
+ sx_xunlock(&rdev->ring_lock);
+}
+
+/**
+ * radeon_ring_force_activity - add some nop packets to the ring
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Add some nop packets to the ring to force activity (all asics).
+ * Used for lockup detection to see if the rptr is advancing.
+ */
+void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ int r;
+
+ radeon_ring_free_size(rdev, ring);
+ if (ring->rptr == ring->wptr) {
+ r = radeon_ring_alloc(rdev, ring, 1);
+ if (!r) {
+ radeon_ring_write(ring, ring->nop);
+ radeon_ring_commit(rdev, ring);
+ }
+ }
+}
+
+/**
+ * radeon_ring_lockup_update - update lockup variables
+ *
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Update the last rptr value and timestamp (all asics).
+ */
+void radeon_ring_lockup_update(struct radeon_ring *ring)
+{
+ ring->last_rptr = ring->rptr;
+ ring->last_activity = jiffies;
+}
+
+/**
+ * radeon_ring_test_lockup() - check if ring is lockedup by recording information
+ * @rdev: radeon device structure
+ * @ring: radeon_ring structure holding ring 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
+ * radeon_ring_test_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 radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ unsigned long cjiffies, elapsed;
+ uint32_t rptr;
+
+ cjiffies = jiffies;
+ if (!time_after(cjiffies, ring->last_activity)) {
+ /* likely a wrap around */
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ rptr = RREG32(ring->rptr_reg);
+ ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+ if (ring->rptr != ring->last_rptr) {
+ /* CP is still working no lockup */
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
+ if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
+ dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed);
+ return true;
+ }
+ /* give a chance to the GPU ... */
+ return false;
+}
+
+/**
+ * radeon_ring_backup - Back up the content of a ring
+ *
+ * @rdev: radeon_device pointer
+ * @ring: the ring we want to back up
+ *
+ * Saves all unprocessed commits from a ring, returns the number of dwords saved.
+ */
+unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring,
+ uint32_t **data)
+{
+ unsigned size, ptr, i;
+
+ /* just in case lock the ring */
+ sx_xlock(&rdev->ring_lock);
+ *data = NULL;
+
+ if (ring->ring_obj == NULL) {
+ sx_xunlock(&rdev->ring_lock);
+ return 0;
+ }
+
+ /* it doesn't make sense to save anything if all fences are signaled */
+ if (!radeon_fence_count_emitted(rdev, ring->idx)) {
+ sx_xunlock(&rdev->ring_lock);
+ return 0;
+ }
+
+ /* calculate the number of dw on the ring */
+ if (ring->rptr_save_reg)
+ ptr = RREG32(ring->rptr_save_reg);
+ else if (rdev->wb.enabled)
+ ptr = le32_to_cpu(*ring->next_rptr_cpu_addr);
+ else {
+ /* no way to read back the next rptr */
+ sx_xunlock(&rdev->ring_lock);
+ return 0;
+ }
+
+ size = ring->wptr + (ring->ring_size / 4);
+ size -= ptr;
+ size &= ring->ptr_mask;
+ if (size == 0) {
+ sx_xunlock(&rdev->ring_lock);
+ return 0;
+ }
+
+ /* and then save the content of the ring */
+ *data = malloc(size * sizeof(uint32_t), DRM_MEM_DRIVER, M_WAITOK);
+ if (!*data) {
+ sx_xunlock(&rdev->ring_lock);
+ return 0;
+ }
+ for (i = 0; i < size; ++i) {
+ (*data)[i] = ring->ring[ptr++];
+ ptr &= ring->ptr_mask;
+ }
+
+ sx_xunlock(&rdev->ring_lock);
+ return size;
+}
+
+/**
+ * radeon_ring_restore - append saved commands to the ring again
+ *
+ * @rdev: radeon_device pointer
+ * @ring: ring to append commands to
+ * @size: number of dwords we want to write
+ * @data: saved commands
+ *
+ * Allocates space on the ring and restore the previously saved commands.
+ */
+int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
+ unsigned size, uint32_t *data)
+{
+ int i, r;
+
+ if (!size || !data)
+ return 0;
+
+ /* restore the saved ring content */
+ r = radeon_ring_lock(rdev, ring, size);
+ if (r)
+ return r;
+
+ for (i = 0; i < size; ++i) {
+ radeon_ring_write(ring, data[i]);
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ free(data, DRM_MEM_DRIVER);
+ return 0;
+}
+
+/**
+ * radeon_ring_init - init driver ring struct.
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ * @ring_size: size of the ring
+ * @rptr_offs: offset of the rptr writeback location in the WB buffer
+ * @rptr_reg: MMIO offset of the rptr register
+ * @wptr_reg: MMIO offset of the wptr register
+ * @ptr_reg_shift: bit offset of the rptr/wptr values
+ * @ptr_reg_mask: bit mask of the rptr/wptr values
+ * @nop: nop packet for this ring
+ *
+ * Initialize the driver information for the selected ring (all asics).
+ * Returns 0 on success, error on failure.
+ */
+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;
+ void *ring_ptr;
+
+ 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,
+ NULL, &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)) {
+ radeon_bo_unref(&ring->ring_obj);
+ return r;
+ }
+ r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT,
+ &ring->gpu_addr);
+ if (r) {
+ radeon_bo_unreserve(ring->ring_obj);
+ radeon_bo_unref(&ring->ring_obj);
+ dev_err(rdev->dev, "(%d) ring pin failed\n", r);
+ return r;
+ }
+ ring_ptr = &ring->ring;
+ r = radeon_bo_kmap(ring->ring_obj,
+ ring_ptr);
+ radeon_bo_unreserve(ring->ring_obj);
+ if (r) {
+ dev_err(rdev->dev, "(%d) ring map failed\n", r);
+ radeon_bo_unref(&ring->ring_obj);
+ return r;
+ }
+ }
+ ring->ptr_mask = (ring->ring_size / 4) - 1;
+ ring->ring_free_dw = ring->ring_size / 4;
+ if (rdev->wb.enabled) {
+ u32 index = RADEON_WB_RING0_NEXT_RPTR + (ring->idx * 4);
+ ring->next_rptr_gpu_addr = rdev->wb.gpu_addr + index;
+ ring->next_rptr_cpu_addr = &rdev->wb.wb[index/4];
+ }
+#ifdef DUMBBELL_WIP
+ if (radeon_debugfs_ring_init(rdev, ring)) {
+ DRM_ERROR("Failed to register debugfs file for rings !\n");
+ }
+#endif /* DUMBBELL_WIP */
+ radeon_ring_lockup_update(ring);
+ return 0;
+}
+
+/**
+ * radeon_ring_fini - tear down the driver ring struct.
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Tear down the driver information for the selected ring (all asics).
+ */
+void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ int r;
+ struct radeon_bo *ring_obj;
+
+ sx_xlock(&rdev->ring_lock);
+ ring_obj = ring->ring_obj;
+ ring->ready = false;
+ ring->ring = NULL;
+ ring->ring_obj = NULL;
+ sx_xunlock(&rdev->ring_lock);
+
+ 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;
+ u32 tmp;
+
+ radeon_ring_free_size(rdev, ring);
+ count = (ring->ring_size / 4) - ring->ring_free_dw;
+ tmp = RREG32(ring->wptr_reg) >> ring->ptr_reg_shift;
+ seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp);
+ tmp = RREG32(ring->rptr_reg) >> ring->ptr_reg_shift;
+ seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp);
+ if (ring->rptr_save_reg) {
+ seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg,
+ RREG32(ring->rptr_save_reg));
+ }
+ seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr);
+ seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n", ring->rptr, ring->rptr);
+ seq_printf(m, "last semaphore signal addr : 0x%016llx\n", ring->last_semaphore_signal_addr);
+ seq_printf(m, "last semaphore wait addr : 0x%016llx\n", ring->last_semaphore_wait_addr);
+ seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
+ seq_printf(m, "%u dwords in ring\n", count);
+ /* print 8 dw before current rptr as often it's the last executed
+ * packet that is the root issue
+ */
+ i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask;
+ for (j = 0; j <= (count + 32); j++) {
+ seq_printf(m, "r[%5d]=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 int radeon_ring_type_dma1_index = R600_RING_TYPE_DMA_INDEX;
+static int radeon_ring_type_dma2_index = CAYMAN_RING_TYPE_DMA1_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},
+ {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma1_index},
+ {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma2_index},
+};
+
+static int radeon_debugfs_sa_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;
+
+ radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m);
+
+ return 0;
+
+}
+
+static struct drm_info_list radeon_debugfs_sa_list[] = {
+ {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
+};
+
+#endif
+
+#ifdef DUMBBELL_WIP
+static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+#if defined(CONFIG_DEBUG_FS)
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(radeon_debugfs_ring_info_list); ++i) {
+ struct drm_info_list *info = &radeon_debugfs_ring_info_list[i];
+ int ridx = *(int*)radeon_debugfs_ring_info_list[i].data;
+ unsigned r;
+
+ if (&rdev->ring[ridx] != ring)
+ continue;
+
+ r = radeon_debugfs_add_files(rdev, info, 1);
+ if (r)
+ return r;
+ }
+#endif
+ return 0;
+}
+
+static int radeon_debugfs_sa_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+ return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
+#else
+ return 0;
+#endif
+}
+#endif /* DUMBBELL_WIP */
diff --git a/sys/dev/drm2/radeon/radeon_sa.c b/sys/dev/drm2/radeon/radeon_sa.c
new file mode 100644
index 0000000..e750812
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_sa.c
@@ -0,0 +1,428 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ */
+/* Algorithm:
+ *
+ * We store the last allocated bo in "hole", we always try to allocate
+ * after the last allocated bo. Principle is that in a linear GPU ring
+ * progression was is after last is the oldest bo we allocated and thus
+ * the first one that should no longer be in use by the GPU.
+ *
+ * If it's not the case we skip over the bo after last to the closest
+ * done bo if such one exist. If none exist and we are not asked to
+ * block we report failure to allocate.
+ *
+ * If we are asked to block we wait on all the oldest fence of all
+ * rings. We just wait for any of those fence to complete.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+
+static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo);
+static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager);
+
+int radeon_sa_bo_manager_init(struct radeon_device *rdev,
+ struct radeon_sa_manager *sa_manager,
+ unsigned size, u32 domain)
+{
+ int i, r;
+
+ sx_init(&sa_manager->wq_lock, "drm__radeon_sa_manager_wq_mtx");
+ cv_init(&sa_manager->wq, "drm__radeon_sa_manager__wq");
+ sa_manager->bo = NULL;
+ sa_manager->size = size;
+ sa_manager->domain = domain;
+ sa_manager->hole = &sa_manager->olist;
+ INIT_LIST_HEAD(&sa_manager->olist);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ INIT_LIST_HEAD(&sa_manager->flist[i]);
+ }
+
+ r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_CPU, NULL, &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->olist)) {
+ sa_manager->hole = &sa_manager->olist,
+ radeon_sa_bo_try_free(sa_manager);
+ if (!list_empty(&sa_manager->olist)) {
+ dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n");
+ }
+ }
+ list_for_each_entry_safe(sa_bo, tmp, &sa_manager->olist, olist) {
+ radeon_sa_bo_remove_locked(sa_bo);
+ }
+ radeon_bo_unref(&sa_manager->bo);
+ sa_manager->size = 0;
+ cv_destroy(&sa_manager->wq);
+ sx_destroy(&sa_manager->wq_lock);
+}
+
+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;
+}
+
+static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo)
+{
+ struct radeon_sa_manager *sa_manager = sa_bo->manager;
+ if (sa_manager->hole == &sa_bo->olist) {
+ sa_manager->hole = sa_bo->olist.prev;
+ }
+ list_del_init(&sa_bo->olist);
+ list_del_init(&sa_bo->flist);
+ radeon_fence_unref(&sa_bo->fence);
+ free(sa_bo, DRM_MEM_DRIVER);
+}
+
+static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager)
+{
+ struct radeon_sa_bo *sa_bo, *tmp;
+
+ if (sa_manager->hole->next == &sa_manager->olist)
+ return;
+
+ sa_bo = list_entry(sa_manager->hole->next, struct radeon_sa_bo, olist);
+ list_for_each_entry_safe_from(sa_bo, tmp, &sa_manager->olist, olist) {
+ if (sa_bo->fence == NULL || !radeon_fence_signaled(sa_bo->fence)) {
+ return;
+ }
+ radeon_sa_bo_remove_locked(sa_bo);
+ }
+}
+
+static inline unsigned radeon_sa_bo_hole_soffset(struct radeon_sa_manager *sa_manager)
+{
+ struct list_head *hole = sa_manager->hole;
+
+ if (hole != &sa_manager->olist) {
+ return list_entry(hole, struct radeon_sa_bo, olist)->eoffset;
+ }
+ return 0;
+}
+
+static inline unsigned radeon_sa_bo_hole_eoffset(struct radeon_sa_manager *sa_manager)
+{
+ struct list_head *hole = sa_manager->hole;
+
+ if (hole->next != &sa_manager->olist) {
+ return list_entry(hole->next, struct radeon_sa_bo, olist)->soffset;
+ }
+ return sa_manager->size;
+}
+
+static bool radeon_sa_bo_try_alloc(struct radeon_sa_manager *sa_manager,
+ struct radeon_sa_bo *sa_bo,
+ unsigned size, unsigned align)
+{
+ unsigned soffset, eoffset, wasted;
+
+ soffset = radeon_sa_bo_hole_soffset(sa_manager);
+ eoffset = radeon_sa_bo_hole_eoffset(sa_manager);
+ wasted = (align - (soffset % align)) % align;
+
+ if ((eoffset - soffset) >= (size + wasted)) {
+ soffset += wasted;
+
+ sa_bo->manager = sa_manager;
+ sa_bo->soffset = soffset;
+ sa_bo->eoffset = soffset + size;
+ list_add(&sa_bo->olist, sa_manager->hole);
+ INIT_LIST_HEAD(&sa_bo->flist);
+ sa_manager->hole = &sa_bo->olist;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * radeon_sa_event - Check if we can stop waiting
+ *
+ * @sa_manager: pointer to the sa_manager
+ * @size: number of bytes we want to allocate
+ * @align: alignment we need to match
+ *
+ * Check if either there is a fence we can wait for or
+ * enough free memory to satisfy the allocation directly
+ */
+static bool radeon_sa_event(struct radeon_sa_manager *sa_manager,
+ unsigned size, unsigned align)
+{
+ unsigned soffset, eoffset, wasted;
+ int i;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (!list_empty(&sa_manager->flist[i])) {
+ return true;
+ }
+ }
+
+ soffset = radeon_sa_bo_hole_soffset(sa_manager);
+ eoffset = radeon_sa_bo_hole_eoffset(sa_manager);
+ wasted = (align - (soffset % align)) % align;
+
+ if ((eoffset - soffset) >= (size + wasted)) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool radeon_sa_bo_next_hole(struct radeon_sa_manager *sa_manager,
+ struct radeon_fence **fences,
+ unsigned *tries)
+{
+ struct radeon_sa_bo *best_bo = NULL;
+ unsigned i, soffset, best, tmp;
+
+ /* if hole points to the end of the buffer */
+ if (sa_manager->hole->next == &sa_manager->olist) {
+ /* try again with its beginning */
+ sa_manager->hole = &sa_manager->olist;
+ return true;
+ }
+
+ soffset = radeon_sa_bo_hole_soffset(sa_manager);
+ /* to handle wrap around we add sa_manager->size */
+ best = sa_manager->size * 2;
+ /* go over all fence list and try to find the closest sa_bo
+ * of the current last
+ */
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ struct radeon_sa_bo *sa_bo;
+
+ if (list_empty(&sa_manager->flist[i])) {
+ continue;
+ }
+
+ sa_bo = list_first_entry(&sa_manager->flist[i],
+ struct radeon_sa_bo, flist);
+
+ if (!radeon_fence_signaled(sa_bo->fence)) {
+ fences[i] = sa_bo->fence;
+ continue;
+ }
+
+ /* limit the number of tries each ring gets */
+ if (tries[i] > 2) {
+ continue;
+ }
+
+ tmp = sa_bo->soffset;
+ if (tmp < soffset) {
+ /* wrap around, pretend it's after */
+ tmp += sa_manager->size;
+ }
+ tmp -= soffset;
+ if (tmp < best) {
+ /* this sa bo is the closest one */
+ best = tmp;
+ best_bo = sa_bo;
+ }
+ }
+
+ if (best_bo) {
+ ++tries[best_bo->fence->ring];
+ sa_manager->hole = best_bo->olist.prev;
+
+ /* we knew that this one is signaled,
+ so it's save to remote it */
+ radeon_sa_bo_remove_locked(best_bo);
+ return true;
+ }
+ return false;
+}
+
+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, bool block)
+{
+ struct radeon_fence *fences[RADEON_NUM_RINGS];
+ unsigned tries[RADEON_NUM_RINGS];
+ int i, r;
+
+ KASSERT(align <= RADEON_GPU_PAGE_SIZE, ("align > RADEON_GPU_PAGE_SIZE"));
+ KASSERT(size <= sa_manager->size, ("size > sa_manager->size"));
+
+ *sa_bo = malloc(sizeof(struct radeon_sa_bo), DRM_MEM_DRIVER, M_WAITOK);
+ if ((*sa_bo) == NULL) {
+ return -ENOMEM;
+ }
+ (*sa_bo)->manager = sa_manager;
+ (*sa_bo)->fence = NULL;
+ INIT_LIST_HEAD(&(*sa_bo)->olist);
+ INIT_LIST_HEAD(&(*sa_bo)->flist);
+
+ sx_xlock(&sa_manager->wq_lock);
+ do {
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ fences[i] = NULL;
+ tries[i] = 0;
+ }
+
+ do {
+ radeon_sa_bo_try_free(sa_manager);
+
+ if (radeon_sa_bo_try_alloc(sa_manager, *sa_bo,
+ size, align)) {
+ sx_xunlock(&sa_manager->wq_lock);
+ return 0;
+ }
+
+ /* see if we can skip over some allocations */
+ } while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
+
+ sx_xunlock(&sa_manager->wq_lock);
+ r = radeon_fence_wait_any(rdev, fences, false);
+ sx_xlock(&sa_manager->wq_lock);
+ /* if we have nothing to wait for block */
+ if (r == -ENOENT && block) {
+ while (!radeon_sa_event(sa_manager, size, align)) {
+ r = -cv_wait_sig(&sa_manager->wq,
+ &sa_manager->wq_lock);
+ if (r != 0)
+ break;
+ }
+
+ } else if (r == -ENOENT) {
+ r = -ENOMEM;
+ }
+
+ } while (!r);
+
+ sx_xunlock(&sa_manager->wq_lock);
+ free(*sa_bo, DRM_MEM_DRIVER);
+ *sa_bo = NULL;
+ return r;
+}
+
+void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo,
+ struct radeon_fence *fence)
+{
+ struct radeon_sa_manager *sa_manager;
+
+ if (sa_bo == NULL || *sa_bo == NULL) {
+ return;
+ }
+
+ sa_manager = (*sa_bo)->manager;
+ sx_xlock(&sa_manager->wq_lock);
+ if (fence && !radeon_fence_signaled(fence)) {
+ (*sa_bo)->fence = radeon_fence_ref(fence);
+ list_add_tail(&(*sa_bo)->flist,
+ &sa_manager->flist[fence->ring]);
+ } else {
+ radeon_sa_bo_remove_locked(*sa_bo);
+ }
+ cv_broadcast(&sa_manager->wq);
+ sx_xunlock(&sa_manager->wq_lock);
+ *sa_bo = NULL;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
+ struct seq_file *m)
+{
+ struct radeon_sa_bo *i;
+
+ spin_lock(&sa_manager->wq.lock);
+ list_for_each_entry(i, &sa_manager->olist, olist) {
+ if (&i->olist == sa_manager->hole) {
+ seq_printf(m, ">");
+ } else {
+ seq_printf(m, " ");
+ }
+ seq_printf(m, "[0x%08x 0x%08x] size %8d",
+ i->soffset, i->eoffset, i->eoffset - i->soffset);
+ if (i->fence) {
+ seq_printf(m, " protected by 0x%016llx on ring %d",
+ i->fence->seq, i->fence->ring);
+ }
+ seq_printf(m, "\n");
+ }
+ spin_unlock(&sa_manager->wq.lock);
+}
+#endif
diff --git a/sys/dev/drm2/radeon/radeon_semaphore.c b/sys/dev/drm2/radeon/radeon_semaphore.c
new file mode 100644
index 0000000..717a94a
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_semaphore.c
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Authors:
+ * Christian König <deathsimple@vodafone.de>
+ */
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+
+
+int radeon_semaphore_create(struct radeon_device *rdev,
+ struct radeon_semaphore **semaphore)
+{
+ int r;
+
+ *semaphore = malloc(sizeof(struct radeon_semaphore),
+ DRM_MEM_DRIVER, M_WAITOK);
+ if (*semaphore == NULL) {
+ return -ENOMEM;
+ }
+ r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
+ &(*semaphore)->sa_bo, 8, 8, true);
+ if (r) {
+ free(*semaphore, DRM_MEM_DRIVER);
+ *semaphore = NULL;
+ return r;
+ }
+ (*semaphore)->waiters = 0;
+ (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
+ *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
+ return 0;
+}
+
+void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
+ struct radeon_semaphore *semaphore)
+{
+ --semaphore->waiters;
+ 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)
+{
+ ++semaphore->waiters;
+ radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true);
+}
+
+/* caller must hold ring lock */
+int radeon_semaphore_sync_rings(struct radeon_device *rdev,
+ struct radeon_semaphore *semaphore,
+ int signaler, int waiter)
+{
+ int r;
+
+ /* no need to signal and wait on the same ring */
+ if (signaler == waiter) {
+ return 0;
+ }
+
+ /* prevent GPU deadlocks */
+ if (!rdev->ring[signaler].ready) {
+ dev_err(rdev->dev, "Trying to sync to a disabled ring!");
+ return -EINVAL;
+ }
+
+ r = radeon_ring_alloc(rdev, &rdev->ring[signaler], 8);
+ if (r) {
+ return r;
+ }
+ radeon_semaphore_emit_signal(rdev, signaler, semaphore);
+ radeon_ring_commit(rdev, &rdev->ring[signaler]);
+
+ /* we assume caller has already allocated space on waiters ring */
+ radeon_semaphore_emit_wait(rdev, waiter, semaphore);
+
+ /* for debugging lockup only, used by sysfs debug files */
+ rdev->ring[signaler].last_semaphore_signal_addr = semaphore->gpu_addr;
+ rdev->ring[waiter].last_semaphore_wait_addr = semaphore->gpu_addr;
+
+ return 0;
+}
+
+void radeon_semaphore_free(struct radeon_device *rdev,
+ struct radeon_semaphore **semaphore,
+ struct radeon_fence *fence)
+{
+ if (semaphore == NULL || *semaphore == NULL) {
+ return;
+ }
+ if ((*semaphore)->waiters > 0) {
+ dev_err(rdev->dev, "semaphore %p has more waiters than signalers,"
+ " hardware lockup imminent!\n", *semaphore);
+ }
+ radeon_sa_bo_free(rdev, &(*semaphore)->sa_bo, fence);
+ free(*semaphore, DRM_MEM_DRIVER);
+ *semaphore = NULL;
+}
diff --git a/sys/dev/drm2/radeon/radeon_state.c b/sys/dev/drm2/radeon/radeon_state.c
new file mode 100644
index 0000000..1716830
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_state.c
@@ -0,0 +1,3262 @@
+/* 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 <gareth@valinux.com>
+ * Kevin E. Martin <martin@valinux.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/drm_buffer.h>
+#include <dev/drm2/radeon/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) {
+ DRM_ERROR("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->masterp->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=%u y=%u w=%u h=%u\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->masterp, 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->masterp->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->masterp, 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->masterp);
+
+ radeon_cp_dispatch_flip(dev, file_priv->masterp);
+
+ 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->masterp->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->masterp);
+ 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->masterp->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->masterp, 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->masterp->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->masterp, buf, &prim);
+ if (elts->discard) {
+ radeon_cp_discard_buffer(dev, file_priv->masterp, 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->masterp, 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->masterp->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->masterp, 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->masterp, 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->masterp, 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 = dev->irq;
+ 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;
+#ifndef __LP64__
+ /*
+ * 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->masterp->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 = malloc(sizeof(*radeon_priv), DRM_MEM_DRIVER, M_WAITOK);
+
+ 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;
+
+ free(radeon_priv, DRM_MEM_DRIVER);
+}
+
+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/sys/dev/drm2/radeon/radeon_test.c b/sys/dev/drm2/radeon/radeon_test.c
new file mode 100644
index 0000000..7774699
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_test.c
@@ -0,0 +1,509 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#include "radeon_reg.h"
+#include "radeon.h"
+
+#define RADEON_TEST_COPY_BLIT 1
+#define RADEON_TEST_COPY_DMA 0
+
+
+/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */
+static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
+{
+ 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, ring;
+
+ switch (flag) {
+ case RADEON_TEST_COPY_DMA:
+ ring = radeon_copy_dma_ring_index(rdev);
+ break;
+ case RADEON_TEST_COPY_BLIT:
+ ring = radeon_copy_blit_ring_index(rdev);
+ break;
+ default:
+ DRM_ERROR("Unknown copy method\n");
+ return;
+ }
+
+ 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 = malloc(n * sizeof(*gtt_obj), DRM_MEM_DRIVER, M_ZERO | M_WAITOK);
+ 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,
+ NULL, &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, NULL, 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, &gtt_addr);
+ if (r) {
+ DRM_ERROR("Failed to pin GTT object %d\n", i);
+ goto out_cleanup;
+ }
+
+ r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
+ if (r) {
+ DRM_ERROR("Failed to map GTT object %d\n", i);
+ goto out_cleanup;
+ }
+
+ for (gtt_start = gtt_map, gtt_end = (void *)((uintptr_t)gtt_map + size);
+ gtt_start < gtt_end;
+ gtt_start++)
+ *gtt_start = gtt_start;
+
+ radeon_bo_kunmap(gtt_obj[i]);
+
+ if (ring == R600_RING_TYPE_DMA_INDEX)
+ r = radeon_copy_dma(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
+ else
+ r = radeon_copy_blit(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 = (void *)((uintptr_t)gtt_map + size),
+ vram_start = vram_map, vram_end = (void *)((uintptr_t)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)
+ ((uintptr_t)gtt_addr - (uintptr_t)rdev->mc.gtt_start +
+ (uintptr_t)gtt_start - (uintptr_t)gtt_map),
+ (unsigned long long)
+ ((uintptr_t)vram_addr - (uintptr_t)rdev->mc.vram_start +
+ (uintptr_t)gtt_start - (uintptr_t)gtt_map));
+ radeon_bo_kunmap(vram_obj);
+ goto out_cleanup;
+ }
+ *vram_start = vram_start;
+ }
+
+ radeon_bo_kunmap(vram_obj);
+
+ if (ring == R600_RING_TYPE_DMA_INDEX)
+ r = radeon_copy_dma(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
+ else
+ r = radeon_copy_blit(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], &gtt_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 = (void *)((uintptr_t)gtt_map + size),
+ vram_start = vram_map, vram_end = (void *)((uintptr_t)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)
+ ((uintptr_t)vram_addr - (uintptr_t)rdev->mc.vram_start +
+ (uintptr_t)vram_start - (uintptr_t)vram_map),
+ (unsigned long long)
+ ((uintptr_t)gtt_addr - (uintptr_t)rdev->mc.gtt_start +
+ (uintptr_t)vram_start - (uintptr_t)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%jx\n",
+ (uintmax_t)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(&gtt_obj[i]);
+ }
+ }
+ free(gtt_obj, DRM_MEM_DRIVER);
+ }
+ if (fence) {
+ radeon_fence_unref(&fence);
+ }
+ if (r) {
+ DRM_ERROR("Error while testing BO move.\n");
+ }
+}
+
+void radeon_test_moves(struct radeon_device *rdev)
+{
+ if (rdev->asic->copy.dma)
+ radeon_do_test_moves(rdev, RADEON_TEST_COPY_DMA);
+ if (rdev->asic->copy.blit)
+ radeon_do_test_moves(rdev, RADEON_TEST_COPY_BLIT);
+}
+
+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 r;
+
+ 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", ringA->idx);
+ goto out_cleanup;
+ }
+ radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
+ r = radeon_fence_emit(rdev, &fence1, ringA->idx);
+ if (r) {
+ DRM_ERROR("Failed to emit fence 1\n");
+ radeon_ring_unlock_undo(rdev, ringA);
+ goto out_cleanup;
+ }
+ radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
+ r = radeon_fence_emit(rdev, &fence2, ringA->idx);
+ if (r) {
+ DRM_ERROR("Failed to emit fence 2\n");
+ radeon_ring_unlock_undo(rdev, ringA);
+ goto out_cleanup;
+ }
+ radeon_ring_unlock_commit(rdev, ringA);
+
+ DRM_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, ringB->idx, 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;
+ }
+
+ DRM_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, ringB->idx, 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:
+ radeon_semaphore_free(rdev, &semaphore, NULL);
+
+ if (fence1)
+ radeon_fence_unref(&fence1);
+
+ if (fence2)
+ radeon_fence_unref(&fence2);
+
+ if (r)
+ DRM_ERROR("Error while testing ring sync (%d).\n", r);
+}
+
+static 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;
+ bool sigA, sigB;
+ int i, r;
+
+ 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", ringA->idx);
+ goto out_cleanup;
+ }
+ radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
+ r = radeon_fence_emit(rdev, &fenceA, ringA->idx);
+ if (r) {
+ DRM_ERROR("Failed to emit sync fence 1\n");
+ radeon_ring_unlock_undo(rdev, ringA);
+ goto out_cleanup;
+ }
+ radeon_ring_unlock_commit(rdev, ringA);
+
+ r = radeon_ring_lock(rdev, ringB, 64);
+ if (r) {
+ DRM_ERROR("Failed to lock ring B %d\n", ringB->idx);
+ goto out_cleanup;
+ }
+ radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore);
+ r = radeon_fence_emit(rdev, &fenceB, ringB->idx);
+ if (r) {
+ DRM_ERROR("Failed to create sync fence 2\n");
+ radeon_ring_unlock_undo(rdev, ringB);
+ goto out_cleanup;
+ }
+ radeon_ring_unlock_commit(rdev, ringB);
+
+ DRM_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, ringC->idx, semaphore);
+ radeon_ring_unlock_commit(rdev, ringC);
+
+ for (i = 0; i < 30; ++i) {
+ DRM_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, ringC->idx, semaphore);
+ radeon_ring_unlock_commit(rdev, ringC);
+
+ DRM_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:
+ radeon_semaphore_free(rdev, &semaphore, NULL);
+
+ if (fenceA)
+ radeon_fence_unref(&fenceA);
+
+ if (fenceB)
+ radeon_fence_unref(&fenceB);
+
+ if (r)
+ DRM_ERROR("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/sys/dev/drm2/radeon/radeon_trace.h b/sys/dev/drm2/radeon/radeon_trace.h
new file mode 100644
index 0000000..e0fe725
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_trace.h
@@ -0,0 +1,85 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#if !defined(_RADEON_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _RADEON_TRACE_H_
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#include <drm/drmP.h>
+
+#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 <trace/define_trace.h>
diff --git a/sys/dev/drm2/radeon/radeon_trace_points.c b/sys/dev/drm2/radeon/radeon_trace_points.c
new file mode 100644
index 0000000..5602c94
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_trace_points.c
@@ -0,0 +1,12 @@
+/* Copyright Red Hat Inc 2010.
+ * Author : Dave Airlie <airlied@redhat.com>
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <drm/drmP.h>
+#include <drm/radeon_drm.h>
+#include "radeon.h"
+
+#define CREATE_TRACE_POINTS
+#include "radeon_trace.h"
diff --git a/sys/dev/drm2/radeon/radeon_ttm.c b/sys/dev/drm2/radeon/radeon_ttm.c
new file mode 100644
index 0000000..22c0935
--- /dev/null
+++ b/sys/dev/drm2/radeon/radeon_ttm.c
@@ -0,0 +1,931 @@
+/*
+ * 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 <glisse@freedesktop.org>
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Dave Airlie
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/ttm/ttm_bo_api.h>
+#include <dev/drm2/ttm/ttm_bo_driver.h>
+#include <dev/drm2/ttm/ttm_placement.h>
+#include <dev/drm2/ttm/ttm_module.h>
+#include <dev/drm2/ttm/ttm_page_alloc.h>
+#include <dev/drm2/drmP.h>
+#include <dev/drm2/radeon/radeon_drm.h>
+#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)
+{
+ 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;
+
+ KASSERT(old_mem->mm_node == NULL, ("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, 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, ridx;
+
+ rdev = radeon_get_rdev(bo->bdev);
+ ridx = radeon_copy_ring_index(rdev);
+ 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[ridx].ready) {
+ DRM_ERROR("Trying to move memory with ring turned off.\n");
+ return -EINVAL;
+ }
+
+ CTASSERT((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) == 0);
+
+ /* sync other rings */
+ fence = bo->sync_obj;
+ 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,
+ evict, 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_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_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_gpu, &tmp_mem, old_mem);
+ if (unlikely(r)) {
+ goto out_cleanup;
+ }
+ r = ttm_bo_move_ttm(bo, true, 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_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_gpu);
+ if (unlikely(r)) {
+ return r;
+ }
+ r = ttm_bo_move_ttm(bo, true, no_wait_gpu, &tmp_mem);
+ if (unlikely(r)) {
+ goto out_cleanup;
+ }
+ r = radeon_move_blit(bo, true, 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_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_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_gpu, new_mem);
+ } else {
+ r = radeon_move_blit(bo, evict, no_wait_gpu, new_mem, old_mem);
+ }
+
+ if (r) {
+memcpy:
+ r = ttm_bo_move_memcpy(bo, evict, 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, bool lazy, bool interruptible)
+{
+ return radeon_fence_wait((struct radeon_fence *)sync_obj, interruptible);
+}
+
+static int radeon_sync_obj_flush(void *sync_obj)
+{
+ 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)
+{
+ 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) {
+ DRM_ERROR("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(&gtt->ttm);
+ free(gtt, DRM_MEM_DRIVER);
+}
+
+static struct ttm_backend_func radeon_backend_func = {
+ .bind = &radeon_ttm_backend_bind,
+ .unbind = &radeon_ttm_backend_unbind,
+ .destroy = &radeon_ttm_backend_destroy,
+};
+
+static struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ vm_page_t dummy_read_page)
+{
+ struct radeon_device *rdev;
+ struct radeon_ttm_tt *gtt;
+
+ rdev = radeon_get_rdev(bdev);
+#if __OS_HAS_AGP
+#ifdef DUMBBELL_WIP
+ if (rdev->flags & RADEON_IS_AGP) {
+ return ttm_agp_tt_create(bdev, rdev->ddev->agp->agpdev,
+ size, page_flags, dummy_read_page);
+ }
+#endif /* DUMBBELL_WIP */
+#endif
+
+ gtt = malloc(sizeof(struct radeon_ttm_tt),
+ DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
+ if (gtt == NULL) {
+ return NULL;
+ }
+ gtt->ttm.ttm.func = &radeon_backend_func;
+ gtt->rdev = rdev;
+ if (ttm_dma_tt_init(&gtt->ttm, bdev, size, page_flags, dummy_read_page)) {
+ free(gtt, DRM_MEM_DRIVER);
+ return NULL;
+ }
+ return &gtt->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;
+#ifdef DUMBBELL_WIP
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+#endif /* DUMBBELL_WIP */
+
+ if (ttm->state != tt_unpopulated)
+ return 0;
+
+#ifdef DUMBBELL_WIP
+ /*
+ * Maybe unneeded on FreeBSD.
+ * -- dumbbell@
+ */
+ if (slave && ttm->sg) {
+ drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
+ gtt->ttm.dma_address, ttm->num_pages);
+ ttm->state = tt_unbound;
+ return 0;
+ }
+#endif /* DUMBBELL_WIP */
+
+ rdev = radeon_get_rdev(ttm->bdev);
+#if __OS_HAS_AGP
+#ifdef DUMBBELL_WIP
+ if (rdev->flags & RADEON_IS_AGP) {
+ return ttm_agp_tt_populate(ttm);
+ }
+#endif /* DUMBBELL_WIP */
+#endif
+
+#ifdef CONFIG_SWIOTLB
+ if (swiotlb_nr_tbl()) {
+ return ttm_dma_populate(&gtt->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] = VM_PAGE_TO_PHYS(ttm->pages[i]);
+#ifdef DUMBBELL_WIP
+ 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;
+ }
+#endif /* DUMBBELL_WIP */
+ }
+ 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;
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+ if (slave)
+ return;
+
+ rdev = radeon_get_rdev(ttm->bdev);
+#if __OS_HAS_AGP
+#ifdef DUMBBELL_WIP
+ if (rdev->flags & RADEON_IS_AGP) {
+ ttm_agp_tt_unpopulate(ttm);
+ return;
+ }
+#endif /* DUMBBELL_WIP */
+#endif
+
+#ifdef CONFIG_SWIOTLB
+ if (swiotlb_nr_tbl()) {
+ ttm_dma_unpopulate(&gtt->ttm, rdev->dev);
+ return;
+ }
+#endif
+
+ for (i = 0; i < ttm->num_pages; i++) {
+ if (gtt->ttm.dma_address[i]) {
+ gtt->ttm.dma_address[i] = 0;
+#ifdef DUMBBELL_WIP
+ pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i],
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+#endif /* DUMBBELL_WIP */
+ }
+ }
+
+ 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, r2;
+
+ 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;
+ rdev->ddev->drm_ttm_bdev = &rdev->mman.bdev;
+ 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,
+ NULL, &rdev->stollen_vga_memory);
+ if (r) {
+ return r;
+ }
+ r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ if (r) {
+ radeon_bo_unref(&rdev->stollen_vga_memory);
+ 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");
+ r2 = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ if (likely(r2 == 0)) {
+ radeon_bo_unpin(rdev->stollen_vga_memory);
+ radeon_bo_unreserve(rdev->stollen_vga_memory);
+ }
+ radeon_bo_unref(&rdev->stollen_vga_memory);
+ return r;
+ }
+ DRM_INFO("radeon: %uM of GTT memory ready.\n",
+ (unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
+
+ r = radeon_ttm_debugfs_init(rdev);
+ if (r) {
+ DRM_ERROR("Failed to init debugfs\n");
+ r2 = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ if (likely(r2 == 0)) {
+ radeon_bo_unpin(rdev->stollen_vga_memory);
+ radeon_bo_unreserve(rdev->stollen_vga_memory);
+ }
+ radeon_bo_unref(&rdev->stollen_vga_memory);
+ 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;
+}
+
+#ifdef DUMBBELL_WIP
+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);
+ sx_slock(&rdev->pm.mclk_lock);
+ r = ttm_vm_ops->fault(vma, vmf);
+ sx_sunlock(&rdev->pm.mclk_lock);
+ 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;
+}
+#endif /* DUMBBELL_WIP */
+
+
+#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/sys/dev/drm2/radeon/reg_srcs/cayman b/sys/dev/drm2/radeon/reg_srcs/cayman
new file mode 100644
index 0000000..a072fa8
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/cayman
@@ -0,0 +1,642 @@
+cayman 0x9400
+0x0000802C GRBM_GFX_INDEX
+0x00008040 WAIT_UNTIL
+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/sys/dev/drm2/radeon/reg_srcs/evergreen b/sys/dev/drm2/radeon/reg_srcs/evergreen
new file mode 100644
index 0000000..b912a37
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/evergreen
@@ -0,0 +1,644 @@
+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/sys/dev/drm2/radeon/reg_srcs/r100 b/sys/dev/drm2/radeon/reg_srcs/r100
new file mode 100644
index 0000000..f7ee062
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/r100
@@ -0,0 +1,105 @@
+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/sys/dev/drm2/radeon/reg_srcs/r200 b/sys/dev/drm2/radeon/reg_srcs/r200
new file mode 100644
index 0000000..c29ac43
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/r200
@@ -0,0 +1,186 @@
+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/sys/dev/drm2/radeon/reg_srcs/r300 b/sys/dev/drm2/radeon/reg_srcs/r300
new file mode 100644
index 0000000..e8a1786
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/r300
@@ -0,0 +1,714 @@
+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/sys/dev/drm2/radeon/reg_srcs/r420 b/sys/dev/drm2/radeon/reg_srcs/r420
new file mode 100644
index 0000000..722074e
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/r420
@@ -0,0 +1,780 @@
+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/sys/dev/drm2/radeon/reg_srcs/r600 b/sys/dev/drm2/radeon/reg_srcs/r600
new file mode 100644
index 0000000..20bfbda
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/r600
@@ -0,0 +1,755 @@
+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
+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/sys/dev/drm2/radeon/reg_srcs/rn50 b/sys/dev/drm2/radeon/reg_srcs/rn50
new file mode 100644
index 0000000..2687b63
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/rn50
@@ -0,0 +1,30 @@
+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/sys/dev/drm2/radeon/reg_srcs/rs600 b/sys/dev/drm2/radeon/reg_srcs/rs600
new file mode 100644
index 0000000..d9f6286
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/rs600
@@ -0,0 +1,780 @@
+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/sys/dev/drm2/radeon/reg_srcs/rv515 b/sys/dev/drm2/radeon/reg_srcs/rv515
new file mode 100644
index 0000000..78d5e99
--- /dev/null
+++ b/sys/dev/drm2/radeon/reg_srcs/rv515
@@ -0,0 +1,496 @@
+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
+0x46C0 RB3D_COLOR_CLEAR_VALUE_AR
+0x46C4 RB3D_COLOR_CLEAR_VALUE_GB
+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/sys/dev/drm2/radeon/rn50_reg_safe.h b/sys/dev/drm2/radeon/rn50_reg_safe.h
new file mode 100644
index 0000000..043d8a4
--- /dev/null
+++ b/sys/dev/drm2/radeon/rn50_reg_safe.h
@@ -0,0 +1,31 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned rn50_reg_safe_bm[102] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF,
+};
diff --git a/sys/dev/drm2/radeon/rs100d.h b/sys/dev/drm2/radeon/rs100d.h
new file mode 100644
index 0000000..d90bb51
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs100d.h
@@ -0,0 +1,43 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/rs400.c b/sys/dev/drm2/radeon/rs400.c
new file mode 100644
index 0000000..f9d638d
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs400.c
@@ -0,0 +1,568 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#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) {
+ DRM_ERROR("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 */
+ if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) {
+ tmp = RREG32_MC(RS690_MC_NB_CNTL);
+ tmp &= ~(RS690_HIDE_MMCFG_BAR |
+ RS690_AGPMODE30 |
+ RS690_AGP30ENHANCED);
+ WREG32_MC(RS690_MC_NB_CNTL, tmp);
+ 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) & 0xfffff000) |
+ ((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;
+}
+
+static void rs400_gpu_init(struct radeon_device *rdev)
+{
+ /* FIXME: is this correct ? */
+ r420_pipes_init(rdev);
+ if (rs400_mc_wait_for_idle(rdev)) {
+ DRM_ERROR("rs400: Failed to wait MC idle while "
+ "programming pipes. Bad things might happen. %08x\n", RREG32(RADEON_MC_STATUS));
+ }
+}
+
+static 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
+}
+
+static 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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/rs400d.h b/sys/dev/drm2/radeon/rs400d.h
new file mode 100644
index 0000000..7a01d20
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs400d.h
@@ -0,0 +1,163 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/rs600.c b/sys/dev/drm2/radeon/rs600.c
new file mode 100644
index 0000000..6d3b17a
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs600.c
@@ -0,0 +1,1042 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "atom.h"
+#include "rs600d.h"
+
+#include "rs600_reg_safe.h"
+
+static void rs600_gpu_init(struct radeon_device *rdev);
+
+static const u32 crtc_offsets[2] =
+{
+ 0,
+ AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
+};
+
+void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
+{
+ int i;
+
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK))
+ break;
+ DRM_UDELAY(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) & AVIVO_D1CRTC_V_BLANK)
+ break;
+ DRM_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;
+ DRM_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)
+ DRM_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)
+ DRM_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;
+ unsigned enable = 0;
+
+ 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));
+ break;
+ case RADEON_HPD_2:
+ WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+ S_007D10_DC_HOT_PLUG_DETECT2_EN(1));
+ break;
+ default:
+ break;
+ }
+ enable |= 1 << radeon_connector->hpd.hpd;
+ radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+ }
+ radeon_irq_kms_enable_hpd(rdev, enable);
+}
+
+void rs600_hpd_fini(struct radeon_device *rdev)
+{
+ struct drm_device *dev = rdev->ddev;
+ struct drm_connector *connector;
+ unsigned disable = 0;
+
+ 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));
+ break;
+ case RADEON_HPD_2:
+ WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL,
+ S_007D10_DC_HOT_PLUG_DETECT2_EN(0));
+ break;
+ default:
+ break;
+ }
+ disable |= 1 << radeon_connector->hpd.hpd;
+ }
+ radeon_irq_kms_disable_hpd(rdev, disable);
+}
+
+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->dev);
+ /* disable bus mastering */
+ pci_disable_busmaster(rdev->dev);
+ DRM_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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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);
+ DRM_MDELAY(500);
+ WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
+ DRM_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->dev);
+ /* 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");
+ 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);
+}
+
+static int rs600_gart_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->gart.robj) {
+ DRM_ERROR("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;
+}
+
+static 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);
+}
+
+static 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)
+{
+ uint64_t *ptr = 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;
+ ptr[i] = addr;
+ 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);
+ u32 hdmi0;
+ if (ASIC_IS_DCE2(rdev))
+ hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) &
+ ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1);
+ else
+ hdmi0 = 0;
+
+ if (!rdev->irq.installed) {
+ DRM_ERROR("Can't enable IRQ/MSI because no handler is installed\n");
+ WREG32(R_000040_GEN_INT_CNTL, 0);
+ return -EINVAL;
+ }
+ if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
+ tmp |= S_000040_SW_INT_EN(1);
+ }
+ if (rdev->irq.crtc_vblank_int[0] ||
+ atomic_read(&rdev->irq.pflip[0])) {
+ mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1);
+ }
+ if (rdev->irq.crtc_vblank_int[1] ||
+ atomic_read(&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);
+ }
+ if (rdev->irq.afmt[0]) {
+ hdmi0 |= S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(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);
+ if (ASIC_IS_DCE2(rdev))
+ WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
+ 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;
+
+ 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 (ASIC_IS_DCE2(rdev)) {
+ rdev->irq.stat_regs.r500.hdmi0_status = RREG32(R_007404_HDMI0_STATUS) &
+ S_007404_HDMI0_AZ_FORMAT_WTRIG(1);
+ if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) {
+ tmp = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL);
+ tmp |= S_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(1);
+ WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, tmp);
+ }
+ } else
+ rdev->irq.stat_regs.r500.hdmi0_status = 0;
+
+ if (irqs) {
+ WREG32(R_000044_GEN_INT_STATUS, irqs);
+ }
+ return irqs & irq_mask;
+}
+
+void rs600_irq_disable(struct radeon_device *rdev)
+{
+ u32 hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) &
+ ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1);
+ WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
+ WREG32(R_000040_GEN_INT_CNTL, 0);
+ WREG32(R_006540_DxMODE_INT_MASK, 0);
+ /* Wait and acknowledge irq */
+ DRM_MDELAY(1);
+ rs600_irq_ack(rdev);
+}
+
+irqreturn_t rs600_irq_process(struct radeon_device *rdev)
+{
+ u32 status, msi_rearm;
+ bool queue_hotplug = false;
+ bool queue_hdmi = false;
+
+ status = rs600_irq_ack(rdev);
+ if (!status &&
+ !rdev->irq.stat_regs.r500.disp_int &&
+ !rdev->irq.stat_regs.r500.hdmi0_status) {
+ return IRQ_NONE;
+ }
+ while (status ||
+ rdev->irq.stat_regs.r500.disp_int ||
+ rdev->irq.stat_regs.r500.hdmi0_status) {
+ /* SW interrupt */
+ if (G_000044_SW_INT(status)) {
+ radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
+ }
+ /* 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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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");
+ }
+ if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) {
+ queue_hdmi = true;
+ DRM_DEBUG("HDMI0\n");
+ }
+ status = rs600_irq_ack(rdev);
+ }
+ if (queue_hotplug)
+ taskqueue_enqueue(rdev->tq, &rdev->hotplug_work);
+ if (queue_hdmi)
+ taskqueue_enqueue(rdev->tq, &rdev->audio_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;
+ DRM_UDELAY(1);
+ }
+ return -1;
+}
+
+static 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");
+}
+
+static void rs600_mc_init(struct radeon_device *rdev)
+{
+ u64 base;
+
+ rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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);
+}
+
+static 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 = DRM_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 = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing audio\n");
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_fini(rdev);
+ rs600_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/rs600_reg_safe.h b/sys/dev/drm2/radeon/rs600_reg_safe.h
new file mode 100644
index 0000000..07913c9
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs600_reg_safe.h
@@ -0,0 +1,60 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned rs600_reg_safe_bm[219] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
+ 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFC48, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE00BFF,
+ 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0xFF800000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0003FC0B, 0xFFFFFCFF, 0xFFBFFB99, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+};
diff --git a/sys/dev/drm2/radeon/rs600d.h b/sys/dev/drm2/radeon/rs600d.h
new file mode 100644
index 0000000..f7a5b71
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs600d.h
@@ -0,0 +1,688 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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
+#define R_007404_HDMI0_STATUS 0x007404
+#define S_007404_HDMI0_AZ_FORMAT_WTRIG(x) (((x) & 0x1) << 28)
+#define G_007404_HDMI0_AZ_FORMAT_WTRIG(x) (((x) >> 28) & 0x1)
+#define C_007404_HDMI0_AZ_FORMAT_WTRIG 0xEFFFFFFF
+#define S_007404_HDMI0_AZ_FORMAT_WTRIG_INT(x) (((x) & 0x1) << 29)
+#define G_007404_HDMI0_AZ_FORMAT_WTRIG_INT(x) (((x) >> 29) & 0x1)
+#define C_007404_HDMI0_AZ_FORMAT_WTRIG_INT 0xDFFFFFFF
+#define R_007408_HDMI0_AUDIO_PACKET_CONTROL 0x007408
+#define S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(x) (((x) & 0x1) << 28)
+#define G_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(x) (((x) >> 28) & 0x1)
+#define C_007408_HDMI0_AZ_FORMAT_WTRIG_MASK 0xEFFFFFFF
+#define S_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(x) (((x) & 0x1) << 29)
+#define G_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(x) (((x) >> 29) & 0x1)
+#define C_007408_HDMI0_AZ_FORMAT_WTRIG_ACK 0xDFFFFFFF
+
+/* 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/sys/dev/drm2/radeon/rs690.c b/sys/dev/drm2/radeon/rs690.c
new file mode 100644
index 0000000..2320538
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs690.c
@@ -0,0 +1,788 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/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;
+ DRM_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)) {
+ DRM_ERROR("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 *)((uintptr_t)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);
+}
+
+static 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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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;
+};
+
+static 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;
+#ifdef DUMBBELL_WIP
+ read_delay_latency.full = dfixed_const(370 * 800 * 1000);
+#endif /* DUMBBELL_WIP */
+ read_delay_latency.full = UINT_MAX;
+ 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);
+}
+
+static 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 = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing audio\n");
+ 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)
+{
+ 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);
+ radeon_ib_pool_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);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/sys/dev/drm2/radeon/rs690d.h b/sys/dev/drm2/radeon/rs690d.h
new file mode 100644
index 0000000..af90d7c
--- /dev/null
+++ b/sys/dev/drm2/radeon/rs690d.h
@@ -0,0 +1,313 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/rv200d.h b/sys/dev/drm2/radeon/rv200d.h
new file mode 100644
index 0000000..0fec87c
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv200d.h
@@ -0,0 +1,39 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/rv250d.h b/sys/dev/drm2/radeon/rv250d.h
new file mode 100644
index 0000000..6122735
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv250d.h
@@ -0,0 +1,126 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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/sys/dev/drm2/radeon/rv350d.h b/sys/dev/drm2/radeon/rv350d.h
new file mode 100644
index 0000000..dbeaa36
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv350d.h
@@ -0,0 +1,55 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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/sys/dev/drm2/radeon/rv515.c b/sys/dev/drm2/radeon/rv515.c
new file mode 100644
index 0000000..d83cf1b
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv515.c
@@ -0,0 +1,1201 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/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 */
+static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
+static int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
+static void rv515_gpu_init(struct radeon_device *rdev);
+
+static const u32 crtc_offsets[2] =
+{
+ 0,
+ AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
+};
+
+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);
+}
+
+static void rv515_gpu_init(struct radeon_device *rdev)
+{
+ unsigned pipe_select_current, gb_pipe_select, tmp;
+
+ if (r100_gui_wait_for_idle(rdev)) {
+ DRM_ERROR("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)) {
+ DRM_ERROR("Failed to wait GUI idle while "
+ "resetting GPU. Bad things might happen.\n");
+ }
+ if (rv515_mc_wait_for_idle(rdev)) {
+ DRM_ERROR("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;
+ }
+}
+
+static 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
+
+static 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
+}
+
+static 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)
+{
+ u32 crtc_enabled, tmp, frame_count, blackout;
+ int i, j;
+
+ save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL);
+ save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL);
+
+ /* disable VGA render */
+ WREG32(R_000300_VGA_RENDER_CONTROL, 0);
+ /* blank the display controllers */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN;
+ if (crtc_enabled) {
+ save->crtc_enabled[i] = true;
+ tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
+ if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ DRM_UDELAY(1);
+ }
+ } else {
+ save->crtc_enabled[i] = false;
+ }
+ }
+
+ radeon_mc_wait_for_idle(rdev);
+
+ if (rdev->family >= CHIP_R600) {
+ if (rdev->family >= CHIP_RV770)
+ blackout = RREG32(R700_MC_CITF_CNTL);
+ else
+ blackout = RREG32(R600_CITF_CNTL);
+ if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) {
+ /* Block CPU access */
+ WREG32(R600_BIF_FB_EN, 0);
+ /* blackout the MC */
+ blackout |= R600_BLACKOUT_MASK;
+ if (rdev->family >= CHIP_RV770)
+ WREG32(R700_MC_CITF_CNTL, blackout);
+ else
+ WREG32(R600_CITF_CNTL, blackout);
+ }
+ }
+ /* wait for the MC to settle */
+ DRM_UDELAY(100);
+}
+
+void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
+{
+ u32 tmp, frame_count;
+ int i, j;
+
+ /* update crtc base addresses */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->family >= CHIP_RV770) {
+ if (i == 1) {
+ WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
+ upper_32_bits(rdev->mc.vram_start));
+ WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
+ upper_32_bits(rdev->mc.vram_start));
+ } else {
+ WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
+ upper_32_bits(rdev->mc.vram_start));
+ WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
+ upper_32_bits(rdev->mc.vram_start));
+ }
+ }
+ WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
+ (u32)rdev->mc.vram_start);
+ WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
+ (u32)rdev->mc.vram_start);
+ }
+ WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
+
+ if (rdev->family >= CHIP_R600) {
+ /* unblackout the MC */
+ if (rdev->family >= CHIP_RV770)
+ tmp = RREG32(R700_MC_CITF_CNTL);
+ else
+ tmp = RREG32(R600_CITF_CNTL);
+ tmp &= ~R600_BLACKOUT_MASK;
+ if (rdev->family >= CHIP_RV770)
+ WREG32(R700_MC_CITF_CNTL, tmp);
+ else
+ WREG32(R600_CITF_CNTL, tmp);
+ /* allow CPU access */
+ WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN);
+ }
+
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (save->crtc_enabled[i]) {
+ tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]);
+ tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp);
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
+ break;
+ DRM_UDELAY(1);
+ }
+ }
+ }
+ /* Unlock vga access */
+ WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
+ DRM_MDELAY(1);
+ WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
+}
+
+static 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_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ 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 = DRM_ARRAY_SIZE(rv515_reg_safe_bm);
+}
+
+void rv515_fini(struct radeon_device *rdev)
+{
+ r100_cp_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_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);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ 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);
+
+ rdev->accel_working = true;
+ 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);
+ radeon_ib_pool_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;
+};
+
+static 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/sys/dev/drm2/radeon/rv515_reg_safe.h b/sys/dev/drm2/radeon/rv515_reg_safe.h
new file mode 100644
index 0000000..07bd827
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv515_reg_safe.h
@@ -0,0 +1,60 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+static const unsigned rv515_reg_safe_bm[219] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+ 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFEFC6, 0xF00EBFFF, 0x007C0000,
+ 0xF0000038, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x1FFFFC48, 0xFFFFE000, 0xFFFFFE1E, 0xFFFFFFFF,
+ 0x388F8F50, 0xFFF88082, 0xFF0000FC, 0xFAE00BFF,
+ 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00008CFC, 0xFFFCC1FF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE80FFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0003FC0B, 0x3FFFFCFF, 0xFFBFFB99, 0xFFDFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+};
diff --git a/sys/dev/drm2/radeon/rv515d.h b/sys/dev/drm2/radeon/rv515d.h
new file mode 100644
index 0000000..38b3a2e
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv515d.h
@@ -0,0 +1,652 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * 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/sys/dev/drm2/radeon/rv770.c b/sys/dev/drm2/radeon/rv770.c
new file mode 100644
index 0000000..cb875bd
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv770.c
@@ -0,0 +1,1297 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include <dev/drm2/radeon/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);
+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;
+ DRM_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
+ */
+static 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;
+}
+
+static 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);
+}
+
+static void rv770_pcie_gart_fini(struct radeon_device *rdev)
+{
+ radeon_gart_fini(rdev);
+ rv770_pcie_gart_disable(rdev);
+ radeon_gart_table_vram_free(rdev);
+}
+
+
+static 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);
+ rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
+}
+
+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);
+ DRM_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)
+{
+ struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ r700_cp_stop(rdev);
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+}
+
+/*
+ * Core functions
+ */
+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 gb_tiling_config = 0;
+ u32 cc_rb_backend_disable = 0;
+ u32 cc_gc_shader_pipe_config = 0;
+ u32 mc_arb_ramcfg;
+ u32 db_debug4, tmp;
+ u32 inactive_pipes, shader_pipe_config;
+ u32 disabled_rb_mask;
+ unsigned active_number;
+
+ /* setup chip specs */
+ rdev->config.rv770.tiling_group_size = 256;
+ 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);
+
+ shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG);
+ inactive_pipes = (shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT;
+ for (i = 0, tmp = 1, active_number = 0; i < R7XX_MAX_PIPES; i++) {
+ if (!(inactive_pipes & tmp)) {
+ active_number++;
+ }
+ tmp <<= 1;
+ }
+ if (active_number == 1) {
+ WREG32(SPI_CONFIG_CNTL, DISABLE_INTERP_1);
+ } else {
+ WREG32(SPI_CONFIG_CNTL, 0);
+ }
+
+ cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000;
+ tmp = R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_rb_backend_disable >> 16);
+ if (tmp < rdev->config.rv770.max_backends) {
+ rdev->config.rv770.max_backends = tmp;
+ }
+
+ cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00;
+ tmp = R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 8) & R7XX_MAX_PIPES_MASK);
+ if (tmp < rdev->config.rv770.max_pipes) {
+ rdev->config.rv770.max_pipes = tmp;
+ }
+ tmp = R7XX_MAX_SIMDS - r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R7XX_MAX_SIMDS_MASK);
+ if (tmp < rdev->config.rv770.max_simds) {
+ rdev->config.rv770.max_simds = tmp;
+ }
+
+ 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;
+
+ disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R7XX_MAX_BACKENDS_MASK;
+ tmp = (gb_tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT;
+ tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.rv770.max_backends,
+ R7XX_MAX_BACKENDS, disabled_rb_mask);
+ gb_tiling_config |= tmp << 16;
+ rdev->config.rv770.backend_map = tmp;
+
+ 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 & 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);
+ rdev->config.rv770.tile_config = gb_tiling_config;
+
+ WREG32(GB_TILING_CONFIG, gb_tiling_config);
+ WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ WREG32(DMA_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ WREG32(DMA_TILING_CONFIG2, (gb_tiling_config & 0xffff));
+
+ 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_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: %juM 0x%08jX - 0x%08jX (%juM used)\n",
+ (uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start,
+ (uintmax_t)mc->vram_end, (uintmax_t)mc->real_vram_size >> 20);
+ } else {
+ radeon_vram_location(rdev, &rdev->mc, 0);
+ rdev->mc.gtt_base_align = 0;
+ radeon_gtt_location(rdev, mc);
+ }
+}
+
+static 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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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;
+}
+
+/**
+ * rv770_copy_dma - copy pages using the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the DMA engine (r7xx).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int rv770_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence)
+{
+ struct radeon_semaphore *sem = NULL;
+ int ring_index = rdev->asic->copy.dma_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ring_index];
+ u32 size_in_dw, cur_size_in_dw;
+ int i, num_loops;
+ int r = 0;
+
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ return r;
+ }
+
+ size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4;
+ num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF);
+ r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ radeon_semaphore_free(rdev, &sem, NULL);
+ return r;
+ }
+
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
+
+ for (i = 0; i < num_loops; i++) {
+ cur_size_in_dw = size_in_dw;
+ if (cur_size_in_dw > 0xFFFF)
+ cur_size_in_dw = 0xFFFF;
+ size_in_dw -= cur_size_in_dw;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw));
+ radeon_ring_write(ring, dst_offset & 0xfffffffc);
+ radeon_ring_write(ring, src_offset & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
+ radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff);
+ src_offset += cur_size_in_dw * 4;
+ dst_offset += cur_size_in_dw * 4;
+ }
+
+ r = radeon_fence_emit(rdev, fence, ring->idx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, *fence);
+
+ return r;
+}
+
+static int rv770_startup(struct radeon_device *rdev)
+{
+ struct radeon_ring *ring;
+ 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;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA 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);
+
+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ 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;
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+ DMA_RB_RPTR, DMA_RB_WPTR,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
+ if (r)
+ return r;
+
+ r = rv770_cp_load_microcode(rdev);
+ if (r)
+ return r;
+ r = r600_cp_resume(rdev);
+ if (r)
+ return r;
+
+ r = r600_dma_resume(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = r600_audio_init(rdev);
+ if (r) {
+ DRM_ERROR("radeon: audio init failed\n");
+ 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;
+ }
+
+ return r;
+
+}
+
+int rv770_suspend(struct radeon_device *rdev)
+{
+ r600_audio_fini(rdev);
+ r700_cp_stop(rdev);
+ r600_dma_stop(rdev);
+ 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;
+
+ /* 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->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
+ r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
+
+ rdev->ih.ring_obj = NULL;
+ r600_ih_ring_init(rdev, 64 * 1024);
+
+ r = r600_pcie_gart_init(rdev);
+ if (r)
+ return r;
+
+ rdev->accel_working = true;
+ r = rv770_startup(rdev);
+ if (r) {
+ dev_err(rdev->dev, "disabling GPU acceleration\n");
+ r700_cp_fini(rdev);
+ r600_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rv770_pcie_gart_fini(rdev);
+ rdev->accel_working = false;
+ }
+
+ return 0;
+}
+
+void rv770_fini(struct radeon_device *rdev)
+{
+ r600_blit_fini(rdev);
+ r700_cp_fini(rdev);
+ r600_dma_fini(rdev);
+ r600_irq_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rv770_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
+ radeon_gem_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_agp_fini(rdev);
+ radeon_bo_fini(rdev);
+ radeon_atombios_fini(rdev);
+ r600_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ rdev->bios = NULL;
+}
+
+static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
+{
+ u32 link_width_cntl, lanes, speed_cntl, tmp;
+ u16 link_cntl2;
+ u32 mask;
+ int ret;
+
+ 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;
+
+ ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+ if (ret != 0)
+ return;
+
+ if (!(mask & DRM_PCIE_SPEED_50))
+ return;
+
+ DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
+
+ /* 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/sys/dev/drm2/radeon/rv770d.h b/sys/dev/drm2/radeon/rv770d.h
new file mode 100644
index 0000000..1f2c23c
--- /dev/null
+++ b/sys/dev/drm2/radeon/rv770d.h
@@ -0,0 +1,673 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#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 PIPE_TILING__SHIFT 1
+#define PIPE_TILING__MASK 0x0000000e
+
+#define DMA_TILING_CONFIG 0x3ec8
+#define DMA_TILING_CONFIG2 0xd0b8
+
+#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 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
+
+/* async DMA */
+#define DMA_RB_RPTR 0xd008
+#define DMA_RB_WPTR 0xd00c
+
+/* async DMA packets */
+#define DMA_PACKET(cmd, t, s, n) ((((cmd) & 0xF) << 28) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((n) & 0xFFFF) << 0))
+/* async DMA Packet types */
+#define DMA_PACKET_WRITE 0x2
+#define DMA_PACKET_COPY 0x3
+#define DMA_PACKET_INDIRECT_BUFFER 0x4
+#define DMA_PACKET_SEMAPHORE 0x5
+#define DMA_PACKET_FENCE 0x6
+#define DMA_PACKET_TRAP 0x7
+#define DMA_PACKET_CONSTANT_FILL 0xd
+#define DMA_PACKET_NOP 0xf
+
+
+#define SRBM_STATUS 0x0E50
+
+/* DCE 3.2 HDMI */
+#define HDMI_CONTROL 0x7400
+# define HDMI_KEEPOUT_MODE (1 << 0)
+# define HDMI_PACKET_GEN_VERSION (1 << 4) /* 0 = r6xx compat */
+# define HDMI_ERROR_ACK (1 << 8)
+# define HDMI_ERROR_MASK (1 << 9)
+#define HDMI_STATUS 0x7404
+# define HDMI_ACTIVE_AVMUTE (1 << 0)
+# define HDMI_AUDIO_PACKET_ERROR (1 << 16)
+# define HDMI_VBI_PACKET_ERROR (1 << 20)
+#define HDMI_AUDIO_PACKET_CONTROL 0x7408
+# define HDMI_AUDIO_DELAY_EN(x) (((x) & 3) << 4)
+# define HDMI_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16)
+#define HDMI_ACR_PACKET_CONTROL 0x740c
+# define HDMI_ACR_SEND (1 << 0)
+# define HDMI_ACR_CONT (1 << 1)
+# define HDMI_ACR_SELECT(x) (((x) & 3) << 4)
+# define HDMI_ACR_HW 0
+# define HDMI_ACR_32 1
+# define HDMI_ACR_44 2
+# define HDMI_ACR_48 3
+# define HDMI_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */
+# define HDMI_ACR_AUTO_SEND (1 << 12)
+#define HDMI_VBI_PACKET_CONTROL 0x7410
+# define HDMI_NULL_SEND (1 << 0)
+# define HDMI_GC_SEND (1 << 4)
+# define HDMI_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */
+#define HDMI_INFOFRAME_CONTROL0 0x7414
+# define HDMI_AVI_INFO_SEND (1 << 0)
+# define HDMI_AVI_INFO_CONT (1 << 1)
+# define HDMI_AUDIO_INFO_SEND (1 << 4)
+# define HDMI_AUDIO_INFO_CONT (1 << 5)
+# define HDMI_MPEG_INFO_SEND (1 << 8)
+# define HDMI_MPEG_INFO_CONT (1 << 9)
+#define HDMI_INFOFRAME_CONTROL1 0x7418
+# define HDMI_AVI_INFO_LINE(x) (((x) & 0x3f) << 0)
+# define HDMI_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8)
+# define HDMI_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16)
+#define HDMI_GENERIC_PACKET_CONTROL 0x741c
+# define HDMI_GENERIC0_SEND (1 << 0)
+# define HDMI_GENERIC0_CONT (1 << 1)
+# define HDMI_GENERIC1_SEND (1 << 4)
+# define HDMI_GENERIC1_CONT (1 << 5)
+# define HDMI_GENERIC0_LINE(x) (((x) & 0x3f) << 16)
+# define HDMI_GENERIC1_LINE(x) (((x) & 0x3f) << 24)
+#define HDMI_GC 0x7428
+# define HDMI_GC_AVMUTE (1 << 0)
+#define AFMT_AUDIO_PACKET_CONTROL2 0x742c
+# define AFMT_AUDIO_LAYOUT_OVRD (1 << 0)
+# define AFMT_AUDIO_LAYOUT_SELECT (1 << 1)
+# define AFMT_60958_CS_SOURCE (1 << 4)
+# define AFMT_AUDIO_CHANNEL_ENABLE(x) (((x) & 0xff) << 8)
+# define AFMT_DP_AUDIO_STREAM_ID(x) (((x) & 0xff) << 16)
+#define AFMT_AVI_INFO0 0x7454
+# define AFMT_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_AVI_INFO_S(x) (((x) & 3) << 8)
+# define AFMT_AVI_INFO_B(x) (((x) & 3) << 10)
+# define AFMT_AVI_INFO_A(x) (((x) & 1) << 12)
+# define AFMT_AVI_INFO_Y(x) (((x) & 3) << 13)
+# define AFMT_AVI_INFO_Y_RGB 0
+# define AFMT_AVI_INFO_Y_YCBCR422 1
+# define AFMT_AVI_INFO_Y_YCBCR444 2
+# define AFMT_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8)
+# define AFMT_AVI_INFO_R(x) (((x) & 0xf) << 16)
+# define AFMT_AVI_INFO_M(x) (((x) & 0x3) << 20)
+# define AFMT_AVI_INFO_C(x) (((x) & 0x3) << 22)
+# define AFMT_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16)
+# define AFMT_AVI_INFO_SC(x) (((x) & 0x3) << 24)
+# define AFMT_AVI_INFO_Q(x) (((x) & 0x3) << 26)
+# define AFMT_AVI_INFO_EC(x) (((x) & 0x3) << 28)
+# define AFMT_AVI_INFO_ITC(x) (((x) & 0x1) << 31)
+# define AFMT_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24)
+#define AFMT_AVI_INFO1 0x7458
+# define AFMT_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */
+# define AFMT_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */
+# define AFMT_AVI_INFO_TOP(x) (((x) & 0xffff) << 16)
+#define AFMT_AVI_INFO2 0x745c
+# define AFMT_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0)
+# define AFMT_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16)
+#define AFMT_AVI_INFO3 0x7460
+# define AFMT_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0)
+# define AFMT_AVI_INFO_VERSION(x) (((x) & 3) << 24)
+#define AFMT_MPEG_INFO0 0x7464
+# define AFMT_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_MPEG_INFO_MB0(x) (((x) & 0xff) << 8)
+# define AFMT_MPEG_INFO_MB1(x) (((x) & 0xff) << 16)
+# define AFMT_MPEG_INFO_MB2(x) (((x) & 0xff) << 24)
+#define AFMT_MPEG_INFO1 0x7468
+# define AFMT_MPEG_INFO_MB3(x) (((x) & 0xff) << 0)
+# define AFMT_MPEG_INFO_MF(x) (((x) & 3) << 8)
+# define AFMT_MPEG_INFO_FR(x) (((x) & 1) << 12)
+#define AFMT_GENERIC0_HDR 0x746c
+#define AFMT_GENERIC0_0 0x7470
+#define AFMT_GENERIC0_1 0x7474
+#define AFMT_GENERIC0_2 0x7478
+#define AFMT_GENERIC0_3 0x747c
+#define AFMT_GENERIC0_4 0x7480
+#define AFMT_GENERIC0_5 0x7484
+#define AFMT_GENERIC0_6 0x7488
+#define AFMT_GENERIC1_HDR 0x748c
+#define AFMT_GENERIC1_0 0x7490
+#define AFMT_GENERIC1_1 0x7494
+#define AFMT_GENERIC1_2 0x7498
+#define AFMT_GENERIC1_3 0x749c
+#define AFMT_GENERIC1_4 0x74a0
+#define AFMT_GENERIC1_5 0x74a4
+#define AFMT_GENERIC1_6 0x74a8
+#define HDMI_ACR_32_0 0x74ac
+# define HDMI_ACR_CTS_32(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_32_1 0x74b0
+# define HDMI_ACR_N_32(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_44_0 0x74b4
+# define HDMI_ACR_CTS_44(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_44_1 0x74b8
+# define HDMI_ACR_N_44(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_48_0 0x74bc
+# define HDMI_ACR_CTS_48(x) (((x) & 0xfffff) << 12)
+#define HDMI_ACR_48_1 0x74c0
+# define HDMI_ACR_N_48(x) (((x) & 0xfffff) << 0)
+#define HDMI_ACR_STATUS_0 0x74c4
+#define HDMI_ACR_STATUS_1 0x74c8
+#define AFMT_AUDIO_INFO0 0x74cc
+# define AFMT_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
+# define AFMT_AUDIO_INFO_CC(x) (((x) & 7) << 8)
+# define AFMT_AUDIO_INFO_CHECKSUM_OFFSET(x) (((x) & 0xff) << 16)
+#define AFMT_AUDIO_INFO1 0x74d0
+# define AFMT_AUDIO_INFO_CA(x) (((x) & 0xff) << 0)
+# define AFMT_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11)
+# define AFMT_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15)
+# define AFMT_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8)
+#define AFMT_60958_0 0x74d4
+# define AFMT_60958_CS_A(x) (((x) & 1) << 0)
+# define AFMT_60958_CS_B(x) (((x) & 1) << 1)
+# define AFMT_60958_CS_C(x) (((x) & 1) << 2)
+# define AFMT_60958_CS_D(x) (((x) & 3) << 3)
+# define AFMT_60958_CS_MODE(x) (((x) & 3) << 6)
+# define AFMT_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8)
+# define AFMT_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16)
+# define AFMT_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20)
+# define AFMT_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24)
+# define AFMT_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28)
+#define AFMT_60958_1 0x74d8
+# define AFMT_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0)
+# define AFMT_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4)
+# define AFMT_60958_CS_VALID_L(x) (((x) & 1) << 16)
+# define AFMT_60958_CS_VALID_R(x) (((x) & 1) << 18)
+# define AFMT_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20)
+#define AFMT_AUDIO_CRC_CONTROL 0x74dc
+# define AFMT_AUDIO_CRC_EN (1 << 0)
+#define AFMT_RAMP_CONTROL0 0x74e0
+# define AFMT_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0)
+# define AFMT_RAMP_DATA_SIGN (1 << 31)
+#define AFMT_RAMP_CONTROL1 0x74e4
+# define AFMT_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0)
+# define AFMT_AUDIO_TEST_CH_DISABLE(x) (((x) & 0xff) << 24)
+#define AFMT_RAMP_CONTROL2 0x74e8
+# define AFMT_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0)
+#define AFMT_RAMP_CONTROL3 0x74ec
+# define AFMT_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0)
+#define AFMT_60958_2 0x74f0
+# define AFMT_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0)
+# define AFMT_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4)
+# define AFMT_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8)
+# define AFMT_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12)
+# define AFMT_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16)
+# define AFMT_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20)
+#define AFMT_STATUS 0x7600
+# define AFMT_AUDIO_ENABLE (1 << 4)
+# define AFMT_AZ_FORMAT_WTRIG (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30)
+#define AFMT_AUDIO_PACKET_CONTROL 0x7604
+# define AFMT_AUDIO_SAMPLE_SEND (1 << 0)
+# define AFMT_AUDIO_TEST_EN (1 << 12)
+# define AFMT_AUDIO_CHANNEL_SWAP (1 << 24)
+# define AFMT_60958_CS_UPDATE (1 << 26)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27)
+# define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28)
+# define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29)
+# define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30)
+#define AFMT_VBI_PACKET_CONTROL 0x7608
+# define AFMT_GENERIC0_UPDATE (1 << 2)
+#define AFMT_INFOFRAME_CONTROL0 0x760c
+# define AFMT_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - hmdi regs */
+# define AFMT_AUDIO_INFO_UPDATE (1 << 7)
+# define AFMT_MPEG_INFO_UPDATE (1 << 10)
+#define AFMT_GENERIC0_7 0x7610
+/* second instance starts at 0x7800 */
+#define HDMI_OFFSET0 (0x7400 - 0x7400)
+#define HDMI_OFFSET1 (0x7800 - 0x7400)
+
+/* DCE3.2 ELD audio interface */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0 0x71c8 /* LPCM */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1 0x71cc /* AC3 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2 0x71d0 /* MPEG1 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3 0x71d4 /* MP3 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4 0x71d8 /* MPEG2 */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5 0x71dc /* AAC */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6 0x71e0 /* DTS */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7 0x71e4 /* ATRAC */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR8 0x71e8 /* one bit audio - leave at 0 (default) */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9 0x71ec /* Dolby Digital */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10 0x71f0 /* DTS-HD */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11 0x71f4 /* MAT-MLP */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR12 0x71f8 /* DTS */
+#define AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13 0x71fc /* WMA Pro */
+# define MAX_CHANNELS(x) (((x) & 0x7) << 0)
+/* max channels minus one. 7 = 8 channels */
+# define SUPPORTED_FREQUENCIES(x) (((x) & 0xff) << 8)
+# define DESCRIPTOR_BYTE_2(x) (((x) & 0xff) << 16)
+# define SUPPORTED_FREQUENCIES_STEREO(x) (((x) & 0xff) << 24) /* LPCM only */
+/* SUPPORTED_FREQUENCIES, SUPPORTED_FREQUENCIES_STEREO
+ * bit0 = 32 kHz
+ * bit1 = 44.1 kHz
+ * bit2 = 48 kHz
+ * bit3 = 88.2 kHz
+ * bit4 = 96 kHz
+ * bit5 = 176.4 kHz
+ * bit6 = 192 kHz
+ */
+
+#define AZ_HOT_PLUG_CONTROL 0x7300
+# define AZ_FORCE_CODEC_WAKE (1 << 0)
+# define PIN0_JACK_DETECTION_ENABLE (1 << 4)
+# define PIN1_JACK_DETECTION_ENABLE (1 << 5)
+# define PIN2_JACK_DETECTION_ENABLE (1 << 6)
+# define PIN3_JACK_DETECTION_ENABLE (1 << 7)
+# define PIN0_UNSOLICITED_RESPONSE_ENABLE (1 << 8)
+# define PIN1_UNSOLICITED_RESPONSE_ENABLE (1 << 9)
+# define PIN2_UNSOLICITED_RESPONSE_ENABLE (1 << 10)
+# define PIN3_UNSOLICITED_RESPONSE_ENABLE (1 << 11)
+# define CODEC_HOT_PLUG_ENABLE (1 << 12)
+# define PIN0_AUDIO_ENABLED (1 << 24)
+# define PIN1_AUDIO_ENABLED (1 << 25)
+# define PIN2_AUDIO_ENABLED (1 << 26)
+# define PIN3_AUDIO_ENABLED (1 << 27)
+# define AUDIO_ENABLED (1 << 31)
+
+
+#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/sys/dev/drm2/radeon/si.c b/sys/dev/drm2/radeon/si.c
new file mode 100644
index 0000000..6a04b94
--- /dev/null
+++ b/sys/dev/drm2/radeon/si.c
@@ -0,0 +1,4424 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include <dev/drm2/radeon/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
+
+/* 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;
+ DRM_UDELAY(1);
+ }
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
+ break;
+ DRM_UDELAY(1);
+ }
+
+ if (running)
+ WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+ }
+
+ return 0;
+}
+
+static int si_init_microcode(struct radeon_device *rdev)
+{
+ 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");
+
+ 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: panic("%s: Unsupported family %d", __func__, rdev->family);
+ }
+
+ DRM_INFO("Loading %s Microcode\n", chip_name);
+ err = 0;
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
+ rdev->pfp_fw = firmware_get(fw_name);
+ if (rdev->pfp_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->pfp_fw->datasize != pfp_req_size) {
+ DRM_ERROR(
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->pfp_fw->datasize, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
+ rdev->me_fw = firmware_get(fw_name);
+ if (rdev->me_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->me_fw->datasize != me_req_size) {
+ DRM_ERROR(
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", chip_name);
+ rdev->ce_fw = firmware_get(fw_name);
+ if (rdev->ce_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->ce_fw->datasize != ce_req_size) {
+ DRM_ERROR(
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->ce_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", rlc_chip_name);
+ rdev->rlc_fw = firmware_get(fw_name);
+ if (rdev->rlc_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->rlc_fw->datasize != rlc_req_size) {
+ DRM_ERROR(
+ "si_rlc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->rlc_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
+ rdev->mc_fw = firmware_get(fw_name);
+ if (rdev->mc_fw == NULL) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (rdev->mc_fw->datasize != mc_req_size) {
+ DRM_ERROR(
+ "si_mc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->mc_fw->datasize, fw_name);
+ err = -EINVAL;
+ }
+
+out:
+ if (err) {
+ if (err != -EINVAL)
+ DRM_ERROR(
+ "si_cp: Failed to load firmware \"%s\"\n",
+ fw_name);
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+ if (rdev->ce_fw != NULL) {
+ firmware_put(rdev->ce_fw, FIRMWARE_UNLOAD);
+ rdev->ce_fw = NULL;
+ }
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+ if (rdev->mc_fw != NULL) {
+ firmware_put(rdev->mc_fw, FIRMWARE_UNLOAD);
+ rdev->mc_fw = NULL;
+ }
+ }
+ return err;
+}
+
+/**
+ * si_fini_microcode - drop the firmwares image references
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Drop the pfp, me, rlc, mc and ce firmware image references.
+ * Called at driver shutdown.
+ */
+static void si_fini_microcode(struct radeon_device *rdev)
+{
+
+ if (rdev->pfp_fw != NULL) {
+ firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+ rdev->pfp_fw = NULL;
+ }
+
+ if (rdev->me_fw != NULL) {
+ firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+ rdev->me_fw = NULL;
+ }
+
+ if (rdev->rlc_fw != NULL) {
+ firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+ rdev->rlc_fw = NULL;
+ }
+
+ if (rdev->mc_fw != NULL) {
+ firmware_put(rdev->mc_fw, FIRMWARE_UNLOAD);
+ rdev->mc_fw = NULL;
+ }
+
+ if (rdev->ce_fw != NULL) {
+ firmware_put(rdev->ce_fw, FIRMWARE_UNLOAD);
+ rdev->ce_fw = NULL;
+ }
+}
+
+/* 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 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_select_se_sh(struct radeon_device *rdev,
+ u32 se_num, u32 sh_num)
+{
+ u32 data = INSTANCE_BROADCAST_WRITES;
+
+ if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
+ data = SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
+ else if (se_num == 0xffffffff)
+ data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
+ else if (sh_num == 0xffffffff)
+ data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
+ else
+ data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
+ WREG32(GRBM_GFX_INDEX, data);
+}
+
+static u32 si_create_bitmask(u32 bit_width)
+{
+ u32 i, mask = 0;
+
+ for (i = 0; i < bit_width; i++) {
+ mask <<= 1;
+ mask |= 1;
+ }
+ return mask;
+}
+
+static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh)
+{
+ u32 data, mask;
+
+ data = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
+ if (data & 1)
+ data &= INACTIVE_CUS_MASK;
+ else
+ data = 0;
+ data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG);
+
+ data >>= INACTIVE_CUS_SHIFT;
+
+ mask = si_create_bitmask(cu_per_sh);
+
+ return ~data & mask;
+}
+
+static void si_setup_spi(struct radeon_device *rdev,
+ u32 se_num, u32 sh_per_se,
+ u32 cu_per_sh)
+{
+ int i, j, k;
+ u32 data, mask, active_cu;
+
+ for (i = 0; i < se_num; i++) {
+ for (j = 0; j < sh_per_se; j++) {
+ si_select_se_sh(rdev, i, j);
+ data = RREG32(SPI_STATIC_THREAD_MGMT_3);
+ active_cu = si_get_cu_enabled(rdev, cu_per_sh);
+
+ mask = 1;
+ for (k = 0; k < 16; k++) {
+ mask <<= k;
+ if (active_cu & mask) {
+ data &= ~mask;
+ WREG32(SPI_STATIC_THREAD_MGMT_3, data);
+ break;
+ }
+ }
+ }
+ }
+ si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+}
+
+static u32 si_get_rb_disabled(struct radeon_device *rdev,
+ u32 max_rb_num, u32 se_num,
+ u32 sh_per_se)
+{
+ u32 data, mask;
+
+ data = RREG32(CC_RB_BACKEND_DISABLE);
+ if (data & 1)
+ data &= BACKEND_DISABLE_MASK;
+ else
+ data = 0;
+ data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
+
+ data >>= BACKEND_DISABLE_SHIFT;
+
+ mask = si_create_bitmask(max_rb_num / se_num / sh_per_se);
+
+ return data & mask;
+}
+
+static void si_setup_rb(struct radeon_device *rdev,
+ u32 se_num, u32 sh_per_se,
+ u32 max_rb_num)
+{
+ int i, j;
+ u32 data, mask;
+ u32 disabled_rbs = 0;
+ u32 enabled_rbs = 0;
+
+ for (i = 0; i < se_num; i++) {
+ for (j = 0; j < sh_per_se; j++) {
+ si_select_se_sh(rdev, i, j);
+ data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se);
+ disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH);
+ }
+ }
+ si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+
+ mask = 1;
+ for (i = 0; i < max_rb_num; i++) {
+ if (!(disabled_rbs & mask))
+ enabled_rbs |= mask;
+ mask <<= 1;
+ }
+
+ for (i = 0; i < se_num; i++) {
+ si_select_se_sh(rdev, i, 0xffffffff);
+ data = 0;
+ for (j = 0; j < sh_per_se; j++) {
+ switch (enabled_rbs & 3) {
+ case 1:
+ data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
+ break;
+ case 2:
+ data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
+ break;
+ case 3:
+ default:
+ data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
+ break;
+ }
+ enabled_rbs >>= 2;
+ }
+ WREG32(PA_SC_RASTER_CONFIG, data);
+ }
+ si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+}
+
+static void si_gpu_init(struct radeon_device *rdev)
+{
+ u32 gb_addr_config = 0;
+ u32 mc_shared_chmap, mc_arb_ramcfg;
+ u32 sx_debug_1;
+ 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_tile_pipes = 12;
+ rdev->config.si.max_cu_per_sh = 8;
+ rdev->config.si.max_sh_per_se = 2;
+ 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;
+ gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_PITCAIRN:
+ rdev->config.si.max_shader_engines = 2;
+ rdev->config.si.max_tile_pipes = 8;
+ rdev->config.si.max_cu_per_sh = 5;
+ rdev->config.si.max_sh_per_se = 2;
+ 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;
+ gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_VERDE:
+ default:
+ rdev->config.si.max_shader_engines = 1;
+ rdev->config.si.max_tile_pipes = 4;
+ rdev->config.si.max_cu_per_sh = 2;
+ rdev->config.si.max_sh_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;
+ gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
+ 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);
+
+ rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
+ 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;
+
+ /* fix up row size */
+ gb_addr_config &= ~ROW_SIZE_MASK;
+ 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;
+ }
+
+ /* 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;
+ }
+ switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
+ case 0: /* four banks */
+ rdev->config.si.tile_config |= 0 << 4;
+ break;
+ case 1: /* eight banks */
+ rdev->config.si.tile_config |= 1 << 4;
+ break;
+ case 2: /* sixteen banks */
+ default:
+ rdev->config.si.tile_config |= 2 << 4;
+ break;
+ }
+ 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;
+
+ WREG32(GB_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
+ WREG32(HDP_ADDR_CONFIG, gb_addr_config);
+ WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
+ WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
+
+ si_tiling_mode_table_init(rdev);
+
+ si_setup_rb(rdev, rdev->config.si.max_shader_engines,
+ rdev->config.si.max_sh_per_se,
+ rdev->config.si.max_backends_per_se);
+
+ si_setup_spi(rdev, rdev->config.si.max_shader_engines,
+ rdev->config.si.max_sh_per_se,
+ rdev->config.si.max_cu_per_sh);
+
+
+ /* 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));
+
+ DRM_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->ring];
+ u32 header;
+
+ if (ib->is_const_ib) {
+ /* set switch buffer packet before const IB */
+ radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
+ radeon_ring_write(ring, 0);
+
+ header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
+ } else {
+ u32 next_rptr;
+ if (ring->rptr_save_reg) {
+ next_rptr = ring->wptr + 3 + 4 + 8;
+ radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+ radeon_ring_write(ring, ((ring->rptr_save_reg -
+ PACKET3_SET_CONFIG_REG_START) >> 2));
+ radeon_ring_write(ring, next_rptr);
+ } else if (rdev->wb.enabled) {
+ next_rptr = ring->wptr + 5 + 4 + 8;
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (1 << 8));
+ radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+ radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff);
+ radeon_ring_write(ring, next_rptr);
+ }
+
+ 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 ? (ib->vm->id << 24) : 0));
+
+ if (!ib->is_const_ib) {
+ /* 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 ? ib->vm->id : 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 */
+ }
+}
+
+/*
+ * 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);
+ 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;
+ }
+ DRM_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)
+{
+ struct radeon_ring *ring;
+ si_cp_enable(rdev, false);
+
+ ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+ radeon_ring_fini(rdev, ring);
+ radeon_scratch_free(rdev, ring->rptr_save_reg);
+}
+
+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);
+ DRM_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 whether 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);
+ }
+
+ DRM_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 whether 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);
+
+ DRM_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 whether 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);
+
+ DRM_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;
+
+ 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)) {
+ radeon_ring_lockup_update(ring);
+ return false;
+ }
+ /* force CP activities */
+ radeon_ring_force_activity(rdev, ring);
+ return radeon_ring_test_lockup(rdev, ring);
+}
+
+static void si_gpu_soft_reset_gfx(struct radeon_device *rdev)
+{
+ u32 grbm_reset = 0;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ return;
+
+ 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));
+
+ /* 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_BCI |
+ 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);
+ DRM_UDELAY(50);
+ WREG32(GRBM_SOFT_RESET, 0);
+ (void)RREG32(GRBM_SOFT_RESET);
+
+ 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));
+}
+
+static void si_gpu_soft_reset_dma(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ return;
+
+ dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+
+ /* dma0 */
+ tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
+
+ /* dma1 */
+ tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
+ tmp &= ~DMA_RB_ENABLE;
+ WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
+
+ /* Reset dma */
+ WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
+ RREG32(SRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ WREG32(SRBM_SOFT_RESET, 0);
+
+ dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n",
+ RREG32(DMA_STATUS_REG));
+}
+
+static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
+{
+ struct evergreen_mc_save save;
+
+ if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+ reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE);
+
+ if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
+ reset_mask &= ~RADEON_RESET_DMA;
+
+ if (reset_mask == 0)
+ return 0;
+
+ dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+
+ dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+ dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+
+ evergreen_mc_stop(rdev, &save);
+ if (radeon_mc_wait_for_idle(rdev)) {
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+ }
+
+ if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE))
+ si_gpu_soft_reset_gfx(rdev);
+
+ if (reset_mask & RADEON_RESET_DMA)
+ si_gpu_soft_reset_dma(rdev);
+
+ /* Wait a little for things to settle down */
+ DRM_UDELAY(50);
+
+ evergreen_mc_resume(rdev, &save);
+ return 0;
+}
+
+int si_asic_reset(struct radeon_device *rdev)
+{
+ return si_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
+ RADEON_RESET_COMPUTE |
+ RADEON_RESET_DMA));
+}
+
+/* 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: %juM 0x%016jX - 0x%016jX (%juM used)\n",
+ (uintmax_t)mc->mc_vram_size >> 20, (uintmax_t)mc->vram_start,
+ (uintmax_t)mc->vram_end, (uintmax_t)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: %juM 0x%016jX - 0x%016jX\n",
+ (uintmax_t)mc->gtt_size >> 20, (uintmax_t)mc->gtt_start, (uintmax_t)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 = drm_get_resource_start(rdev->ddev, 0);
+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 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);
+}
+
+static 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 */
+ /* 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);
+ /* Assign the pt base to something valid for now; the pts used for
+ * the VMs are determined by the application and setup and assigned
+ * on the fly in the vm part of radeon_gart.c
+ */
+ 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, 4);
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
+ RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+ PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
+ VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
+ READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ READ_PROTECTION_FAULT_ENABLE_DEFAULT |
+ WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+ WRITE_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;
+}
+
+static 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);
+}
+
+static 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 CP_STRMOUT_CNTL:
+ 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;
+ u32 command, info;
+
+ 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;
+ case PACKET3_CP_DMA:
+ command = ib[idx + 4];
+ info = ib[idx + 1];
+ if (command & PACKET3_CP_DMA_CMD_SAS) {
+ /* src address space is register */
+ if (((info & 0x60000000) >> 29) == 0) {
+ start_reg = idx_value << 2;
+ if (command & PACKET3_CP_DMA_CMD_SAIC) {
+ reg = start_reg;
+ if (!si_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad SRC register\n");
+ return -EINVAL;
+ }
+ } else {
+ for (i = 0; i < (command & 0x1fffff); i++) {
+ reg = start_reg + (4 * i);
+ if (!si_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad SRC register\n");
+ return -EINVAL;
+ }
+ }
+ }
+ }
+ }
+ if (command & PACKET3_CP_DMA_CMD_DAS) {
+ /* dst address space is register */
+ if (((info & 0x00300000) >> 20) == 0) {
+ start_reg = ib[idx + 2];
+ if (command & PACKET3_CP_DMA_CMD_DAIC) {
+ reg = start_reg;
+ if (!si_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad DST register\n");
+ return -EINVAL;
+ }
+ } else {
+ for (i = 0; i < (command & 0x1fffff); i++) {
+ reg = start_reg + (4 * i);
+ if (!si_vm_reg_valid(reg)) {
+ DRM_ERROR("CP DMA Bad DST register\n");
+ 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->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->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)
+{
+}
+
+/**
+ * si_vm_set_page - update the page tables using the CP
+ *
+ * @rdev: radeon_device pointer
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the CP (cayman-si).
+ */
+void si_vm_set_page(struct radeon_device *rdev, uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
+ uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+ uint64_t value;
+ unsigned ndw;
+
+ if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+ while (count) {
+ ndw = 2 + count * 2;
+ if (ndw > 0x3FFE)
+ ndw = 0x3FFE;
+
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(1)));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe));
+ for (; ndw > 2; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
+ }
+ } else {
+ /* DMA */
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ /* for non-physically contiguous pages (system) */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, ndw));
+ radeon_ring_write(ring, pe);
+ radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+ for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ if (flags & RADEON_VM_PAGE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & RADEON_VM_PAGE_VALID) {
+ value = addr;
+ } else {
+ value = 0;
+ }
+ addr += incr;
+ value |= r600_flags;
+ radeon_ring_write(ring, value);
+ radeon_ring_write(ring, upper_32_bits(value));
+ }
+ }
+ } else {
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ if (flags & RADEON_VM_PAGE_VALID)
+ value = addr;
+ else
+ value = 0;
+ /* for physically contiguous pages (vram) */
+ radeon_ring_write(ring, DMA_PTE_PDE_PACKET(ndw));
+ radeon_ring_write(ring, pe); /* dst addr */
+ radeon_ring_write(ring, upper_32_bits(pe) & 0xff);
+ radeon_ring_write(ring, r600_flags); /* mask */
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, value); /* value */
+ radeon_ring_write(ring, upper_32_bits(value));
+ radeon_ring_write(ring, incr); /* increment size */
+ radeon_ring_write(ring, 0);
+ pe += ndw * 4;
+ addr += (ndw / 2) * incr;
+ count -= ndw / 2;
+ }
+ }
+ }
+}
+
+void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+ struct radeon_ring *ring = &rdev->ring[ridx];
+
+ if (vm == NULL)
+ return;
+
+ /* write new base address */
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+
+ if (vm->id < 8) {
+ radeon_ring_write(ring,
+ (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
+ } else {
+ radeon_ring_write(ring,
+ (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2);
+ }
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+ /* flush hdp cache */
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+ radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 0x1);
+
+ /* bits 0-15 are the VM contexts0-15 */
+ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ WRITE_DATA_DST_SEL(0)));
+ radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
+ radeon_ring_write(ring, 0);
+ radeon_ring_write(ring, 1 << vm->id);
+
+ /* sync PFP to ME, otherwise we might get invalid PFP reads */
+ radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+ radeon_ring_write(ring, 0x0);
+}
+
+void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+ struct radeon_ring *ring = &rdev->ring[ridx];
+
+ if (vm == NULL)
+ return;
+
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
+ if (vm->id < 8) {
+ radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
+ } else {
+ radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2));
+ }
+ radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+ /* flush hdp cache */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
+ radeon_ring_write(ring, 1);
+
+ /* bits 0-7 are the VM contexts0-7 */
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
+ radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
+ radeon_ring_write(ring, 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, NULL,
+ &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, NULL,
+ &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.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);
+ tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
+ WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp);
+ tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
+ WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
+ 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);
+
+ pci_enable_busmaster(rdev->dev);
+
+ /* 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;
+ u32 dma_cntl, dma_cntl1;
+
+ if (!rdev->irq.installed) {
+ DRM_ERROR("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;
+
+ dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
+ dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
+
+ /* enable CP interrupts on all rings */
+ if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
+ DRM_DEBUG("si_irq_set: sw int gfx\n");
+ cp_int_cntl |= TIME_STAMP_INT_ENABLE;
+ }
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
+ DRM_DEBUG("si_irq_set: sw int cp1\n");
+ cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
+ }
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
+ DRM_DEBUG("si_irq_set: sw int cp2\n");
+ cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
+ }
+ if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
+ DRM_DEBUG("si_irq_set: sw int dma\n");
+ dma_cntl |= TRAP_ENABLE;
+ }
+
+ if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
+ DRM_DEBUG("si_irq_set: sw int dma1\n");
+ dma_cntl1 |= TRAP_ENABLE;
+ }
+ if (rdev->irq.crtc_vblank_int[0] ||
+ atomic_read(&rdev->irq.pflip[0])) {
+ DRM_DEBUG("si_irq_set: vblank 0\n");
+ crtc1 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[1] ||
+ atomic_read(&rdev->irq.pflip[1])) {
+ DRM_DEBUG("si_irq_set: vblank 1\n");
+ crtc2 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[2] ||
+ atomic_read(&rdev->irq.pflip[2])) {
+ DRM_DEBUG("si_irq_set: vblank 2\n");
+ crtc3 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[3] ||
+ atomic_read(&rdev->irq.pflip[3])) {
+ DRM_DEBUG("si_irq_set: vblank 3\n");
+ crtc4 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[4] ||
+ atomic_read(&rdev->irq.pflip[4])) {
+ DRM_DEBUG("si_irq_set: vblank 4\n");
+ crtc5 |= VBLANK_INT_MASK;
+ }
+ if (rdev->irq.crtc_vblank_int[5] ||
+ atomic_read(&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;
+ }
+
+ 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(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl);
+ WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1);
+
+ 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 */
+ DRM_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
+ */
+irqreturn_t si_irq_process(struct radeon_device *rdev)
+{
+ u32 wptr;
+ u32 rptr;
+ u32 src_id, src_data, ring_id;
+ u32 ring_index;
+ bool queue_hotplug = false;
+
+ if (!rdev->ih.enabled || rdev->shutdown)
+ return IRQ_NONE;
+
+ wptr = si_get_ih_wptr(rdev);
+
+restart_ih:
+ /* is somebody else already processing irqs? */
+ if (atomic_xchg(&rdev->ih.lock, 1))
+ return IRQ_NONE;
+
+ rptr = rdev->ih.rptr;
+ DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
+ /* Order reading of wptr vs. reading of IH ring data */
+ rmb();
+
+ /* display interrupts */
+ si_irq_ack(rdev);
+
+ 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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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;
+ DRM_WAKEUP(&rdev->irq.vblank_queue);
+ }
+ if (atomic_read(&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 146:
+ case 147:
+ dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
+ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
+ RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+ /* reset addr and status */
+ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+ 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 224: /* DMA trap event */
+ DRM_DEBUG("IH: DMA trap\n");
+ radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
+ break;
+ case 233: /* GUI IDLE */
+ DRM_DEBUG("IH: GUI idle\n");
+ break;
+ case 244: /* DMA trap event */
+ DRM_DEBUG("IH: DMA1 trap\n");
+ radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+ 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;
+ }
+ if (queue_hotplug)
+ taskqueue_enqueue(rdev->tq, &rdev->hotplug_work);
+ rdev->ih.rptr = rptr;
+ WREG32(IH_RB_RPTR, rdev->ih.rptr);
+ atomic_set(&rdev->ih.lock, 0);
+
+ /* make sure wptr hasn't changed while processing */
+ wptr = si_get_ih_wptr(rdev);
+ if (wptr != rptr)
+ goto restart_ih;
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * si_copy_dma - copy pages using the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the DMA engine (SI).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int si_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset, uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence **fence)
+{
+ struct radeon_semaphore *sem = NULL;
+ int ring_index = rdev->asic->copy.dma_ring_index;
+ struct radeon_ring *ring = &rdev->ring[ring_index];
+ u32 size_in_bytes, cur_size_in_bytes;
+ int i, num_loops;
+ int r = 0;
+
+ r = radeon_semaphore_create(rdev, &sem);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ return r;
+ }
+
+ size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
+ num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff);
+ r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11);
+ if (r) {
+ DRM_ERROR("radeon: moving bo (%d).\n", r);
+ radeon_semaphore_free(rdev, &sem, NULL);
+ return r;
+ }
+
+ if (radeon_fence_need_sync(*fence, ring->idx)) {
+ radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+ ring->idx);
+ radeon_fence_note_sync(*fence, ring->idx);
+ } else {
+ radeon_semaphore_free(rdev, &sem, NULL);
+ }
+
+ for (i = 0; i < num_loops; i++) {
+ cur_size_in_bytes = size_in_bytes;
+ if (cur_size_in_bytes > 0xFFFFF)
+ cur_size_in_bytes = 0xFFFFF;
+ size_in_bytes -= cur_size_in_bytes;
+ radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 1, 0, 0, cur_size_in_bytes));
+ radeon_ring_write(ring, dst_offset & 0xffffffff);
+ radeon_ring_write(ring, src_offset & 0xffffffff);
+ radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
+ radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff);
+ src_offset += cur_size_in_bytes;
+ dst_offset += cur_size_in_bytes;
+ }
+
+ r = radeon_fence_emit(rdev, fence, ring->idx);
+ if (r) {
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ radeon_ring_unlock_commit(rdev, ring);
+ radeon_semaphore_free(rdev, &sem, *fence);
+
+ return r;
+}
+
+/*
+ * 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;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
+ return r;
+ }
+
+ r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+ if (r) {
+ dev_err(rdev->dev, "failed initializing DMA 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;
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+ DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
+ DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
+ if (r)
+ return r;
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+ r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
+ DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
+ DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
+ 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
+ if (r)
+ return r;
+
+ r = si_cp_load_microcode(rdev);
+ if (r)
+ return r;
+ r = si_cp_resume(rdev);
+ if (r)
+ return r;
+
+ r = cayman_dma_resume(rdev);
+ if (r)
+ return r;
+
+ r = radeon_ib_pool_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+ return r;
+ }
+
+ r = radeon_vm_manager_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "vm manager initialization failed (%d).\n", 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)
+{
+ si_cp_enable(rdev, false);
+ cayman_dma_stop(rdev);
+ 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;
+
+ /* 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);
+
+ ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 64 * 1024);
+
+ ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 64 * 1024);
+
+ rdev->ih.ring_obj = NULL;
+ r600_ih_ring_init(rdev, 64 * 1024);
+
+ r = r600_pcie_gart_init(rdev);
+ if (r)
+ return r;
+
+ rdev->accel_working = true;
+ r = si_startup(rdev);
+ if (r) {
+ dev_err(rdev->dev, "disabling GPU acceleration\n");
+ si_cp_fini(rdev);
+ cayman_dma_fini(rdev);
+ si_irq_fini(rdev);
+ si_rlc_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_ib_pool_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);
+ cayman_dma_fini(rdev);
+ si_irq_fini(rdev);
+ si_rlc_fini(rdev);
+ radeon_wb_fini(rdev);
+ radeon_vm_manager_fini(rdev);
+ radeon_ib_pool_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ si_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
+ radeon_gem_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_bo_fini(rdev);
+ radeon_atombios_fini(rdev);
+ si_fini_microcode(rdev);
+ free(rdev->bios, DRM_MEM_DRIVER);
+ rdev->bios = NULL;
+}
+
+/**
+ * si_get_gpu_clock - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (SI).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t si_get_gpu_clock(struct radeon_device *rdev)
+{
+ uint64_t clock;
+
+ sx_xlock(&rdev->gpu_clock_mutex);
+ WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+ clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+ ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+ sx_xunlock(&rdev->gpu_clock_mutex);
+ return clock;
+}
diff --git a/sys/dev/drm2/radeon/si_blit_shaders.c b/sys/dev/drm2/radeon/si_blit_shaders.c
new file mode 100644
index 0000000..dc31fe3
--- /dev/null
+++ b/sys/dev/drm2/radeon/si_blit_shaders.c
@@ -0,0 +1,254 @@
+/*
+ * 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 <alexander.deucher@amd.com>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dev/drm2/drmP.h>
+
+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 = DRM_ARRAY_SIZE(si_default_state);
diff --git a/sys/dev/drm2/radeon/si_blit_shaders.h b/sys/dev/drm2/radeon/si_blit_shaders.h
new file mode 100644
index 0000000..0ba0aa8
--- /dev/null
+++ b/sys/dev/drm2/radeon/si_blit_shaders.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+extern const u32 si_default_state[];
+
+extern const u32 si_default_size;
+
+#endif
diff --git a/sys/dev/drm2/radeon/si_reg.h b/sys/dev/drm2/radeon/si_reg.h
new file mode 100644
index 0000000..aa94b66
--- /dev/null
+++ b/sys/dev/drm2/radeon/si_reg.h
@@ -0,0 +1,108 @@
+/*
+ * 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__
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* 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
+
+#define SI_GRPH_CONTROL 0x6804
+# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0)
+# define SI_GRPH_DEPTH_8BPP 0
+# define SI_GRPH_DEPTH_16BPP 1
+# define SI_GRPH_DEPTH_32BPP 2
+# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2)
+# define SI_ADDR_SURF_2_BANK 0
+# define SI_ADDR_SURF_4_BANK 1
+# define SI_ADDR_SURF_8_BANK 2
+# define SI_ADDR_SURF_16_BANK 3
+# define SI_GRPH_Z(x) (((x) & 0x3) << 4)
+# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6)
+# define SI_ADDR_SURF_BANK_WIDTH_1 0
+# define SI_ADDR_SURF_BANK_WIDTH_2 1
+# define SI_ADDR_SURF_BANK_WIDTH_4 2
+# define SI_ADDR_SURF_BANK_WIDTH_8 3
+# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8)
+/* 8 BPP */
+# define SI_GRPH_FORMAT_INDEXED 0
+/* 16 BPP */
+# define SI_GRPH_FORMAT_ARGB1555 0
+# define SI_GRPH_FORMAT_ARGB565 1
+# define SI_GRPH_FORMAT_ARGB4444 2
+# define SI_GRPH_FORMAT_AI88 3
+# define SI_GRPH_FORMAT_MONO16 4
+# define SI_GRPH_FORMAT_BGRA5551 5
+/* 32 BPP */
+# define SI_GRPH_FORMAT_ARGB8888 0
+# define SI_GRPH_FORMAT_ARGB2101010 1
+# define SI_GRPH_FORMAT_32BPP_DIG 2
+# define SI_GRPH_FORMAT_8B_ARGB2101010 3
+# define SI_GRPH_FORMAT_BGRA1010102 4
+# define SI_GRPH_FORMAT_8B_BGRA1010102 5
+# define SI_GRPH_FORMAT_RGB111110 6
+# define SI_GRPH_FORMAT_BGR101111 7
+# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11)
+# define SI_ADDR_SURF_BANK_HEIGHT_1 0
+# define SI_ADDR_SURF_BANK_HEIGHT_2 1
+# define SI_ADDR_SURF_BANK_HEIGHT_4 2
+# define SI_ADDR_SURF_BANK_HEIGHT_8 3
+# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13)
+# define SI_ADDR_SURF_TILE_SPLIT_64B 0
+# define SI_ADDR_SURF_TILE_SPLIT_128B 1
+# define SI_ADDR_SURF_TILE_SPLIT_256B 2
+# define SI_ADDR_SURF_TILE_SPLIT_512B 3
+# define SI_ADDR_SURF_TILE_SPLIT_1KB 4
+# define SI_ADDR_SURF_TILE_SPLIT_2KB 5
+# define SI_ADDR_SURF_TILE_SPLIT_4KB 6
+# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18)
+# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0
+# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1
+# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2
+# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3
+# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20)
+# define SI_GRPH_ARRAY_LINEAR_GENERAL 0
+# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1
+# define SI_GRPH_ARRAY_1D_TILED_THIN1 2
+# define SI_GRPH_ARRAY_2D_TILED_THIN1 4
+# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24)
+# define SI_ADDR_SURF_P2 0
+# define SI_ADDR_SURF_P4_8x16 4
+# define SI_ADDR_SURF_P4_16x16 5
+# define SI_ADDR_SURF_P4_16x32 6
+# define SI_ADDR_SURF_P4_32x32 7
+# define SI_ADDR_SURF_P8_16x16_8x16 8
+# define SI_ADDR_SURF_P8_16x32_8x16 9
+# define SI_ADDR_SURF_P8_32x32_8x16 10
+# define SI_ADDR_SURF_P8_16x32_16x16 11
+# define SI_ADDR_SURF_P8_32x32_16x16 12
+# define SI_ADDR_SURF_P8_32x32_16x32 13
+# define SI_ADDR_SURF_P8_32x64_32x32 14
+
+#endif
diff --git a/sys/dev/drm2/radeon/sid.h b/sys/dev/drm2/radeon/sid.h
new file mode 100644
index 0000000..028916f
--- /dev/null
+++ b/sys/dev/drm2/radeon/sid.h
@@ -0,0 +1,1065 @@
+/*
+ * 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
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define TAHITI_RB_BITMAP_WIDTH_PER_SH 2
+
+#define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003
+#define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002
+
+#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 SRBM_SOFT_RESET 0x0E60
+#define SOFT_RESET_BIF (1 << 1)
+#define SOFT_RESET_DC (1 << 5)
+#define SOFT_RESET_DMA1 (1 << 6)
+#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_ROM (1 << 14)
+#define SOFT_RESET_SEM (1 << 15)
+#define SOFT_RESET_VMC (1 << 17)
+#define SOFT_RESET_DMA (1 << 20)
+#define SOFT_RESET_TST (1 << 21)
+#define SOFT_RESET_REGBB (1 << 22)
+#define SOFT_RESET_ORB (1 << 23)
+
+#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_INTERRUPT (1 << 3)
+#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
+#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 6)
+#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 7)
+#define PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 9)
+#define PDE0_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 10)
+#define VALID_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 12)
+#define VALID_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 13)
+#define READ_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 15)
+#define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16)
+#define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18)
+#define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19)
+#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_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
+#define VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
+
+#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 INSTANCE_INDEX(x) ((x) << 0)
+#define SH_INDEX(x) ((x) << 8)
+#define SE_INDEX(x) ((x) << 16)
+#define SH_BROADCAST_WRITES (1 << 29)
+#define INSTANCE_BROADCAST_WRITES (1 << 30)
+#define SE_BROADCAST_WRITES (1 << 31)
+
+#define GRBM_INT_CNTL 0x8060
+# define RDERR_INT_ENABLE (1 << 0)
+# define GUI_IDLE_INT_ENABLE (1 << 19)
+
+#define CP_STRMOUT_CNTL 0x84FC
+#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 INACTIVE_CUS_MASK 0xFFFF0000
+#define INACTIVE_CUS_SHIFT 16
+#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_GPU_CLOCK_COUNT_LSB 0xC338
+#define RLC_GPU_CLOCK_COUNT_MSB 0xC33C
+#define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340
+#define RLC_MC_CNTL 0xC344
+#define RLC_UCODE_CNTL 0xC348
+
+#define PA_SC_RASTER_CONFIG 0x28350
+# define RASTER_CONFIG_RB_MAP_0 0
+# define RASTER_CONFIG_RB_MAP_1 1
+# define RASTER_CONFIG_RB_MAP_2 2
+# define RASTER_CONFIG_RB_MAP_3 3
+
+#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 WRITE_DATA_DST_SEL(x) ((x) << 8)
+ /* 0 - register
+ * 1 - memory (sync - via GRBM)
+ * 2 - tc/l2
+ * 3 - gds
+ * 4 - reserved
+ * 5 - memory (async - direct)
+ */
+#define WR_ONE_ADDR (1 << 16)
+#define WR_CONFIRM (1 << 20)
+#define WRITE_DATA_ENGINE_SEL(x) ((x) << 30)
+ /* 0 - me
+ * 1 - pfp
+ * 2 - ce
+ */
+#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_CP_DMA 0x41
+/* 1. header
+ * 2. SRC_ADDR_LO or DATA [31:0]
+ * 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] |
+ * SRC_ADDR_HI [7:0]
+ * 4. DST_ADDR_LO [31:0]
+ * 5. DST_ADDR_HI [7:0]
+ * 6. COMMAND [30:21] | BYTE_COUNT [20:0]
+ */
+# define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20)
+ /* 0 - SRC_ADDR
+ * 1 - GDS
+ */
+# define PACKET3_CP_DMA_ENGINE(x) ((x) << 27)
+ /* 0 - ME
+ * 1 - PFP
+ */
+# define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29)
+ /* 0 - SRC_ADDR
+ * 1 - GDS
+ * 2 - DATA
+ */
+# define PACKET3_CP_DMA_CP_SYNC (1 << 31)
+/* COMMAND */
+# define PACKET3_CP_DMA_DIS_WC (1 << 21)
+# define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
+ /* 0 - none
+ * 1 - 8 in 16
+ * 2 - 8 in 32
+ * 3 - 8 in 64
+ */
+# define PACKET3_CP_DMA_CMD_SAS (1 << 26)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_DAS (1 << 27)
+ /* 0 - memory
+ * 1 - register
+ */
+# define PACKET3_CP_DMA_CMD_SAIC (1 << 28)
+# define PACKET3_CP_DMA_CMD_DAIC (1 << 29)
+# define PACKET3_CP_DMA_CMD_RAW_WAIT (1 << 30)
+#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
+#define PACKET3_SWITCH_BUFFER 0x8B
+
+/* ASYNC DMA - first instance at 0xd000, second at 0xd800 */
+#define DMA0_REGISTER_OFFSET 0x0 /* not a register */
+#define DMA1_REGISTER_OFFSET 0x800 /* not a register */
+
+#define DMA_RB_CNTL 0xd000
+# define DMA_RB_ENABLE (1 << 0)
+# define DMA_RB_SIZE(x) ((x) << 1) /* log2 */
+# define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_ENABLE (1 << 12)
+# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */
+# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
+#define DMA_RB_BASE 0xd004
+#define DMA_RB_RPTR 0xd008
+#define DMA_RB_WPTR 0xd00c
+
+#define DMA_RB_RPTR_ADDR_HI 0xd01c
+#define DMA_RB_RPTR_ADDR_LO 0xd020
+
+#define DMA_IB_CNTL 0xd024
+# define DMA_IB_ENABLE (1 << 0)
+# define DMA_IB_SWAP_ENABLE (1 << 4)
+#define DMA_IB_RPTR 0xd028
+#define DMA_CNTL 0xd02c
+# define TRAP_ENABLE (1 << 0)
+# define SEM_INCOMPLETE_INT_ENABLE (1 << 1)
+# define SEM_WAIT_INT_ENABLE (1 << 2)
+# define DATA_SWAP_ENABLE (1 << 3)
+# define FENCE_SWAP_ENABLE (1 << 4)
+# define CTXEMPTY_INT_ENABLE (1 << 28)
+#define DMA_STATUS_REG 0xd034
+# define DMA_IDLE (1 << 0)
+#define DMA_TILING_CONFIG 0xd0b8
+
+#define DMA_PACKET(cmd, b, t, s, n) ((((cmd) & 0xF) << 28) | \
+ (((b) & 0x1) << 26) | \
+ (((t) & 0x1) << 23) | \
+ (((s) & 0x1) << 22) | \
+ (((n) & 0xFFFFF) << 0))
+
+#define DMA_IB_PACKET(cmd, vmid, n) ((((cmd) & 0xF) << 28) | \
+ (((vmid) & 0xF) << 20) | \
+ (((n) & 0xFFFFF) << 0))
+
+#define DMA_PTE_PDE_PACKET(n) ((2 << 28) | \
+ (1 << 26) | \
+ (1 << 21) | \
+ (((n) & 0xFFFFF) << 0))
+
+/* async DMA Packet types */
+#define DMA_PACKET_WRITE 0x2
+#define DMA_PACKET_COPY 0x3
+#define DMA_PACKET_INDIRECT_BUFFER 0x4
+#define DMA_PACKET_SEMAPHORE 0x5
+#define DMA_PACKET_FENCE 0x6
+#define DMA_PACKET_TRAP 0x7
+#define DMA_PACKET_SRBM_WRITE 0x9
+#define DMA_PACKET_CONSTANT_FILL 0xd
+#define DMA_PACKET_NOP 0xf
+
+#endif
diff --git a/sys/modules/drm2/Makefile b/sys/modules/drm2/Makefile
index f8411e3..02e35ea 100644
--- a/sys/modules/drm2/Makefile
+++ b/sys/modules/drm2/Makefile
@@ -2,8 +2,14 @@
.include <bsd.own.mk>
+.if ${MK_SOURCELESS_UCODE} != "no"
+_radeonkmsfw= radeonkmsfw
+.endif
+
SUBDIR = \
drm2 \
- i915kms
+ i915kms \
+ radeonkms \
+ ${_radeonkmsfw}
.include <bsd.subdir.mk>
diff --git a/sys/modules/drm2/drm2/Makefile b/sys/modules/drm2/drm2/Makefile
index 9105c78..acb2d33 100644
--- a/sys/modules/drm2/drm2/Makefile
+++ b/sys/modules/drm2/drm2/Makefile
@@ -44,7 +44,8 @@ SRCS = \
ttm_execbuf_util.c \
ttm_memory.c \
ttm_page_alloc.c \
- ttm_bo_vm.c
+ ttm_bo_vm.c \
+ ati_pcigart.c
#ttm_agp_backend.c
#ttm_page_alloc_dma.c
diff --git a/sys/modules/drm2/radeonkms/Makefile b/sys/modules/drm2/radeonkms/Makefile
new file mode 100644
index 0000000..f8468f6
--- /dev/null
+++ b/sys/modules/drm2/radeonkms/Makefile
@@ -0,0 +1,107 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../dev/drm2/radeon
+
+KMOD = radeonkms
+SRCS = \
+ 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
+SRCS += \
+ radeon_acpi.c \
+ radeon_agp.c \
+ radeon_asic.c \
+ radeon_atombios.c \
+ radeon_atpx_handler.c \
+ radeon_benchmark.c \
+ radeon_bios.c \
+ radeon_clocks.c \
+ radeon_combios.c \
+ radeon_connectors.c \
+ radeon_cp.c \
+ radeon_cs.c \
+ radeon_cursor.c \
+ radeon_device.c \
+ radeon_display.c \
+ radeon_drv.c \
+ radeon_encoders.c \
+ radeon_fb.c \
+ radeon_fence.c \
+ radeon_gart.c \
+ radeon_gem.c \
+ radeon_i2c.c \
+ radeon_irq.c \
+ radeon_irq_kms.c \
+ radeon_kms.c \
+ radeon_legacy_crtc.c \
+ radeon_legacy_encoders.c \
+ radeon_legacy_tv.c \
+ radeon_mem.c \
+ radeon_object.c \
+ radeon_pm.c \
+ radeon_ring.c \
+ radeon_sa.c \
+ radeon_semaphore.c \
+ radeon_state.c \
+ radeon_test.c \
+ radeon_ttm.c \
+ atom.c \
+ atombios_crtc.c \
+ atombios_dp.c \
+ atombios_encoders.c \
+ atombios_i2c.c \
+ r100.c \
+ r200.c \
+ r300.c \
+ r300_cmdbuf.c \
+ r420.c \
+ rs400.c \
+ rs600.c \
+ rs690.c \
+ rv515.c \
+ r520.c \
+ r600.c \
+ r600_audio.c \
+ r600_blit.c \
+ r600_blit_kms.c \
+ r600_blit_shaders.c \
+ r600_cp.c \
+ r600_cs.c \
+ r600_hdmi.c \
+ rv770.c \
+ evergreen.c \
+ evergreen_blit_kms.c \
+ evergreen_blit_shaders.c \
+ evergreen_cs.c \
+ evergreen_hdmi.c \
+ cayman_blit_shaders.c \
+ ni.c \
+ si.c \
+ si_blit_shaders.c
+
+#radeon_ioc32.c
+#radeon_prime.c
+#--radeon_trace_points.c
+
+SRCS += \
+ opt_acpi.h \
+ opt_compat.h \
+ opt_drm.h \
+ acpi_if.h \
+ bus_if.h \
+ device_if.h \
+ iicbb_if.h \
+ iicbus_if.h \
+ pci_if.h
+
+CFLAGS += -I${.CURDIR}/../../../dev/drm2/radeon \
+ -fms-extensions
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/ARUBA_me/Makefile b/sys/modules/drm2/radeonkmsfw/ARUBA_me/Makefile
new file mode 100644
index 0000000..a73cf06
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/ARUBA_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_ARUBA_me
+IMG= ARUBA_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/ARUBA_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/ARUBA_pfp/Makefile
new file mode 100644
index 0000000..83c2d21
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/ARUBA_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_ARUBA_pfp
+IMG= ARUBA_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/ARUBA_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/ARUBA_rlc/Makefile
new file mode 100644
index 0000000..95cafc2
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/ARUBA_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_ARUBA_rlc
+IMG= ARUBA_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/BARTS_mc/Makefile b/sys/modules/drm2/radeonkmsfw/BARTS_mc/Makefile
new file mode 100644
index 0000000..d8c530a
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/BARTS_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_BARTS_mc
+IMG= BARTS_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/BARTS_me/Makefile b/sys/modules/drm2/radeonkmsfw/BARTS_me/Makefile
new file mode 100644
index 0000000..86da688
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/BARTS_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_BARTS_me
+IMG= BARTS_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/BARTS_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/BARTS_pfp/Makefile
new file mode 100644
index 0000000..690cd32
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/BARTS_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_BARTS_pfp
+IMG= BARTS_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/BTC_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/BTC_rlc/Makefile
new file mode 100644
index 0000000..900a2e9
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/BTC_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_BTC_rlc
+IMG= BTC_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAICOS_mc/Makefile b/sys/modules/drm2/radeonkmsfw/CAICOS_mc/Makefile
new file mode 100644
index 0000000..9b0fe66
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAICOS_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAICOS_mc
+IMG= CAICOS_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAICOS_me/Makefile b/sys/modules/drm2/radeonkmsfw/CAICOS_me/Makefile
new file mode 100644
index 0000000..c3a167e
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAICOS_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAICOS_me
+IMG= CAICOS_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAICOS_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/CAICOS_pfp/Makefile
new file mode 100644
index 0000000..bbee7aa
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAICOS_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAICOS_pfp
+IMG= CAICOS_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAYMAN_mc/Makefile b/sys/modules/drm2/radeonkmsfw/CAYMAN_mc/Makefile
new file mode 100644
index 0000000..98a4a9a
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAYMAN_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAYMAN_mc
+IMG= CAYMAN_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAYMAN_me/Makefile b/sys/modules/drm2/radeonkmsfw/CAYMAN_me/Makefile
new file mode 100644
index 0000000..8f2c708
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAYMAN_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAYMAN_me
+IMG= CAYMAN_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAYMAN_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/CAYMAN_pfp/Makefile
new file mode 100644
index 0000000..6c9adfa
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAYMAN_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAYMAN_pfp
+IMG= CAYMAN_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CAYMAN_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/CAYMAN_rlc/Makefile
new file mode 100644
index 0000000..9f8fc80
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CAYMAN_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CAYMAN_rlc
+IMG= CAYMAN_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CEDAR_me/Makefile b/sys/modules/drm2/radeonkmsfw/CEDAR_me/Makefile
new file mode 100644
index 0000000..d693d79
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CEDAR_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CEDAR_me
+IMG= CEDAR_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CEDAR_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/CEDAR_pfp/Makefile
new file mode 100644
index 0000000..cef6073
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CEDAR_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CEDAR_pfp
+IMG= CEDAR_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CEDAR_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/CEDAR_rlc/Makefile
new file mode 100644
index 0000000..d316e46
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CEDAR_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CEDAR_rlc
+IMG= CEDAR_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CYPRESS_me/Makefile b/sys/modules/drm2/radeonkmsfw/CYPRESS_me/Makefile
new file mode 100644
index 0000000..78fe6c6
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CYPRESS_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CYPRESS_me
+IMG= CYPRESS_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CYPRESS_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/CYPRESS_pfp/Makefile
new file mode 100644
index 0000000..7b3a6aa
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CYPRESS_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CYPRESS_pfp
+IMG= CYPRESS_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CYPRESS_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/CYPRESS_rlc/Makefile
new file mode 100644
index 0000000..a8475b0
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CYPRESS_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CYPRESS_rlc
+IMG= CYPRESS_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/CYPRESS_uvd/Makefile b/sys/modules/drm2/radeonkmsfw/CYPRESS_uvd/Makefile
new file mode 100644
index 0000000..3779a09
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/CYPRESS_uvd/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_CYPRESS_uvd
+IMG= CYPRESS_uvd
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/HAINAN_ce/Makefile b/sys/modules/drm2/radeonkmsfw/HAINAN_ce/Makefile
new file mode 100644
index 0000000..1aad7cf
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/HAINAN_ce/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_HAINAN_ce
+IMG= HAINAN_ce
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/HAINAN_mc/Makefile b/sys/modules/drm2/radeonkmsfw/HAINAN_mc/Makefile
new file mode 100644
index 0000000..54727af
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/HAINAN_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_HAINAN_mc
+IMG= HAINAN_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/HAINAN_me/Makefile b/sys/modules/drm2/radeonkmsfw/HAINAN_me/Makefile
new file mode 100644
index 0000000..6d065c0
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/HAINAN_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_HAINAN_me
+IMG= HAINAN_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/HAINAN_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/HAINAN_pfp/Makefile
new file mode 100644
index 0000000..ccf8834
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/HAINAN_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_HAINAN_pfp
+IMG= HAINAN_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/HAINAN_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/HAINAN_rlc/Makefile
new file mode 100644
index 0000000..a930fe0
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/HAINAN_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_HAINAN_rlc
+IMG= HAINAN_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/JUNIPER_me/Makefile b/sys/modules/drm2/radeonkmsfw/JUNIPER_me/Makefile
new file mode 100644
index 0000000..1d10e66
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/JUNIPER_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_JUNIPER_me
+IMG= JUNIPER_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/JUNIPER_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/JUNIPER_pfp/Makefile
new file mode 100644
index 0000000..ef53b1b
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/JUNIPER_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_JUNIPER_pfp
+IMG= JUNIPER_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/JUNIPER_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/JUNIPER_rlc/Makefile
new file mode 100644
index 0000000..3fa7388
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/JUNIPER_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_JUNIPER_rlc
+IMG= JUNIPER_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/Makefile b/sys/modules/drm2/radeonkmsfw/Makefile
new file mode 100644
index 0000000..167743c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/Makefile
@@ -0,0 +1,85 @@
+# $FreeBSD$
+
+SUBDIR= \
+ ARUBA_me \
+ ARUBA_pfp \
+ ARUBA_rlc \
+ BARTS_mc \
+ BARTS_me \
+ BARTS_pfp \
+ BTC_rlc \
+ CAICOS_mc \
+ CAICOS_me \
+ CAICOS_pfp \
+ CAYMAN_mc \
+ CAYMAN_me \
+ CAYMAN_pfp \
+ CAYMAN_rlc \
+ CEDAR_me \
+ CEDAR_pfp \
+ CEDAR_rlc \
+ CYPRESS_me \
+ CYPRESS_pfp \
+ CYPRESS_rlc \
+ JUNIPER_me \
+ JUNIPER_pfp \
+ JUNIPER_rlc \
+ PALM_me \
+ PALM_pfp \
+ PITCAIRN_ce \
+ PITCAIRN_mc \
+ PITCAIRN_me \
+ PITCAIRN_pfp \
+ PITCAIRN_rlc \
+ R100_cp \
+ R200_cp \
+ R300_cp \
+ R420_cp \
+ R520_cp \
+ R600_me \
+ R600_pfp \
+ R600_rlc \
+ R700_rlc \
+ REDWOOD_me \
+ REDWOOD_pfp \
+ REDWOOD_rlc \
+ RS600_cp \
+ RS690_cp \
+ RS780_me \
+ RS780_pfp \
+ RV610_me \
+ RV610_pfp \
+ RV620_me \
+ RV620_pfp \
+ RV630_me \
+ RV630_pfp \
+ RV635_me \
+ RV635_pfp \
+ RV670_me \
+ RV670_pfp \
+ RV710_me \
+ RV710_pfp \
+ RV730_me \
+ RV730_pfp \
+ RV770_me \
+ RV770_pfp \
+ SUMO2_me \
+ SUMO2_pfp \
+ SUMO_me \
+ SUMO_pfp \
+ SUMO_rlc \
+ TAHITI_ce \
+ TAHITI_mc \
+ TAHITI_me \
+ TAHITI_pfp \
+ TAHITI_rlc \
+ TURKS_mc \
+ TURKS_me \
+ TURKS_pfp \
+ VERDE_ce \
+ VERDE_mc \
+ VERDE_me \
+ VERDE_pfp \
+ VERDE_rlc
+
+.include <bsd.subdir.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/Makefile.inc b/sys/modules/drm2/radeonkmsfw/Makefile.inc
new file mode 100644
index 0000000..f6035a1
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/Makefile.inc
@@ -0,0 +1,18 @@
+# $FreeBSD$
+#
+# Common rules for building firmware. Note this gets auto-included
+# by the subdir Makefile's as a consequence of included bsd.kmod.mk.
+
+_FIRM= ${IMG}.bin
+
+CLEANFILES+= ${_FIRM}
+
+FIRMWS= ${_FIRM}:${KMOD}
+
+#
+# Note that a license ack is not needed for iwn.
+#
+#FIRMWARE_LICENSE=
+
+${_FIRM}: ${.CURDIR}/../../../../contrib/dev/drm2/radeonkmsfw/${_FIRM}.uu
+ uudecode -p $? > ${.TARGET}
diff --git a/sys/modules/drm2/radeonkmsfw/OLAND_ce/Makefile b/sys/modules/drm2/radeonkmsfw/OLAND_ce/Makefile
new file mode 100644
index 0000000..0de1de4
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/OLAND_ce/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_OLAND_ce
+IMG= OLAND_ce
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/OLAND_mc/Makefile b/sys/modules/drm2/radeonkmsfw/OLAND_mc/Makefile
new file mode 100644
index 0000000..161bfc0
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/OLAND_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_OLAND_mc
+IMG= OLAND_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/OLAND_me/Makefile b/sys/modules/drm2/radeonkmsfw/OLAND_me/Makefile
new file mode 100644
index 0000000..fbe07cb
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/OLAND_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_OLAND_me
+IMG= OLAND_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/OLAND_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/OLAND_pfp/Makefile
new file mode 100644
index 0000000..193d753
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/OLAND_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_OLAND_pfp
+IMG= OLAND_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/OLAND_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/OLAND_rlc/Makefile
new file mode 100644
index 0000000..2490b34
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/OLAND_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_OLAND_rlc
+IMG= OLAND_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PALM_me/Makefile b/sys/modules/drm2/radeonkmsfw/PALM_me/Makefile
new file mode 100644
index 0000000..f73e1b8
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PALM_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PALM_me
+IMG= PALM_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PALM_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/PALM_pfp/Makefile
new file mode 100644
index 0000000..2e5b2e6
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PALM_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PALM_pfp
+IMG= PALM_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PITCAIRN_ce/Makefile b/sys/modules/drm2/radeonkmsfw/PITCAIRN_ce/Makefile
new file mode 100644
index 0000000..101d9a4
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PITCAIRN_ce/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PITCAIRN_ce
+IMG= PITCAIRN_ce
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PITCAIRN_mc/Makefile b/sys/modules/drm2/radeonkmsfw/PITCAIRN_mc/Makefile
new file mode 100644
index 0000000..f1a86924
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PITCAIRN_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PITCAIRN_mc
+IMG= PITCAIRN_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PITCAIRN_me/Makefile b/sys/modules/drm2/radeonkmsfw/PITCAIRN_me/Makefile
new file mode 100644
index 0000000..b41d40f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PITCAIRN_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PITCAIRN_me
+IMG= PITCAIRN_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PITCAIRN_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/PITCAIRN_pfp/Makefile
new file mode 100644
index 0000000..d60d8b1
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PITCAIRN_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PITCAIRN_pfp
+IMG= PITCAIRN_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/PITCAIRN_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/PITCAIRN_rlc/Makefile
new file mode 100644
index 0000000..ff9d7c7
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/PITCAIRN_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_PITCAIRN_rlc
+IMG= PITCAIRN_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R100_cp/Makefile b/sys/modules/drm2/radeonkmsfw/R100_cp/Makefile
new file mode 100644
index 0000000..f5407dd
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R100_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R100_cp
+IMG= R100_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R200_cp/Makefile b/sys/modules/drm2/radeonkmsfw/R200_cp/Makefile
new file mode 100644
index 0000000..bdfc803
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R200_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R200_cp
+IMG= R200_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R300_cp/Makefile b/sys/modules/drm2/radeonkmsfw/R300_cp/Makefile
new file mode 100644
index 0000000..41e984b
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R300_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R300_cp
+IMG= R300_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R420_cp/Makefile b/sys/modules/drm2/radeonkmsfw/R420_cp/Makefile
new file mode 100644
index 0000000..18e6788
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R420_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R420_cp
+IMG= R420_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R520_cp/Makefile b/sys/modules/drm2/radeonkmsfw/R520_cp/Makefile
new file mode 100644
index 0000000..484283d
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R520_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R520_cp
+IMG= R520_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R600_me/Makefile b/sys/modules/drm2/radeonkmsfw/R600_me/Makefile
new file mode 100644
index 0000000..e42d1cd
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R600_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R600_me
+IMG= R600_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R600_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/R600_pfp/Makefile
new file mode 100644
index 0000000..0cd74c6
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R600_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R600_pfp
+IMG= R600_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R600_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/R600_rlc/Makefile
new file mode 100644
index 0000000..6cb5acf
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R600_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R600_rlc
+IMG= R600_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/R700_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/R700_rlc/Makefile
new file mode 100644
index 0000000..c6853f1
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/R700_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_R700_rlc
+IMG= R700_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/REDWOOD_me/Makefile b/sys/modules/drm2/radeonkmsfw/REDWOOD_me/Makefile
new file mode 100644
index 0000000..84019ba
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/REDWOOD_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_REDWOOD_me
+IMG= REDWOOD_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/REDWOOD_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/REDWOOD_pfp/Makefile
new file mode 100644
index 0000000..f175171
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/REDWOOD_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_REDWOOD_pfp
+IMG= REDWOOD_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/REDWOOD_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/REDWOOD_rlc/Makefile
new file mode 100644
index 0000000..2727422
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/REDWOOD_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_REDWOOD_rlc
+IMG= REDWOOD_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RS600_cp/Makefile b/sys/modules/drm2/radeonkmsfw/RS600_cp/Makefile
new file mode 100644
index 0000000..d33f0e3
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RS600_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RS600_cp
+IMG= RS600_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RS690_cp/Makefile b/sys/modules/drm2/radeonkmsfw/RS690_cp/Makefile
new file mode 100644
index 0000000..e295ced
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RS690_cp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RS690_cp
+IMG= RS690_cp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RS780_me/Makefile b/sys/modules/drm2/radeonkmsfw/RS780_me/Makefile
new file mode 100644
index 0000000..413bf58
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RS780_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RS780_me
+IMG= RS780_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RS780_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RS780_pfp/Makefile
new file mode 100644
index 0000000..c6eb278
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RS780_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RS780_pfp
+IMG= RS780_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV610_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV610_me/Makefile
new file mode 100644
index 0000000..c44f841
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV610_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV610_me
+IMG= RV610_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV610_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV610_pfp/Makefile
new file mode 100644
index 0000000..e6419fd
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV610_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV610_pfp
+IMG= RV610_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV620_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV620_me/Makefile
new file mode 100644
index 0000000..997e913
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV620_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV620_me
+IMG= RV620_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV620_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV620_pfp/Makefile
new file mode 100644
index 0000000..476e486
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV620_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV620_pfp
+IMG= RV620_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV630_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV630_me/Makefile
new file mode 100644
index 0000000..0807570c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV630_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV630_me
+IMG= RV630_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV630_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV630_pfp/Makefile
new file mode 100644
index 0000000..38c66dc
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV630_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV630_pfp
+IMG= RV630_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV635_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV635_me/Makefile
new file mode 100644
index 0000000..440508e
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV635_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV635_me
+IMG= RV635_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV635_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV635_pfp/Makefile
new file mode 100644
index 0000000..01fc97b
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV635_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV635_pfp
+IMG= RV635_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV670_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV670_me/Makefile
new file mode 100644
index 0000000..3c13ed1
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV670_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV670_me
+IMG= RV670_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV670_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV670_pfp/Makefile
new file mode 100644
index 0000000..50aee8d
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV670_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV670_pfp
+IMG= RV670_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV710_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV710_me/Makefile
new file mode 100644
index 0000000..f42c7ad
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV710_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV710_me
+IMG= RV710_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV710_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV710_pfp/Makefile
new file mode 100644
index 0000000..5acaf3f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV710_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV710_pfp
+IMG= RV710_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV710_uvd/Makefile b/sys/modules/drm2/radeonkmsfw/RV710_uvd/Makefile
new file mode 100644
index 0000000..8146bc2
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV710_uvd/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV710_uvd
+IMG= RV710_uvd
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV730_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV730_me/Makefile
new file mode 100644
index 0000000..9a0907d
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV730_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV730_me
+IMG= RV730_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV730_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV730_pfp/Makefile
new file mode 100644
index 0000000..0ecb70c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV730_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV730_pfp
+IMG= RV730_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV770_me/Makefile b/sys/modules/drm2/radeonkmsfw/RV770_me/Makefile
new file mode 100644
index 0000000..85852a1
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV770_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV770_me
+IMG= RV770_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/RV770_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/RV770_pfp/Makefile
new file mode 100644
index 0000000..2eebdfa
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/RV770_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_RV770_pfp
+IMG= RV770_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO2_me/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO2_me/Makefile
new file mode 100644
index 0000000..2d6091f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO2_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO2_me
+IMG= SUMO2_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO2_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO2_pfp/Makefile
new file mode 100644
index 0000000..2b99a5f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO2_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO2_pfp
+IMG= SUMO2_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO_me/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO_me/Makefile
new file mode 100644
index 0000000..e050d3e
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO_me
+IMG= SUMO_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO_pfp/Makefile
new file mode 100644
index 0000000..2fc1ac2
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO_pfp
+IMG= SUMO_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO_rlc/Makefile
new file mode 100644
index 0000000..4864b1f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO_rlc
+IMG= SUMO_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/SUMO_uvd/Makefile b/sys/modules/drm2/radeonkmsfw/SUMO_uvd/Makefile
new file mode 100644
index 0000000..694b226
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/SUMO_uvd/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_SUMO_uvd
+IMG= SUMO_uvd
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_ce/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_ce/Makefile
new file mode 100644
index 0000000..8b75706
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_ce/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_ce
+IMG= TAHITI_ce
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_mc/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_mc/Makefile
new file mode 100644
index 0000000..af9227f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_mc
+IMG= TAHITI_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_me/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_me/Makefile
new file mode 100644
index 0000000..b6da4a9
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_me
+IMG= TAHITI_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_pfp/Makefile
new file mode 100644
index 0000000..0c5322d
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_pfp
+IMG= TAHITI_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_rlc/Makefile
new file mode 100644
index 0000000..8af425f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_rlc
+IMG= TAHITI_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TAHITI_uvd/Makefile b/sys/modules/drm2/radeonkmsfw/TAHITI_uvd/Makefile
new file mode 100644
index 0000000..89834bf
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TAHITI_uvd/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TAHITI_uvd
+IMG= TAHITI_uvd
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TURKS_mc/Makefile b/sys/modules/drm2/radeonkmsfw/TURKS_mc/Makefile
new file mode 100644
index 0000000..b317c78
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TURKS_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TURKS_mc
+IMG= TURKS_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TURKS_me/Makefile b/sys/modules/drm2/radeonkmsfw/TURKS_me/Makefile
new file mode 100644
index 0000000..e7c616c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TURKS_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TURKS_me
+IMG= TURKS_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/TURKS_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/TURKS_pfp/Makefile
new file mode 100644
index 0000000..e42ce25
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/TURKS_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_TURKS_pfp
+IMG= TURKS_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/VERDE_ce/Makefile b/sys/modules/drm2/radeonkmsfw/VERDE_ce/Makefile
new file mode 100644
index 0000000..d3b471f
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/VERDE_ce/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_VERDE_ce
+IMG= VERDE_ce
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/VERDE_mc/Makefile b/sys/modules/drm2/radeonkmsfw/VERDE_mc/Makefile
new file mode 100644
index 0000000..0f1b57c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/VERDE_mc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_VERDE_mc
+IMG= VERDE_mc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/VERDE_me/Makefile b/sys/modules/drm2/radeonkmsfw/VERDE_me/Makefile
new file mode 100644
index 0000000..a039c19
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/VERDE_me/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_VERDE_me
+IMG= VERDE_me
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/VERDE_pfp/Makefile b/sys/modules/drm2/radeonkmsfw/VERDE_pfp/Makefile
new file mode 100644
index 0000000..4e73c0c
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/VERDE_pfp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_VERDE_pfp
+IMG= VERDE_pfp
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/VERDE_rlc/Makefile b/sys/modules/drm2/radeonkmsfw/VERDE_rlc/Makefile
new file mode 100644
index 0000000..a2e882a
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/VERDE_rlc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= radeonkmsfw_VERDE_rlc
+IMG= VERDE_rlc
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/drm2/radeonkmsfw/gen-makefiles b/sys/modules/drm2/radeonkmsfw/gen-makefiles
new file mode 100755
index 0000000..4c364a7
--- /dev/null
+++ b/sys/modules/drm2/radeonkmsfw/gen-makefiles
@@ -0,0 +1,30 @@
+#!/bin/sh
+# $FreeBSD$
+
+set -e
+
+scriptdir=$(cd $(dirname $0) && pwd)
+fwdir=$scriptdir/../../../contrib/dev/drm2/radeonkmsfw
+
+for dir in $scriptdir/*; do
+ if [ ! -d $dir ]; then
+ continue
+ fi
+ rm -rf $dir
+done
+
+for file in $fwdir/*.uu; do
+ img=$(basename $file)
+ img=${img%.bin.uu}
+ echo "Image: $img"
+
+ mkdir -p $scriptdir/$img
+ cat > $scriptdir/$img/Makefile <<EOF
+# \$FreeBSD$
+
+KMOD= radeonkmsfw_$img
+IMG= $img
+
+.include <bsd.kmod.mk>
+EOF
+done
OpenPOWER on IntegriCloud