aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/core.c19
-rw-r--r--drivers/base/devtmpfs.c24
-rw-r--r--drivers/block/aoe/aoechr.c4
-rw-r--r--drivers/block/pktcdvd.c6
-rw-r--r--drivers/char/cyclades.c2311
-rw-r--r--drivers/char/esp.c7
-rw-r--r--drivers/char/hw_random/core.c2
-rw-r--r--drivers/char/isicom.c57
-rw-r--r--drivers/char/mem.c29
-rw-r--r--drivers/char/misc.c10
-rw-r--r--drivers/char/mxser.c62
-rw-r--r--drivers/char/n_tty.c79
-rw-r--r--drivers/char/raw.c4
-rw-r--r--drivers/char/riscom8.c164
-rw-r--r--drivers/char/tty_io.c33
-rw-r--r--drivers/char/tty_ioctl.c4
-rw-r--r--drivers/char/tty_ldisc.c82
-rw-r--r--drivers/char/tty_port.c31
-rw-r--r--drivers/char/vt.c14
-rw-r--r--drivers/char/vt_ioctl.c482
-rw-r--r--drivers/cpuidle/cpuidle.c2
-rw-r--r--drivers/gpu/drm/Kconfig18
-rw-r--r--drivers/gpu/drm/Makefile8
-rw-r--r--drivers/gpu/drm/drm_bufs.c4
-rw-r--r--drivers/gpu/drm/drm_cache.c46
-rw-r--r--drivers/gpu/drm/drm_crtc.c77
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c223
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_edid.c504
-rw-r--r--drivers/gpu/drm/drm_encoder_slave.c116
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c707
-rw-r--r--drivers/gpu/drm/drm_gem.c11
-rw-r--r--drivers/gpu/drm/drm_irq.c27
-rw-r--r--drivers/gpu/drm/drm_mm.c21
-rw-r--r--drivers/gpu/drm/drm_modes.c435
-rw-r--r--drivers/gpu/drm/drm_proc.c17
-rw-r--r--drivers/gpu/drm/drm_sysfs.c32
-rw-r--r--drivers/gpu/drm/i915/Makefile2
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c (renamed from drivers/gpu/drm/i915/i915_gem_debugfs.c)91
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c120
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c9
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h63
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c14
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c80
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c21
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h144
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c4
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c8
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c28
-rw-r--r--drivers/gpu/drm/i915/intel_display.c624
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h8
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c737
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c8
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c22
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c331
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c30
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c4
-rw-r--r--drivers/gpu/drm/mga/mga_drv.h1
-rw-r--r--drivers/gpu/drm/mga/mga_ucode.h11645
-rw-r--r--drivers/gpu/drm/mga/mga_warp.c180
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c116
-rw-r--r--drivers/gpu/drm/r128/r128_drv.h8
-rw-r--r--drivers/gpu/drm/r128/r128_state.c36
-rw-r--r--drivers/gpu/drm/radeon/Kconfig1
-rw-r--r--drivers/gpu/drm/radeon/Makefile43
-rw-r--r--drivers/gpu/drm/radeon/atombios.h11
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c105
-rw-r--r--drivers/gpu/drm/radeon/avivod.h69
-rw-r--r--drivers/gpu/drm/radeon/mkregtable.c720
-rw-r--r--drivers/gpu/drm/radeon/r100.c1232
-rw-r--r--drivers/gpu/drm/radeon/r100_track.h124
-rw-r--r--drivers/gpu/drm/radeon/r100d.h607
-rw-r--r--drivers/gpu/drm/radeon/r200.c456
-rw-r--r--drivers/gpu/drm/radeon/r300.c556
-rw-r--r--drivers/gpu/drm/radeon/r300.h36
-rw-r--r--drivers/gpu/drm/radeon/r300d.h101
-rw-r--r--drivers/gpu/drm/radeon/r420.c301
-rw-r--r--drivers/gpu/drm/radeon/r420d.h249
-rw-r--r--drivers/gpu/drm/radeon/r520.c6
-rw-r--r--drivers/gpu/drm/radeon/r600.c1802
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c850
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c805
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_shaders.c1072
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_shaders.h14
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c541
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c657
-rw-r--r--drivers/gpu/drm/radeon/r600_microcode.h23297
-rw-r--r--drivers/gpu/drm/radeon/r600d.h662
-rw-r--r--drivers/gpu/drm/radeon/radeon.h269
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h240
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c171
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c58
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c480
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c151
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c423
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c101
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h151
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c137
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c674
-rw-r--r--drivers/gpu/drm/radeon/radeon_fence.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_ioc32.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c85
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c368
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_tv.c904
-rw-r--r--drivers/gpu/drm/radeon/radeon_microcode.h1844
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h74
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_reg.h79
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c143
-rw-r--r--drivers/gpu/drm/radeon/radeon_share.h39
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c96
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r100105
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r200184
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r300729
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rn5030
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rs600729
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/rv515486
-rw-r--r--drivers/gpu/drm/radeon/rs400.c56
-rw-r--r--drivers/gpu/drm/radeon/rs600.c106
-rw-r--r--drivers/gpu/drm/radeon/rs690.c4
-rw-r--r--drivers/gpu/drm/radeon/rs780.c102
-rw-r--r--drivers/gpu/drm/radeon/rv515.c524
-rw-r--r--drivers/gpu/drm/radeon/rv515d.h (renamed from drivers/gpu/drm/radeon/rv515r.h)56
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1050
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h341
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c295
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_global.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_memory.c508
-rw-r--r--drivers/gpu/drm/ttm/ttm_module.c58
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c104
-rw-r--r--drivers/hid/usbhid/hiddev.c4
-rw-r--r--drivers/i2c/busses/i2c-imx.c3
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c4
-rw-r--r--drivers/input/input.c4
-rw-r--r--drivers/isdn/gigaset/interface.c19
-rw-r--r--drivers/md/dm-ioctl.c2
-rw-r--r--drivers/media/common/tuners/tda18271-common.c3
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c83
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c3
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h1
-rw-r--r--drivers/media/common/tuners/tda18271.h14
-rw-r--r--drivers/media/common/tuners/tuner-types.c27
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c218
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h17
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig9
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c50
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c14
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c501
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c483
-rw-r--r--drivers/media/dvb/dvb-usb/friio.c525
-rw-r--r--drivers/media/dvb/dvb-usb/friio.h99
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c5
-rw-r--r--drivers/media/dvb/frontends/dib0070.c803
-rw-r--r--drivers/media/dvb/frontends/dib0070.h30
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c33
-rw-r--r--drivers/media/dvb/frontends/dib8000.c2277
-rw-r--r--drivers/media/dvb/frontends/dib8000.h79
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c95
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h31
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c2
-rw-r--r--drivers/media/dvb/frontends/s921_module.c2
-rw-r--r--drivers/media/dvb/pt1/Kconfig12
-rw-r--r--drivers/media/dvb/pt1/Makefile5
-rw-r--r--drivers/media/dvb/pt1/pt1.c1056
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.c658
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.h40
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.c468
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.h40
-rw-r--r--drivers/media/radio/Kconfig2
-rw-r--r--drivers/media/radio/radio-si4713.c1
-rw-r--r--drivers/media/video/Kconfig93
-rw-r--r--drivers/media/video/Makefile6
-rw-r--r--drivers/media/video/adv7180.c202
-rw-r--r--drivers/media/video/adv7343.c1
-rw-r--r--drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c44
-rw-r--r--drivers/media/video/cafe_ccic.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c16
-rw-r--r--drivers/media/video/cx18/cx18-streams.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c4
-rw-r--r--drivers/media/video/cx23885/cimax2.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c14
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c5
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c6
-rw-r--r--drivers/media/video/cx23885/cx23885.h2
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.c6
-rw-r--r--drivers/media/video/cx88/cx88-cards.c14
-rw-r--r--drivers/media/video/cx88/cx88-video.c6
-rw-r--r--drivers/media/video/dabusb.c4
-rw-r--r--drivers/media/video/davinci/Makefile17
-rw-r--r--drivers/media/video/davinci/ccdc_hw_device.h110
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c978
-rw-r--r--drivers/media/video/davinci/dm355_ccdc_regs.h310
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c878
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc_regs.h145
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2124
-rw-r--r--drivers/media/video/davinci/vpif.c296
-rw-r--r--drivers/media/video/davinci/vpif.h642
-rw-r--r--drivers/media/video/davinci/vpif_capture.c2168
-rw-r--r--drivers/media/video/davinci/vpif_capture.h165
-rw-r--r--drivers/media/video/davinci/vpif_display.c1656
-rw-r--r--drivers/media/video/davinci/vpif_display.h175
-rw-r--r--drivers/media/video/davinci/vpss.c301
-rw-r--r--drivers/media/video/em28xx/Kconfig1
-rw-r--r--drivers/media/video/em28xx/Makefile2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c59
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c51
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c19
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h16
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c142
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c589
-rw-r--r--drivers/media/video/em28xx/em28xx.h26
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c6
-rw-r--r--drivers/media/video/gspca/Kconfig1
-rw-r--r--drivers/media/video/gspca/Makefile1
-rw-r--r--drivers/media/video/gspca/gl860/Kconfig8
-rw-r--r--drivers/media/video/gspca/gl860/Makefile10
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi1320.c537
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c937
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c505
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c337
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c785
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h108
-rw-r--r--drivers/media/video/gspca/jeilinj.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c262
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h138
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c13
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c19
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c151
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c15
-rw-r--r--drivers/media/video/gspca/vc032x.c7
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c18
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c4
-rw-r--r--drivers/media/video/mt9m001.c435
-rw-r--r--drivers/media/video/mt9m111.c524
-rw-r--r--drivers/media/video/mt9t031.c491
-rw-r--r--drivers/media/video/mt9v022.c434
-rw-r--r--drivers/media/video/mx1_camera.c78
-rw-r--r--drivers/media/video/mx3_camera.c207
-rw-r--r--drivers/media/video/mxb.c14
-rw-r--r--drivers/media/video/ov772x.c381
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c10
-rw-r--r--drivers/media/video/pxa_camera.c358
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c53
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c30
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c4
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/Kconfig18
-rw-r--r--drivers/media/video/saa7164/Makefile12
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c600
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c155
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c448
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c624
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c572
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c740
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c602
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c613
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c141
-rw-r--r--drivers/media/video/saa7164/saa7164-reg.h166
-rw-r--r--drivers/media/video/saa7164/saa7164-types.h287
-rw-r--r--drivers/media/video/saa7164/saa7164.h400
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c1062
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c6
-rw-r--r--drivers/media/video/soc_camera.c725
-rw-r--r--drivers/media/video/soc_camera_platform.c163
-rw-r--r--drivers/media/video/tuner-core.c12
-rw-r--r--drivers/media/video/tvp514x.c1030
-rw-r--r--drivers/media/video/tvp514x_regs.h10
-rw-r--r--drivers/media/video/tw9910.c361
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c12
-rw-r--r--drivers/media/video/uvc/uvc_video.c7
-rw-r--r--drivers/media/video/v4l1-compat.c14
-rw-r--r--drivers/media/video/v4l2-common.c133
-rw-r--r--drivers/media/video/v4l2-dev.c154
-rw-r--r--drivers/media/video/vino.c8
-rw-r--r--drivers/media/video/w9968cf.c4
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c6
-rw-r--r--drivers/media/video/zoran/zoran_card.c8
-rw-r--r--drivers/mtd/ubi/debug.c32
-rw-r--r--drivers/mtd/ubi/debug.h2
-rw-r--r--drivers/mtd/ubi/io.c49
-rw-r--r--drivers/mtd/ubi/scan.c22
-rw-r--r--drivers/mtd/ubi/scan.h2
-rw-r--r--drivers/mtd/ubi/ubi.h3
-rw-r--r--drivers/net/slip.c96
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/scsi/fcoe/libfcoe.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/serial/21285.c8
-rw-r--r--drivers/serial/8250.c28
-rw-r--r--drivers/serial/8250.h1
-rw-r--r--drivers/serial/amba-pl010.c6
-rw-r--r--drivers/serial/amba-pl011.c6
-rw-r--r--drivers/serial/atmel_serial.c14
-rw-r--r--drivers/serial/bfin_5xx.c24
-rw-r--r--drivers/serial/bfin_sport_uart.c6
-rw-r--r--drivers/serial/clps711x.c4
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/dz.c6
-rw-r--r--drivers/serial/icom.c20
-rw-r--r--drivers/serial/imx.c16
-rw-r--r--drivers/serial/ioc3_serial.c54
-rw-r--r--drivers/serial/ioc4_serial.c68
-rw-r--r--drivers/serial/ip22zilog.c14
-rw-r--r--drivers/serial/jsm/jsm_neo.c2
-rw-r--r--drivers/serial/jsm/jsm_tty.c20
-rw-r--r--drivers/serial/m32r_sio.c6
-rw-r--r--drivers/serial/max3100.c16
-rw-r--r--drivers/serial/mcf.c4
-rw-r--r--drivers/serial/mpc52xx_uart.c4
-rw-r--r--drivers/serial/mpsc.c4
-rw-r--r--drivers/serial/msm_serial.c6
-rw-r--r--drivers/serial/mux.c4
-rw-r--r--drivers/serial/netx-serial.c6
-rw-r--r--drivers/serial/nwpserial.c4
-rw-r--r--drivers/serial/pmac_zilog.c20
-rw-r--r--drivers/serial/pnx8xxx_uart.c8
-rw-r--r--drivers/serial/pxa.c6
-rw-r--r--drivers/serial/sa1100.c8
-rw-r--r--drivers/serial/samsung.c8
-rw-r--r--drivers/serial/sb1250-duart.c6
-rw-r--r--drivers/serial/sc26xx.c10
-rw-r--r--drivers/serial/serial_core.c876
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/serial_ks8695.c6
-rw-r--r--drivers/serial/serial_lh7a40x.c6
-rw-r--r--drivers/serial/serial_txx9.c4
-rw-r--r--drivers/serial/sh-sci.c10
-rw-r--r--drivers/serial/sn_console.c22
-rw-r--r--drivers/serial/sunhv.c8
-rw-r--r--drivers/serial/sunsab.c10
-rw-r--r--drivers/serial/sunsu.c6
-rw-r--r--drivers/serial/sunzilog.c14
-rw-r--r--drivers/serial/timbuart.c10
-rw-r--r--drivers/serial/uartlite.c19
-rw-r--r--drivers/serial/ucc_uart.c4
-rw-r--r--drivers/serial/vr41xx_siu.c6
-rw-r--r--drivers/serial/zs.c6
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/cx25821/Kconfig34
-rw-r--r--drivers/staging/cx25821/Makefile14
-rw-r--r--drivers/staging/cx25821/README6
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c789
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c804
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c434
-rw-r--r--drivers/staging/cx25821/cx25821-biffuncs.h45
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c70
-rw-r--r--drivers/staging/cx25821/cx25821-core.c1551
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.c98
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.h2
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c419
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-defines.h51
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-reg.h455
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c869
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.h49
-rw-r--r--drivers/staging/cx25821/cx25821-reg.h1592
-rw-r--r--drivers/staging/cx25821/cx25821-sram.h261
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c835
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.h101
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c894
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.h109
-rw-r--r--drivers/staging/cx25821/cx25821-video.c1299
-rw-r--r--drivers/staging/cx25821/cx25821-video.h194
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c452
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c449
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c496
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c435
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c433
-rw-r--r--drivers/staging/cx25821/cx25821.h602
-rw-r--r--drivers/staging/go7007/Kconfig84
-rw-r--r--drivers/staging/go7007/Makefile20
-rw-r--r--drivers/staging/go7007/go7007-driver.c35
-rw-r--r--drivers/staging/go7007/go7007-fw.c3
-rw-r--r--drivers/staging/go7007/go7007-i2c.c12
-rw-r--r--drivers/staging/go7007/go7007-priv.h6
-rw-r--r--drivers/staging/go7007/go7007-usb.c58
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c225
-rw-r--r--drivers/staging/go7007/go7007.txt176
-rw-r--r--drivers/staging/go7007/s2250-board.c107
-rw-r--r--drivers/staging/go7007/s2250-loader.c8
-rw-r--r--drivers/staging/go7007/snd-go7007.c2
-rw-r--r--drivers/staging/go7007/wis-tw9903.c3
-rw-r--r--drivers/staging/iio/industrialio-core.c4
-rw-r--r--drivers/usb/class/cdc-acm.c5
-rw-r--r--drivers/usb/class/usblp.c4
-rw-r--r--drivers/usb/core/file.c8
-rw-r--r--drivers/usb/core/usb.c4
-rw-r--r--drivers/usb/misc/iowarrior.c4
-rw-r--r--drivers/usb/misc/legousbtower.c4
-rw-r--r--drivers/usb/serial/ark3116.c51
-rw-r--r--drivers/usb/serial/belkin_sa.c4
-rw-r--r--drivers/usb/serial/ch341.c5
-rw-r--r--drivers/usb/serial/console.c32
-rw-r--r--drivers/usb/serial/cp210x.c12
-rw-r--r--drivers/usb/serial/cyberjack.c4
-rw-r--r--drivers/usb/serial/cypress_m8.c18
-rw-r--r--drivers/usb/serial/digi_acceleport.c6
-rw-r--r--drivers/usb/serial/empeg.c18
-rw-r--r--drivers/usb/serial/ftdi_sio.c6
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/generic.c3
-rw-r--r--drivers/usb/serial/io_edgeport.c6
-rw-r--r--drivers/usb/serial/io_ti.c3
-rw-r--r--drivers/usb/serial/ipaq.c9
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/ir-usb.c6
-rw-r--r--drivers/usb/serial/iuu_phoenix.c34
-rw-r--r--drivers/usb/serial/keyspan.c3
-rw-r--r--drivers/usb/serial/keyspan.h3
-rw-r--r--drivers/usb/serial/keyspan_pda.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c10
-rw-r--r--drivers/usb/serial/kobil_sct.c28
-rw-r--r--drivers/usb/serial/mct_u232.c15
-rw-r--r--drivers/usb/serial/mos7720.c123
-rw-r--r--drivers/usb/serial/mos7840.c118
-rw-r--r--drivers/usb/serial/navman.c3
-rw-r--r--drivers/usb/serial/omninet.c6
-rw-r--r--drivers/usb/serial/opticon.c3
-rw-r--r--drivers/usb/serial/option.c6
-rw-r--r--drivers/usb/serial/oti6858.c27
-rw-r--r--drivers/usb/serial/pl2303.c5
-rw-r--r--drivers/usb/serial/sierra.c3
-rw-r--r--drivers/usb/serial/spcp8x5.c26
-rw-r--r--drivers/usb/serial/symbolserial.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c6
-rw-r--r--drivers/usb/serial/usb-serial.c385
-rw-r--r--drivers/usb/serial/usb_debug.c5
-rw-r--r--drivers/usb/serial/visor.c6
-rw-r--r--drivers/usb/serial/whiteheat.c11
-rw-r--r--drivers/video/console/vgacon.c1
-rw-r--r--drivers/xen/evtchn.c1
465 files changed, 72965 insertions, 48670 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 390e664ec1c7..6bee6af8d8e1 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
166 if (MAJOR(dev->devt)) { 166 if (MAJOR(dev->devt)) {
167 const char *tmp; 167 const char *tmp;
168 const char *name; 168 const char *name;
169 mode_t mode = 0;
169 170
170 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 171 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
171 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 172 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
172 name = device_get_nodename(dev, &tmp); 173 name = device_get_devnode(dev, &mode, &tmp);
173 if (name) { 174 if (name) {
174 add_uevent_var(env, "DEVNAME=%s", name); 175 add_uevent_var(env, "DEVNAME=%s", name);
175 kfree(tmp); 176 kfree(tmp);
177 if (mode)
178 add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
176 } 179 }
177 } 180 }
178 181
@@ -1148,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i)
1148} 1151}
1149 1152
1150/** 1153/**
1151 * device_get_nodename - path of device node file 1154 * device_get_devnode - path of device node file
1152 * @dev: device 1155 * @dev: device
1156 * @mode: returned file access mode
1153 * @tmp: possibly allocated string 1157 * @tmp: possibly allocated string
1154 * 1158 *
1155 * Return the relative path of a possible device node. 1159 * Return the relative path of a possible device node.
@@ -1157,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i)
1157 * a name. This memory is returned in tmp and needs to be 1161 * a name. This memory is returned in tmp and needs to be
1158 * freed by the caller. 1162 * freed by the caller.
1159 */ 1163 */
1160const char *device_get_nodename(struct device *dev, const char **tmp) 1164const char *device_get_devnode(struct device *dev,
1165 mode_t *mode, const char **tmp)
1161{ 1166{
1162 char *s; 1167 char *s;
1163 1168
1164 *tmp = NULL; 1169 *tmp = NULL;
1165 1170
1166 /* the device type may provide a specific name */ 1171 /* the device type may provide a specific name */
1167 if (dev->type && dev->type->nodename) 1172 if (dev->type && dev->type->devnode)
1168 *tmp = dev->type->nodename(dev); 1173 *tmp = dev->type->devnode(dev, mode);
1169 if (*tmp) 1174 if (*tmp)
1170 return *tmp; 1175 return *tmp;
1171 1176
1172 /* the class may provide a specific name */ 1177 /* the class may provide a specific name */
1173 if (dev->class && dev->class->nodename) 1178 if (dev->class && dev->class->devnode)
1174 *tmp = dev->class->nodename(dev); 1179 *tmp = dev->class->devnode(dev, mode);
1175 if (*tmp) 1180 if (*tmp)
1176 return *tmp; 1181 return *tmp;
1177 1182
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index fd488ad4263a..a1cb5afe6801 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -6,9 +6,10 @@
6 * During bootup, before any driver core device is registered, 6 * During bootup, before any driver core device is registered,
7 * devtmpfs, a tmpfs-based filesystem is created. Every driver-core 7 * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
8 * device which requests a device node, will add a node in this 8 * device which requests a device node, will add a node in this
9 * filesystem. The node is named after the the name of the device, 9 * filesystem.
10 * or the susbsytem can provide a custom name. All devices are 10 * By default, all devices are named after the the name of the
11 * owned by root and have a mode of 0600. 11 * device, owned by root and have a default mode of 0600. Subsystems
12 * can overwrite the default setting if needed.
12 */ 13 */
13 14
14#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -20,6 +21,7 @@
20#include <linux/fs.h> 21#include <linux/fs.h>
21#include <linux/shmem_fs.h> 22#include <linux/shmem_fs.h>
22#include <linux/cred.h> 23#include <linux/cred.h>
24#include <linux/sched.h>
23#include <linux/init_task.h> 25#include <linux/init_task.h>
24 26
25static struct vfsmount *dev_mnt; 27static struct vfsmount *dev_mnt;
@@ -134,7 +136,7 @@ int devtmpfs_create_node(struct device *dev)
134 const char *tmp = NULL; 136 const char *tmp = NULL;
135 const char *nodename; 137 const char *nodename;
136 const struct cred *curr_cred; 138 const struct cred *curr_cred;
137 mode_t mode; 139 mode_t mode = 0;
138 struct nameidata nd; 140 struct nameidata nd;
139 struct dentry *dentry; 141 struct dentry *dentry;
140 int err; 142 int err;
@@ -142,14 +144,16 @@ int devtmpfs_create_node(struct device *dev)
142 if (!dev_mnt) 144 if (!dev_mnt)
143 return 0; 145 return 0;
144 146
145 nodename = device_get_nodename(dev, &tmp); 147 nodename = device_get_devnode(dev, &mode, &tmp);
146 if (!nodename) 148 if (!nodename)
147 return -ENOMEM; 149 return -ENOMEM;
148 150
151 if (mode == 0)
152 mode = 0600;
149 if (is_blockdev(dev)) 153 if (is_blockdev(dev))
150 mode = S_IFBLK|0600; 154 mode |= S_IFBLK;
151 else 155 else
152 mode = S_IFCHR|0600; 156 mode |= S_IFCHR;
153 157
154 curr_cred = override_creds(&init_cred); 158 curr_cred = override_creds(&init_cred);
155 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, 159 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
@@ -165,8 +169,12 @@ int devtmpfs_create_node(struct device *dev)
165 169
166 dentry = lookup_create(&nd, 0); 170 dentry = lookup_create(&nd, 0);
167 if (!IS_ERR(dentry)) { 171 if (!IS_ERR(dentry)) {
172 int umask;
173
174 umask = sys_umask(0000);
168 err = vfs_mknod(nd.path.dentry->d_inode, 175 err = vfs_mknod(nd.path.dentry->d_inode,
169 dentry, mode, dev->devt); 176 dentry, mode, dev->devt);
177 sys_umask(umask);
170 /* mark as kernel created inode */ 178 /* mark as kernel created inode */
171 if (!err) 179 if (!err)
172 dentry->d_inode->i_private = &dev_mnt; 180 dentry->d_inode->i_private = &dev_mnt;
@@ -271,7 +279,7 @@ int devtmpfs_delete_node(struct device *dev)
271 if (!dev_mnt) 279 if (!dev_mnt)
272 return 0; 280 return 0;
273 281
274 nodename = device_get_nodename(dev, &tmp); 282 nodename = device_get_devnode(dev, NULL, &tmp);
275 if (!nodename) 283 if (!nodename)
276 return -ENOMEM; 284 return -ENOMEM;
277 285
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 19888354188f..62141ec09a22 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -266,7 +266,7 @@ static const struct file_operations aoe_fops = {
266 .owner = THIS_MODULE, 266 .owner = THIS_MODULE,
267}; 267};
268 268
269static char *aoe_nodename(struct device *dev) 269static char *aoe_devnode(struct device *dev, mode_t *mode)
270{ 270{
271 return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev)); 271 return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev));
272} 272}
@@ -288,7 +288,7 @@ aoechr_init(void)
288 unregister_chrdev(AOE_MAJOR, "aoechr"); 288 unregister_chrdev(AOE_MAJOR, "aoechr");
289 return PTR_ERR(aoe_class); 289 return PTR_ERR(aoe_class);
290 } 290 }
291 aoe_class->nodename = aoe_nodename; 291 aoe_class->devnode = aoe_devnode;
292 292
293 for (i = 0; i < ARRAY_SIZE(chardevs); ++i) 293 for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
294 device_create(aoe_class, NULL, 294 device_create(aoe_class, NULL,
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 95f11cdef203..fd5bb8ad59a9 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2857,7 +2857,7 @@ static struct block_device_operations pktcdvd_ops = {
2857 .media_changed = pkt_media_changed, 2857 .media_changed = pkt_media_changed,
2858}; 2858};
2859 2859
2860static char *pktcdvd_nodename(struct gendisk *gd) 2860static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode)
2861{ 2861{
2862 return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name); 2862 return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name);
2863} 2863}
@@ -2914,7 +2914,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
2914 disk->fops = &pktcdvd_ops; 2914 disk->fops = &pktcdvd_ops;
2915 disk->flags = GENHD_FL_REMOVABLE; 2915 disk->flags = GENHD_FL_REMOVABLE;
2916 strcpy(disk->disk_name, pd->name); 2916 strcpy(disk->disk_name, pd->name);
2917 disk->nodename = pktcdvd_nodename; 2917 disk->devnode = pktcdvd_devnode;
2918 disk->private_data = pd; 2918 disk->private_data = pd;
2919 disk->queue = blk_alloc_queue(GFP_KERNEL); 2919 disk->queue = blk_alloc_queue(GFP_KERNEL);
2920 if (!disk->queue) 2920 if (!disk->queue)
@@ -3070,7 +3070,7 @@ static const struct file_operations pkt_ctl_fops = {
3070static struct miscdevice pkt_misc = { 3070static struct miscdevice pkt_misc = {
3071 .minor = MISC_DYNAMIC_MINOR, 3071 .minor = MISC_DYNAMIC_MINOR,
3072 .name = DRIVER_NAME, 3072 .name = DRIVER_NAME,
3073 .name = "pktcdvd/control", 3073 .nodename = "pktcdvd/control",
3074 .fops = &pkt_ctl_fops 3074 .fops = &pkt_ctl_fops
3075}; 3075};
3076 3076
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 2dafc2da0648..df5038bbcbc2 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -11,7 +11,7 @@
11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. 11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>. 12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
13 * 13 *
14 * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com> 14 * Copyright (C) 2007-2009 Jiri Slaby <jirislaby@gmail.com>
15 * 15 *
16 * Much of the design and some of the code came from serial.c 16 * Much of the design and some of the code came from serial.c
17 * which was copyright (C) 1991, 1992 Linus Torvalds. It was 17 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
@@ -19,577 +19,9 @@
19 * and then fixed as suggested by Michael K. Johnson 12/12/92. 19 * and then fixed as suggested by Michael K. Johnson 12/12/92.
20 * Converted to pci probing and cleaned up by Jiri Slaby. 20 * Converted to pci probing and cleaned up by Jiri Slaby.
21 * 21 *
22 * This version supports shared IRQ's (only for PCI boards).
23 *
24 * Prevent users from opening non-existing Z ports.
25 *
26 * Revision 2.3.2.8 2000/07/06 18:14:16 ivan
27 * Fixed the PCI detection function to work properly on Alpha systems.
28 * Implemented support for TIOCSERGETLSR ioctl.
29 * Implemented full support for non-standard baud rates.
30 *
31 * Revision 2.3.2.7 2000/06/01 18:26:34 ivan
32 * Request PLX I/O region, although driver doesn't use it, to avoid
33 * problems with other drivers accessing it.
34 * Removed count for on-board buffer characters in cy_chars_in_buffer
35 * (Cyclades-Z only).
36 *
37 * Revision 2.3.2.6 2000/05/05 13:56:05 ivan
38 * Driver now reports physical instead of virtual memory addresses.
39 * Masks were added to some Cyclades-Z read accesses.
40 * Implemented workaround for PLX9050 bug that would cause a system lockup
41 * in certain systems, depending on the MMIO addresses allocated to the
42 * board.
43 * Changed the Tx interrupt programming in the CD1400 chips to boost up
44 * performance (Cyclom-Y only).
45 * Code is now compliant with the new module interface (module_[init|exit]).
46 * Make use of the PCI helper functions to access PCI resources.
47 * Did some code "housekeeping".
48 *
49 * Revision 2.3.2.5 2000/01/19 14:35:33 ivan
50 * Fixed bug in cy_set_termios on CRTSCTS flag turnoff.
51 *
52 * Revision 2.3.2.4 2000/01/17 09:19:40 ivan
53 * Fixed SMP locking in Cyclom-Y interrupt handler.
54 *
55 * Revision 2.3.2.3 1999/12/28 12:11:39 ivan
56 * Added a new cyclades_card field called nports to allow the driver to
57 * know the exact number of ports found by the Z firmware after its load;
58 * RX buffer contention prevention logic on interrupt op mode revisited
59 * (Cyclades-Z only);
60 * Revisited printk's for Z debug;
61 * Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined;
62 *
63 * Revision 2.3.2.2 1999/10/01 11:27:43 ivan
64 * Fixed bug in cyz_poll that would make all ports but port 0
65 * unable to transmit/receive data (Cyclades-Z only);
66 * Implemented logic to prevent the RX buffer from being stuck with data
67 * due to a driver / firmware race condition in interrupt op mode
68 * (Cyclades-Z only);
69 * Fixed bug in block_til_ready logic that would lead to a system crash;
70 * Revisited cy_close spinlock usage;
71 *
72 * Revision 2.3.2.1 1999/09/28 11:01:22 ivan
73 * Revisited CONFIG_PCI conditional compilation for PCI board support;
74 * Implemented TIOCGICOUNT and TIOCMIWAIT ioctl support;
75 * _Major_ cleanup on the Cyclades-Z interrupt support code / logic;
76 * Removed CTS handling from the driver -- this is now completely handled
77 * by the firmware (Cyclades-Z only);
78 * Flush RX on-board buffers on a port open (Cyclades-Z only);
79 * Fixed handling of ASYNC_SPD_* TTY flags;
80 * Module unload now unmaps all memory area allocated by ioremap;
81 *
82 * Revision 2.3.1.1 1999/07/15 16:45:53 ivan
83 * Removed CY_PROC conditional compilation;
84 * Implemented SMP-awareness for the driver;
85 * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off]
86 * functions;
87 * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs
88 * (irq=NN) as parameters (only for ISA boards);
89 * Fixed bug in set_line_char that would prevent the Cyclades-Z
90 * ports from being configured at speeds above 115.2Kbps;
91 * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
92 * switching from working properly;
93 * The driver now only prints IRQ info for the Cyclades-Z if it's
94 * configured to work in interrupt mode;
95 *
96 * Revision 2.2.2.3 1999/06/28 11:13:29 ivan
97 * Added support for interrupt mode operation for the Z cards;
98 * Removed the driver inactivity control for the Z;
99 * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
100 * the Z firmware is not loaded yet;
101 * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
102 * same functionality;
103 * Implemented workaround for IRQ setting loss on the PCI configuration
104 * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
105 *
106 * Revision 2.2.2.2 1999/05/14 17:18:15 ivan
107 * /proc entry location changed to /proc/tty/driver/cyclades;
108 * Added support to shared IRQ's (only for PCI boards);
109 * Added support for Cobalt Qube2 systems;
110 * IRQ [de]allocation scheme revisited;
111 * BREAK implementation changed in order to make use of the 'break_ctl'
112 * TTY facility;
113 * Fixed typo in TTY structure field 'driver_name';
114 * Included a PCI bridge reset and EEPROM reload in the board
115 * initialization code (for both Y and Z series).
116 *
117 * Revision 2.2.2.1 1999/04/08 16:17:43 ivan
118 * Fixed a bug in cy_wait_until_sent that was preventing the port to be
119 * closed properly after a SIGINT;
120 * Module usage counter scheme revisited;
121 * Added support to the upcoming Y PCI boards (i.e., support to additional
122 * PCI Device ID's).
123 *
124 * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
125 * Removed all unnecessary page-alignement operations in ioremap calls
126 * (ioremap is currently safe for these operations).
127 *
128 * Revision 2.2.1.9 1998/12/30 18:18:30 ivan
129 * Changed access to PLX PCI bridge registers from I/O to MMIO, in
130 * order to make PLX9050-based boards work with certain motherboards.
131 *
132 * Revision 2.2.1.8 1998/11/13 12:46:20 ivan
133 * cy_close function now resets (correctly) the tty->closing flag;
134 * JIFFIES_DIFF macro fixed.
135 *
136 * Revision 2.2.1.7 1998/09/03 12:07:28 ivan
137 * Fixed bug in cy_close function, which was not informing HW of
138 * which port should have the reception disabled before doing so;
139 * fixed Cyclom-8YoP hardware detection bug.
140 *
141 * Revision 2.2.1.6 1998/08/20 17:15:39 ivan
142 * Fixed bug in cy_close function, which causes malfunction
143 * of one of the first 4 ports when a higher port is closed
144 * (Cyclom-Y only).
145 *
146 * Revision 2.2.1.5 1998/08/10 18:10:28 ivan
147 * Fixed Cyclom-4Yo hardware detection bug.
148 *
149 * Revision 2.2.1.4 1998/08/04 11:02:50 ivan
150 * /proc/cyclades implementation with great collaboration of
151 * Marc Lewis <marc@blarg.net>;
152 * cyy_interrupt was changed to avoid occurrence of kernel oopses
153 * during PPP operation.
154 *
155 * Revision 2.2.1.3 1998/06/01 12:09:10 ivan
156 * General code review in order to comply with 2.1 kernel standards;
157 * data loss prevention for slow devices revisited (cy_wait_until_sent
158 * was created);
159 * removed conditional compilation for new/old PCI structure support
160 * (now the driver only supports the new PCI structure).
161 *
162 * Revision 2.2.1.1 1998/03/19 16:43:12 ivan
163 * added conditional compilation for new/old PCI structure support;
164 * removed kernel series (2.0.x / 2.1.x) conditional compilation.
165 *
166 * Revision 2.1.1.3 1998/03/16 18:01:12 ivan
167 * cleaned up the data loss fix;
168 * fixed XON/XOFF handling once more (Cyclades-Z);
169 * general review of the driver routines;
170 * introduction of a mechanism to prevent data loss with slow
171 * printers, by forcing a delay before closing the port.
172 *
173 * Revision 2.1.1.2 1998/02/17 16:50:00 ivan
174 * fixed detection/handling of new CD1400 in Ye boards;
175 * fixed XON/XOFF handling (Cyclades-Z);
176 * fixed data loss caused by a premature port close;
177 * introduction of a flag that holds the CD1400 version ID per port
178 * (used by the CYGETCD1400VER new ioctl).
179 *
180 * Revision 2.1.1.1 1997/12/03 17:31:19 ivan
181 * Code review for the module cleanup routine;
182 * fixed RTS and DTR status report for new CD1400's in get_modem_info;
183 * includes anonymous changes regarding signal_pending.
184 *
185 * Revision 2.1 1997/11/01 17:42:41 ivan
186 * Changes in the driver to support Alpha systems (except 8Zo V_1);
187 * BREAK fix for the Cyclades-Z boards;
188 * driver inactivity control by FW implemented;
189 * introduction of flag that allows driver to take advantage of
190 * a special CD1400 feature related to HW flow control;
191 * added support for the CD1400 rev. J (Cyclom-Y boards);
192 * introduction of ioctls to:
193 * - control the rtsdtr_inv flag (Cyclom-Y);
194 * - control the rflow flag (Cyclom-Y);
195 * - adjust the polling interval (Cyclades-Z);
196 *
197 * Revision 1.36.4.33 1997/06/27 19:00:00 ivan
198 * Fixes related to kernel version conditional
199 * compilation.
200 *
201 * Revision 1.36.4.32 1997/06/14 19:30:00 ivan
202 * Compatibility issues between kernels 2.0.x and
203 * 2.1.x (mainly related to clear_bit function).
204 *
205 * Revision 1.36.4.31 1997/06/03 15:30:00 ivan
206 * Changes to define the memory window according to the
207 * board type.
208 *
209 * Revision 1.36.4.30 1997/05/16 15:30:00 daniel
210 * Changes to support new cycladesZ boards.
211 *
212 * Revision 1.36.4.29 1997/05/12 11:30:00 daniel
213 * Merge of Bentson's and Daniel's version 1.36.4.28.
214 * Corrects bug in cy_detect_pci: check if there are more
215 * ports than the number of static structs allocated.
216 * Warning message during initialization if this driver is
217 * used with the new generation of cycladesZ boards. Those
218 * will be supported only in next release of the driver.
219 * Corrects bug in cy_detect_pci and cy_detect_isa that
220 * returned wrong number of VALID boards, when a cyclomY
221 * was found with no serial modules connected.
222 * Changes to use current (2.1.x) kernel subroutine names
223 * and created macros for compilation with 2.0.x kernel,
224 * instead of the other way around.
225 *
226 * Revision 1.36.4.28 1997/05/?? ??:00:00 bentson
227 * Change queue_task_irq_off to queue_task_irq.
228 * The inline function queue_task_irq_off (tqueue.h)
229 * was removed from latest releases of 2.1.x kernel.
230 * Use of macro __init to mark the initialization
231 * routines, so memory can be reused.
232 * Also incorporate implementation of critical region
233 * in function cleanup_module() created by anonymous
234 * linuxer.
235 *
236 * Revision 1.36.4.28 1997/04/25 16:00:00 daniel
237 * Change to support new firmware that solves DCD problem:
238 * application could fail to receive SIGHUP signal when DCD
239 * varying too fast.
240 *
241 * Revision 1.36.4.27 1997/03/26 10:30:00 daniel
242 * Changed for support linux versions 2.1.X.
243 * Backward compatible with linux versions 2.0.X.
244 * Corrected illegal use of filler field in
245 * CH_CTRL struct.
246 * Deleted some debug messages.
247 *
248 * Revision 1.36.4.26 1997/02/27 12:00:00 daniel
249 * Included check for NULL tty pointer in cyz_poll.
250 *
251 * Revision 1.36.4.25 1997/02/26 16:28:30 bentson
252 * Bill Foster at Blarg! Online services noticed that
253 * some of the switch elements of -Z modem control
254 * lacked a closing "break;"
255 *
256 * Revision 1.36.4.24 1997/02/24 11:00:00 daniel
257 * Changed low water threshold for buffer xmit_buf
258 *
259 * Revision 1.36.4.23 1996/12/02 21:50:16 bentson
260 * Marcio provided fix to modem status fetch for -Z
261 *
262 * Revision 1.36.4.22 1996/10/28 22:41:17 bentson
263 * improve mapping of -Z control page (thanks to Steve
264 * Price <stevep@fa.tdktca.com> for help on this)
265 *
266 * Revision 1.36.4.21 1996/09/10 17:00:10 bentson
267 * shift from CPU-bound to memcopy in cyz_polling operation
268 *
269 * Revision 1.36.4.20 1996/09/09 18:30:32 Bentson
270 * Added support to set and report higher speeds.
271 *
272 * Revision 1.36.4.19c 1996/08/09 10:00:00 Marcio Saito
273 * Some fixes in the HW flow control for the BETA release.
274 * Don't try to register the IRQ.
275 *
276 * Revision 1.36.4.19 1996/08/08 16:23:18 Bentson
277 * make sure "cyc" appears in all kernel messages; all soft interrupts
278 * handled by same routine; recognize out-of-band reception; comment
279 * out some diagnostic messages; leave RTS/CTS flow control to hardware;
280 * fix race condition in -Z buffer management; only -Y needs to explicitly
281 * flush chars; tidy up some startup messages;
282 *
283 * Revision 1.36.4.18 1996/07/25 18:57:31 bentson
284 * shift MOD_INC_USE_COUNT location to match
285 * serial.c; purge some diagnostic messages;
286 *
287 * Revision 1.36.4.17 1996/07/25 18:01:08 bentson
288 * enable modem status messages and fetch & process them; note
289 * time of last activity type for each port; set_line_char now
290 * supports more than line 0 and treats 0 baud correctly;
291 * get_modem_info senses rs_status;
292 *
293 * Revision 1.36.4.16 1996/07/20 08:43:15 bentson
294 * barely works--now's time to turn on
295 * more features 'til it breaks
296 *
297 * Revision 1.36.4.15 1996/07/19 22:30:06 bentson
298 * check more -Z board status; shorten boot message
299 *
300 * Revision 1.36.4.14 1996/07/19 22:20:37 bentson
301 * fix reference to ch_ctrl in startup; verify return
302 * values from cyz_issue_cmd and cyz_update_channel;
303 * more stuff to get modem control correct;
304 *
305 * Revision 1.36.4.13 1996/07/11 19:53:33 bentson
306 * more -Z stuff folded in; re-order changes to put -Z stuff
307 * after -Y stuff (to make changes clearer)
308 *
309 * Revision 1.36.4.12 1996/07/11 15:40:55 bentson
310 * Add code to poll Cyclades-Z. Add code to get & set RS-232 control.
311 * Add code to send break. Clear firmware ID word at startup (so
312 * that other code won't talk to inactive board).
313 *
314 * Revision 1.36.4.11 1996/07/09 05:28:29 bentson
315 * add code for -Z in set_line_char
316 *
317 * Revision 1.36.4.10 1996/07/08 19:28:37 bentson
318 * fold more -Z stuff (or in some cases, error messages)
319 * into driver; add text to "don't know what to do" messages.
320 *
321 * Revision 1.36.4.9 1996/07/08 18:38:38 bentson
322 * moved compile-time flags near top of file; cosmetic changes
323 * to narrow text (to allow 2-up printing); changed many declarations
324 * to "static" to limit external symbols; shuffled code order to
325 * coalesce -Y and -Z specific code, also to put internal functions
326 * in order of tty_driver structure; added code to recognize -Z
327 * ports (and for moment, do nothing or report error); add cy_startup
328 * to parse boot command line for extra base addresses for ISA probes;
329 *
330 * Revision 1.36.4.8 1996/06/25 17:40:19 bentson
331 * reorder some code, fix types of some vars (int vs. long),
332 * add cy_setup to support user declared ISA addresses
333 *
334 * Revision 1.36.4.7 1996/06/21 23:06:18 bentson
335 * dump ioctl based firmware load (it's now a user level
336 * program); ensure uninitialzed ports cannot be used
337 *
338 * Revision 1.36.4.6 1996/06/20 23:17:19 bentson
339 * rename vars and restructure some code
340 *
341 * Revision 1.36.4.5 1996/06/14 15:09:44 bentson
342 * get right status back after boot load
343 *
344 * Revision 1.36.4.4 1996/06/13 19:51:44 bentson
345 * successfully loads firmware
346 *
347 * Revision 1.36.4.3 1996/06/13 06:08:33 bentson
348 * add more of the code for the boot/load ioctls
349 *
350 * Revision 1.36.4.2 1996/06/11 21:00:51 bentson
351 * start to add Z functionality--starting with ioctl
352 * for loading firmware
353 *
354 * Revision 1.36.4.1 1996/06/10 18:03:02 bentson
355 * added code to recognize Z/PCI card at initialization; report
356 * presence, but card is not initialized (because firmware needs
357 * to be loaded)
358 *
359 * Revision 1.36.3.8 1996/06/07 16:29:00 bentson
360 * starting minor number at zero; added missing verify_area
361 * as noted by Heiko Eißfeldt <heiko@colossus.escape.de>
362 *
363 * Revision 1.36.3.7 1996/04/19 21:06:18 bentson
364 * remove unneeded boot message & fix CLOCAL hardware flow
365 * control (Miquel van Smoorenburg <miquels@Q.cistron.nl>);
366 * remove unused diagnostic statements; minor 0 is first;
367 *
368 * Revision 1.36.3.6 1996/03/13 13:21:17 marcio
369 * The kernel function vremap (available only in later 1.3.xx kernels)
370 * allows the access to memory addresses above the RAM. This revision
371 * of the driver supports PCI boards below 1Mb (device id 0x100) and
372 * above 1Mb (device id 0x101).
373 *
374 * Revision 1.36.3.5 1996/03/07 15:20:17 bentson
375 * Some global changes to interrupt handling spilled into
376 * this driver--mostly unused arguments in system function
377 * calls. Also added change by Marcio Saito which should
378 * reduce lost interrupts at startup by fast processors.
379 *
380 * Revision 1.36.3.4 1995/11/13 20:45:10 bentson
381 * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
382 * in 1.3.41 kernel to remove a possible race condition, extend
383 * some error messages, and let the driver run as a loadable module
384 * Change by Alan Wendt <alan@ez0.ezlink.com> to remove a
385 * possible race condition.
386 * Change by Marcio Saito <marcio@cyclades.com> to fix PCI addressing.
387 *
388 * Revision 1.36.3.3 1995/11/13 19:44:48 bentson
389 * Changes by Linus Torvalds in 1.3.33 kernel distribution
390 * required due to reordering of driver initialization.
391 * Drivers are now initialized *after* memory management.
392 *
393 * Revision 1.36.3.2 1995/09/08 22:07:14 bentson
394 * remove printk from ISR; fix typo
395 *
396 * Revision 1.36.3.1 1995/09/01 12:00:42 marcio
397 * Minor fixes in the PCI board support. PCI function calls in
398 * conditional compilation (CONFIG_PCI). Thanks to Jim Duncan
399 * <duncan@okay.com>. "bad serial count" message removed.
400 *
401 * Revision 1.36.3 1995/08/22 09:19:42 marcio
402 * Cyclom-Y/PCI support added. Changes in the cy_init routine and
403 * board initialization. Changes in the boot messages. The driver
404 * supports up to 4 boards and 64 ports by default.
405 *
406 * Revision 1.36.1.4 1995/03/29 06:14:14 bentson
407 * disambiguate between Cyclom-16Y and Cyclom-32Ye;
408 *
409 * Revision 1.36.1.3 1995/03/23 22:15:35 bentson
410 * add missing break in modem control block in ioctl switch statement
411 * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
412 *
413 * Revision 1.36.1.2 1995/03/22 19:16:22 bentson
414 * make sure CTS flow control is set as soon as possible (thanks
415 * to note from David Lambert <lambert@chesapeake.rps.slb.com>);
416 *
417 * Revision 1.36.1.1 1995/03/13 15:44:43 bentson
418 * initialize defaults for receive threshold and stale data timeout;
419 * cosmetic changes;
420 *
421 * Revision 1.36 1995/03/10 23:33:53 bentson
422 * added support of chips 4-7 in 32 port Cyclom-Ye;
423 * fix cy_interrupt pointer dereference problem
424 * (Joe Portman <baron@aa.net>);
425 * give better error response if open is attempted on non-existent port
426 * (Zachariah Vaum <jchryslr@netcom.com>);
427 * correct command timeout (Kenneth Lerman <lerman@@seltd.newnet.com>);
428 * conditional compilation for -16Y on systems with fast, noisy bus;
429 * comment out diagnostic print function;
430 * cleaned up table of base addresses;
431 * set receiver time-out period register to correct value,
432 * set receive threshold to better default values,
433 * set chip timer to more accurate 200 Hz ticking,
434 * add code to monitor and modify receive parameters
435 * (Rik Faith <faith@cs.unc.edu> Nick Simicich
436 * <njs@scifi.emi.net>);
437 *
438 * Revision 1.35 1994/12/16 13:54:18 steffen
439 * additional patch by Marcio Saito for board detection
440 * Accidently left out in 1.34
441 *
442 * Revision 1.34 1994/12/10 12:37:12 steffen
443 * This is the corrected version as suggested by Marcio Saito
444 *
445 * Revision 1.33 1994/12/01 22:41:18 bentson
446 * add hooks to support more high speeds directly; add tytso
447 * patch regarding CLOCAL wakeups
448 *
449 * Revision 1.32 1994/11/23 19:50:04 bentson
450 * allow direct kernel control of higher signalling rates;
451 * look for cards at additional locations
452 *
453 * Revision 1.31 1994/11/16 04:33:28 bentson
454 * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
455 * a problem in chars_in_buffer has been resolved by some
456 * small changes; this should yield smoother output
457 *
458 * Revision 1.30 1994/11/16 04:28:05 bentson
459 * Fix from Corey Minyard, Internet: minyard@metronet.com,
460 * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
461 * cy_hangup that appears to clear up much (all?) of the
462 * DTR glitches; also he's added/cleaned-up diagnostic messages
463 *
464 * Revision 1.29 1994/11/16 04:16:07 bentson
465 * add change proposed by Ralph Sims, ralphs@halcyon.com, to
466 * operate higher speeds in same way as other serial ports;
467 * add more serial ports (for up to two 16-port muxes).
468 *
469 * Revision 1.28 1994/11/04 00:13:16 root
470 * turn off diagnostic messages
471 *
472 * Revision 1.27 1994/11/03 23:46:37 root
473 * bunch of changes to bring driver into greater conformance
474 * with the serial.c driver (looking for missed fixes)
475 *
476 * Revision 1.26 1994/11/03 22:40:36 root
477 * automatic interrupt probing fixed.
478 *
479 * Revision 1.25 1994/11/03 20:17:02 root
480 * start to implement auto-irq
481 *
482 * Revision 1.24 1994/11/03 18:01:55 root
483 * still working on modem signals--trying not to drop DTR
484 * during the getty/login processes
485 *
486 * Revision 1.23 1994/11/03 17:51:36 root
487 * extend baud rate support; set receive threshold as function
488 * of baud rate; fix some problems with RTS/CTS;
489 *
490 * Revision 1.22 1994/11/02 18:05:35 root
491 * changed arguments to udelay to type long to get
492 * delays to be of correct duration
493 *
494 * Revision 1.21 1994/11/02 17:37:30 root
495 * employ udelay (after calibrating loops_per_second earlier
496 * in init/main.c) instead of using home-grown delay routines
497 *
498 * Revision 1.20 1994/11/02 03:11:38 root
499 * cy_chars_in_buffer forces a return value of 0 to let
500 * login work (don't know why it does); some functions
501 * that were returning EFAULT, now executes the code;
502 * more work on deciding when to disable xmit interrupts;
503 *
504 * Revision 1.19 1994/11/01 20:10:14 root
505 * define routine to start transmission interrupts (by enabling
506 * transmit interrupts); directly enable/disable modem interrupts;
507 *
508 * Revision 1.18 1994/11/01 18:40:45 bentson
509 * Don't always enable transmit interrupts in startup; interrupt on
510 * TxMpty instead of TxRdy to help characters get out before shutdown;
511 * restructure xmit interrupt to check for chars first and quit if
512 * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
513 * (to my view);
514 *
515 * Revision 1.17 1994/10/30 04:39:45 bentson
516 * rename serial_driver and callout_driver to cy_serial_driver and
517 * cy_callout_driver to avoid linkage interference; initialize
518 * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
519 * from cyclades_port structure; add paranoia check to cy_close;
520 *
521 * Revision 1.16 1994/10/30 01:14:33 bentson
522 * change major numbers; add some _early_ return statements;
523 *
524 * Revision 1.15 1994/10/29 06:43:15 bentson
525 * final tidying up for clean compile; enable some error reporting
526 *
527 * Revision 1.14 1994/10/28 20:30:22 Bentson
528 * lots of changes to drag the driver towards the new tty_io
529 * structures and operation. not expected to work, but may
530 * compile cleanly.
531 *
532 * Revision 1.13 1994/07/21 23:08:57 Bentson
533 * add some diagnostic cruft; support 24 lines (for testing
534 * both -8Y and -16Y cards; be more thorough in servicing all
535 * chips during interrupt; add "volatile" a few places to
536 * circumvent compiler optimizations; fix base & offset
537 * computations in block_til_ready (was causing chip 0 to
538 * stop operation)
539 *
540 * Revision 1.12 1994/07/19 16:42:11 Bentson
541 * add some hackery for kernel version 1.1.8; expand
542 * error messages; refine timing for delay loops and
543 * declare loop params volatile
544 *
545 * Revision 1.11 1994/06/11 21:53:10 bentson
546 * get use of save_car right in transmit interrupt service
547 *
548 * Revision 1.10.1.1 1994/06/11 21:31:18 bentson
549 * add some diagnostic printing; try to fix save_car stuff
550 *
551 * Revision 1.10 1994/06/11 20:36:08 bentson
552 * clean up compiler warnings
553 *
554 * Revision 1.9 1994/06/11 19:42:46 bentson
555 * added a bunch of code to support modem signalling
556 *
557 * Revision 1.8 1994/06/11 17:57:07 bentson
558 * recognize break & parity error
559 *
560 * Revision 1.7 1994/06/05 05:51:34 bentson
561 * Reorder baud table to be monotonic; add cli to CP; discard
562 * incoming characters and status if the line isn't open; start to
563 * fold code into cy_throttle; start to port get_serial_info,
564 * set_serial_info, get_modem_info, set_modem_info, and send_break
565 * from serial.c; expand cy_ioctl; relocate and expand config_setup;
566 * get flow control characters from tty struct; invalidate ports w/o
567 * hardware;
568 *
569 * Revision 1.6 1994/05/31 18:42:21 bentson
570 * add a loop-breaker in the interrupt service routine;
571 * note when port is initialized so that it can be shut
572 * down under the right conditions; receive works without
573 * any obvious errors
574 *
575 * Revision 1.5 1994/05/30 00:55:02 bentson
576 * transmit works without obvious errors
577 *
578 * Revision 1.4 1994/05/27 18:46:27 bentson
579 * incorporated more code from lib_y.c; can now print short
580 * strings under interrupt control to port zero; seems to
581 * select ports/channels/lines correctly
582 *
583 * Revision 1.3 1994/05/25 22:12:44 bentson
584 * shifting from multi-port on a card to proper multiplexor
585 * data structures; added skeletons of most routines
586 *
587 * Revision 1.2 1994/05/19 13:21:43 bentson
588 * start to crib from other sources
589 *
590 */ 22 */
591 23
592#define CY_VERSION "2.5" 24#define CY_VERSION "2.6"
593 25
594/* If you need to install more boards than NR_CARDS, change the constant 26/* If you need to install more boards than NR_CARDS, change the constant
595 in the definition below. No other change is necessary to support up to 27 in the definition below. No other change is necessary to support up to
@@ -648,9 +80,7 @@
648#include <linux/firmware.h> 80#include <linux/firmware.h>
649#include <linux/device.h> 81#include <linux/device.h>
650 82
651#include <asm/system.h>
652#include <linux/io.h> 83#include <linux/io.h>
653#include <asm/irq.h>
654#include <linux/uaccess.h> 84#include <linux/uaccess.h>
655 85
656#include <linux/kernel.h> 86#include <linux/kernel.h>
@@ -660,13 +90,11 @@
660#include <linux/proc_fs.h> 90#include <linux/proc_fs.h>
661#include <linux/seq_file.h> 91#include <linux/seq_file.h>
662 92
663static void cy_throttle(struct tty_struct *tty);
664static void cy_send_xchar(struct tty_struct *tty, char ch); 93static void cy_send_xchar(struct tty_struct *tty, char ch);
665 94
666#ifndef SERIAL_XMIT_SIZE 95#ifndef SERIAL_XMIT_SIZE
667#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096)) 96#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096))
668#endif 97#endif
669#define WAKEUP_CHARS 256
670 98
671#define STD_COM_FLAGS (0) 99#define STD_COM_FLAGS (0)
672 100
@@ -756,25 +184,25 @@ static int cy_next_channel; /* next minor available */
756 * HI VHI 184 * HI VHI
757 * 20 185 * 20
758 */ 186 */
759static int baud_table[] = { 187static const int baud_table[] = {
760 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 188 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
761 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, 189 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
762 230400, 0 190 230400, 0
763}; 191};
764 192
765static char baud_co_25[] = { /* 25 MHz clock option table */ 193static const char baud_co_25[] = { /* 25 MHz clock option table */
766 /* value => 00 01 02 03 04 */ 194 /* value => 00 01 02 03 04 */
767 /* divide by 8 32 128 512 2048 */ 195 /* divide by 8 32 128 512 2048 */
768 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 196 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
769 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 197 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
770}; 198};
771 199
772static char baud_bpr_25[] = { /* 25 MHz baud rate period table */ 200static const char baud_bpr_25[] = { /* 25 MHz baud rate period table */
773 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, 201 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
774 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 202 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
775}; 203};
776 204
777static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */ 205static const char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
778 /* value => 00 01 02 03 04 */ 206 /* value => 00 01 02 03 04 */
779 /* divide by 8 32 128 512 2048 */ 207 /* divide by 8 32 128 512 2048 */
780 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 208 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
@@ -782,13 +210,13 @@ static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
782 0x00 210 0x00
783}; 211};
784 212
785static char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */ 213static const char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */
786 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62, 214 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
787 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32, 215 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
788 0x21 216 0x21
789}; 217};
790 218
791static char baud_cor3[] = { /* receive threshold */ 219static const char baud_cor3[] = { /* receive threshold */
792 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 220 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
793 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, 221 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
794 0x07 222 0x07
@@ -805,7 +233,7 @@ static char baud_cor3[] = { /* receive threshold */
805 * cables. 233 * cables.
806 */ 234 */
807 235
808static char rflow_thr[] = { /* rflow threshold */ 236static const char rflow_thr[] = { /* rflow threshold */
809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 238 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
811 0x0a 239 0x0a
@@ -814,7 +242,7 @@ static char rflow_thr[] = { /* rflow threshold */
814/* The Cyclom-Ye has placed the sequential chips in non-sequential 242/* The Cyclom-Ye has placed the sequential chips in non-sequential
815 * address order. This look-up table overcomes that problem. 243 * address order. This look-up table overcomes that problem.
816 */ 244 */
817static int cy_chip_offset[] = { 0x0000, 245static const unsigned int cy_chip_offset[] = { 0x0000,
818 0x0400, 246 0x0400,
819 0x0800, 247 0x0800,
820 0x0C00, 248 0x0C00,
@@ -827,7 +255,7 @@ static int cy_chip_offset[] = { 0x0000,
827/* PCI related definitions */ 255/* PCI related definitions */
828 256
829#ifdef CONFIG_PCI 257#ifdef CONFIG_PCI
830static struct pci_device_id cy_pci_dev_id[] __devinitdata = { 258static const struct pci_device_id cy_pci_dev_id[] = {
831 /* PCI < 1Mb */ 259 /* PCI < 1Mb */
832 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, 260 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
833 /* PCI > 1Mb */ 261 /* PCI > 1Mb */
@@ -850,7 +278,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
850#endif 278#endif
851 279
852static void cy_start(struct tty_struct *); 280static void cy_start(struct tty_struct *);
853static void set_line_char(struct cyclades_port *); 281static void cy_set_line_char(struct cyclades_port *, struct tty_struct *);
854static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); 282static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
855#ifdef CONFIG_ISA 283#ifdef CONFIG_ISA
856static unsigned detect_isa_irq(void __iomem *); 284static unsigned detect_isa_irq(void __iomem *);
@@ -869,6 +297,20 @@ static void cyz_rx_restart(unsigned long);
869static struct timer_list cyz_rx_full_timer[NR_PORTS]; 297static struct timer_list cyz_rx_full_timer[NR_PORTS];
870#endif /* CONFIG_CYZ_INTR */ 298#endif /* CONFIG_CYZ_INTR */
871 299
300static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val)
301{
302 struct cyclades_card *card = port->card;
303
304 cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val);
305}
306
307static inline u8 cyy_readb(struct cyclades_port *port, u32 reg)
308{
309 struct cyclades_card *card = port->card;
310
311 return readb(port->u.cyy.base_addr + (reg << card->bus_index));
312}
313
872static inline bool cy_is_Z(struct cyclades_card *card) 314static inline bool cy_is_Z(struct cyclades_card *card)
873{ 315{
874 return card->num_chips == (unsigned int)-1; 316 return card->num_chips == (unsigned int)-1;
@@ -893,7 +335,7 @@ static inline bool cyz_is_loaded(struct cyclades_card *card)
893} 335}
894 336
895static inline int serial_paranoia_check(struct cyclades_port *info, 337static inline int serial_paranoia_check(struct cyclades_port *info,
896 char *name, const char *routine) 338 const char *name, const char *routine)
897{ 339{
898#ifdef SERIAL_PARANOIA_CHECK 340#ifdef SERIAL_PARANOIA_CHECK
899 if (!info) { 341 if (!info) {
@@ -909,7 +351,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
909 } 351 }
910#endif 352#endif
911 return 0; 353 return 0;
912} /* serial_paranoia_check */ 354}
913 355
914/***********************************************************/ 356/***********************************************************/
915/********* Start of block of Cyclom-Y specific code ********/ 357/********* Start of block of Cyclom-Y specific code ********/
@@ -921,13 +363,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
921 363
922 This function is only called from inside spinlock-protected code. 364 This function is only called from inside spinlock-protected code.
923 */ 365 */
924static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index) 366static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index)
925{ 367{
368 void __iomem *ccr = base_addr + (CyCCR << index);
926 unsigned int i; 369 unsigned int i;
927 370
928 /* Check to see that the previous command has completed */ 371 /* Check to see that the previous command has completed */
929 for (i = 0; i < 100; i++) { 372 for (i = 0; i < 100; i++) {
930 if (readb(base_addr + (CyCCR << index)) == 0) 373 if (readb(ccr) == 0)
931 break; 374 break;
932 udelay(10L); 375 udelay(10L);
933 } 376 }
@@ -937,10 +380,16 @@ static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
937 return -1; 380 return -1;
938 381
939 /* Issue the new command */ 382 /* Issue the new command */
940 cy_writeb(base_addr + (CyCCR << index), cmd); 383 cy_writeb(ccr, cmd);
941 384
942 return 0; 385 return 0;
943} /* cyy_issue_cmd */ 386}
387
388static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd)
389{
390 return __cyy_issue_cmd(port->u.cyy.base_addr, cmd,
391 port->card->bus_index);
392}
944 393
945#ifdef CONFIG_ISA 394#ifdef CONFIG_ISA
946/* ISA interrupt detection code */ 395/* ISA interrupt detection code */
@@ -960,12 +409,12 @@ static unsigned detect_isa_irq(void __iomem *address)
960 409
961 irqs = probe_irq_on(); 410 irqs = probe_irq_on();
962 /* Wait ... */ 411 /* Wait ... */
963 udelay(5000L); 412 msleep(5);
964 413
965 /* Enable the Tx interrupts on the CD1400 */ 414 /* Enable the Tx interrupts on the CD1400 */
966 local_irq_save(flags); 415 local_irq_save(flags);
967 cy_writeb(address + (CyCAR << index), 0); 416 cy_writeb(address + (CyCAR << index), 0);
968 cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); 417 __cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
969 418
970 cy_writeb(address + (CyCAR << index), 0); 419 cy_writeb(address + (CyCAR << index), 0);
971 cy_writeb(address + (CySRER << index), 420 cy_writeb(address + (CySRER << index),
@@ -973,7 +422,7 @@ static unsigned detect_isa_irq(void __iomem *address)
973 local_irq_restore(flags); 422 local_irq_restore(flags);
974 423
975 /* Wait ... */ 424 /* Wait ... */
976 udelay(5000L); 425 msleep(5);
977 426
978 /* Check which interrupt is in use */ 427 /* Check which interrupt is in use */
979 irq = probe_irq_off(irqs); 428 irq = probe_irq_off(irqs);
@@ -999,7 +448,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
999 struct cyclades_port *info; 448 struct cyclades_port *info;
1000 struct tty_struct *tty; 449 struct tty_struct *tty;
1001 int len, index = cinfo->bus_index; 450 int len, index = cinfo->bus_index;
1002 u8 save_xir, channel, save_car, data, char_count; 451 u8 ivr, save_xir, channel, save_car, data, char_count;
1003 452
1004#ifdef CY_DEBUG_INTERRUPTS 453#ifdef CY_DEBUG_INTERRUPTS
1005 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); 454 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
@@ -1008,26 +457,25 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1008 save_xir = readb(base_addr + (CyRIR << index)); 457 save_xir = readb(base_addr + (CyRIR << index));
1009 channel = save_xir & CyIRChannel; 458 channel = save_xir & CyIRChannel;
1010 info = &cinfo->ports[channel + chip * 4]; 459 info = &cinfo->ports[channel + chip * 4];
1011 save_car = readb(base_addr + (CyCAR << index)); 460 save_car = cyy_readb(info, CyCAR);
1012 cy_writeb(base_addr + (CyCAR << index), save_xir); 461 cyy_writeb(info, CyCAR, save_xir);
462 ivr = cyy_readb(info, CyRIVR) & CyIVRMask;
1013 463
464 tty = tty_port_tty_get(&info->port);
1014 /* if there is nowhere to put the data, discard it */ 465 /* if there is nowhere to put the data, discard it */
1015 if (info->port.tty == NULL) { 466 if (tty == NULL) {
1016 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == 467 if (ivr == CyIVRRxEx) { /* exception */
1017 CyIVRRxEx) { /* exception */ 468 data = cyy_readb(info, CyRDSR);
1018 data = readb(base_addr + (CyRDSR << index));
1019 } else { /* normal character reception */ 469 } else { /* normal character reception */
1020 char_count = readb(base_addr + (CyRDCR << index)); 470 char_count = cyy_readb(info, CyRDCR);
1021 while (char_count--) 471 while (char_count--)
1022 data = readb(base_addr + (CyRDSR << index)); 472 data = cyy_readb(info, CyRDSR);
1023 } 473 }
1024 goto end; 474 goto end;
1025 } 475 }
1026 /* there is an open port for this data */ 476 /* there is an open port for this data */
1027 tty = info->port.tty; 477 if (ivr == CyIVRRxEx) { /* exception */
1028 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == 478 data = cyy_readb(info, CyRDSR);
1029 CyIVRRxEx) { /* exception */
1030 data = readb(base_addr + (CyRDSR << index));
1031 479
1032 /* For statistics only */ 480 /* For statistics only */
1033 if (data & CyBREAK) 481 if (data & CyBREAK)
@@ -1041,28 +489,29 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1041 489
1042 if (data & info->ignore_status_mask) { 490 if (data & info->ignore_status_mask) {
1043 info->icount.rx++; 491 info->icount.rx++;
492 tty_kref_put(tty);
1044 return; 493 return;
1045 } 494 }
1046 if (tty_buffer_request_room(tty, 1)) { 495 if (tty_buffer_request_room(tty, 1)) {
1047 if (data & info->read_status_mask) { 496 if (data & info->read_status_mask) {
1048 if (data & CyBREAK) { 497 if (data & CyBREAK) {
1049 tty_insert_flip_char(tty, 498 tty_insert_flip_char(tty,
1050 readb(base_addr + (CyRDSR << 499 cyy_readb(info, CyRDSR),
1051 index)), TTY_BREAK); 500 TTY_BREAK);
1052 info->icount.rx++; 501 info->icount.rx++;
1053 if (info->port.flags & ASYNC_SAK) 502 if (info->port.flags & ASYNC_SAK)
1054 do_SAK(tty); 503 do_SAK(tty);
1055 } else if (data & CyFRAME) { 504 } else if (data & CyFRAME) {
1056 tty_insert_flip_char(tty, 505 tty_insert_flip_char(tty,
1057 readb(base_addr + (CyRDSR << 506 cyy_readb(info, CyRDSR),
1058 index)), TTY_FRAME); 507 TTY_FRAME);
1059 info->icount.rx++; 508 info->icount.rx++;
1060 info->idle_stats.frame_errs++; 509 info->idle_stats.frame_errs++;
1061 } else if (data & CyPARITY) { 510 } else if (data & CyPARITY) {
1062 /* Pieces of seven... */ 511 /* Pieces of seven... */
1063 tty_insert_flip_char(tty, 512 tty_insert_flip_char(tty,
1064 readb(base_addr + (CyRDSR << 513 cyy_readb(info, CyRDSR),
1065 index)), TTY_PARITY); 514 TTY_PARITY);
1066 info->icount.rx++; 515 info->icount.rx++;
1067 info->idle_stats.parity_errs++; 516 info->idle_stats.parity_errs++;
1068 } else if (data & CyOVERRUN) { 517 } else if (data & CyOVERRUN) {
@@ -1074,8 +523,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1074 the next incoming character. 523 the next incoming character.
1075 */ 524 */
1076 tty_insert_flip_char(tty, 525 tty_insert_flip_char(tty,
1077 readb(base_addr + (CyRDSR << 526 cyy_readb(info, CyRDSR),
1078 index)), TTY_FRAME); 527 TTY_FRAME);
1079 info->icount.rx++; 528 info->icount.rx++;
1080 info->idle_stats.overruns++; 529 info->idle_stats.overruns++;
1081 /* These two conditions may imply */ 530 /* These two conditions may imply */
@@ -1099,7 +548,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1099 } 548 }
1100 } else { /* normal character reception */ 549 } else { /* normal character reception */
1101 /* load # chars available from the chip */ 550 /* load # chars available from the chip */
1102 char_count = readb(base_addr + (CyRDCR << index)); 551 char_count = cyy_readb(info, CyRDCR);
1103 552
1104#ifdef CY_ENABLE_MONITORING 553#ifdef CY_ENABLE_MONITORING
1105 ++info->mon.int_count; 554 ++info->mon.int_count;
@@ -1110,7 +559,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1110#endif 559#endif
1111 len = tty_buffer_request_room(tty, char_count); 560 len = tty_buffer_request_room(tty, char_count);
1112 while (len--) { 561 while (len--) {
1113 data = readb(base_addr + (CyRDSR << index)); 562 data = cyy_readb(info, CyRDSR);
1114 tty_insert_flip_char(tty, data, TTY_NORMAL); 563 tty_insert_flip_char(tty, data, TTY_NORMAL);
1115 info->idle_stats.recv_bytes++; 564 info->idle_stats.recv_bytes++;
1116 info->icount.rx++; 565 info->icount.rx++;
@@ -1121,16 +570,18 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1121 info->idle_stats.recv_idle = jiffies; 570 info->idle_stats.recv_idle = jiffies;
1122 } 571 }
1123 tty_schedule_flip(tty); 572 tty_schedule_flip(tty);
573 tty_kref_put(tty);
1124end: 574end:
1125 /* end of service */ 575 /* end of service */
1126 cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); 576 cyy_writeb(info, CyRIR, save_xir & 0x3f);
1127 cy_writeb(base_addr + (CyCAR << index), save_car); 577 cyy_writeb(info, CyCAR, save_car);
1128} 578}
1129 579
1130static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, 580static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1131 void __iomem *base_addr) 581 void __iomem *base_addr)
1132{ 582{
1133 struct cyclades_port *info; 583 struct cyclades_port *info;
584 struct tty_struct *tty;
1134 int char_count, index = cinfo->bus_index; 585 int char_count, index = cinfo->bus_index;
1135 u8 save_xir, channel, save_car, outch; 586 u8 save_xir, channel, save_car, outch;
1136 587
@@ -1154,9 +605,9 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1154 goto end; 605 goto end;
1155 } 606 }
1156 info = &cinfo->ports[channel + chip * 4]; 607 info = &cinfo->ports[channel + chip * 4];
1157 if (info->port.tty == NULL) { 608 tty = tty_port_tty_get(&info->port);
1158 cy_writeb(base_addr + (CySRER << index), 609 if (tty == NULL) {
1159 readb(base_addr + (CySRER << index)) & ~CyTxRdy); 610 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
1160 goto end; 611 goto end;
1161 } 612 }
1162 613
@@ -1165,7 +616,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1165 616
1166 if (info->x_char) { /* send special char */ 617 if (info->x_char) { /* send special char */
1167 outch = info->x_char; 618 outch = info->x_char;
1168 cy_writeb(base_addr + (CyTDR << index), outch); 619 cyy_writeb(info, CyTDR, outch);
1169 char_count--; 620 char_count--;
1170 info->icount.tx++; 621 info->icount.tx++;
1171 info->x_char = 0; 622 info->x_char = 0;
@@ -1173,14 +624,14 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1173 624
1174 if (info->breakon || info->breakoff) { 625 if (info->breakon || info->breakoff) {
1175 if (info->breakon) { 626 if (info->breakon) {
1176 cy_writeb(base_addr + (CyTDR << index), 0); 627 cyy_writeb(info, CyTDR, 0);
1177 cy_writeb(base_addr + (CyTDR << index), 0x81); 628 cyy_writeb(info, CyTDR, 0x81);
1178 info->breakon = 0; 629 info->breakon = 0;
1179 char_count -= 2; 630 char_count -= 2;
1180 } 631 }
1181 if (info->breakoff) { 632 if (info->breakoff) {
1182 cy_writeb(base_addr + (CyTDR << index), 0); 633 cyy_writeb(info, CyTDR, 0);
1183 cy_writeb(base_addr + (CyTDR << index), 0x83); 634 cyy_writeb(info, CyTDR, 0x83);
1184 info->breakoff = 0; 635 info->breakoff = 0;
1185 char_count -= 2; 636 char_count -= 2;
1186 } 637 }
@@ -1188,27 +639,23 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1188 639
1189 while (char_count-- > 0) { 640 while (char_count-- > 0) {
1190 if (!info->xmit_cnt) { 641 if (!info->xmit_cnt) {
1191 if (readb(base_addr + (CySRER << index)) & CyTxMpty) { 642 if (cyy_readb(info, CySRER) & CyTxMpty) {
1192 cy_writeb(base_addr + (CySRER << index), 643 cyy_writeb(info, CySRER,
1193 readb(base_addr + (CySRER << index)) & 644 cyy_readb(info, CySRER) & ~CyTxMpty);
1194 ~CyTxMpty);
1195 } else { 645 } else {
1196 cy_writeb(base_addr + (CySRER << index), 646 cyy_writeb(info, CySRER, CyTxMpty |
1197 (readb(base_addr + (CySRER << index)) & 647 (cyy_readb(info, CySRER) & ~CyTxRdy));
1198 ~CyTxRdy) | CyTxMpty);
1199 } 648 }
1200 goto done; 649 goto done;
1201 } 650 }
1202 if (info->port.xmit_buf == NULL) { 651 if (info->port.xmit_buf == NULL) {
1203 cy_writeb(base_addr + (CySRER << index), 652 cyy_writeb(info, CySRER,
1204 readb(base_addr + (CySRER << index)) & 653 cyy_readb(info, CySRER) & ~CyTxRdy);
1205 ~CyTxRdy);
1206 goto done; 654 goto done;
1207 } 655 }
1208 if (info->port.tty->stopped || info->port.tty->hw_stopped) { 656 if (tty->stopped || tty->hw_stopped) {
1209 cy_writeb(base_addr + (CySRER << index), 657 cyy_writeb(info, CySRER,
1210 readb(base_addr + (CySRER << index)) & 658 cyy_readb(info, CySRER) & ~CyTxRdy);
1211 ~CyTxRdy);
1212 goto done; 659 goto done;
1213 } 660 }
1214 /* Because the Embedded Transmit Commands have been enabled, 661 /* Because the Embedded Transmit Commands have been enabled,
@@ -1225,15 +672,15 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1225 info->xmit_cnt--; 672 info->xmit_cnt--;
1226 info->xmit_tail = (info->xmit_tail + 1) & 673 info->xmit_tail = (info->xmit_tail + 1) &
1227 (SERIAL_XMIT_SIZE - 1); 674 (SERIAL_XMIT_SIZE - 1);
1228 cy_writeb(base_addr + (CyTDR << index), outch); 675 cyy_writeb(info, CyTDR, outch);
1229 info->icount.tx++; 676 info->icount.tx++;
1230 } else { 677 } else {
1231 if (char_count > 1) { 678 if (char_count > 1) {
1232 info->xmit_cnt--; 679 info->xmit_cnt--;
1233 info->xmit_tail = (info->xmit_tail + 1) & 680 info->xmit_tail = (info->xmit_tail + 1) &
1234 (SERIAL_XMIT_SIZE - 1); 681 (SERIAL_XMIT_SIZE - 1);
1235 cy_writeb(base_addr + (CyTDR << index), outch); 682 cyy_writeb(info, CyTDR, outch);
1236 cy_writeb(base_addr + (CyTDR << index), 0); 683 cyy_writeb(info, CyTDR, 0);
1237 info->icount.tx++; 684 info->icount.tx++;
1238 char_count--; 685 char_count--;
1239 } 686 }
@@ -1241,17 +688,19 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1241 } 688 }
1242 689
1243done: 690done:
1244 tty_wakeup(info->port.tty); 691 tty_wakeup(tty);
692 tty_kref_put(tty);
1245end: 693end:
1246 /* end of service */ 694 /* end of service */
1247 cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); 695 cyy_writeb(info, CyTIR, save_xir & 0x3f);
1248 cy_writeb(base_addr + (CyCAR << index), save_car); 696 cyy_writeb(info, CyCAR, save_car);
1249} 697}
1250 698
1251static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, 699static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1252 void __iomem *base_addr) 700 void __iomem *base_addr)
1253{ 701{
1254 struct cyclades_port *info; 702 struct cyclades_port *info;
703 struct tty_struct *tty;
1255 int index = cinfo->bus_index; 704 int index = cinfo->bus_index;
1256 u8 save_xir, channel, save_car, mdm_change, mdm_status; 705 u8 save_xir, channel, save_car, mdm_change, mdm_status;
1257 706
@@ -1259,13 +708,14 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1259 save_xir = readb(base_addr + (CyMIR << index)); 708 save_xir = readb(base_addr + (CyMIR << index));
1260 channel = save_xir & CyIRChannel; 709 channel = save_xir & CyIRChannel;
1261 info = &cinfo->ports[channel + chip * 4]; 710 info = &cinfo->ports[channel + chip * 4];
1262 save_car = readb(base_addr + (CyCAR << index)); 711 save_car = cyy_readb(info, CyCAR);
1263 cy_writeb(base_addr + (CyCAR << index), save_xir); 712 cyy_writeb(info, CyCAR, save_xir);
1264 713
1265 mdm_change = readb(base_addr + (CyMISR << index)); 714 mdm_change = cyy_readb(info, CyMISR);
1266 mdm_status = readb(base_addr + (CyMSVR1 << index)); 715 mdm_status = cyy_readb(info, CyMSVR1);
1267 716
1268 if (!info->port.tty) 717 tty = tty_port_tty_get(&info->port);
718 if (!tty)
1269 goto end; 719 goto end;
1270 720
1271 if (mdm_change & CyANY_DELTA) { 721 if (mdm_change & CyANY_DELTA) {
@@ -1279,35 +729,32 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1279 if (mdm_change & CyRI) 729 if (mdm_change & CyRI)
1280 info->icount.rng++; 730 info->icount.rng++;
1281 731
1282 wake_up_interruptible(&info->delta_msr_wait); 732 wake_up_interruptible(&info->port.delta_msr_wait);
1283 } 733 }
1284 734
1285 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) { 735 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
1286 if (!(mdm_status & CyDCD)) { 736 if (mdm_status & CyDCD)
1287 tty_hangup(info->port.tty); 737 wake_up_interruptible(&info->port.open_wait);
1288 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 738 else
1289 } 739 tty_hangup(tty);
1290 wake_up_interruptible(&info->port.open_wait);
1291 } 740 }
1292 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) { 741 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
1293 if (info->port.tty->hw_stopped) { 742 if (tty->hw_stopped) {
1294 if (mdm_status & CyCTS) { 743 if (mdm_status & CyCTS) {
1295 /* cy_start isn't used 744 /* cy_start isn't used
1296 because... !!! */ 745 because... !!! */
1297 info->port.tty->hw_stopped = 0; 746 tty->hw_stopped = 0;
1298 cy_writeb(base_addr + (CySRER << index), 747 cyy_writeb(info, CySRER,
1299 readb(base_addr + (CySRER << index)) | 748 cyy_readb(info, CySRER) | CyTxRdy);
1300 CyTxRdy); 749 tty_wakeup(tty);
1301 tty_wakeup(info->port.tty);
1302 } 750 }
1303 } else { 751 } else {
1304 if (!(mdm_status & CyCTS)) { 752 if (!(mdm_status & CyCTS)) {
1305 /* cy_stop isn't used 753 /* cy_stop isn't used
1306 because ... !!! */ 754 because ... !!! */
1307 info->port.tty->hw_stopped = 1; 755 tty->hw_stopped = 1;
1308 cy_writeb(base_addr + (CySRER << index), 756 cyy_writeb(info, CySRER,
1309 readb(base_addr + (CySRER << index)) & 757 cyy_readb(info, CySRER) & ~CyTxRdy);
1310 ~CyTxRdy);
1311 } 758 }
1312 } 759 }
1313 } 760 }
@@ -1315,10 +762,11 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1315 } 762 }
1316 if (mdm_change & CyRI) { 763 if (mdm_change & CyRI) {
1317 }*/ 764 }*/
765 tty_kref_put(tty);
1318end: 766end:
1319 /* end of service */ 767 /* end of service */
1320 cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); 768 cyy_writeb(info, CyMIR, save_xir & 0x3f);
1321 cy_writeb(base_addr + (CyCAR << index), save_car); 769 cyy_writeb(info, CyCAR, save_car);
1322} 770}
1323 771
1324/* The real interrupt service routine is called 772/* The real interrupt service routine is called
@@ -1389,6 +837,56 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1389 return IRQ_HANDLED; 837 return IRQ_HANDLED;
1390} /* cyy_interrupt */ 838} /* cyy_interrupt */
1391 839
840static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set,
841 unsigned int clear)
842{
843 struct cyclades_card *card = info->card;
844 int channel = info->line - card->first_line;
845 u32 rts, dtr, msvrr, msvrd;
846
847 channel &= 0x03;
848
849 if (info->rtsdtr_inv) {
850 msvrr = CyMSVR2;
851 msvrd = CyMSVR1;
852 rts = CyDTR;
853 dtr = CyRTS;
854 } else {
855 msvrr = CyMSVR1;
856 msvrd = CyMSVR2;
857 rts = CyRTS;
858 dtr = CyDTR;
859 }
860 if (set & TIOCM_RTS) {
861 cyy_writeb(info, CyCAR, channel);
862 cyy_writeb(info, msvrr, rts);
863 }
864 if (clear & TIOCM_RTS) {
865 cyy_writeb(info, CyCAR, channel);
866 cyy_writeb(info, msvrr, ~rts);
867 }
868 if (set & TIOCM_DTR) {
869 cyy_writeb(info, CyCAR, channel);
870 cyy_writeb(info, msvrd, dtr);
871#ifdef CY_DEBUG_DTR
872 printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
873 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
874 cyy_readb(info, CyMSVR1),
875 cyy_readb(info, CyMSVR2));
876#endif
877 }
878 if (clear & TIOCM_DTR) {
879 cyy_writeb(info, CyCAR, channel);
880 cyy_writeb(info, msvrd, ~dtr);
881#ifdef CY_DEBUG_DTR
882 printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
883 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
884 cyy_readb(info, CyMSVR1),
885 cyy_readb(info, CyMSVR2));
886#endif
887 }
888}
889
1392/***********************************************************/ 890/***********************************************************/
1393/********* End of block of Cyclom-Y specific code **********/ 891/********* End of block of Cyclom-Y specific code **********/
1394/******** Start of block of Cyclades-Z specific code *******/ 892/******** Start of block of Cyclades-Z specific code *******/
@@ -1398,15 +896,9 @@ static int
1398cyz_fetch_msg(struct cyclades_card *cinfo, 896cyz_fetch_msg(struct cyclades_card *cinfo,
1399 __u32 *channel, __u8 *cmd, __u32 *param) 897 __u32 *channel, __u8 *cmd, __u32 *param)
1400{ 898{
1401 struct FIRM_ID __iomem *firm_id; 899 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1402 struct ZFW_CTRL __iomem *zfw_ctrl;
1403 struct BOARD_CTRL __iomem *board_ctrl;
1404 unsigned long loc_doorbell; 900 unsigned long loc_doorbell;
1405 901
1406 firm_id = cinfo->base_addr + ID_ADDRESS;
1407 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1408 board_ctrl = &zfw_ctrl->board_ctrl;
1409
1410 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell); 902 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
1411 if (loc_doorbell) { 903 if (loc_doorbell) {
1412 *cmd = (char)(0xff & loc_doorbell); 904 *cmd = (char)(0xff & loc_doorbell);
@@ -1422,19 +914,13 @@ static int
1422cyz_issue_cmd(struct cyclades_card *cinfo, 914cyz_issue_cmd(struct cyclades_card *cinfo,
1423 __u32 channel, __u8 cmd, __u32 param) 915 __u32 channel, __u8 cmd, __u32 param)
1424{ 916{
1425 struct FIRM_ID __iomem *firm_id; 917 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1426 struct ZFW_CTRL __iomem *zfw_ctrl;
1427 struct BOARD_CTRL __iomem *board_ctrl;
1428 __u32 __iomem *pci_doorbell; 918 __u32 __iomem *pci_doorbell;
1429 unsigned int index; 919 unsigned int index;
1430 920
1431 firm_id = cinfo->base_addr + ID_ADDRESS;
1432 if (!cyz_is_loaded(cinfo)) 921 if (!cyz_is_loaded(cinfo))
1433 return -1; 922 return -1;
1434 923
1435 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1436 board_ctrl = &zfw_ctrl->board_ctrl;
1437
1438 index = 0; 924 index = 0;
1439 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell; 925 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
1440 while ((readl(pci_doorbell) & 0xff) != 0) { 926 while ((readl(pci_doorbell) & 0xff) != 0) {
@@ -1449,11 +935,10 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
1449 return 0; 935 return 0;
1450} /* cyz_issue_cmd */ 936} /* cyz_issue_cmd */
1451 937
1452static void cyz_handle_rx(struct cyclades_port *info, 938static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
1453 struct BUF_CTRL __iomem *buf_ctrl)
1454{ 939{
940 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1455 struct cyclades_card *cinfo = info->card; 941 struct cyclades_card *cinfo = info->card;
1456 struct tty_struct *tty = info->port.tty;
1457 unsigned int char_count; 942 unsigned int char_count;
1458 int len; 943 int len;
1459#ifdef BLOCKMOVE 944#ifdef BLOCKMOVE
@@ -1542,11 +1027,10 @@ static void cyz_handle_rx(struct cyclades_port *info,
1542 } 1027 }
1543} 1028}
1544 1029
1545static void cyz_handle_tx(struct cyclades_port *info, 1030static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
1546 struct BUF_CTRL __iomem *buf_ctrl)
1547{ 1031{
1032 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1548 struct cyclades_card *cinfo = info->card; 1033 struct cyclades_card *cinfo = info->card;
1549 struct tty_struct *tty = info->port.tty;
1550 u8 data; 1034 u8 data;
1551 unsigned int char_count; 1035 unsigned int char_count;
1552#ifdef BLOCKMOVE 1036#ifdef BLOCKMOVE
@@ -1621,34 +1105,24 @@ ztxdone:
1621 1105
1622static void cyz_handle_cmd(struct cyclades_card *cinfo) 1106static void cyz_handle_cmd(struct cyclades_card *cinfo)
1623{ 1107{
1108 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1624 struct tty_struct *tty; 1109 struct tty_struct *tty;
1625 struct cyclades_port *info; 1110 struct cyclades_port *info;
1626 static struct FIRM_ID __iomem *firm_id;
1627 static struct ZFW_CTRL __iomem *zfw_ctrl;
1628 static struct BOARD_CTRL __iomem *board_ctrl;
1629 static struct CH_CTRL __iomem *ch_ctrl;
1630 static struct BUF_CTRL __iomem *buf_ctrl;
1631 __u32 channel, param, fw_ver; 1111 __u32 channel, param, fw_ver;
1632 __u8 cmd; 1112 __u8 cmd;
1633 int special_count; 1113 int special_count;
1634 int delta_count; 1114 int delta_count;
1635 1115
1636 firm_id = cinfo->base_addr + ID_ADDRESS;
1637 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1638 board_ctrl = &zfw_ctrl->board_ctrl;
1639 fw_ver = readl(&board_ctrl->fw_version); 1116 fw_ver = readl(&board_ctrl->fw_version);
1640 1117
1641 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) { 1118 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1642 special_count = 0; 1119 special_count = 0;
1643 delta_count = 0; 1120 delta_count = 0;
1644 info = &cinfo->ports[channel]; 1121 info = &cinfo->ports[channel];
1645 tty = info->port.tty; 1122 tty = tty_port_tty_get(&info->port);
1646 if (tty == NULL) 1123 if (tty == NULL)
1647 continue; 1124 continue;
1648 1125
1649 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1650 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1651
1652 switch (cmd) { 1126 switch (cmd) {
1653 case C_CM_PR_ERROR: 1127 case C_CM_PR_ERROR:
1654 tty_insert_flip_char(tty, 0, TTY_PARITY); 1128 tty_insert_flip_char(tty, 0, TTY_PARITY);
@@ -1669,15 +1143,12 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1669 info->icount.dcd++; 1143 info->icount.dcd++;
1670 delta_count++; 1144 delta_count++;
1671 if (info->port.flags & ASYNC_CHECK_CD) { 1145 if (info->port.flags & ASYNC_CHECK_CD) {
1672 if ((fw_ver > 241 ? ((u_long) param) : 1146 u32 dcd = fw_ver > 241 ? param :
1673 readl(&ch_ctrl->rs_status)) & 1147 readl(&info->u.cyz.ch_ctrl->rs_status);
1674 C_RS_DCD) { 1148 if (dcd & C_RS_DCD)
1675 wake_up_interruptible(&info->port.open_wait); 1149 wake_up_interruptible(&info->port.open_wait);
1676 } else { 1150 else
1677 tty_hangup(info->port.tty); 1151 tty_hangup(tty);
1678 wake_up_interruptible(&info->port.open_wait);
1679 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1680 }
1681 } 1152 }
1682 break; 1153 break;
1683 case C_CM_MCTS: 1154 case C_CM_MCTS:
@@ -1706,7 +1177,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1706 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " 1177 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1707 "port %ld\n", info->card, channel); 1178 "port %ld\n", info->card, channel);
1708#endif 1179#endif
1709 cyz_handle_rx(info, buf_ctrl); 1180 cyz_handle_rx(info, tty);
1710 break; 1181 break;
1711 case C_CM_TXBEMPTY: 1182 case C_CM_TXBEMPTY:
1712 case C_CM_TXLOWWM: 1183 case C_CM_TXLOWWM:
@@ -1716,7 +1187,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1716 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " 1187 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1717 "port %ld\n", info->card, channel); 1188 "port %ld\n", info->card, channel);
1718#endif 1189#endif
1719 cyz_handle_tx(info, buf_ctrl); 1190 cyz_handle_tx(info, tty);
1720 break; 1191 break;
1721#endif /* CONFIG_CYZ_INTR */ 1192#endif /* CONFIG_CYZ_INTR */
1722 case C_CM_FATAL: 1193 case C_CM_FATAL:
@@ -1726,9 +1197,10 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1726 break; 1197 break;
1727 } 1198 }
1728 if (delta_count) 1199 if (delta_count)
1729 wake_up_interruptible(&info->delta_msr_wait); 1200 wake_up_interruptible(&info->port.delta_msr_wait);
1730 if (special_count) 1201 if (special_count)
1731 tty_schedule_flip(tty); 1202 tty_schedule_flip(tty);
1203 tty_kref_put(tty);
1732 } 1204 }
1733} 1205}
1734 1206
@@ -1774,10 +1246,6 @@ static void cyz_poll(unsigned long arg)
1774{ 1246{
1775 struct cyclades_card *cinfo; 1247 struct cyclades_card *cinfo;
1776 struct cyclades_port *info; 1248 struct cyclades_port *info;
1777 struct tty_struct *tty;
1778 struct FIRM_ID __iomem *firm_id;
1779 struct ZFW_CTRL __iomem *zfw_ctrl;
1780 struct BUF_CTRL __iomem *buf_ctrl;
1781 unsigned long expires = jiffies + HZ; 1249 unsigned long expires = jiffies + HZ;
1782 unsigned int port, card; 1250 unsigned int port, card;
1783 1251
@@ -1789,10 +1257,6 @@ static void cyz_poll(unsigned long arg)
1789 if (!cyz_is_loaded(cinfo)) 1257 if (!cyz_is_loaded(cinfo))
1790 continue; 1258 continue;
1791 1259
1792 firm_id = cinfo->base_addr + ID_ADDRESS;
1793 zfw_ctrl = cinfo->base_addr +
1794 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1795
1796 /* Skip first polling cycle to avoid racing conditions with the FW */ 1260 /* Skip first polling cycle to avoid racing conditions with the FW */
1797 if (!cinfo->intr_enabled) { 1261 if (!cinfo->intr_enabled) {
1798 cinfo->intr_enabled = 1; 1262 cinfo->intr_enabled = 1;
@@ -1802,13 +1266,17 @@ static void cyz_poll(unsigned long arg)
1802 cyz_handle_cmd(cinfo); 1266 cyz_handle_cmd(cinfo);
1803 1267
1804 for (port = 0; port < cinfo->nports; port++) { 1268 for (port = 0; port < cinfo->nports; port++) {
1269 struct tty_struct *tty;
1270
1805 info = &cinfo->ports[port]; 1271 info = &cinfo->ports[port];
1806 tty = info->port.tty; 1272 tty = tty_port_tty_get(&info->port);
1807 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); 1273 /* OK to pass NULL to the handle functions below.
1274 They need to drop the data in that case. */
1808 1275
1809 if (!info->throttle) 1276 if (!info->throttle)
1810 cyz_handle_rx(info, buf_ctrl); 1277 cyz_handle_rx(info, tty);
1811 cyz_handle_tx(info, buf_ctrl); 1278 cyz_handle_tx(info, tty);
1279 tty_kref_put(tty);
1812 } 1280 }
1813 /* poll every 'cyz_polling_cycle' period */ 1281 /* poll every 'cyz_polling_cycle' period */
1814 expires = jiffies + cyz_polling_cycle; 1282 expires = jiffies + cyz_polling_cycle;
@@ -1824,13 +1292,12 @@ static void cyz_poll(unsigned long arg)
1824/* This is called whenever a port becomes active; 1292/* This is called whenever a port becomes active;
1825 interrupts are enabled and DTR & RTS are turned on. 1293 interrupts are enabled and DTR & RTS are turned on.
1826 */ 1294 */
1827static int startup(struct cyclades_port *info) 1295static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
1828{ 1296{
1829 struct cyclades_card *card; 1297 struct cyclades_card *card;
1830 unsigned long flags; 1298 unsigned long flags;
1831 int retval = 0; 1299 int retval = 0;
1832 void __iomem *base_addr; 1300 int channel;
1833 int chip, channel, index;
1834 unsigned long page; 1301 unsigned long page;
1835 1302
1836 card = info->card; 1303 card = info->card;
@@ -1842,15 +1309,11 @@ static int startup(struct cyclades_port *info)
1842 1309
1843 spin_lock_irqsave(&card->card_lock, flags); 1310 spin_lock_irqsave(&card->card_lock, flags);
1844 1311
1845 if (info->port.flags & ASYNC_INITIALIZED) { 1312 if (info->port.flags & ASYNC_INITIALIZED)
1846 free_page(page);
1847 goto errout; 1313 goto errout;
1848 }
1849 1314
1850 if (!info->type) { 1315 if (!info->type) {
1851 if (info->port.tty) 1316 set_bit(TTY_IO_ERROR, &tty->flags);
1852 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1853 free_page(page);
1854 goto errout; 1317 goto errout;
1855 } 1318 }
1856 1319
@@ -1861,96 +1324,53 @@ static int startup(struct cyclades_port *info)
1861 1324
1862 spin_unlock_irqrestore(&card->card_lock, flags); 1325 spin_unlock_irqrestore(&card->card_lock, flags);
1863 1326
1864 set_line_char(info); 1327 cy_set_line_char(info, tty);
1865 1328
1866 if (!cy_is_Z(card)) { 1329 if (!cy_is_Z(card)) {
1867 chip = channel >> 2;
1868 channel &= 0x03; 1330 channel &= 0x03;
1869 index = card->bus_index;
1870 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1871 1331
1872#ifdef CY_DEBUG_OPEN
1873 printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
1874 "base_addr %p\n",
1875 card, chip, channel, base_addr);
1876#endif
1877 spin_lock_irqsave(&card->card_lock, flags); 1332 spin_lock_irqsave(&card->card_lock, flags);
1878 1333
1879 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 1334 cyy_writeb(info, CyCAR, channel);
1880 1335
1881 cy_writeb(base_addr + (CyRTPR << index), 1336 cyy_writeb(info, CyRTPR,
1882 (info->default_timeout ? info->default_timeout : 0x02)); 1337 (info->default_timeout ? info->default_timeout : 0x02));
1883 /* 10ms rx timeout */ 1338 /* 10ms rx timeout */
1884 1339
1885 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR, 1340 cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR);
1886 index);
1887
1888 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
1889 cy_writeb(base_addr + (CyMSVR1 << index), CyRTS);
1890 cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
1891
1892#ifdef CY_DEBUG_DTR
1893 printk(KERN_DEBUG "cyc:startup raising DTR\n");
1894 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
1895 readb(base_addr + (CyMSVR1 << index)),
1896 readb(base_addr + (CyMSVR2 << index)));
1897#endif
1898
1899 cy_writeb(base_addr + (CySRER << index),
1900 readb(base_addr + (CySRER << index)) | CyRxData);
1901 info->port.flags |= ASYNC_INITIALIZED;
1902
1903 if (info->port.tty)
1904 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
1905 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1906 info->breakon = info->breakoff = 0;
1907 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
1908 info->idle_stats.in_use =
1909 info->idle_stats.recv_idle =
1910 info->idle_stats.xmit_idle = jiffies;
1911 1341
1912 spin_unlock_irqrestore(&card->card_lock, flags); 1342 cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0);
1913 1343
1344 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData);
1914 } else { 1345 } else {
1915 struct FIRM_ID __iomem *firm_id; 1346 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1916 struct ZFW_CTRL __iomem *zfw_ctrl;
1917 struct BOARD_CTRL __iomem *board_ctrl;
1918 struct CH_CTRL __iomem *ch_ctrl;
1919 1347
1920 base_addr = card->base_addr;
1921
1922 firm_id = base_addr + ID_ADDRESS;
1923 if (!cyz_is_loaded(card)) 1348 if (!cyz_is_loaded(card))
1924 return -ENODEV; 1349 return -ENODEV;
1925 1350
1926 zfw_ctrl = card->base_addr +
1927 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1928 board_ctrl = &zfw_ctrl->board_ctrl;
1929 ch_ctrl = zfw_ctrl->ch_ctrl;
1930
1931#ifdef CY_DEBUG_OPEN 1351#ifdef CY_DEBUG_OPEN
1932 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " 1352 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
1933 "base_addr %p\n", card, channel, base_addr); 1353 "base_addr %p\n", card, channel, card->base_addr);
1934#endif 1354#endif
1935 spin_lock_irqsave(&card->card_lock, flags); 1355 spin_lock_irqsave(&card->card_lock, flags);
1936 1356
1937 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); 1357 cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE);
1938#ifdef Z_WAKE 1358#ifdef Z_WAKE
1939#ifdef CONFIG_CYZ_INTR 1359#ifdef CONFIG_CYZ_INTR
1940 cy_writel(&ch_ctrl[channel].intr_enable, 1360 cy_writel(&ch_ctrl->intr_enable,
1941 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | 1361 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1942 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD); 1362 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
1943#else 1363#else
1944 cy_writel(&ch_ctrl[channel].intr_enable, 1364 cy_writel(&ch_ctrl->intr_enable,
1945 C_IN_IOCTLW | C_IN_MDCD); 1365 C_IN_IOCTLW | C_IN_MDCD);
1946#endif /* CONFIG_CYZ_INTR */ 1366#endif /* CONFIG_CYZ_INTR */
1947#else 1367#else
1948#ifdef CONFIG_CYZ_INTR 1368#ifdef CONFIG_CYZ_INTR
1949 cy_writel(&ch_ctrl[channel].intr_enable, 1369 cy_writel(&ch_ctrl->intr_enable,
1950 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | 1370 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1951 C_IN_RXNNDT | C_IN_MDCD); 1371 C_IN_RXNNDT | C_IN_MDCD);
1952#else 1372#else
1953 cy_writel(&ch_ctrl[channel].intr_enable, C_IN_MDCD); 1373 cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD);
1954#endif /* CONFIG_CYZ_INTR */ 1374#endif /* CONFIG_CYZ_INTR */
1955#endif /* Z_WAKE */ 1375#endif /* Z_WAKE */
1956 1376
@@ -1969,32 +1389,22 @@ static int startup(struct cyclades_port *info)
1969 1389
1970 /* set timeout !!! */ 1390 /* set timeout !!! */
1971 /* set RTS and DTR !!! */ 1391 /* set RTS and DTR !!! */
1972 cy_writel(&ch_ctrl[channel].rs_control, 1392 tty_port_raise_dtr_rts(&info->port);
1973 readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
1974 C_RS_DTR);
1975 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
1976 if (retval != 0) {
1977 printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
1978 "%x\n", info->line, retval);
1979 }
1980#ifdef CY_DEBUG_DTR
1981 printk(KERN_DEBUG "cyc:startup raising Z DTR\n");
1982#endif
1983 1393
1984 /* enable send, recv, modem !!! */ 1394 /* enable send, recv, modem !!! */
1395 }
1985 1396
1986 info->port.flags |= ASYNC_INITIALIZED; 1397 info->port.flags |= ASYNC_INITIALIZED;
1987 if (info->port.tty)
1988 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
1989 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1990 info->breakon = info->breakoff = 0;
1991 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
1992 info->idle_stats.in_use =
1993 info->idle_stats.recv_idle =
1994 info->idle_stats.xmit_idle = jiffies;
1995 1398
1996 spin_unlock_irqrestore(&card->card_lock, flags); 1399 clear_bit(TTY_IO_ERROR, &tty->flags);
1997 } 1400 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1401 info->breakon = info->breakoff = 0;
1402 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
1403 info->idle_stats.in_use =
1404 info->idle_stats.recv_idle =
1405 info->idle_stats.xmit_idle = jiffies;
1406
1407 spin_unlock_irqrestore(&card->card_lock, flags);
1998 1408
1999#ifdef CY_DEBUG_OPEN 1409#ifdef CY_DEBUG_OPEN
2000 printk(KERN_DEBUG "cyc startup done\n"); 1410 printk(KERN_DEBUG "cyc startup done\n");
@@ -2003,28 +1413,20 @@ static int startup(struct cyclades_port *info)
2003 1413
2004errout: 1414errout:
2005 spin_unlock_irqrestore(&card->card_lock, flags); 1415 spin_unlock_irqrestore(&card->card_lock, flags);
1416 free_page(page);
2006 return retval; 1417 return retval;
2007} /* startup */ 1418} /* startup */
2008 1419
2009static void start_xmit(struct cyclades_port *info) 1420static void start_xmit(struct cyclades_port *info)
2010{ 1421{
2011 struct cyclades_card *card; 1422 struct cyclades_card *card = info->card;
2012 unsigned long flags; 1423 unsigned long flags;
2013 void __iomem *base_addr; 1424 int channel = info->line - card->first_line;
2014 int chip, channel, index;
2015 1425
2016 card = info->card;
2017 channel = info->line - card->first_line;
2018 if (!cy_is_Z(card)) { 1426 if (!cy_is_Z(card)) {
2019 chip = channel >> 2;
2020 channel &= 0x03;
2021 index = card->bus_index;
2022 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2023
2024 spin_lock_irqsave(&card->card_lock, flags); 1427 spin_lock_irqsave(&card->card_lock, flags);
2025 cy_writeb(base_addr + (CyCAR << index), channel); 1428 cyy_writeb(info, CyCAR, channel & 0x03);
2026 cy_writeb(base_addr + (CySRER << index), 1429 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
2027 readb(base_addr + (CySRER << index)) | CyTxRdy);
2028 spin_unlock_irqrestore(&card->card_lock, flags); 1430 spin_unlock_irqrestore(&card->card_lock, flags);
2029 } else { 1431 } else {
2030#ifdef CONFIG_CYZ_INTR 1432#ifdef CONFIG_CYZ_INTR
@@ -2047,12 +1449,11 @@ static void start_xmit(struct cyclades_port *info)
2047 * This routine shuts down a serial port; interrupts are disabled, 1449 * This routine shuts down a serial port; interrupts are disabled,
2048 * and DTR is dropped if the hangup on close termio flag is on. 1450 * and DTR is dropped if the hangup on close termio flag is on.
2049 */ 1451 */
2050static void shutdown(struct cyclades_port *info) 1452static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
2051{ 1453{
2052 struct cyclades_card *card; 1454 struct cyclades_card *card;
2053 unsigned long flags; 1455 unsigned long flags;
2054 void __iomem *base_addr; 1456 int channel;
2055 int chip, channel, index;
2056 1457
2057 if (!(info->port.flags & ASYNC_INITIALIZED)) 1458 if (!(info->port.flags & ASYNC_INITIALIZED))
2058 return; 1459 return;
@@ -2060,21 +1461,10 @@ static void shutdown(struct cyclades_port *info)
2060 card = info->card; 1461 card = info->card;
2061 channel = info->line - card->first_line; 1462 channel = info->line - card->first_line;
2062 if (!cy_is_Z(card)) { 1463 if (!cy_is_Z(card)) {
2063 chip = channel >> 2;
2064 channel &= 0x03;
2065 index = card->bus_index;
2066 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2067
2068#ifdef CY_DEBUG_OPEN
2069 printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
2070 "channel %d, base_addr %p\n",
2071 card, chip, channel, base_addr);
2072#endif
2073
2074 spin_lock_irqsave(&card->card_lock, flags); 1464 spin_lock_irqsave(&card->card_lock, flags);
2075 1465
2076 /* Clear delta_msr_wait queue to avoid mem leaks. */ 1466 /* Clear delta_msr_wait queue to avoid mem leaks. */
2077 wake_up_interruptible(&info->delta_msr_wait); 1467 wake_up_interruptible(&info->port.delta_msr_wait);
2078 1468
2079 if (info->port.xmit_buf) { 1469 if (info->port.xmit_buf) {
2080 unsigned char *temp; 1470 unsigned char *temp;
@@ -2082,47 +1472,25 @@ static void shutdown(struct cyclades_port *info)
2082 info->port.xmit_buf = NULL; 1472 info->port.xmit_buf = NULL;
2083 free_page((unsigned long)temp); 1473 free_page((unsigned long)temp);
2084 } 1474 }
2085 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 1475 if (tty->termios->c_cflag & HUPCL)
2086 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { 1476 cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR);
2087 cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); 1477
2088 cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); 1478 cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR);
2089#ifdef CY_DEBUG_DTR
2090 printk(KERN_DEBUG "cyc shutdown dropping DTR\n");
2091 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
2092 readb(base_addr + (CyMSVR1 << index)),
2093 readb(base_addr + (CyMSVR2 << index)));
2094#endif
2095 }
2096 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
2097 /* it may be appropriate to clear _XMIT at 1479 /* it may be appropriate to clear _XMIT at
2098 some later date (after testing)!!! */ 1480 some later date (after testing)!!! */
2099 1481
2100 if (info->port.tty) 1482 set_bit(TTY_IO_ERROR, &tty->flags);
2101 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2102 info->port.flags &= ~ASYNC_INITIALIZED; 1483 info->port.flags &= ~ASYNC_INITIALIZED;
2103 spin_unlock_irqrestore(&card->card_lock, flags); 1484 spin_unlock_irqrestore(&card->card_lock, flags);
2104 } else { 1485 } else {
2105 struct FIRM_ID __iomem *firm_id;
2106 struct ZFW_CTRL __iomem *zfw_ctrl;
2107 struct BOARD_CTRL __iomem *board_ctrl;
2108 struct CH_CTRL __iomem *ch_ctrl;
2109 int retval;
2110
2111 base_addr = card->base_addr;
2112#ifdef CY_DEBUG_OPEN 1486#ifdef CY_DEBUG_OPEN
2113 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " 1487 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
2114 "base_addr %p\n", card, channel, base_addr); 1488 "base_addr %p\n", card, channel, card->base_addr);
2115#endif 1489#endif
2116 1490
2117 firm_id = base_addr + ID_ADDRESS;
2118 if (!cyz_is_loaded(card)) 1491 if (!cyz_is_loaded(card))
2119 return; 1492 return;
2120 1493
2121 zfw_ctrl = card->base_addr +
2122 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2123 board_ctrl = &zfw_ctrl->board_ctrl;
2124 ch_ctrl = zfw_ctrl->ch_ctrl;
2125
2126 spin_lock_irqsave(&card->card_lock, flags); 1494 spin_lock_irqsave(&card->card_lock, flags);
2127 1495
2128 if (info->port.xmit_buf) { 1496 if (info->port.xmit_buf) {
@@ -2132,23 +1500,10 @@ static void shutdown(struct cyclades_port *info)
2132 free_page((unsigned long)temp); 1500 free_page((unsigned long)temp);
2133 } 1501 }
2134 1502
2135 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { 1503 if (tty->termios->c_cflag & HUPCL)
2136 cy_writel(&ch_ctrl[channel].rs_control, 1504 tty_port_lower_dtr_rts(&info->port);
2137 (__u32)(readl(&ch_ctrl[channel].rs_control) &
2138 ~(C_RS_RTS | C_RS_DTR)));
2139 retval = cyz_issue_cmd(info->card, channel,
2140 C_CM_IOCTLM, 0L);
2141 if (retval != 0) {
2142 printk(KERN_ERR"cyc:shutdown retval on ttyC%d "
2143 "was %x\n", info->line, retval);
2144 }
2145#ifdef CY_DEBUG_DTR
2146 printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n");
2147#endif
2148 }
2149 1505
2150 if (info->port.tty) 1506 set_bit(TTY_IO_ERROR, &tty->flags);
2151 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2152 info->port.flags &= ~ASYNC_INITIALIZED; 1507 info->port.flags &= ~ASYNC_INITIALIZED;
2153 1508
2154 spin_unlock_irqrestore(&card->card_lock, flags); 1509 spin_unlock_irqrestore(&card->card_lock, flags);
@@ -2165,199 +1520,6 @@ static void shutdown(struct cyclades_port *info)
2165 * ------------------------------------------------------------ 1520 * ------------------------------------------------------------
2166 */ 1521 */
2167 1522
2168static int
2169block_til_ready(struct tty_struct *tty, struct file *filp,
2170 struct cyclades_port *info)
2171{
2172 DECLARE_WAITQUEUE(wait, current);
2173 struct cyclades_card *cinfo;
2174 unsigned long flags;
2175 int chip, channel, index;
2176 int retval;
2177 void __iomem *base_addr;
2178
2179 cinfo = info->card;
2180 channel = info->line - cinfo->first_line;
2181
2182 /*
2183 * If the device is in the middle of being closed, then block
2184 * until it's done, and then try again.
2185 */
2186 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
2187 wait_event_interruptible(info->port.close_wait,
2188 !(info->port.flags & ASYNC_CLOSING));
2189 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2190 }
2191
2192 /*
2193 * If non-blocking mode is set, then make the check up front
2194 * and then exit.
2195 */
2196 if ((filp->f_flags & O_NONBLOCK) ||
2197 (tty->flags & (1 << TTY_IO_ERROR))) {
2198 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2199 return 0;
2200 }
2201
2202 /*
2203 * Block waiting for the carrier detect and the line to become
2204 * free (i.e., not in use by the callout). While we are in
2205 * this loop, info->port.count is dropped by one, so that
2206 * cy_close() knows when to free things. We restore it upon
2207 * exit, either normal or abnormal.
2208 */
2209 retval = 0;
2210 add_wait_queue(&info->port.open_wait, &wait);
2211#ifdef CY_DEBUG_OPEN
2212 printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
2213 "count = %d\n", info->line, info->port.count);
2214#endif
2215 spin_lock_irqsave(&cinfo->card_lock, flags);
2216 if (!tty_hung_up_p(filp))
2217 info->port.count--;
2218 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2219#ifdef CY_DEBUG_COUNT
2220 printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
2221 "%d\n", current->pid, info->port.count);
2222#endif
2223 info->port.blocked_open++;
2224
2225 if (!cy_is_Z(cinfo)) {
2226 chip = channel >> 2;
2227 channel &= 0x03;
2228 index = cinfo->bus_index;
2229 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
2230
2231 while (1) {
2232 spin_lock_irqsave(&cinfo->card_lock, flags);
2233 if ((tty->termios->c_cflag & CBAUD)) {
2234 cy_writeb(base_addr + (CyCAR << index),
2235 (u_char) channel);
2236 cy_writeb(base_addr + (CyMSVR1 << index),
2237 CyRTS);
2238 cy_writeb(base_addr + (CyMSVR2 << index),
2239 CyDTR);
2240#ifdef CY_DEBUG_DTR
2241 printk(KERN_DEBUG "cyc:block_til_ready raising "
2242 "DTR\n");
2243 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
2244 readb(base_addr + (CyMSVR1 << index)),
2245 readb(base_addr + (CyMSVR2 << index)));
2246#endif
2247 }
2248 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2249
2250 set_current_state(TASK_INTERRUPTIBLE);
2251 if (tty_hung_up_p(filp) ||
2252 !(info->port.flags & ASYNC_INITIALIZED)) {
2253 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
2254 -EAGAIN : -ERESTARTSYS);
2255 break;
2256 }
2257
2258 spin_lock_irqsave(&cinfo->card_lock, flags);
2259 cy_writeb(base_addr + (CyCAR << index),
2260 (u_char) channel);
2261 if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2262 (readb(base_addr +
2263 (CyMSVR1 << index)) & CyDCD))) {
2264 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2265 break;
2266 }
2267 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2268
2269 if (signal_pending(current)) {
2270 retval = -ERESTARTSYS;
2271 break;
2272 }
2273#ifdef CY_DEBUG_OPEN
2274 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2275 "ttyC%d, count = %d\n",
2276 info->line, info->port.count);
2277#endif
2278 schedule();
2279 }
2280 } else {
2281 struct FIRM_ID __iomem *firm_id;
2282 struct ZFW_CTRL __iomem *zfw_ctrl;
2283 struct BOARD_CTRL __iomem *board_ctrl;
2284 struct CH_CTRL __iomem *ch_ctrl;
2285
2286 base_addr = cinfo->base_addr;
2287 firm_id = base_addr + ID_ADDRESS;
2288 if (!cyz_is_loaded(cinfo)) {
2289 __set_current_state(TASK_RUNNING);
2290 remove_wait_queue(&info->port.open_wait, &wait);
2291 return -EINVAL;
2292 }
2293
2294 zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)
2295 & 0xfffff);
2296 board_ctrl = &zfw_ctrl->board_ctrl;
2297 ch_ctrl = zfw_ctrl->ch_ctrl;
2298
2299 while (1) {
2300 if ((tty->termios->c_cflag & CBAUD)) {
2301 cy_writel(&ch_ctrl[channel].rs_control,
2302 readl(&ch_ctrl[channel].rs_control) |
2303 C_RS_RTS | C_RS_DTR);
2304 retval = cyz_issue_cmd(cinfo,
2305 channel, C_CM_IOCTLM, 0L);
2306 if (retval != 0) {
2307 printk(KERN_ERR "cyc:block_til_ready "
2308 "retval on ttyC%d was %x\n",
2309 info->line, retval);
2310 }
2311#ifdef CY_DEBUG_DTR
2312 printk(KERN_DEBUG "cyc:block_til_ready raising "
2313 "Z DTR\n");
2314#endif
2315 }
2316
2317 set_current_state(TASK_INTERRUPTIBLE);
2318 if (tty_hung_up_p(filp) ||
2319 !(info->port.flags & ASYNC_INITIALIZED)) {
2320 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
2321 -EAGAIN : -ERESTARTSYS);
2322 break;
2323 }
2324 if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2325 (readl(&ch_ctrl[channel].rs_status) &
2326 C_RS_DCD))) {
2327 break;
2328 }
2329 if (signal_pending(current)) {
2330 retval = -ERESTARTSYS;
2331 break;
2332 }
2333#ifdef CY_DEBUG_OPEN
2334 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2335 "ttyC%d, count = %d\n",
2336 info->line, info->port.count);
2337#endif
2338 schedule();
2339 }
2340 }
2341 __set_current_state(TASK_RUNNING);
2342 remove_wait_queue(&info->port.open_wait, &wait);
2343 if (!tty_hung_up_p(filp)) {
2344 info->port.count++;
2345#ifdef CY_DEBUG_COUNT
2346 printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
2347 "count to %d\n", current->pid, info->port.count);
2348#endif
2349 }
2350 info->port.blocked_open--;
2351#ifdef CY_DEBUG_OPEN
2352 printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
2353 "count = %d\n", info->line, info->port.count);
2354#endif
2355 if (retval)
2356 return retval;
2357 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2358 return 0;
2359} /* block_til_ready */
2360
2361/* 1523/*
2362 * This routine is called whenever a serial port is opened. It 1524 * This routine is called whenever a serial port is opened. It
2363 * performs the serial-specific initialization for the tty structure. 1525 * performs the serial-specific initialization for the tty structure.
@@ -2436,7 +1598,6 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2436 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); 1598 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
2437#endif 1599#endif
2438 tty->driver_data = info; 1600 tty->driver_data = info;
2439 info->port.tty = tty;
2440 if (serial_paranoia_check(info, tty->name, "cy_open")) 1601 if (serial_paranoia_check(info, tty->name, "cy_open"))
2441 return -ENODEV; 1602 return -ENODEV;
2442 1603
@@ -2462,11 +1623,11 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2462 /* 1623 /*
2463 * Start up serial port 1624 * Start up serial port
2464 */ 1625 */
2465 retval = startup(info); 1626 retval = cy_startup(info, tty);
2466 if (retval) 1627 if (retval)
2467 return retval; 1628 return retval;
2468 1629
2469 retval = block_til_ready(tty, filp, info); 1630 retval = tty_port_block_til_ready(&info->port, tty, filp);
2470 if (retval) { 1631 if (retval) {
2471#ifdef CY_DEBUG_OPEN 1632#ifdef CY_DEBUG_OPEN
2472 printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " 1633 printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
@@ -2476,6 +1637,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2476 } 1637 }
2477 1638
2478 info->throttle = 0; 1639 info->throttle = 0;
1640 tty_port_tty_set(&info->port, tty);
2479 1641
2480#ifdef CY_DEBUG_OPEN 1642#ifdef CY_DEBUG_OPEN
2481 printk(KERN_DEBUG "cyc:cy_open done\n"); 1643 printk(KERN_DEBUG "cyc:cy_open done\n");
@@ -2490,8 +1652,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2490{ 1652{
2491 struct cyclades_card *card; 1653 struct cyclades_card *card;
2492 struct cyclades_port *info = tty->driver_data; 1654 struct cyclades_port *info = tty->driver_data;
2493 void __iomem *base_addr;
2494 int chip, channel, index;
2495 unsigned long orig_jiffies; 1655 unsigned long orig_jiffies;
2496 int char_time; 1656 int char_time;
2497 1657
@@ -2535,13 +1695,8 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2535 timeout, char_time, jiffies); 1695 timeout, char_time, jiffies);
2536#endif 1696#endif
2537 card = info->card; 1697 card = info->card;
2538 channel = (info->line) - (card->first_line);
2539 if (!cy_is_Z(card)) { 1698 if (!cy_is_Z(card)) {
2540 chip = channel >> 2; 1699 while (cyy_readb(info, CySRER) & CyTxRdy) {
2541 channel &= 0x03;
2542 index = card->bus_index;
2543 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2544 while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
2545#ifdef CY_DEBUG_WAIT_UNTIL_SENT 1700#ifdef CY_DEBUG_WAIT_UNTIL_SENT
2546 printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); 1701 printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
2547#endif 1702#endif
@@ -2595,103 +1750,37 @@ static void cy_flush_buffer(struct tty_struct *tty)
2595} /* cy_flush_buffer */ 1750} /* cy_flush_buffer */
2596 1751
2597 1752
2598/* 1753static void cy_do_close(struct tty_port *port)
2599 * This routine is called when a particular tty device is closed.
2600 */
2601static void cy_close(struct tty_struct *tty, struct file *filp)
2602{ 1754{
2603 struct cyclades_port *info = tty->driver_data; 1755 struct cyclades_port *info = container_of(port, struct cyclades_port,
1756 port);
2604 struct cyclades_card *card; 1757 struct cyclades_card *card;
2605 unsigned long flags; 1758 unsigned long flags;
2606 1759 int channel;
2607#ifdef CY_DEBUG_OTHER
2608 printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
2609#endif
2610
2611 if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
2612 return;
2613 1760
2614 card = info->card; 1761 card = info->card;
2615 1762 channel = info->line - card->first_line;
2616 spin_lock_irqsave(&card->card_lock, flags);
2617 /* If the TTY is being hung up, nothing to do */
2618 if (tty_hung_up_p(filp)) {
2619 spin_unlock_irqrestore(&card->card_lock, flags);
2620 return;
2621 }
2622#ifdef CY_DEBUG_OPEN
2623 printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
2624 info->port.count);
2625#endif
2626 if ((tty->count == 1) && (info->port.count != 1)) {
2627 /*
2628 * Uh, oh. tty->count is 1, which means that the tty
2629 * structure will be freed. Info->count should always
2630 * be one in these conditions. If it's greater than
2631 * one, we've got real problems, since it means the
2632 * serial port won't be shutdown.
2633 */
2634 printk(KERN_ERR "cyc:cy_close: bad serial port count; "
2635 "tty->count is 1, info->port.count is %d\n", info->port.count);
2636 info->port.count = 1;
2637 }
2638#ifdef CY_DEBUG_COUNT
2639 printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
2640 current->pid, info->port.count - 1);
2641#endif
2642 if (--info->port.count < 0) {
2643#ifdef CY_DEBUG_COUNT
2644 printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
2645#endif
2646 info->port.count = 0;
2647 }
2648 if (info->port.count) {
2649 spin_unlock_irqrestore(&card->card_lock, flags);
2650 return;
2651 }
2652 info->port.flags |= ASYNC_CLOSING;
2653
2654 /*
2655 * Now we wait for the transmit buffer to clear; and we notify
2656 * the line discipline to only process XON/XOFF characters.
2657 */
2658 tty->closing = 1;
2659 spin_unlock_irqrestore(&card->card_lock, flags);
2660 if (info->port.closing_wait != CY_CLOSING_WAIT_NONE)
2661 tty_wait_until_sent(tty, info->port.closing_wait);
2662
2663 spin_lock_irqsave(&card->card_lock, flags); 1763 spin_lock_irqsave(&card->card_lock, flags);
2664 1764
2665 if (!cy_is_Z(card)) { 1765 if (!cy_is_Z(card)) {
2666 int channel = info->line - card->first_line;
2667 int index = card->bus_index;
2668 void __iomem *base_addr = card->base_addr +
2669 (cy_chip_offset[channel >> 2] << index);
2670 /* Stop accepting input */ 1766 /* Stop accepting input */
2671 channel &= 0x03; 1767 cyy_writeb(info, CyCAR, channel & 0x03);
2672 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 1768 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData);
2673 cy_writeb(base_addr + (CySRER << index),
2674 readb(base_addr + (CySRER << index)) & ~CyRxData);
2675 if (info->port.flags & ASYNC_INITIALIZED) { 1769 if (info->port.flags & ASYNC_INITIALIZED) {
2676 /* Waiting for on-board buffers to be empty before 1770 /* Waiting for on-board buffers to be empty before
2677 closing the port */ 1771 closing the port */
2678 spin_unlock_irqrestore(&card->card_lock, flags); 1772 spin_unlock_irqrestore(&card->card_lock, flags);
2679 cy_wait_until_sent(tty, info->timeout); 1773 cy_wait_until_sent(port->tty, info->timeout);
2680 spin_lock_irqsave(&card->card_lock, flags); 1774 spin_lock_irqsave(&card->card_lock, flags);
2681 } 1775 }
2682 } else { 1776 } else {
2683#ifdef Z_WAKE 1777#ifdef Z_WAKE
2684 /* Waiting for on-board buffers to be empty before closing 1778 /* Waiting for on-board buffers to be empty before closing
2685 the port */ 1779 the port */
2686 void __iomem *base_addr = card->base_addr; 1780 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2687 struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
2688 struct ZFW_CTRL __iomem *zfw_ctrl =
2689 base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2690 struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
2691 int channel = info->line - card->first_line;
2692 int retval; 1781 int retval;
2693 1782
2694 if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { 1783 if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) {
2695 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); 1784 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
2696 if (retval != 0) { 1785 if (retval != 0) {
2697 printk(KERN_DEBUG "cyc:cy_close retval on " 1786 printk(KERN_DEBUG "cyc:cy_close retval on "
@@ -2703,32 +1792,19 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2703 } 1792 }
2704#endif 1793#endif
2705 } 1794 }
2706
2707 spin_unlock_irqrestore(&card->card_lock, flags); 1795 spin_unlock_irqrestore(&card->card_lock, flags);
2708 shutdown(info); 1796 cy_shutdown(info, port->tty);
2709 cy_flush_buffer(tty); 1797}
2710 tty_ldisc_flush(tty);
2711 spin_lock_irqsave(&card->card_lock, flags);
2712
2713 tty->closing = 0;
2714 info->port.tty = NULL;
2715 if (info->port.blocked_open) {
2716 spin_unlock_irqrestore(&card->card_lock, flags);
2717 if (info->port.close_delay) {
2718 msleep_interruptible(jiffies_to_msecs
2719 (info->port.close_delay));
2720 }
2721 wake_up_interruptible(&info->port.open_wait);
2722 spin_lock_irqsave(&card->card_lock, flags);
2723 }
2724 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
2725 wake_up_interruptible(&info->port.close_wait);
2726
2727#ifdef CY_DEBUG_OTHER
2728 printk(KERN_DEBUG "cyc:cy_close done\n");
2729#endif
2730 1798
2731 spin_unlock_irqrestore(&card->card_lock, flags); 1799/*
1800 * This routine is called when a particular tty device is closed.
1801 */
1802static void cy_close(struct tty_struct *tty, struct file *filp)
1803{
1804 struct cyclades_port *info = tty->driver_data;
1805 if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
1806 return;
1807 tty_port_close(&info->port, tty, filp);
2732} /* cy_close */ 1808} /* cy_close */
2733 1809
2734/* This routine gets called when tty_write has put something into 1810/* This routine gets called when tty_write has put something into
@@ -2871,18 +1947,13 @@ static int cy_write_room(struct tty_struct *tty)
2871 1947
2872static int cy_chars_in_buffer(struct tty_struct *tty) 1948static int cy_chars_in_buffer(struct tty_struct *tty)
2873{ 1949{
2874 struct cyclades_card *card;
2875 struct cyclades_port *info = tty->driver_data; 1950 struct cyclades_port *info = tty->driver_data;
2876 int channel;
2877 1951
2878 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) 1952 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
2879 return 0; 1953 return 0;
2880 1954
2881 card = info->card;
2882 channel = (info->line) - (card->first_line);
2883
2884#ifdef Z_EXT_CHARS_IN_BUFFER 1955#ifdef Z_EXT_CHARS_IN_BUFFER
2885 if (!cy_is_Z(card)) { 1956 if (!cy_is_Z(info->card)) {
2886#endif /* Z_EXT_CHARS_IN_BUFFER */ 1957#endif /* Z_EXT_CHARS_IN_BUFFER */
2887#ifdef CY_DEBUG_IO 1958#ifdef CY_DEBUG_IO
2888 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", 1959 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
@@ -2891,20 +1962,11 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
2891 return info->xmit_cnt; 1962 return info->xmit_cnt;
2892#ifdef Z_EXT_CHARS_IN_BUFFER 1963#ifdef Z_EXT_CHARS_IN_BUFFER
2893 } else { 1964 } else {
2894 static struct FIRM_ID *firm_id; 1965 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
2895 static struct ZFW_CTRL *zfw_ctrl;
2896 static struct CH_CTRL *ch_ctrl;
2897 static struct BUF_CTRL *buf_ctrl;
2898 int char_count; 1966 int char_count;
2899 __u32 tx_put, tx_get, tx_bufsize; 1967 __u32 tx_put, tx_get, tx_bufsize;
2900 1968
2901 lock_kernel(); 1969 lock_kernel();
2902 firm_id = card->base_addr + ID_ADDRESS;
2903 zfw_ctrl = card->base_addr +
2904 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2905 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
2906 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
2907
2908 tx_get = readl(&buf_ctrl->tx_get); 1970 tx_get = readl(&buf_ctrl->tx_get);
2909 tx_put = readl(&buf_ctrl->tx_put); 1971 tx_put = readl(&buf_ctrl->tx_put);
2910 tx_bufsize = readl(&buf_ctrl->tx_bufsize); 1972 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
@@ -2957,48 +2019,44 @@ static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
2957 * This routine finds or computes the various line characteristics. 2019 * This routine finds or computes the various line characteristics.
2958 * It used to be called config_setup 2020 * It used to be called config_setup
2959 */ 2021 */
2960static void set_line_char(struct cyclades_port *info) 2022static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
2961{ 2023{
2962 struct cyclades_card *card; 2024 struct cyclades_card *card;
2963 unsigned long flags; 2025 unsigned long flags;
2964 void __iomem *base_addr; 2026 int channel;
2965 int chip, channel, index;
2966 unsigned cflag, iflag; 2027 unsigned cflag, iflag;
2967 int baud, baud_rate = 0; 2028 int baud, baud_rate = 0;
2968 int i; 2029 int i;
2969 2030
2970 if (!info->port.tty || !info->port.tty->termios) 2031 if (!tty->termios) /* XXX can this happen at all? */
2971 return; 2032 return;
2972 2033
2973 if (info->line == -1) 2034 if (info->line == -1)
2974 return; 2035 return;
2975 2036
2976 cflag = info->port.tty->termios->c_cflag; 2037 cflag = tty->termios->c_cflag;
2977 iflag = info->port.tty->termios->c_iflag; 2038 iflag = tty->termios->c_iflag;
2978 2039
2979 /* 2040 /*
2980 * Set up the tty->alt_speed kludge 2041 * Set up the tty->alt_speed kludge
2981 */ 2042 */
2982 if (info->port.tty) { 2043 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2983 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 2044 tty->alt_speed = 57600;
2984 info->port.tty->alt_speed = 57600; 2045 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2985 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 2046 tty->alt_speed = 115200;
2986 info->port.tty->alt_speed = 115200; 2047 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2987 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 2048 tty->alt_speed = 230400;
2988 info->port.tty->alt_speed = 230400; 2049 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2989 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 2050 tty->alt_speed = 460800;
2990 info->port.tty->alt_speed = 460800;
2991 }
2992 2051
2993 card = info->card; 2052 card = info->card;
2994 channel = info->line - card->first_line; 2053 channel = info->line - card->first_line;
2995 2054
2996 if (!cy_is_Z(card)) { 2055 if (!cy_is_Z(card)) {
2997 2056 u32 cflags;
2998 index = card->bus_index;
2999 2057
3000 /* baud rate */ 2058 /* baud rate */
3001 baud = tty_get_baud_rate(info->port.tty); 2059 baud = tty_get_baud_rate(tty);
3002 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == 2060 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3003 ASYNC_SPD_CUST) { 2061 ASYNC_SPD_CUST) {
3004 if (info->custom_divisor) 2062 if (info->custom_divisor)
@@ -3107,124 +2165,68 @@ static void set_line_char(struct cyclades_port *info)
3107 cable. Contact Marcio Saito for details. 2165 cable. Contact Marcio Saito for details.
3108 ***********************************************/ 2166 ***********************************************/
3109 2167
3110 chip = channel >> 2;
3111 channel &= 0x03; 2168 channel &= 0x03;
3112 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3113 2169
3114 spin_lock_irqsave(&card->card_lock, flags); 2170 spin_lock_irqsave(&card->card_lock, flags);
3115 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2171 cyy_writeb(info, CyCAR, channel);
3116 2172
3117 /* tx and rx baud rate */ 2173 /* tx and rx baud rate */
3118 2174
3119 cy_writeb(base_addr + (CyTCOR << index), info->tco); 2175 cyy_writeb(info, CyTCOR, info->tco);
3120 cy_writeb(base_addr + (CyTBPR << index), info->tbpr); 2176 cyy_writeb(info, CyTBPR, info->tbpr);
3121 cy_writeb(base_addr + (CyRCOR << index), info->rco); 2177 cyy_writeb(info, CyRCOR, info->rco);
3122 cy_writeb(base_addr + (CyRBPR << index), info->rbpr); 2178 cyy_writeb(info, CyRBPR, info->rbpr);
3123 2179
3124 /* set line characteristics according configuration */ 2180 /* set line characteristics according configuration */
3125 2181
3126 cy_writeb(base_addr + (CySCHR1 << index), 2182 cyy_writeb(info, CySCHR1, START_CHAR(tty));
3127 START_CHAR(info->port.tty)); 2183 cyy_writeb(info, CySCHR2, STOP_CHAR(tty));
3128 cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->port.tty)); 2184 cyy_writeb(info, CyCOR1, info->cor1);
3129 cy_writeb(base_addr + (CyCOR1 << index), info->cor1); 2185 cyy_writeb(info, CyCOR2, info->cor2);
3130 cy_writeb(base_addr + (CyCOR2 << index), info->cor2); 2186 cyy_writeb(info, CyCOR3, info->cor3);
3131 cy_writeb(base_addr + (CyCOR3 << index), info->cor3); 2187 cyy_writeb(info, CyCOR4, info->cor4);
3132 cy_writeb(base_addr + (CyCOR4 << index), info->cor4); 2188 cyy_writeb(info, CyCOR5, info->cor5);
3133 cy_writeb(base_addr + (CyCOR5 << index), info->cor5);
3134 2189
3135 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | 2190 cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
3136 CyCOR3ch, index); 2191 CyCOR3ch);
3137 2192
3138 /* !!! Is this needed? */ 2193 /* !!! Is this needed? */
3139 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2194 cyy_writeb(info, CyCAR, channel);
3140 cy_writeb(base_addr + (CyRTPR << index), 2195 cyy_writeb(info, CyRTPR,
3141 (info->default_timeout ? info->default_timeout : 0x02)); 2196 (info->default_timeout ? info->default_timeout : 0x02));
3142 /* 10ms rx timeout */ 2197 /* 10ms rx timeout */
3143 2198
3144 if (C_CLOCAL(info->port.tty)) { 2199 cflags = CyCTS;
3145 /* without modem intr */ 2200 if (!C_CLOCAL(tty))
3146 cy_writeb(base_addr + (CySRER << index), 2201 cflags |= CyDSR | CyRI | CyDCD;
3147 readb(base_addr + (CySRER << index)) | CyMdmCh); 2202 /* without modem intr */
3148 /* act on 1->0 modem transitions */ 2203 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyMdmCh);
3149 if ((cflag & CRTSCTS) && info->rflow) { 2204 /* act on 1->0 modem transitions */
3150 cy_writeb(base_addr + (CyMCOR1 << index), 2205 if ((cflag & CRTSCTS) && info->rflow)
3151 (CyCTS | rflow_thr[i])); 2206 cyy_writeb(info, CyMCOR1, cflags | rflow_thr[i]);
3152 } else { 2207 else
3153 cy_writeb(base_addr + (CyMCOR1 << index), 2208 cyy_writeb(info, CyMCOR1, cflags);
3154 CyCTS); 2209 /* act on 0->1 modem transitions */
3155 } 2210 cyy_writeb(info, CyMCOR2, cflags);
3156 /* act on 0->1 modem transitions */
3157 cy_writeb(base_addr + (CyMCOR2 << index), CyCTS);
3158 } else {
3159 /* without modem intr */
3160 cy_writeb(base_addr + (CySRER << index),
3161 readb(base_addr +
3162 (CySRER << index)) | CyMdmCh);
3163 /* act on 1->0 modem transitions */
3164 if ((cflag & CRTSCTS) && info->rflow) {
3165 cy_writeb(base_addr + (CyMCOR1 << index),
3166 (CyDSR | CyCTS | CyRI | CyDCD |
3167 rflow_thr[i]));
3168 } else {
3169 cy_writeb(base_addr + (CyMCOR1 << index),
3170 CyDSR | CyCTS | CyRI | CyDCD);
3171 }
3172 /* act on 0->1 modem transitions */
3173 cy_writeb(base_addr + (CyMCOR2 << index),
3174 CyDSR | CyCTS | CyRI | CyDCD);
3175 }
3176 2211
3177 if (i == 0) { /* baud rate is zero, turn off line */ 2212 if (i == 0) /* baud rate is zero, turn off line */
3178 if (info->rtsdtr_inv) { 2213 cyy_change_rts_dtr(info, 0, TIOCM_DTR);
3179 cy_writeb(base_addr + (CyMSVR1 << index), 2214 else
3180 ~CyRTS); 2215 cyy_change_rts_dtr(info, TIOCM_DTR, 0);
3181 } else {
3182 cy_writeb(base_addr + (CyMSVR2 << index),
3183 ~CyDTR);
3184 }
3185#ifdef CY_DEBUG_DTR
3186 printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n");
3187 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3188 readb(base_addr + (CyMSVR1 << index)),
3189 readb(base_addr + (CyMSVR2 << index)));
3190#endif
3191 } else {
3192 if (info->rtsdtr_inv) {
3193 cy_writeb(base_addr + (CyMSVR1 << index),
3194 CyRTS);
3195 } else {
3196 cy_writeb(base_addr + (CyMSVR2 << index),
3197 CyDTR);
3198 }
3199#ifdef CY_DEBUG_DTR
3200 printk(KERN_DEBUG "cyc:set_line_char raising DTR\n");
3201 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3202 readb(base_addr + (CyMSVR1 << index)),
3203 readb(base_addr + (CyMSVR2 << index)));
3204#endif
3205 }
3206 2216
3207 if (info->port.tty) 2217 clear_bit(TTY_IO_ERROR, &tty->flags);
3208 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
3209 spin_unlock_irqrestore(&card->card_lock, flags); 2218 spin_unlock_irqrestore(&card->card_lock, flags);
3210 2219
3211 } else { 2220 } else {
3212 struct FIRM_ID __iomem *firm_id; 2221 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
3213 struct ZFW_CTRL __iomem *zfw_ctrl;
3214 struct CH_CTRL __iomem *ch_ctrl;
3215 __u32 sw_flow; 2222 __u32 sw_flow;
3216 int retval; 2223 int retval;
3217 2224
3218 firm_id = card->base_addr + ID_ADDRESS;
3219 if (!cyz_is_loaded(card)) 2225 if (!cyz_is_loaded(card))
3220 return; 2226 return;
3221 2227
3222 zfw_ctrl = card->base_addr +
3223 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3224 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3225
3226 /* baud rate */ 2228 /* baud rate */
3227 baud = tty_get_baud_rate(info->port.tty); 2229 baud = tty_get_baud_rate(tty);
3228 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == 2230 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3229 ASYNC_SPD_CUST) { 2231 ASYNC_SPD_CUST) {
3230 if (info->custom_divisor) 2232 if (info->custom_divisor)
@@ -3335,45 +2337,38 @@ static void set_line_char(struct cyclades_port *info)
3335 "was %x\n", info->line, retval); 2337 "was %x\n", info->line, retval);
3336 } 2338 }
3337 2339
3338 if (info->port.tty) 2340 clear_bit(TTY_IO_ERROR, &tty->flags);
3339 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
3340 } 2341 }
3341} /* set_line_char */ 2342} /* set_line_char */
3342 2343
3343static int 2344static int cy_get_serial_info(struct cyclades_port *info,
3344get_serial_info(struct cyclades_port *info,
3345 struct serial_struct __user *retinfo) 2345 struct serial_struct __user *retinfo)
3346{ 2346{
3347 struct serial_struct tmp;
3348 struct cyclades_card *cinfo = info->card; 2347 struct cyclades_card *cinfo = info->card;
3349 2348 struct serial_struct tmp = {
3350 if (!retinfo) 2349 .type = info->type,
3351 return -EFAULT; 2350 .line = info->line,
3352 memset(&tmp, 0, sizeof(tmp)); 2351 .port = (info->card - cy_card) * 0x100 + info->line -
3353 tmp.type = info->type; 2352 cinfo->first_line,
3354 tmp.line = info->line; 2353 .irq = cinfo->irq,
3355 tmp.port = (info->card - cy_card) * 0x100 + info->line - 2354 .flags = info->port.flags,
3356 cinfo->first_line; 2355 .close_delay = info->port.close_delay,
3357 tmp.irq = cinfo->irq; 2356 .closing_wait = info->port.closing_wait,
3358 tmp.flags = info->port.flags; 2357 .baud_base = info->baud,
3359 tmp.close_delay = info->port.close_delay; 2358 .custom_divisor = info->custom_divisor,
3360 tmp.closing_wait = info->port.closing_wait; 2359 .hub6 = 0, /*!!! */
3361 tmp.baud_base = info->baud; 2360 };
3362 tmp.custom_divisor = info->custom_divisor;
3363 tmp.hub6 = 0; /*!!! */
3364 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; 2361 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
3365} /* get_serial_info */ 2362}
3366 2363
3367static int 2364static int
3368set_serial_info(struct cyclades_port *info, 2365cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
3369 struct serial_struct __user *new_info) 2366 struct serial_struct __user *new_info)
3370{ 2367{
3371 struct serial_struct new_serial; 2368 struct serial_struct new_serial;
3372 struct cyclades_port old_info;
3373 2369
3374 if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) 2370 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
3375 return -EFAULT; 2371 return -EFAULT;
3376 old_info = *info;
3377 2372
3378 if (!capable(CAP_SYS_ADMIN)) { 2373 if (!capable(CAP_SYS_ADMIN)) {
3379 if (new_serial.close_delay != info->port.close_delay || 2374 if (new_serial.close_delay != info->port.close_delay ||
@@ -3403,10 +2398,10 @@ set_serial_info(struct cyclades_port *info,
3403 2398
3404check_and_exit: 2399check_and_exit:
3405 if (info->port.flags & ASYNC_INITIALIZED) { 2400 if (info->port.flags & ASYNC_INITIALIZED) {
3406 set_line_char(info); 2401 cy_set_line_char(info, tty);
3407 return 0; 2402 return 0;
3408 } else { 2403 } else {
3409 return startup(info); 2404 return cy_startup(info, tty);
3410 } 2405 }
3411} /* set_serial_info */ 2406} /* set_serial_info */
3412 2407
@@ -3422,24 +2417,14 @@ check_and_exit:
3422 */ 2417 */
3423static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) 2418static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
3424{ 2419{
3425 struct cyclades_card *card; 2420 struct cyclades_card *card = info->card;
3426 int chip, channel, index;
3427 unsigned char status;
3428 unsigned int result; 2421 unsigned int result;
3429 unsigned long flags; 2422 unsigned long flags;
3430 void __iomem *base_addr; 2423 u8 status;
3431 2424
3432 card = info->card;
3433 channel = (info->line) - (card->first_line);
3434 if (!cy_is_Z(card)) { 2425 if (!cy_is_Z(card)) {
3435 chip = channel >> 2;
3436 channel &= 0x03;
3437 index = card->bus_index;
3438 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3439
3440 spin_lock_irqsave(&card->card_lock, flags); 2426 spin_lock_irqsave(&card->card_lock, flags);
3441 status = readb(base_addr + (CySRER << index)) & 2427 status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty);
3442 (CyTxRdy | CyTxMpty);
3443 spin_unlock_irqrestore(&card->card_lock, flags); 2428 spin_unlock_irqrestore(&card->card_lock, flags);
3444 result = (status ? 0 : TIOCSER_TEMT); 2429 result = (status ? 0 : TIOCSER_TEMT);
3445 } else { 2430 } else {
@@ -3453,34 +2438,23 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3453{ 2438{
3454 struct cyclades_port *info = tty->driver_data; 2439 struct cyclades_port *info = tty->driver_data;
3455 struct cyclades_card *card; 2440 struct cyclades_card *card;
3456 int chip, channel, index; 2441 int result;
3457 void __iomem *base_addr;
3458 unsigned long flags;
3459 unsigned char status;
3460 unsigned long lstatus;
3461 unsigned int result;
3462 struct FIRM_ID __iomem *firm_id;
3463 struct ZFW_CTRL __iomem *zfw_ctrl;
3464 struct BOARD_CTRL __iomem *board_ctrl;
3465 struct CH_CTRL __iomem *ch_ctrl;
3466 2442
3467 if (serial_paranoia_check(info, tty->name, __func__)) 2443 if (serial_paranoia_check(info, tty->name, __func__))
3468 return -ENODEV; 2444 return -ENODEV;
3469 2445
3470 lock_kernel();
3471
3472 card = info->card; 2446 card = info->card;
3473 channel = info->line - card->first_line; 2447
2448 lock_kernel();
3474 if (!cy_is_Z(card)) { 2449 if (!cy_is_Z(card)) {
3475 chip = channel >> 2; 2450 unsigned long flags;
3476 channel &= 0x03; 2451 int channel = info->line - card->first_line;
3477 index = card->bus_index; 2452 u8 status;
3478 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3479 2453
3480 spin_lock_irqsave(&card->card_lock, flags); 2454 spin_lock_irqsave(&card->card_lock, flags);
3481 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2455 cyy_writeb(info, CyCAR, channel & 0x03);
3482 status = readb(base_addr + (CyMSVR1 << index)); 2456 status = cyy_readb(info, CyMSVR1);
3483 status |= readb(base_addr + (CyMSVR2 << index)); 2457 status |= cyy_readb(info, CyMSVR2);
3484 spin_unlock_irqrestore(&card->card_lock, flags); 2458 spin_unlock_irqrestore(&card->card_lock, flags);
3485 2459
3486 if (info->rtsdtr_inv) { 2460 if (info->rtsdtr_inv) {
@@ -3495,27 +2469,22 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3495 ((status & CyDSR) ? TIOCM_DSR : 0) | 2469 ((status & CyDSR) ? TIOCM_DSR : 0) |
3496 ((status & CyCTS) ? TIOCM_CTS : 0); 2470 ((status & CyCTS) ? TIOCM_CTS : 0);
3497 } else { 2471 } else {
3498 base_addr = card->base_addr; 2472 u32 lstatus;
3499 firm_id = card->base_addr + ID_ADDRESS; 2473
3500 if (cyz_is_loaded(card)) { 2474 if (!cyz_is_loaded(card)) {
3501 zfw_ctrl = card->base_addr + 2475 result = -ENODEV;
3502 (readl(&firm_id->zfwctrl_addr) & 0xfffff); 2476 goto end;
3503 board_ctrl = &zfw_ctrl->board_ctrl;
3504 ch_ctrl = zfw_ctrl->ch_ctrl;
3505 lstatus = readl(&ch_ctrl[channel].rs_status);
3506 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
3507 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
3508 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
3509 ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
3510 ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
3511 ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
3512 } else {
3513 result = 0;
3514 unlock_kernel();
3515 return -ENODEV;
3516 } 2477 }
3517 2478
2479 lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
2480 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
2481 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
2482 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
2483 ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
2484 ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
2485 ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
3518 } 2486 }
2487end:
3519 unlock_kernel(); 2488 unlock_kernel();
3520 return result; 2489 return result;
3521} /* cy_tiomget */ 2490} /* cy_tiomget */
@@ -3526,150 +2495,53 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3526{ 2495{
3527 struct cyclades_port *info = tty->driver_data; 2496 struct cyclades_port *info = tty->driver_data;
3528 struct cyclades_card *card; 2497 struct cyclades_card *card;
3529 int chip, channel, index;
3530 void __iomem *base_addr;
3531 unsigned long flags; 2498 unsigned long flags;
3532 struct FIRM_ID __iomem *firm_id;
3533 struct ZFW_CTRL __iomem *zfw_ctrl;
3534 struct BOARD_CTRL __iomem *board_ctrl;
3535 struct CH_CTRL __iomem *ch_ctrl;
3536 int retval;
3537 2499
3538 if (serial_paranoia_check(info, tty->name, __func__)) 2500 if (serial_paranoia_check(info, tty->name, __func__))
3539 return -ENODEV; 2501 return -ENODEV;
3540 2502
3541 card = info->card; 2503 card = info->card;
3542 channel = (info->line) - (card->first_line);
3543 if (!cy_is_Z(card)) { 2504 if (!cy_is_Z(card)) {
3544 chip = channel >> 2; 2505 spin_lock_irqsave(&card->card_lock, flags);
3545 channel &= 0x03; 2506 cyy_change_rts_dtr(info, set, clear);
3546 index = card->bus_index; 2507 spin_unlock_irqrestore(&card->card_lock, flags);
3547 base_addr = card->base_addr + (cy_chip_offset[chip] << index); 2508 } else {
2509 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2510 int retval, channel = info->line - card->first_line;
2511 u32 rs;
3548 2512
3549 if (set & TIOCM_RTS) { 2513 if (!cyz_is_loaded(card))
3550 spin_lock_irqsave(&card->card_lock, flags); 2514 return -ENODEV;
3551 cy_writeb(base_addr + (CyCAR << index), 2515
3552 (u_char) channel); 2516 spin_lock_irqsave(&card->card_lock, flags);
3553 if (info->rtsdtr_inv) { 2517 rs = readl(&ch_ctrl->rs_control);
3554 cy_writeb(base_addr + (CyMSVR2 << index), 2518 if (set & TIOCM_RTS)
3555 CyDTR); 2519 rs |= C_RS_RTS;
3556 } else { 2520 if (clear & TIOCM_RTS)
3557 cy_writeb(base_addr + (CyMSVR1 << index), 2521 rs &= ~C_RS_RTS;
3558 CyRTS);
3559 }
3560 spin_unlock_irqrestore(&card->card_lock, flags);
3561 }
3562 if (clear & TIOCM_RTS) {
3563 spin_lock_irqsave(&card->card_lock, flags);
3564 cy_writeb(base_addr + (CyCAR << index),
3565 (u_char) channel);
3566 if (info->rtsdtr_inv) {
3567 cy_writeb(base_addr + (CyMSVR2 << index),
3568 ~CyDTR);
3569 } else {
3570 cy_writeb(base_addr + (CyMSVR1 << index),
3571 ~CyRTS);
3572 }
3573 spin_unlock_irqrestore(&card->card_lock, flags);
3574 }
3575 if (set & TIOCM_DTR) { 2522 if (set & TIOCM_DTR) {
3576 spin_lock_irqsave(&card->card_lock, flags); 2523 rs |= C_RS_DTR;
3577 cy_writeb(base_addr + (CyCAR << index),
3578 (u_char) channel);
3579 if (info->rtsdtr_inv) {
3580 cy_writeb(base_addr + (CyMSVR1 << index),
3581 CyRTS);
3582 } else {
3583 cy_writeb(base_addr + (CyMSVR2 << index),
3584 CyDTR);
3585 }
3586#ifdef CY_DEBUG_DTR 2524#ifdef CY_DEBUG_DTR
3587 printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); 2525 printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n");
3588 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3589 readb(base_addr + (CyMSVR1 << index)),
3590 readb(base_addr + (CyMSVR2 << index)));
3591#endif 2526#endif
3592 spin_unlock_irqrestore(&card->card_lock, flags);
3593 } 2527 }
3594 if (clear & TIOCM_DTR) { 2528 if (clear & TIOCM_DTR) {
3595 spin_lock_irqsave(&card->card_lock, flags); 2529 rs &= ~C_RS_DTR;
3596 cy_writeb(base_addr + (CyCAR << index),
3597 (u_char) channel);
3598 if (info->rtsdtr_inv) {
3599 cy_writeb(base_addr + (CyMSVR1 << index),
3600 ~CyRTS);
3601 } else {
3602 cy_writeb(base_addr + (CyMSVR2 << index),
3603 ~CyDTR);
3604 }
3605
3606#ifdef CY_DEBUG_DTR 2530#ifdef CY_DEBUG_DTR
3607 printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); 2531 printk(KERN_DEBUG "cyc:set_modem_info clearing "
3608 printk(KERN_DEBUG " status: 0x%x, 0x%x\n", 2532 "Z DTR\n");
3609 readb(base_addr + (CyMSVR1 << index)),
3610 readb(base_addr + (CyMSVR2 << index)));
3611#endif 2533#endif
3612 spin_unlock_irqrestore(&card->card_lock, flags);
3613 } 2534 }
3614 } else { 2535 cy_writel(&ch_ctrl->rs_control, rs);
3615 base_addr = card->base_addr;
3616
3617 firm_id = card->base_addr + ID_ADDRESS;
3618 if (cyz_is_loaded(card)) {
3619 zfw_ctrl = card->base_addr +
3620 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3621 board_ctrl = &zfw_ctrl->board_ctrl;
3622 ch_ctrl = zfw_ctrl->ch_ctrl;
3623
3624 if (set & TIOCM_RTS) {
3625 spin_lock_irqsave(&card->card_lock, flags);
3626 cy_writel(&ch_ctrl[channel].rs_control,
3627 readl(&ch_ctrl[channel].rs_control) |
3628 C_RS_RTS);
3629 spin_unlock_irqrestore(&card->card_lock, flags);
3630 }
3631 if (clear & TIOCM_RTS) {
3632 spin_lock_irqsave(&card->card_lock, flags);
3633 cy_writel(&ch_ctrl[channel].rs_control,
3634 readl(&ch_ctrl[channel].rs_control) &
3635 ~C_RS_RTS);
3636 spin_unlock_irqrestore(&card->card_lock, flags);
3637 }
3638 if (set & TIOCM_DTR) {
3639 spin_lock_irqsave(&card->card_lock, flags);
3640 cy_writel(&ch_ctrl[channel].rs_control,
3641 readl(&ch_ctrl[channel].rs_control) |
3642 C_RS_DTR);
3643#ifdef CY_DEBUG_DTR
3644 printk(KERN_DEBUG "cyc:set_modem_info raising "
3645 "Z DTR\n");
3646#endif
3647 spin_unlock_irqrestore(&card->card_lock, flags);
3648 }
3649 if (clear & TIOCM_DTR) {
3650 spin_lock_irqsave(&card->card_lock, flags);
3651 cy_writel(&ch_ctrl[channel].rs_control,
3652 readl(&ch_ctrl[channel].rs_control) &
3653 ~C_RS_DTR);
3654#ifdef CY_DEBUG_DTR
3655 printk(KERN_DEBUG "cyc:set_modem_info clearing "
3656 "Z DTR\n");
3657#endif
3658 spin_unlock_irqrestore(&card->card_lock, flags);
3659 }
3660 } else {
3661 return -ENODEV;
3662 }
3663 spin_lock_irqsave(&card->card_lock, flags);
3664 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); 2536 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
2537 spin_unlock_irqrestore(&card->card_lock, flags);
3665 if (retval != 0) { 2538 if (retval != 0) {
3666 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " 2539 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
3667 "was %x\n", info->line, retval); 2540 "was %x\n", info->line, retval);
3668 } 2541 }
3669 spin_unlock_irqrestore(&card->card_lock, flags);
3670 } 2542 }
3671 return 0; 2543 return 0;
3672} /* cy_tiocmset */ 2544}
3673 2545
3674/* 2546/*
3675 * cy_break() --- routine which turns the break handling on or off 2547 * cy_break() --- routine which turns the break handling on or off
@@ -3734,41 +2606,18 @@ static int cy_break(struct tty_struct *tty, int break_state)
3734 return retval; 2606 return retval;
3735} /* cy_break */ 2607} /* cy_break */
3736 2608
3737static int get_mon_info(struct cyclades_port *info,
3738 struct cyclades_monitor __user *mon)
3739{
3740
3741 if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
3742 return -EFAULT;
3743 info->mon.int_count = 0;
3744 info->mon.char_count = 0;
3745 info->mon.char_max = 0;
3746 info->mon.char_last = 0;
3747 return 0;
3748} /* get_mon_info */
3749
3750static int set_threshold(struct cyclades_port *info, unsigned long value) 2609static int set_threshold(struct cyclades_port *info, unsigned long value)
3751{ 2610{
3752 struct cyclades_card *card; 2611 struct cyclades_card *card = info->card;
3753 void __iomem *base_addr;
3754 int channel, chip, index;
3755 unsigned long flags; 2612 unsigned long flags;
3756 2613
3757 card = info->card;
3758 channel = info->line - card->first_line;
3759 if (!cy_is_Z(card)) { 2614 if (!cy_is_Z(card)) {
3760 chip = channel >> 2;
3761 channel &= 0x03;
3762 index = card->bus_index;
3763 base_addr =
3764 card->base_addr + (cy_chip_offset[chip] << index);
3765
3766 info->cor3 &= ~CyREC_FIFO; 2615 info->cor3 &= ~CyREC_FIFO;
3767 info->cor3 |= value & CyREC_FIFO; 2616 info->cor3 |= value & CyREC_FIFO;
3768 2617
3769 spin_lock_irqsave(&card->card_lock, flags); 2618 spin_lock_irqsave(&card->card_lock, flags);
3770 cy_writeb(base_addr + (CyCOR3 << index), info->cor3); 2619 cyy_writeb(info, CyCOR3, info->cor3);
3771 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); 2620 cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch);
3772 spin_unlock_irqrestore(&card->card_lock, flags); 2621 spin_unlock_irqrestore(&card->card_lock, flags);
3773 } 2622 }
3774 return 0; 2623 return 0;
@@ -3777,55 +2626,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
3777static int get_threshold(struct cyclades_port *info, 2626static int get_threshold(struct cyclades_port *info,
3778 unsigned long __user *value) 2627 unsigned long __user *value)
3779{ 2628{
3780 struct cyclades_card *card; 2629 struct cyclades_card *card = info->card;
3781 void __iomem *base_addr;
3782 int channel, chip, index;
3783 unsigned long tmp;
3784 2630
3785 card = info->card;
3786 channel = info->line - card->first_line;
3787 if (!cy_is_Z(card)) { 2631 if (!cy_is_Z(card)) {
3788 chip = channel >> 2; 2632 u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO;
3789 channel &= 0x03;
3790 index = card->bus_index;
3791 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3792
3793 tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
3794 return put_user(tmp, value); 2633 return put_user(tmp, value);
3795 } 2634 }
3796 return 0; 2635 return 0;
3797} /* get_threshold */ 2636} /* get_threshold */
3798 2637
3799static int set_default_threshold(struct cyclades_port *info,
3800 unsigned long value)
3801{
3802 info->default_threshold = value & 0x0f;
3803 return 0;
3804} /* set_default_threshold */
3805
3806static int get_default_threshold(struct cyclades_port *info,
3807 unsigned long __user *value)
3808{
3809 return put_user(info->default_threshold, value);
3810} /* get_default_threshold */
3811
3812static int set_timeout(struct cyclades_port *info, unsigned long value) 2638static int set_timeout(struct cyclades_port *info, unsigned long value)
3813{ 2639{
3814 struct cyclades_card *card; 2640 struct cyclades_card *card = info->card;
3815 void __iomem *base_addr;
3816 int channel, chip, index;
3817 unsigned long flags; 2641 unsigned long flags;
3818 2642
3819 card = info->card;
3820 channel = info->line - card->first_line;
3821 if (!cy_is_Z(card)) { 2643 if (!cy_is_Z(card)) {
3822 chip = channel >> 2;
3823 channel &= 0x03;
3824 index = card->bus_index;
3825 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3826
3827 spin_lock_irqsave(&card->card_lock, flags); 2644 spin_lock_irqsave(&card->card_lock, flags);
3828 cy_writeb(base_addr + (CyRTPR << index), value & 0xff); 2645 cyy_writeb(info, CyRTPR, value & 0xff);
3829 spin_unlock_irqrestore(&card->card_lock, flags); 2646 spin_unlock_irqrestore(&card->card_lock, flags);
3830 } 2647 }
3831 return 0; 2648 return 0;
@@ -3834,36 +2651,35 @@ static int set_timeout(struct cyclades_port *info, unsigned long value)
3834static int get_timeout(struct cyclades_port *info, 2651static int get_timeout(struct cyclades_port *info,
3835 unsigned long __user *value) 2652 unsigned long __user *value)
3836{ 2653{
3837 struct cyclades_card *card; 2654 struct cyclades_card *card = info->card;
3838 void __iomem *base_addr;
3839 int channel, chip, index;
3840 unsigned long tmp;
3841 2655
3842 card = info->card;
3843 channel = info->line - card->first_line;
3844 if (!cy_is_Z(card)) { 2656 if (!cy_is_Z(card)) {
3845 chip = channel >> 2; 2657 u8 tmp = cyy_readb(info, CyRTPR);
3846 channel &= 0x03;
3847 index = card->bus_index;
3848 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3849
3850 tmp = readb(base_addr + (CyRTPR << index));
3851 return put_user(tmp, value); 2658 return put_user(tmp, value);
3852 } 2659 }
3853 return 0; 2660 return 0;
3854} /* get_timeout */ 2661} /* get_timeout */
3855 2662
3856static int set_default_timeout(struct cyclades_port *info, unsigned long value) 2663static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg,
2664 struct cyclades_icount *cprev)
3857{ 2665{
3858 info->default_timeout = value & 0xff; 2666 struct cyclades_icount cnow;
3859 return 0; 2667 unsigned long flags;
3860} /* set_default_timeout */ 2668 int ret;
3861 2669
3862static int get_default_timeout(struct cyclades_port *info, 2670 spin_lock_irqsave(&info->card->card_lock, flags);
3863 unsigned long __user *value) 2671 cnow = info->icount; /* atomic copy */
3864{ 2672 spin_unlock_irqrestore(&info->card->card_lock, flags);
3865 return put_user(info->default_timeout, value); 2673
3866} /* get_default_timeout */ 2674 ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
2675 ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
2676 ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
2677 ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts));
2678
2679 *cprev = cnow;
2680
2681 return ret;
2682}
3867 2683
3868/* 2684/*
3869 * This routine allows the tty driver to implement device- 2685 * This routine allows the tty driver to implement device-
@@ -3875,8 +2691,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3875 unsigned int cmd, unsigned long arg) 2691 unsigned int cmd, unsigned long arg)
3876{ 2692{
3877 struct cyclades_port *info = tty->driver_data; 2693 struct cyclades_port *info = tty->driver_data;
3878 struct cyclades_icount cprev, cnow; /* kernel counter temps */ 2694 struct cyclades_icount cnow; /* kernel counter temps */
3879 struct serial_icounter_struct __user *p_cuser; /* user space */
3880 int ret_val = 0; 2695 int ret_val = 0;
3881 unsigned long flags; 2696 unsigned long flags;
3882 void __user *argp = (void __user *)arg; 2697 void __user *argp = (void __user *)arg;
@@ -3892,7 +2707,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3892 2707
3893 switch (cmd) { 2708 switch (cmd) {
3894 case CYGETMON: 2709 case CYGETMON:
3895 ret_val = get_mon_info(info, argp); 2710 if (copy_to_user(argp, &info->mon, sizeof(info->mon))) {
2711 ret_val = -EFAULT;
2712 break;
2713 }
2714 memset(&info->mon, 0, sizeof(info->mon));
3896 break; 2715 break;
3897 case CYGETTHRESH: 2716 case CYGETTHRESH:
3898 ret_val = get_threshold(info, argp); 2717 ret_val = get_threshold(info, argp);
@@ -3901,10 +2720,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3901 ret_val = set_threshold(info, arg); 2720 ret_val = set_threshold(info, arg);
3902 break; 2721 break;
3903 case CYGETDEFTHRESH: 2722 case CYGETDEFTHRESH:
3904 ret_val = get_default_threshold(info, argp); 2723 ret_val = put_user(info->default_threshold,
2724 (unsigned long __user *)argp);
3905 break; 2725 break;
3906 case CYSETDEFTHRESH: 2726 case CYSETDEFTHRESH:
3907 ret_val = set_default_threshold(info, arg); 2727 info->default_threshold = arg & 0x0f;
3908 break; 2728 break;
3909 case CYGETTIMEOUT: 2729 case CYGETTIMEOUT:
3910 ret_val = get_timeout(info, argp); 2730 ret_val = get_timeout(info, argp);
@@ -3913,21 +2733,20 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3913 ret_val = set_timeout(info, arg); 2733 ret_val = set_timeout(info, arg);
3914 break; 2734 break;
3915 case CYGETDEFTIMEOUT: 2735 case CYGETDEFTIMEOUT:
3916 ret_val = get_default_timeout(info, argp); 2736 ret_val = put_user(info->default_timeout,
2737 (unsigned long __user *)argp);
3917 break; 2738 break;
3918 case CYSETDEFTIMEOUT: 2739 case CYSETDEFTIMEOUT:
3919 ret_val = set_default_timeout(info, arg); 2740 info->default_timeout = arg & 0xff;
3920 break; 2741 break;
3921 case CYSETRFLOW: 2742 case CYSETRFLOW:
3922 info->rflow = (int)arg; 2743 info->rflow = (int)arg;
3923 ret_val = 0;
3924 break; 2744 break;
3925 case CYGETRFLOW: 2745 case CYGETRFLOW:
3926 ret_val = info->rflow; 2746 ret_val = info->rflow;
3927 break; 2747 break;
3928 case CYSETRTSDTR_INV: 2748 case CYSETRTSDTR_INV:
3929 info->rtsdtr_inv = (int)arg; 2749 info->rtsdtr_inv = (int)arg;
3930 ret_val = 0;
3931 break; 2750 break;
3932 case CYGETRTSDTR_INV: 2751 case CYGETRTSDTR_INV:
3933 ret_val = info->rtsdtr_inv; 2752 ret_val = info->rtsdtr_inv;
@@ -3938,7 +2757,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3938#ifndef CONFIG_CYZ_INTR 2757#ifndef CONFIG_CYZ_INTR
3939 case CYZSETPOLLCYCLE: 2758 case CYZSETPOLLCYCLE:
3940 cyz_polling_cycle = (arg * HZ) / 1000; 2759 cyz_polling_cycle = (arg * HZ) / 1000;
3941 ret_val = 0;
3942 break; 2760 break;
3943 case CYZGETPOLLCYCLE: 2761 case CYZGETPOLLCYCLE:
3944 ret_val = (cyz_polling_cycle * 1000) / HZ; 2762 ret_val = (cyz_polling_cycle * 1000) / HZ;
@@ -3946,16 +2764,15 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3946#endif /* CONFIG_CYZ_INTR */ 2764#endif /* CONFIG_CYZ_INTR */
3947 case CYSETWAIT: 2765 case CYSETWAIT:
3948 info->port.closing_wait = (unsigned short)arg * HZ / 100; 2766 info->port.closing_wait = (unsigned short)arg * HZ / 100;
3949 ret_val = 0;
3950 break; 2767 break;
3951 case CYGETWAIT: 2768 case CYGETWAIT:
3952 ret_val = info->port.closing_wait / (HZ / 100); 2769 ret_val = info->port.closing_wait / (HZ / 100);
3953 break; 2770 break;
3954 case TIOCGSERIAL: 2771 case TIOCGSERIAL:
3955 ret_val = get_serial_info(info, argp); 2772 ret_val = cy_get_serial_info(info, argp);
3956 break; 2773 break;
3957 case TIOCSSERIAL: 2774 case TIOCSSERIAL:
3958 ret_val = set_serial_info(info, argp); 2775 ret_val = cy_set_serial_info(info, tty, argp);
3959 break; 2776 break;
3960 case TIOCSERGETLSR: /* Get line status register */ 2777 case TIOCSERGETLSR: /* Get line status register */
3961 ret_val = get_lsr_info(info, argp); 2778 ret_val = get_lsr_info(info, argp);
@@ -3971,17 +2788,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3971 /* note the counters on entry */ 2788 /* note the counters on entry */
3972 cnow = info->icount; 2789 cnow = info->icount;
3973 spin_unlock_irqrestore(&info->card->card_lock, flags); 2790 spin_unlock_irqrestore(&info->card->card_lock, flags);
3974 ret_val = wait_event_interruptible(info->delta_msr_wait, ({ 2791 ret_val = wait_event_interruptible(info->port.delta_msr_wait,
3975 cprev = cnow; 2792 cy_cflags_changed(info, arg, &cnow));
3976 spin_lock_irqsave(&info->card->card_lock, flags);
3977 cnow = info->icount; /* atomic copy */
3978 spin_unlock_irqrestore(&info->card->card_lock, flags);
3979
3980 ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
3981 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
3982 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
3983 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
3984 }));
3985 break; 2793 break;
3986 2794
3987 /* 2795 /*
@@ -3990,46 +2798,29 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3990 * NB: both 1->0 and 0->1 transitions are counted except for 2798 * NB: both 1->0 and 0->1 transitions are counted except for
3991 * RI where only 0->1 is counted. 2799 * RI where only 0->1 is counted.
3992 */ 2800 */
3993 case TIOCGICOUNT: 2801 case TIOCGICOUNT: {
2802 struct serial_icounter_struct sic = { };
2803
3994 spin_lock_irqsave(&info->card->card_lock, flags); 2804 spin_lock_irqsave(&info->card->card_lock, flags);
3995 cnow = info->icount; 2805 cnow = info->icount;
3996 spin_unlock_irqrestore(&info->card->card_lock, flags); 2806 spin_unlock_irqrestore(&info->card->card_lock, flags);
3997 p_cuser = argp; 2807
3998 ret_val = put_user(cnow.cts, &p_cuser->cts); 2808 sic.cts = cnow.cts;
3999 if (ret_val) 2809 sic.dsr = cnow.dsr;
4000 break; 2810 sic.rng = cnow.rng;
4001 ret_val = put_user(cnow.dsr, &p_cuser->dsr); 2811 sic.dcd = cnow.dcd;
4002 if (ret_val) 2812 sic.rx = cnow.rx;
4003 break; 2813 sic.tx = cnow.tx;
4004 ret_val = put_user(cnow.rng, &p_cuser->rng); 2814 sic.frame = cnow.frame;
4005 if (ret_val) 2815 sic.overrun = cnow.overrun;
4006 break; 2816 sic.parity = cnow.parity;
4007 ret_val = put_user(cnow.dcd, &p_cuser->dcd); 2817 sic.brk = cnow.brk;
4008 if (ret_val) 2818 sic.buf_overrun = cnow.buf_overrun;
4009 break; 2819
4010 ret_val = put_user(cnow.rx, &p_cuser->rx); 2820 if (copy_to_user(argp, &sic, sizeof(sic)))
4011 if (ret_val) 2821 ret_val = -EFAULT;
4012 break;
4013 ret_val = put_user(cnow.tx, &p_cuser->tx);
4014 if (ret_val)
4015 break;
4016 ret_val = put_user(cnow.frame, &p_cuser->frame);
4017 if (ret_val)
4018 break;
4019 ret_val = put_user(cnow.overrun, &p_cuser->overrun);
4020 if (ret_val)
4021 break;
4022 ret_val = put_user(cnow.parity, &p_cuser->parity);
4023 if (ret_val)
4024 break;
4025 ret_val = put_user(cnow.brk, &p_cuser->brk);
4026 if (ret_val)
4027 break;
4028 ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
4029 if (ret_val)
4030 break;
4031 ret_val = 0;
4032 break; 2822 break;
2823 }
4033 default: 2824 default:
4034 ret_val = -ENOIOCTLCMD; 2825 ret_val = -ENOIOCTLCMD;
4035 } 2826 }
@@ -4055,7 +2846,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
4055 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); 2846 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
4056#endif 2847#endif
4057 2848
4058 set_line_char(info); 2849 cy_set_line_char(info, tty);
4059 2850
4060 if ((old_termios->c_cflag & CRTSCTS) && 2851 if ((old_termios->c_cflag & CRTSCTS) &&
4061 !(tty->termios->c_cflag & CRTSCTS)) { 2852 !(tty->termios->c_cflag & CRTSCTS)) {
@@ -4112,8 +2903,6 @@ static void cy_throttle(struct tty_struct *tty)
4112 struct cyclades_port *info = tty->driver_data; 2903 struct cyclades_port *info = tty->driver_data;
4113 struct cyclades_card *card; 2904 struct cyclades_card *card;
4114 unsigned long flags; 2905 unsigned long flags;
4115 void __iomem *base_addr;
4116 int chip, channel, index;
4117 2906
4118#ifdef CY_DEBUG_THROTTLE 2907#ifdef CY_DEBUG_THROTTLE
4119 char buf[64]; 2908 char buf[64];
@@ -4135,24 +2924,9 @@ static void cy_throttle(struct tty_struct *tty)
4135 } 2924 }
4136 2925
4137 if (tty->termios->c_cflag & CRTSCTS) { 2926 if (tty->termios->c_cflag & CRTSCTS) {
4138 channel = info->line - card->first_line;
4139 if (!cy_is_Z(card)) { 2927 if (!cy_is_Z(card)) {
4140 chip = channel >> 2;
4141 channel &= 0x03;
4142 index = card->bus_index;
4143 base_addr = card->base_addr +
4144 (cy_chip_offset[chip] << index);
4145
4146 spin_lock_irqsave(&card->card_lock, flags); 2928 spin_lock_irqsave(&card->card_lock, flags);
4147 cy_writeb(base_addr + (CyCAR << index), 2929 cyy_change_rts_dtr(info, 0, TIOCM_RTS);
4148 (u_char) channel);
4149 if (info->rtsdtr_inv) {
4150 cy_writeb(base_addr + (CyMSVR2 << index),
4151 ~CyDTR);
4152 } else {
4153 cy_writeb(base_addr + (CyMSVR1 << index),
4154 ~CyRTS);
4155 }
4156 spin_unlock_irqrestore(&card->card_lock, flags); 2930 spin_unlock_irqrestore(&card->card_lock, flags);
4157 } else { 2931 } else {
4158 info->throttle = 1; 2932 info->throttle = 1;
@@ -4170,8 +2944,6 @@ static void cy_unthrottle(struct tty_struct *tty)
4170 struct cyclades_port *info = tty->driver_data; 2944 struct cyclades_port *info = tty->driver_data;
4171 struct cyclades_card *card; 2945 struct cyclades_card *card;
4172 unsigned long flags; 2946 unsigned long flags;
4173 void __iomem *base_addr;
4174 int chip, channel, index;
4175 2947
4176#ifdef CY_DEBUG_THROTTLE 2948#ifdef CY_DEBUG_THROTTLE
4177 char buf[64]; 2949 char buf[64];
@@ -4192,24 +2964,9 @@ static void cy_unthrottle(struct tty_struct *tty)
4192 2964
4193 if (tty->termios->c_cflag & CRTSCTS) { 2965 if (tty->termios->c_cflag & CRTSCTS) {
4194 card = info->card; 2966 card = info->card;
4195 channel = info->line - card->first_line;
4196 if (!cy_is_Z(card)) { 2967 if (!cy_is_Z(card)) {
4197 chip = channel >> 2;
4198 channel &= 0x03;
4199 index = card->bus_index;
4200 base_addr = card->base_addr +
4201 (cy_chip_offset[chip] << index);
4202
4203 spin_lock_irqsave(&card->card_lock, flags); 2968 spin_lock_irqsave(&card->card_lock, flags);
4204 cy_writeb(base_addr + (CyCAR << index), 2969 cyy_change_rts_dtr(info, TIOCM_RTS, 0);
4205 (u_char) channel);
4206 if (info->rtsdtr_inv) {
4207 cy_writeb(base_addr + (CyMSVR2 << index),
4208 CyDTR);
4209 } else {
4210 cy_writeb(base_addr + (CyMSVR1 << index),
4211 CyRTS);
4212 }
4213 spin_unlock_irqrestore(&card->card_lock, flags); 2970 spin_unlock_irqrestore(&card->card_lock, flags);
4214 } else { 2971 } else {
4215 info->throttle = 0; 2972 info->throttle = 0;
@@ -4224,8 +2981,7 @@ static void cy_stop(struct tty_struct *tty)
4224{ 2981{
4225 struct cyclades_card *cinfo; 2982 struct cyclades_card *cinfo;
4226 struct cyclades_port *info = tty->driver_data; 2983 struct cyclades_port *info = tty->driver_data;
4227 void __iomem *base_addr; 2984 int channel;
4228 int chip, channel, index;
4229 unsigned long flags; 2985 unsigned long flags;
4230 2986
4231#ifdef CY_DEBUG_OTHER 2987#ifdef CY_DEBUG_OTHER
@@ -4238,16 +2994,9 @@ static void cy_stop(struct tty_struct *tty)
4238 cinfo = info->card; 2994 cinfo = info->card;
4239 channel = info->line - cinfo->first_line; 2995 channel = info->line - cinfo->first_line;
4240 if (!cy_is_Z(cinfo)) { 2996 if (!cy_is_Z(cinfo)) {
4241 index = cinfo->bus_index;
4242 chip = channel >> 2;
4243 channel &= 0x03;
4244 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
4245
4246 spin_lock_irqsave(&cinfo->card_lock, flags); 2997 spin_lock_irqsave(&cinfo->card_lock, flags);
4247 cy_writeb(base_addr + (CyCAR << index), 2998 cyy_writeb(info, CyCAR, channel & 0x03);
4248 (u_char)(channel & 0x0003)); /* index channel */ 2999 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
4249 cy_writeb(base_addr + (CySRER << index),
4250 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
4251 spin_unlock_irqrestore(&cinfo->card_lock, flags); 3000 spin_unlock_irqrestore(&cinfo->card_lock, flags);
4252 } 3001 }
4253} /* cy_stop */ 3002} /* cy_stop */
@@ -4256,8 +3005,7 @@ static void cy_start(struct tty_struct *tty)
4256{ 3005{
4257 struct cyclades_card *cinfo; 3006 struct cyclades_card *cinfo;
4258 struct cyclades_port *info = tty->driver_data; 3007 struct cyclades_port *info = tty->driver_data;
4259 void __iomem *base_addr; 3008 int channel;
4260 int chip, channel, index;
4261 unsigned long flags; 3009 unsigned long flags;
4262 3010
4263#ifdef CY_DEBUG_OTHER 3011#ifdef CY_DEBUG_OTHER
@@ -4269,17 +3017,10 @@ static void cy_start(struct tty_struct *tty)
4269 3017
4270 cinfo = info->card; 3018 cinfo = info->card;
4271 channel = info->line - cinfo->first_line; 3019 channel = info->line - cinfo->first_line;
4272 index = cinfo->bus_index;
4273 if (!cy_is_Z(cinfo)) { 3020 if (!cy_is_Z(cinfo)) {
4274 chip = channel >> 2;
4275 channel &= 0x03;
4276 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
4277
4278 spin_lock_irqsave(&cinfo->card_lock, flags); 3021 spin_lock_irqsave(&cinfo->card_lock, flags);
4279 cy_writeb(base_addr + (CyCAR << index), 3022 cyy_writeb(info, CyCAR, channel & 0x03);
4280 (u_char) (channel & 0x0003)); /* index channel */ 3023 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
4281 cy_writeb(base_addr + (CySRER << index),
4282 readb(base_addr + (CySRER << index)) | CyTxRdy);
4283 spin_unlock_irqrestore(&cinfo->card_lock, flags); 3024 spin_unlock_irqrestore(&cinfo->card_lock, flags);
4284 } 3025 }
4285} /* cy_start */ 3026} /* cy_start */
@@ -4299,17 +3040,84 @@ static void cy_hangup(struct tty_struct *tty)
4299 return; 3040 return;
4300 3041
4301 cy_flush_buffer(tty); 3042 cy_flush_buffer(tty);
4302 shutdown(info); 3043 cy_shutdown(info, tty);
4303 info->port.count = 0; 3044 tty_port_hangup(&info->port);
4304#ifdef CY_DEBUG_COUNT
4305 printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
4306 current->pid);
4307#endif
4308 info->port.tty = NULL;
4309 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
4310 wake_up_interruptible(&info->port.open_wait);
4311} /* cy_hangup */ 3045} /* cy_hangup */
4312 3046
3047static int cyy_carrier_raised(struct tty_port *port)
3048{
3049 struct cyclades_port *info = container_of(port, struct cyclades_port,
3050 port);
3051 struct cyclades_card *cinfo = info->card;
3052 unsigned long flags;
3053 int channel = info->line - cinfo->first_line;
3054 u32 cd;
3055
3056 spin_lock_irqsave(&cinfo->card_lock, flags);
3057 cyy_writeb(info, CyCAR, channel & 0x03);
3058 cd = cyy_readb(info, CyMSVR1) & CyDCD;
3059 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3060
3061 return cd;
3062}
3063
3064static void cyy_dtr_rts(struct tty_port *port, int raise)
3065{
3066 struct cyclades_port *info = container_of(port, struct cyclades_port,
3067 port);
3068 struct cyclades_card *cinfo = info->card;
3069 unsigned long flags;
3070
3071 spin_lock_irqsave(&cinfo->card_lock, flags);
3072 cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0,
3073 raise ? 0 : TIOCM_RTS | TIOCM_DTR);
3074 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3075}
3076
3077static int cyz_carrier_raised(struct tty_port *port)
3078{
3079 struct cyclades_port *info = container_of(port, struct cyclades_port,
3080 port);
3081
3082 return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
3083}
3084
3085static void cyz_dtr_rts(struct tty_port *port, int raise)
3086{
3087 struct cyclades_port *info = container_of(port, struct cyclades_port,
3088 port);
3089 struct cyclades_card *cinfo = info->card;
3090 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
3091 int ret, channel = info->line - cinfo->first_line;
3092 u32 rs;
3093
3094 rs = readl(&ch_ctrl->rs_control);
3095 if (raise)
3096 rs |= C_RS_RTS | C_RS_DTR;
3097 else
3098 rs &= ~(C_RS_RTS | C_RS_DTR);
3099 cy_writel(&ch_ctrl->rs_control, rs);
3100 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
3101 if (ret != 0)
3102 printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
3103 __func__, info->line, ret);
3104#ifdef CY_DEBUG_DTR
3105 printk(KERN_DEBUG "%s: raising Z DTR\n", __func__);
3106#endif
3107}
3108
3109static const struct tty_port_operations cyy_port_ops = {
3110 .carrier_raised = cyy_carrier_raised,
3111 .dtr_rts = cyy_dtr_rts,
3112 .shutdown = cy_do_close,
3113};
3114
3115static const struct tty_port_operations cyz_port_ops = {
3116 .carrier_raised = cyz_carrier_raised,
3117 .dtr_rts = cyz_dtr_rts,
3118 .shutdown = cy_do_close,
3119};
3120
4313/* 3121/*
4314 * --------------------------------------------------------------------- 3122 * ---------------------------------------------------------------------
4315 * cy_init() and friends 3123 * cy_init() and friends
@@ -4321,8 +3129,7 @@ static void cy_hangup(struct tty_struct *tty)
4321static int __devinit cy_init_card(struct cyclades_card *cinfo) 3129static int __devinit cy_init_card(struct cyclades_card *cinfo)
4322{ 3130{
4323 struct cyclades_port *info; 3131 struct cyclades_port *info;
4324 unsigned int port; 3132 unsigned int channel, port;
4325 unsigned short chip_number;
4326 3133
4327 spin_lock_init(&cinfo->card_lock); 3134 spin_lock_init(&cinfo->card_lock);
4328 cinfo->intr_enabled = 0; 3135 cinfo->intr_enabled = 0;
@@ -4334,9 +3141,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4334 return -ENOMEM; 3141 return -ENOMEM;
4335 } 3142 }
4336 3143
4337 for (port = cinfo->first_line; port < cinfo->first_line + cinfo->nports; 3144 for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
4338 port++) { 3145 channel++, port++) {
4339 info = &cinfo->ports[port - cinfo->first_line]; 3146 info = &cinfo->ports[channel];
4340 tty_port_init(&info->port); 3147 tty_port_init(&info->port);
4341 info->magic = CYCLADES_MAGIC; 3148 info->magic = CYCLADES_MAGIC;
4342 info->card = cinfo; 3149 info->card = cinfo;
@@ -4346,10 +3153,19 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4346 info->port.close_delay = 5 * HZ / 10; 3153 info->port.close_delay = 5 * HZ / 10;
4347 info->port.flags = STD_COM_FLAGS; 3154 info->port.flags = STD_COM_FLAGS;
4348 init_completion(&info->shutdown_wait); 3155 init_completion(&info->shutdown_wait);
4349 init_waitqueue_head(&info->delta_msr_wait);
4350 3156
4351 if (cy_is_Z(cinfo)) { 3157 if (cy_is_Z(cinfo)) {
3158 struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
3159 struct ZFW_CTRL *zfw_ctrl;
3160
3161 info->port.ops = &cyz_port_ops;
4352 info->type = PORT_STARTECH; 3162 info->type = PORT_STARTECH;
3163
3164 zfw_ctrl = cinfo->base_addr +
3165 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3166 info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
3167 info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3168
4353 if (cinfo->hw_ver == ZO_V1) 3169 if (cinfo->hw_ver == ZO_V1)
4354 info->xmit_fifo_size = CYZ_FIFO_SIZE; 3170 info->xmit_fifo_size = CYZ_FIFO_SIZE;
4355 else 3171 else
@@ -4359,17 +3175,20 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4359 cyz_rx_restart, (unsigned long)info); 3175 cyz_rx_restart, (unsigned long)info);
4360#endif 3176#endif
4361 } else { 3177 } else {
3178 unsigned short chip_number;
4362 int index = cinfo->bus_index; 3179 int index = cinfo->bus_index;
3180
3181 info->port.ops = &cyy_port_ops;
4363 info->type = PORT_CIRRUS; 3182 info->type = PORT_CIRRUS;
4364 info->xmit_fifo_size = CyMAX_CHAR_FIFO; 3183 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
4365 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; 3184 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
4366 info->cor2 = CyETC; 3185 info->cor2 = CyETC;
4367 info->cor3 = 0x08; /* _very_ small rcv threshold */ 3186 info->cor3 = 0x08; /* _very_ small rcv threshold */
4368 3187
4369 chip_number = (port - cinfo->first_line) / 4; 3188 chip_number = channel / CyPORTS_PER_CHIP;
4370 info->chip_rev = readb(cinfo->base_addr + 3189 info->u.cyy.base_addr = cinfo->base_addr +
4371 (cy_chip_offset[chip_number] << index) + 3190 (cy_chip_offset[chip_number] << index);
4372 (CyGFRCR << index)); 3191 info->chip_rev = cyy_readb(info, CyGFRCR);
4373 3192
4374 if (info->chip_rev >= CD1400_REV_J) { 3193 if (info->chip_rev >= CD1400_REV_J) {
4375 /* It is a CD1400 rev. J or later */ 3194 /* It is a CD1400 rev. J or later */
@@ -5060,8 +3879,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5060 } 3879 }
5061 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; 3880 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
5062 } else { 3881 } else {
3882 struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
3883 struct ZFW_CTRL __iomem *zfw_ctrl;
3884
3885 zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3886
5063 cy_card[card_no].hw_ver = mailbox; 3887 cy_card[card_no].hw_ver = mailbox;
5064 cy_card[card_no].num_chips = (unsigned int)-1; 3888 cy_card[card_no].num_chips = (unsigned int)-1;
3889 cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
5065#ifdef CONFIG_CYZ_INTR 3890#ifdef CONFIG_CYZ_INTR
5066 /* allocate IRQ only if board has an IRQ */ 3891 /* allocate IRQ only if board has an IRQ */
5067 if (irq != 0 && irq != 255) { 3892 if (irq != 0 && irq != 255) {
@@ -5191,18 +4016,30 @@ static int cyclades_proc_show(struct seq_file *m, void *v)
5191 for (j = 0; j < cy_card[i].nports; j++) { 4016 for (j = 0; j < cy_card[i].nports; j++) {
5192 info = &cy_card[i].ports[j]; 4017 info = &cy_card[i].ports[j];
5193 4018
5194 if (info->port.count) 4019 if (info->port.count) {
4020 /* XXX is the ldisc num worth this? */
4021 struct tty_struct *tty;
4022 struct tty_ldisc *ld;
4023 int num = 0;
4024 tty = tty_port_tty_get(&info->port);
4025 if (tty) {
4026 ld = tty_ldisc_ref(tty);
4027 if (ld) {
4028 num = ld->ops->num;
4029 tty_ldisc_deref(ld);
4030 }
4031 tty_kref_put(tty);
4032 }
5195 seq_printf(m, "%3d %8lu %10lu %8lu " 4033 seq_printf(m, "%3d %8lu %10lu %8lu "
5196 "%10lu %8lu %9lu %6ld\n", info->line, 4034 "%10lu %8lu %9lu %6d\n", info->line,
5197 (cur_jifs - info->idle_stats.in_use) / 4035 (cur_jifs - info->idle_stats.in_use) /
5198 HZ, info->idle_stats.xmit_bytes, 4036 HZ, info->idle_stats.xmit_bytes,
5199 (cur_jifs - info->idle_stats.xmit_idle)/ 4037 (cur_jifs - info->idle_stats.xmit_idle)/
5200 HZ, info->idle_stats.recv_bytes, 4038 HZ, info->idle_stats.recv_bytes,
5201 (cur_jifs - info->idle_stats.recv_idle)/ 4039 (cur_jifs - info->idle_stats.recv_idle)/
5202 HZ, info->idle_stats.overruns, 4040 HZ, info->idle_stats.overruns,
5203 /* FIXME: double check locking */ 4041 num);
5204 (long)info->port.tty->ldisc->ops->num); 4042 } else
5205 else
5206 seq_printf(m, "%3d %8lu %10lu %8lu " 4043 seq_printf(m, "%3d %8lu %10lu %8lu "
5207 "%10lu %8lu %9lu %6ld\n", 4044 "%10lu %8lu %9lu %6ld\n",
5208 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); 4045 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index a5c59fc2b0ff..b19d43cd9542 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -572,7 +572,7 @@ static void check_modem_status(struct esp_struct *info)
572 info->icount.dcd++; 572 info->icount.dcd++;
573 if (status & UART_MSR_DCTS) 573 if (status & UART_MSR_DCTS)
574 info->icount.cts++; 574 info->icount.cts++;
575 wake_up_interruptible(&info->delta_msr_wait); 575 wake_up_interruptible(&info->port.delta_msr_wait);
576 } 576 }
577 577
578 if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 578 if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
@@ -927,7 +927,7 @@ static void shutdown(struct esp_struct *info)
927 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq 927 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
928 * here so the queue might never be waken up 928 * here so the queue might never be waken up
929 */ 929 */
930 wake_up_interruptible(&info->delta_msr_wait); 930 wake_up_interruptible(&info->port.delta_msr_wait);
931 wake_up_interruptible(&info->break_wait); 931 wake_up_interruptible(&info->break_wait);
932 932
933 /* stop a DMA transfer on the port being closed */ 933 /* stop a DMA transfer on the port being closed */
@@ -1800,7 +1800,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file *file,
1800 spin_unlock_irqrestore(&info->lock, flags); 1800 spin_unlock_irqrestore(&info->lock, flags);
1801 while (1) { 1801 while (1) {
1802 /* FIXME: convert to new style wakeup */ 1802 /* FIXME: convert to new style wakeup */
1803 interruptible_sleep_on(&info->delta_msr_wait); 1803 interruptible_sleep_on(&info->port.delta_msr_wait);
1804 /* see if a signal did it */ 1804 /* see if a signal did it */
1805 if (signal_pending(current)) 1805 if (signal_pending(current))
1806 return -ERESTARTSYS; 1806 return -ERESTARTSYS;
@@ -2452,7 +2452,6 @@ static int __init espserial_init(void)
2452 info->config.flow_off = flow_off; 2452 info->config.flow_off = flow_off;
2453 info->config.pio_threshold = pio_threshold; 2453 info->config.pio_threshold = pio_threshold;
2454 info->next_port = ports; 2454 info->next_port = ports;
2455 init_waitqueue_head(&info->delta_msr_wait);
2456 init_waitqueue_head(&info->break_wait); 2455 init_waitqueue_head(&info->break_wait);
2457 ports = info; 2456 ports = info;
2458 printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ", 2457 printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index fc93e2fc7c71..1573aebd54b5 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -153,7 +153,7 @@ static const struct file_operations rng_chrdev_ops = {
153static struct miscdevice rng_miscdev = { 153static struct miscdevice rng_miscdev = {
154 .minor = RNG_MISCDEV_MINOR, 154 .minor = RNG_MISCDEV_MINOR,
155 .name = RNG_MODULE_NAME, 155 .name = RNG_MODULE_NAME,
156 .devnode = "hwrng", 156 .nodename = "hwrng",
157 .fops = &rng_chrdev_ops, 157 .fops = &rng_chrdev_ops,
158}; 158};
159 159
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4f1f4cd670da..426bfdd7f3e0 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -846,37 +846,53 @@ static int isicom_carrier_raised(struct tty_port *port)
846 return (ip->status & ISI_DCD)?1 : 0; 846 return (ip->status & ISI_DCD)?1 : 0;
847} 847}
848 848
849static int isicom_open(struct tty_struct *tty, struct file *filp) 849static struct tty_port *isicom_find_port(struct tty_struct *tty)
850{ 850{
851 struct isi_port *port; 851 struct isi_port *port;
852 struct isi_board *card; 852 struct isi_board *card;
853 unsigned int board; 853 unsigned int board;
854 int error, line; 854 int line = tty->index;
855 855
856 line = tty->index;
857 if (line < 0 || line > PORT_COUNT-1) 856 if (line < 0 || line > PORT_COUNT-1)
858 return -ENODEV; 857 return NULL;
859 board = BOARD(line); 858 board = BOARD(line);
860 card = &isi_card[board]; 859 card = &isi_card[board];
861 860
862 if (!(card->status & FIRMWARE_LOADED)) 861 if (!(card->status & FIRMWARE_LOADED))
863 return -ENODEV; 862 return NULL;
864 863
865 /* open on a port greater than the port count for the card !!! */ 864 /* open on a port greater than the port count for the card !!! */
866 if (line > ((board * 16) + card->port_count - 1)) 865 if (line > ((board * 16) + card->port_count - 1))
867 return -ENODEV; 866 return NULL;
868 867
869 port = &isi_ports[line]; 868 port = &isi_ports[line];
870 if (isicom_paranoia_check(port, tty->name, "isicom_open")) 869 if (isicom_paranoia_check(port, tty->name, "isicom_open"))
871 return -ENODEV; 870 return NULL;
872 871
872 return &port->port;
873}
874
875static int isicom_open(struct tty_struct *tty, struct file *filp)
876{
877 struct isi_port *port;
878 struct isi_board *card;
879 struct tty_port *tport;
880 int error = 0;
881
882 tport = isicom_find_port(tty);
883 if (tport == NULL)
884 return -ENODEV;
885 port = container_of(tport, struct isi_port, port);
886 card = &isi_card[BOARD(tty->index)];
873 isicom_setup_board(card); 887 isicom_setup_board(card);
874 888
875 /* FIXME: locking on port.count etc */ 889 /* FIXME: locking on port.count etc */
876 port->port.count++; 890 port->port.count++;
877 tty->driver_data = port; 891 tty->driver_data = port;
878 tty_port_tty_set(&port->port, tty); 892 tty_port_tty_set(&port->port, tty);
879 error = isicom_setup_port(tty); 893 /* FIXME: Locking on Initialized flag */
894 if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
895 error = isicom_setup_port(tty);
880 if (error == 0) 896 if (error == 0)
881 error = tty_port_block_til_ready(&port->port, tty, filp); 897 error = tty_port_block_til_ready(&port->port, tty, filp);
882 return error; 898 return error;
@@ -952,19 +968,12 @@ static void isicom_flush_buffer(struct tty_struct *tty)
952 tty_wakeup(tty); 968 tty_wakeup(tty);
953} 969}
954 970
955static void isicom_close(struct tty_struct *tty, struct file *filp) 971static void isicom_close_port(struct tty_port *port)
956{ 972{
957 struct isi_port *ip = tty->driver_data; 973 struct isi_port *ip = container_of(port, struct isi_port, port);
958 struct tty_port *port = &ip->port; 974 struct isi_board *card = ip->card;
959 struct isi_board *card;
960 unsigned long flags; 975 unsigned long flags;
961 976
962 BUG_ON(!ip);
963
964 card = ip->card;
965 if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
966 return;
967
968 /* indicate to the card that no more data can be received 977 /* indicate to the card that no more data can be received
969 on this port */ 978 on this port */
970 spin_lock_irqsave(&card->card_lock, flags); 979 spin_lock_irqsave(&card->card_lock, flags);
@@ -974,9 +983,19 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
974 } 983 }
975 isicom_shutdown_port(ip); 984 isicom_shutdown_port(ip);
976 spin_unlock_irqrestore(&card->card_lock, flags); 985 spin_unlock_irqrestore(&card->card_lock, flags);
986}
987
988static void isicom_close(struct tty_struct *tty, struct file *filp)
989{
990 struct isi_port *ip = tty->driver_data;
991 struct tty_port *port = &ip->port;
992 if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
993 return;
977 994
995 if (tty_port_close_start(port, tty, filp) == 0)
996 return;
997 isicom_close_port(port);
978 isicom_flush_buffer(tty); 998 isicom_flush_buffer(tty);
979
980 tty_port_close_end(port, tty); 999 tty_port_close_end(port, tty);
981} 1000}
982 1001
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 0491cdf63f2a..0aede1d6a9ea 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -866,24 +866,25 @@ static const struct file_operations kmsg_fops = {
866 866
867static const struct memdev { 867static const struct memdev {
868 const char *name; 868 const char *name;
869 mode_t mode;
869 const struct file_operations *fops; 870 const struct file_operations *fops;
870 struct backing_dev_info *dev_info; 871 struct backing_dev_info *dev_info;
871} devlist[] = { 872} devlist[] = {
872 [ 1] = { "mem", &mem_fops, &directly_mappable_cdev_bdi }, 873 [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
873#ifdef CONFIG_DEVKMEM 874#ifdef CONFIG_DEVKMEM
874 [ 2] = { "kmem", &kmem_fops, &directly_mappable_cdev_bdi }, 875 [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
875#endif 876#endif
876 [ 3] = {"null", &null_fops, NULL }, 877 [3] = { "null", 0666, &null_fops, NULL },
877#ifdef CONFIG_DEVPORT 878#ifdef CONFIG_DEVPORT
878 [ 4] = { "port", &port_fops, NULL }, 879 [4] = { "port", 0, &port_fops, NULL },
879#endif 880#endif
880 [ 5] = { "zero", &zero_fops, &zero_bdi }, 881 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
881 [ 7] = { "full", &full_fops, NULL }, 882 [7] = { "full", 0666, &full_fops, NULL },
882 [ 8] = { "random", &random_fops, NULL }, 883 [8] = { "random", 0666, &random_fops, NULL },
883 [ 9] = { "urandom", &urandom_fops, NULL }, 884 [9] = { "urandom", 0666, &urandom_fops, NULL },
884 [11] = { "kmsg", &kmsg_fops, NULL }, 885 [11] = { "kmsg", 0, &kmsg_fops, NULL },
885#ifdef CONFIG_CRASH_DUMP 886#ifdef CONFIG_CRASH_DUMP
886 [12] = { "oldmem", &oldmem_fops, NULL }, 887 [12] = { "oldmem", 0, &oldmem_fops, NULL },
887#endif 888#endif
888}; 889};
889 890
@@ -920,6 +921,13 @@ static const struct file_operations memory_fops = {
920 .open = memory_open, 921 .open = memory_open,
921}; 922};
922 923
924static char *mem_devnode(struct device *dev, mode_t *mode)
925{
926 if (mode && devlist[MINOR(dev->devt)].mode)
927 *mode = devlist[MINOR(dev->devt)].mode;
928 return NULL;
929}
930
923static struct class *mem_class; 931static struct class *mem_class;
924 932
925static int __init chr_dev_init(void) 933static int __init chr_dev_init(void)
@@ -935,6 +943,7 @@ static int __init chr_dev_init(void)
935 printk("unable to get major %d for memory devs\n", MEM_MAJOR); 943 printk("unable to get major %d for memory devs\n", MEM_MAJOR);
936 944
937 mem_class = class_create(THIS_MODULE, "mem"); 945 mem_class = class_create(THIS_MODULE, "mem");
946 mem_class->devnode = mem_devnode;
938 for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { 947 for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
939 if (!devlist[minor].name) 948 if (!devlist[minor].name)
940 continue; 949 continue;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 62c99fa59e2b..1ee27cc23426 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -263,12 +263,14 @@ int misc_deregister(struct miscdevice *misc)
263EXPORT_SYMBOL(misc_register); 263EXPORT_SYMBOL(misc_register);
264EXPORT_SYMBOL(misc_deregister); 264EXPORT_SYMBOL(misc_deregister);
265 265
266static char *misc_nodename(struct device *dev) 266static char *misc_devnode(struct device *dev, mode_t *mode)
267{ 267{
268 struct miscdevice *c = dev_get_drvdata(dev); 268 struct miscdevice *c = dev_get_drvdata(dev);
269 269
270 if (c->devnode) 270 if (mode && c->mode)
271 return kstrdup(c->devnode, GFP_KERNEL); 271 *mode = c->mode;
272 if (c->nodename)
273 return kstrdup(c->nodename, GFP_KERNEL);
272 return NULL; 274 return NULL;
273} 275}
274 276
@@ -287,7 +289,7 @@ static int __init misc_init(void)
287 err = -EIO; 289 err = -EIO;
288 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) 290 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
289 goto fail_printk; 291 goto fail_printk;
290 misc_class->nodename = misc_nodename; 292 misc_class->devnode = misc_devnode;
291 return 0; 293 return 0;
292 294
293fail_printk: 295fail_printk:
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index dbf8d52f31d0..5e28d39b9e81 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -48,7 +48,7 @@
48 48
49#include "mxser.h" 49#include "mxser.h"
50 50
51#define MXSER_VERSION "2.0.4" /* 1.12 */ 51#define MXSER_VERSION "2.0.5" /* 1.14 */
52#define MXSERMAJOR 174 52#define MXSERMAJOR 174
53 53
54#define MXSER_BOARDS 4 /* Max. boards */ 54#define MXSER_BOARDS 4 /* Max. boards */
@@ -69,6 +69,7 @@
69#define PCI_DEVICE_ID_POS104UL 0x1044 69#define PCI_DEVICE_ID_POS104UL 0x1044
70#define PCI_DEVICE_ID_CB108 0x1080 70#define PCI_DEVICE_ID_CB108 0x1080
71#define PCI_DEVICE_ID_CP102UF 0x1023 71#define PCI_DEVICE_ID_CP102UF 0x1023
72#define PCI_DEVICE_ID_CP112UL 0x1120
72#define PCI_DEVICE_ID_CB114 0x1142 73#define PCI_DEVICE_ID_CB114 0x1142
73#define PCI_DEVICE_ID_CP114UL 0x1143 74#define PCI_DEVICE_ID_CP114UL 0x1143
74#define PCI_DEVICE_ID_CB134I 0x1341 75#define PCI_DEVICE_ID_CB134I 0x1341
@@ -139,7 +140,8 @@ static const struct mxser_cardinfo mxser_cards[] = {
139 { "CP-138U series", 8, }, 140 { "CP-138U series", 8, },
140 { "POS-104UL series", 4, }, 141 { "POS-104UL series", 4, },
141 { "CP-114UL series", 4, }, 142 { "CP-114UL series", 4, },
142/*30*/ { "CP-102UF series", 2, } 143/*30*/ { "CP-102UF series", 2, },
144 { "CP-112UL series", 2, },
143}; 145};
144 146
145/* driver_data correspond to the lines in the structure above 147/* driver_data correspond to the lines in the structure above
@@ -170,6 +172,7 @@ static struct pci_device_id mxser_pcibrds[] = {
170 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, 172 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 },
171 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, 173 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 },
172 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 }, 174 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 },
175 { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 31 },
173 { } 176 { }
174}; 177};
175MODULE_DEVICE_TABLE(pci, mxser_pcibrds); 178MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
@@ -258,7 +261,6 @@ struct mxser_port {
258 struct mxser_mon mon_data; 261 struct mxser_mon mon_data;
259 262
260 spinlock_t slock; 263 spinlock_t slock;
261 wait_queue_head_t delta_msr_wait;
262}; 264};
263 265
264struct mxser_board { 266struct mxser_board {
@@ -818,7 +820,7 @@ static void mxser_check_modem_status(struct tty_struct *tty,
818 if (status & UART_MSR_DCTS) 820 if (status & UART_MSR_DCTS)
819 port->icount.cts++; 821 port->icount.cts++;
820 port->mon_data.modem_status = status; 822 port->mon_data.modem_status = status;
821 wake_up_interruptible(&port->delta_msr_wait); 823 wake_up_interruptible(&port->port.delta_msr_wait);
822 824
823 if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 825 if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
824 if (status & UART_MSR_DCD) 826 if (status & UART_MSR_DCD)
@@ -973,7 +975,7 @@ static void mxser_shutdown(struct tty_struct *tty)
973 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq 975 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
974 * here so the queue might never be waken up 976 * here so the queue might never be waken up
975 */ 977 */
976 wake_up_interruptible(&info->delta_msr_wait); 978 wake_up_interruptible(&info->port.delta_msr_wait);
977 979
978 /* 980 /*
979 * Free the IRQ, if necessary 981 * Free the IRQ, if necessary
@@ -1073,34 +1075,17 @@ static void mxser_flush_buffer(struct tty_struct *tty)
1073} 1075}
1074 1076
1075 1077
1076/* 1078static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
1077 * This routine is called when the serial port gets closed. First, we
1078 * wait for the last remaining data to be sent. Then, we unlink its
1079 * async structure from the interrupt chain if necessary, and we free
1080 * that IRQ if nothing is left in the chain.
1081 */
1082static void mxser_close(struct tty_struct *tty, struct file *filp)
1083{ 1079{
1084 struct mxser_port *info = tty->driver_data; 1080 struct mxser_port *info = container_of(port, struct mxser_port, port);
1085 struct tty_port *port = &info->port;
1086
1087 unsigned long timeout; 1081 unsigned long timeout;
1088
1089 if (tty->index == MXSER_PORTS)
1090 return;
1091 if (!info)
1092 return;
1093
1094 if (tty_port_close_start(port, tty, filp) == 0)
1095 return;
1096
1097 /* 1082 /*
1098 * Save the termios structure, since this port may have 1083 * Save the termios structure, since this port may have
1099 * separate termios for callout and dialin. 1084 * separate termios for callout and dialin.
1100 * 1085 *
1101 * FIXME: Can this go ? 1086 * FIXME: Can this go ?
1102 */ 1087 */
1103 if (info->port.flags & ASYNC_NORMAL_ACTIVE) 1088 if (port->flags & ASYNC_NORMAL_ACTIVE)
1104 info->normal_termios = *tty->termios; 1089 info->normal_termios = *tty->termios;
1105 /* 1090 /*
1106 * At this point we stop accepting input. To do this, we 1091 * At this point we stop accepting input. To do this, we
@@ -1112,7 +1097,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1112 if (info->board->chip_flag) 1097 if (info->board->chip_flag)
1113 info->IER &= ~MOXA_MUST_RECV_ISR; 1098 info->IER &= ~MOXA_MUST_RECV_ISR;
1114 1099
1115 if (info->port.flags & ASYNC_INITIALIZED) { 1100 if (port->flags & ASYNC_INITIALIZED) {
1116 outb(info->IER, info->ioaddr + UART_IER); 1101 outb(info->IER, info->ioaddr + UART_IER);
1117 /* 1102 /*
1118 * Before we drop DTR, make sure the UART transmitter 1103 * Before we drop DTR, make sure the UART transmitter
@@ -1127,8 +1112,26 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1127 } 1112 }
1128 } 1113 }
1129 mxser_shutdown(tty); 1114 mxser_shutdown(tty);
1130 mxser_flush_buffer(tty);
1131 1115
1116}
1117
1118/*
1119 * This routine is called when the serial port gets closed. First, we
1120 * wait for the last remaining data to be sent. Then, we unlink its
1121 * async structure from the interrupt chain if necessary, and we free
1122 * that IRQ if nothing is left in the chain.
1123 */
1124static void mxser_close(struct tty_struct *tty, struct file *filp)
1125{
1126 struct mxser_port *info = tty->driver_data;
1127 struct tty_port *port = &info->port;
1128
1129 if (tty->index == MXSER_PORTS)
1130 return;
1131 if (tty_port_close_start(port, tty, filp) == 0)
1132 return;
1133 mxser_close_port(tty, port);
1134 mxser_flush_buffer(tty);
1132 /* Right now the tty_port set is done outside of the close_end helper 1135 /* Right now the tty_port set is done outside of the close_end helper
1133 as we don't yet have everyone using refcounts */ 1136 as we don't yet have everyone using refcounts */
1134 tty_port_close_end(port, tty); 1137 tty_port_close_end(port, tty);
@@ -1761,7 +1764,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1761 cnow = info->icount; /* note the counters on entry */ 1764 cnow = info->icount; /* note the counters on entry */
1762 spin_unlock_irqrestore(&info->slock, flags); 1765 spin_unlock_irqrestore(&info->slock, flags);
1763 1766
1764 return wait_event_interruptible(info->delta_msr_wait, 1767 return wait_event_interruptible(info->port.delta_msr_wait,
1765 mxser_cflags_changed(info, arg, &cnow)); 1768 mxser_cflags_changed(info, arg, &cnow));
1766 /* 1769 /*
1767 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 1770 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -1803,7 +1806,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1803 1806
1804 lock_kernel(); 1807 lock_kernel();
1805 len = mxser_chars_in_buffer(tty); 1808 len = mxser_chars_in_buffer(tty);
1806 lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; 1809 lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
1807 len += (lsr ? 0 : 1); 1810 len += (lsr ? 0 : 1);
1808 unlock_kernel(); 1811 unlock_kernel();
1809 1812
@@ -2413,7 +2416,6 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
2413 info->port.close_delay = 5 * HZ / 10; 2416 info->port.close_delay = 5 * HZ / 10;
2414 info->port.closing_wait = 30 * HZ; 2417 info->port.closing_wait = 30 * HZ;
2415 info->normal_termios = mxvar_sdriver->init_termios; 2418 info->normal_termios = mxvar_sdriver->init_termios;
2416 init_waitqueue_head(&info->delta_msr_wait);
2417 memset(&info->mon_data, 0, sizeof(struct mxser_mon)); 2419 memset(&info->mon_data, 0, sizeof(struct mxser_mon));
2418 info->err_shadow = 0; 2420 info->err_shadow = 0;
2419 spin_lock_init(&info->slock); 2421 spin_lock_init(&info->slock);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 4e28b35024ec..2e50f4dfc79c 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -272,7 +272,8 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
272 * 272 *
273 * This is a helper function that handles one output character 273 * This is a helper function that handles one output character
274 * (including special characters like TAB, CR, LF, etc.), 274 * (including special characters like TAB, CR, LF, etc.),
275 * putting the results in the tty driver's write buffer. 275 * doing OPOST processing and putting the results in the
276 * tty driver's write buffer.
276 * 277 *
277 * Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY 278 * Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
278 * and NLDLY. They simply aren't relevant in the world today. 279 * and NLDLY. They simply aren't relevant in the world today.
@@ -350,8 +351,9 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
350 * @c: character (or partial unicode symbol) 351 * @c: character (or partial unicode symbol)
351 * @tty: terminal device 352 * @tty: terminal device
352 * 353 *
353 * Perform OPOST processing. Returns -1 when the output device is 354 * Output one character with OPOST processing.
354 * full and the character must be retried. 355 * Returns -1 when the output device is full and the character
356 * must be retried.
355 * 357 *
356 * Locking: output_lock to protect column state and space left 358 * Locking: output_lock to protect column state and space left
357 * (also, this is called from n_tty_write under the 359 * (also, this is called from n_tty_write under the
@@ -377,8 +379,11 @@ static int process_output(unsigned char c, struct tty_struct *tty)
377/** 379/**
378 * process_output_block - block post processor 380 * process_output_block - block post processor
379 * @tty: terminal device 381 * @tty: terminal device
380 * @inbuf: user buffer 382 * @buf: character buffer
381 * @nr: number of bytes 383 * @nr: number of bytes to output
384 *
385 * Output a block of characters with OPOST processing.
386 * Returns the number of characters output.
382 * 387 *
383 * This path is used to speed up block console writes, among other 388 * This path is used to speed up block console writes, among other
384 * things when processing blocks of output data. It handles only 389 * things when processing blocks of output data. It handles only
@@ -571,33 +576,23 @@ static void process_echoes(struct tty_struct *tty)
571 break; 576 break;
572 577
573 default: 578 default:
574 if (iscntrl(op)) {
575 if (L_ECHOCTL(tty)) {
576 /*
577 * Ensure there is enough space
578 * for the whole ctrl pair.
579 */
580 if (space < 2) {
581 no_space_left = 1;
582 break;
583 }
584 tty_put_char(tty, '^');
585 tty_put_char(tty, op ^ 0100);
586 tty->column += 2;
587 space -= 2;
588 } else {
589 if (!space) {
590 no_space_left = 1;
591 break;
592 }
593 tty_put_char(tty, op);
594 space--;
595 }
596 }
597 /* 579 /*
598 * If above falls through, this was an 580 * If the op is not a special byte code,
599 * undefined op. 581 * it is a ctrl char tagged to be echoed
582 * as "^X" (where X is the letter
583 * representing the control char).
584 * Note that we must ensure there is
585 * enough space for the whole ctrl pair.
586 *
600 */ 587 */
588 if (space < 2) {
589 no_space_left = 1;
590 break;
591 }
592 tty_put_char(tty, '^');
593 tty_put_char(tty, op ^ 0100);
594 tty->column += 2;
595 space -= 2;
601 cp += 2; 596 cp += 2;
602 nr -= 2; 597 nr -= 2;
603 } 598 }
@@ -605,12 +600,18 @@ static void process_echoes(struct tty_struct *tty)
605 if (no_space_left) 600 if (no_space_left)
606 break; 601 break;
607 } else { 602 } else {
608 int retval; 603 if (O_OPOST(tty) &&
609 604 !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
610 retval = do_output_char(c, tty, space); 605 int retval = do_output_char(c, tty, space);
611 if (retval < 0) 606 if (retval < 0)
612 break; 607 break;
613 space -= retval; 608 space -= retval;
609 } else {
610 if (!space)
611 break;
612 tty_put_char(tty, c);
613 space -= 1;
614 }
614 cp += 1; 615 cp += 1;
615 nr -= 1; 616 nr -= 1;
616 } 617 }
@@ -798,8 +799,8 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty)
798 * Echo user input back onto the screen. This must be called only when 799 * Echo user input back onto the screen. This must be called only when
799 * L_ECHO(tty) is true. Called from the driver receive_buf path. 800 * L_ECHO(tty) is true. Called from the driver receive_buf path.
800 * 801 *
801 * This variant tags control characters to be possibly echoed as 802 * This variant tags control characters to be echoed as "^X"
802 * as "^X" (where X is the letter representing the control char). 803 * (where X is the letter representing the control char).
803 * 804 *
804 * Locking: echo_lock to protect the echo buffer 805 * Locking: echo_lock to protect the echo buffer
805 */ 806 */
@@ -812,7 +813,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
812 add_echo_byte(ECHO_OP_START, tty); 813 add_echo_byte(ECHO_OP_START, tty);
813 add_echo_byte(ECHO_OP_START, tty); 814 add_echo_byte(ECHO_OP_START, tty);
814 } else { 815 } else {
815 if (iscntrl(c) && c != '\t') 816 if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
816 add_echo_byte(ECHO_OP_START, tty); 817 add_echo_byte(ECHO_OP_START, tty);
817 add_echo_byte(c, tty); 818 add_echo_byte(c, tty);
818 } 819 }
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 40268db02e22..64acd05f71c8 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -261,7 +261,7 @@ static const struct file_operations raw_ctl_fops = {
261 261
262static struct cdev raw_cdev; 262static struct cdev raw_cdev;
263 263
264static char *raw_nodename(struct device *dev) 264static char *raw_devnode(struct device *dev, mode_t *mode)
265{ 265{
266 return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev)); 266 return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
267} 267}
@@ -289,7 +289,7 @@ static int __init raw_init(void)
289 ret = PTR_ERR(raw_class); 289 ret = PTR_ERR(raw_class);
290 goto error_region; 290 goto error_region;
291 } 291 }
292 raw_class->nodename = raw_nodename; 292 raw_class->devnode = raw_devnode;
293 device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); 293 device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
294 294
295 return 0; 295 return 0;
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 171711acf5cd..3cfa22d469e0 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -343,7 +343,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
343 if (port == NULL) 343 if (port == NULL)
344 return; 344 return;
345 345
346 tty = port->port.tty; 346 tty = tty_port_tty_get(&port->port);
347 347
348#ifdef RC_REPORT_OVERRUN 348#ifdef RC_REPORT_OVERRUN
349 status = rc_in(bp, CD180_RCSR); 349 status = rc_in(bp, CD180_RCSR);
@@ -355,18 +355,18 @@ static void rc_receive_exc(struct riscom_board const *bp)
355#endif 355#endif
356 ch = rc_in(bp, CD180_RDR); 356 ch = rc_in(bp, CD180_RDR);
357 if (!status) 357 if (!status)
358 return; 358 goto out;
359 if (status & RCSR_TOUT) { 359 if (status & RCSR_TOUT) {
360 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " 360 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
361 "Hardware problems ?\n", 361 "Hardware problems ?\n",
362 board_No(bp), port_No(port)); 362 board_No(bp), port_No(port));
363 return; 363 goto out;
364 364
365 } else if (status & RCSR_BREAK) { 365 } else if (status & RCSR_BREAK) {
366 printk(KERN_INFO "rc%d: port %d: Handling break...\n", 366 printk(KERN_INFO "rc%d: port %d: Handling break...\n",
367 board_No(bp), port_No(port)); 367 board_No(bp), port_No(port));
368 flag = TTY_BREAK; 368 flag = TTY_BREAK;
369 if (port->port.flags & ASYNC_SAK) 369 if (tty && (port->port.flags & ASYNC_SAK))
370 do_SAK(tty); 370 do_SAK(tty);
371 371
372 } else if (status & RCSR_PE) 372 } else if (status & RCSR_PE)
@@ -380,8 +380,12 @@ static void rc_receive_exc(struct riscom_board const *bp)
380 else 380 else
381 flag = TTY_NORMAL; 381 flag = TTY_NORMAL;
382 382
383 tty_insert_flip_char(tty, ch, flag); 383 if (tty) {
384 tty_flip_buffer_push(tty); 384 tty_insert_flip_char(tty, ch, flag);
385 tty_flip_buffer_push(tty);
386 }
387out:
388 tty_kref_put(tty);
385} 389}
386 390
387static void rc_receive(struct riscom_board const *bp) 391static void rc_receive(struct riscom_board const *bp)
@@ -394,7 +398,7 @@ static void rc_receive(struct riscom_board const *bp)
394 if (port == NULL) 398 if (port == NULL)
395 return; 399 return;
396 400
397 tty = port->port.tty; 401 tty = tty_port_tty_get(&port->port);
398 402
399 count = rc_in(bp, CD180_RDCR); 403 count = rc_in(bp, CD180_RDCR);
400 404
@@ -403,15 +407,14 @@ static void rc_receive(struct riscom_board const *bp)
403#endif 407#endif
404 408
405 while (count--) { 409 while (count--) {
406 if (tty_buffer_request_room(tty, 1) == 0) { 410 u8 ch = rc_in(bp, CD180_RDR);
407 printk(KERN_WARNING "rc%d: port %d: Working around " 411 if (tty)
408 "flip buffer overflow.\n", 412 tty_insert_flip_char(tty, ch, TTY_NORMAL);
409 board_No(bp), port_No(port)); 413 }
410 break; 414 if (tty) {
411 } 415 tty_flip_buffer_push(tty);
412 tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL); 416 tty_kref_put(tty);
413 } 417 }
414 tty_flip_buffer_push(tty);
415} 418}
416 419
417static void rc_transmit(struct riscom_board const *bp) 420static void rc_transmit(struct riscom_board const *bp)
@@ -424,22 +427,22 @@ static void rc_transmit(struct riscom_board const *bp)
424 if (port == NULL) 427 if (port == NULL)
425 return; 428 return;
426 429
427 tty = port->port.tty; 430 tty = tty_port_tty_get(&port->port);
428 431
429 if (port->IER & IER_TXEMPTY) { 432 if (port->IER & IER_TXEMPTY) {
430 /* FIFO drained */ 433 /* FIFO drained */
431 rc_out(bp, CD180_CAR, port_No(port)); 434 rc_out(bp, CD180_CAR, port_No(port));
432 port->IER &= ~IER_TXEMPTY; 435 port->IER &= ~IER_TXEMPTY;
433 rc_out(bp, CD180_IER, port->IER); 436 rc_out(bp, CD180_IER, port->IER);
434 return; 437 goto out;
435 } 438 }
436 439
437 if ((port->xmit_cnt <= 0 && !port->break_length) 440 if ((port->xmit_cnt <= 0 && !port->break_length)
438 || tty->stopped || tty->hw_stopped) { 441 || (tty && (tty->stopped || tty->hw_stopped))) {
439 rc_out(bp, CD180_CAR, port_No(port)); 442 rc_out(bp, CD180_CAR, port_No(port));
440 port->IER &= ~IER_TXRDY; 443 port->IER &= ~IER_TXRDY;
441 rc_out(bp, CD180_IER, port->IER); 444 rc_out(bp, CD180_IER, port->IER);
442 return; 445 goto out;
443 } 446 }
444 447
445 if (port->break_length) { 448 if (port->break_length) {
@@ -464,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)
464 rc_out(bp, CD180_CCR, CCR_CORCHG2); 467 rc_out(bp, CD180_CCR, CCR_CORCHG2);
465 port->break_length = 0; 468 port->break_length = 0;
466 } 469 }
467 return; 470 goto out;
468 } 471 }
469 472
470 count = CD180_NFIFO; 473 count = CD180_NFIFO;
@@ -480,8 +483,10 @@ static void rc_transmit(struct riscom_board const *bp)
480 port->IER &= ~IER_TXRDY; 483 port->IER &= ~IER_TXRDY;
481 rc_out(bp, CD180_IER, port->IER); 484 rc_out(bp, CD180_IER, port->IER);
482 } 485 }
483 if (port->xmit_cnt <= port->wakeup_chars) 486 if (tty && port->xmit_cnt <= port->wakeup_chars)
484 tty_wakeup(tty); 487 tty_wakeup(tty);
488out:
489 tty_kref_put(tty);
485} 490}
486 491
487static void rc_check_modem(struct riscom_board const *bp) 492static void rc_check_modem(struct riscom_board const *bp)
@@ -494,37 +499,43 @@ static void rc_check_modem(struct riscom_board const *bp)
494 if (port == NULL) 499 if (port == NULL)
495 return; 500 return;
496 501
497 tty = port->port.tty; 502 tty = tty_port_tty_get(&port->port);
498 503
499 mcr = rc_in(bp, CD180_MCR); 504 mcr = rc_in(bp, CD180_MCR);
500 if (mcr & MCR_CDCHG) { 505 if (mcr & MCR_CDCHG) {
501 if (rc_in(bp, CD180_MSVR) & MSVR_CD) 506 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
502 wake_up_interruptible(&port->port.open_wait); 507 wake_up_interruptible(&port->port.open_wait);
503 else 508 else if (tty)
504 tty_hangup(tty); 509 tty_hangup(tty);
505 } 510 }
506 511
507#ifdef RISCOM_BRAIN_DAMAGED_CTS 512#ifdef RISCOM_BRAIN_DAMAGED_CTS
508 if (mcr & MCR_CTSCHG) { 513 if (mcr & MCR_CTSCHG) {
509 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { 514 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
510 tty->hw_stopped = 0;
511 port->IER |= IER_TXRDY; 515 port->IER |= IER_TXRDY;
512 if (port->xmit_cnt <= port->wakeup_chars) 516 if (tty) {
513 tty_wakeup(tty); 517 tty->hw_stopped = 0;
518 if (port->xmit_cnt <= port->wakeup_chars)
519 tty_wakeup(tty);
520 }
514 } else { 521 } else {
515 tty->hw_stopped = 1; 522 if (tty)
523 tty->hw_stopped = 1;
516 port->IER &= ~IER_TXRDY; 524 port->IER &= ~IER_TXRDY;
517 } 525 }
518 rc_out(bp, CD180_IER, port->IER); 526 rc_out(bp, CD180_IER, port->IER);
519 } 527 }
520 if (mcr & MCR_DSRCHG) { 528 if (mcr & MCR_DSRCHG) {
521 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) { 529 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) {
522 tty->hw_stopped = 0;
523 port->IER |= IER_TXRDY; 530 port->IER |= IER_TXRDY;
524 if (port->xmit_cnt <= port->wakeup_chars) 531 if (tty) {
525 tty_wakeup(tty); 532 tty->hw_stopped = 0;
533 if (port->xmit_cnt <= port->wakeup_chars)
534 tty_wakeup(tty);
535 }
526 } else { 536 } else {
527 tty->hw_stopped = 1; 537 if (tty)
538 tty->hw_stopped = 1;
528 port->IER &= ~IER_TXRDY; 539 port->IER &= ~IER_TXRDY;
529 } 540 }
530 rc_out(bp, CD180_IER, port->IER); 541 rc_out(bp, CD180_IER, port->IER);
@@ -533,6 +544,7 @@ static void rc_check_modem(struct riscom_board const *bp)
533 544
534 /* Clear change bits */ 545 /* Clear change bits */
535 rc_out(bp, CD180_MCR, 0); 546 rc_out(bp, CD180_MCR, 0);
547 tty_kref_put(tty);
536} 548}
537 549
538/* The main interrupt processing routine */ 550/* The main interrupt processing routine */
@@ -632,9 +644,9 @@ static void rc_shutdown_board(struct riscom_board *bp)
632 * Setting up port characteristics. 644 * Setting up port characteristics.
633 * Must be called with disabled interrupts 645 * Must be called with disabled interrupts
634 */ 646 */
635static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) 647static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp,
648 struct riscom_port *port)
636{ 649{
637 struct tty_struct *tty = port->port.tty;
638 unsigned long baud; 650 unsigned long baud;
639 long tmp; 651 long tmp;
640 unsigned char cor1 = 0, cor3 = 0; 652 unsigned char cor1 = 0, cor3 = 0;
@@ -781,7 +793,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
781} 793}
782 794
783/* Must be called with interrupts enabled */ 795/* Must be called with interrupts enabled */
784static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) 796static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
797 struct riscom_port *port)
785{ 798{
786 unsigned long flags; 799 unsigned long flags;
787 800
@@ -793,11 +806,11 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
793 806
794 spin_lock_irqsave(&riscom_lock, flags); 807 spin_lock_irqsave(&riscom_lock, flags);
795 808
796 clear_bit(TTY_IO_ERROR, &port->port.tty->flags); 809 clear_bit(TTY_IO_ERROR, &tty->flags);
797 if (port->port.count == 1) 810 if (port->port.count == 1)
798 bp->count++; 811 bp->count++;
799 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 812 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
800 rc_change_speed(bp, port); 813 rc_change_speed(tty, bp, port);
801 port->port.flags |= ASYNC_INITIALIZED; 814 port->port.flags |= ASYNC_INITIALIZED;
802 815
803 spin_unlock_irqrestore(&riscom_lock, flags); 816 spin_unlock_irqrestore(&riscom_lock, flags);
@@ -898,9 +911,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
898 911
899 port->port.count++; 912 port->port.count++;
900 tty->driver_data = port; 913 tty->driver_data = port;
901 port->port.tty = tty; 914 tty_port_tty_set(&port->port, tty);
902 915
903 error = rc_setup_port(bp, port); 916 error = rc_setup_port(tty, bp, port);
904 if (error == 0) 917 if (error == 0)
905 error = tty_port_block_til_ready(&port->port, tty, filp); 918 error = tty_port_block_til_ready(&port->port, tty, filp);
906 return error; 919 return error;
@@ -921,20 +934,12 @@ static void rc_flush_buffer(struct tty_struct *tty)
921 tty_wakeup(tty); 934 tty_wakeup(tty);
922} 935}
923 936
924static void rc_close(struct tty_struct *tty, struct file *filp) 937static void rc_close_port(struct tty_port *port)
925{ 938{
926 struct riscom_port *port = tty->driver_data;
927 struct riscom_board *bp;
928 unsigned long flags; 939 unsigned long flags;
940 struct riscom_port *rp = container_of(port, struct riscom_port, port);
941 struct riscom_board *bp = port_Board(rp);
929 unsigned long timeout; 942 unsigned long timeout;
930
931 if (!port || rc_paranoia_check(port, tty->name, "close"))
932 return;
933
934 bp = port_Board(port);
935
936 if (tty_port_close_start(&port->port, tty, filp) == 0)
937 return;
938 943
939 /* 944 /*
940 * At this point we stop accepting input. To do this, we 945 * At this point we stop accepting input. To do this, we
@@ -944,31 +949,37 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
944 */ 949 */
945 950
946 spin_lock_irqsave(&riscom_lock, flags); 951 spin_lock_irqsave(&riscom_lock, flags);
947 port->IER &= ~IER_RXD; 952 rp->IER &= ~IER_RXD;
948 if (port->port.flags & ASYNC_INITIALIZED) { 953 if (port->flags & ASYNC_INITIALIZED) {
949 port->IER &= ~IER_TXRDY; 954 rp->IER &= ~IER_TXRDY;
950 port->IER |= IER_TXEMPTY; 955 rp->IER |= IER_TXEMPTY;
951 rc_out(bp, CD180_CAR, port_No(port)); 956 rc_out(bp, CD180_CAR, port_No(rp));
952 rc_out(bp, CD180_IER, port->IER); 957 rc_out(bp, CD180_IER, rp->IER);
953 /* 958 /*
954 * Before we drop DTR, make sure the UART transmitter 959 * Before we drop DTR, make sure the UART transmitter
955 * has completely drained; this is especially 960 * has completely drained; this is especially
956 * important if there is a transmit FIFO! 961 * important if there is a transmit FIFO!
957 */ 962 */
958 timeout = jiffies + HZ; 963 timeout = jiffies + HZ;
959 while (port->IER & IER_TXEMPTY) { 964 while (rp->IER & IER_TXEMPTY) {
960 spin_unlock_irqrestore(&riscom_lock, flags); 965 spin_unlock_irqrestore(&riscom_lock, flags);
961 msleep_interruptible(jiffies_to_msecs(port->timeout)); 966 msleep_interruptible(jiffies_to_msecs(rp->timeout));
962 spin_lock_irqsave(&riscom_lock, flags); 967 spin_lock_irqsave(&riscom_lock, flags);
963 if (time_after(jiffies, timeout)) 968 if (time_after(jiffies, timeout))
964 break; 969 break;
965 } 970 }
966 } 971 }
967 rc_shutdown_port(tty, bp, port); 972 rc_shutdown_port(port->tty, bp, rp);
968 rc_flush_buffer(tty);
969 spin_unlock_irqrestore(&riscom_lock, flags); 973 spin_unlock_irqrestore(&riscom_lock, flags);
974}
975
976static void rc_close(struct tty_struct *tty, struct file *filp)
977{
978 struct riscom_port *port = tty->driver_data;
970 979
971 tty_port_close_end(&port->port, tty); 980 if (!port || rc_paranoia_check(port, tty->name, "close"))
981 return;
982 tty_port_close(&port->port, tty, filp);
972} 983}
973 984
974static int rc_write(struct tty_struct *tty, 985static int rc_write(struct tty_struct *tty,
@@ -1170,7 +1181,7 @@ static int rc_send_break(struct tty_struct *tty, int length)
1170 return 0; 1181 return 0;
1171} 1182}
1172 1183
1173static int rc_set_serial_info(struct riscom_port *port, 1184static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port,
1174 struct serial_struct __user *newinfo) 1185 struct serial_struct __user *newinfo)
1175{ 1186{
1176 struct serial_struct tmp; 1187 struct serial_struct tmp;
@@ -1180,17 +1191,6 @@ static int rc_set_serial_info(struct riscom_port *port,
1180 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) 1191 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1181 return -EFAULT; 1192 return -EFAULT;
1182 1193
1183#if 0
1184 if ((tmp.irq != bp->irq) ||
1185 (tmp.port != bp->base) ||
1186 (tmp.type != PORT_CIRRUS) ||
1187 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1188 (tmp.custom_divisor != 0) ||
1189 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1190 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1191 return -EINVAL;
1192#endif
1193
1194 change_speed = ((port->port.flags & ASYNC_SPD_MASK) != 1194 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1195 (tmp.flags & ASYNC_SPD_MASK)); 1195 (tmp.flags & ASYNC_SPD_MASK));
1196 1196
@@ -1212,7 +1212,7 @@ static int rc_set_serial_info(struct riscom_port *port,
1212 unsigned long flags; 1212 unsigned long flags;
1213 1213
1214 spin_lock_irqsave(&riscom_lock, flags); 1214 spin_lock_irqsave(&riscom_lock, flags);
1215 rc_change_speed(bp, port); 1215 rc_change_speed(tty, bp, port);
1216 spin_unlock_irqrestore(&riscom_lock, flags); 1216 spin_unlock_irqrestore(&riscom_lock, flags);
1217 } 1217 }
1218 return 0; 1218 return 0;
@@ -1255,7 +1255,7 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp,
1255 break; 1255 break;
1256 case TIOCSSERIAL: 1256 case TIOCSSERIAL:
1257 lock_kernel(); 1257 lock_kernel();
1258 retval = rc_set_serial_info(port, argp); 1258 retval = rc_set_serial_info(tty, port, argp);
1259 unlock_kernel(); 1259 unlock_kernel();
1260 break; 1260 break;
1261 default: 1261 default:
@@ -1350,21 +1350,12 @@ static void rc_start(struct tty_struct *tty)
1350static void rc_hangup(struct tty_struct *tty) 1350static void rc_hangup(struct tty_struct *tty)
1351{ 1351{
1352 struct riscom_port *port = tty->driver_data; 1352 struct riscom_port *port = tty->driver_data;
1353 struct riscom_board *bp;
1354 unsigned long flags;
1355 1353
1356 if (rc_paranoia_check(port, tty->name, "rc_hangup")) 1354 if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1357 return; 1355 return;
1358 1356
1359 bp = port_Board(port); 1357 rc_shutdown_port(tty, port_Board(port), port);
1360 1358 tty_port_hangup(&port->port);
1361 rc_shutdown_port(tty, bp, port);
1362 spin_lock_irqsave(&port->port.lock, flags);
1363 port->port.count = 0;
1364 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1365 port->port.tty = NULL;
1366 wake_up_interruptible(&port->port.open_wait);
1367 spin_unlock_irqrestore(&port->port.lock, flags);
1368} 1359}
1369 1360
1370static void rc_set_termios(struct tty_struct *tty, 1361static void rc_set_termios(struct tty_struct *tty,
@@ -1377,7 +1368,7 @@ static void rc_set_termios(struct tty_struct *tty,
1377 return; 1368 return;
1378 1369
1379 spin_lock_irqsave(&riscom_lock, flags); 1370 spin_lock_irqsave(&riscom_lock, flags);
1380 rc_change_speed(port_Board(port), port); 1371 rc_change_speed(tty, port_Board(port), port);
1381 spin_unlock_irqrestore(&riscom_lock, flags); 1372 spin_unlock_irqrestore(&riscom_lock, flags);
1382 1373
1383 if ((old_termios->c_cflag & CRTSCTS) && 1374 if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1410,6 +1401,7 @@ static const struct tty_operations riscom_ops = {
1410 1401
1411static const struct tty_port_operations riscom_port_ops = { 1402static const struct tty_port_operations riscom_port_ops = {
1412 .carrier_raised = carrier_raised, 1403 .carrier_raised = carrier_raised,
1404 .shutdown = rc_close_port,
1413}; 1405};
1414 1406
1415 1407
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a3afa0c387cd..ea18a129b0b5 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty)
1184 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); 1184 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1185 return 0; 1185 return 0;
1186} 1186}
1187EXPORT_SYMBOL_GPL(tty_init_termios);
1187 1188
1188/** 1189/**
1189 * tty_driver_install_tty() - install a tty entry in the driver 1190 * tty_driver_install_tty() - install a tty entry in the driver
@@ -1386,10 +1387,14 @@ EXPORT_SYMBOL(tty_shutdown);
1386 * tty_mutex - sometimes only 1387 * tty_mutex - sometimes only
1387 * takes the file list lock internally when working on the list 1388 * takes the file list lock internally when working on the list
1388 * of ttys that the driver keeps. 1389 * of ttys that the driver keeps.
1390 *
1391 * This method gets called from a work queue so that the driver private
1392 * shutdown ops can sleep (needed for USB at least)
1389 */ 1393 */
1390static void release_one_tty(struct kref *kref) 1394static void release_one_tty(struct work_struct *work)
1391{ 1395{
1392 struct tty_struct *tty = container_of(kref, struct tty_struct, kref); 1396 struct tty_struct *tty =
1397 container_of(work, struct tty_struct, hangup_work);
1393 struct tty_driver *driver = tty->driver; 1398 struct tty_driver *driver = tty->driver;
1394 1399
1395 if (tty->ops->shutdown) 1400 if (tty->ops->shutdown)
@@ -1407,6 +1412,15 @@ static void release_one_tty(struct kref *kref)
1407 free_tty_struct(tty); 1412 free_tty_struct(tty);
1408} 1413}
1409 1414
1415static void queue_release_one_tty(struct kref *kref)
1416{
1417 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
1418 /* The hangup queue is now free so we can reuse it rather than
1419 waste a chunk of memory for each port */
1420 INIT_WORK(&tty->hangup_work, release_one_tty);
1421 schedule_work(&tty->hangup_work);
1422}
1423
1410/** 1424/**
1411 * tty_kref_put - release a tty kref 1425 * tty_kref_put - release a tty kref
1412 * @tty: tty device 1426 * @tty: tty device
@@ -1418,7 +1432,7 @@ static void release_one_tty(struct kref *kref)
1418void tty_kref_put(struct tty_struct *tty) 1432void tty_kref_put(struct tty_struct *tty)
1419{ 1433{
1420 if (tty) 1434 if (tty)
1421 kref_put(&tty->kref, release_one_tty); 1435 kref_put(&tty->kref, queue_release_one_tty);
1422} 1436}
1423EXPORT_SYMBOL(tty_kref_put); 1437EXPORT_SYMBOL(tty_kref_put);
1424 1438
@@ -2085,7 +2099,7 @@ static int tioccons(struct file *file)
2085 * the generic functionality existed. This piece of history is preserved 2099 * the generic functionality existed. This piece of history is preserved
2086 * in the expected tty API of posix OS's. 2100 * in the expected tty API of posix OS's.
2087 * 2101 *
2088 * Locking: none, the open fle handle ensures it won't go away. 2102 * Locking: none, the open file handle ensures it won't go away.
2089 */ 2103 */
2090 2104
2091static int fionbio(struct file *file, int __user *p) 2105static int fionbio(struct file *file, int __user *p)
@@ -3056,11 +3070,22 @@ void __init console_init(void)
3056 } 3070 }
3057} 3071}
3058 3072
3073static char *tty_devnode(struct device *dev, mode_t *mode)
3074{
3075 if (!mode)
3076 return NULL;
3077 if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
3078 dev->devt == MKDEV(TTYAUX_MAJOR, 2))
3079 *mode = 0666;
3080 return NULL;
3081}
3082
3059static int __init tty_class_init(void) 3083static int __init tty_class_init(void)
3060{ 3084{
3061 tty_class = class_create(THIS_MODULE, "tty"); 3085 tty_class = class_create(THIS_MODULE, "tty");
3062 if (IS_ERR(tty_class)) 3086 if (IS_ERR(tty_class))
3063 return PTR_ERR(tty_class); 3087 return PTR_ERR(tty_class);
3088 tty_class->devnode = tty_devnode;
3064 return 0; 3089 return 0;
3065} 3090}
3066 3091
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index ad6ba4ed2808..8e67d5c642a4 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -393,9 +393,7 @@ void tty_termios_encode_baud_rate(struct ktermios *termios,
393 termios->c_cflag |= (BOTHER << IBSHIFT); 393 termios->c_cflag |= (BOTHER << IBSHIFT);
394#else 394#else
395 if (ifound == -1 || ofound == -1) { 395 if (ifound == -1 || ofound == -1) {
396 static int warned; 396 printk_once(KERN_WARNING "tty: Unable to return correct "
397 if (!warned++)
398 printk(KERN_WARNING "tty: Unable to return correct "
399 "speed data as your architecture needs updating.\n"); 397 "speed data as your architecture needs updating.\n");
400 } 398 }
401#endif 399#endif
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index e48af9f79219..aafdbaebc16a 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -145,48 +145,33 @@ int tty_unregister_ldisc(int disc)
145} 145}
146EXPORT_SYMBOL(tty_unregister_ldisc); 146EXPORT_SYMBOL(tty_unregister_ldisc);
147 147
148 148static struct tty_ldisc_ops *get_ldops(int disc)
149/**
150 * tty_ldisc_try_get - try and reference an ldisc
151 * @disc: ldisc number
152 *
153 * Attempt to open and lock a line discipline into place. Return
154 * the line discipline refcounted or an error.
155 */
156
157static struct tty_ldisc *tty_ldisc_try_get(int disc)
158{ 149{
159 unsigned long flags; 150 unsigned long flags;
160 struct tty_ldisc *ld; 151 struct tty_ldisc_ops *ldops, *ret;
161 struct tty_ldisc_ops *ldops;
162 int err = -EINVAL;
163
164 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
165 if (ld == NULL)
166 return ERR_PTR(-ENOMEM);
167 152
168 spin_lock_irqsave(&tty_ldisc_lock, flags); 153 spin_lock_irqsave(&tty_ldisc_lock, flags);
169 ld->ops = NULL; 154 ret = ERR_PTR(-EINVAL);
170 ldops = tty_ldiscs[disc]; 155 ldops = tty_ldiscs[disc];
171 /* Check the entry is defined */
172 if (ldops) { 156 if (ldops) {
173 /* If the module is being unloaded we can't use it */ 157 ret = ERR_PTR(-EAGAIN);
174 if (!try_module_get(ldops->owner)) 158 if (try_module_get(ldops->owner)) {
175 err = -EAGAIN;
176 else {
177 /* lock it */
178 ldops->refcount++; 159 ldops->refcount++;
179 ld->ops = ldops; 160 ret = ldops;
180 atomic_set(&ld->users, 1);
181 err = 0;
182 } 161 }
183 } 162 }
184 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 163 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
185 if (err) { 164 return ret;
186 kfree(ld); 165}
187 return ERR_PTR(err); 166
188 } 167static void put_ldops(struct tty_ldisc_ops *ldops)
189 return ld; 168{
169 unsigned long flags;
170
171 spin_lock_irqsave(&tty_ldisc_lock, flags);
172 ldops->refcount--;
173 module_put(ldops->owner);
174 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
190} 175}
191 176
192/** 177/**
@@ -205,14 +190,31 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
205static struct tty_ldisc *tty_ldisc_get(int disc) 190static struct tty_ldisc *tty_ldisc_get(int disc)
206{ 191{
207 struct tty_ldisc *ld; 192 struct tty_ldisc *ld;
193 struct tty_ldisc_ops *ldops;
208 194
209 if (disc < N_TTY || disc >= NR_LDISCS) 195 if (disc < N_TTY || disc >= NR_LDISCS)
210 return ERR_PTR(-EINVAL); 196 return ERR_PTR(-EINVAL);
211 ld = tty_ldisc_try_get(disc); 197
212 if (IS_ERR(ld)) { 198 /*
199 * Get the ldisc ops - we may need to request them to be loaded
200 * dynamically and try again.
201 */
202 ldops = get_ldops(disc);
203 if (IS_ERR(ldops)) {
213 request_module("tty-ldisc-%d", disc); 204 request_module("tty-ldisc-%d", disc);
214 ld = tty_ldisc_try_get(disc); 205 ldops = get_ldops(disc);
206 if (IS_ERR(ldops))
207 return ERR_CAST(ldops);
215 } 208 }
209
210 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
211 if (ld == NULL) {
212 put_ldops(ldops);
213 return ERR_PTR(-ENOMEM);
214 }
215
216 ld->ops = ldops;
217 atomic_set(&ld->users, 1);
216 return ld; 218 return ld;
217} 219}
218 220
@@ -234,13 +236,13 @@ static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
234static int tty_ldiscs_seq_show(struct seq_file *m, void *v) 236static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
235{ 237{
236 int i = *(loff_t *)v; 238 int i = *(loff_t *)v;
237 struct tty_ldisc *ld; 239 struct tty_ldisc_ops *ldops;
238 240
239 ld = tty_ldisc_try_get(i); 241 ldops = get_ldops(i);
240 if (IS_ERR(ld)) 242 if (IS_ERR(ldops))
241 return 0; 243 return 0;
242 seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i); 244 seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
243 put_ldisc(ld); 245 put_ldops(ldops);
244 return 0; 246 return 0;
245} 247}
246 248
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 9769b1149f76..a4bbb28f10be 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -23,6 +23,7 @@ void tty_port_init(struct tty_port *port)
23 memset(port, 0, sizeof(*port)); 23 memset(port, 0, sizeof(*port));
24 init_waitqueue_head(&port->open_wait); 24 init_waitqueue_head(&port->open_wait);
25 init_waitqueue_head(&port->close_wait); 25 init_waitqueue_head(&port->close_wait);
26 init_waitqueue_head(&port->delta_msr_wait);
26 mutex_init(&port->mutex); 27 mutex_init(&port->mutex);
27 spin_lock_init(&port->lock); 28 spin_lock_init(&port->lock);
28 port->close_delay = (50 * HZ) / 100; 29 port->close_delay = (50 * HZ) / 100;
@@ -96,6 +97,14 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
96} 97}
97EXPORT_SYMBOL(tty_port_tty_set); 98EXPORT_SYMBOL(tty_port_tty_set);
98 99
100static void tty_port_shutdown(struct tty_port *port)
101{
102 if (port->ops->shutdown &&
103 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
104 port->ops->shutdown(port);
105
106}
107
99/** 108/**
100 * tty_port_hangup - hangup helper 109 * tty_port_hangup - hangup helper
101 * @port: tty port 110 * @port: tty port
@@ -116,6 +125,8 @@ void tty_port_hangup(struct tty_port *port)
116 port->tty = NULL; 125 port->tty = NULL;
117 spin_unlock_irqrestore(&port->lock, flags); 126 spin_unlock_irqrestore(&port->lock, flags);
118 wake_up_interruptible(&port->open_wait); 127 wake_up_interruptible(&port->open_wait);
128 wake_up_interruptible(&port->delta_msr_wait);
129 tty_port_shutdown(port);
119} 130}
120EXPORT_SYMBOL(tty_port_hangup); 131EXPORT_SYMBOL(tty_port_hangup);
121 132
@@ -296,15 +307,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
296 307
297 if (port->count) { 308 if (port->count) {
298 spin_unlock_irqrestore(&port->lock, flags); 309 spin_unlock_irqrestore(&port->lock, flags);
310 if (port->ops->drop)
311 port->ops->drop(port);
299 return 0; 312 return 0;
300 } 313 }
301 port->flags |= ASYNC_CLOSING; 314 set_bit(ASYNCB_CLOSING, &port->flags);
302 tty->closing = 1; 315 tty->closing = 1;
303 spin_unlock_irqrestore(&port->lock, flags); 316 spin_unlock_irqrestore(&port->lock, flags);
304 /* Don't block on a stalled port, just pull the chain */ 317 /* Don't block on a stalled port, just pull the chain */
305 if (tty->flow_stopped) 318 if (tty->flow_stopped)
306 tty_driver_flush_buffer(tty); 319 tty_driver_flush_buffer(tty);
307 if (port->flags & ASYNC_INITIALIZED && 320 if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
308 port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 321 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
309 tty_wait_until_sent(tty, port->closing_wait); 322 tty_wait_until_sent(tty, port->closing_wait);
310 if (port->drain_delay) { 323 if (port->drain_delay) {
@@ -318,6 +331,9 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
318 timeout = 2 * HZ; 331 timeout = 2 * HZ;
319 schedule_timeout_interruptible(timeout); 332 schedule_timeout_interruptible(timeout);
320 } 333 }
334 /* Don't call port->drop for the last reference. Callers will want
335 to drop the last active reference in ->shutdown() or the tty
336 shutdown path */
321 return 1; 337 return 1;
322} 338}
323EXPORT_SYMBOL(tty_port_close_start); 339EXPORT_SYMBOL(tty_port_close_start);
@@ -348,3 +364,14 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
348 spin_unlock_irqrestore(&port->lock, flags); 364 spin_unlock_irqrestore(&port->lock, flags);
349} 365}
350EXPORT_SYMBOL(tty_port_close_end); 366EXPORT_SYMBOL(tty_port_close_end);
367
368void tty_port_close(struct tty_port *port, struct tty_struct *tty,
369 struct file *filp)
370{
371 if (tty_port_close_start(port, tty, filp) == 0)
372 return;
373 tty_port_shutdown(port);
374 tty_port_close_end(port, tty);
375 tty_port_tty_set(port, NULL);
376}
377EXPORT_SYMBOL(tty_port_close);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 6aa88f50b039..0c80c68cd047 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -252,7 +252,6 @@ static void notify_update(struct vc_data *vc)
252 struct vt_notifier_param param = { .vc = vc }; 252 struct vt_notifier_param param = { .vc = vc };
253 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param); 253 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
254} 254}
255
256/* 255/*
257 * Low-Level Functions 256 * Low-Level Functions
258 */ 257 */
@@ -935,6 +934,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
935 934
936 if (CON_IS_VISIBLE(vc)) 935 if (CON_IS_VISIBLE(vc))
937 update_screen(vc); 936 update_screen(vc);
937 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
938 return err; 938 return err;
939} 939}
940 940
@@ -2129,11 +2129,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2129 currcons = vc->vc_num; 2129 currcons = vc->vc_num;
2130 if (!vc_cons_allocated(currcons)) { 2130 if (!vc_cons_allocated(currcons)) {
2131 /* could this happen? */ 2131 /* could this happen? */
2132 static int error = 0; 2132 printk_once("con_write: tty %d not allocated\n", currcons+1);
2133 if (!error) {
2134 error = 1;
2135 printk("con_write: tty %d not allocated\n", currcons+1);
2136 }
2137 release_console_sem(); 2133 release_console_sem();
2138 return 0; 2134 return 0;
2139 } 2135 }
@@ -2910,6 +2906,9 @@ static const struct tty_operations con_ops = {
2910 .flush_chars = con_flush_chars, 2906 .flush_chars = con_flush_chars,
2911 .chars_in_buffer = con_chars_in_buffer, 2907 .chars_in_buffer = con_chars_in_buffer,
2912 .ioctl = vt_ioctl, 2908 .ioctl = vt_ioctl,
2909#ifdef CONFIG_COMPAT
2910 .compat_ioctl = vt_compat_ioctl,
2911#endif
2913 .stop = con_stop, 2912 .stop = con_stop,
2914 .start = con_start, 2913 .start = con_start,
2915 .throttle = con_throttle, 2914 .throttle = con_throttle,
@@ -2955,7 +2954,6 @@ int __init vty_init(const struct file_operations *console_fops)
2955} 2954}
2956 2955
2957#ifndef VT_SINGLE_DRIVER 2956#ifndef VT_SINGLE_DRIVER
2958#include <linux/device.h>
2959 2957
2960static struct class *vtconsole_class; 2958static struct class *vtconsole_class;
2961 2959
@@ -3638,6 +3636,7 @@ void do_blank_screen(int entering_gfx)
3638 blank_state = blank_vesa_wait; 3636 blank_state = blank_vesa_wait;
3639 mod_timer(&console_timer, jiffies + vesa_off_interval); 3637 mod_timer(&console_timer, jiffies + vesa_off_interval);
3640 } 3638 }
3639 vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
3641} 3640}
3642EXPORT_SYMBOL(do_blank_screen); 3641EXPORT_SYMBOL(do_blank_screen);
3643 3642
@@ -3682,6 +3681,7 @@ void do_unblank_screen(int leaving_gfx)
3682 console_blank_hook(0); 3681 console_blank_hook(0);
3683 set_palette(vc); 3682 set_palette(vc);
3684 set_cursor(vc); 3683 set_cursor(vc);
3684 vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
3685} 3685}
3686EXPORT_SYMBOL(do_unblank_screen); 3686EXPORT_SYMBOL(do_unblank_screen);
3687 3687
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 95189f288f8c..29c651ab0d78 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -16,6 +16,8 @@
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/compat.h>
20#include <linux/module.h>
19#include <linux/kd.h> 21#include <linux/kd.h>
20#include <linux/vt.h> 22#include <linux/vt.h>
21#include <linux/string.h> 23#include <linux/string.h>
@@ -62,6 +64,133 @@ extern struct tty_driver *console_driver;
62static void complete_change_console(struct vc_data *vc); 64static void complete_change_console(struct vc_data *vc);
63 65
64/* 66/*
67 * User space VT_EVENT handlers
68 */
69
70struct vt_event_wait {
71 struct list_head list;
72 struct vt_event event;
73 int done;
74};
75
76static LIST_HEAD(vt_events);
77static DEFINE_SPINLOCK(vt_event_lock);
78static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
79
80/**
81 * vt_event_post
82 * @event: the event that occurred
83 * @old: old console
84 * @new: new console
85 *
86 * Post an VT event to interested VT handlers
87 */
88
89void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
90{
91 struct list_head *pos, *head;
92 unsigned long flags;
93 int wake = 0;
94
95 spin_lock_irqsave(&vt_event_lock, flags);
96 head = &vt_events;
97
98 list_for_each(pos, head) {
99 struct vt_event_wait *ve = list_entry(pos,
100 struct vt_event_wait, list);
101 if (!(ve->event.event & event))
102 continue;
103 ve->event.event = event;
104 /* kernel view is consoles 0..n-1, user space view is
105 console 1..n with 0 meaning current, so we must bias */
106 ve->event.old = old + 1;
107 ve->event.new = new + 1;
108 wake = 1;
109 ve->done = 1;
110 }
111 spin_unlock_irqrestore(&vt_event_lock, flags);
112 if (wake)
113 wake_up_interruptible(&vt_event_waitqueue);
114}
115
116/**
117 * vt_event_wait - wait for an event
118 * @vw: our event
119 *
120 * Waits for an event to occur which completes our vt_event_wait
121 * structure. On return the structure has wv->done set to 1 for success
122 * or 0 if some event such as a signal ended the wait.
123 */
124
125static void vt_event_wait(struct vt_event_wait *vw)
126{
127 unsigned long flags;
128 /* Prepare the event */
129 INIT_LIST_HEAD(&vw->list);
130 vw->done = 0;
131 /* Queue our event */
132 spin_lock_irqsave(&vt_event_lock, flags);
133 list_add(&vw->list, &vt_events);
134 spin_unlock_irqrestore(&vt_event_lock, flags);
135 /* Wait for it to pass */
136 wait_event_interruptible(vt_event_waitqueue, vw->done);
137 /* Dequeue it */
138 spin_lock_irqsave(&vt_event_lock, flags);
139 list_del(&vw->list);
140 spin_unlock_irqrestore(&vt_event_lock, flags);
141}
142
143/**
144 * vt_event_wait_ioctl - event ioctl handler
145 * @arg: argument to ioctl
146 *
147 * Implement the VT_WAITEVENT ioctl using the VT event interface
148 */
149
150static int vt_event_wait_ioctl(struct vt_event __user *event)
151{
152 struct vt_event_wait vw;
153
154 if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
155 return -EFAULT;
156 /* Highest supported event for now */
157 if (vw.event.event & ~VT_MAX_EVENT)
158 return -EINVAL;
159
160 vt_event_wait(&vw);
161 /* If it occurred report it */
162 if (vw.done) {
163 if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
164 return -EFAULT;
165 return 0;
166 }
167 return -EINTR;
168}
169
170/**
171 * vt_waitactive - active console wait
172 * @event: event code
173 * @n: new console
174 *
175 * Helper for event waits. Used to implement the legacy
176 * event waiting ioctls in terms of events
177 */
178
179int vt_waitactive(int n)
180{
181 struct vt_event_wait vw;
182 do {
183 if (n == fg_console + 1)
184 break;
185 vw.event.event = VT_EVENT_SWITCH;
186 vt_event_wait(&vw);
187 if (vw.done == 0)
188 return -EINTR;
189 } while (vw.event.new != n);
190 return 0;
191}
192
193/*
65 * these are the valid i/o ports we're allowed to change. they map all the 194 * these are the valid i/o ports we're allowed to change. they map all the
66 * video ports 195 * video ports
67 */ 196 */
@@ -360,6 +489,8 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_
360 return 0; 489 return 0;
361} 490}
362 491
492
493
363/* 494/*
364 * We handle the console-specific ioctl's here. We allow the 495 * We handle the console-specific ioctl's here. We allow the
365 * capability to modify any console, not just the fg_console. 496 * capability to modify any console, not just the fg_console.
@@ -842,6 +973,41 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
842 } 973 }
843 break; 974 break;
844 975
976 case VT_SETACTIVATE:
977 {
978 struct vt_setactivate vsa;
979
980 if (!perm)
981 goto eperm;
982
983 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
984 sizeof(struct vt_setactivate)))
985 return -EFAULT;
986 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
987 ret = -ENXIO;
988 else {
989 vsa.console--;
990 acquire_console_sem();
991 ret = vc_allocate(vsa.console);
992 if (ret == 0) {
993 struct vc_data *nvc;
994 /* This is safe providing we don't drop the
995 console sem between vc_allocate and
996 finishing referencing nvc */
997 nvc = vc_cons[vsa.console].d;
998 nvc->vt_mode = vsa.mode;
999 nvc->vt_mode.frsig = 0;
1000 put_pid(nvc->vt_pid);
1001 nvc->vt_pid = get_pid(task_pid(current));
1002 }
1003 release_console_sem();
1004 if (ret)
1005 break;
1006 /* Commence switch and lock */
1007 set_console(arg);
1008 }
1009 }
1010
845 /* 1011 /*
846 * wait until the specified VT has been activated 1012 * wait until the specified VT has been activated
847 */ 1013 */
@@ -851,7 +1017,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
851 if (arg == 0 || arg > MAX_NR_CONSOLES) 1017 if (arg == 0 || arg > MAX_NR_CONSOLES)
852 ret = -ENXIO; 1018 ret = -ENXIO;
853 else 1019 else
854 ret = vt_waitactive(arg - 1); 1020 ret = vt_waitactive(arg);
855 break; 1021 break;
856 1022
857 /* 1023 /*
@@ -1159,6 +1325,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
1159 ret = put_user(vc->vc_hi_font_mask, 1325 ret = put_user(vc->vc_hi_font_mask,
1160 (unsigned short __user *)arg); 1326 (unsigned short __user *)arg);
1161 break; 1327 break;
1328 case VT_WAITEVENT:
1329 ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
1330 break;
1162 default: 1331 default:
1163 ret = -ENOIOCTLCMD; 1332 ret = -ENOIOCTLCMD;
1164 } 1333 }
@@ -1170,54 +1339,6 @@ eperm:
1170 goto out; 1339 goto out;
1171} 1340}
1172 1341
1173/*
1174 * Sometimes we want to wait until a particular VT has been activated. We
1175 * do it in a very simple manner. Everybody waits on a single queue and
1176 * get woken up at once. Those that are satisfied go on with their business,
1177 * while those not ready go back to sleep. Seems overkill to add a wait
1178 * to each vt just for this - usually this does nothing!
1179 */
1180static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
1181
1182/*
1183 * Sleeps until a vt is activated, or the task is interrupted. Returns
1184 * 0 if activation, -EINTR if interrupted by a signal handler.
1185 */
1186int vt_waitactive(int vt)
1187{
1188 int retval;
1189 DECLARE_WAITQUEUE(wait, current);
1190
1191 add_wait_queue(&vt_activate_queue, &wait);
1192 for (;;) {
1193 retval = 0;
1194
1195 /*
1196 * Synchronize with redraw_screen(). By acquiring the console
1197 * semaphore we make sure that the console switch is completed
1198 * before we return. If we didn't wait for the semaphore, we
1199 * could return at a point where fg_console has already been
1200 * updated, but the console switch hasn't been completed.
1201 */
1202 acquire_console_sem();
1203 set_current_state(TASK_INTERRUPTIBLE);
1204 if (vt == fg_console) {
1205 release_console_sem();
1206 break;
1207 }
1208 release_console_sem();
1209 retval = -ERESTARTNOHAND;
1210 if (signal_pending(current))
1211 break;
1212 schedule();
1213 }
1214 remove_wait_queue(&vt_activate_queue, &wait);
1215 __set_current_state(TASK_RUNNING);
1216 return retval;
1217}
1218
1219#define vt_wake_waitactive() wake_up(&vt_activate_queue)
1220
1221void reset_vc(struct vc_data *vc) 1342void reset_vc(struct vc_data *vc)
1222{ 1343{
1223 vc->vc_mode = KD_TEXT; 1344 vc->vc_mode = KD_TEXT;
@@ -1256,12 +1377,216 @@ void vc_SAK(struct work_struct *work)
1256 release_console_sem(); 1377 release_console_sem();
1257} 1378}
1258 1379
1380#ifdef CONFIG_COMPAT
1381
1382struct compat_consolefontdesc {
1383 unsigned short charcount; /* characters in font (256 or 512) */
1384 unsigned short charheight; /* scan lines per character (1-32) */
1385 compat_caddr_t chardata; /* font data in expanded form */
1386};
1387
1388static inline int
1389compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
1390 int perm, struct console_font_op *op)
1391{
1392 struct compat_consolefontdesc cfdarg;
1393 int i;
1394
1395 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
1396 return -EFAULT;
1397
1398 switch (cmd) {
1399 case PIO_FONTX:
1400 if (!perm)
1401 return -EPERM;
1402 op->op = KD_FONT_OP_SET;
1403 op->flags = KD_FONT_FLAG_OLD;
1404 op->width = 8;
1405 op->height = cfdarg.charheight;
1406 op->charcount = cfdarg.charcount;
1407 op->data = compat_ptr(cfdarg.chardata);
1408 return con_font_op(vc_cons[fg_console].d, op);
1409 case GIO_FONTX:
1410 op->op = KD_FONT_OP_GET;
1411 op->flags = KD_FONT_FLAG_OLD;
1412 op->width = 8;
1413 op->height = cfdarg.charheight;
1414 op->charcount = cfdarg.charcount;
1415 op->data = compat_ptr(cfdarg.chardata);
1416 i = con_font_op(vc_cons[fg_console].d, op);
1417 if (i)
1418 return i;
1419 cfdarg.charheight = op->height;
1420 cfdarg.charcount = op->charcount;
1421 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
1422 return -EFAULT;
1423 return 0;
1424 }
1425 return -EINVAL;
1426}
1427
1428struct compat_console_font_op {
1429 compat_uint_t op; /* operation code KD_FONT_OP_* */
1430 compat_uint_t flags; /* KD_FONT_FLAG_* */
1431 compat_uint_t width, height; /* font size */
1432 compat_uint_t charcount;
1433 compat_caddr_t data; /* font data with height fixed to 32 */
1434};
1435
1436static inline int
1437compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1438 int perm, struct console_font_op *op, struct vc_data *vc)
1439{
1440 int i;
1441
1442 if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
1443 return -EFAULT;
1444 if (!perm && op->op != KD_FONT_OP_GET)
1445 return -EPERM;
1446 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1447 op->flags |= KD_FONT_FLAG_OLD;
1448 i = con_font_op(vc, op);
1449 if (i)
1450 return i;
1451 ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
1452 if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
1453 return -EFAULT;
1454 return 0;
1455}
1456
1457struct compat_unimapdesc {
1458 unsigned short entry_ct;
1459 compat_caddr_t entries;
1460};
1461
1462static inline int
1463compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
1464 int perm, struct vc_data *vc)
1465{
1466 struct compat_unimapdesc tmp;
1467 struct unipair __user *tmp_entries;
1468
1469 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1470 return -EFAULT;
1471 tmp_entries = compat_ptr(tmp.entries);
1472 if (tmp_entries)
1473 if (!access_ok(VERIFY_WRITE, tmp_entries,
1474 tmp.entry_ct*sizeof(struct unipair)))
1475 return -EFAULT;
1476 switch (cmd) {
1477 case PIO_UNIMAP:
1478 if (!perm)
1479 return -EPERM;
1480 return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
1481 case GIO_UNIMAP:
1482 if (!perm && fg_console != vc->vc_num)
1483 return -EPERM;
1484 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
1485 }
1486 return 0;
1487}
1488
1489long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
1490 unsigned int cmd, unsigned long arg)
1491{
1492 struct vc_data *vc = tty->driver_data;
1493 struct console_font_op op; /* used in multiple places here */
1494 struct kbd_struct *kbd;
1495 unsigned int console;
1496 void __user *up = (void __user *)arg;
1497 int perm;
1498 int ret = 0;
1499
1500 console = vc->vc_num;
1501
1502 lock_kernel();
1503
1504 if (!vc_cons_allocated(console)) { /* impossible? */
1505 ret = -ENOIOCTLCMD;
1506 goto out;
1507 }
1508
1509 /*
1510 * To have permissions to do most of the vt ioctls, we either have
1511 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
1512 */
1513 perm = 0;
1514 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1515 perm = 1;
1516
1517 kbd = kbd_table + console;
1518 switch (cmd) {
1519 /*
1520 * these need special handlers for incompatible data structures
1521 */
1522 case PIO_FONTX:
1523 case GIO_FONTX:
1524 ret = compat_fontx_ioctl(cmd, up, perm, &op);
1525 break;
1526
1527 case KDFONTOP:
1528 ret = compat_kdfontop_ioctl(up, perm, &op, vc);
1529 break;
1530
1531 case PIO_UNIMAP:
1532 case GIO_UNIMAP:
1533 ret = do_unimap_ioctl(cmd, up, perm, vc);
1534 break;
1535
1536 /*
1537 * all these treat 'arg' as an integer
1538 */
1539 case KIOCSOUND:
1540 case KDMKTONE:
1541#ifdef CONFIG_X86
1542 case KDADDIO:
1543 case KDDELIO:
1544#endif
1545 case KDSETMODE:
1546 case KDMAPDISP:
1547 case KDUNMAPDISP:
1548 case KDSKBMODE:
1549 case KDSKBMETA:
1550 case KDSKBLED:
1551 case KDSETLED:
1552 case KDSIGACCEPT:
1553 case VT_ACTIVATE:
1554 case VT_WAITACTIVE:
1555 case VT_RELDISP:
1556 case VT_DISALLOCATE:
1557 case VT_RESIZE:
1558 case VT_RESIZEX:
1559 goto fallback;
1560
1561 /*
1562 * the rest has a compatible data structure behind arg,
1563 * but we have to convert it to a proper 64 bit pointer.
1564 */
1565 default:
1566 arg = (unsigned long)compat_ptr(arg);
1567 goto fallback;
1568 }
1569out:
1570 unlock_kernel();
1571 return ret;
1572
1573fallback:
1574 unlock_kernel();
1575 return vt_ioctl(tty, file, cmd, arg);
1576}
1577
1578
1579#endif /* CONFIG_COMPAT */
1580
1581
1259/* 1582/*
1260 * Performs the back end of a vt switch 1583 * Performs the back end of a vt switch. Called under the console
1584 * semaphore.
1261 */ 1585 */
1262static void complete_change_console(struct vc_data *vc) 1586static void complete_change_console(struct vc_data *vc)
1263{ 1587{
1264 unsigned char old_vc_mode; 1588 unsigned char old_vc_mode;
1589 int old = fg_console;
1265 1590
1266 last_console = fg_console; 1591 last_console = fg_console;
1267 1592
@@ -1325,7 +1650,7 @@ static void complete_change_console(struct vc_data *vc)
1325 /* 1650 /*
1326 * Wake anyone waiting for their VT to activate 1651 * Wake anyone waiting for their VT to activate
1327 */ 1652 */
1328 vt_wake_waitactive(); 1653 vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
1329 return; 1654 return;
1330} 1655}
1331 1656
@@ -1398,3 +1723,58 @@ void change_console(struct vc_data *new_vc)
1398 1723
1399 complete_change_console(new_vc); 1724 complete_change_console(new_vc);
1400} 1725}
1726
1727/* Perform a kernel triggered VT switch for suspend/resume */
1728
1729static int disable_vt_switch;
1730
1731int vt_move_to_console(unsigned int vt, int alloc)
1732{
1733 int prev;
1734
1735 acquire_console_sem();
1736 /* Graphics mode - up to X */
1737 if (disable_vt_switch) {
1738 release_console_sem();
1739 return 0;
1740 }
1741 prev = fg_console;
1742
1743 if (alloc && vc_allocate(vt)) {
1744 /* we can't have a free VC for now. Too bad,
1745 * we don't want to mess the screen for now. */
1746 release_console_sem();
1747 return -ENOSPC;
1748 }
1749
1750 if (set_console(vt)) {
1751 /*
1752 * We're unable to switch to the SUSPEND_CONSOLE.
1753 * Let the calling function know so it can decide
1754 * what to do.
1755 */
1756 release_console_sem();
1757 return -EIO;
1758 }
1759 release_console_sem();
1760 if (vt_waitactive(vt + 1)) {
1761 pr_debug("Suspend: Can't switch VCs.");
1762 return -EINTR;
1763 }
1764 return prev;
1765}
1766
1767/*
1768 * Normally during a suspend, we allocate a new console and switch to it.
1769 * When we resume, we switch back to the original console. This switch
1770 * can be slow, so on systems where the framebuffer can handle restoration
1771 * of video registers anyways, there's little point in doing the console
1772 * switch. This function allows you to disable it by passing it '0'.
1773 */
1774void pm_set_vt_switch(int do_switch)
1775{
1776 acquire_console_sem();
1777 disable_vt_switch = !do_switch;
1778 release_console_sem();
1779}
1780EXPORT_SYMBOL(pm_set_vt_switch);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 8504a2108557..ad41f19b8e3f 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -17,6 +17,7 @@
17#include <linux/cpuidle.h> 17#include <linux/cpuidle.h>
18#include <linux/ktime.h> 18#include <linux/ktime.h>
19#include <linux/hrtimer.h> 19#include <linux/hrtimer.h>
20#include <trace/events/power.h>
20 21
21#include "cpuidle.h" 22#include "cpuidle.h"
22 23
@@ -91,6 +92,7 @@ static void cpuidle_idle_call(void)
91 /* give the governor an opportunity to reflect on the outcome */ 92 /* give the governor an opportunity to reflect on the outcome */
92 if (cpuidle_curr_governor->reflect) 93 if (cpuidle_curr_governor->reflect)
93 cpuidle_curr_governor->reflect(dev); 94 cpuidle_curr_governor->reflect(dev);
95 trace_power_end(0);
94} 96}
95 97
96/** 98/**
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 39b393d38bb3..e4d971c8b9d0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -18,6 +18,14 @@ menuconfig DRM
18 details. You should also select and configure AGP 18 details. You should also select and configure AGP
19 (/dev/agpgart) support. 19 (/dev/agpgart) support.
20 20
21config DRM_KMS_HELPER
22 tristate
23 depends on DRM
24 select FB
25 select FRAMEBUFFER_CONSOLE if !EMBEDDED
26 help
27 FB and CRTC helpers for KMS drivers.
28
21config DRM_TTM 29config DRM_TTM
22 tristate 30 tristate
23 depends on DRM 31 depends on DRM
@@ -36,6 +44,7 @@ config DRM_TDFX
36config DRM_R128 44config DRM_R128
37 tristate "ATI Rage 128" 45 tristate "ATI Rage 128"
38 depends on DRM && PCI 46 depends on DRM && PCI
47 select FW_LOADER
39 help 48 help
40 Choose this option if you have an ATI Rage 128 graphics card. If M 49 Choose this option if you have an ATI Rage 128 graphics card. If M
41 is selected, the module will be called r128. AGP support for 50 is selected, the module will be called r128. AGP support for
@@ -47,8 +56,9 @@ config DRM_RADEON
47 select FB_CFB_FILLRECT 56 select FB_CFB_FILLRECT
48 select FB_CFB_COPYAREA 57 select FB_CFB_COPYAREA
49 select FB_CFB_IMAGEBLIT 58 select FB_CFB_IMAGEBLIT
50 select FB 59 select FW_LOADER
51 select FRAMEBUFFER_CONSOLE if !EMBEDDED 60 select DRM_KMS_HELPER
61 select DRM_TTM
52 help 62 help
53 Choose this option if you have an ATI Radeon graphics card. There 63 Choose this option if you have an ATI Radeon graphics card. There
54 are both PCI and AGP versions. You don't need to choose this to 64 are both PCI and AGP versions. You don't need to choose this to
@@ -82,11 +92,10 @@ config DRM_I830
82config DRM_I915 92config DRM_I915
83 tristate "i915 driver" 93 tristate "i915 driver"
84 depends on AGP_INTEL 94 depends on AGP_INTEL
95 select DRM_KMS_HELPER
85 select FB_CFB_FILLRECT 96 select FB_CFB_FILLRECT
86 select FB_CFB_COPYAREA 97 select FB_CFB_COPYAREA
87 select FB_CFB_IMAGEBLIT 98 select FB_CFB_IMAGEBLIT
88 select FB
89 select FRAMEBUFFER_CONSOLE if !EMBEDDED
90 # i915 depends on ACPI_VIDEO when ACPI is enabled 99 # i915 depends on ACPI_VIDEO when ACPI is enabled
91 # but for select to work, need to select ACPI_VIDEO's dependencies, ick 100 # but for select to work, need to select ACPI_VIDEO's dependencies, ick
92 select VIDEO_OUTPUT_CONTROL if ACPI 101 select VIDEO_OUTPUT_CONTROL if ACPI
@@ -116,6 +125,7 @@ endchoice
116config DRM_MGA 125config DRM_MGA
117 tristate "Matrox g200/g400" 126 tristate "Matrox g200/g400"
118 depends on DRM 127 depends on DRM
128 select FW_LOADER
119 help 129 help
120 Choose this option if you have a Matrox G200, G400 or G450 graphics 130 Choose this option if you have a Matrox G200, G400 or G450 graphics
121 card. If M is selected, the module will be called mga. AGP 131 card. If M is selected, the module will be called mga. AGP
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index fe23f29f7cba..3c8827a7aabd 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -10,11 +10,15 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
10 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ 10 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
11 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ 11 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
12 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ 12 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
13 drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \ 13 drm_crtc.o drm_modes.o drm_edid.o \
14 drm_info.o drm_debugfs.o 14 drm_info.o drm_debugfs.o drm_encoder_slave.o
15 15
16drm-$(CONFIG_COMPAT) += drm_ioc32.o 16drm-$(CONFIG_COMPAT) += drm_ioc32.o
17 17
18drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
19
20obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
21
18obj-$(CONFIG_DRM) += drm.o 22obj-$(CONFIG_DRM) += drm.o
19obj-$(CONFIG_DRM_TTM) += ttm/ 23obj-$(CONFIG_DRM_TTM) += ttm/
20obj-$(CONFIG_DRM_TDFX) += tdfx/ 24obj-$(CONFIG_DRM_TDFX) += tdfx/
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 6246e3f3dad7..3d09e304f6f4 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -310,10 +310,10 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
310 (unsigned long long)map->offset, map->size); 310 (unsigned long long)map->offset, map->size);
311 311
312 break; 312 break;
313 }
313 case _DRM_GEM: 314 case _DRM_GEM:
314 DRM_ERROR("tried to rmmap GEM object\n"); 315 DRM_ERROR("tried to addmap GEM object\n");
315 break; 316 break;
316 }
317 case _DRM_SCATTER_GATHER: 317 case _DRM_SCATTER_GATHER:
318 if (!dev->sg) { 318 if (!dev->sg) {
319 kfree(map); 319 kfree(map);
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 0e994a0e46d4..0e3bd5b54b78 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -45,6 +45,23 @@ drm_clflush_page(struct page *page)
45 clflush(page_virtual + i); 45 clflush(page_virtual + i);
46 kunmap_atomic(page_virtual, KM_USER0); 46 kunmap_atomic(page_virtual, KM_USER0);
47} 47}
48
49static void drm_cache_flush_clflush(struct page *pages[],
50 unsigned long num_pages)
51{
52 unsigned long i;
53
54 mb();
55 for (i = 0; i < num_pages; i++)
56 drm_clflush_page(*pages++);
57 mb();
58}
59
60static void
61drm_clflush_ipi_handler(void *null)
62{
63 wbinvd();
64}
48#endif 65#endif
49 66
50void 67void
@@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
53 70
54#if defined(CONFIG_X86) 71#if defined(CONFIG_X86)
55 if (cpu_has_clflush) { 72 if (cpu_has_clflush) {
56 unsigned long i; 73 drm_cache_flush_clflush(pages, num_pages);
57
58 mb();
59 for (i = 0; i < num_pages; ++i)
60 drm_clflush_page(*pages++);
61 mb();
62
63 return; 74 return;
64 } 75 }
65 76
66 wbinvd(); 77 if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
78 printk(KERN_ERR "Timed out waiting for cache flush.\n");
79
80#elif defined(__powerpc__)
81 unsigned long i;
82 for (i = 0; i < num_pages; i++) {
83 struct page *page = pages[i];
84 void *page_virtual;
85
86 if (unlikely(page == NULL))
87 continue;
88
89 page_virtual = kmap_atomic(page, KM_USER0);
90 flush_dcache_range((unsigned long)page_virtual,
91 (unsigned long)page_virtual + PAGE_SIZE);
92 kunmap_atomic(page_virtual, KM_USER0);
93 }
94#else
95 printk(KERN_ERR "Architecture has no drm_cache.c support\n");
96 WARN_ON_ONCE(1);
67#endif 97#endif
68} 98}
69EXPORT_SYMBOL(drm_clflush_pages); 99EXPORT_SYMBOL(drm_clflush_pages);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2f631c75f704..ba728ad77f2a 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -68,10 +68,10 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
68 */ 68 */
69static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = 69static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
70{ 70{
71 { DRM_MODE_SCALE_NON_GPU, "Non-GPU" }, 71 { DRM_MODE_SCALE_NONE, "None" },
72 { DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" }, 72 { DRM_MODE_SCALE_FULLSCREEN, "Full" },
73 { DRM_MODE_SCALE_NO_SCALE, "No scale" }, 73 { DRM_MODE_SCALE_CENTER, "Center" },
74 { DRM_MODE_SCALE_ASPECT, "Aspect" }, 74 { DRM_MODE_SCALE_ASPECT, "Full aspect" },
75}; 75};
76 76
77static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = 77static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
@@ -108,6 +108,7 @@ static struct drm_prop_enum_list drm_tv_select_enum_list[] =
108 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 108 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
109 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 109 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
110 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 110 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
111 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
111}; 112};
112 113
113DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) 114DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
@@ -118,6 +119,7 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
118 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ 119 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
119 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ 120 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
120 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ 121 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
122 { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */
121}; 123};
122 124
123DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, 125DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
@@ -146,6 +148,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
146 { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, 148 { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
147 { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, 149 { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
148 { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, 150 { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
151 { DRM_MODE_CONNECTOR_TV, "TV", 0 },
149}; 152};
150 153
151static struct drm_prop_enum_list drm_encoder_enum_list[] = 154static struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -165,6 +168,7 @@ char *drm_get_encoder_name(struct drm_encoder *encoder)
165 encoder->base.id); 168 encoder->base.id);
166 return buf; 169 return buf;
167} 170}
171EXPORT_SYMBOL(drm_get_encoder_name);
168 172
169char *drm_get_connector_name(struct drm_connector *connector) 173char *drm_get_connector_name(struct drm_connector *connector)
170{ 174{
@@ -699,6 +703,42 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
699 drm_property_add_enum(dev->mode_config.tv_mode_property, i, 703 drm_property_add_enum(dev->mode_config.tv_mode_property, i,
700 i, modes[i]); 704 i, modes[i]);
701 705
706 dev->mode_config.tv_brightness_property =
707 drm_property_create(dev, DRM_MODE_PROP_RANGE,
708 "brightness", 2);
709 dev->mode_config.tv_brightness_property->values[0] = 0;
710 dev->mode_config.tv_brightness_property->values[1] = 100;
711
712 dev->mode_config.tv_contrast_property =
713 drm_property_create(dev, DRM_MODE_PROP_RANGE,
714 "contrast", 2);
715 dev->mode_config.tv_contrast_property->values[0] = 0;
716 dev->mode_config.tv_contrast_property->values[1] = 100;
717
718 dev->mode_config.tv_flicker_reduction_property =
719 drm_property_create(dev, DRM_MODE_PROP_RANGE,
720 "flicker reduction", 2);
721 dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
722 dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
723
724 dev->mode_config.tv_overscan_property =
725 drm_property_create(dev, DRM_MODE_PROP_RANGE,
726 "overscan", 2);
727 dev->mode_config.tv_overscan_property->values[0] = 0;
728 dev->mode_config.tv_overscan_property->values[1] = 100;
729
730 dev->mode_config.tv_saturation_property =
731 drm_property_create(dev, DRM_MODE_PROP_RANGE,
732 "saturation", 2);
733 dev->mode_config.tv_saturation_property->values[0] = 0;
734 dev->mode_config.tv_saturation_property->values[1] = 100;
735
736 dev->mode_config.tv_hue_property =
737 drm_property_create(dev, DRM_MODE_PROP_RANGE,
738 "hue", 2);
739 dev->mode_config.tv_hue_property->values[0] = 0;
740 dev->mode_config.tv_hue_property->values[1] = 100;
741
702 return 0; 742 return 0;
703} 743}
704EXPORT_SYMBOL(drm_mode_create_tv_properties); 744EXPORT_SYMBOL(drm_mode_create_tv_properties);
@@ -1044,7 +1084,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1044 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { 1084 if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
1045 list_for_each_entry(crtc, &dev->mode_config.crtc_list, 1085 list_for_each_entry(crtc, &dev->mode_config.crtc_list,
1046 head) { 1086 head) {
1047 DRM_DEBUG("CRTC ID is %d\n", crtc->base.id); 1087 DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
1048 if (put_user(crtc->base.id, crtc_id + copied)) { 1088 if (put_user(crtc->base.id, crtc_id + copied)) {
1049 ret = -EFAULT; 1089 ret = -EFAULT;
1050 goto out; 1090 goto out;
@@ -1072,7 +1112,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1072 list_for_each_entry(encoder, 1112 list_for_each_entry(encoder,
1073 &dev->mode_config.encoder_list, 1113 &dev->mode_config.encoder_list,
1074 head) { 1114 head) {
1075 DRM_DEBUG("ENCODER ID is %d\n", 1115 DRM_DEBUG_KMS("ENCODER ID is %d\n",
1076 encoder->base.id); 1116 encoder->base.id);
1077 if (put_user(encoder->base.id, encoder_id + 1117 if (put_user(encoder->base.id, encoder_id +
1078 copied)) { 1118 copied)) {
@@ -1103,7 +1143,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1103 list_for_each_entry(connector, 1143 list_for_each_entry(connector,
1104 &dev->mode_config.connector_list, 1144 &dev->mode_config.connector_list,
1105 head) { 1145 head) {
1106 DRM_DEBUG("CONNECTOR ID is %d\n", 1146 DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
1107 connector->base.id); 1147 connector->base.id);
1108 if (put_user(connector->base.id, 1148 if (put_user(connector->base.id,
1109 connector_id + copied)) { 1149 connector_id + copied)) {
@@ -1127,7 +1167,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
1127 } 1167 }
1128 card_res->count_connectors = connector_count; 1168 card_res->count_connectors = connector_count;
1129 1169
1130 DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs, 1170 DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
1131 card_res->count_connectors, card_res->count_encoders); 1171 card_res->count_connectors, card_res->count_encoders);
1132 1172
1133out: 1173out:
@@ -1230,7 +1270,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1230 1270
1231 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); 1271 memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
1232 1272
1233 DRM_DEBUG("connector id %d:\n", out_resp->connector_id); 1273 DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
1234 1274
1235 mutex_lock(&dev->mode_config.mutex); 1275 mutex_lock(&dev->mode_config.mutex);
1236 1276
@@ -1406,7 +1446,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1406 obj = drm_mode_object_find(dev, crtc_req->crtc_id, 1446 obj = drm_mode_object_find(dev, crtc_req->crtc_id,
1407 DRM_MODE_OBJECT_CRTC); 1447 DRM_MODE_OBJECT_CRTC);
1408 if (!obj) { 1448 if (!obj) {
1409 DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id); 1449 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
1410 ret = -EINVAL; 1450 ret = -EINVAL;
1411 goto out; 1451 goto out;
1412 } 1452 }
@@ -1419,7 +1459,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1419 list_for_each_entry(crtcfb, 1459 list_for_each_entry(crtcfb,
1420 &dev->mode_config.crtc_list, head) { 1460 &dev->mode_config.crtc_list, head) {
1421 if (crtcfb == crtc) { 1461 if (crtcfb == crtc) {
1422 DRM_DEBUG("Using current fb for setmode\n"); 1462 DRM_DEBUG_KMS("Using current fb for "
1463 "setmode\n");
1423 fb = crtc->fb; 1464 fb = crtc->fb;
1424 } 1465 }
1425 } 1466 }
@@ -1427,7 +1468,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1427 obj = drm_mode_object_find(dev, crtc_req->fb_id, 1468 obj = drm_mode_object_find(dev, crtc_req->fb_id,
1428 DRM_MODE_OBJECT_FB); 1469 DRM_MODE_OBJECT_FB);
1429 if (!obj) { 1470 if (!obj) {
1430 DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id); 1471 DRM_DEBUG_KMS("Unknown FB ID%d\n",
1472 crtc_req->fb_id);
1431 ret = -EINVAL; 1473 ret = -EINVAL;
1432 goto out; 1474 goto out;
1433 } 1475 }
@@ -1440,13 +1482,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1440 } 1482 }
1441 1483
1442 if (crtc_req->count_connectors == 0 && mode) { 1484 if (crtc_req->count_connectors == 0 && mode) {
1443 DRM_DEBUG("Count connectors is 0 but mode set\n"); 1485 DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
1444 ret = -EINVAL; 1486 ret = -EINVAL;
1445 goto out; 1487 goto out;
1446 } 1488 }
1447 1489
1448 if (crtc_req->count_connectors > 0 && (!mode || !fb)) { 1490 if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
1449 DRM_DEBUG("Count connectors is %d but no mode or fb set\n", 1491 DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
1450 crtc_req->count_connectors); 1492 crtc_req->count_connectors);
1451 ret = -EINVAL; 1493 ret = -EINVAL;
1452 goto out; 1494 goto out;
@@ -1479,7 +1521,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
1479 obj = drm_mode_object_find(dev, out_id, 1521 obj = drm_mode_object_find(dev, out_id,
1480 DRM_MODE_OBJECT_CONNECTOR); 1522 DRM_MODE_OBJECT_CONNECTOR);
1481 if (!obj) { 1523 if (!obj) {
1482 DRM_DEBUG("Connector id %d unknown\n", out_id); 1524 DRM_DEBUG_KMS("Connector id %d unknown\n",
1525 out_id);
1483 ret = -EINVAL; 1526 ret = -EINVAL;
1484 goto out; 1527 goto out;
1485 } 1528 }
@@ -1512,7 +1555,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
1512 struct drm_crtc *crtc; 1555 struct drm_crtc *crtc;
1513 int ret = 0; 1556 int ret = 0;
1514 1557
1515 DRM_DEBUG("\n"); 1558 DRM_DEBUG_KMS("\n");
1516 1559
1517 if (!req->flags) { 1560 if (!req->flags) {
1518 DRM_ERROR("no operation set\n"); 1561 DRM_ERROR("no operation set\n");
@@ -1522,7 +1565,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
1522 mutex_lock(&dev->mode_config.mutex); 1565 mutex_lock(&dev->mode_config.mutex);
1523 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); 1566 obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
1524 if (!obj) { 1567 if (!obj) {
1525 DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id); 1568 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
1526 ret = -EINVAL; 1569 ret = -EINVAL;
1527 goto out; 1570 goto out;
1528 } 1571 }
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 6aaa2cb23365..fe8697447f32 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -33,15 +33,6 @@
33#include "drm_crtc.h" 33#include "drm_crtc.h"
34#include "drm_crtc_helper.h" 34#include "drm_crtc_helper.h"
35 35
36/*
37 * Detailed mode info for 800x600@60Hz
38 */
39static struct drm_display_mode std_modes[] = {
40 { DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840,
41 968, 1056, 0, 600, 601, 605, 628, 0,
42 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
43};
44
45static void drm_mode_validate_flag(struct drm_connector *connector, 36static void drm_mode_validate_flag(struct drm_connector *connector,
46 int flags) 37 int flags)
47{ 38{
@@ -94,7 +85,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
94 int count = 0; 85 int count = 0;
95 int mode_flags = 0; 86 int mode_flags = 0;
96 87
97 DRM_DEBUG("%s\n", drm_get_connector_name(connector)); 88 DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector));
98 /* set all modes to the unverified state */ 89 /* set all modes to the unverified state */
99 list_for_each_entry_safe(mode, t, &connector->modes, head) 90 list_for_each_entry_safe(mode, t, &connector->modes, head)
100 mode->status = MODE_UNVERIFIED; 91 mode->status = MODE_UNVERIFIED;
@@ -102,15 +93,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
102 connector->status = connector->funcs->detect(connector); 93 connector->status = connector->funcs->detect(connector);
103 94
104 if (connector->status == connector_status_disconnected) { 95 if (connector->status == connector_status_disconnected) {
105 DRM_DEBUG("%s is disconnected\n", 96 DRM_DEBUG_KMS("%s is disconnected\n",
106 drm_get_connector_name(connector)); 97 drm_get_connector_name(connector));
107 /* TODO set EDID to NULL */ 98 goto prune;
108 return 0;
109 } 99 }
110 100
111 count = (*connector_funcs->get_modes)(connector); 101 count = (*connector_funcs->get_modes)(connector);
112 if (!count) 102 if (!count) {
113 return 0; 103 count = drm_add_modes_noedid(connector, 800, 600);
104 if (!count)
105 return 0;
106 }
114 107
115 drm_mode_connector_list_update(connector); 108 drm_mode_connector_list_update(connector);
116 109
@@ -130,7 +123,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
130 mode); 123 mode);
131 } 124 }
132 125
133 126prune:
134 drm_mode_prune_invalid(dev, &connector->modes, true); 127 drm_mode_prune_invalid(dev, &connector->modes, true);
135 128
136 if (list_empty(&connector->modes)) 129 if (list_empty(&connector->modes))
@@ -138,7 +131,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
138 131
139 drm_mode_sort(&connector->modes); 132 drm_mode_sort(&connector->modes);
140 133
141 DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector)); 134 DRM_DEBUG_KMS("Probed modes for %s\n",
135 drm_get_connector_name(connector));
142 list_for_each_entry_safe(mode, t, &connector->modes, head) { 136 list_for_each_entry_safe(mode, t, &connector->modes, head) {
143 mode->vrefresh = drm_mode_vrefresh(mode); 137 mode->vrefresh = drm_mode_vrefresh(mode);
144 138
@@ -165,39 +159,6 @@ int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
165} 159}
166EXPORT_SYMBOL(drm_helper_probe_connector_modes); 160EXPORT_SYMBOL(drm_helper_probe_connector_modes);
167 161
168static void drm_helper_add_std_modes(struct drm_device *dev,
169 struct drm_connector *connector)
170{
171 struct drm_display_mode *mode, *t;
172 int i;
173
174 for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
175 struct drm_display_mode *stdmode;
176
177 /*
178 * When no valid EDID modes are available we end up
179 * here and bailed in the past, now we add some standard
180 * modes and move on.
181 */
182 stdmode = drm_mode_duplicate(dev, &std_modes[i]);
183 drm_mode_probed_add(connector, stdmode);
184 drm_mode_list_concat(&connector->probed_modes,
185 &connector->modes);
186
187 DRM_DEBUG("Adding mode %s to %s\n", stdmode->name,
188 drm_get_connector_name(connector));
189 }
190 drm_mode_sort(&connector->modes);
191
192 DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector));
193 list_for_each_entry_safe(mode, t, &connector->modes, head) {
194 mode->vrefresh = drm_mode_vrefresh(mode);
195
196 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
197 drm_mode_debug_printmodeline(mode);
198 }
199}
200
201/** 162/**
202 * drm_helper_encoder_in_use - check if a given encoder is in use 163 * drm_helper_encoder_in_use - check if a given encoder is in use
203 * @encoder: encoder to check 164 * @encoder: encoder to check
@@ -258,13 +219,27 @@ EXPORT_SYMBOL(drm_helper_crtc_in_use);
258void drm_helper_disable_unused_functions(struct drm_device *dev) 219void drm_helper_disable_unused_functions(struct drm_device *dev)
259{ 220{
260 struct drm_encoder *encoder; 221 struct drm_encoder *encoder;
222 struct drm_connector *connector;
261 struct drm_encoder_helper_funcs *encoder_funcs; 223 struct drm_encoder_helper_funcs *encoder_funcs;
262 struct drm_crtc *crtc; 224 struct drm_crtc *crtc;
263 225
226 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
227 if (!connector->encoder)
228 continue;
229 if (connector->status == connector_status_disconnected)
230 connector->encoder = NULL;
231 }
232
264 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 233 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
265 encoder_funcs = encoder->helper_private; 234 encoder_funcs = encoder->helper_private;
266 if (!drm_helper_encoder_in_use(encoder)) 235 if (!drm_helper_encoder_in_use(encoder)) {
267 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); 236 if (encoder_funcs->disable)
237 (*encoder_funcs->disable)(encoder);
238 else
239 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
240 /* disconnector encoder from any connector */
241 encoder->crtc = NULL;
242 }
268 } 243 }
269 244
270 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 245 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -312,7 +287,7 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled)
312 287
313 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 288 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
314 enabled[i] = drm_connector_enabled(connector, true); 289 enabled[i] = drm_connector_enabled(connector, true);
315 DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, 290 DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
316 enabled[i] ? "yes" : "no"); 291 enabled[i] ? "yes" : "no");
317 any_enabled |= enabled[i]; 292 any_enabled |= enabled[i];
318 i++; 293 i++;
@@ -342,7 +317,7 @@ static bool drm_target_preferred(struct drm_device *dev,
342 continue; 317 continue;
343 } 318 }
344 319
345 DRM_DEBUG("looking for preferred mode on connector %d\n", 320 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
346 connector->base.id); 321 connector->base.id);
347 322
348 modes[i] = drm_has_preferred_mode(connector, width, height); 323 modes[i] = drm_has_preferred_mode(connector, width, height);
@@ -351,7 +326,7 @@ static bool drm_target_preferred(struct drm_device *dev,
351 list_for_each_entry(modes[i], &connector->modes, head) 326 list_for_each_entry(modes[i], &connector->modes, head)
352 break; 327 break;
353 } 328 }
354 DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : 329 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
355 "none"); 330 "none");
356 i++; 331 i++;
357 } 332 }
@@ -409,7 +384,7 @@ static int drm_pick_crtcs(struct drm_device *dev,
409 c = 0; 384 c = 0;
410 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 385 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
411 386
412 if ((connector->encoder->possible_crtcs & (1 << c)) == 0) { 387 if ((encoder->possible_crtcs & (1 << c)) == 0) {
413 c++; 388 c++;
414 continue; 389 continue;
415 } 390 }
@@ -452,7 +427,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
452 int width, height; 427 int width, height;
453 int i, ret; 428 int i, ret;
454 429
455 DRM_DEBUG("\n"); 430 DRM_DEBUG_KMS("\n");
456 431
457 width = dev->mode_config.max_width; 432 width = dev->mode_config.max_width;
458 height = dev->mode_config.max_height; 433 height = dev->mode_config.max_height;
@@ -475,7 +450,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
475 if (!ret) 450 if (!ret)
476 DRM_ERROR("Unable to find initial modes\n"); 451 DRM_ERROR("Unable to find initial modes\n");
477 452
478 DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); 453 DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
479 454
480 drm_pick_crtcs(dev, crtcs, modes, 0, width, height); 455 drm_pick_crtcs(dev, crtcs, modes, 0, width, height);
481 456
@@ -490,12 +465,14 @@ static void drm_setup_crtcs(struct drm_device *dev)
490 } 465 }
491 466
492 if (mode && crtc) { 467 if (mode && crtc) {
493 DRM_DEBUG("desired mode %s set on crtc %d\n", 468 DRM_DEBUG_KMS("desired mode %s set on crtc %d\n",
494 mode->name, crtc->base.id); 469 mode->name, crtc->base.id);
495 crtc->desired_mode = mode; 470 crtc->desired_mode = mode;
496 connector->encoder->crtc = crtc; 471 connector->encoder->crtc = crtc;
497 } else 472 } else {
498 connector->encoder->crtc = NULL; 473 connector->encoder->crtc = NULL;
474 connector->encoder = NULL;
475 }
499 i++; 476 i++;
500 } 477 }
501 478
@@ -702,18 +679,17 @@ EXPORT_SYMBOL(drm_crtc_helper_set_mode);
702int drm_crtc_helper_set_config(struct drm_mode_set *set) 679int drm_crtc_helper_set_config(struct drm_mode_set *set)
703{ 680{
704 struct drm_device *dev; 681 struct drm_device *dev;
705 struct drm_crtc **save_crtcs, *new_crtc; 682 struct drm_crtc *save_crtcs, *new_crtc, *crtc;
706 struct drm_encoder **save_encoders, *new_encoder; 683 struct drm_encoder *save_encoders, *new_encoder, *encoder;
707 struct drm_framebuffer *old_fb = NULL; 684 struct drm_framebuffer *old_fb = NULL;
708 bool save_enabled;
709 bool mode_changed = false; /* if true do a full mode set */ 685 bool mode_changed = false; /* if true do a full mode set */
710 bool fb_changed = false; /* if true and !mode_changed just do a flip */ 686 bool fb_changed = false; /* if true and !mode_changed just do a flip */
711 struct drm_connector *connector; 687 struct drm_connector *save_connectors, *connector;
712 int count = 0, ro, fail = 0; 688 int count = 0, ro, fail = 0;
713 struct drm_crtc_helper_funcs *crtc_funcs; 689 struct drm_crtc_helper_funcs *crtc_funcs;
714 int ret = 0; 690 int ret = 0;
715 691
716 DRM_DEBUG("\n"); 692 DRM_DEBUG_KMS("\n");
717 693
718 if (!set) 694 if (!set)
719 return -EINVAL; 695 return -EINVAL;
@@ -726,37 +702,60 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
726 702
727 crtc_funcs = set->crtc->helper_private; 703 crtc_funcs = set->crtc->helper_private;
728 704
729 DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n", 705 DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:"
706 " %d (x, y) (%i, %i)\n",
730 set->crtc, set->crtc->base.id, set->fb, set->connectors, 707 set->crtc, set->crtc->base.id, set->fb, set->connectors,
731 (int)set->num_connectors, set->x, set->y); 708 (int)set->num_connectors, set->x, set->y);
732 709
733 dev = set->crtc->dev; 710 dev = set->crtc->dev;
734 711
735 /* save previous config */ 712 /* Allocate space for the backup of all (non-pointer) crtc, encoder and
736 save_enabled = set->crtc->enabled; 713 * connector data. */
737 714 save_crtcs = kzalloc(dev->mode_config.num_crtc *
738 /* 715 sizeof(struct drm_crtc), GFP_KERNEL);
739 * We do mode_config.num_connectors here since we'll look at the
740 * CRTC and encoder associated with each connector later.
741 */
742 save_crtcs = kzalloc(dev->mode_config.num_connector *
743 sizeof(struct drm_crtc *), GFP_KERNEL);
744 if (!save_crtcs) 716 if (!save_crtcs)
745 return -ENOMEM; 717 return -ENOMEM;
746 718
747 save_encoders = kzalloc(dev->mode_config.num_connector * 719 save_encoders = kzalloc(dev->mode_config.num_encoder *
748 sizeof(struct drm_encoders *), GFP_KERNEL); 720 sizeof(struct drm_encoder), GFP_KERNEL);
749 if (!save_encoders) { 721 if (!save_encoders) {
750 kfree(save_crtcs); 722 kfree(save_crtcs);
751 return -ENOMEM; 723 return -ENOMEM;
752 } 724 }
753 725
726 save_connectors = kzalloc(dev->mode_config.num_connector *
727 sizeof(struct drm_connector), GFP_KERNEL);
728 if (!save_connectors) {
729 kfree(save_crtcs);
730 kfree(save_encoders);
731 return -ENOMEM;
732 }
733
734 /* Copy data. Note that driver private data is not affected.
735 * Should anything bad happen only the expected state is
736 * restored, not the drivers personal bookkeeping.
737 */
738 count = 0;
739 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
740 save_crtcs[count++] = *crtc;
741 }
742
743 count = 0;
744 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
745 save_encoders[count++] = *encoder;
746 }
747
748 count = 0;
749 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
750 save_connectors[count++] = *connector;
751 }
752
754 /* We should be able to check here if the fb has the same properties 753 /* We should be able to check here if the fb has the same properties
755 * and then just flip_or_move it */ 754 * and then just flip_or_move it */
756 if (set->crtc->fb != set->fb) { 755 if (set->crtc->fb != set->fb) {
757 /* If we have no fb then treat it as a full mode set */ 756 /* If we have no fb then treat it as a full mode set */
758 if (set->crtc->fb == NULL) { 757 if (set->crtc->fb == NULL) {
759 DRM_DEBUG("crtc has no fb, full mode set\n"); 758 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
760 mode_changed = true; 759 mode_changed = true;
761 } else if (set->fb == NULL) { 760 } else if (set->fb == NULL) {
762 mode_changed = true; 761 mode_changed = true;
@@ -772,7 +771,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
772 fb_changed = true; 771 fb_changed = true;
773 772
774 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 773 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
775 DRM_DEBUG("modes are different, full mode set\n"); 774 DRM_DEBUG_KMS("modes are different, full mode set\n");
776 drm_mode_debug_printmodeline(&set->crtc->mode); 775 drm_mode_debug_printmodeline(&set->crtc->mode);
777 drm_mode_debug_printmodeline(set->mode); 776 drm_mode_debug_printmodeline(set->mode);
778 mode_changed = true; 777 mode_changed = true;
@@ -783,7 +782,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
783 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 782 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
784 struct drm_connector_helper_funcs *connector_funcs = 783 struct drm_connector_helper_funcs *connector_funcs =
785 connector->helper_private; 784 connector->helper_private;
786 save_encoders[count++] = connector->encoder;
787 new_encoder = connector->encoder; 785 new_encoder = connector->encoder;
788 for (ro = 0; ro < set->num_connectors; ro++) { 786 for (ro = 0; ro < set->num_connectors; ro++) {
789 if (set->connectors[ro] == connector) { 787 if (set->connectors[ro] == connector) {
@@ -798,15 +796,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
798 } 796 }
799 797
800 if (new_encoder != connector->encoder) { 798 if (new_encoder != connector->encoder) {
801 DRM_DEBUG("encoder changed, full mode switch\n"); 799 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
802 mode_changed = true; 800 mode_changed = true;
801 /* If the encoder is reused for another connector, then
802 * the appropriate crtc will be set later.
803 */
804 if (connector->encoder)
805 connector->encoder->crtc = NULL;
803 connector->encoder = new_encoder; 806 connector->encoder = new_encoder;
804 } 807 }
805 } 808 }
806 809
807 if (fail) { 810 if (fail) {
808 ret = -EINVAL; 811 ret = -EINVAL;
809 goto fail_no_encoder; 812 goto fail;
810 } 813 }
811 814
812 count = 0; 815 count = 0;
@@ -814,8 +817,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
814 if (!connector->encoder) 817 if (!connector->encoder)
815 continue; 818 continue;
816 819
817 save_crtcs[count++] = connector->encoder->crtc;
818
819 if (connector->encoder->crtc == set->crtc) 820 if (connector->encoder->crtc == set->crtc)
820 new_crtc = NULL; 821 new_crtc = NULL;
821 else 822 else
@@ -830,14 +831,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
830 if (new_crtc && 831 if (new_crtc &&
831 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { 832 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
832 ret = -EINVAL; 833 ret = -EINVAL;
833 goto fail_set_mode; 834 goto fail;
834 } 835 }
835 if (new_crtc != connector->encoder->crtc) { 836 if (new_crtc != connector->encoder->crtc) {
836 DRM_DEBUG("crtc changed, full mode switch\n"); 837 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
837 mode_changed = true; 838 mode_changed = true;
838 connector->encoder->crtc = new_crtc; 839 connector->encoder->crtc = new_crtc;
839 } 840 }
840 DRM_DEBUG("setting connector %d crtc to %p\n", 841 DRM_DEBUG_KMS("setting connector %d crtc to %p\n",
841 connector->base.id, new_crtc); 842 connector->base.id, new_crtc);
842 } 843 }
843 844
@@ -850,7 +851,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
850 set->crtc->fb = set->fb; 851 set->crtc->fb = set->fb;
851 set->crtc->enabled = (set->mode != NULL); 852 set->crtc->enabled = (set->mode != NULL);
852 if (set->mode != NULL) { 853 if (set->mode != NULL) {
853 DRM_DEBUG("attempting to set mode from userspace\n"); 854 DRM_DEBUG_KMS("attempting to set mode from"
855 " userspace\n");
854 drm_mode_debug_printmodeline(set->mode); 856 drm_mode_debug_printmodeline(set->mode);
855 if (!drm_crtc_helper_set_mode(set->crtc, set->mode, 857 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
856 set->x, set->y, 858 set->x, set->y,
@@ -858,7 +860,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
858 DRM_ERROR("failed to set mode on crtc %p\n", 860 DRM_ERROR("failed to set mode on crtc %p\n",
859 set->crtc); 861 set->crtc);
860 ret = -EINVAL; 862 ret = -EINVAL;
861 goto fail_set_mode; 863 goto fail;
862 } 864 }
863 /* TODO are these needed? */ 865 /* TODO are these needed? */
864 set->crtc->desired_x = set->x; 866 set->crtc->desired_x = set->x;
@@ -867,43 +869,50 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
867 } 869 }
868 drm_helper_disable_unused_functions(dev); 870 drm_helper_disable_unused_functions(dev);
869 } else if (fb_changed) { 871 } else if (fb_changed) {
872 set->crtc->x = set->x;
873 set->crtc->y = set->y;
874
870 old_fb = set->crtc->fb; 875 old_fb = set->crtc->fb;
871 if (set->crtc->fb != set->fb) 876 if (set->crtc->fb != set->fb)
872 set->crtc->fb = set->fb; 877 set->crtc->fb = set->fb;
873 ret = crtc_funcs->mode_set_base(set->crtc, 878 ret = crtc_funcs->mode_set_base(set->crtc,
874 set->x, set->y, old_fb); 879 set->x, set->y, old_fb);
875 if (ret != 0) 880 if (ret != 0)
876 goto fail_set_mode; 881 goto fail;
877 } 882 }
878 883
884 kfree(save_connectors);
879 kfree(save_encoders); 885 kfree(save_encoders);
880 kfree(save_crtcs); 886 kfree(save_crtcs);
881 return 0; 887 return 0;
882 888
883fail_set_mode: 889fail:
884 set->crtc->enabled = save_enabled; 890 /* Restore all previous data. */
885 set->crtc->fb = old_fb;
886 count = 0; 891 count = 0;
887 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 892 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
888 if (!connector->encoder) 893 *crtc = save_crtcs[count++];
889 continue; 894 }
890 895
891 connector->encoder->crtc = save_crtcs[count++]; 896 count = 0;
897 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
898 *encoder = save_encoders[count++];
892 } 899 }
893fail_no_encoder: 900
894 kfree(save_crtcs);
895 count = 0; 901 count = 0;
896 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 902 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
897 connector->encoder = save_encoders[count++]; 903 *connector = save_connectors[count++];
898 } 904 }
905
906 kfree(save_connectors);
899 kfree(save_encoders); 907 kfree(save_encoders);
908 kfree(save_crtcs);
900 return ret; 909 return ret;
901} 910}
902EXPORT_SYMBOL(drm_crtc_helper_set_config); 911EXPORT_SYMBOL(drm_crtc_helper_set_config);
903 912
904bool drm_helper_plugged_event(struct drm_device *dev) 913bool drm_helper_plugged_event(struct drm_device *dev)
905{ 914{
906 DRM_DEBUG("\n"); 915 DRM_DEBUG_KMS("\n");
907 916
908 drm_helper_probe_connector_modes(dev, dev->mode_config.max_width, 917 drm_helper_probe_connector_modes(dev, dev->mode_config.max_width,
909 dev->mode_config.max_height); 918 dev->mode_config.max_height);
@@ -932,7 +941,6 @@ bool drm_helper_plugged_event(struct drm_device *dev)
932 */ 941 */
933bool drm_helper_initial_config(struct drm_device *dev) 942bool drm_helper_initial_config(struct drm_device *dev)
934{ 943{
935 struct drm_connector *connector;
936 int count = 0; 944 int count = 0;
937 945
938 count = drm_helper_probe_connector_modes(dev, 946 count = drm_helper_probe_connector_modes(dev,
@@ -940,16 +948,9 @@ bool drm_helper_initial_config(struct drm_device *dev)
940 dev->mode_config.max_height); 948 dev->mode_config.max_height);
941 949
942 /* 950 /*
943 * None of the available connectors had any modes, so add some 951 * we shouldn't end up with no modes here.
944 * and try to light them up anyway
945 */ 952 */
946 if (!count) { 953 WARN(!count, "Connected connector with 0 modes\n");
947 DRM_ERROR("connectors have no modes, using standard modes\n");
948 list_for_each_entry(connector,
949 &dev->mode_config.connector_list,
950 head)
951 drm_helper_add_std_modes(dev, connector);
952 }
953 954
954 drm_setup_crtcs(dev); 955 drm_setup_crtcs(dev);
955 956
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b39d7bfc0c9c..a75ca63deea6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -63,12 +63,12 @@ static struct drm_ioctl_desc drm_ioctls[] = {
63 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), 63 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
64 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), 64 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
65 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), 65 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
66 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), 66 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
67 67
68 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 68 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
69 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 69 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
70 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 70 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
71 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 71 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
72 72
73 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 73 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
74 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), 74 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7f2728bbc16c..90d76bacff17 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -60,6 +60,12 @@
60#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) 60#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
61/* use +hsync +vsync for detailed mode */ 61/* use +hsync +vsync for detailed mode */
62#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) 62#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6)
63/* define the number of Extension EDID block */
64#define MAX_EDID_EXT_NUM 4
65
66#define LEVEL_DMT 0
67#define LEVEL_GTF 1
68#define LEVEL_CVT 2
63 69
64static struct edid_quirk { 70static struct edid_quirk {
65 char *vendor; 71 char *vendor;
@@ -237,28 +243,291 @@ static void edid_fixup_preferred(struct drm_connector *connector,
237 preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; 243 preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
238} 244}
239 245
246/*
247 * Add the Autogenerated from the DMT spec.
248 * This table is copied from xfree86/modes/xf86EdidModes.c.
249 * But the mode with Reduced blank feature is deleted.
250 */
251static struct drm_display_mode drm_dmt_modes[] = {
252 /* 640x350@85Hz */
253 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
254 736, 832, 0, 350, 382, 385, 445, 0,
255 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
256 /* 640x400@85Hz */
257 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
258 736, 832, 0, 400, 401, 404, 445, 0,
259 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
260 /* 720x400@85Hz */
261 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
262 828, 936, 0, 400, 401, 404, 446, 0,
263 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
264 /* 640x480@60Hz */
265 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
266 752, 800, 0, 480, 489, 492, 525, 0,
267 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
268 /* 640x480@72Hz */
269 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
270 704, 832, 0, 480, 489, 492, 520, 0,
271 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
272 /* 640x480@75Hz */
273 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
274 720, 840, 0, 480, 481, 484, 500, 0,
275 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
276 /* 640x480@85Hz */
277 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
278 752, 832, 0, 480, 481, 484, 509, 0,
279 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
280 /* 800x600@56Hz */
281 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
282 896, 1024, 0, 600, 601, 603, 625, 0,
283 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
284 /* 800x600@60Hz */
285 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
286 968, 1056, 0, 600, 601, 605, 628, 0,
287 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
288 /* 800x600@72Hz */
289 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
290 976, 1040, 0, 600, 637, 643, 666, 0,
291 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
292 /* 800x600@75Hz */
293 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
294 896, 1056, 0, 600, 601, 604, 625, 0,
295 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
296 /* 800x600@85Hz */
297 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
298 896, 1048, 0, 600, 601, 604, 631, 0,
299 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
300 /* 848x480@60Hz */
301 { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
302 976, 1088, 0, 480, 486, 494, 517, 0,
303 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
304 /* 1024x768@43Hz, interlace */
305 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
306 1208, 1264, 0, 768, 768, 772, 817, 0,
307 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
308 DRM_MODE_FLAG_INTERLACE) },
309 /* 1024x768@60Hz */
310 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
311 1184, 1344, 0, 768, 771, 777, 806, 0,
312 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
313 /* 1024x768@70Hz */
314 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
315 1184, 1328, 0, 768, 771, 777, 806, 0,
316 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
317 /* 1024x768@75Hz */
318 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
319 1136, 1312, 0, 768, 769, 772, 800, 0,
320 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
321 /* 1024x768@85Hz */
322 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
323 1072, 1376, 0, 768, 769, 772, 808, 0,
324 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
325 /* 1152x864@75Hz */
326 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
327 1344, 1600, 0, 864, 865, 868, 900, 0,
328 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
329 /* 1280x768@60Hz */
330 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
331 1472, 1664, 0, 768, 771, 778, 798, 0,
332 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
333 /* 1280x768@75Hz */
334 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
335 1488, 1696, 0, 768, 771, 778, 805, 0,
336 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
337 /* 1280x768@85Hz */
338 { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
339 1496, 1712, 0, 768, 771, 778, 809, 0,
340 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
341 /* 1280x800@60Hz */
342 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
343 1480, 1680, 0, 800, 803, 809, 831, 0,
344 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
345 /* 1280x800@75Hz */
346 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
347 1488, 1696, 0, 800, 803, 809, 838, 0,
348 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
349 /* 1280x800@85Hz */
350 { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
351 1496, 1712, 0, 800, 803, 809, 843, 0,
352 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
353 /* 1280x960@60Hz */
354 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
355 1488, 1800, 0, 960, 961, 964, 1000, 0,
356 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
357 /* 1280x960@85Hz */
358 { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
359 1504, 1728, 0, 960, 961, 964, 1011, 0,
360 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
361 /* 1280x1024@60Hz */
362 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
363 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
364 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
365 /* 1280x1024@75Hz */
366 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
367 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
368 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
369 /* 1280x1024@85Hz */
370 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
371 1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
372 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
373 /* 1360x768@60Hz */
374 { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
375 1536, 1792, 0, 768, 771, 777, 795, 0,
376 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
377 /* 1440x1050@60Hz */
378 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
379 1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
380 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
381 /* 1440x1050@75Hz */
382 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
383 1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
384 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
385 /* 1440x1050@85Hz */
386 { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
387 1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
388 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
389 /* 1440x900@60Hz */
390 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
391 1672, 1904, 0, 900, 903, 909, 934, 0,
392 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
393 /* 1440x900@75Hz */
394 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
395 1688, 1936, 0, 900, 903, 909, 942, 0,
396 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
397 /* 1440x900@85Hz */
398 { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
399 1696, 1952, 0, 900, 903, 909, 948, 0,
400 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
401 /* 1600x1200@60Hz */
402 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
403 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
404 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
405 /* 1600x1200@65Hz */
406 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
407 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
408 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
409 /* 1600x1200@70Hz */
410 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
411 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
412 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
413 /* 1600x1200@75Hz */
414 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 2025000, 1600, 1664,
415 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
416 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
417 /* 1600x1200@85Hz */
418 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
419 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
420 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
421 /* 1680x1050@60Hz */
422 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
423 1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
424 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
425 /* 1680x1050@75Hz */
426 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
427 1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
428 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
429 /* 1680x1050@85Hz */
430 { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
431 1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
432 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
433 /* 1792x1344@60Hz */
434 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
435 2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
436 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
437 /* 1729x1344@75Hz */
438 { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
439 2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
440 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
441 /* 1853x1392@60Hz */
442 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
443 2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
444 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
445 /* 1856x1392@75Hz */
446 { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
447 2208, 2560, 0, 1392, 1395, 1399, 1500, 0,
448 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
449 /* 1920x1200@60Hz */
450 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
451 2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
452 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
453 /* 1920x1200@75Hz */
454 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
455 2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
456 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
457 /* 1920x1200@85Hz */
458 { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
459 2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
460 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
461 /* 1920x1440@60Hz */
462 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
463 2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
464 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
465 /* 1920x1440@75Hz */
466 { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
467 2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
468 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
469 /* 2560x1600@60Hz */
470 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
471 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
472 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
473 /* 2560x1600@75HZ */
474 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
475 3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
476 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
477 /* 2560x1600@85HZ */
478 { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
479 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
480 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
481};
482
483static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
484 int hsize, int vsize, int fresh)
485{
486 int i, count;
487 struct drm_display_mode *ptr, *mode;
488
489 count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
490 mode = NULL;
491 for (i = 0; i < count; i++) {
492 ptr = &drm_dmt_modes[i];
493 if (hsize == ptr->hdisplay &&
494 vsize == ptr->vdisplay &&
495 fresh == drm_mode_vrefresh(ptr)) {
496 /* get the expected default mode */
497 mode = drm_mode_duplicate(dev, ptr);
498 break;
499 }
500 }
501 return mode;
502}
240/** 503/**
241 * drm_mode_std - convert standard mode info (width, height, refresh) into mode 504 * drm_mode_std - convert standard mode info (width, height, refresh) into mode
242 * @t: standard timing params 505 * @t: standard timing params
506 * @timing_level: standard timing level
243 * 507 *
244 * Take the standard timing params (in this case width, aspect, and refresh) 508 * Take the standard timing params (in this case width, aspect, and refresh)
245 * and convert them into a real mode using CVT. 509 * and convert them into a real mode using CVT/GTF/DMT.
246 * 510 *
247 * Punts for now, but should eventually use the FB layer's CVT based mode 511 * Punts for now, but should eventually use the FB layer's CVT based mode
248 * generation code. 512 * generation code.
249 */ 513 */
250struct drm_display_mode *drm_mode_std(struct drm_device *dev, 514struct drm_display_mode *drm_mode_std(struct drm_device *dev,
251 struct std_timing *t) 515 struct std_timing *t,
516 int timing_level)
252{ 517{
253 struct drm_display_mode *mode; 518 struct drm_display_mode *mode;
254 int hsize = t->hsize * 8 + 248, vsize; 519 int hsize, vsize;
520 int vrefresh_rate;
255 unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) 521 unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
256 >> EDID_TIMING_ASPECT_SHIFT; 522 >> EDID_TIMING_ASPECT_SHIFT;
257 523 unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
258 mode = drm_mode_create(dev); 524 >> EDID_TIMING_VFREQ_SHIFT;
259 if (!mode) 525
260 return NULL; 526 /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
261 527 hsize = t->hsize * 8 + 248;
528 /* vrefresh_rate = vfreq + 60 */
529 vrefresh_rate = vfreq + 60;
530 /* the vdisplay is calculated based on the aspect ratio */
262 if (aspect_ratio == 0) 531 if (aspect_ratio == 0)
263 vsize = (hsize * 10) / 16; 532 vsize = (hsize * 10) / 16;
264 else if (aspect_ratio == 1) 533 else if (aspect_ratio == 1)
@@ -267,9 +536,30 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
267 vsize = (hsize * 4) / 5; 536 vsize = (hsize * 4) / 5;
268 else 537 else
269 vsize = (hsize * 9) / 16; 538 vsize = (hsize * 9) / 16;
270 539 /* HDTV hack */
271 drm_mode_set_name(mode); 540 if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) {
272 541 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
542 mode->hdisplay = 1366;
543 mode->vsync_start = mode->vsync_start - 1;
544 mode->vsync_end = mode->vsync_end - 1;
545 return mode;
546 }
547 mode = NULL;
548 /* check whether it can be found in default mode table */
549 mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate);
550 if (mode)
551 return mode;
552
553 switch (timing_level) {
554 case LEVEL_DMT:
555 break;
556 case LEVEL_GTF:
557 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
558 break;
559 case LEVEL_CVT:
560 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
561 break;
562 }
273 return mode; 563 return mode;
274} 564}
275 565
@@ -451,6 +741,19 @@ static int add_established_modes(struct drm_connector *connector, struct edid *e
451 741
452 return modes; 742 return modes;
453} 743}
744/**
745 * stanard_timing_level - get std. timing level(CVT/GTF/DMT)
746 * @edid: EDID block to scan
747 */
748static int standard_timing_level(struct edid *edid)
749{
750 if (edid->revision >= 2) {
751 if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
752 return LEVEL_CVT;
753 return LEVEL_GTF;
754 }
755 return LEVEL_DMT;
756}
454 757
455/** 758/**
456 * add_standard_modes - get std. modes from EDID and add them 759 * add_standard_modes - get std. modes from EDID and add them
@@ -463,6 +766,9 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
463{ 766{
464 struct drm_device *dev = connector->dev; 767 struct drm_device *dev = connector->dev;
465 int i, modes = 0; 768 int i, modes = 0;
769 int timing_level;
770
771 timing_level = standard_timing_level(edid);
466 772
467 for (i = 0; i < EDID_STD_TIMINGS; i++) { 773 for (i = 0; i < EDID_STD_TIMINGS; i++) {
468 struct std_timing *t = &edid->standard_timings[i]; 774 struct std_timing *t = &edid->standard_timings[i];
@@ -472,7 +778,8 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
472 if (t->hsize == 1 && t->vfreq_aspect == 1) 778 if (t->hsize == 1 && t->vfreq_aspect == 1)
473 continue; 779 continue;
474 780
475 newmode = drm_mode_std(dev, &edid->standard_timings[i]); 781 newmode = drm_mode_std(dev, &edid->standard_timings[i],
782 timing_level);
476 if (newmode) { 783 if (newmode) {
477 drm_mode_probed_add(connector, newmode); 784 drm_mode_probed_add(connector, newmode);
478 modes++; 785 modes++;
@@ -496,6 +803,9 @@ static int add_detailed_info(struct drm_connector *connector,
496{ 803{
497 struct drm_device *dev = connector->dev; 804 struct drm_device *dev = connector->dev;
498 int i, j, modes = 0; 805 int i, j, modes = 0;
806 int timing_level;
807
808 timing_level = standard_timing_level(edid);
499 809
500 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { 810 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
501 struct detailed_timing *timing = &edid->detailed_timings[i]; 811 struct detailed_timing *timing = &edid->detailed_timings[i];
@@ -525,7 +835,8 @@ static int add_detailed_info(struct drm_connector *connector,
525 struct drm_display_mode *newmode; 835 struct drm_display_mode *newmode;
526 836
527 std = &data->data.timings[j]; 837 std = &data->data.timings[j];
528 newmode = drm_mode_std(dev, std); 838 newmode = drm_mode_std(dev, std,
839 timing_level);
529 if (newmode) { 840 if (newmode) {
530 drm_mode_probed_add(connector, newmode); 841 drm_mode_probed_add(connector, newmode);
531 modes++; 842 modes++;
@@ -551,6 +862,122 @@ static int add_detailed_info(struct drm_connector *connector,
551 862
552 return modes; 863 return modes;
553} 864}
865/**
866 * add_detailed_mode_eedid - get detailed mode info from addtional timing
867 * EDID block
868 * @connector: attached connector
869 * @edid: EDID block to scan(It is only to get addtional timing EDID block)
870 * @quirks: quirks to apply
871 *
872 * Some of the detailed timing sections may contain mode information. Grab
873 * it and add it to the list.
874 */
875static int add_detailed_info_eedid(struct drm_connector *connector,
876 struct edid *edid, u32 quirks)
877{
878 struct drm_device *dev = connector->dev;
879 int i, j, modes = 0;
880 char *edid_ext = NULL;
881 struct detailed_timing *timing;
882 struct detailed_non_pixel *data;
883 struct drm_display_mode *newmode;
884 int edid_ext_num;
885 int start_offset, end_offset;
886 int timing_level;
887
888 if (edid->version == 1 && edid->revision < 3) {
889 /* If the EDID version is less than 1.3, there is no
890 * extension EDID.
891 */
892 return 0;
893 }
894 if (!edid->extensions) {
895 /* if there is no extension EDID, it is unnecessary to
896 * parse the E-EDID to get detailed info
897 */
898 return 0;
899 }
900
901 /* Chose real EDID extension number */
902 edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
903 MAX_EDID_EXT_NUM : edid->extensions;
904
905 /* Find CEA extension */
906 for (i = 0; i < edid_ext_num; i++) {
907 edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
908 /* This block is CEA extension */
909 if (edid_ext[0] == 0x02)
910 break;
911 }
912
913 if (i == edid_ext_num) {
914 /* if there is no additional timing EDID block, return */
915 return 0;
916 }
917
918 /* Get the start offset of detailed timing block */
919 start_offset = edid_ext[2];
920 if (start_offset == 0) {
921 /* If the start_offset is zero, it means that neither detailed
922 * info nor data block exist. In such case it is also
923 * unnecessary to parse the detailed timing info.
924 */
925 return 0;
926 }
927
928 timing_level = standard_timing_level(edid);
929 end_offset = EDID_LENGTH;
930 end_offset -= sizeof(struct detailed_timing);
931 for (i = start_offset; i < end_offset;
932 i += sizeof(struct detailed_timing)) {
933 timing = (struct detailed_timing *)(edid_ext + i);
934 data = &timing->data.other_data;
935 /* Detailed mode timing */
936 if (timing->pixel_clock) {
937 newmode = drm_mode_detailed(dev, edid, timing, quirks);
938 if (!newmode)
939 continue;
940
941 drm_mode_probed_add(connector, newmode);
942
943 modes++;
944 continue;
945 }
946
947 /* Other timing or info */
948 switch (data->type) {
949 case EDID_DETAIL_MONITOR_SERIAL:
950 break;
951 case EDID_DETAIL_MONITOR_STRING:
952 break;
953 case EDID_DETAIL_MONITOR_RANGE:
954 /* Get monitor range data */
955 break;
956 case EDID_DETAIL_MONITOR_NAME:
957 break;
958 case EDID_DETAIL_MONITOR_CPDATA:
959 break;
960 case EDID_DETAIL_STD_MODES:
961 /* Five modes per detailed section */
962 for (j = 0; j < 5; i++) {
963 struct std_timing *std;
964 struct drm_display_mode *newmode;
965
966 std = &data->data.timings[j];
967 newmode = drm_mode_std(dev, std, timing_level);
968 if (newmode) {
969 drm_mode_probed_add(connector, newmode);
970 modes++;
971 }
972 }
973 break;
974 default:
975 break;
976 }
977 }
978
979 return modes;
980}
554 981
555#define DDC_ADDR 0x50 982#define DDC_ADDR 0x50
556/** 983/**
@@ -584,7 +1011,6 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
584 if (i2c_transfer(adapter, msgs, 2) == 2) 1011 if (i2c_transfer(adapter, msgs, 2) == 2)
585 return 0; 1012 return 0;
586 1013
587 dev_info(&adapter->dev, "unable to read EDID block.\n");
588 return -1; 1014 return -1;
589} 1015}
590EXPORT_SYMBOL(drm_do_probe_ddc_edid); 1016EXPORT_SYMBOL(drm_do_probe_ddc_edid);
@@ -597,8 +1023,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector,
597 1023
598 ret = drm_do_probe_ddc_edid(adapter, buf, len); 1024 ret = drm_do_probe_ddc_edid(adapter, buf, len);
599 if (ret != 0) { 1025 if (ret != 0) {
600 dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
601 drm_get_connector_name(connector));
602 goto end; 1026 goto end;
603 } 1027 }
604 if (!edid_is_valid((struct edid *)buf)) { 1028 if (!edid_is_valid((struct edid *)buf)) {
@@ -610,7 +1034,6 @@ end:
610 return ret; 1034 return ret;
611} 1035}
612 1036
613#define MAX_EDID_EXT_NUM 4
614/** 1037/**
615 * drm_get_edid - get EDID data, if available 1038 * drm_get_edid - get EDID data, if available
616 * @connector: connector we're probing 1039 * @connector: connector we're probing
@@ -763,6 +1186,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
763 num_modes += add_established_modes(connector, edid); 1186 num_modes += add_established_modes(connector, edid);
764 num_modes += add_standard_modes(connector, edid); 1187 num_modes += add_standard_modes(connector, edid);
765 num_modes += add_detailed_info(connector, edid, quirks); 1188 num_modes += add_detailed_info(connector, edid, quirks);
1189 num_modes += add_detailed_info_eedid(connector, edid, quirks);
766 1190
767 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) 1191 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
768 edid_fixup_preferred(connector, quirks); 1192 edid_fixup_preferred(connector, quirks);
@@ -788,3 +1212,49 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
788 return num_modes; 1212 return num_modes;
789} 1213}
790EXPORT_SYMBOL(drm_add_edid_modes); 1214EXPORT_SYMBOL(drm_add_edid_modes);
1215
1216/**
1217 * drm_add_modes_noedid - add modes for the connectors without EDID
1218 * @connector: connector we're probing
1219 * @hdisplay: the horizontal display limit
1220 * @vdisplay: the vertical display limit
1221 *
1222 * Add the specified modes to the connector's mode list. Only when the
1223 * hdisplay/vdisplay is not beyond the given limit, it will be added.
1224 *
1225 * Return number of modes added or 0 if we couldn't find any.
1226 */
1227int drm_add_modes_noedid(struct drm_connector *connector,
1228 int hdisplay, int vdisplay)
1229{
1230 int i, count, num_modes = 0;
1231 struct drm_display_mode *mode, *ptr;
1232 struct drm_device *dev = connector->dev;
1233
1234 count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
1235 if (hdisplay < 0)
1236 hdisplay = 0;
1237 if (vdisplay < 0)
1238 vdisplay = 0;
1239
1240 for (i = 0; i < count; i++) {
1241 ptr = &drm_dmt_modes[i];
1242 if (hdisplay && vdisplay) {
1243 /*
1244 * Only when two are valid, they will be used to check
1245 * whether the mode should be added to the mode list of
1246 * the connector.
1247 */
1248 if (ptr->hdisplay > hdisplay ||
1249 ptr->vdisplay > vdisplay)
1250 continue;
1251 }
1252 mode = drm_mode_duplicate(dev, ptr);
1253 if (mode) {
1254 drm_mode_probed_add(connector, mode);
1255 num_modes++;
1256 }
1257 }
1258 return num_modes;
1259}
1260EXPORT_SYMBOL(drm_add_modes_noedid);
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
new file mode 100644
index 000000000000..f0184696edf3
--- /dev/null
+++ b/drivers/gpu/drm/drm_encoder_slave.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright (C) 2009 Francisco Jerez.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#include "drm_encoder_slave.h"
28
29/**
30 * drm_i2c_encoder_init - Initialize an I2C slave encoder
31 * @dev: DRM device.
32 * @encoder: Encoder to be attached to the I2C device. You aren't
33 * required to have called drm_encoder_init() before.
34 * @adap: I2C adapter that will be used to communicate with
35 * the device.
36 * @info: Information that will be used to create the I2C device.
37 * Required fields are @addr and @type.
38 *
39 * Create an I2C device on the specified bus (the module containing its
40 * driver is transparently loaded) and attach it to the specified
41 * &drm_encoder_slave. The @slave_funcs field will be initialized with
42 * the hooks provided by the slave driver.
43 *
44 * Returns 0 on success or a negative errno on failure, in particular,
45 * -ENODEV is returned when no matching driver is found.
46 */
47int drm_i2c_encoder_init(struct drm_device *dev,
48 struct drm_encoder_slave *encoder,
49 struct i2c_adapter *adap,
50 const struct i2c_board_info *info)
51{
52 char modalias[sizeof(I2C_MODULE_PREFIX)
53 + I2C_NAME_SIZE];
54 struct module *module = NULL;
55 struct i2c_client *client;
56 struct drm_i2c_encoder_driver *encoder_drv;
57 int err = 0;
58
59 snprintf(modalias, sizeof(modalias),
60 "%s%s", I2C_MODULE_PREFIX, info->type);
61 request_module(modalias);
62
63 client = i2c_new_device(adap, info);
64 if (!client) {
65 err = -ENOMEM;
66 goto fail;
67 }
68
69 if (!client->driver) {
70 err = -ENODEV;
71 goto fail_unregister;
72 }
73
74 module = client->driver->driver.owner;
75 if (!try_module_get(module)) {
76 err = -ENODEV;
77 goto fail_unregister;
78 }
79
80 encoder->bus_priv = client;
81
82 encoder_drv = to_drm_i2c_encoder_driver(client->driver);
83
84 err = encoder_drv->encoder_init(client, dev, encoder);
85 if (err)
86 goto fail_unregister;
87
88 return 0;
89
90fail_unregister:
91 i2c_unregister_device(client);
92 module_put(module);
93fail:
94 return err;
95}
96EXPORT_SYMBOL(drm_i2c_encoder_init);
97
98/**
99 * drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
100 * @drm_encoder: Encoder to be unregistered.
101 *
102 * This should be called from the @destroy method of an I2C slave
103 * encoder driver once I2C access is no longer needed.
104 */
105void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
106{
107 struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
108 struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
109 struct module *module = client->driver->driver.owner;
110
111 i2c_unregister_device(client);
112 encoder->bus_priv = NULL;
113
114 module_put(module);
115}
116EXPORT_SYMBOL(drm_i2c_encoder_destroy);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
new file mode 100644
index 000000000000..2c4671314884
--- /dev/null
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -0,0 +1,707 @@
1/*
2 * Copyright (c) 2006-2009 Red Hat Inc.
3 * Copyright (c) 2006-2008 Intel Corporation
4 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
5 *
6 * DRM framebuffer helper functions
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that copyright
11 * notice and this permission notice appear in supporting documentation, and
12 * that the name of the copyright holders not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. The copyright holders make no representations
15 * about the suitability of this software for any purpose. It is provided "as
16 * is" without express or implied warranty.
17 *
18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 *
26 * Authors:
27 * Dave Airlie <airlied@linux.ie>
28 * Jesse Barnes <jesse.barnes@intel.com>
29 */
30#include <linux/sysrq.h>
31#include <linux/fb.h>
32#include "drmP.h"
33#include "drm_crtc.h"
34#include "drm_fb_helper.h"
35#include "drm_crtc_helper.h"
36
37MODULE_AUTHOR("David Airlie, Jesse Barnes");
38MODULE_DESCRIPTION("DRM KMS helper");
39MODULE_LICENSE("GPL and additional rights");
40
41static LIST_HEAD(kernel_fb_helper_list);
42
43bool drm_fb_helper_force_kernel_mode(void)
44{
45 int i = 0;
46 bool ret, error = false;
47 struct drm_fb_helper *helper;
48
49 if (list_empty(&kernel_fb_helper_list))
50 return false;
51
52 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
53 for (i = 0; i < helper->crtc_count; i++) {
54 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
55 ret = drm_crtc_helper_set_config(mode_set);
56 if (ret)
57 error = true;
58 }
59 }
60 return error;
61}
62
63int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
64 void *panic_str)
65{
66 DRM_ERROR("panic occurred, switching back to text console\n");
67 return drm_fb_helper_force_kernel_mode();
68 return 0;
69}
70EXPORT_SYMBOL(drm_fb_helper_panic);
71
72static struct notifier_block paniced = {
73 .notifier_call = drm_fb_helper_panic,
74};
75
76/**
77 * drm_fb_helper_restore - restore the framebuffer console (kernel) config
78 *
79 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
80 */
81void drm_fb_helper_restore(void)
82{
83 bool ret;
84 ret = drm_fb_helper_force_kernel_mode();
85 if (ret == true)
86 DRM_ERROR("Failed to restore crtc configuration\n");
87}
88EXPORT_SYMBOL(drm_fb_helper_restore);
89
90static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
91{
92 drm_fb_helper_restore();
93}
94static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
95
96static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3)
97{
98 schedule_work(&drm_fb_helper_restore_work);
99}
100
101static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
102 .handler = drm_fb_helper_sysrq,
103 .help_msg = "force-fb(V)",
104 .action_msg = "Restore framebuffer console",
105};
106
107static void drm_fb_helper_on(struct fb_info *info)
108{
109 struct drm_fb_helper *fb_helper = info->par;
110 struct drm_device *dev = fb_helper->dev;
111 struct drm_crtc *crtc;
112 struct drm_encoder *encoder;
113 int i;
114
115 /*
116 * For each CRTC in this fb, turn the crtc on then,
117 * find all associated encoders and turn them on.
118 */
119 for (i = 0; i < fb_helper->crtc_count; i++) {
120 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
121 struct drm_crtc_helper_funcs *crtc_funcs =
122 crtc->helper_private;
123
124 /* Only mess with CRTCs in this fb */
125 if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
126 !crtc->enabled)
127 continue;
128
129 mutex_lock(&dev->mode_config.mutex);
130 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
131 mutex_unlock(&dev->mode_config.mutex);
132
133 /* Found a CRTC on this fb, now find encoders */
134 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
135 if (encoder->crtc == crtc) {
136 struct drm_encoder_helper_funcs *encoder_funcs;
137
138 encoder_funcs = encoder->helper_private;
139 mutex_lock(&dev->mode_config.mutex);
140 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
141 mutex_unlock(&dev->mode_config.mutex);
142 }
143 }
144 }
145 }
146}
147
148static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
149{
150 struct drm_fb_helper *fb_helper = info->par;
151 struct drm_device *dev = fb_helper->dev;
152 struct drm_crtc *crtc;
153 struct drm_encoder *encoder;
154 int i;
155
156 /*
157 * For each CRTC in this fb, find all associated encoders
158 * and turn them off, then turn off the CRTC.
159 */
160 for (i = 0; i < fb_helper->crtc_count; i++) {
161 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
162 struct drm_crtc_helper_funcs *crtc_funcs =
163 crtc->helper_private;
164
165 /* Only mess with CRTCs in this fb */
166 if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
167 !crtc->enabled)
168 continue;
169
170 /* Found a CRTC on this fb, now find encoders */
171 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
172 if (encoder->crtc == crtc) {
173 struct drm_encoder_helper_funcs *encoder_funcs;
174
175 encoder_funcs = encoder->helper_private;
176 mutex_lock(&dev->mode_config.mutex);
177 encoder_funcs->dpms(encoder, dpms_mode);
178 mutex_unlock(&dev->mode_config.mutex);
179 }
180 }
181 if (dpms_mode == DRM_MODE_DPMS_OFF) {
182 mutex_lock(&dev->mode_config.mutex);
183 crtc_funcs->dpms(crtc, dpms_mode);
184 mutex_unlock(&dev->mode_config.mutex);
185 }
186 }
187 }
188}
189
190int drm_fb_helper_blank(int blank, struct fb_info *info)
191{
192 switch (blank) {
193 case FB_BLANK_UNBLANK:
194 drm_fb_helper_on(info);
195 break;
196 case FB_BLANK_NORMAL:
197 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
198 break;
199 case FB_BLANK_HSYNC_SUSPEND:
200 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
201 break;
202 case FB_BLANK_VSYNC_SUSPEND:
203 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
204 break;
205 case FB_BLANK_POWERDOWN:
206 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
207 break;
208 }
209 return 0;
210}
211EXPORT_SYMBOL(drm_fb_helper_blank);
212
213static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
214{
215 int i;
216
217 for (i = 0; i < helper->crtc_count; i++)
218 kfree(helper->crtc_info[i].mode_set.connectors);
219 kfree(helper->crtc_info);
220}
221
222int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn_count)
223{
224 struct drm_device *dev = helper->dev;
225 struct drm_crtc *crtc;
226 int ret = 0;
227 int i;
228
229 helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
230 if (!helper->crtc_info)
231 return -ENOMEM;
232
233 helper->crtc_count = crtc_count;
234
235 for (i = 0; i < crtc_count; i++) {
236 helper->crtc_info[i].mode_set.connectors =
237 kcalloc(max_conn_count,
238 sizeof(struct drm_connector *),
239 GFP_KERNEL);
240
241 if (!helper->crtc_info[i].mode_set.connectors) {
242 ret = -ENOMEM;
243 goto out_free;
244 }
245 helper->crtc_info[i].mode_set.num_connectors = 0;
246 }
247
248 i = 0;
249 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
250 helper->crtc_info[i].crtc_id = crtc->base.id;
251 helper->crtc_info[i].mode_set.crtc = crtc;
252 i++;
253 }
254 helper->conn_limit = max_conn_count;
255 return 0;
256out_free:
257 drm_fb_helper_crtc_free(helper);
258 return -ENOMEM;
259}
260EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
261
262int drm_fb_helper_setcolreg(unsigned regno,
263 unsigned red,
264 unsigned green,
265 unsigned blue,
266 unsigned transp,
267 struct fb_info *info)
268{
269 struct drm_fb_helper *fb_helper = info->par;
270 struct drm_device *dev = fb_helper->dev;
271 struct drm_crtc *crtc;
272 int i;
273
274 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
275 struct drm_framebuffer *fb = fb_helper->fb;
276
277 for (i = 0; i < fb_helper->crtc_count; i++) {
278 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
279 break;
280 }
281 if (i == fb_helper->crtc_count)
282 continue;
283
284 if (regno > 255)
285 return 1;
286
287 if (fb->depth == 8) {
288 fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
289 return 0;
290 }
291
292 if (regno < 16) {
293 switch (fb->depth) {
294 case 15:
295 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
296 ((green & 0xf800) >> 6) |
297 ((blue & 0xf800) >> 11);
298 break;
299 case 16:
300 fb->pseudo_palette[regno] = (red & 0xf800) |
301 ((green & 0xfc00) >> 5) |
302 ((blue & 0xf800) >> 11);
303 break;
304 case 24:
305 case 32:
306 fb->pseudo_palette[regno] =
307 (((red >> 8) & 0xff) << info->var.red.offset) |
308 (((green >> 8) & 0xff) << info->var.green.offset) |
309 (((blue >> 8) & 0xff) << info->var.blue.offset);
310 break;
311 }
312 }
313 }
314 return 0;
315}
316EXPORT_SYMBOL(drm_fb_helper_setcolreg);
317
318int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
319 struct fb_info *info)
320{
321 struct drm_fb_helper *fb_helper = info->par;
322 struct drm_framebuffer *fb = fb_helper->fb;
323 int depth;
324
325 if (var->pixclock == -1 || !var->pixclock)
326 return -EINVAL;
327
328 /* Need to resize the fb object !!! */
329 if (var->xres > fb->width || var->yres > fb->height) {
330 DRM_ERROR("Requested width/height is greater than current fb "
331 "object %dx%d > %dx%d\n", var->xres, var->yres,
332 fb->width, fb->height);
333 DRM_ERROR("Need resizing code.\n");
334 return -EINVAL;
335 }
336
337 switch (var->bits_per_pixel) {
338 case 16:
339 depth = (var->green.length == 6) ? 16 : 15;
340 break;
341 case 32:
342 depth = (var->transp.length > 0) ? 32 : 24;
343 break;
344 default:
345 depth = var->bits_per_pixel;
346 break;
347 }
348
349 switch (depth) {
350 case 8:
351 var->red.offset = 0;
352 var->green.offset = 0;
353 var->blue.offset = 0;
354 var->red.length = 8;
355 var->green.length = 8;
356 var->blue.length = 8;
357 var->transp.length = 0;
358 var->transp.offset = 0;
359 break;
360 case 15:
361 var->red.offset = 10;
362 var->green.offset = 5;
363 var->blue.offset = 0;
364 var->red.length = 5;
365 var->green.length = 5;
366 var->blue.length = 5;
367 var->transp.length = 1;
368 var->transp.offset = 15;
369 break;
370 case 16:
371 var->red.offset = 11;
372 var->green.offset = 5;
373 var->blue.offset = 0;
374 var->red.length = 5;
375 var->green.length = 6;
376 var->blue.length = 5;
377 var->transp.length = 0;
378 var->transp.offset = 0;
379 break;
380 case 24:
381 var->red.offset = 16;
382 var->green.offset = 8;
383 var->blue.offset = 0;
384 var->red.length = 8;
385 var->green.length = 8;
386 var->blue.length = 8;
387 var->transp.length = 0;
388 var->transp.offset = 0;
389 break;
390 case 32:
391 var->red.offset = 16;
392 var->green.offset = 8;
393 var->blue.offset = 0;
394 var->red.length = 8;
395 var->green.length = 8;
396 var->blue.length = 8;
397 var->transp.length = 8;
398 var->transp.offset = 24;
399 break;
400 default:
401 return -EINVAL;
402 }
403 return 0;
404}
405EXPORT_SYMBOL(drm_fb_helper_check_var);
406
407/* this will let fbcon do the mode init */
408int drm_fb_helper_set_par(struct fb_info *info)
409{
410 struct drm_fb_helper *fb_helper = info->par;
411 struct drm_device *dev = fb_helper->dev;
412 struct fb_var_screeninfo *var = &info->var;
413 struct drm_crtc *crtc;
414 int ret;
415 int i;
416
417 if (var->pixclock != -1) {
418 DRM_ERROR("PIXEL CLCOK SET\n");
419 return -EINVAL;
420 }
421
422 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
423
424 for (i = 0; i < fb_helper->crtc_count; i++) {
425 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
426 break;
427 }
428 if (i == fb_helper->crtc_count)
429 continue;
430
431 if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
432 mutex_lock(&dev->mode_config.mutex);
433 ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
434 mutex_unlock(&dev->mode_config.mutex);
435 if (ret)
436 return ret;
437 }
438 }
439 return 0;
440}
441EXPORT_SYMBOL(drm_fb_helper_set_par);
442
443int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
444 struct fb_info *info)
445{
446 struct drm_fb_helper *fb_helper = info->par;
447 struct drm_device *dev = fb_helper->dev;
448 struct drm_mode_set *modeset;
449 struct drm_crtc *crtc;
450 int ret = 0;
451 int i;
452
453 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
454 for (i = 0; i < fb_helper->crtc_count; i++) {
455 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
456 break;
457 }
458
459 if (i == fb_helper->crtc_count)
460 continue;
461
462 modeset = &fb_helper->crtc_info[i].mode_set;
463
464 modeset->x = var->xoffset;
465 modeset->y = var->yoffset;
466
467 if (modeset->num_connectors) {
468 mutex_lock(&dev->mode_config.mutex);
469 ret = crtc->funcs->set_config(modeset);
470 mutex_unlock(&dev->mode_config.mutex);
471 if (!ret) {
472 info->var.xoffset = var->xoffset;
473 info->var.yoffset = var->yoffset;
474 }
475 }
476 }
477 return ret;
478}
479EXPORT_SYMBOL(drm_fb_helper_pan_display);
480
481int drm_fb_helper_single_fb_probe(struct drm_device *dev,
482 int (*fb_create)(struct drm_device *dev,
483 uint32_t fb_width,
484 uint32_t fb_height,
485 uint32_t surface_width,
486 uint32_t surface_height,
487 struct drm_framebuffer **fb_ptr))
488{
489 struct drm_crtc *crtc;
490 struct drm_connector *connector;
491 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
492 unsigned int surface_width = 0, surface_height = 0;
493 int new_fb = 0;
494 int crtc_count = 0;
495 int ret, i, conn_count = 0;
496 struct fb_info *info;
497 struct drm_framebuffer *fb;
498 struct drm_mode_set *modeset = NULL;
499 struct drm_fb_helper *fb_helper;
500
501 /* first up get a count of crtcs now in use and new min/maxes width/heights */
502 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
503 if (drm_helper_crtc_in_use(crtc)) {
504 if (crtc->desired_mode) {
505 if (crtc->desired_mode->hdisplay < fb_width)
506 fb_width = crtc->desired_mode->hdisplay;
507
508 if (crtc->desired_mode->vdisplay < fb_height)
509 fb_height = crtc->desired_mode->vdisplay;
510
511 if (crtc->desired_mode->hdisplay > surface_width)
512 surface_width = crtc->desired_mode->hdisplay;
513
514 if (crtc->desired_mode->vdisplay > surface_height)
515 surface_height = crtc->desired_mode->vdisplay;
516 }
517 crtc_count++;
518 }
519 }
520
521 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
522 /* hmm everyone went away - assume VGA cable just fell out
523 and will come back later. */
524 return 0;
525 }
526
527 /* do we have an fb already? */
528 if (list_empty(&dev->mode_config.fb_kernel_list)) {
529 ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
530 surface_height, &fb);
531 if (ret)
532 return -EINVAL;
533 new_fb = 1;
534 } else {
535 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
536 struct drm_framebuffer, filp_head);
537
538 /* if someone hotplugs something bigger than we have already allocated, we are pwned.
539 As really we can't resize an fbdev that is in the wild currently due to fbdev
540 not really being designed for the lower layers moving stuff around under it.
541 - so in the grand style of things - punt. */
542 if ((fb->width < surface_width) ||
543 (fb->height < surface_height)) {
544 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
545 return -EINVAL;
546 }
547 }
548
549 info = fb->fbdev;
550 fb_helper = info->par;
551
552 crtc_count = 0;
553 /* okay we need to setup new connector sets in the crtcs */
554 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
555 modeset = &fb_helper->crtc_info[crtc_count].mode_set;
556 modeset->fb = fb;
557 conn_count = 0;
558 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
559 if (connector->encoder)
560 if (connector->encoder->crtc == modeset->crtc) {
561 modeset->connectors[conn_count] = connector;
562 conn_count++;
563 if (conn_count > fb_helper->conn_limit)
564 BUG();
565 }
566 }
567
568 for (i = conn_count; i < fb_helper->conn_limit; i++)
569 modeset->connectors[i] = NULL;
570
571 modeset->crtc = crtc;
572 crtc_count++;
573
574 modeset->num_connectors = conn_count;
575 if (modeset->crtc->desired_mode) {
576 if (modeset->mode)
577 drm_mode_destroy(dev, modeset->mode);
578 modeset->mode = drm_mode_duplicate(dev,
579 modeset->crtc->desired_mode);
580 }
581 }
582 fb_helper->crtc_count = crtc_count;
583 fb_helper->fb = fb;
584
585 if (new_fb) {
586 info->var.pixclock = -1;
587 if (register_framebuffer(info) < 0)
588 return -EINVAL;
589 } else {
590 drm_fb_helper_set_par(info);
591 }
592 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
593 info->fix.id);
594
595 /* Switch back to kernel console on panic */
596 /* multi card linked list maybe */
597 if (list_empty(&kernel_fb_helper_list)) {
598 printk(KERN_INFO "registered panic notifier\n");
599 atomic_notifier_chain_register(&panic_notifier_list,
600 &paniced);
601 register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
602 }
603 list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
604 return 0;
605}
606EXPORT_SYMBOL(drm_fb_helper_single_fb_probe);
607
608void drm_fb_helper_free(struct drm_fb_helper *helper)
609{
610 list_del(&helper->kernel_fb_list);
611 if (list_empty(&kernel_fb_helper_list)) {
612 printk(KERN_INFO "unregistered panic notifier\n");
613 atomic_notifier_chain_unregister(&panic_notifier_list,
614 &paniced);
615 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
616 }
617 drm_fb_helper_crtc_free(helper);
618}
619EXPORT_SYMBOL(drm_fb_helper_free);
620
621void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
622{
623 info->fix.type = FB_TYPE_PACKED_PIXELS;
624 info->fix.visual = FB_VISUAL_TRUECOLOR;
625 info->fix.type_aux = 0;
626 info->fix.xpanstep = 1; /* doing it in hw */
627 info->fix.ypanstep = 1; /* doing it in hw */
628 info->fix.ywrapstep = 0;
629 info->fix.accel = FB_ACCEL_NONE;
630 info->fix.type_aux = 0;
631
632 info->fix.line_length = pitch;
633 return;
634}
635EXPORT_SYMBOL(drm_fb_helper_fill_fix);
636
637void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
638 uint32_t fb_width, uint32_t fb_height)
639{
640 info->pseudo_palette = fb->pseudo_palette;
641 info->var.xres_virtual = fb->width;
642 info->var.yres_virtual = fb->height;
643 info->var.bits_per_pixel = fb->bits_per_pixel;
644 info->var.xoffset = 0;
645 info->var.yoffset = 0;
646 info->var.activate = FB_ACTIVATE_NOW;
647 info->var.height = -1;
648 info->var.width = -1;
649
650 switch (fb->depth) {
651 case 8:
652 info->var.red.offset = 0;
653 info->var.green.offset = 0;
654 info->var.blue.offset = 0;
655 info->var.red.length = 8; /* 8bit DAC */
656 info->var.green.length = 8;
657 info->var.blue.length = 8;
658 info->var.transp.offset = 0;
659 info->var.transp.length = 0;
660 break;
661 case 15:
662 info->var.red.offset = 10;
663 info->var.green.offset = 5;
664 info->var.blue.offset = 0;
665 info->var.red.length = 5;
666 info->var.green.length = 5;
667 info->var.blue.length = 5;
668 info->var.transp.offset = 15;
669 info->var.transp.length = 1;
670 break;
671 case 16:
672 info->var.red.offset = 11;
673 info->var.green.offset = 5;
674 info->var.blue.offset = 0;
675 info->var.red.length = 5;
676 info->var.green.length = 6;
677 info->var.blue.length = 5;
678 info->var.transp.offset = 0;
679 break;
680 case 24:
681 info->var.red.offset = 16;
682 info->var.green.offset = 8;
683 info->var.blue.offset = 0;
684 info->var.red.length = 8;
685 info->var.green.length = 8;
686 info->var.blue.length = 8;
687 info->var.transp.offset = 0;
688 info->var.transp.length = 0;
689 break;
690 case 32:
691 info->var.red.offset = 16;
692 info->var.green.offset = 8;
693 info->var.blue.offset = 0;
694 info->var.red.length = 8;
695 info->var.green.length = 8;
696 info->var.blue.length = 8;
697 info->var.transp.offset = 24;
698 info->var.transp.length = 8;
699 break;
700 default:
701 break;
702 }
703
704 info->var.xres = fb_width;
705 info->var.yres = fb_height;
706}
707EXPORT_SYMBOL(drm_fb_helper_fill_var);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index ffe8f4394d50..230c9ffdd5e9 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -164,7 +164,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc);
164 * Removes the mapping from handle to filp for this object. 164 * Removes the mapping from handle to filp for this object.
165 */ 165 */
166static int 166static int
167drm_gem_handle_delete(struct drm_file *filp, int handle) 167drm_gem_handle_delete(struct drm_file *filp, u32 handle)
168{ 168{
169 struct drm_device *dev; 169 struct drm_device *dev;
170 struct drm_gem_object *obj; 170 struct drm_gem_object *obj;
@@ -207,7 +207,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle)
207int 207int
208drm_gem_handle_create(struct drm_file *file_priv, 208drm_gem_handle_create(struct drm_file *file_priv,
209 struct drm_gem_object *obj, 209 struct drm_gem_object *obj,
210 int *handlep) 210 u32 *handlep)
211{ 211{
212 int ret; 212 int ret;
213 213
@@ -221,7 +221,7 @@ again:
221 221
222 /* do the allocation under our spinlock */ 222 /* do the allocation under our spinlock */
223 spin_lock(&file_priv->table_lock); 223 spin_lock(&file_priv->table_lock);
224 ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep); 224 ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
225 spin_unlock(&file_priv->table_lock); 225 spin_unlock(&file_priv->table_lock);
226 if (ret == -EAGAIN) 226 if (ret == -EAGAIN)
227 goto again; 227 goto again;
@@ -237,7 +237,7 @@ EXPORT_SYMBOL(drm_gem_handle_create);
237/** Returns a reference to the object named by the handle. */ 237/** Returns a reference to the object named by the handle. */
238struct drm_gem_object * 238struct drm_gem_object *
239drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, 239drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
240 int handle) 240 u32 handle)
241{ 241{
242 struct drm_gem_object *obj; 242 struct drm_gem_object *obj;
243 243
@@ -344,7 +344,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
344 struct drm_gem_open *args = data; 344 struct drm_gem_open *args = data;
345 struct drm_gem_object *obj; 345 struct drm_gem_object *obj;
346 int ret; 346 int ret;
347 int handle; 347 u32 handle;
348 348
349 if (!(dev->driver->driver_features & DRIVER_GEM)) 349 if (!(dev->driver->driver_features & DRIVER_GEM))
350 return -ENODEV; 350 return -ENODEV;
@@ -539,7 +539,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
539 vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; 539 vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
540 vma->vm_ops = obj->dev->driver->gem_vm_ops; 540 vma->vm_ops = obj->dev->driver->gem_vm_ops;
541 vma->vm_private_data = map->handle; 541 vma->vm_private_data = map->handle;
542 /* FIXME: use pgprot_writecombine when available */
543 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 542 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
544 543
545 /* Take a ref for this mapping of the object, so that the fault 544 /* Take a ref for this mapping of the object, so that the fault
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f85aaf21e783..0a6f0b3bdc78 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -37,6 +37,7 @@
37 37
38#include <linux/interrupt.h> /* For task queue support */ 38#include <linux/interrupt.h> /* For task queue support */
39 39
40#include <linux/vgaarb.h>
40/** 41/**
41 * Get interrupt from bus id. 42 * Get interrupt from bus id.
42 * 43 *
@@ -171,6 +172,26 @@ err:
171} 172}
172EXPORT_SYMBOL(drm_vblank_init); 173EXPORT_SYMBOL(drm_vblank_init);
173 174
175static void drm_irq_vgaarb_nokms(void *cookie, bool state)
176{
177 struct drm_device *dev = cookie;
178
179 if (dev->driver->vgaarb_irq) {
180 dev->driver->vgaarb_irq(dev, state);
181 return;
182 }
183
184 if (!dev->irq_enabled)
185 return;
186
187 if (state)
188 dev->driver->irq_uninstall(dev);
189 else {
190 dev->driver->irq_preinstall(dev);
191 dev->driver->irq_postinstall(dev);
192 }
193}
194
174/** 195/**
175 * Install IRQ handler. 196 * Install IRQ handler.
176 * 197 *
@@ -231,6 +252,9 @@ int drm_irq_install(struct drm_device *dev)
231 return ret; 252 return ret;
232 } 253 }
233 254
255 if (!drm_core_check_feature(dev, DRIVER_MODESET))
256 vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
257
234 /* After installing handler */ 258 /* After installing handler */
235 ret = dev->driver->irq_postinstall(dev); 259 ret = dev->driver->irq_postinstall(dev);
236 if (ret < 0) { 260 if (ret < 0) {
@@ -279,6 +303,9 @@ int drm_irq_uninstall(struct drm_device * dev)
279 303
280 DRM_DEBUG("irq=%d\n", dev->pdev->irq); 304 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
281 305
306 if (!drm_core_check_feature(dev, DRIVER_MODESET))
307 vga_client_register(dev->pdev, NULL, NULL, NULL);
308
282 dev->driver->irq_uninstall(dev); 309 dev->driver->irq_uninstall(dev);
283 310
284 free_irq(dev->pdev->irq, dev); 311 free_irq(dev->pdev->irq, dev);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 3e47869d6dae..c861d80fd779 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -44,6 +44,7 @@
44#include "drmP.h" 44#include "drmP.h"
45#include "drm_mm.h" 45#include "drm_mm.h"
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <linux/seq_file.h>
47 48
48#define MM_UNUSED_TARGET 4 49#define MM_UNUSED_TARGET 4
49 50
@@ -370,3 +371,23 @@ void drm_mm_takedown(struct drm_mm * mm)
370 BUG_ON(mm->num_unused != 0); 371 BUG_ON(mm->num_unused != 0);
371} 372}
372EXPORT_SYMBOL(drm_mm_takedown); 373EXPORT_SYMBOL(drm_mm_takedown);
374
375#if defined(CONFIG_DEBUG_FS)
376int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
377{
378 struct drm_mm_node *entry;
379 int total_used = 0, total_free = 0, total = 0;
380
381 list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
382 seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used");
383 total += entry->size;
384 if (entry->free)
385 total_free += entry->size;
386 else
387 total_used += entry->size;
388 }
389 seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used);
390 return 0;
391}
392EXPORT_SYMBOL(drm_mm_dump_table);
393#endif
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 7914097b09c6..49404ce1666e 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -8,6 +8,8 @@
8 * Copyright © 2007 Dave Airlie 8 * Copyright © 2007 Dave Airlie
9 * Copyright © 2007-2008 Intel Corporation 9 * Copyright © 2007-2008 Intel Corporation
10 * Jesse Barnes <jesse.barnes@intel.com> 10 * Jesse Barnes <jesse.barnes@intel.com>
11 * Copyright 2005-2006 Luc Verhaegen
12 * Copyright (c) 2001, Andy Ritger aritger@nvidia.com
11 * 13 *
12 * Permission is hereby granted, free of charge, to any person obtaining a 14 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"), 15 * copy of this software and associated documentation files (the "Software"),
@@ -38,7 +40,6 @@
38#include "drm.h" 40#include "drm.h"
39#include "drm_crtc.h" 41#include "drm_crtc.h"
40 42
41#define DRM_MODESET_DEBUG "drm_mode"
42/** 43/**
43 * drm_mode_debug_printmodeline - debug print a mode 44 * drm_mode_debug_printmodeline - debug print a mode
44 * @dev: DRM device 45 * @dev: DRM device
@@ -51,8 +52,8 @@
51 */ 52 */
52void drm_mode_debug_printmodeline(struct drm_display_mode *mode) 53void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
53{ 54{
54 DRM_DEBUG_MODE(DRM_MODESET_DEBUG, 55 DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d "
55 "Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", 56 "0x%x 0x%x\n",
56 mode->base.id, mode->name, mode->vrefresh, mode->clock, 57 mode->base.id, mode->name, mode->vrefresh, mode->clock,
57 mode->hdisplay, mode->hsync_start, 58 mode->hdisplay, mode->hsync_start,
58 mode->hsync_end, mode->htotal, 59 mode->hsync_end, mode->htotal,
@@ -62,6 +63,420 @@ void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
62EXPORT_SYMBOL(drm_mode_debug_printmodeline); 63EXPORT_SYMBOL(drm_mode_debug_printmodeline);
63 64
64/** 65/**
66 * drm_cvt_mode -create a modeline based on CVT algorithm
67 * @dev: DRM device
68 * @hdisplay: hdisplay size
69 * @vdisplay: vdisplay size
70 * @vrefresh : vrefresh rate
71 * @reduced : Whether the GTF calculation is simplified
72 * @interlaced:Whether the interlace is supported
73 *
74 * LOCKING:
75 * none.
76 *
77 * return the modeline based on CVT algorithm
78 *
79 * This function is called to generate the modeline based on CVT algorithm
80 * according to the hdisplay, vdisplay, vrefresh.
81 * It is based from the VESA(TM) Coordinated Video Timing Generator by
82 * Graham Loveridge April 9, 2003 available at
83 * http://www.vesa.org/public/CVT/CVTd6r1.xls
84 *
85 * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c.
86 * What I have done is to translate it by using integer calculation.
87 */
88#define HV_FACTOR 1000
89struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
90 int vdisplay, int vrefresh,
91 bool reduced, bool interlaced)
92{
93 /* 1) top/bottom margin size (% of height) - default: 1.8, */
94#define CVT_MARGIN_PERCENTAGE 18
95 /* 2) character cell horizontal granularity (pixels) - default 8 */
96#define CVT_H_GRANULARITY 8
97 /* 3) Minimum vertical porch (lines) - default 3 */
98#define CVT_MIN_V_PORCH 3
99 /* 4) Minimum number of vertical back porch lines - default 6 */
100#define CVT_MIN_V_BPORCH 6
101 /* Pixel Clock step (kHz) */
102#define CVT_CLOCK_STEP 250
103 struct drm_display_mode *drm_mode;
104 bool margins = false;
105 unsigned int vfieldrate, hperiod;
106 int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
107 int interlace;
108
109 /* allocate the drm_display_mode structure. If failure, we will
110 * return directly
111 */
112 drm_mode = drm_mode_create(dev);
113 if (!drm_mode)
114 return NULL;
115
116 /* the CVT default refresh rate is 60Hz */
117 if (!vrefresh)
118 vrefresh = 60;
119
120 /* the required field fresh rate */
121 if (interlaced)
122 vfieldrate = vrefresh * 2;
123 else
124 vfieldrate = vrefresh;
125
126 /* horizontal pixels */
127 hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY);
128
129 /* determine the left&right borders */
130 hmargin = 0;
131 if (margins) {
132 hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
133 hmargin -= hmargin % CVT_H_GRANULARITY;
134 }
135 /* find the total active pixels */
136 drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin;
137
138 /* find the number of lines per field */
139 if (interlaced)
140 vdisplay_rnd = vdisplay / 2;
141 else
142 vdisplay_rnd = vdisplay;
143
144 /* find the top & bottom borders */
145 vmargin = 0;
146 if (margins)
147 vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
148
149 drm_mode->vdisplay = vdisplay + 2 * vmargin;
150
151 /* Interlaced */
152 if (interlaced)
153 interlace = 1;
154 else
155 interlace = 0;
156
157 /* Determine VSync Width from aspect ratio */
158 if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay))
159 vsync = 4;
160 else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay))
161 vsync = 5;
162 else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay))
163 vsync = 6;
164 else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay))
165 vsync = 7;
166 else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay))
167 vsync = 7;
168 else /* custom */
169 vsync = 10;
170
171 if (!reduced) {
172 /* simplify the GTF calculation */
173 /* 4) Minimum time of vertical sync + back porch interval (µs)
174 * default 550.0
175 */
176 int tmp1, tmp2;
177#define CVT_MIN_VSYNC_BP 550
178 /* 3) Nominal HSync width (% of line period) - default 8 */
179#define CVT_HSYNC_PERCENTAGE 8
180 unsigned int hblank_percentage;
181 int vsyncandback_porch, vback_porch, hblank;
182
183 /* estimated the horizontal period */
184 tmp1 = HV_FACTOR * 1000000 -
185 CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate;
186 tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 +
187 interlace;
188 hperiod = tmp1 * 2 / (tmp2 * vfieldrate);
189
190 tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1;
191 /* 9. Find number of lines in sync + backporch */
192 if (tmp1 < (vsync + CVT_MIN_V_PORCH))
193 vsyncandback_porch = vsync + CVT_MIN_V_PORCH;
194 else
195 vsyncandback_porch = tmp1;
196 /* 10. Find number of lines in back porch */
197 vback_porch = vsyncandback_porch - vsync;
198 drm_mode->vtotal = vdisplay_rnd + 2 * vmargin +
199 vsyncandback_porch + CVT_MIN_V_PORCH;
200 /* 5) Definition of Horizontal blanking time limitation */
201 /* Gradient (%/kHz) - default 600 */
202#define CVT_M_FACTOR 600
203 /* Offset (%) - default 40 */
204#define CVT_C_FACTOR 40
205 /* Blanking time scaling factor - default 128 */
206#define CVT_K_FACTOR 128
207 /* Scaling factor weighting - default 20 */
208#define CVT_J_FACTOR 20
209#define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256)
210#define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
211 CVT_J_FACTOR)
212 /* 12. Find ideal blanking duty cycle from formula */
213 hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME *
214 hperiod / 1000;
215 /* 13. Blanking time */
216 if (hblank_percentage < 20 * HV_FACTOR)
217 hblank_percentage = 20 * HV_FACTOR;
218 hblank = drm_mode->hdisplay * hblank_percentage /
219 (100 * HV_FACTOR - hblank_percentage);
220 hblank -= hblank % (2 * CVT_H_GRANULARITY);
221 /* 14. find the total pixes per line */
222 drm_mode->htotal = drm_mode->hdisplay + hblank;
223 drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2;
224 drm_mode->hsync_start = drm_mode->hsync_end -
225 (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100;
226 drm_mode->hsync_start += CVT_H_GRANULARITY -
227 drm_mode->hsync_start % CVT_H_GRANULARITY;
228 /* fill the Vsync values */
229 drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH;
230 drm_mode->vsync_end = drm_mode->vsync_start + vsync;
231 } else {
232 /* Reduced blanking */
233 /* Minimum vertical blanking interval time (µs)- default 460 */
234#define CVT_RB_MIN_VBLANK 460
235 /* Fixed number of clocks for horizontal sync */
236#define CVT_RB_H_SYNC 32
237 /* Fixed number of clocks for horizontal blanking */
238#define CVT_RB_H_BLANK 160
239 /* Fixed number of lines for vertical front porch - default 3*/
240#define CVT_RB_VFPORCH 3
241 int vbilines;
242 int tmp1, tmp2;
243 /* 8. Estimate Horizontal period. */
244 tmp1 = HV_FACTOR * 1000000 -
245 CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate;
246 tmp2 = vdisplay_rnd + 2 * vmargin;
247 hperiod = tmp1 / (tmp2 * vfieldrate);
248 /* 9. Find number of lines in vertical blanking */
249 vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1;
250 /* 10. Check if vertical blanking is sufficient */
251 if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH))
252 vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH;
253 /* 11. Find total number of lines in vertical field */
254 drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines;
255 /* 12. Find total number of pixels in a line */
256 drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK;
257 /* Fill in HSync values */
258 drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2;
259 drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC;
260 }
261 /* 15/13. Find pixel clock frequency (kHz for xf86) */
262 drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod;
263 drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP;
264 /* 18/16. Find actual vertical frame frequency */
265 /* ignore - just set the mode flag for interlaced */
266 if (interlaced)
267 drm_mode->vtotal *= 2;
268 /* Fill the mode line name */
269 drm_mode_set_name(drm_mode);
270 if (reduced)
271 drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
272 DRM_MODE_FLAG_NVSYNC);
273 else
274 drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC |
275 DRM_MODE_FLAG_NHSYNC);
276 if (interlaced)
277 drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
278
279 return drm_mode;
280}
281EXPORT_SYMBOL(drm_cvt_mode);
282
283/**
284 * drm_gtf_mode - create the modeline based on GTF algorithm
285 *
286 * @dev :drm device
287 * @hdisplay :hdisplay size
288 * @vdisplay :vdisplay size
289 * @vrefresh :vrefresh rate.
290 * @interlaced :whether the interlace is supported
291 * @margins :whether the margin is supported
292 *
293 * LOCKING.
294 * none.
295 *
296 * return the modeline based on GTF algorithm
297 *
298 * This function is to create the modeline based on the GTF algorithm.
299 * Generalized Timing Formula is derived from:
300 * GTF Spreadsheet by Andy Morrish (1/5/97)
301 * available at http://www.vesa.org
302 *
303 * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
304 * What I have done is to translate it by using integer calculation.
305 * I also refer to the function of fb_get_mode in the file of
306 * drivers/video/fbmon.c
307 */
308struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay,
309 int vdisplay, int vrefresh,
310 bool interlaced, int margins)
311{
312 /* 1) top/bottom margin size (% of height) - default: 1.8, */
313#define GTF_MARGIN_PERCENTAGE 18
314 /* 2) character cell horizontal granularity (pixels) - default 8 */
315#define GTF_CELL_GRAN 8
316 /* 3) Minimum vertical porch (lines) - default 3 */
317#define GTF_MIN_V_PORCH 1
318 /* width of vsync in lines */
319#define V_SYNC_RQD 3
320 /* width of hsync as % of total line */
321#define H_SYNC_PERCENT 8
322 /* min time of vsync + back porch (microsec) */
323#define MIN_VSYNC_PLUS_BP 550
324 /* blanking formula gradient */
325#define GTF_M 600
326 /* blanking formula offset */
327#define GTF_C 40
328 /* blanking formula scaling factor */
329#define GTF_K 128
330 /* blanking formula scaling factor */
331#define GTF_J 20
332 /* C' and M' are part of the Blanking Duty Cycle computation */
333#define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J)
334#define GTF_M_PRIME (GTF_K * GTF_M / 256)
335 struct drm_display_mode *drm_mode;
336 unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd;
337 int top_margin, bottom_margin;
338 int interlace;
339 unsigned int hfreq_est;
340 int vsync_plus_bp, vback_porch;
341 unsigned int vtotal_lines, vfieldrate_est, hperiod;
342 unsigned int vfield_rate, vframe_rate;
343 int left_margin, right_margin;
344 unsigned int total_active_pixels, ideal_duty_cycle;
345 unsigned int hblank, total_pixels, pixel_freq;
346 int hsync, hfront_porch, vodd_front_porch_lines;
347 unsigned int tmp1, tmp2;
348
349 drm_mode = drm_mode_create(dev);
350 if (!drm_mode)
351 return NULL;
352
353 /* 1. In order to give correct results, the number of horizontal
354 * pixels requested is first processed to ensure that it is divisible
355 * by the character size, by rounding it to the nearest character
356 * cell boundary:
357 */
358 hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
359 hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN;
360
361 /* 2. If interlace is requested, the number of vertical lines assumed
362 * by the calculation must be halved, as the computation calculates
363 * the number of vertical lines per field.
364 */
365 if (interlaced)
366 vdisplay_rnd = vdisplay / 2;
367 else
368 vdisplay_rnd = vdisplay;
369
370 /* 3. Find the frame rate required: */
371 if (interlaced)
372 vfieldrate_rqd = vrefresh * 2;
373 else
374 vfieldrate_rqd = vrefresh;
375
376 /* 4. Find number of lines in Top margin: */
377 top_margin = 0;
378 if (margins)
379 top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
380 1000;
381 /* 5. Find number of lines in bottom margin: */
382 bottom_margin = top_margin;
383
384 /* 6. If interlace is required, then set variable interlace: */
385 if (interlaced)
386 interlace = 1;
387 else
388 interlace = 0;
389
390 /* 7. Estimate the Horizontal frequency */
391 {
392 tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500;
393 tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) *
394 2 + interlace;
395 hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1;
396 }
397
398 /* 8. Find the number of lines in V sync + back porch */
399 /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */
400 vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000;
401 vsync_plus_bp = (vsync_plus_bp + 500) / 1000;
402 /* 9. Find the number of lines in V back porch alone: */
403 vback_porch = vsync_plus_bp - V_SYNC_RQD;
404 /* 10. Find the total number of lines in Vertical field period: */
405 vtotal_lines = vdisplay_rnd + top_margin + bottom_margin +
406 vsync_plus_bp + GTF_MIN_V_PORCH;
407 /* 11. Estimate the Vertical field frequency: */
408 vfieldrate_est = hfreq_est / vtotal_lines;
409 /* 12. Find the actual horizontal period: */
410 hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines);
411
412 /* 13. Find the actual Vertical field frequency: */
413 vfield_rate = hfreq_est / vtotal_lines;
414 /* 14. Find the Vertical frame frequency: */
415 if (interlaced)
416 vframe_rate = vfield_rate / 2;
417 else
418 vframe_rate = vfield_rate;
419 /* 15. Find number of pixels in left margin: */
420 if (margins)
421 left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
422 1000;
423 else
424 left_margin = 0;
425
426 /* 16.Find number of pixels in right margin: */
427 right_margin = left_margin;
428 /* 17.Find total number of active pixels in image and left and right */
429 total_active_pixels = hdisplay_rnd + left_margin + right_margin;
430 /* 18.Find the ideal blanking duty cycle from blanking duty cycle */
431 ideal_duty_cycle = GTF_C_PRIME * 1000 -
432 (GTF_M_PRIME * 1000000 / hfreq_est);
433 /* 19.Find the number of pixels in the blanking time to the nearest
434 * double character cell: */
435 hblank = total_active_pixels * ideal_duty_cycle /
436 (100000 - ideal_duty_cycle);
437 hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN);
438 hblank = hblank * 2 * GTF_CELL_GRAN;
439 /* 20.Find total number of pixels: */
440 total_pixels = total_active_pixels + hblank;
441 /* 21.Find pixel clock frequency: */
442 pixel_freq = total_pixels * hfreq_est / 1000;
443 /* Stage 1 computations are now complete; I should really pass
444 * the results to another function and do the Stage 2 computations,
445 * but I only need a few more values so I'll just append the
446 * computations here for now */
447 /* 17. Find the number of pixels in the horizontal sync period: */
448 hsync = H_SYNC_PERCENT * total_pixels / 100;
449 hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
450 hsync = hsync * GTF_CELL_GRAN;
451 /* 18. Find the number of pixels in horizontal front porch period */
452 hfront_porch = hblank / 2 - hsync;
453 /* 36. Find the number of lines in the odd front porch period: */
454 vodd_front_porch_lines = GTF_MIN_V_PORCH ;
455
456 /* finally, pack the results in the mode struct */
457 drm_mode->hdisplay = hdisplay_rnd;
458 drm_mode->hsync_start = hdisplay_rnd + hfront_porch;
459 drm_mode->hsync_end = drm_mode->hsync_start + hsync;
460 drm_mode->htotal = total_pixels;
461 drm_mode->vdisplay = vdisplay_rnd;
462 drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines;
463 drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD;
464 drm_mode->vtotal = vtotal_lines;
465
466 drm_mode->clock = pixel_freq;
467
468 drm_mode_set_name(drm_mode);
469 drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC;
470
471 if (interlaced) {
472 drm_mode->vtotal *= 2;
473 drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
474 }
475
476 return drm_mode;
477}
478EXPORT_SYMBOL(drm_gtf_mode);
479/**
65 * drm_mode_set_name - set the name on a mode 480 * drm_mode_set_name - set the name on a mode
66 * @mode: name will be set in this mode 481 * @mode: name will be set in this mode
67 * 482 *
@@ -151,7 +566,9 @@ EXPORT_SYMBOL(drm_mode_height);
151 * FIXME: why is this needed? shouldn't vrefresh be set already? 566 * FIXME: why is this needed? shouldn't vrefresh be set already?
152 * 567 *
153 * RETURNS: 568 * RETURNS:
154 * Vertical refresh rate of @mode x 1000. For precision reasons. 569 * Vertical refresh rate. It will be the result of actual value plus 0.5.
570 * If it is 70.288, it will return 70Hz.
571 * If it is 59.6, it will return 60Hz.
155 */ 572 */
156int drm_mode_vrefresh(struct drm_display_mode *mode) 573int drm_mode_vrefresh(struct drm_display_mode *mode)
157{ 574{
@@ -161,14 +578,13 @@ int drm_mode_vrefresh(struct drm_display_mode *mode)
161 if (mode->vrefresh > 0) 578 if (mode->vrefresh > 0)
162 refresh = mode->vrefresh; 579 refresh = mode->vrefresh;
163 else if (mode->htotal > 0 && mode->vtotal > 0) { 580 else if (mode->htotal > 0 && mode->vtotal > 0) {
581 int vtotal;
582 vtotal = mode->vtotal;
164 /* work out vrefresh the value will be x1000 */ 583 /* work out vrefresh the value will be x1000 */
165 calc_val = (mode->clock * 1000); 584 calc_val = (mode->clock * 1000);
166
167 calc_val /= mode->htotal; 585 calc_val /= mode->htotal;
168 calc_val *= 1000; 586 refresh = (calc_val + vtotal / 2) / vtotal;
169 calc_val /= mode->vtotal;
170 587
171 refresh = calc_val;
172 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 588 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
173 refresh *= 2; 589 refresh *= 2;
174 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 590 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -403,8 +819,7 @@ void drm_mode_prune_invalid(struct drm_device *dev,
403 list_del(&mode->head); 819 list_del(&mode->head);
404 if (verbose) { 820 if (verbose) {
405 drm_mode_debug_printmodeline(mode); 821 drm_mode_debug_printmodeline(mode);
406 DRM_DEBUG_MODE(DRM_MODESET_DEBUG, 822 DRM_DEBUG_KMS("Not using %s mode %d\n",
407 "Not using %s mode %d\n",
408 mode->name, mode->status); 823 mode->name, mode->status);
409 } 824 }
410 drm_mode_destroy(dev, mode); 825 drm_mode_destroy(dev, mode);
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index bbd4b3d1074a..d379c4f2892f 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -106,20 +106,25 @@ int drm_proc_create_files(struct drm_info_list *files, int count,
106 continue; 106 continue;
107 107
108 tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); 108 tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
109 ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); 109 if (tmp == NULL) {
110 ret = -1;
111 goto fail;
112 }
113 tmp->minor = minor;
114 tmp->info_ent = &files[i];
115 list_add(&tmp->list, &minor->proc_nodes.list);
116
117 ent = proc_create_data(files[i].name, S_IRUGO, root,
118 &drm_proc_fops, tmp);
110 if (!ent) { 119 if (!ent) {
111 DRM_ERROR("Cannot create /proc/dri/%s/%s\n", 120 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
112 name, files[i].name); 121 name, files[i].name);
122 list_del(&tmp->list);
113 kfree(tmp); 123 kfree(tmp);
114 ret = -1; 124 ret = -1;
115 goto fail; 125 goto fail;
116 } 126 }
117 127
118 ent->proc_fops = &drm_proc_fops;
119 ent->data = tmp;
120 tmp->minor = minor;
121 tmp->info_ent = &files[i];
122 list_add(&(tmp->list), &(minor->proc_nodes.list));
123 } 128 }
124 return 0; 129 return 0;
125 130
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index f7a615b80c70..7e42b7e9d43a 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -16,6 +16,7 @@
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/err.h> 17#include <linux/err.h>
18 18
19#include "drm_sysfs.h"
19#include "drm_core.h" 20#include "drm_core.h"
20#include "drmP.h" 21#include "drmP.h"
21 22
@@ -76,7 +77,7 @@ static ssize_t version_show(struct class *dev, char *buf)
76 CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); 77 CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
77} 78}
78 79
79static char *drm_nodename(struct device *dev) 80static char *drm_devnode(struct device *dev, mode_t *mode)
80{ 81{
81 return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); 82 return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
82} 83}
@@ -112,7 +113,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
112 if (err) 113 if (err)
113 goto err_out_class; 114 goto err_out_class;
114 115
115 class->nodename = drm_nodename; 116 class->devnode = drm_devnode;
116 117
117 return class; 118 return class;
118 119
@@ -253,6 +254,7 @@ static ssize_t subconnector_show(struct device *device,
253 case DRM_MODE_CONNECTOR_Composite: 254 case DRM_MODE_CONNECTOR_Composite:
254 case DRM_MODE_CONNECTOR_SVIDEO: 255 case DRM_MODE_CONNECTOR_SVIDEO:
255 case DRM_MODE_CONNECTOR_Component: 256 case DRM_MODE_CONNECTOR_Component:
257 case DRM_MODE_CONNECTOR_TV:
256 prop = dev->mode_config.tv_subconnector_property; 258 prop = dev->mode_config.tv_subconnector_property;
257 is_tv = 1; 259 is_tv = 1;
258 break; 260 break;
@@ -293,6 +295,7 @@ static ssize_t select_subconnector_show(struct device *device,
293 case DRM_MODE_CONNECTOR_Composite: 295 case DRM_MODE_CONNECTOR_Composite:
294 case DRM_MODE_CONNECTOR_SVIDEO: 296 case DRM_MODE_CONNECTOR_SVIDEO:
295 case DRM_MODE_CONNECTOR_Component: 297 case DRM_MODE_CONNECTOR_Component:
298 case DRM_MODE_CONNECTOR_TV:
296 prop = dev->mode_config.tv_select_subconnector_property; 299 prop = dev->mode_config.tv_select_subconnector_property;
297 is_tv = 1; 300 is_tv = 1;
298 break; 301 break;
@@ -391,6 +394,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
391 case DRM_MODE_CONNECTOR_Composite: 394 case DRM_MODE_CONNECTOR_Composite:
392 case DRM_MODE_CONNECTOR_SVIDEO: 395 case DRM_MODE_CONNECTOR_SVIDEO:
393 case DRM_MODE_CONNECTOR_Component: 396 case DRM_MODE_CONNECTOR_Component:
397 case DRM_MODE_CONNECTOR_TV:
394 for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) { 398 for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
395 ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]); 399 ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
396 if (ret) 400 if (ret)
@@ -519,3 +523,27 @@ void drm_sysfs_device_remove(struct drm_minor *minor)
519{ 523{
520 device_unregister(&minor->kdev); 524 device_unregister(&minor->kdev);
521} 525}
526
527
528/**
529 * drm_class_device_register - Register a struct device in the drm class.
530 *
531 * @dev: pointer to struct device to register.
532 *
533 * @dev should have all relevant members pre-filled with the exception
534 * of the class member. In particular, the device_type member must
535 * be set.
536 */
537
538int drm_class_device_register(struct device *dev)
539{
540 dev->class = drm_class;
541 return device_register(dev);
542}
543EXPORT_SYMBOL_GPL(drm_class_device_register);
544
545void drm_class_device_unregister(struct device *dev)
546{
547 return device_unregister(dev);
548}
549EXPORT_SYMBOL_GPL(drm_class_device_unregister);
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 30d6b99fb302..5269dfa5f620 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -4,10 +4,10 @@
4 4
5ccflags-y := -Iinclude/drm 5ccflags-y := -Iinclude/drm
6i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ 6i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
7 i915_debugfs.o \
7 i915_suspend.o \ 8 i915_suspend.o \
8 i915_gem.o \ 9 i915_gem.o \
9 i915_gem_debug.o \ 10 i915_gem_debug.o \
10 i915_gem_debugfs.o \
11 i915_gem_tiling.o \ 11 i915_gem_tiling.o \
12 intel_display.o \ 12 intel_display.o \
13 intel_crt.o \ 13 intel_crt.o \
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index cb3b97405fbf..1e3bdcee863c 100644
--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -158,16 +158,37 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
158 struct drm_device *dev = node->minor->dev; 158 struct drm_device *dev = node->minor->dev;
159 drm_i915_private_t *dev_priv = dev->dev_private; 159 drm_i915_private_t *dev_priv = dev->dev_private;
160 160
161 seq_printf(m, "Interrupt enable: %08x\n", 161 if (!IS_IGDNG(dev)) {
162 I915_READ(IER)); 162 seq_printf(m, "Interrupt enable: %08x\n",
163 seq_printf(m, "Interrupt identity: %08x\n", 163 I915_READ(IER));
164 I915_READ(IIR)); 164 seq_printf(m, "Interrupt identity: %08x\n",
165 seq_printf(m, "Interrupt mask: %08x\n", 165 I915_READ(IIR));
166 I915_READ(IMR)); 166 seq_printf(m, "Interrupt mask: %08x\n",
167 seq_printf(m, "Pipe A stat: %08x\n", 167 I915_READ(IMR));
168 I915_READ(PIPEASTAT)); 168 seq_printf(m, "Pipe A stat: %08x\n",
169 seq_printf(m, "Pipe B stat: %08x\n", 169 I915_READ(PIPEASTAT));
170 I915_READ(PIPEBSTAT)); 170 seq_printf(m, "Pipe B stat: %08x\n",
171 I915_READ(PIPEBSTAT));
172 } else {
173 seq_printf(m, "North Display Interrupt enable: %08x\n",
174 I915_READ(DEIER));
175 seq_printf(m, "North Display Interrupt identity: %08x\n",
176 I915_READ(DEIIR));
177 seq_printf(m, "North Display Interrupt mask: %08x\n",
178 I915_READ(DEIMR));
179 seq_printf(m, "South Display Interrupt enable: %08x\n",
180 I915_READ(SDEIER));
181 seq_printf(m, "South Display Interrupt identity: %08x\n",
182 I915_READ(SDEIIR));
183 seq_printf(m, "South Display Interrupt mask: %08x\n",
184 I915_READ(SDEIMR));
185 seq_printf(m, "Graphics Interrupt enable: %08x\n",
186 I915_READ(GTIER));
187 seq_printf(m, "Graphics Interrupt identity: %08x\n",
188 I915_READ(GTIIR));
189 seq_printf(m, "Graphics Interrupt mask: %08x\n",
190 I915_READ(GTIMR));
191 }
171 seq_printf(m, "Interrupts received: %d\n", 192 seq_printf(m, "Interrupts received: %d\n",
172 atomic_read(&dev_priv->irq_received)); 193 atomic_read(&dev_priv->irq_received));
173 if (dev_priv->hw_status_page != NULL) { 194 if (dev_priv->hw_status_page != NULL) {
@@ -312,15 +333,13 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
312 struct drm_info_node *node = (struct drm_info_node *) m->private; 333 struct drm_info_node *node = (struct drm_info_node *) m->private;
313 struct drm_device *dev = node->minor->dev; 334 struct drm_device *dev = node->minor->dev;
314 drm_i915_private_t *dev_priv = dev->dev_private; 335 drm_i915_private_t *dev_priv = dev->dev_private;
315 unsigned int head, tail, mask; 336 unsigned int head, tail;
316 337
317 head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 338 head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
318 tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 339 tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
319 mask = dev_priv->ring.tail_mask;
320 340
321 seq_printf(m, "RingHead : %08x\n", head); 341 seq_printf(m, "RingHead : %08x\n", head);
322 seq_printf(m, "RingTail : %08x\n", tail); 342 seq_printf(m, "RingTail : %08x\n", tail);
323 seq_printf(m, "RingMask : %08x\n", mask);
324 seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); 343 seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size);
325 seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); 344 seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
326 345
@@ -363,7 +382,37 @@ out:
363 return 0; 382 return 0;
364} 383}
365 384
366static struct drm_info_list i915_gem_debugfs_list[] = { 385static int i915_registers_info(struct seq_file *m, void *data) {
386 struct drm_info_node *node = (struct drm_info_node *) m->private;
387 struct drm_device *dev = node->minor->dev;
388 drm_i915_private_t *dev_priv = dev->dev_private;
389 uint32_t reg;
390
391#define DUMP_RANGE(start, end) \
392 for (reg=start; reg < end; reg += 4) \
393 seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
394
395 DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */
396 DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */
397 DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */
398 DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */
399 DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */
400 DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */
401 DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */
402 DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */
403 DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */
404 DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */
405 DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */
406 DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */
407 DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */
408 DUMP_RANGE(0x73000, 0x73fff); /* performance counters */
409
410 return 0;
411}
412
413
414static struct drm_info_list i915_debugfs_list[] = {
415 {"i915_regs", i915_registers_info, 0},
367 {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, 416 {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
368 {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, 417 {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
369 {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, 418 {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
@@ -377,19 +426,19 @@ static struct drm_info_list i915_gem_debugfs_list[] = {
377 {"i915_batchbuffers", i915_batchbuffer_info, 0}, 426 {"i915_batchbuffers", i915_batchbuffer_info, 0},
378 {"i915_error_state", i915_error_state, 0}, 427 {"i915_error_state", i915_error_state, 0},
379}; 428};
380#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) 429#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
381 430
382int i915_gem_debugfs_init(struct drm_minor *minor) 431int i915_debugfs_init(struct drm_minor *minor)
383{ 432{
384 return drm_debugfs_create_files(i915_gem_debugfs_list, 433 return drm_debugfs_create_files(i915_debugfs_list,
385 I915_GEM_DEBUGFS_ENTRIES, 434 I915_DEBUGFS_ENTRIES,
386 minor->debugfs_root, minor); 435 minor->debugfs_root, minor);
387} 436}
388 437
389void i915_gem_debugfs_cleanup(struct drm_minor *minor) 438void i915_debugfs_cleanup(struct drm_minor *minor)
390{ 439{
391 drm_debugfs_remove_files(i915_gem_debugfs_list, 440 drm_debugfs_remove_files(i915_debugfs_list,
392 I915_GEM_DEBUGFS_ENTRIES, minor); 441 I915_DEBUGFS_ENTRIES, minor);
393} 442}
394 443
395#endif /* CONFIG_DEBUG_FS */ 444#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 50d1f782768c..5a49a1867b35 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -29,11 +29,11 @@
29#include "drmP.h" 29#include "drmP.h"
30#include "drm.h" 30#include "drm.h"
31#include "drm_crtc_helper.h" 31#include "drm_crtc_helper.h"
32#include "drm_fb_helper.h"
32#include "intel_drv.h" 33#include "intel_drv.h"
33#include "i915_drm.h" 34#include "i915_drm.h"
34#include "i915_drv.h" 35#include "i915_drv.h"
35 36#include <linux/vgaarb.h>
36#define I915_DRV "i915_drv"
37 37
38/* Really want an OS-independent resettable timer. Would like to have 38/* Really want an OS-independent resettable timer. Would like to have
39 * this loop run for (eg) 3 sec, but have the timer reset every time 39 * this loop run for (eg) 3 sec, but have the timer reset every time
@@ -80,6 +80,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
80 return -EBUSY; 80 return -EBUSY;
81} 81}
82 82
83/* As a ringbuffer is only allowed to wrap between instructions, fill
84 * the tail with NOOPs.
85 */
86int i915_wrap_ring(struct drm_device *dev)
87{
88 drm_i915_private_t *dev_priv = dev->dev_private;
89 volatile unsigned int *virt;
90 int rem;
91
92 rem = dev_priv->ring.Size - dev_priv->ring.tail;
93 if (dev_priv->ring.space < rem) {
94 int ret = i915_wait_ring(dev, rem, __func__);
95 if (ret)
96 return ret;
97 }
98 dev_priv->ring.space -= rem;
99
100 virt = (unsigned int *)
101 (dev_priv->ring.virtual_start + dev_priv->ring.tail);
102 rem /= 4;
103 while (rem--)
104 *virt++ = MI_NOOP;
105
106 dev_priv->ring.tail = 0;
107
108 return 0;
109}
110
83/** 111/**
84 * Sets up the hardware status page for devices that need a physical address 112 * Sets up the hardware status page for devices that need a physical address
85 * in the register. 113 * in the register.
@@ -101,7 +129,7 @@ static int i915_init_phys_hws(struct drm_device *dev)
101 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 129 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
102 130
103 I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 131 I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
104 DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n"); 132 DRM_DEBUG_DRIVER("Enabled hardware status page\n");
105 return 0; 133 return 0;
106} 134}
107 135
@@ -187,8 +215,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
187 master_priv->sarea_priv = (drm_i915_sarea_t *) 215 master_priv->sarea_priv = (drm_i915_sarea_t *)
188 ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); 216 ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset);
189 } else { 217 } else {
190 DRM_DEBUG_DRIVER(I915_DRV, 218 DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n");
191 "sarea not found assuming DRI2 userspace\n");
192 } 219 }
193 220
194 if (init->ring_size != 0) { 221 if (init->ring_size != 0) {
@@ -200,7 +227,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
200 } 227 }
201 228
202 dev_priv->ring.Size = init->ring_size; 229 dev_priv->ring.Size = init->ring_size;
203 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
204 230
205 dev_priv->ring.map.offset = init->ring_start; 231 dev_priv->ring.map.offset = init->ring_start;
206 dev_priv->ring.map.size = init->ring_size; 232 dev_priv->ring.map.size = init->ring_size;
@@ -238,7 +264,7 @@ static int i915_dma_resume(struct drm_device * dev)
238{ 264{
239 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 265 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
240 266
241 DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__); 267 DRM_DEBUG_DRIVER("%s\n", __func__);
242 268
243 if (dev_priv->ring.map.handle == NULL) { 269 if (dev_priv->ring.map.handle == NULL) {
244 DRM_ERROR("can not ioremap virtual address for" 270 DRM_ERROR("can not ioremap virtual address for"
@@ -251,14 +277,14 @@ static int i915_dma_resume(struct drm_device * dev)
251 DRM_ERROR("Can not find hardware status page\n"); 277 DRM_ERROR("Can not find hardware status page\n");
252 return -EINVAL; 278 return -EINVAL;
253 } 279 }
254 DRM_DEBUG_DRIVER(I915_DRV, "hw status page @ %p\n", 280 DRM_DEBUG_DRIVER("hw status page @ %p\n",
255 dev_priv->hw_status_page); 281 dev_priv->hw_status_page);
256 282
257 if (dev_priv->status_gfx_addr != 0) 283 if (dev_priv->status_gfx_addr != 0)
258 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); 284 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
259 else 285 else
260 I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 286 I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
261 DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n"); 287 DRM_DEBUG_DRIVER("Enabled hardware status page\n");
262 288
263 return 0; 289 return 0;
264} 290}
@@ -552,7 +578,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
552 if (!master_priv->sarea_priv) 578 if (!master_priv->sarea_priv)
553 return -EINVAL; 579 return -EINVAL;
554 580
555 DRM_DEBUG_DRIVER(I915_DRV, "%s: page=%d pfCurrentPage=%d\n", 581 DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
556 __func__, 582 __func__,
557 dev_priv->current_page, 583 dev_priv->current_page,
558 master_priv->sarea_priv->pf_current_page); 584 master_priv->sarea_priv->pf_current_page);
@@ -633,8 +659,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
633 return -EINVAL; 659 return -EINVAL;
634 } 660 }
635 661
636 DRM_DEBUG_DRIVER(I915_DRV, 662 DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n",
637 "i915 batchbuffer, start %x used %d cliprects %d\n",
638 batch->start, batch->used, batch->num_cliprects); 663 batch->start, batch->used, batch->num_cliprects);
639 664
640 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 665 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -681,8 +706,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
681 void *batch_data; 706 void *batch_data;
682 int ret; 707 int ret;
683 708
684 DRM_DEBUG_DRIVER(I915_DRV, 709 DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
685 "i915 cmdbuffer, buf %p sz %d cliprects %d\n",
686 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); 710 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
687 711
688 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 712 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -735,7 +759,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data,
735{ 759{
736 int ret; 760 int ret;
737 761
738 DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__); 762 DRM_DEBUG_DRIVER("%s\n", __func__);
739 763
740 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 764 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
741 765
@@ -778,7 +802,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
778 value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; 802 value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
779 break; 803 break;
780 default: 804 default:
781 DRM_DEBUG_DRIVER(I915_DRV, "Unknown parameter %d\n", 805 DRM_DEBUG_DRIVER("Unknown parameter %d\n",
782 param->param); 806 param->param);
783 return -EINVAL; 807 return -EINVAL;
784 } 808 }
@@ -819,7 +843,7 @@ static int i915_setparam(struct drm_device *dev, void *data,
819 dev_priv->fence_reg_start = param->value; 843 dev_priv->fence_reg_start = param->value;
820 break; 844 break;
821 default: 845 default:
822 DRM_DEBUG_DRIVER(I915_DRV, "unknown parameter %d\n", 846 DRM_DEBUG_DRIVER("unknown parameter %d\n",
823 param->param); 847 param->param);
824 return -EINVAL; 848 return -EINVAL;
825 } 849 }
@@ -846,7 +870,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
846 return 0; 870 return 0;
847 } 871 }
848 872
849 DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); 873 DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
850 874
851 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 875 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
852 876
@@ -868,13 +892,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
868 892
869 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 893 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
870 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); 894 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
871 DRM_DEBUG_DRIVER(I915_DRV, "load hws HWS_PGA with gfx mem 0x%x\n", 895 DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
872 dev_priv->status_gfx_addr); 896 dev_priv->status_gfx_addr);
873 DRM_DEBUG_DRIVER(I915_DRV, "load hws at %p\n", 897 DRM_DEBUG_DRIVER("load hws at %p\n",
874 dev_priv->hw_status_page); 898 dev_priv->hw_status_page);
875 return 0; 899 return 0;
876} 900}
877 901
902static int i915_get_bridge_dev(struct drm_device *dev)
903{
904 struct drm_i915_private *dev_priv = dev->dev_private;
905
906 dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
907 if (!dev_priv->bridge_dev) {
908 DRM_ERROR("bridge device not found\n");
909 return -1;
910 }
911 return 0;
912}
913
878/** 914/**
879 * i915_probe_agp - get AGP bootup configuration 915 * i915_probe_agp - get AGP bootup configuration
880 * @pdev: PCI device 916 * @pdev: PCI device
@@ -888,20 +924,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
888static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, 924static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
889 uint32_t *preallocated_size) 925 uint32_t *preallocated_size)
890{ 926{
891 struct pci_dev *bridge_dev; 927 struct drm_i915_private *dev_priv = dev->dev_private;
892 u16 tmp = 0; 928 u16 tmp = 0;
893 unsigned long overhead; 929 unsigned long overhead;
894 unsigned long stolen; 930 unsigned long stolen;
895 931
896 bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
897 if (!bridge_dev) {
898 DRM_ERROR("bridge device not found\n");
899 return -1;
900 }
901
902 /* Get the fb aperture size and "stolen" memory amount. */ 932 /* Get the fb aperture size and "stolen" memory amount. */
903 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 933 pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp);
904 pci_dev_put(bridge_dev);
905 934
906 *aperture_size = 1024 * 1024; 935 *aperture_size = 1024 * 1024;
907 *preallocated_size = 1024 * 1024; 936 *preallocated_size = 1024 * 1024;
@@ -984,6 +1013,19 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
984 return 0; 1013 return 0;
985} 1014}
986 1015
1016/* true = enable decode, false = disable decoder */
1017static unsigned int i915_vga_set_decode(void *cookie, bool state)
1018{
1019 struct drm_device *dev = cookie;
1020
1021 intel_modeset_vga_set_state(dev, state);
1022 if (state)
1023 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
1024 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1025 else
1026 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1027}
1028
987static int i915_load_modeset_init(struct drm_device *dev, 1029static int i915_load_modeset_init(struct drm_device *dev,
988 unsigned long prealloc_size, 1030 unsigned long prealloc_size,
989 unsigned long agp_size) 1031 unsigned long agp_size)
@@ -1029,6 +1071,11 @@ static int i915_load_modeset_init(struct drm_device *dev,
1029 if (ret) 1071 if (ret)
1030 DRM_INFO("failed to find VBIOS tables\n"); 1072 DRM_INFO("failed to find VBIOS tables\n");
1031 1073
1074 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
1075 ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
1076 if (ret)
1077 goto destroy_ringbuffer;
1078
1032 ret = drm_irq_install(dev); 1079 ret = drm_irq_install(dev);
1033 if (ret) 1080 if (ret)
1034 goto destroy_ringbuffer; 1081 goto destroy_ringbuffer;
@@ -1153,11 +1200,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1153 base = drm_get_resource_start(dev, mmio_bar); 1200 base = drm_get_resource_start(dev, mmio_bar);
1154 size = drm_get_resource_len(dev, mmio_bar); 1201 size = drm_get_resource_len(dev, mmio_bar);
1155 1202
1203 if (i915_get_bridge_dev(dev)) {
1204 ret = -EIO;
1205 goto free_priv;
1206 }
1207
1156 dev_priv->regs = ioremap(base, size); 1208 dev_priv->regs = ioremap(base, size);
1157 if (!dev_priv->regs) { 1209 if (!dev_priv->regs) {
1158 DRM_ERROR("failed to map registers\n"); 1210 DRM_ERROR("failed to map registers\n");
1159 ret = -EIO; 1211 ret = -EIO;
1160 goto free_priv; 1212 goto put_bridge;
1161 } 1213 }
1162 1214
1163 dev_priv->mm.gtt_mapping = 1215 dev_priv->mm.gtt_mapping =
@@ -1269,6 +1321,8 @@ out_iomapfree:
1269 io_mapping_free(dev_priv->mm.gtt_mapping); 1321 io_mapping_free(dev_priv->mm.gtt_mapping);
1270out_rmmap: 1322out_rmmap:
1271 iounmap(dev_priv->regs); 1323 iounmap(dev_priv->regs);
1324put_bridge:
1325 pci_dev_put(dev_priv->bridge_dev);
1272free_priv: 1326free_priv:
1273 kfree(dev_priv); 1327 kfree(dev_priv);
1274 return ret; 1328 return ret;
@@ -1289,6 +1343,7 @@ int i915_driver_unload(struct drm_device *dev)
1289 1343
1290 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1344 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1291 drm_irq_uninstall(dev); 1345 drm_irq_uninstall(dev);
1346 vga_client_register(dev->pdev, NULL, NULL, NULL);
1292 } 1347 }
1293 1348
1294 if (dev->pdev->msi_enabled) 1349 if (dev->pdev->msi_enabled)
@@ -1312,6 +1367,7 @@ int i915_driver_unload(struct drm_device *dev)
1312 i915_gem_lastclose(dev); 1367 i915_gem_lastclose(dev);
1313 } 1368 }
1314 1369
1370 pci_dev_put(dev_priv->bridge_dev);
1315 kfree(dev->dev_private); 1371 kfree(dev->dev_private);
1316 1372
1317 return 0; 1373 return 0;
@@ -1321,7 +1377,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1321{ 1377{
1322 struct drm_i915_file_private *i915_file_priv; 1378 struct drm_i915_file_private *i915_file_priv;
1323 1379
1324 DRM_DEBUG_DRIVER(I915_DRV, "\n"); 1380 DRM_DEBUG_DRIVER("\n");
1325 i915_file_priv = (struct drm_i915_file_private *) 1381 i915_file_priv = (struct drm_i915_file_private *)
1326 kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); 1382 kmalloc(sizeof(*i915_file_priv), GFP_KERNEL);
1327 1383
@@ -1352,7 +1408,7 @@ void i915_driver_lastclose(struct drm_device * dev)
1352 drm_i915_private_t *dev_priv = dev->dev_private; 1408 drm_i915_private_t *dev_priv = dev->dev_private;
1353 1409
1354 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { 1410 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
1355 intelfb_restore(); 1411 drm_fb_helper_restore();
1356 return; 1412 return;
1357 } 1413 }
1358 1414
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index fc4b68aa2d05..dbe568c9327b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -37,12 +37,15 @@
37#include <linux/console.h> 37#include <linux/console.h>
38#include "drm_crtc_helper.h" 38#include "drm_crtc_helper.h"
39 39
40static unsigned int i915_modeset = -1; 40static int i915_modeset = -1;
41module_param_named(modeset, i915_modeset, int, 0400); 41module_param_named(modeset, i915_modeset, int, 0400);
42 42
43unsigned int i915_fbpercrtc = 0; 43unsigned int i915_fbpercrtc = 0;
44module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); 44module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
45 45
46unsigned int i915_powersave = 1;
47module_param_named(powersave, i915_powersave, int, 0400);
48
46static struct drm_driver driver; 49static struct drm_driver driver;
47 50
48static struct pci_device_id pciidlist[] = { 51static struct pci_device_id pciidlist[] = {
@@ -188,8 +191,8 @@ static struct drm_driver driver = {
188 .master_create = i915_master_create, 191 .master_create = i915_master_create,
189 .master_destroy = i915_master_destroy, 192 .master_destroy = i915_master_destroy,
190#if defined(CONFIG_DEBUG_FS) 193#if defined(CONFIG_DEBUG_FS)
191 .debugfs_init = i915_gem_debugfs_init, 194 .debugfs_init = i915_debugfs_init,
192 .debugfs_cleanup = i915_gem_debugfs_cleanup, 195 .debugfs_cleanup = i915_debugfs_cleanup,
193#endif 196#endif
194 .gem_init_object = i915_gem_init_object, 197 .gem_init_object = i915_gem_init_object,
195 .gem_free_object = i915_gem_free_object, 198 .gem_free_object = i915_gem_free_object,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5b4f87e55621..a0632f8e76ac 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object {
85}; 85};
86 86
87typedef struct _drm_i915_ring_buffer { 87typedef struct _drm_i915_ring_buffer {
88 int tail_mask;
89 unsigned long Size; 88 unsigned long Size;
90 u8 *virtual_start; 89 u8 *virtual_start;
91 int head; 90 int head;
@@ -156,6 +155,7 @@ typedef struct drm_i915_private {
156 155
157 void __iomem *regs; 156 void __iomem *regs;
158 157
158 struct pci_dev *bridge_dev;
159 drm_i915_ring_buffer_t ring; 159 drm_i915_ring_buffer_t ring;
160 160
161 drm_dma_handle_t *status_page_dmah; 161 drm_dma_handle_t *status_page_dmah;
@@ -311,7 +311,7 @@ typedef struct drm_i915_private {
311 u32 saveIMR; 311 u32 saveIMR;
312 u32 saveCACHE_MODE_0; 312 u32 saveCACHE_MODE_0;
313 u32 saveD_STATE; 313 u32 saveD_STATE;
314 u32 saveCG_2D_DIS; 314 u32 saveDSPCLK_GATE_D;
315 u32 saveMI_ARB_STATE; 315 u32 saveMI_ARB_STATE;
316 u32 saveSWF0[16]; 316 u32 saveSWF0[16];
317 u32 saveSWF1[16]; 317 u32 saveSWF1[16];
@@ -443,6 +443,14 @@ typedef struct drm_i915_private {
443 struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; 443 struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
444 } mm; 444 } mm;
445 struct sdvo_device_mapping sdvo_mappings[2]; 445 struct sdvo_device_mapping sdvo_mappings[2];
446
447 /* Reclocking support */
448 bool render_reclock_avail;
449 bool lvds_downclock_avail;
450 struct work_struct idle_work;
451 struct timer_list idle_timer;
452 bool busy;
453 u16 orig_clock;
446} drm_i915_private_t; 454} drm_i915_private_t;
447 455
448/** driver private structure attached to each drm_gem_object */ 456/** driver private structure attached to each drm_gem_object */
@@ -575,6 +583,7 @@ enum intel_chip_family {
575extern struct drm_ioctl_desc i915_ioctls[]; 583extern struct drm_ioctl_desc i915_ioctls[];
576extern int i915_max_ioctl; 584extern int i915_max_ioctl;
577extern unsigned int i915_fbpercrtc; 585extern unsigned int i915_fbpercrtc;
586extern unsigned int i915_powersave;
578 587
579extern int i915_master_create(struct drm_device *dev, struct drm_master *master); 588extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
580extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); 589extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -730,8 +739,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len,
730void i915_dump_lru(struct drm_device *dev, const char *where); 739void i915_dump_lru(struct drm_device *dev, const char *where);
731 740
732/* i915_debugfs.c */ 741/* i915_debugfs.c */
733int i915_gem_debugfs_init(struct drm_minor *minor); 742int i915_debugfs_init(struct drm_minor *minor);
734void i915_gem_debugfs_cleanup(struct drm_minor *minor); 743void i915_debugfs_cleanup(struct drm_minor *minor);
735 744
736/* i915_suspend.c */ 745/* i915_suspend.c */
737extern int i915_save_state(struct drm_device *dev); 746extern int i915_save_state(struct drm_device *dev);
@@ -757,6 +766,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
757/* modesetting */ 766/* modesetting */
758extern void intel_modeset_init(struct drm_device *dev); 767extern void intel_modeset_init(struct drm_device *dev);
759extern void intel_modeset_cleanup(struct drm_device *dev); 768extern void intel_modeset_cleanup(struct drm_device *dev);
769extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
760 770
761/** 771/**
762 * Lock test for when it's just for synchronization of ring access. 772 * Lock test for when it's just for synchronization of ring access.
@@ -781,33 +791,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
781 791
782#define I915_VERBOSE 0 792#define I915_VERBOSE 0
783 793
784#define RING_LOCALS unsigned int outring, ringmask, outcount; \ 794#define RING_LOCALS volatile unsigned int *ring_virt__;
785 volatile char *virt; 795
786 796#define BEGIN_LP_RING(n) do { \
787#define BEGIN_LP_RING(n) do { \ 797 int bytes__ = 4*(n); \
788 if (I915_VERBOSE) \ 798 if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
789 DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ 799 /* a wrap must occur between instructions so pad beforehand */ \
790 if (dev_priv->ring.space < (n)*4) \ 800 if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
791 i915_wait_ring(dev, (n)*4, __func__); \ 801 i915_wrap_ring(dev); \
792 outcount = 0; \ 802 if (unlikely (dev_priv->ring.space < bytes__)) \
793 outring = dev_priv->ring.tail; \ 803 i915_wait_ring(dev, bytes__, __func__); \
794 ringmask = dev_priv->ring.tail_mask; \ 804 ring_virt__ = (unsigned int *) \
795 virt = dev_priv->ring.virtual_start; \ 805 (dev_priv->ring.virtual_start + dev_priv->ring.tail); \
806 dev_priv->ring.tail += bytes__; \
807 dev_priv->ring.tail &= dev_priv->ring.Size - 1; \
808 dev_priv->ring.space -= bytes__; \
796} while (0) 809} while (0)
797 810
798#define OUT_RING(n) do { \ 811#define OUT_RING(n) do { \
799 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ 812 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
800 *(volatile unsigned int *)(virt + outring) = (n); \ 813 *ring_virt__++ = (n); \
801 outcount++; \
802 outring += 4; \
803 outring &= ringmask; \
804} while (0) 814} while (0)
805 815
806#define ADVANCE_LP_RING() do { \ 816#define ADVANCE_LP_RING() do { \
807 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ 817 if (I915_VERBOSE) \
808 dev_priv->ring.tail = outring; \ 818 DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \
809 dev_priv->ring.space -= outcount * 4; \ 819 I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \
810 I915_WRITE(PRB0_TAIL, outring); \
811} while(0) 820} while(0)
812 821
813/** 822/**
@@ -830,6 +839,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
830#define I915_GEM_HWS_INDEX 0x20 839#define I915_GEM_HWS_INDEX 0x20
831#define I915_BREADCRUMB_INDEX 0x21 840#define I915_BREADCRUMB_INDEX 0x21
832 841
842extern int i915_wrap_ring(struct drm_device * dev);
833extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); 843extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
834 844
835#define IS_I830(dev) ((dev)->pci_device == 0x3577) 845#define IS_I830(dev) ((dev)->pci_device == 0x3577)
@@ -903,6 +913,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
903/* dsparb controlled by hw only */ 913/* dsparb controlled by hw only */
904#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) 914#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
905 915
916#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
917#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
918
906#define PRIMARY_RINGBUFFER_SIZE (128*1024) 919#define PRIMARY_RINGBUFFER_SIZE (128*1024)
907 920
908#endif 921#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 80e5ba490dc2..c67317112f4a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -29,6 +29,7 @@
29#include "drm.h" 29#include "drm.h"
30#include "i915_drm.h" 30#include "i915_drm.h"
31#include "i915_drv.h" 31#include "i915_drv.h"
32#include "intel_drv.h"
32#include <linux/swap.h> 33#include <linux/swap.h>
33#include <linux/pci.h> 34#include <linux/pci.h>
34 35
@@ -111,7 +112,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
111{ 112{
112 struct drm_i915_gem_create *args = data; 113 struct drm_i915_gem_create *args = data;
113 struct drm_gem_object *obj; 114 struct drm_gem_object *obj;
114 int handle, ret; 115 int ret;
116 u32 handle;
115 117
116 args->size = roundup(args->size, PAGE_SIZE); 118 args->size = roundup(args->size, PAGE_SIZE);
117 119
@@ -981,6 +983,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
981 struct drm_i915_private *dev_priv = dev->dev_private; 983 struct drm_i915_private *dev_priv = dev->dev_private;
982 struct drm_i915_gem_set_domain *args = data; 984 struct drm_i915_gem_set_domain *args = data;
983 struct drm_gem_object *obj; 985 struct drm_gem_object *obj;
986 struct drm_i915_gem_object *obj_priv;
984 uint32_t read_domains = args->read_domains; 987 uint32_t read_domains = args->read_domains;
985 uint32_t write_domain = args->write_domain; 988 uint32_t write_domain = args->write_domain;
986 int ret; 989 int ret;
@@ -1004,15 +1007,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1004 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 1007 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1005 if (obj == NULL) 1008 if (obj == NULL)
1006 return -EBADF; 1009 return -EBADF;
1010 obj_priv = obj->driver_private;
1007 1011
1008 mutex_lock(&dev->struct_mutex); 1012 mutex_lock(&dev->struct_mutex);
1013
1014 intel_mark_busy(dev, obj);
1015
1009#if WATCH_BUF 1016#if WATCH_BUF
1010 DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", 1017 DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n",
1011 obj, obj->size, read_domains, write_domain); 1018 obj, obj->size, read_domains, write_domain);
1012#endif 1019#endif
1013 if (read_domains & I915_GEM_DOMAIN_GTT) { 1020 if (read_domains & I915_GEM_DOMAIN_GTT) {
1014 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1015
1016 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); 1021 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
1017 1022
1018 /* Update the LRU on the fence for the CPU access that's 1023 /* Update the LRU on the fence for the CPU access that's
@@ -2776,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
2776 BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); 2781 BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
2777 BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); 2782 BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
2778 2783
2784 intel_mark_busy(dev, obj);
2785
2779#if WATCH_BUF 2786#if WATCH_BUF
2780 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", 2787 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2781 __func__, obj, 2788 __func__, obj,
@@ -4093,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
4093 4100
4094 /* Set up the kernel mapping for the ring. */ 4101 /* Set up the kernel mapping for the ring. */
4095 ring->Size = obj->size; 4102 ring->Size = obj->size;
4096 ring->tail_mask = obj->size - 1;
4097 4103
4098 ring->map.offset = dev->agp->base + obj_priv->gtt_offset; 4104 ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
4099 ring->map.size = obj->size; 4105 ring->map.size = obj->size;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index a2d527b22ec4..200e398453ca 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -94,23 +94,15 @@
94static int 94static int
95intel_alloc_mchbar_resource(struct drm_device *dev) 95intel_alloc_mchbar_resource(struct drm_device *dev)
96{ 96{
97 struct pci_dev *bridge_dev;
98 drm_i915_private_t *dev_priv = dev->dev_private; 97 drm_i915_private_t *dev_priv = dev->dev_private;
99 int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; 98 int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
100 u32 temp_lo, temp_hi = 0; 99 u32 temp_lo, temp_hi = 0;
101 u64 mchbar_addr; 100 u64 mchbar_addr;
102 int ret = 0; 101 int ret = 0;
103 102
104 bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
105 if (!bridge_dev) {
106 DRM_DEBUG("no bridge dev?!\n");
107 ret = -ENODEV;
108 goto out;
109 }
110
111 if (IS_I965G(dev)) 103 if (IS_I965G(dev))
112 pci_read_config_dword(bridge_dev, reg + 4, &temp_hi); 104 pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
113 pci_read_config_dword(bridge_dev, reg, &temp_lo); 105 pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
114 mchbar_addr = ((u64)temp_hi << 32) | temp_lo; 106 mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
115 107
116 /* If ACPI doesn't have it, assume we need to allocate it ourselves */ 108 /* If ACPI doesn't have it, assume we need to allocate it ourselves */
@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
118 if (mchbar_addr && 110 if (mchbar_addr &&
119 pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { 111 pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
120 ret = 0; 112 ret = 0;
121 goto out_put; 113 goto out;
122 } 114 }
123#endif 115#endif
124 116
125 /* Get some space for it */ 117 /* Get some space for it */
126 ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, 118 ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
127 MCHBAR_SIZE, MCHBAR_SIZE, 119 MCHBAR_SIZE, MCHBAR_SIZE,
128 PCIBIOS_MIN_MEM, 120 PCIBIOS_MIN_MEM,
129 0, pcibios_align_resource, 121 0, pcibios_align_resource,
130 bridge_dev); 122 dev_priv->bridge_dev);
131 if (ret) { 123 if (ret) {
132 DRM_DEBUG("failed bus alloc: %d\n", ret); 124 DRM_DEBUG("failed bus alloc: %d\n", ret);
133 dev_priv->mch_res.start = 0; 125 dev_priv->mch_res.start = 0;
134 goto out_put; 126 goto out;
135 } 127 }
136 128
137 if (IS_I965G(dev)) 129 if (IS_I965G(dev))
138 pci_write_config_dword(bridge_dev, reg + 4, 130 pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
139 upper_32_bits(dev_priv->mch_res.start)); 131 upper_32_bits(dev_priv->mch_res.start));
140 132
141 pci_write_config_dword(bridge_dev, reg, 133 pci_write_config_dword(dev_priv->bridge_dev, reg,
142 lower_32_bits(dev_priv->mch_res.start)); 134 lower_32_bits(dev_priv->mch_res.start));
143out_put:
144 pci_dev_put(bridge_dev);
145out: 135out:
146 return ret; 136 return ret;
147} 137}
@@ -150,44 +140,36 @@ out:
150static bool 140static bool
151intel_setup_mchbar(struct drm_device *dev) 141intel_setup_mchbar(struct drm_device *dev)
152{ 142{
153 struct pci_dev *bridge_dev; 143 drm_i915_private_t *dev_priv = dev->dev_private;
154 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; 144 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
155 u32 temp; 145 u32 temp;
156 bool need_disable = false, enabled; 146 bool need_disable = false, enabled;
157 147
158 bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
159 if (!bridge_dev) {
160 DRM_DEBUG("no bridge dev?!\n");
161 goto out;
162 }
163
164 if (IS_I915G(dev) || IS_I915GM(dev)) { 148 if (IS_I915G(dev) || IS_I915GM(dev)) {
165 pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); 149 pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
166 enabled = !!(temp & DEVEN_MCHBAR_EN); 150 enabled = !!(temp & DEVEN_MCHBAR_EN);
167 } else { 151 } else {
168 pci_read_config_dword(bridge_dev, mchbar_reg, &temp); 152 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
169 enabled = temp & 1; 153 enabled = temp & 1;
170 } 154 }
171 155
172 /* If it's already enabled, don't have to do anything */ 156 /* If it's already enabled, don't have to do anything */
173 if (enabled) 157 if (enabled)
174 goto out_put; 158 goto out;
175 159
176 if (intel_alloc_mchbar_resource(dev)) 160 if (intel_alloc_mchbar_resource(dev))
177 goto out_put; 161 goto out;
178 162
179 need_disable = true; 163 need_disable = true;
180 164
181 /* Space is allocated or reserved, so enable it. */ 165 /* Space is allocated or reserved, so enable it. */
182 if (IS_I915G(dev) || IS_I915GM(dev)) { 166 if (IS_I915G(dev) || IS_I915GM(dev)) {
183 pci_write_config_dword(bridge_dev, DEVEN_REG, 167 pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
184 temp | DEVEN_MCHBAR_EN); 168 temp | DEVEN_MCHBAR_EN);
185 } else { 169 } else {
186 pci_read_config_dword(bridge_dev, mchbar_reg, &temp); 170 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
187 pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1); 171 pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
188 } 172 }
189out_put:
190 pci_dev_put(bridge_dev);
191out: 173out:
192 return need_disable; 174 return need_disable;
193} 175}
@@ -196,25 +178,18 @@ static void
196intel_teardown_mchbar(struct drm_device *dev, bool disable) 178intel_teardown_mchbar(struct drm_device *dev, bool disable)
197{ 179{
198 drm_i915_private_t *dev_priv = dev->dev_private; 180 drm_i915_private_t *dev_priv = dev->dev_private;
199 struct pci_dev *bridge_dev;
200 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; 181 int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
201 u32 temp; 182 u32 temp;
202 183
203 bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
204 if (!bridge_dev) {
205 DRM_DEBUG("no bridge dev?!\n");
206 return;
207 }
208
209 if (disable) { 184 if (disable) {
210 if (IS_I915G(dev) || IS_I915GM(dev)) { 185 if (IS_I915G(dev) || IS_I915GM(dev)) {
211 pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); 186 pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
212 temp &= ~DEVEN_MCHBAR_EN; 187 temp &= ~DEVEN_MCHBAR_EN;
213 pci_write_config_dword(bridge_dev, DEVEN_REG, temp); 188 pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
214 } else { 189 } else {
215 pci_read_config_dword(bridge_dev, mchbar_reg, &temp); 190 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
216 temp &= ~1; 191 temp &= ~1;
217 pci_write_config_dword(bridge_dev, mchbar_reg, temp); 192 pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
218 } 193 }
219 } 194 }
220 195
@@ -234,7 +209,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
234 uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; 209 uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
235 bool need_disable; 210 bool need_disable;
236 211
237 if (!IS_I9XX(dev)) { 212 if (IS_IGDNG(dev)) {
213 /* On IGDNG whatever DRAM config, GPU always do
214 * same swizzling setup.
215 */
216 swizzle_x = I915_BIT_6_SWIZZLE_9_10;
217 swizzle_y = I915_BIT_6_SWIZZLE_9;
218 } else if (!IS_I9XX(dev)) {
238 /* As far as we know, the 865 doesn't have these bit 6 219 /* As far as we know, the 865 doesn't have these bit 6
239 * swizzling issues. 220 * swizzling issues.
240 */ 221 */
@@ -317,13 +298,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
317 } 298 }
318 } 299 }
319 300
320 /* FIXME: check with memory config on IGDNG */
321 if (IS_IGDNG(dev)) {
322 DRM_ERROR("disable tiling on IGDNG...\n");
323 swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
324 swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
325 }
326
327 dev_priv->mm.bit_6_swizzle_x = swizzle_x; 301 dev_priv->mm.bit_6_swizzle_x = swizzle_x;
328 dev_priv->mm.bit_6_swizzle_y = swizzle_y; 302 dev_priv->mm.bit_6_swizzle_y = swizzle_y;
329} 303}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7ebc84c2881e..6c89f2ff2495 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
565 565
566 I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); 566 I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
567 I915_READ(PORT_HOTPLUG_STAT); 567 I915_READ(PORT_HOTPLUG_STAT);
568
569 /* EOS interrupts occurs */
570 if (IS_IGD(dev) &&
571 (hotplug_status & CRT_EOS_INT_STATUS)) {
572 u32 temp;
573
574 DRM_DEBUG("EOS interrupt occurs\n");
575 /* status is already cleared */
576 temp = I915_READ(ADPA);
577 temp &= ~ADPA_DAC_ENABLE;
578 I915_WRITE(ADPA, temp);
579
580 temp = I915_READ(PORT_HOTPLUG_EN);
581 temp &= ~CRT_EOS_INT_EN;
582 I915_WRITE(PORT_HOTPLUG_EN, temp);
583
584 temp = I915_READ(PORT_HOTPLUG_STAT);
585 if (temp & CRT_EOS_INT_STATUS)
586 I915_WRITE(PORT_HOTPLUG_STAT,
587 CRT_EOS_INT_STATUS);
588 }
568 } 589 }
569 590
570 I915_WRITE(IIR, iir); 591 I915_WRITE(IIR, iir);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2955083aa471..3f7963553464 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -30,6 +30,7 @@
30 * fb aperture size and the amount of pre-reserved memory. 30 * fb aperture size and the amount of pre-reserved memory.
31 */ 31 */
32#define INTEL_GMCH_CTRL 0x52 32#define INTEL_GMCH_CTRL 0x52
33#define INTEL_GMCH_VGA_DISABLE (1 << 1)
33#define INTEL_GMCH_ENABLED 0x4 34#define INTEL_GMCH_ENABLED 0x4
34#define INTEL_GMCH_MEM_MASK 0x1 35#define INTEL_GMCH_MEM_MASK 0x1
35#define INTEL_GMCH_MEM_64M 0x1 36#define INTEL_GMCH_MEM_64M 0x1
@@ -55,7 +56,7 @@
55/* PCI config space */ 56/* PCI config space */
56 57
57#define HPLLCC 0xc0 /* 855 only */ 58#define HPLLCC 0xc0 /* 855 only */
58#define GC_CLOCK_CONTROL_MASK (3 << 0) 59#define GC_CLOCK_CONTROL_MASK (0xf << 0)
59#define GC_CLOCK_133_200 (0 << 0) 60#define GC_CLOCK_133_200 (0 << 0)
60#define GC_CLOCK_100_200 (1 << 0) 61#define GC_CLOCK_100_200 (1 << 0)
61#define GC_CLOCK_100_133 (2 << 0) 62#define GC_CLOCK_100_133 (2 << 0)
@@ -65,6 +66,25 @@
65#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) 66#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
66#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) 67#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
67#define GC_DISPLAY_CLOCK_MASK (7 << 4) 68#define GC_DISPLAY_CLOCK_MASK (7 << 4)
69#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0)
70#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0)
71#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0)
72#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0)
73#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0)
74#define I965_GC_RENDER_CLOCK_MASK (0xf << 0)
75#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0)
76#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0)
77#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0)
78#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0)
79#define I945_GC_RENDER_CLOCK_MASK (7 << 0)
80#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0)
81#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0)
82#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0)
83#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0)
84#define I915_GC_RENDER_CLOCK_MASK (7 << 0)
85#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0)
86#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0)
87#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0)
68#define LBB 0xf4 88#define LBB 0xf4
69 89
70/* VGA stuff */ 90/* VGA stuff */
@@ -553,9 +573,118 @@
553#define DPLLA_TEST_M_BYPASS (1 << 2) 573#define DPLLA_TEST_M_BYPASS (1 << 2)
554#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) 574#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
555#define D_STATE 0x6104 575#define D_STATE 0x6104
556#define CG_2D_DIS 0x6200 576#define DSTATE_PLL_D3_OFF (1<<3)
557#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) 577#define DSTATE_GFX_CLOCK_GATING (1<<1)
558#define CG_3D_DIS 0x6204 578#define DSTATE_DOT_CLOCK_GATING (1<<0)
579#define DSPCLK_GATE_D 0x6200
580# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */
581# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */
582# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */
583# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */
584# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */
585# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */
586# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */
587# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */
588# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */
589# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */
590# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */
591# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */
592# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */
593# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */
594# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */
595# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */
596# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */
597# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */
598# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */
599# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11)
600# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10)
601# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9)
602# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8)
603# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */
604# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */
605# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */
606# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5)
607# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4)
608/**
609 * This bit must be set on the 830 to prevent hangs when turning off the
610 * overlay scaler.
611 */
612# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3)
613# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2)
614# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1)
615# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */
616# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */
617
618#define RENCLK_GATE_D1 0x6204
619# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */
620# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */
621# define PC_FE_CLOCK_GATE_DISABLE (1 << 11)
622# define PC_BE_CLOCK_GATE_DISABLE (1 << 10)
623# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9)
624# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8)
625# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7)
626# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6)
627# define MAG_CLOCK_GATE_DISABLE (1 << 5)
628/** This bit must be unset on 855,865 */
629# define MECI_CLOCK_GATE_DISABLE (1 << 4)
630# define DCMP_CLOCK_GATE_DISABLE (1 << 3)
631# define MEC_CLOCK_GATE_DISABLE (1 << 2)
632# define MECO_CLOCK_GATE_DISABLE (1 << 1)
633/** This bit must be set on 855,865. */
634# define SV_CLOCK_GATE_DISABLE (1 << 0)
635# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16)
636# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15)
637# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14)
638# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13)
639# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12)
640# define I915_WM_CLOCK_GATE_DISABLE (1 << 11)
641# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10)
642# define I915_PI_CLOCK_GATE_DISABLE (1 << 9)
643# define I915_DI_CLOCK_GATE_DISABLE (1 << 8)
644# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7)
645# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6)
646# define I915_SC_CLOCK_GATE_DISABLE (1 << 5)
647# define I915_FL_CLOCK_GATE_DISABLE (1 << 4)
648# define I915_DM_CLOCK_GATE_DISABLE (1 << 3)
649# define I915_PS_CLOCK_GATE_DISABLE (1 << 2)
650# define I915_CC_CLOCK_GATE_DISABLE (1 << 1)
651# define I915_BY_CLOCK_GATE_DISABLE (1 << 0)
652
653# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30)
654/** This bit must always be set on 965G/965GM */
655# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29)
656# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28)
657# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27)
658# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26)
659# define I965_GW_CLOCK_GATE_DISABLE (1 << 25)
660# define I965_TD_CLOCK_GATE_DISABLE (1 << 24)
661/** This bit must always be set on 965G */
662# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23)
663# define I965_IC_CLOCK_GATE_DISABLE (1 << 22)
664# define I965_EU_CLOCK_GATE_DISABLE (1 << 21)
665# define I965_IF_CLOCK_GATE_DISABLE (1 << 20)
666# define I965_TC_CLOCK_GATE_DISABLE (1 << 19)
667# define I965_SO_CLOCK_GATE_DISABLE (1 << 17)
668# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16)
669# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15)
670# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14)
671# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13)
672# define I965_EM_CLOCK_GATE_DISABLE (1 << 12)
673# define I965_UC_CLOCK_GATE_DISABLE (1 << 11)
674# define I965_SI_CLOCK_GATE_DISABLE (1 << 6)
675# define I965_MT_CLOCK_GATE_DISABLE (1 << 5)
676# define I965_PL_CLOCK_GATE_DISABLE (1 << 4)
677# define I965_DG_CLOCK_GATE_DISABLE (1 << 3)
678# define I965_QC_CLOCK_GATE_DISABLE (1 << 2)
679# define I965_FT_CLOCK_GATE_DISABLE (1 << 1)
680# define I965_DM_CLOCK_GATE_DISABLE (1 << 0)
681
682#define RENCLK_GATE_D2 0x6208
683#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9)
684#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7)
685#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6)
686#define RAMCLK_GATE_D 0x6210 /* CRL only */
687#define DEUC 0x6214 /* CRL only */
559 688
560/* 689/*
561 * Palette regs 690 * Palette regs
@@ -683,6 +812,7 @@
683#define SDVOB_HOTPLUG_INT_EN (1 << 26) 812#define SDVOB_HOTPLUG_INT_EN (1 << 26)
684#define SDVOC_HOTPLUG_INT_EN (1 << 25) 813#define SDVOC_HOTPLUG_INT_EN (1 << 25)
685#define TV_HOTPLUG_INT_EN (1 << 18) 814#define TV_HOTPLUG_INT_EN (1 << 18)
815#define CRT_EOS_INT_EN (1 << 10)
686#define CRT_HOTPLUG_INT_EN (1 << 9) 816#define CRT_HOTPLUG_INT_EN (1 << 9)
687#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) 817#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
688#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) 818#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8)
@@ -717,6 +847,7 @@
717#define DPC_HOTPLUG_INT_STATUS (1 << 28) 847#define DPC_HOTPLUG_INT_STATUS (1 << 28)
718#define HDMID_HOTPLUG_INT_STATUS (1 << 27) 848#define HDMID_HOTPLUG_INT_STATUS (1 << 27)
719#define DPD_HOTPLUG_INT_STATUS (1 << 27) 849#define DPD_HOTPLUG_INT_STATUS (1 << 27)
850#define CRT_EOS_INT_STATUS (1 << 12)
720#define CRT_HOTPLUG_INT_STATUS (1 << 11) 851#define CRT_HOTPLUG_INT_STATUS (1 << 11)
721#define TV_HOTPLUG_INT_STATUS (1 << 10) 852#define TV_HOTPLUG_INT_STATUS (1 << 10)
722#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) 853#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
@@ -1586,6 +1717,7 @@
1586#define PIPECONF_PROGRESSIVE (0 << 21) 1717#define PIPECONF_PROGRESSIVE (0 << 21)
1587#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) 1718#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1588#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) 1719#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1720#define PIPECONF_CXSR_DOWNCLOCK (1<<16)
1589#define PIPEASTAT 0x70024 1721#define PIPEASTAT 0x70024
1590#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) 1722#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
1591#define PIPE_CRC_ERROR_ENABLE (1UL<<29) 1723#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
@@ -1733,6 +1865,7 @@
1733#define DISPPLANE_NO_LINE_DOUBLE 0 1865#define DISPPLANE_NO_LINE_DOUBLE 0
1734#define DISPPLANE_STEREO_POLARITY_FIRST 0 1866#define DISPPLANE_STEREO_POLARITY_FIRST 0
1735#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) 1867#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1868#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */
1736#define DISPPLANE_TILED (1<<10) 1869#define DISPPLANE_TILED (1<<10)
1737#define DSPAADDR 0x70184 1870#define DSPAADDR 0x70184
1738#define DSPASTRIDE 0x70188 1871#define DSPASTRIDE 0x70188
@@ -1913,6 +2046,9 @@
1913#define GTIIR 0x44018 2046#define GTIIR 0x44018
1914#define GTIER 0x4401c 2047#define GTIER 0x4401c
1915 2048
2049#define DISP_ARB_CTL 0x45000
2050#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
2051
1916/* PCH */ 2052/* PCH */
1917 2053
1918/* south display engine interrupt */ 2054/* south display engine interrupt */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 1d04e1904ac6..20d4d19f5568 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev)
461 461
462 /* Clock gating state */ 462 /* Clock gating state */
463 dev_priv->saveD_STATE = I915_READ(D_STATE); 463 dev_priv->saveD_STATE = I915_READ(D_STATE);
464 dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); 464 dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
465 465
466 /* Cache mode state */ 466 /* Cache mode state */
467 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); 467 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev)
588 588
589 /* Clock gating state */ 589 /* Clock gating state */
590 I915_WRITE (D_STATE, dev_priv->saveD_STATE); 590 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
591 I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); 591 I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
592 592
593 /* Cache mode state */ 593 /* Cache mode state */
594 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); 594 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f806fcc54e09..1e28c1652fd0 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv,
355 } 355 }
356 356
357 driver = find_section(bdb, BDB_DRIVER_FEATURES); 357 driver = find_section(bdb, BDB_DRIVER_FEATURES);
358 if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) 358 if (!driver)
359 return;
360
361 if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
359 dev_priv->edp_support = 1; 362 dev_priv->edp_support = 1;
363
364 if (driver->dual_frequency)
365 dev_priv->render_reclock_avail = true;
360} 366}
361 367
362/** 368/**
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 590f81c8f594..88814fa2dfd2 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
64 } 64 }
65 65
66 I915_WRITE(reg, temp); 66 I915_WRITE(reg, temp);
67
68 if (IS_IGD(dev)) {
69 if (mode == DRM_MODE_DPMS_OFF) {
70 /* turn off DAC */
71 temp = I915_READ(PORT_HOTPLUG_EN);
72 temp &= ~CRT_EOS_INT_EN;
73 I915_WRITE(PORT_HOTPLUG_EN, temp);
74
75 temp = I915_READ(PORT_HOTPLUG_STAT);
76 if (temp & CRT_EOS_INT_STATUS)
77 I915_WRITE(PORT_HOTPLUG_STAT,
78 CRT_EOS_INT_STATUS);
79 } else {
80 /* turn on DAC. EOS interrupt must be enabled after DAC
81 * is enabled, so it sounds not good to enable it in
82 * i915_driver_irq_postinstall()
83 * wait 12.5ms after DAC is enabled
84 */
85 msleep(13);
86 temp = I915_READ(PORT_HOTPLUG_STAT);
87 if (temp & CRT_EOS_INT_STATUS)
88 I915_WRITE(PORT_HOTPLUG_STAT,
89 CRT_EOS_INT_STATUS);
90 temp = I915_READ(PORT_HOTPLUG_EN);
91 temp |= CRT_EOS_INT_EN;
92 I915_WRITE(PORT_HOTPLUG_EN, temp);
93 }
94 }
67} 95}
68 96
69static int intel_crt_mode_valid(struct drm_connector *connector, 97static int intel_crt_mode_valid(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 748ed50c55ca..0227b1652906 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -38,6 +38,7 @@
38 38
39bool intel_pipe_has_type (struct drm_crtc *crtc, int type); 39bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
40static void intel_update_watermarks(struct drm_device *dev); 40static void intel_update_watermarks(struct drm_device *dev);
41static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
41 42
42typedef struct { 43typedef struct {
43 /* given values */ 44 /* given values */
@@ -67,6 +68,8 @@ struct intel_limit {
67 intel_p2_t p2; 68 intel_p2_t p2;
68 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, 69 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
69 int, int, intel_clock_t *); 70 int, int, intel_clock_t *);
71 bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
72 int, int, intel_clock_t *);
70}; 73};
71 74
72#define I8XX_DOT_MIN 25000 75#define I8XX_DOT_MIN 25000
@@ -261,6 +264,9 @@ static bool
261intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 264intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
262 int target, int refclk, intel_clock_t *best_clock); 265 int target, int refclk, intel_clock_t *best_clock);
263static bool 266static bool
267intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
268 int target, int refclk, intel_clock_t *best_clock);
269static bool
264intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 270intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
265 int target, int refclk, intel_clock_t *best_clock); 271 int target, int refclk, intel_clock_t *best_clock);
266static bool 272static bool
@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
286 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 292 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
287 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, 293 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
288 .find_pll = intel_find_best_PLL, 294 .find_pll = intel_find_best_PLL,
295 .find_reduced_pll = intel_find_best_reduced_PLL,
289}; 296};
290 297
291static const intel_limit_t intel_limits_i8xx_lvds = { 298static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
300 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 307 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
301 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, 308 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
302 .find_pll = intel_find_best_PLL, 309 .find_pll = intel_find_best_PLL,
310 .find_reduced_pll = intel_find_best_reduced_PLL,
303}; 311};
304 312
305static const intel_limit_t intel_limits_i9xx_sdvo = { 313static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
314 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 322 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
315 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 323 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
316 .find_pll = intel_find_best_PLL, 324 .find_pll = intel_find_best_PLL,
325 .find_reduced_pll = intel_find_best_reduced_PLL,
317}; 326};
318 327
319static const intel_limit_t intel_limits_i9xx_lvds = { 328static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
331 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 340 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
332 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, 341 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
333 .find_pll = intel_find_best_PLL, 342 .find_pll = intel_find_best_PLL,
343 .find_reduced_pll = intel_find_best_reduced_PLL,
334}; 344};
335 345
336 /* below parameter and function is for G4X Chipset Family*/ 346 /* below parameter and function is for G4X Chipset Family*/
@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
348 .p2_fast = G4X_P2_SDVO_FAST 358 .p2_fast = G4X_P2_SDVO_FAST
349 }, 359 },
350 .find_pll = intel_g4x_find_best_PLL, 360 .find_pll = intel_g4x_find_best_PLL,
361 .find_reduced_pll = intel_g4x_find_best_PLL,
351}; 362};
352 363
353static const intel_limit_t intel_limits_g4x_hdmi = { 364static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
364 .p2_fast = G4X_P2_HDMI_DAC_FAST 375 .p2_fast = G4X_P2_HDMI_DAC_FAST
365 }, 376 },
366 .find_pll = intel_g4x_find_best_PLL, 377 .find_pll = intel_g4x_find_best_PLL,
378 .find_reduced_pll = intel_g4x_find_best_PLL,
367}; 379};
368 380
369static const intel_limit_t intel_limits_g4x_single_channel_lvds = { 381static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
388 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST 400 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
389 }, 401 },
390 .find_pll = intel_g4x_find_best_PLL, 402 .find_pll = intel_g4x_find_best_PLL,
403 .find_reduced_pll = intel_g4x_find_best_PLL,
391}; 404};
392 405
393static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { 406static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
412 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST 425 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
413 }, 426 },
414 .find_pll = intel_g4x_find_best_PLL, 427 .find_pll = intel_g4x_find_best_PLL,
428 .find_reduced_pll = intel_g4x_find_best_PLL,
415}; 429};
416 430
417static const intel_limit_t intel_limits_g4x_display_port = { 431static const intel_limit_t intel_limits_g4x_display_port = {
@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = {
449 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 463 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
450 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 464 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
451 .find_pll = intel_find_best_PLL, 465 .find_pll = intel_find_best_PLL,
466 .find_reduced_pll = intel_find_best_reduced_PLL,
452}; 467};
453 468
454static const intel_limit_t intel_limits_igd_lvds = { 469static const intel_limit_t intel_limits_igd_lvds = {
@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = {
464 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 479 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
465 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, 480 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
466 .find_pll = intel_find_best_PLL, 481 .find_pll = intel_find_best_PLL,
482 .find_reduced_pll = intel_find_best_reduced_PLL,
467}; 483};
468 484
469static const intel_limit_t intel_limits_igdng_sdvo = { 485static const intel_limit_t intel_limits_igdng_sdvo = {
@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
688 704
689 memset (best_clock, 0, sizeof (*best_clock)); 705 memset (best_clock, 0, sizeof (*best_clock));
690 706
691 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { 707 for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
692 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { 708 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
693 /* m1 is always 0 in IGD */ 709 clock.m1++) {
694 if (clock.m2 >= clock.m1 && !IS_IGD(dev)) 710 for (clock.m2 = limit->m2.min;
695 break; 711 clock.m2 <= limit->m2.max; clock.m2++) {
696 for (clock.n = limit->n.min; clock.n <= limit->n.max; 712 /* m1 is always 0 in IGD */
697 clock.n++) { 713 if (clock.m2 >= clock.m1 && !IS_IGD(dev))
698 for (clock.p1 = limit->p1.min; 714 break;
699 clock.p1 <= limit->p1.max; clock.p1++) { 715 for (clock.n = limit->n.min;
716 clock.n <= limit->n.max; clock.n++) {
700 int this_err; 717 int this_err;
701 718
702 intel_clock(dev, refclk, &clock); 719 intel_clock(dev, refclk, &clock);
@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
717 return (err != target); 734 return (err != target);
718} 735}
719 736
737
738static bool
739intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
740 int target, int refclk, intel_clock_t *best_clock)
741
742{
743 struct drm_device *dev = crtc->dev;
744 intel_clock_t clock;
745 int err = target;
746 bool found = false;
747
748 memcpy(&clock, best_clock, sizeof(intel_clock_t));
749
750 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
751 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
752 /* m1 is always 0 in IGD */
753 if (clock.m2 >= clock.m1 && !IS_IGD(dev))
754 break;
755 for (clock.n = limit->n.min; clock.n <= limit->n.max;
756 clock.n++) {
757 int this_err;
758
759 intel_clock(dev, refclk, &clock);
760
761 if (!intel_PLL_is_valid(crtc, &clock))
762 continue;
763
764 this_err = abs(clock.dot - target);
765 if (this_err < err) {
766 *best_clock = clock;
767 err = this_err;
768 found = true;
769 }
770 }
771 }
772 }
773
774 return found;
775}
776
720static bool 777static bool
721intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 778intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
722 int target, int refclk, intel_clock_t *best_clock) 779 int target, int refclk, intel_clock_t *best_clock)
@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
747 max_n = limit->n.max; 804 max_n = limit->n.max;
748 /* based on hardware requriment prefer smaller n to precision */ 805 /* based on hardware requriment prefer smaller n to precision */
749 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { 806 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
750 /* based on hardware requirment prefere larger m1,m2, p1 */ 807 /* based on hardware requirment prefere larger m1,m2 */
751 for (clock.m1 = limit->m1.max; 808 for (clock.m1 = limit->m1.max;
752 clock.m1 >= limit->m1.min; clock.m1--) { 809 clock.m1 >= limit->m1.min; clock.m1--) {
753 for (clock.m2 = limit->m2.max; 810 for (clock.m2 = limit->m2.max;
@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
832 889
833 memset(best_clock, 0, sizeof(*best_clock)); 890 memset(best_clock, 0, sizeof(*best_clock));
834 max_n = limit->n.max; 891 max_n = limit->n.max;
835 /* based on hardware requriment prefer smaller n to precision */ 892 for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
836 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { 893 /* based on hardware requriment prefer smaller n to precision */
837 /* based on hardware requirment prefere larger m1,m2, p1 */ 894 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
838 for (clock.m1 = limit->m1.max; 895 /* based on hardware requirment prefere larger m1,m2 */
839 clock.m1 >= limit->m1.min; clock.m1--) { 896 for (clock.m1 = limit->m1.max;
840 for (clock.m2 = limit->m2.max; 897 clock.m1 >= limit->m1.min; clock.m1--) {
841 clock.m2 >= limit->m2.min; clock.m2--) { 898 for (clock.m2 = limit->m2.max;
842 for (clock.p1 = limit->p1.max; 899 clock.m2 >= limit->m2.min; clock.m2--) {
843 clock.p1 >= limit->p1.min; clock.p1--) {
844 int this_err; 900 int this_err;
845 901
846 intel_clock(dev, refclk, &clock); 902 intel_clock(dev, refclk, &clock);
@@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1008 dspcntr &= ~DISPPLANE_TILED; 1064 dspcntr &= ~DISPPLANE_TILED;
1009 } 1065 }
1010 1066
1067 if (IS_IGDNG(dev))
1068 /* must disable */
1069 dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
1070
1011 I915_WRITE(dspcntr_reg, dspcntr); 1071 I915_WRITE(dspcntr_reg, dspcntr);
1012 1072
1013 Start = obj_priv->gtt_offset; 1073 Start = obj_priv->gtt_offset;
@@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1030 1090
1031 if (old_fb) { 1091 if (old_fb) {
1032 intel_fb = to_intel_framebuffer(old_fb); 1092 intel_fb = to_intel_framebuffer(old_fb);
1093 obj_priv = intel_fb->obj->driver_private;
1033 i915_gem_object_unpin(intel_fb->obj); 1094 i915_gem_object_unpin(intel_fb->obj);
1034 } 1095 }
1096 intel_increase_pllclock(crtc, true);
1097
1035 mutex_unlock(&dev->struct_mutex); 1098 mutex_unlock(&dev->struct_mutex);
1036 1099
1037 if (!dev->primary->master) 1100 if (!dev->primary->master)
@@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
1581 else 1644 else
1582 i9xx_crtc_dpms(crtc, mode); 1645 i9xx_crtc_dpms(crtc, mode);
1583 1646
1647 intel_crtc->dpms_mode = mode;
1648
1584 if (!dev->primary->master) 1649 if (!dev->primary->master)
1585 return; 1650 return;
1586 1651
@@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
1603 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); 1668 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
1604 break; 1669 break;
1605 } 1670 }
1606
1607 intel_crtc->dpms_mode = mode;
1608} 1671}
1609 1672
1610static void intel_crtc_prepare (struct drm_crtc *crtc) 1673static void intel_crtc_prepare (struct drm_crtc *crtc)
@@ -2054,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane)
2054 return size; 2117 return size;
2055} 2118}
2056 2119
2120static void g4x_update_wm(struct drm_device *dev)
2121{
2122 struct drm_i915_private *dev_priv = dev->dev_private;
2123 u32 fw_blc_self = I915_READ(FW_BLC_SELF);
2124
2125 if (i915_powersave)
2126 fw_blc_self |= FW_BLC_SELF_EN;
2127 else
2128 fw_blc_self &= ~FW_BLC_SELF_EN;
2129 I915_WRITE(FW_BLC_SELF, fw_blc_self);
2130}
2131
2057static void i965_update_wm(struct drm_device *dev) 2132static void i965_update_wm(struct drm_device *dev)
2058{ 2133{
2059 struct drm_i915_private *dev_priv = dev->dev_private; 2134 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2105,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
2105 cwm = 2; 2180 cwm = 2;
2106 2181
2107 /* Calc sr entries for one plane configs */ 2182 /* Calc sr entries for one plane configs */
2108 if (sr_hdisplay && (!planea_clock || !planeb_clock)) { 2183 if (HAS_FW_BLC(dev) && sr_hdisplay &&
2184 (!planea_clock || !planeb_clock)) {
2109 /* self-refresh has much higher latency */ 2185 /* self-refresh has much higher latency */
2110 const static int sr_latency_ns = 6000; 2186 const static int sr_latency_ns = 6000;
2111 2187
@@ -2120,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
2120 srwm = total_size - sr_entries; 2196 srwm = total_size - sr_entries;
2121 if (srwm < 0) 2197 if (srwm < 0)
2122 srwm = 1; 2198 srwm = 1;
2123 if (IS_I9XX(dev)) 2199 I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
2124 I915_WRITE(FW_BLC_SELF, (srwm & 0x3f));
2125 } 2200 }
2126 2201
2127 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", 2202 DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
@@ -2195,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev)
2195 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; 2270 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
2196 int enabled = 0, pixel_size = 0; 2271 int enabled = 0, pixel_size = 0;
2197 2272
2198 if (DSPARB_HWCONTROL(dev))
2199 return;
2200
2201 /* Get the clock config from both planes */ 2273 /* Get the clock config from both planes */
2202 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 2274 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2203 intel_crtc = to_intel_crtc(crtc); 2275 intel_crtc = to_intel_crtc(crtc);
@@ -2230,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev)
2230 else if (IS_IGD(dev)) 2302 else if (IS_IGD(dev))
2231 igd_disable_cxsr(dev); 2303 igd_disable_cxsr(dev);
2232 2304
2233 if (IS_I965G(dev)) 2305 if (IS_G4X(dev))
2306 g4x_update_wm(dev);
2307 else if (IS_I965G(dev))
2234 i965_update_wm(dev); 2308 i965_update_wm(dev);
2235 else if (IS_I9XX(dev) || IS_MOBILE(dev)) 2309 else if (IS_I9XX(dev) || IS_MOBILE(dev))
2236 i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, 2310 i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay,
@@ -2264,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2264 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; 2338 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
2265 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; 2339 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
2266 int refclk, num_outputs = 0; 2340 int refclk, num_outputs = 0;
2267 intel_clock_t clock; 2341 intel_clock_t clock, reduced_clock;
2268 u32 dpll = 0, fp = 0, dspcntr, pipeconf; 2342 u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
2269 bool ok, is_sdvo = false, is_dvo = false; 2343 bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
2270 bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; 2344 bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
2271 bool is_edp = false; 2345 bool is_edp = false;
2272 struct drm_mode_config *mode_config = &dev->mode_config; 2346 struct drm_mode_config *mode_config = &dev->mode_config;
@@ -2349,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2349 return -EINVAL; 2423 return -EINVAL;
2350 } 2424 }
2351 2425
2426 if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
2427 memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
2428 has_reduced_clock = limit->find_reduced_pll(limit, crtc,
2429 (adjusted_mode->clock*3/4),
2430 refclk,
2431 &reduced_clock);
2432 }
2433
2352 /* SDVO TV has fixed PLL values depend on its clock range, 2434 /* SDVO TV has fixed PLL values depend on its clock range,
2353 this mirrors vbios setting. */ 2435 this mirrors vbios setting. */
2354 if (is_sdvo && is_tv) { 2436 if (is_sdvo && is_tv) {
@@ -2394,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2394 link_bw, &m_n); 2476 link_bw, &m_n);
2395 } 2477 }
2396 2478
2397 if (IS_IGD(dev)) 2479 if (IS_IGD(dev)) {
2398 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 2480 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
2399 else 2481 if (has_reduced_clock)
2482 fp2 = (1 << reduced_clock.n) << 16 |
2483 reduced_clock.m1 << 8 | reduced_clock.m2;
2484 } else {
2400 fp = clock.n << 16 | clock.m1 << 8 | clock.m2; 2485 fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
2486 if (has_reduced_clock)
2487 fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
2488 reduced_clock.m2;
2489 }
2401 2490
2402 if (!IS_IGDNG(dev)) 2491 if (!IS_IGDNG(dev))
2403 dpll = DPLL_VGA_MODE_DIS; 2492 dpll = DPLL_VGA_MODE_DIS;
@@ -2426,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2426 /* also FPA1 */ 2515 /* also FPA1 */
2427 if (IS_IGDNG(dev)) 2516 if (IS_IGDNG(dev))
2428 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; 2517 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
2518 if (IS_G4X(dev) && has_reduced_clock)
2519 dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
2429 } 2520 }
2430 switch (clock.p2) { 2521 switch (clock.p2) {
2431 case 5: 2522 case 5:
@@ -2573,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2573 udelay(150); 2664 udelay(150);
2574 } 2665 }
2575 2666
2667 if (is_lvds && has_reduced_clock && i915_powersave) {
2668 I915_WRITE(fp_reg + 4, fp2);
2669 intel_crtc->lowfreq_avail = true;
2670 if (HAS_PIPE_CXSR(dev)) {
2671 DRM_DEBUG("enabling CxSR downclocking\n");
2672 pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
2673 }
2674 } else {
2675 I915_WRITE(fp_reg + 4, fp);
2676 intel_crtc->lowfreq_avail = false;
2677 if (HAS_PIPE_CXSR(dev)) {
2678 DRM_DEBUG("disabling CxSR downclocking\n");
2679 pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
2680 }
2681 }
2682
2576 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | 2683 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
2577 ((adjusted_mode->crtc_htotal - 1) << 16)); 2684 ((adjusted_mode->crtc_htotal - 1) << 16));
2578 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | 2685 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
@@ -2616,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2616 2723
2617 intel_wait_for_vblank(dev); 2724 intel_wait_for_vblank(dev);
2618 2725
2726 if (IS_IGDNG(dev)) {
2727 /* enable address swizzle for tiling buffer */
2728 temp = I915_READ(DISP_ARB_CTL);
2729 I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
2730 }
2731
2619 I915_WRITE(dspcntr_reg, dspcntr); 2732 I915_WRITE(dspcntr_reg, dspcntr);
2620 2733
2621 /* Flush the plane changes */ 2734 /* Flush the plane changes */
@@ -2769,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
2769 struct drm_device *dev = crtc->dev; 2882 struct drm_device *dev = crtc->dev;
2770 struct drm_i915_private *dev_priv = dev->dev_private; 2883 struct drm_i915_private *dev_priv = dev->dev_private;
2771 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2884 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2885 struct intel_framebuffer *intel_fb;
2772 int pipe = intel_crtc->pipe; 2886 int pipe = intel_crtc->pipe;
2773 uint32_t temp = 0; 2887 uint32_t temp = 0;
2774 uint32_t adder; 2888 uint32_t adder;
2775 2889
2890 if (crtc->fb) {
2891 intel_fb = to_intel_framebuffer(crtc->fb);
2892 intel_mark_busy(dev, intel_fb->obj);
2893 }
2894
2776 if (x < 0) { 2895 if (x < 0) {
2777 temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; 2896 temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
2778 x = -x; 2897 x = -x;
@@ -3070,12 +3189,319 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
3070 return mode; 3189 return mode;
3071} 3190}
3072 3191
3192#define GPU_IDLE_TIMEOUT 500 /* ms */
3193
3194/* When this timer fires, we've been idle for awhile */
3195static void intel_gpu_idle_timer(unsigned long arg)
3196{
3197 struct drm_device *dev = (struct drm_device *)arg;
3198 drm_i915_private_t *dev_priv = dev->dev_private;
3199
3200 DRM_DEBUG("idle timer fired, downclocking\n");
3201
3202 dev_priv->busy = false;
3203
3204 queue_work(dev_priv->wq, &dev_priv->idle_work);
3205}
3206
3207void intel_increase_renderclock(struct drm_device *dev, bool schedule)
3208{
3209 drm_i915_private_t *dev_priv = dev->dev_private;
3210
3211 if (IS_IGDNG(dev))
3212 return;
3213
3214 if (!dev_priv->render_reclock_avail) {
3215 DRM_DEBUG("not reclocking render clock\n");
3216 return;
3217 }
3218
3219 /* Restore render clock frequency to original value */
3220 if (IS_G4X(dev) || IS_I9XX(dev))
3221 pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
3222 else if (IS_I85X(dev))
3223 pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
3224 DRM_DEBUG("increasing render clock frequency\n");
3225
3226 /* Schedule downclock */
3227 if (schedule)
3228 mod_timer(&dev_priv->idle_timer, jiffies +
3229 msecs_to_jiffies(GPU_IDLE_TIMEOUT));
3230}
3231
3232void intel_decrease_renderclock(struct drm_device *dev)
3233{
3234 drm_i915_private_t *dev_priv = dev->dev_private;
3235
3236 if (IS_IGDNG(dev))
3237 return;
3238
3239 if (!dev_priv->render_reclock_avail) {
3240 DRM_DEBUG("not reclocking render clock\n");
3241 return;
3242 }
3243
3244 if (IS_G4X(dev)) {
3245 u16 gcfgc;
3246
3247 /* Adjust render clock... */
3248 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
3249
3250 /* Down to minimum... */
3251 gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
3252 gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
3253
3254 pci_write_config_word(dev->pdev, GCFGC, gcfgc);
3255 } else if (IS_I965G(dev)) {
3256 u16 gcfgc;
3257
3258 /* Adjust render clock... */
3259 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
3260
3261 /* Down to minimum... */
3262 gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
3263 gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
3264
3265 pci_write_config_word(dev->pdev, GCFGC, gcfgc);
3266 } else if (IS_I945G(dev) || IS_I945GM(dev)) {
3267 u16 gcfgc;
3268
3269 /* Adjust render clock... */
3270 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
3271
3272 /* Down to minimum... */
3273 gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
3274 gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
3275
3276 pci_write_config_word(dev->pdev, GCFGC, gcfgc);
3277 } else if (IS_I915G(dev)) {
3278 u16 gcfgc;
3279
3280 /* Adjust render clock... */
3281 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
3282
3283 /* Down to minimum... */
3284 gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
3285 gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
3286
3287 pci_write_config_word(dev->pdev, GCFGC, gcfgc);
3288 } else if (IS_I85X(dev)) {
3289 u16 hpllcc;
3290
3291 /* Adjust render clock... */
3292 pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
3293
3294 /* Up to maximum... */
3295 hpllcc &= ~GC_CLOCK_CONTROL_MASK;
3296 hpllcc |= GC_CLOCK_133_200;
3297
3298 pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
3299 }
3300 DRM_DEBUG("decreasing render clock frequency\n");
3301}
3302
3303/* Note that no increase function is needed for this - increase_renderclock()
3304 * will also rewrite these bits
3305 */
3306void intel_decrease_displayclock(struct drm_device *dev)
3307{
3308 if (IS_IGDNG(dev))
3309 return;
3310
3311 if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
3312 IS_I915GM(dev)) {
3313 u16 gcfgc;
3314
3315 /* Adjust render clock... */
3316 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
3317
3318 /* Down to minimum... */
3319 gcfgc &= ~0xf0;
3320 gcfgc |= 0x80;
3321
3322 pci_write_config_word(dev->pdev, GCFGC, gcfgc);
3323 }
3324}
3325
3326#define CRTC_IDLE_TIMEOUT 1000 /* ms */
3327
3328static void intel_crtc_idle_timer(unsigned long arg)
3329{
3330 struct intel_crtc *intel_crtc = (struct intel_crtc *)arg;
3331 struct drm_crtc *crtc = &intel_crtc->base;
3332 drm_i915_private_t *dev_priv = crtc->dev->dev_private;
3333
3334 DRM_DEBUG("idle timer fired, downclocking\n");
3335
3336 intel_crtc->busy = false;
3337
3338 queue_work(dev_priv->wq, &dev_priv->idle_work);
3339}
3340
3341static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
3342{
3343 struct drm_device *dev = crtc->dev;
3344 drm_i915_private_t *dev_priv = dev->dev_private;
3345 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3346 int pipe = intel_crtc->pipe;
3347 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
3348 int dpll = I915_READ(dpll_reg);
3349
3350 if (IS_IGDNG(dev))
3351 return;
3352
3353 if (!dev_priv->lvds_downclock_avail)
3354 return;
3355
3356 if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
3357 DRM_DEBUG("upclocking LVDS\n");
3358
3359 /* Unlock panel regs */
3360 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
3361
3362 dpll &= ~DISPLAY_RATE_SELECT_FPA1;
3363 I915_WRITE(dpll_reg, dpll);
3364 dpll = I915_READ(dpll_reg);
3365 intel_wait_for_vblank(dev);
3366 dpll = I915_READ(dpll_reg);
3367 if (dpll & DISPLAY_RATE_SELECT_FPA1)
3368 DRM_DEBUG("failed to upclock LVDS!\n");
3369
3370 /* ...and lock them again */
3371 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
3372 }
3373
3374 /* Schedule downclock */
3375 if (schedule)
3376 mod_timer(&intel_crtc->idle_timer, jiffies +
3377 msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
3378}
3379
3380static void intel_decrease_pllclock(struct drm_crtc *crtc)
3381{
3382 struct drm_device *dev = crtc->dev;
3383 drm_i915_private_t *dev_priv = dev->dev_private;
3384 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3385 int pipe = intel_crtc->pipe;
3386 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
3387 int dpll = I915_READ(dpll_reg);
3388
3389 if (IS_IGDNG(dev))
3390 return;
3391
3392 if (!dev_priv->lvds_downclock_avail)
3393 return;
3394
3395 /*
3396 * Since this is called by a timer, we should never get here in
3397 * the manual case.
3398 */
3399 if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
3400 DRM_DEBUG("downclocking LVDS\n");
3401
3402 /* Unlock panel regs */
3403 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
3404
3405 dpll |= DISPLAY_RATE_SELECT_FPA1;
3406 I915_WRITE(dpll_reg, dpll);
3407 dpll = I915_READ(dpll_reg);
3408 intel_wait_for_vblank(dev);
3409 dpll = I915_READ(dpll_reg);
3410 if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
3411 DRM_DEBUG("failed to downclock LVDS!\n");
3412
3413 /* ...and lock them again */
3414 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
3415 }
3416
3417}
3418
3419/**
3420 * intel_idle_update - adjust clocks for idleness
3421 * @work: work struct
3422 *
3423 * Either the GPU or display (or both) went idle. Check the busy status
3424 * here and adjust the CRTC and GPU clocks as necessary.
3425 */
3426static void intel_idle_update(struct work_struct *work)
3427{
3428 drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
3429 idle_work);
3430 struct drm_device *dev = dev_priv->dev;
3431 struct drm_crtc *crtc;
3432 struct intel_crtc *intel_crtc;
3433
3434 if (!i915_powersave)
3435 return;
3436
3437 mutex_lock(&dev->struct_mutex);
3438
3439 /* GPU isn't processing, downclock it. */
3440 if (!dev_priv->busy) {
3441 intel_decrease_renderclock(dev);
3442 intel_decrease_displayclock(dev);
3443 }
3444
3445 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
3446 /* Skip inactive CRTCs */
3447 if (!crtc->fb)
3448 continue;
3449
3450 intel_crtc = to_intel_crtc(crtc);
3451 if (!intel_crtc->busy)
3452 intel_decrease_pllclock(crtc);
3453 }
3454
3455 mutex_unlock(&dev->struct_mutex);
3456}
3457
3458/**
3459 * intel_mark_busy - mark the GPU and possibly the display busy
3460 * @dev: drm device
3461 * @obj: object we're operating on
3462 *
3463 * Callers can use this function to indicate that the GPU is busy processing
3464 * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout
3465 * buffer), we'll also mark the display as busy, so we know to increase its
3466 * clock frequency.
3467 */
3468void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
3469{
3470 drm_i915_private_t *dev_priv = dev->dev_private;
3471 struct drm_crtc *crtc = NULL;
3472 struct intel_framebuffer *intel_fb;
3473 struct intel_crtc *intel_crtc;
3474
3475 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3476 return;
3477
3478 dev_priv->busy = true;
3479 intel_increase_renderclock(dev, true);
3480
3481 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
3482 if (!crtc->fb)
3483 continue;
3484
3485 intel_crtc = to_intel_crtc(crtc);
3486 intel_fb = to_intel_framebuffer(crtc->fb);
3487 if (intel_fb->obj == obj) {
3488 if (!intel_crtc->busy) {
3489 /* Non-busy -> busy, upclock */
3490 intel_increase_pllclock(crtc, true);
3491 intel_crtc->busy = true;
3492 } else {
3493 /* Busy -> busy, put off timer */
3494 mod_timer(&intel_crtc->idle_timer, jiffies +
3495 msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
3496 }
3497 }
3498 }
3499}
3500
3073static void intel_crtc_destroy(struct drm_crtc *crtc) 3501static void intel_crtc_destroy(struct drm_crtc *crtc)
3074{ 3502{
3075 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 3503 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3076 3504
3077 if (intel_crtc->mode_set.mode)
3078 drm_mode_destroy(crtc->dev, intel_crtc->mode_set.mode);
3079 drm_crtc_cleanup(crtc); 3505 drm_crtc_cleanup(crtc);
3080 kfree(intel_crtc); 3506 kfree(intel_crtc);
3081} 3507}
@@ -3122,15 +3548,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
3122 intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; 3548 intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
3123 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); 3549 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
3124 3550
3125 intel_crtc->mode_set.crtc = &intel_crtc->base; 3551 intel_crtc->busy = false;
3126 intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
3127 intel_crtc->mode_set.num_connectors = 0;
3128
3129 if (i915_fbpercrtc) {
3130 3552
3131 3553 setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
3132 3554 (unsigned long)intel_crtc);
3133 }
3134} 3555}
3135 3556
3136int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 3557int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -3138,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
3138{ 3559{
3139 drm_i915_private_t *dev_priv = dev->dev_private; 3560 drm_i915_private_t *dev_priv = dev->dev_private;
3140 struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; 3561 struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
3141 struct drm_crtc *crtc = NULL; 3562 struct drm_mode_object *drmmode_obj;
3142 int pipe = -1; 3563 struct intel_crtc *crtc;
3143 3564
3144 if (!dev_priv) { 3565 if (!dev_priv) {
3145 DRM_ERROR("called with no initialization\n"); 3566 DRM_ERROR("called with no initialization\n");
3146 return -EINVAL; 3567 return -EINVAL;
3147 } 3568 }
3148 3569
3149 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 3570 drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
3150 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 3571 DRM_MODE_OBJECT_CRTC);
3151 if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
3152 pipe = intel_crtc->pipe;
3153 break;
3154 }
3155 }
3156 3572
3157 if (pipe == -1) { 3573 if (!drmmode_obj) {
3158 DRM_ERROR("no such CRTC id\n"); 3574 DRM_ERROR("no such CRTC id\n");
3159 return -EINVAL; 3575 return -EINVAL;
3160 } 3576 }
3161 3577
3162 pipe_from_crtc_id->pipe = pipe; 3578 crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
3579 pipe_from_crtc_id->pipe = crtc->pipe;
3163 3580
3164 return 0; 3581 return 0;
3165} 3582}
3166 3583
3167struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) 3584struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
@@ -3362,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
3362 .fb_changed = intelfb_probe, 3779 .fb_changed = intelfb_probe,
3363}; 3780};
3364 3781
3782void intel_init_clock_gating(struct drm_device *dev)
3783{
3784 struct drm_i915_private *dev_priv = dev->dev_private;
3785
3786 /*
3787 * Disable clock gating reported to work incorrectly according to the
3788 * specs, but enable as much else as we can.
3789 */
3790 if (IS_G4X(dev)) {
3791 uint32_t dspclk_gate;
3792 I915_WRITE(RENCLK_GATE_D1, 0);
3793 I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
3794 GS_UNIT_CLOCK_GATE_DISABLE |
3795 CL_UNIT_CLOCK_GATE_DISABLE);
3796 I915_WRITE(RAMCLK_GATE_D, 0);
3797 dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
3798 OVRUNIT_CLOCK_GATE_DISABLE |
3799 OVCUNIT_CLOCK_GATE_DISABLE;
3800 if (IS_GM45(dev))
3801 dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
3802 I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
3803 } else if (IS_I965GM(dev)) {
3804 I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
3805 I915_WRITE(RENCLK_GATE_D2, 0);
3806 I915_WRITE(DSPCLK_GATE_D, 0);
3807 I915_WRITE(RAMCLK_GATE_D, 0);
3808 I915_WRITE16(DEUC, 0);
3809 } else if (IS_I965G(dev)) {
3810 I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
3811 I965_RCC_CLOCK_GATE_DISABLE |
3812 I965_RCPB_CLOCK_GATE_DISABLE |
3813 I965_ISC_CLOCK_GATE_DISABLE |
3814 I965_FBC_CLOCK_GATE_DISABLE);
3815 I915_WRITE(RENCLK_GATE_D2, 0);
3816 } else if (IS_I9XX(dev)) {
3817 u32 dstate = I915_READ(D_STATE);
3818
3819 dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
3820 DSTATE_DOT_CLOCK_GATING;
3821 I915_WRITE(D_STATE, dstate);
3822 } else if (IS_I855(dev) || IS_I865G(dev)) {
3823 I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
3824 } else if (IS_I830(dev)) {
3825 I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
3826 }
3827}
3828
3365void intel_modeset_init(struct drm_device *dev) 3829void intel_modeset_init(struct drm_device *dev)
3366{ 3830{
3831 struct drm_i915_private *dev_priv = dev->dev_private;
3367 int num_pipe; 3832 int num_pipe;
3368 int i; 3833 int i;
3369 3834
@@ -3398,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev)
3398 DRM_DEBUG("%d display pipe%s available.\n", 3863 DRM_DEBUG("%d display pipe%s available.\n",
3399 num_pipe, num_pipe > 1 ? "s" : ""); 3864 num_pipe, num_pipe > 1 ? "s" : "");
3400 3865
3866 if (IS_I85X(dev))
3867 pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock);
3868 else if (IS_I9XX(dev) || IS_G4X(dev))
3869 pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock);
3870
3401 for (i = 0; i < num_pipe; i++) { 3871 for (i = 0; i < num_pipe; i++) {
3402 intel_crtc_init(dev, i); 3872 intel_crtc_init(dev, i);
3403 } 3873 }
3404 3874
3405 intel_setup_outputs(dev); 3875 intel_setup_outputs(dev);
3876
3877 intel_init_clock_gating(dev);
3878
3879 INIT_WORK(&dev_priv->idle_work, intel_idle_update);
3880 setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
3881 (unsigned long)dev);
3406} 3882}
3407 3883
3408void intel_modeset_cleanup(struct drm_device *dev) 3884void intel_modeset_cleanup(struct drm_device *dev)
3409{ 3885{
3886 struct drm_i915_private *dev_priv = dev->dev_private;
3887 struct drm_crtc *crtc;
3888 struct intel_crtc *intel_crtc;
3889
3890 mutex_lock(&dev->struct_mutex);
3891
3892 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
3893 /* Skip inactive CRTCs */
3894 if (!crtc->fb)
3895 continue;
3896
3897 intel_crtc = to_intel_crtc(crtc);
3898 intel_increase_pllclock(crtc, false);
3899 del_timer_sync(&intel_crtc->idle_timer);
3900 }
3901
3902 intel_increase_renderclock(dev, false);
3903 del_timer_sync(&dev_priv->idle_timer);
3904
3905 mutex_unlock(&dev->struct_mutex);
3906
3410 drm_mode_config_cleanup(dev); 3907 drm_mode_config_cleanup(dev);
3411} 3908}
3412 3909
@@ -3420,3 +3917,20 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
3420 3917
3421 return &intel_output->enc; 3918 return &intel_output->enc;
3422} 3919}
3920
3921/*
3922 * set vga decode state - true == enable VGA decode
3923 */
3924int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
3925{
3926 struct drm_i915_private *dev_priv = dev->dev_private;
3927 u16 gmch_ctrl;
3928
3929 pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
3930 if (state)
3931 gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
3932 else
3933 gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
3934 pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
3935 return 0;
3936}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 26a6227c15fe..3ebbbabfe59b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -117,9 +117,9 @@ struct intel_crtc {
117 uint32_t cursor_addr; 117 uint32_t cursor_addr;
118 u8 lut_r[256], lut_g[256], lut_b[256]; 118 u8 lut_r[256], lut_g[256], lut_b[256];
119 int dpms_mode; 119 int dpms_mode;
120 struct intel_framebuffer *fbdev_fb; 120 bool busy; /* is scanout buffer being updated frequently? */
121 /* a mode_set for fbdev users on this crtc */ 121 struct timer_list idle_timer;
122 struct drm_mode_set mode_set; 122 bool lowfreq_avail;
123}; 123};
124 124
125#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) 125#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -138,6 +138,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
138extern bool intel_sdvo_init(struct drm_device *dev, int output_device); 138extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
139extern void intel_dvo_init(struct drm_device *dev); 139extern void intel_dvo_init(struct drm_device *dev);
140extern void intel_tv_init(struct drm_device *dev); 140extern void intel_tv_init(struct drm_device *dev);
141extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
141extern void intel_lvds_init(struct drm_device *dev); 142extern void intel_lvds_init(struct drm_device *dev);
142extern void intel_dp_init(struct drm_device *dev, int dp_reg); 143extern void intel_dp_init(struct drm_device *dev, int dp_reg);
143void 144void
@@ -178,4 +179,5 @@ extern int intel_framebuffer_create(struct drm_device *dev,
178 struct drm_mode_fb_cmd *mode_cmd, 179 struct drm_mode_fb_cmd *mode_cmd,
179 struct drm_framebuffer **fb, 180 struct drm_framebuffer **fb,
180 struct drm_gem_object *obj); 181 struct drm_gem_object *obj);
182
181#endif /* __INTEL_DRV_H__ */ 183#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 1d30802e773e..7ba4a232a97f 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -39,339 +39,34 @@
39#include "drmP.h" 39#include "drmP.h"
40#include "drm.h" 40#include "drm.h"
41#include "drm_crtc.h" 41#include "drm_crtc.h"
42#include "drm_fb_helper.h"
42#include "intel_drv.h" 43#include "intel_drv.h"
43#include "i915_drm.h" 44#include "i915_drm.h"
44#include "i915_drv.h" 45#include "i915_drv.h"
45 46
46struct intelfb_par { 47struct intelfb_par {
47 struct drm_device *dev; 48 struct drm_fb_helper helper;
48 struct drm_display_mode *our_mode;
49 struct intel_framebuffer *intel_fb; 49 struct intel_framebuffer *intel_fb;
50 int crtc_count; 50 struct drm_display_mode *our_mode;
51 /* crtc currently bound to this */
52 uint32_t crtc_ids[2];
53}; 51};
54 52
55static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
56 unsigned blue, unsigned transp,
57 struct fb_info *info)
58{
59 struct intelfb_par *par = info->par;
60 struct drm_device *dev = par->dev;
61 struct drm_crtc *crtc;
62 int i;
63
64 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
65 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
66 struct drm_mode_set *modeset = &intel_crtc->mode_set;
67 struct drm_framebuffer *fb = modeset->fb;
68
69 for (i = 0; i < par->crtc_count; i++)
70 if (crtc->base.id == par->crtc_ids[i])
71 break;
72
73 if (i == par->crtc_count)
74 continue;
75
76
77 if (regno > 255)
78 return 1;
79
80 if (fb->depth == 8) {
81 intel_crtc_fb_gamma_set(crtc, red, green, blue, regno);
82 return 0;
83 }
84
85 if (regno < 16) {
86 switch (fb->depth) {
87 case 15:
88 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
89 ((green & 0xf800) >> 6) |
90 ((blue & 0xf800) >> 11);
91 break;
92 case 16:
93 fb->pseudo_palette[regno] = (red & 0xf800) |
94 ((green & 0xfc00) >> 5) |
95 ((blue & 0xf800) >> 11);
96 break;
97 case 24:
98 case 32:
99 fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
100 (green & 0xff00) |
101 ((blue & 0xff00) >> 8);
102 break;
103 }
104 }
105 }
106 return 0;
107}
108
109static int intelfb_check_var(struct fb_var_screeninfo *var,
110 struct fb_info *info)
111{
112 struct intelfb_par *par = info->par;
113 struct intel_framebuffer *intel_fb = par->intel_fb;
114 struct drm_framebuffer *fb = &intel_fb->base;
115 int depth;
116
117 if (var->pixclock == -1 || !var->pixclock)
118 return -EINVAL;
119
120 /* Need to resize the fb object !!! */
121 if (var->xres > fb->width || var->yres > fb->height) {
122 DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height);
123 DRM_ERROR("Need resizing code.\n");
124 return -EINVAL;
125 }
126
127 switch (var->bits_per_pixel) {
128 case 16:
129 depth = (var->green.length == 6) ? 16 : 15;
130 break;
131 case 32:
132 depth = (var->transp.length > 0) ? 32 : 24;
133 break;
134 default:
135 depth = var->bits_per_pixel;
136 break;
137 }
138
139 switch (depth) {
140 case 8:
141 var->red.offset = 0;
142 var->green.offset = 0;
143 var->blue.offset = 0;
144 var->red.length = 8;
145 var->green.length = 8;
146 var->blue.length = 8;
147 var->transp.length = 0;
148 var->transp.offset = 0;
149 break;
150 case 15:
151 var->red.offset = 10;
152 var->green.offset = 5;
153 var->blue.offset = 0;
154 var->red.length = 5;
155 var->green.length = 5;
156 var->blue.length = 5;
157 var->transp.length = 1;
158 var->transp.offset = 15;
159 break;
160 case 16:
161 var->red.offset = 11;
162 var->green.offset = 5;
163 var->blue.offset = 0;
164 var->red.length = 5;
165 var->green.length = 6;
166 var->blue.length = 5;
167 var->transp.length = 0;
168 var->transp.offset = 0;
169 break;
170 case 24:
171 var->red.offset = 16;
172 var->green.offset = 8;
173 var->blue.offset = 0;
174 var->red.length = 8;
175 var->green.length = 8;
176 var->blue.length = 8;
177 var->transp.length = 0;
178 var->transp.offset = 0;
179 break;
180 case 32:
181 var->red.offset = 16;
182 var->green.offset = 8;
183 var->blue.offset = 0;
184 var->red.length = 8;
185 var->green.length = 8;
186 var->blue.length = 8;
187 var->transp.length = 8;
188 var->transp.offset = 24;
189 break;
190 default:
191 return -EINVAL;
192 }
193
194 return 0;
195}
196
197/* this will let fbcon do the mode init */
198/* FIXME: take mode config lock? */
199static int intelfb_set_par(struct fb_info *info)
200{
201 struct intelfb_par *par = info->par;
202 struct drm_device *dev = par->dev;
203 struct fb_var_screeninfo *var = &info->var;
204 int i;
205
206 DRM_DEBUG("%d %d\n", var->xres, var->pixclock);
207
208 if (var->pixclock != -1) {
209
210 DRM_ERROR("PIXEL CLOCK SET\n");
211 return -EINVAL;
212 } else {
213 struct drm_crtc *crtc;
214 int ret;
215
216 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
217 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
218
219 for (i = 0; i < par->crtc_count; i++)
220 if (crtc->base.id == par->crtc_ids[i])
221 break;
222
223 if (i == par->crtc_count)
224 continue;
225
226 if (crtc->fb == intel_crtc->mode_set.fb) {
227 mutex_lock(&dev->mode_config.mutex);
228 ret = crtc->funcs->set_config(&intel_crtc->mode_set);
229 mutex_unlock(&dev->mode_config.mutex);
230 if (ret)
231 return ret;
232 }
233 }
234 return 0;
235 }
236}
237
238static int intelfb_pan_display(struct fb_var_screeninfo *var,
239 struct fb_info *info)
240{
241 struct intelfb_par *par = info->par;
242 struct drm_device *dev = par->dev;
243 struct drm_mode_set *modeset;
244 struct drm_crtc *crtc;
245 struct intel_crtc *intel_crtc;
246 int ret = 0;
247 int i;
248
249 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
250 for (i = 0; i < par->crtc_count; i++)
251 if (crtc->base.id == par->crtc_ids[i])
252 break;
253
254 if (i == par->crtc_count)
255 continue;
256
257 intel_crtc = to_intel_crtc(crtc);
258 modeset = &intel_crtc->mode_set;
259
260 modeset->x = var->xoffset;
261 modeset->y = var->yoffset;
262
263 if (modeset->num_connectors) {
264 mutex_lock(&dev->mode_config.mutex);
265 ret = crtc->funcs->set_config(modeset);
266 mutex_unlock(&dev->mode_config.mutex);
267 if (!ret) {
268 info->var.xoffset = var->xoffset;
269 info->var.yoffset = var->yoffset;
270 }
271 }
272 }
273
274 return ret;
275}
276
277static void intelfb_on(struct fb_info *info)
278{
279 struct intelfb_par *par = info->par;
280 struct drm_device *dev = par->dev;
281 struct drm_crtc *crtc;
282 struct drm_encoder *encoder;
283 int i;
284
285 /*
286 * For each CRTC in this fb, find all associated encoders
287 * and turn them off, then turn off the CRTC.
288 */
289 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
290 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
291
292 for (i = 0; i < par->crtc_count; i++)
293 if (crtc->base.id == par->crtc_ids[i])
294 break;
295
296 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
297
298 /* Found a CRTC on this fb, now find encoders */
299 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
300 if (encoder->crtc == crtc) {
301 struct drm_encoder_helper_funcs *encoder_funcs;
302 encoder_funcs = encoder->helper_private;
303 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
304 }
305 }
306 }
307}
308
309static void intelfb_off(struct fb_info *info, int dpms_mode)
310{
311 struct intelfb_par *par = info->par;
312 struct drm_device *dev = par->dev;
313 struct drm_crtc *crtc;
314 struct drm_encoder *encoder;
315 int i;
316
317 /*
318 * For each CRTC in this fb, find all associated encoders
319 * and turn them off, then turn off the CRTC.
320 */
321 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
322 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
323
324 for (i = 0; i < par->crtc_count; i++)
325 if (crtc->base.id == par->crtc_ids[i])
326 break;
327
328 /* Found a CRTC on this fb, now find encoders */
329 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
330 if (encoder->crtc == crtc) {
331 struct drm_encoder_helper_funcs *encoder_funcs;
332 encoder_funcs = encoder->helper_private;
333 encoder_funcs->dpms(encoder, dpms_mode);
334 }
335 }
336 if (dpms_mode == DRM_MODE_DPMS_OFF)
337 crtc_funcs->dpms(crtc, dpms_mode);
338 }
339}
340
341static int intelfb_blank(int blank, struct fb_info *info)
342{
343 switch (blank) {
344 case FB_BLANK_UNBLANK:
345 intelfb_on(info);
346 break;
347 case FB_BLANK_NORMAL:
348 intelfb_off(info, DRM_MODE_DPMS_STANDBY);
349 break;
350 case FB_BLANK_HSYNC_SUSPEND:
351 intelfb_off(info, DRM_MODE_DPMS_STANDBY);
352 break;
353 case FB_BLANK_VSYNC_SUSPEND:
354 intelfb_off(info, DRM_MODE_DPMS_SUSPEND);
355 break;
356 case FB_BLANK_POWERDOWN:
357 intelfb_off(info, DRM_MODE_DPMS_OFF);
358 break;
359 }
360 return 0;
361}
362
363static struct fb_ops intelfb_ops = { 53static struct fb_ops intelfb_ops = {
364 .owner = THIS_MODULE, 54 .owner = THIS_MODULE,
365 .fb_check_var = intelfb_check_var, 55 .fb_check_var = drm_fb_helper_check_var,
366 .fb_set_par = intelfb_set_par, 56 .fb_set_par = drm_fb_helper_set_par,
367 .fb_setcolreg = intelfb_setcolreg, 57 .fb_setcolreg = drm_fb_helper_setcolreg,
368 .fb_fillrect = cfb_fillrect, 58 .fb_fillrect = cfb_fillrect,
369 .fb_copyarea = cfb_copyarea, 59 .fb_copyarea = cfb_copyarea,
370 .fb_imageblit = cfb_imageblit, 60 .fb_imageblit = cfb_imageblit,
371 .fb_pan_display = intelfb_pan_display, 61 .fb_pan_display = drm_fb_helper_pan_display,
372 .fb_blank = intelfb_blank, 62 .fb_blank = drm_fb_helper_blank,
373}; 63};
374 64
65static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
66 .gamma_set = intel_crtc_fb_gamma_set,
67};
68
69
375/** 70/**
376 * Curretly it is assumed that the old framebuffer is reused. 71 * Curretly it is assumed that the old framebuffer is reused.
377 * 72 *
@@ -412,25 +107,10 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
412} 107}
413EXPORT_SYMBOL(intelfb_resize); 108EXPORT_SYMBOL(intelfb_resize);
414 109
415static struct drm_mode_set kernelfb_mode;
416
417static int intelfb_panic(struct notifier_block *n, unsigned long ununsed,
418 void *panic_str)
419{
420 DRM_ERROR("panic occurred, switching back to text console\n");
421
422 intelfb_restore();
423 return 0;
424}
425
426static struct notifier_block paniced = {
427 .notifier_call = intelfb_panic,
428};
429
430static int intelfb_create(struct drm_device *dev, uint32_t fb_width, 110static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
431 uint32_t fb_height, uint32_t surface_width, 111 uint32_t fb_height, uint32_t surface_width,
432 uint32_t surface_height, 112 uint32_t surface_height,
433 struct intel_framebuffer **intel_fb_p) 113 struct drm_framebuffer **fb_p)
434{ 114{
435 struct fb_info *info; 115 struct fb_info *info;
436 struct intelfb_par *par; 116 struct intelfb_par *par;
@@ -479,7 +159,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
479 list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); 159 list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
480 160
481 intel_fb = to_intel_framebuffer(fb); 161 intel_fb = to_intel_framebuffer(fb);
482 *intel_fb_p = intel_fb; 162 *fb_p = fb;
483 163
484 info = framebuffer_alloc(sizeof(struct intelfb_par), device); 164 info = framebuffer_alloc(sizeof(struct intelfb_par), device);
485 if (!info) { 165 if (!info) {
@@ -489,21 +169,19 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
489 169
490 par = info->par; 170 par = info->par;
491 171
172 par->helper.funcs = &intel_fb_helper_funcs;
173 par->helper.dev = dev;
174 ret = drm_fb_helper_init_crtc_count(&par->helper, 2,
175 INTELFB_CONN_LIMIT);
176 if (ret)
177 goto out_unref;
178
492 strcpy(info->fix.id, "inteldrmfb"); 179 strcpy(info->fix.id, "inteldrmfb");
493 info->fix.type = FB_TYPE_PACKED_PIXELS;
494 info->fix.visual = FB_VISUAL_TRUECOLOR;
495 info->fix.type_aux = 0;
496 info->fix.xpanstep = 1; /* doing it in hw */
497 info->fix.ypanstep = 1; /* doing it in hw */
498 info->fix.ywrapstep = 0;
499 info->fix.accel = FB_ACCEL_I830;
500 info->fix.type_aux = 0;
501 180
502 info->flags = FBINFO_DEFAULT; 181 info->flags = FBINFO_DEFAULT;
503 182
504 info->fbops = &intelfb_ops; 183 info->fbops = &intelfb_ops;
505 184
506 info->fix.line_length = fb->pitch;
507 185
508 /* setup aperture base/size for vesafb takeover */ 186 /* setup aperture base/size for vesafb takeover */
509 info->aperture_base = dev->mode_config.fb_base; 187 info->aperture_base = dev->mode_config.fb_base;
@@ -527,18 +205,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
527 205
528// memset(info->screen_base, 0, size); 206// memset(info->screen_base, 0, size);
529 207
530 info->pseudo_palette = fb->pseudo_palette; 208 drm_fb_helper_fill_fix(info, fb->pitch);
531 info->var.xres_virtual = fb->width; 209 drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
532 info->var.yres_virtual = fb->height;
533 info->var.bits_per_pixel = fb->bits_per_pixel;
534 info->var.xoffset = 0;
535 info->var.yoffset = 0;
536 info->var.activate = FB_ACTIVATE_NOW;
537 info->var.height = -1;
538 info->var.width = -1;
539
540 info->var.xres = fb_width;
541 info->var.yres = fb_height;
542 210
543 /* FIXME: we really shouldn't expose mmio space at all */ 211 /* FIXME: we really shouldn't expose mmio space at all */
544 info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar); 212 info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar);
@@ -550,64 +218,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
550 info->pixmap.flags = FB_PIXMAP_SYSTEM; 218 info->pixmap.flags = FB_PIXMAP_SYSTEM;
551 info->pixmap.scan_align = 1; 219 info->pixmap.scan_align = 1;
552 220
553 switch(fb->depth) {
554 case 8:
555 info->var.red.offset = 0;
556 info->var.green.offset = 0;
557 info->var.blue.offset = 0;
558 info->var.red.length = 8; /* 8bit DAC */
559 info->var.green.length = 8;
560 info->var.blue.length = 8;
561 info->var.transp.offset = 0;
562 info->var.transp.length = 0;
563 break;
564 case 15:
565 info->var.red.offset = 10;
566 info->var.green.offset = 5;
567 info->var.blue.offset = 0;
568 info->var.red.length = 5;
569 info->var.green.length = 5;
570 info->var.blue.length = 5;
571 info->var.transp.offset = 15;
572 info->var.transp.length = 1;
573 break;
574 case 16:
575 info->var.red.offset = 11;
576 info->var.green.offset = 5;
577 info->var.blue.offset = 0;
578 info->var.red.length = 5;
579 info->var.green.length = 6;
580 info->var.blue.length = 5;
581 info->var.transp.offset = 0;
582 break;
583 case 24:
584 info->var.red.offset = 16;
585 info->var.green.offset = 8;
586 info->var.blue.offset = 0;
587 info->var.red.length = 8;
588 info->var.green.length = 8;
589 info->var.blue.length = 8;
590 info->var.transp.offset = 0;
591 info->var.transp.length = 0;
592 break;
593 case 32:
594 info->var.red.offset = 16;
595 info->var.green.offset = 8;
596 info->var.blue.offset = 0;
597 info->var.red.length = 8;
598 info->var.green.length = 8;
599 info->var.blue.length = 8;
600 info->var.transp.offset = 24;
601 info->var.transp.length = 8;
602 break;
603 default:
604 break;
605 }
606
607 fb->fbdev = info; 221 fb->fbdev = info;
608 222
609 par->intel_fb = intel_fb; 223 par->intel_fb = intel_fb;
610 par->dev = dev;
611 224
612 /* To allow resizeing without swapping buffers */ 225 /* To allow resizeing without swapping buffers */
613 DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, 226 DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
@@ -625,307 +238,12 @@ out:
625 return ret; 238 return ret;
626} 239}
627 240
628static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc)
629{
630 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
631 struct intel_framebuffer *intel_fb;
632 struct drm_framebuffer *fb;
633 struct drm_connector *connector;
634 struct fb_info *info;
635 struct intelfb_par *par;
636 struct drm_mode_set *modeset;
637 unsigned int width, height;
638 int new_fb = 0;
639 int ret, i, conn_count;
640
641 if (!drm_helper_crtc_in_use(crtc))
642 return 0;
643
644 if (!crtc->desired_mode)
645 return 0;
646
647 width = crtc->desired_mode->hdisplay;
648 height = crtc->desired_mode->vdisplay;
649
650 /* is there an fb bound to this crtc already */
651 if (!intel_crtc->mode_set.fb) {
652 ret = intelfb_create(dev, width, height, width, height, &intel_fb);
653 if (ret)
654 return -EINVAL;
655 new_fb = 1;
656 } else {
657 fb = intel_crtc->mode_set.fb;
658 intel_fb = to_intel_framebuffer(fb);
659 if ((intel_fb->base.width < width) || (intel_fb->base.height < height))
660 return -EINVAL;
661 }
662
663 info = intel_fb->base.fbdev;
664 par = info->par;
665
666 modeset = &intel_crtc->mode_set;
667 modeset->fb = &intel_fb->base;
668 conn_count = 0;
669 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
670 if (connector->encoder)
671 if (connector->encoder->crtc == modeset->crtc) {
672 modeset->connectors[conn_count] = connector;
673 conn_count++;
674 if (conn_count > INTELFB_CONN_LIMIT)
675 BUG();
676 }
677 }
678
679 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
680 modeset->connectors[i] = NULL;
681
682 par->crtc_ids[0] = crtc->base.id;
683
684 modeset->num_connectors = conn_count;
685 if (modeset->crtc->desired_mode) {
686 if (modeset->mode)
687 drm_mode_destroy(dev, modeset->mode);
688 modeset->mode = drm_mode_duplicate(dev,
689 modeset->crtc->desired_mode);
690 }
691
692 par->crtc_count = 1;
693
694 if (new_fb) {
695 info->var.pixclock = -1;
696 if (register_framebuffer(info) < 0)
697 return -EINVAL;
698 } else
699 intelfb_set_par(info);
700
701 DRM_INFO("fb%d: %s frame buffer device\n", info->node,
702 info->fix.id);
703
704 /* Switch back to kernel console on panic */
705 kernelfb_mode = *modeset;
706 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
707 DRM_DEBUG("registered panic notifier\n");
708
709 return 0;
710}
711
712static int intelfb_multi_fb_probe(struct drm_device *dev)
713{
714
715 struct drm_crtc *crtc;
716 int ret = 0;
717
718 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
719 ret = intelfb_multi_fb_probe_crtc(dev, crtc);
720 if (ret)
721 return ret;
722 }
723 return ret;
724}
725
726static int intelfb_single_fb_probe(struct drm_device *dev)
727{
728 struct drm_crtc *crtc;
729 struct drm_connector *connector;
730 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
731 unsigned int surface_width = 0, surface_height = 0;
732 int new_fb = 0;
733 int crtc_count = 0;
734 int ret, i, conn_count = 0;
735 struct intel_framebuffer *intel_fb;
736 struct fb_info *info;
737 struct intelfb_par *par;
738 struct drm_mode_set *modeset = NULL;
739
740 DRM_DEBUG("\n");
741
742 /* Get a count of crtcs now in use and new min/maxes width/heights */
743 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
744 if (!drm_helper_crtc_in_use(crtc))
745 continue;
746
747 crtc_count++;
748 if (!crtc->desired_mode)
749 continue;
750
751 /* Smallest mode determines console size... */
752 if (crtc->desired_mode->hdisplay < fb_width)
753 fb_width = crtc->desired_mode->hdisplay;
754
755 if (crtc->desired_mode->vdisplay < fb_height)
756 fb_height = crtc->desired_mode->vdisplay;
757
758 /* ... but largest for memory allocation dimensions */
759 if (crtc->desired_mode->hdisplay > surface_width)
760 surface_width = crtc->desired_mode->hdisplay;
761
762 if (crtc->desired_mode->vdisplay > surface_height)
763 surface_height = crtc->desired_mode->vdisplay;
764 }
765
766 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
767 /* hmm everyone went away - assume VGA cable just fell out
768 and will come back later. */
769 DRM_DEBUG("no CRTCs available?\n");
770 return 0;
771 }
772
773//fail
774 /* Find the fb for our new config */
775 if (list_empty(&dev->mode_config.fb_kernel_list)) {
776 DRM_DEBUG("creating new fb (console size %dx%d, "
777 "buffer size %dx%d)\n", fb_width, fb_height,
778 surface_width, surface_height);
779 ret = intelfb_create(dev, fb_width, fb_height, surface_width,
780 surface_height, &intel_fb);
781 if (ret)
782 return -EINVAL;
783 new_fb = 1;
784 } else {
785 struct drm_framebuffer *fb;
786
787 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
788 struct drm_framebuffer, filp_head);
789 intel_fb = to_intel_framebuffer(fb);
790
791 /* if someone hotplugs something bigger than we have already
792 * allocated, we are pwned. As really we can't resize an
793 * fbdev that is in the wild currently due to fbdev not really
794 * being designed for the lower layers moving stuff around
795 * under it.
796 * - so in the grand style of things - punt.
797 */
798 if ((fb->width < surface_width) ||
799 (fb->height < surface_height)) {
800 DRM_ERROR("fb not large enough for console\n");
801 return -EINVAL;
802 }
803 }
804// fail
805
806 info = intel_fb->base.fbdev;
807 par = info->par;
808
809 crtc_count = 0;
810 /*
811 * For each CRTC, set up the connector list for the CRTC's mode
812 * set configuration.
813 */
814 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
815 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
816
817 modeset = &intel_crtc->mode_set;
818 modeset->fb = &intel_fb->base;
819 conn_count = 0;
820 list_for_each_entry(connector, &dev->mode_config.connector_list,
821 head) {
822 if (!connector->encoder)
823 continue;
824
825 if(connector->encoder->crtc == modeset->crtc) {
826 modeset->connectors[conn_count++] = connector;
827 if (conn_count > INTELFB_CONN_LIMIT)
828 BUG();
829 }
830 }
831
832 /* Zero out remaining connector pointers */
833 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
834 modeset->connectors[i] = NULL;
835
836 par->crtc_ids[crtc_count++] = crtc->base.id;
837
838 modeset->num_connectors = conn_count;
839 if (modeset->crtc->desired_mode) {
840 if (modeset->mode)
841 drm_mode_destroy(dev, modeset->mode);
842 modeset->mode = drm_mode_duplicate(dev,
843 modeset->crtc->desired_mode);
844 }
845 }
846 par->crtc_count = crtc_count;
847
848 if (new_fb) {
849 info->var.pixclock = -1;
850 if (register_framebuffer(info) < 0)
851 return -EINVAL;
852 } else
853 intelfb_set_par(info);
854
855 DRM_INFO("fb%d: %s frame buffer device\n", info->node,
856 info->fix.id);
857
858 /* Switch back to kernel console on panic */
859 kernelfb_mode = *modeset;
860 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
861 DRM_DEBUG("registered panic notifier\n");
862
863 return 0;
864}
865
866/**
867 * intelfb_restore - restore the framebuffer console (kernel) config
868 *
869 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
870 */
871void intelfb_restore(void)
872{
873 int ret;
874 if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) {
875 DRM_ERROR("Failed to restore crtc configuration: %d\n",
876 ret);
877 }
878}
879
880static void intelfb_restore_work_fn(struct work_struct *ignored)
881{
882 intelfb_restore();
883}
884static DECLARE_WORK(intelfb_restore_work, intelfb_restore_work_fn);
885
886static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
887{
888 schedule_work(&intelfb_restore_work);
889}
890
891static struct sysrq_key_op sysrq_intelfb_restore_op = {
892 .handler = intelfb_sysrq,
893 .help_msg = "force-fb(V)",
894 .action_msg = "Restore framebuffer console",
895};
896
897int intelfb_probe(struct drm_device *dev) 241int intelfb_probe(struct drm_device *dev)
898{ 242{
899 int ret; 243 int ret;
900 244
901 DRM_DEBUG("\n"); 245 DRM_DEBUG("\n");
902 246 ret = drm_fb_helper_single_fb_probe(dev, intelfb_create);
903 /* something has changed in the lower levels of hell - deal with it
904 here */
905
906 /* two modes : a) 1 fb to rule all crtcs.
907 b) one fb per crtc.
908 two actions 1) new connected device
909 2) device removed.
910 case a/1 : if the fb surface isn't big enough - resize the surface fb.
911 if the fb size isn't big enough - resize fb into surface.
912 if everything big enough configure the new crtc/etc.
913 case a/2 : undo the configuration
914 possibly resize down the fb to fit the new configuration.
915 case b/1 : see if it is on a new crtc - setup a new fb and add it.
916 case b/2 : teardown the new fb.
917 */
918
919 /* mode a first */
920 /* search for an fb */
921 if (i915_fbpercrtc == 1) {
922 ret = intelfb_multi_fb_probe(dev);
923 } else {
924 ret = intelfb_single_fb_probe(dev);
925 }
926
927 register_sysrq_key('v', &sysrq_intelfb_restore_op);
928
929 return ret; 247 return ret;
930} 248}
931EXPORT_SYMBOL(intelfb_probe); 249EXPORT_SYMBOL(intelfb_probe);
@@ -940,13 +258,14 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
940 info = fb->fbdev; 258 info = fb->fbdev;
941 259
942 if (info) { 260 if (info) {
261 struct intelfb_par *par = info->par;
943 unregister_framebuffer(info); 262 unregister_framebuffer(info);
944 iounmap(info->screen_base); 263 iounmap(info->screen_base);
264 if (info->par)
265 drm_fb_helper_free(&par->helper);
945 framebuffer_release(info); 266 framebuffer_release(info);
946 } 267 }
947 268
948 atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
949 memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set));
950 return 0; 269 return 0;
951} 270}
952EXPORT_SYMBOL(intelfb_remove); 271EXPORT_SYMBOL(intelfb_remove);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 62b8bead7652..c7eab724c418 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
42 if (!IS_IGD(dev)) 42 if (!IS_IGD(dev))
43 return; 43 return;
44 if (enable) 44 if (enable)
45 I915_WRITE(CG_2D_DIS, 45 I915_WRITE(DSPCLK_GATE_D,
46 I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE); 46 I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE);
47 else 47 else
48 I915_WRITE(CG_2D_DIS, 48 I915_WRITE(DSPCLK_GATE_D,
49 I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE)); 49 I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE));
50} 50}
51 51
52/* 52/*
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 8df02ef89261..dafc0da1c256 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -38,16 +38,6 @@
38#include "i915_drv.h" 38#include "i915_drv.h"
39#include <linux/acpi.h> 39#include <linux/acpi.h>
40 40
41#define I915_LVDS "i915_lvds"
42
43/*
44 * the following four scaling options are defined.
45 * #define DRM_MODE_SCALE_NON_GPU 0
46 * #define DRM_MODE_SCALE_FULLSCREEN 1
47 * #define DRM_MODE_SCALE_NO_SCALE 2
48 * #define DRM_MODE_SCALE_ASPECT 3
49 */
50
51/* Private structure for the integrated LVDS support */ 41/* Private structure for the integrated LVDS support */
52struct intel_lvds_priv { 42struct intel_lvds_priv {
53 int fitting_mode; 43 int fitting_mode;
@@ -336,7 +326,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
336 I915_WRITE(BCLRPAT_B, 0); 326 I915_WRITE(BCLRPAT_B, 0);
337 327
338 switch (lvds_priv->fitting_mode) { 328 switch (lvds_priv->fitting_mode) {
339 case DRM_MODE_SCALE_NO_SCALE: 329 case DRM_MODE_SCALE_CENTER:
340 /* 330 /*
341 * For centered modes, we have to calculate border widths & 331 * For centered modes, we have to calculate border widths &
342 * heights and modify the values programmed into the CRTC. 332 * heights and modify the values programmed into the CRTC.
@@ -672,9 +662,8 @@ static int intel_lvds_set_property(struct drm_connector *connector,
672 connector->encoder) { 662 connector->encoder) {
673 struct drm_crtc *crtc = connector->encoder->crtc; 663 struct drm_crtc *crtc = connector->encoder->crtc;
674 struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; 664 struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
675 if (value == DRM_MODE_SCALE_NON_GPU) { 665 if (value == DRM_MODE_SCALE_NONE) {
676 DRM_DEBUG_KMS(I915_LVDS, 666 DRM_DEBUG_KMS("no scaling not supported\n");
677 "non_GPU property is unsupported\n");
678 return 0; 667 return 0;
679 } 668 }
680 if (lvds_priv->fitting_mode == value) { 669 if (lvds_priv->fitting_mode == value) {
@@ -731,8 +720,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
731 720
732static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) 721static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
733{ 722{
734 DRM_DEBUG_KMS(I915_LVDS, 723 DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident);
735 "Skipping LVDS initialization for %s\n", id->ident);
736 return 1; 724 return 1;
737} 725}
738 726
@@ -1027,7 +1015,7 @@ out:
1027 return; 1015 return;
1028 1016
1029failed: 1017failed:
1030 DRM_DEBUG_KMS(I915_LVDS, "No LVDS modes found, disabling.\n"); 1018 DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
1031 if (intel_output->ddc_bus) 1019 if (intel_output->ddc_bus)
1032 intel_i2c_destroy(intel_output->ddc_bus); 1020 intel_i2c_destroy(intel_output->ddc_bus);
1033 drm_connector_cleanup(connector); 1021 drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index d3b74ba62b4a..0bf28efcf2c1 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -37,7 +37,19 @@
37#include "intel_sdvo_regs.h" 37#include "intel_sdvo_regs.h"
38 38
39#undef SDVO_DEBUG 39#undef SDVO_DEBUG
40#define I915_SDVO "i915_sdvo" 40
41static char *tv_format_names[] = {
42 "NTSC_M" , "NTSC_J" , "NTSC_443",
43 "PAL_B" , "PAL_D" , "PAL_G" ,
44 "PAL_H" , "PAL_I" , "PAL_M" ,
45 "PAL_N" , "PAL_NC" , "PAL_60" ,
46 "SECAM_B" , "SECAM_D" , "SECAM_G" ,
47 "SECAM_K" , "SECAM_K1", "SECAM_L" ,
48 "SECAM_60"
49};
50
51#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names))
52
41struct intel_sdvo_priv { 53struct intel_sdvo_priv {
42 u8 slave_addr; 54 u8 slave_addr;
43 55
@@ -71,6 +83,15 @@ struct intel_sdvo_priv {
71 */ 83 */
72 bool is_tv; 84 bool is_tv;
73 85
86 /* This is for current tv format name */
87 char *tv_format_name;
88
89 /* This contains all current supported TV format */
90 char *tv_format_supported[TV_FORMAT_NUM];
91 int format_supported_num;
92 struct drm_property *tv_format_property;
93 struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
94
74 /** 95 /**
75 * This is set if we treat the device as HDMI, instead of DVI. 96 * This is set if we treat the device as HDMI, instead of DVI.
76 */ 97 */
@@ -97,14 +118,6 @@ struct intel_sdvo_priv {
97 */ 118 */
98 struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; 119 struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
99 120
100 /**
101 * Current selected TV format.
102 *
103 * This is stored in the same structure that's passed to the device, for
104 * convenience.
105 */
106 struct intel_sdvo_tv_format tv_format;
107
108 /* 121 /*
109 * supported encoding mode, used to determine whether HDMI is 122 * supported encoding mode, used to determine whether HDMI is
110 * supported 123 * supported
@@ -114,6 +127,9 @@ struct intel_sdvo_priv {
114 /* DDC bus used by this SDVO output */ 127 /* DDC bus used by this SDVO output */
115 uint8_t ddc_bus; 128 uint8_t ddc_bus;
116 129
130 /* Mac mini hack -- use the same DDC as the analog connector */
131 struct i2c_adapter *analog_ddc_bus;
132
117 int save_sdvo_mult; 133 int save_sdvo_mult;
118 u16 save_active_outputs; 134 u16 save_active_outputs;
119 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; 135 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
@@ -188,7 +204,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
188 return true; 204 return true;
189 } 205 }
190 206
191 DRM_DEBUG("i2c transfer returned %d\n", ret); 207 DRM_DEBUG_KMS("i2c transfer returned %d\n", ret);
192 return false; 208 return false;
193} 209}
194 210
@@ -298,7 +314,7 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
298 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; 314 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
299 int i; 315 int i;
300 316
301 DRM_DEBUG_KMS(I915_SDVO, "%s: W: %02X ", 317 DRM_DEBUG_KMS("%s: W: %02X ",
302 SDVO_NAME(sdvo_priv), cmd); 318 SDVO_NAME(sdvo_priv), cmd);
303 for (i = 0; i < args_len; i++) 319 for (i = 0; i < args_len; i++)
304 DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); 320 DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
@@ -351,7 +367,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
351 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; 367 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
352 int i; 368 int i;
353 369
354 DRM_DEBUG_KMS(I915_SDVO, "%s: R: ", SDVO_NAME(sdvo_priv)); 370 DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
355 for (i = 0; i < response_len; i++) 371 for (i = 0; i < response_len; i++)
356 DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); 372 DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
357 for (; i < 8; i++) 373 for (; i < 8; i++)
@@ -668,10 +684,10 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
668 status = intel_sdvo_read_response(intel_output, &response, 1); 684 status = intel_sdvo_read_response(intel_output, &response, 1);
669 685
670 if (status != SDVO_CMD_STATUS_SUCCESS) { 686 if (status != SDVO_CMD_STATUS_SUCCESS) {
671 DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n"); 687 DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
672 return SDVO_CLOCK_RATE_MULT_1X; 688 return SDVO_CLOCK_RATE_MULT_1X;
673 } else { 689 } else {
674 DRM_DEBUG("Current clock rate multiplier: %d\n", response); 690 DRM_DEBUG_KMS("Current clock rate multiplier: %d\n", response);
675 } 691 }
676 692
677 return response; 693 return response;
@@ -945,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
945 961
946static void intel_sdvo_set_tv_format(struct intel_output *output) 962static void intel_sdvo_set_tv_format(struct intel_output *output)
947{ 963{
964
965 struct intel_sdvo_tv_format format;
948 struct intel_sdvo_priv *sdvo_priv = output->dev_priv; 966 struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
949 struct intel_sdvo_tv_format *format, unset; 967 uint32_t format_map, i;
950 u8 status; 968 uint8_t status;
951 969
952 format = &sdvo_priv->tv_format; 970 for (i = 0; i < TV_FORMAT_NUM; i++)
953 memset(&unset, 0, sizeof(unset)); 971 if (tv_format_names[i] == sdvo_priv->tv_format_name)
954 if (memcmp(format, &unset, sizeof(*format))) { 972 break;
955 DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", 973
956 SDVO_NAME(sdvo_priv)); 974 format_map = 1 << i;
957 format->ntsc_m = 1; 975 memset(&format, 0, sizeof(format));
958 intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, 976 memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
959 sizeof(*format)); 977 sizeof(format) : sizeof(format_map));
960 status = intel_sdvo_read_response(output, NULL, 0); 978
961 if (status != SDVO_CMD_STATUS_SUCCESS) 979 intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
962 DRM_DEBUG("%s: Failed to set TV format\n", 980 sizeof(format));
963 SDVO_NAME(sdvo_priv)); 981
964 } 982 status = intel_sdvo_read_response(output, NULL, 0);
983 if (status != SDVO_CMD_STATUS_SUCCESS)
984 DRM_DEBUG("%s: Failed to set TV format\n",
985 SDVO_NAME(sdvo_priv));
965} 986}
966 987
967static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, 988static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
@@ -1230,8 +1251,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1230 * a given it the status is a success, we succeeded. 1251 * a given it the status is a success, we succeeded.
1231 */ 1252 */
1232 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { 1253 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
1233 DRM_DEBUG("First %s output reported failure to sync\n", 1254 DRM_DEBUG_KMS("First %s output reported failure to "
1234 SDVO_NAME(sdvo_priv)); 1255 "sync\n", SDVO_NAME(sdvo_priv));
1235 } 1256 }
1236 1257
1237 if (0) 1258 if (0)
@@ -1326,8 +1347,8 @@ static void intel_sdvo_restore(struct drm_connector *connector)
1326 intel_wait_for_vblank(dev); 1347 intel_wait_for_vblank(dev);
1327 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); 1348 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
1328 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) 1349 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
1329 DRM_DEBUG("First %s output reported failure to sync\n", 1350 DRM_DEBUG_KMS("First %s output reported failure to "
1330 SDVO_NAME(sdvo_priv)); 1351 "sync\n", SDVO_NAME(sdvo_priv));
1331 } 1352 }
1332 1353
1333 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); 1354 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
@@ -1405,7 +1426,7 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
1405 u8 response[2]; 1426 u8 response[2];
1406 u8 status; 1427 u8 status;
1407 struct intel_output *intel_output; 1428 struct intel_output *intel_output;
1408 DRM_DEBUG("\n"); 1429 DRM_DEBUG_KMS("\n");
1409 1430
1410 if (!connector) 1431 if (!connector)
1411 return 0; 1432 return 0;
@@ -1478,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
1478 return (caps > 1); 1499 return (caps > 1);
1479} 1500}
1480 1501
1502static struct drm_connector *
1503intel_find_analog_connector(struct drm_device *dev)
1504{
1505 struct drm_connector *connector;
1506 struct intel_output *intel_output;
1507
1508 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1509 intel_output = to_intel_output(connector);
1510 if (intel_output->type == INTEL_OUTPUT_ANALOG)
1511 return connector;
1512 }
1513 return NULL;
1514}
1515
1516static int
1517intel_analog_is_connected(struct drm_device *dev)
1518{
1519 struct drm_connector *analog_connector;
1520 analog_connector = intel_find_analog_connector(dev);
1521
1522 if (!analog_connector)
1523 return false;
1524
1525 if (analog_connector->funcs->detect(analog_connector) ==
1526 connector_status_disconnected)
1527 return false;
1528
1529 return true;
1530}
1531
1481enum drm_connector_status 1532enum drm_connector_status
1482intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) 1533intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1483{ 1534{
@@ -1488,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1488 1539
1489 edid = drm_get_edid(&intel_output->base, 1540 edid = drm_get_edid(&intel_output->base,
1490 intel_output->ddc_bus); 1541 intel_output->ddc_bus);
1542
1543 /* when there is no edid and no monitor is connected with VGA
1544 * port, try to use the CRT ddc to read the EDID for DVI-connector
1545 */
1546 if (edid == NULL &&
1547 sdvo_priv->analog_ddc_bus &&
1548 !intel_analog_is_connected(intel_output->base.dev))
1549 edid = drm_get_edid(&intel_output->base,
1550 sdvo_priv->analog_ddc_bus);
1491 if (edid != NULL) { 1551 if (edid != NULL) {
1492 /* Don't report the output as connected if it's a DVI-I 1552 /* Don't report the output as connected if it's a DVI-I
1493 * connector with a non-digital EDID coming out. 1553 * connector with a non-digital EDID coming out.
@@ -1516,10 +1576,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
1516 struct intel_output *intel_output = to_intel_output(connector); 1576 struct intel_output *intel_output = to_intel_output(connector);
1517 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; 1577 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
1518 1578
1519 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); 1579 intel_sdvo_write_cmd(intel_output,
1580 SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
1520 status = intel_sdvo_read_response(intel_output, &response, 2); 1581 status = intel_sdvo_read_response(intel_output, &response, 2);
1521 1582
1522 DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8); 1583 DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
1523 1584
1524 if (status != SDVO_CMD_STATUS_SUCCESS) 1585 if (status != SDVO_CMD_STATUS_SUCCESS)
1525 return connector_status_unknown; 1586 return connector_status_unknown;
@@ -1540,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
1540static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) 1601static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1541{ 1602{
1542 struct intel_output *intel_output = to_intel_output(connector); 1603 struct intel_output *intel_output = to_intel_output(connector);
1604 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
1605 int num_modes;
1543 1606
1544 /* set the bus switch and get the modes */ 1607 /* set the bus switch and get the modes */
1545 intel_ddc_get_modes(intel_output); 1608 num_modes = intel_ddc_get_modes(intel_output);
1546 1609
1547#if 0 1610 /*
1548 struct drm_device *dev = encoder->dev; 1611 * Mac mini hack. On this device, the DVI-I connector shares one DDC
1549 struct drm_i915_private *dev_priv = dev->dev_private; 1612 * link between analog and digital outputs. So, if the regular SDVO
1550 /* Mac mini hack. On this device, I get DDC through the analog, which 1613 * DDC fails, check to see if the analog output is disconnected, in
1551 * load-detects as disconnected. I fail to DDC through the SDVO DDC, 1614 * which case we'll look there for the digital DDC data.
1552 * but it does load-detect as connected. So, just steal the DDC bits
1553 * from analog when we fail at finding it the right way.
1554 */ 1615 */
1555 crt = xf86_config->output[0]; 1616 if (num_modes == 0 &&
1556 intel_output = crt->driver_private; 1617 sdvo_priv->analog_ddc_bus &&
1557 if (intel_output->type == I830_OUTPUT_ANALOG && 1618 !intel_analog_is_connected(intel_output->base.dev)) {
1558 crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { 1619 struct i2c_adapter *digital_ddc_bus;
1559 I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
1560 edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
1561 xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
1562 }
1563 if (edid_mon) {
1564 xf86OutputSetEDID(output, edid_mon);
1565 modes = xf86OutputGetEDIDModes(output);
1566 }
1567#endif
1568}
1569 1620
1570/** 1621 /* Switch to the analog ddc bus and try that
1571 * This function checks the current TV format, and chooses a default if 1622 */
1572 * it hasn't been set. 1623 digital_ddc_bus = intel_output->ddc_bus;
1573 */ 1624 intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
1574static void
1575intel_sdvo_check_tv_format(struct intel_output *output)
1576{
1577 struct intel_sdvo_priv *dev_priv = output->dev_priv;
1578 struct intel_sdvo_tv_format format;
1579 uint8_t status;
1580 1625
1581 intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); 1626 (void) intel_ddc_get_modes(intel_output);
1582 status = intel_sdvo_read_response(output, &format, sizeof(format));
1583 if (status != SDVO_CMD_STATUS_SUCCESS)
1584 return;
1585 1627
1586 memcpy(&dev_priv->tv_format, &format, sizeof(format)); 1628 intel_output->ddc_bus = digital_ddc_bus;
1629 }
1587} 1630}
1588 1631
1589/* 1632/*
@@ -1656,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
1656 struct intel_output *output = to_intel_output(connector); 1699 struct intel_output *output = to_intel_output(connector);
1657 struct intel_sdvo_priv *sdvo_priv = output->dev_priv; 1700 struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
1658 struct intel_sdvo_sdtv_resolution_request tv_res; 1701 struct intel_sdvo_sdtv_resolution_request tv_res;
1659 uint32_t reply = 0; 1702 uint32_t reply = 0, format_map = 0;
1703 int i;
1660 uint8_t status; 1704 uint8_t status;
1661 int i = 0;
1662 1705
1663 intel_sdvo_check_tv_format(output);
1664 1706
1665 /* Read the list of supported input resolutions for the selected TV 1707 /* Read the list of supported input resolutions for the selected TV
1666 * format. 1708 * format.
1667 */ 1709 */
1668 memset(&tv_res, 0, sizeof(tv_res)); 1710 for (i = 0; i < TV_FORMAT_NUM; i++)
1669 memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res)); 1711 if (tv_format_names[i] == sdvo_priv->tv_format_name)
1712 break;
1713
1714 format_map = (1 << i);
1715 memcpy(&tv_res, &format_map,
1716 sizeof(struct intel_sdvo_sdtv_resolution_request) >
1717 sizeof(format_map) ? sizeof(format_map) :
1718 sizeof(struct intel_sdvo_sdtv_resolution_request));
1719
1720 intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
1721
1670 intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, 1722 intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
1671 &tv_res, sizeof(tv_res)); 1723 &tv_res, sizeof(tv_res));
1672 status = intel_sdvo_read_response(output, &reply, 3); 1724 status = intel_sdvo_read_response(output, &reply, 3);
@@ -1681,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
1681 if (nmode) 1733 if (nmode)
1682 drm_mode_probed_add(connector, nmode); 1734 drm_mode_probed_add(connector, nmode);
1683 } 1735 }
1736
1684} 1737}
1685 1738
1686static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) 1739static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
@@ -1748,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
1748 intel_i2c_destroy(intel_output->i2c_bus); 1801 intel_i2c_destroy(intel_output->i2c_bus);
1749 if (intel_output->ddc_bus) 1802 if (intel_output->ddc_bus)
1750 intel_i2c_destroy(intel_output->ddc_bus); 1803 intel_i2c_destroy(intel_output->ddc_bus);
1804 if (sdvo_priv->analog_ddc_bus)
1805 intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
1751 1806
1752 if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) 1807 if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
1753 drm_mode_destroy(connector->dev, 1808 drm_mode_destroy(connector->dev,
1754 sdvo_priv->sdvo_lvds_fixed_mode); 1809 sdvo_priv->sdvo_lvds_fixed_mode);
1755 1810
1811 if (sdvo_priv->tv_format_property)
1812 drm_property_destroy(connector->dev,
1813 sdvo_priv->tv_format_property);
1814
1756 drm_sysfs_connector_remove(connector); 1815 drm_sysfs_connector_remove(connector);
1757 drm_connector_cleanup(connector); 1816 drm_connector_cleanup(connector);
1758 1817
1759 kfree(intel_output); 1818 kfree(intel_output);
1760} 1819}
1761 1820
1821static int
1822intel_sdvo_set_property(struct drm_connector *connector,
1823 struct drm_property *property,
1824 uint64_t val)
1825{
1826 struct intel_output *intel_output = to_intel_output(connector);
1827 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
1828 struct drm_encoder *encoder = &intel_output->enc;
1829 struct drm_crtc *crtc = encoder->crtc;
1830 int ret = 0;
1831 bool changed = false;
1832
1833 ret = drm_connector_property_set_value(connector, property, val);
1834 if (ret < 0)
1835 goto out;
1836
1837 if (property == sdvo_priv->tv_format_property) {
1838 if (val >= TV_FORMAT_NUM) {
1839 ret = -EINVAL;
1840 goto out;
1841 }
1842 if (sdvo_priv->tv_format_name ==
1843 sdvo_priv->tv_format_supported[val])
1844 goto out;
1845
1846 sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val];
1847 changed = true;
1848 } else {
1849 ret = -EINVAL;
1850 goto out;
1851 }
1852
1853 if (changed && crtc)
1854 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
1855 crtc->y, crtc->fb);
1856out:
1857 return ret;
1858}
1859
1762static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { 1860static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
1763 .dpms = intel_sdvo_dpms, 1861 .dpms = intel_sdvo_dpms,
1764 .mode_fixup = intel_sdvo_mode_fixup, 1862 .mode_fixup = intel_sdvo_mode_fixup,
@@ -1773,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
1773 .restore = intel_sdvo_restore, 1871 .restore = intel_sdvo_restore,
1774 .detect = intel_sdvo_detect, 1872 .detect = intel_sdvo_detect,
1775 .fill_modes = drm_helper_probe_single_connector_modes, 1873 .fill_modes = drm_helper_probe_single_connector_modes,
1874 .set_property = intel_sdvo_set_property,
1776 .destroy = intel_sdvo_destroy, 1875 .destroy = intel_sdvo_destroy,
1777}; 1876};
1778 1877
@@ -2013,10 +2112,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
2013 2112
2014 sdvo_priv->controlled_output = 0; 2113 sdvo_priv->controlled_output = 0;
2015 memcpy(bytes, &sdvo_priv->caps.output_flags, 2); 2114 memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
2016 DRM_DEBUG_KMS(I915_SDVO, 2115 DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
2017 "%s: Unknown SDVO output type (0x%02x%02x)\n", 2116 SDVO_NAME(sdvo_priv),
2018 SDVO_NAME(sdvo_priv), 2117 bytes[0], bytes[1]);
2019 bytes[0], bytes[1]);
2020 ret = false; 2118 ret = false;
2021 } 2119 }
2022 intel_output->crtc_mask = (1 << 0) | (1 << 1); 2120 intel_output->crtc_mask = (1 << 0) | (1 << 1);
@@ -2029,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
2029 2127
2030} 2128}
2031 2129
2130static void intel_sdvo_tv_create_property(struct drm_connector *connector)
2131{
2132 struct intel_output *intel_output = to_intel_output(connector);
2133 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
2134 struct intel_sdvo_tv_format format;
2135 uint32_t format_map, i;
2136 uint8_t status;
2137
2138 intel_sdvo_set_target_output(intel_output,
2139 sdvo_priv->controlled_output);
2140
2141 intel_sdvo_write_cmd(intel_output,
2142 SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
2143 status = intel_sdvo_read_response(intel_output,
2144 &format, sizeof(format));
2145 if (status != SDVO_CMD_STATUS_SUCCESS)
2146 return;
2147
2148 memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ?
2149 sizeof(format_map) : sizeof(format));
2150
2151 if (format_map == 0)
2152 return;
2153
2154 sdvo_priv->format_supported_num = 0;
2155 for (i = 0 ; i < TV_FORMAT_NUM; i++)
2156 if (format_map & (1 << i)) {
2157 sdvo_priv->tv_format_supported
2158 [sdvo_priv->format_supported_num++] =
2159 tv_format_names[i];
2160 }
2161
2162
2163 sdvo_priv->tv_format_property =
2164 drm_property_create(
2165 connector->dev, DRM_MODE_PROP_ENUM,
2166 "mode", sdvo_priv->format_supported_num);
2167
2168 for (i = 0; i < sdvo_priv->format_supported_num; i++)
2169 drm_property_add_enum(
2170 sdvo_priv->tv_format_property, i,
2171 i, sdvo_priv->tv_format_supported[i]);
2172
2173 sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0];
2174 drm_connector_attach_property(
2175 connector, sdvo_priv->tv_format_property, 0);
2176
2177}
2178
2032bool intel_sdvo_init(struct drm_device *dev, int output_device) 2179bool intel_sdvo_init(struct drm_device *dev, int output_device)
2033{ 2180{
2034 struct drm_connector *connector; 2181 struct drm_connector *connector;
@@ -2066,18 +2213,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2066 /* Read the regs to test if we can talk to the device */ 2213 /* Read the regs to test if we can talk to the device */
2067 for (i = 0; i < 0x40; i++) { 2214 for (i = 0; i < 0x40; i++) {
2068 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { 2215 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
2069 DRM_DEBUG_KMS(I915_SDVO, 2216 DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
2070 "No SDVO device found on SDVO%c\n",
2071 output_device == SDVOB ? 'B' : 'C'); 2217 output_device == SDVOB ? 'B' : 'C');
2072 goto err_i2c; 2218 goto err_i2c;
2073 } 2219 }
2074 } 2220 }
2075 2221
2076 /* setup the DDC bus. */ 2222 /* setup the DDC bus. */
2077 if (output_device == SDVOB) 2223 if (output_device == SDVOB) {
2078 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); 2224 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
2079 else 2225 sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
2226 "SDVOB/VGA DDC BUS");
2227 } else {
2080 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); 2228 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
2229 sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
2230 "SDVOC/VGA DDC BUS");
2231 }
2081 2232
2082 if (intel_output->ddc_bus == NULL) 2233 if (intel_output->ddc_bus == NULL)
2083 goto err_i2c; 2234 goto err_i2c;
@@ -2090,7 +2241,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2090 2241
2091 if (intel_sdvo_output_setup(intel_output, 2242 if (intel_sdvo_output_setup(intel_output,
2092 sdvo_priv->caps.output_flags) != true) { 2243 sdvo_priv->caps.output_flags) != true) {
2093 DRM_DEBUG("SDVO output failed to setup on SDVO%c\n", 2244 DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
2094 output_device == SDVOB ? 'B' : 'C'); 2245 output_device == SDVOB ? 'B' : 'C');
2095 goto err_i2c; 2246 goto err_i2c;
2096 } 2247 }
@@ -2111,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2111 drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); 2262 drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
2112 2263
2113 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); 2264 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
2265 if (sdvo_priv->is_tv)
2266 intel_sdvo_tv_create_property(connector);
2114 drm_sysfs_connector_add(connector); 2267 drm_sysfs_connector_add(connector);
2115 2268
2116 intel_sdvo_select_ddc_bus(sdvo_priv); 2269 intel_sdvo_select_ddc_bus(sdvo_priv);
@@ -2123,7 +2276,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2123 &sdvo_priv->pixel_clock_max); 2276 &sdvo_priv->pixel_clock_max);
2124 2277
2125 2278
2126 DRM_DEBUG_KMS(I915_SDVO, "%s device VID/DID: %02X:%02X.%02X, " 2279 DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
2127 "clock range %dMHz - %dMHz, " 2280 "clock range %dMHz - %dMHz, "
2128 "input 1: %c, input 2: %c, " 2281 "input 1: %c, input 2: %c, "
2129 "output 1: %c, output 2: %c\n", 2282 "output 1: %c, output 2: %c\n",
@@ -2143,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2143 return true; 2296 return true;
2144 2297
2145err_i2c: 2298err_i2c:
2299 if (sdvo_priv->analog_ddc_bus != NULL)
2300 intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
2146 if (intel_output->ddc_bus != NULL) 2301 if (intel_output->ddc_bus != NULL)
2147 intel_i2c_destroy(intel_output->ddc_bus); 2302 intel_i2c_destroy(intel_output->ddc_bus);
2148 if (intel_output->i2c_bus != NULL) 2303 if (intel_output->i2c_bus != NULL)
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 5b1c9e9fdba0..c64eab493fb0 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1437,6 +1437,35 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
1437 return type; 1437 return type;
1438} 1438}
1439 1439
1440/*
1441 * Here we set accurate tv format according to connector type
1442 * i.e Component TV should not be assigned by NTSC or PAL
1443 */
1444static void intel_tv_find_better_format(struct drm_connector *connector)
1445{
1446 struct intel_output *intel_output = to_intel_output(connector);
1447 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
1448 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
1449 int i;
1450
1451 if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1452 tv_mode->component_only)
1453 return;
1454
1455
1456 for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
1457 tv_mode = tv_modes + i;
1458
1459 if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
1460 tv_mode->component_only)
1461 break;
1462 }
1463
1464 tv_priv->tv_format = tv_mode->name;
1465 drm_connector_property_set_value(connector,
1466 connector->dev->mode_config.tv_mode_property, i);
1467}
1468
1440/** 1469/**
1441 * Detect the TV connection. 1470 * Detect the TV connection.
1442 * 1471 *
@@ -1473,6 +1502,7 @@ intel_tv_detect(struct drm_connector *connector)
1473 if (type < 0) 1502 if (type < 0)
1474 return connector_status_disconnected; 1503 return connector_status_disconnected;
1475 1504
1505 intel_tv_find_better_format(connector);
1476 return connector_status_connected; 1506 return connector_status_connected;
1477} 1507}
1478 1508
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 6c67a02910c8..3c917fb3a60b 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -444,7 +444,7 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
444{ 444{
445 drm_mga_private_t *const dev_priv = 445 drm_mga_private_t *const dev_priv =
446 (drm_mga_private_t *) dev->dev_private; 446 (drm_mga_private_t *) dev->dev_private;
447 unsigned int warp_size = mga_warp_microcode_size(dev_priv); 447 unsigned int warp_size = MGA_WARP_UCODE_SIZE;
448 int err; 448 int err;
449 unsigned offset; 449 unsigned offset;
450 const unsigned secondary_size = dma_bs->secondary_bin_count 450 const unsigned secondary_size = dma_bs->secondary_bin_count
@@ -619,7 +619,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
619{ 619{
620 drm_mga_private_t *const dev_priv = 620 drm_mga_private_t *const dev_priv =
621 (drm_mga_private_t *) dev->dev_private; 621 (drm_mga_private_t *) dev->dev_private;
622 unsigned int warp_size = mga_warp_microcode_size(dev_priv); 622 unsigned int warp_size = MGA_WARP_UCODE_SIZE;
623 unsigned int primary_size; 623 unsigned int primary_size;
624 unsigned int bin_count; 624 unsigned int bin_count;
625 int err; 625 int err;
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index 3d264f288237..be6c6b9b0e89 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -177,7 +177,6 @@ extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
177extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); 177extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf);
178 178
179 /* mga_warp.c */ 179 /* mga_warp.c */
180extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
181extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); 180extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
182extern int mga_warp_init(drm_mga_private_t * dev_priv); 181extern int mga_warp_init(drm_mga_private_t * dev_priv);
183 182
diff --git a/drivers/gpu/drm/mga/mga_ucode.h b/drivers/gpu/drm/mga/mga_ucode.h
deleted file mode 100644
index b611e27470e1..000000000000
--- a/drivers/gpu/drm/mga/mga_ucode.h
+++ /dev/null
@@ -1,11645 +0,0 @@
1/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*-
2 * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com
3 *
4 * Copyright 1999 Matrox Graphics Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
23 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Kernel-based WARP engine management:
26 * Gareth Hughes <gareth@valinux.com>
27 */
28
29/*
30 * WARP pipes are named according to the functions they perform, where:
31 *
32 * - T stands for computation of texture stage 0
33 * - T2 stands for computation of both texture stage 0 and texture stage 1
34 * - G stands for computation of triangle intensity (Gouraud interpolation)
35 * - Z stands for computation of Z buffer interpolation
36 * - S stands for computation of specular highlight
37 * - A stands for computation of the alpha channel
38 * - F stands for computation of vertex fog interpolation
39 */
40
41static unsigned char warp_g200_tgz[] = {
42
43 0x00, 0x80, 0x00, 0xE8,
44 0x00, 0x80, 0x00, 0xE8,
45
46 0x00, 0x80, 0x00, 0xE8,
47 0x00, 0x80, 0x00, 0xE8,
48
49 0x00, 0x80, 0x00, 0xE8,
50 0x00, 0x80, 0x00, 0xE8,
51
52 0x00, 0x80, 0x00, 0xE8,
53 0x00, 0x80, 0x00, 0xE8,
54
55 0x00, 0x80, 0x00, 0xE8,
56 0x00, 0x80, 0x00, 0xE8,
57
58 0x00, 0x98, 0xA0, 0xE9,
59 0x40, 0x40, 0xD8, 0xEC,
60
61 0xFF, 0x80, 0xC0, 0xE9,
62 0x00, 0x80, 0x00, 0xE8,
63
64 0x1F, 0xD7, 0x18, 0xBD,
65 0x3F, 0xD7, 0x22, 0xBD,
66
67 0x81, 0x04,
68 0x89, 0x04,
69 0x01, 0x04,
70 0x09, 0x04,
71
72 0xC9, 0x41, 0xC0, 0xEC,
73 0x11, 0x04,
74 0x00, 0xE0,
75
76 0x41, 0xCC, 0x41, 0xCD,
77 0x49, 0xCC, 0x49, 0xCD,
78
79 0xD1, 0x41, 0xC0, 0xEC,
80 0x51, 0xCC, 0x51, 0xCD,
81
82 0x80, 0x04,
83 0x10, 0x04,
84 0x08, 0x04,
85 0x00, 0xE0,
86
87 0x00, 0xCC, 0xC0, 0xCD,
88 0xD1, 0x49, 0xC0, 0xEC,
89
90 0x8A, 0x1F, 0x20, 0xE9,
91 0x8B, 0x3F, 0x20, 0xE9,
92
93 0x41, 0x3C, 0x41, 0xAD,
94 0x49, 0x3C, 0x49, 0xAD,
95
96 0x10, 0xCC, 0x10, 0xCD,
97 0x08, 0xCC, 0x08, 0xCD,
98
99 0xB9, 0x41, 0x49, 0xBB,
100 0x1F, 0xF0, 0x41, 0xCD,
101
102 0x51, 0x3C, 0x51, 0xAD,
103 0x00, 0x98, 0x80, 0xE9,
104
105 0x72, 0x80, 0x07, 0xEA,
106 0x24, 0x1F, 0x20, 0xE9,
107
108 0x15, 0x41, 0x49, 0xBD,
109 0x1D, 0x41, 0x51, 0xBD,
110
111 0x2E, 0x41, 0x2A, 0xB8,
112 0x34, 0x53, 0xA0, 0xE8,
113
114 0x15, 0x30,
115 0x1D, 0x30,
116 0x58, 0xE3,
117 0x00, 0xE0,
118
119 0xB5, 0x40, 0x48, 0xBD,
120 0x3D, 0x40, 0x50, 0xBD,
121
122 0x24, 0x43, 0xA0, 0xE8,
123 0x2C, 0x4B, 0xA0, 0xE8,
124
125 0x15, 0x72,
126 0x09, 0xE3,
127 0x00, 0xE0,
128 0x1D, 0x72,
129
130 0x35, 0x30,
131 0xB5, 0x30,
132 0xBD, 0x30,
133 0x3D, 0x30,
134
135 0x9C, 0x97, 0x57, 0x9F,
136 0x00, 0x80, 0x00, 0xE8,
137
138 0x6C, 0x64, 0xC8, 0xEC,
139 0x98, 0xE1,
140 0xB5, 0x05,
141
142 0xBD, 0x05,
143 0x2E, 0x30,
144 0x32, 0xC0, 0xA0, 0xE8,
145
146 0x33, 0xC0, 0xA0, 0xE8,
147 0x74, 0x64, 0xC8, 0xEC,
148
149 0x40, 0x3C, 0x40, 0xAD,
150 0x32, 0x6A,
151 0x2A, 0x30,
152
153 0x20, 0x73,
154 0x33, 0x6A,
155 0x00, 0xE0,
156 0x28, 0x73,
157
158 0x1C, 0x72,
159 0x83, 0xE2,
160 0x60, 0x80, 0x15, 0xEA,
161
162 0xB8, 0x3D, 0x28, 0xDF,
163 0x30, 0x35, 0x20, 0xDF,
164
165 0x40, 0x30,
166 0x00, 0xE0,
167 0xCC, 0xE2,
168 0x64, 0x72,
169
170 0x25, 0x42, 0x52, 0xBF,
171 0x2D, 0x42, 0x4A, 0xBF,
172
173 0x30, 0x2E, 0x30, 0xDF,
174 0x38, 0x2E, 0x38, 0xDF,
175
176 0x18, 0x1D, 0x45, 0xE9,
177 0x1E, 0x15, 0x45, 0xE9,
178
179 0x2B, 0x49, 0x51, 0xBD,
180 0x00, 0xE0,
181 0x1F, 0x73,
182
183 0x38, 0x38, 0x40, 0xAF,
184 0x30, 0x30, 0x40, 0xAF,
185
186 0x24, 0x1F, 0x24, 0xDF,
187 0x1D, 0x32, 0x20, 0xE9,
188
189 0x2C, 0x1F, 0x2C, 0xDF,
190 0x1A, 0x33, 0x20, 0xE9,
191
192 0xB0, 0x10,
193 0x08, 0xE3,
194 0x40, 0x10,
195 0xB8, 0x10,
196
197 0x26, 0xF0, 0x30, 0xCD,
198 0x2F, 0xF0, 0x38, 0xCD,
199
200 0x2B, 0x80, 0x20, 0xE9,
201 0x2A, 0x80, 0x20, 0xE9,
202
203 0xA6, 0x20,
204 0x88, 0xE2,
205 0x00, 0xE0,
206 0xAF, 0x20,
207
208 0x28, 0x2A, 0x26, 0xAF,
209 0x20, 0x2A, 0xC0, 0xAF,
210
211 0x34, 0x1F, 0x34, 0xDF,
212 0x46, 0x24, 0x46, 0xDF,
213
214 0x28, 0x30, 0x80, 0xBF,
215 0x20, 0x38, 0x80, 0xBF,
216
217 0x47, 0x24, 0x47, 0xDF,
218 0x4E, 0x2C, 0x4E, 0xDF,
219
220 0x4F, 0x2C, 0x4F, 0xDF,
221 0x56, 0x34, 0x56, 0xDF,
222
223 0x28, 0x15, 0x28, 0xDF,
224 0x20, 0x1D, 0x20, 0xDF,
225
226 0x57, 0x34, 0x57, 0xDF,
227 0x00, 0xE0,
228 0x1D, 0x05,
229
230 0x04, 0x80, 0x10, 0xEA,
231 0x89, 0xE2,
232 0x2B, 0x30,
233
234 0x3F, 0xC1, 0x1D, 0xBD,
235 0x00, 0x80, 0x00, 0xE8,
236
237 0x00, 0x80, 0x00, 0xE8,
238 0x00, 0x80, 0x00, 0xE8,
239
240 0xA0, 0x68,
241 0xBF, 0x25,
242 0x00, 0x80, 0x00, 0xE8,
243
244 0x20, 0xC0, 0x20, 0xAF,
245 0x28, 0x05,
246 0x97, 0x74,
247
248 0x00, 0xE0,
249 0x2A, 0x10,
250 0x16, 0xC0, 0x20, 0xE9,
251
252 0x04, 0x80, 0x10, 0xEA,
253 0x8C, 0xE2,
254 0x95, 0x05,
255
256 0x28, 0xC1, 0x28, 0xAD,
257 0x1F, 0xC1, 0x15, 0xBD,
258
259 0x00, 0x80, 0x00, 0xE8,
260 0x00, 0x80, 0x00, 0xE8,
261
262 0xA8, 0x67,
263 0x9F, 0x6B,
264 0x00, 0x80, 0x00, 0xE8,
265
266 0x28, 0xC0, 0x28, 0xAD,
267 0x1D, 0x25,
268 0x20, 0x05,
269
270 0x28, 0x32, 0x80, 0xAD,
271 0x40, 0x2A, 0x40, 0xBD,
272
273 0x1C, 0x80, 0x20, 0xE9,
274 0x20, 0x33, 0x20, 0xAD,
275
276 0x20, 0x73,
277 0x00, 0xE0,
278 0xB6, 0x49, 0x51, 0xBB,
279
280 0x26, 0x2F, 0xB0, 0xE8,
281 0x19, 0x20, 0x20, 0xE9,
282
283 0x35, 0x20, 0x35, 0xDF,
284 0x3D, 0x20, 0x3D, 0xDF,
285
286 0x15, 0x20, 0x15, 0xDF,
287 0x1D, 0x20, 0x1D, 0xDF,
288
289 0x26, 0xD0, 0x26, 0xCD,
290 0x29, 0x49, 0x2A, 0xB8,
291
292 0x26, 0x40, 0x80, 0xBD,
293 0x3B, 0x48, 0x50, 0xBD,
294
295 0x3E, 0x54, 0x57, 0x9F,
296 0x00, 0xE0,
297 0x82, 0xE1,
298
299 0x1E, 0xAF, 0x59, 0x9F,
300 0x00, 0x80, 0x00, 0xE8,
301
302 0x26, 0x30,
303 0x29, 0x30,
304 0x48, 0x3C, 0x48, 0xAD,
305
306 0x2B, 0x72,
307 0xC2, 0xE1,
308 0x2C, 0xC0, 0x44, 0xC2,
309
310 0x05, 0x24, 0x34, 0xBF,
311 0x0D, 0x24, 0x2C, 0xBF,
312
313 0x2D, 0x46, 0x4E, 0xBF,
314 0x25, 0x46, 0x56, 0xBF,
315
316 0x20, 0x1D, 0x6F, 0x8F,
317 0x32, 0x3E, 0x5F, 0xE9,
318
319 0x3E, 0x50, 0x56, 0x9F,
320 0x00, 0xE0,
321 0x3B, 0x30,
322
323 0x1E, 0x8F, 0x51, 0x9F,
324 0x33, 0x1E, 0x5F, 0xE9,
325
326 0x05, 0x44, 0x54, 0xB2,
327 0x0D, 0x44, 0x4C, 0xB2,
328
329 0x19, 0xC0, 0xB0, 0xE8,
330 0x34, 0xC0, 0x44, 0xC4,
331
332 0x33, 0x73,
333 0x00, 0xE0,
334 0x3E, 0x62, 0x57, 0x9F,
335
336 0x1E, 0xAF, 0x59, 0x9F,
337 0x00, 0xE0,
338 0x0D, 0x20,
339
340 0x84, 0x3E, 0x58, 0xE9,
341 0x28, 0x1D, 0x6F, 0x8F,
342
343 0x05, 0x20,
344 0x00, 0xE0,
345 0x85, 0x1E, 0x58, 0xE9,
346
347 0x9B, 0x3B, 0x33, 0xDF,
348 0x20, 0x20, 0x42, 0xAF,
349
350 0x30, 0x42, 0x56, 0x9F,
351 0x80, 0x3E, 0x57, 0xE9,
352
353 0x3F, 0x8F, 0x51, 0x9F,
354 0x30, 0x80, 0x5F, 0xE9,
355
356 0x28, 0x28, 0x24, 0xAF,
357 0x81, 0x1E, 0x57, 0xE9,
358
359 0x05, 0x47, 0x57, 0xBF,
360 0x0D, 0x47, 0x4F, 0xBF,
361
362 0x88, 0x80, 0x58, 0xE9,
363 0x1B, 0x29, 0x1B, 0xDF,
364
365 0x30, 0x1D, 0x6F, 0x8F,
366 0x3A, 0x30, 0x4F, 0xE9,
367
368 0x1C, 0x30, 0x26, 0xDF,
369 0x09, 0xE3,
370 0x3B, 0x05,
371
372 0x3E, 0x50, 0x56, 0x9F,
373 0x3B, 0x3F, 0x4F, 0xE9,
374
375 0x1E, 0x8F, 0x51, 0x9F,
376 0x00, 0xE0,
377 0xAC, 0x20,
378
379 0x2D, 0x44, 0x4C, 0xB4,
380 0x2C, 0x1C, 0xC0, 0xAF,
381
382 0x25, 0x44, 0x54, 0xB4,
383 0x00, 0xE0,
384 0xC8, 0x30,
385
386 0x30, 0x46, 0x30, 0xAF,
387 0x1B, 0x1B, 0x48, 0xAF,
388
389 0x00, 0xE0,
390 0x25, 0x20,
391 0x38, 0x2C, 0x4F, 0xE9,
392
393 0x86, 0x80, 0x57, 0xE9,
394 0x38, 0x1D, 0x6F, 0x8F,
395
396 0x28, 0x74,
397 0x00, 0xE0,
398 0x0D, 0x44, 0x4C, 0xB0,
399
400 0x05, 0x44, 0x54, 0xB0,
401 0x2D, 0x20,
402 0x9B, 0x10,
403
404 0x82, 0x3E, 0x57, 0xE9,
405 0x32, 0xF0, 0x1B, 0xCD,
406
407 0x1E, 0xBD, 0x59, 0x9F,
408 0x83, 0x1E, 0x57, 0xE9,
409
410 0x38, 0x47, 0x38, 0xAF,
411 0x34, 0x20,
412 0x2A, 0x30,
413
414 0x00, 0xE0,
415 0x0D, 0x20,
416 0x32, 0x20,
417 0x05, 0x20,
418
419 0x87, 0x80, 0x57, 0xE9,
420 0x1F, 0x54, 0x57, 0x9F,
421
422 0x17, 0x42, 0x56, 0x9F,
423 0x00, 0xE0,
424 0x3B, 0x6A,
425
426 0x3F, 0x8F, 0x51, 0x9F,
427 0x37, 0x1E, 0x4F, 0xE9,
428
429 0x37, 0x32, 0x2A, 0xAF,
430 0x00, 0xE0,
431 0x32, 0x00,
432
433 0x00, 0x80, 0x00, 0xE8,
434 0x27, 0xC0, 0x44, 0xC0,
435
436 0x36, 0x1F, 0x4F, 0xE9,
437 0x1F, 0x1F, 0x26, 0xDF,
438
439 0x37, 0x1B, 0x37, 0xBF,
440 0x17, 0x26, 0x17, 0xDF,
441
442 0x3E, 0x17, 0x4F, 0xE9,
443 0x3F, 0x3F, 0x4F, 0xE9,
444
445 0x34, 0x1F, 0x34, 0xAF,
446 0x2B, 0x05,
447 0xA7, 0x20,
448
449 0x33, 0x2B, 0x37, 0xDF,
450 0x27, 0x17, 0xC0, 0xAF,
451
452 0x34, 0x80, 0x4F, 0xE9,
453 0x00, 0x80, 0x00, 0xE8,
454
455 0x03, 0x80, 0x0A, 0xEA,
456 0x17, 0xC1, 0x2B, 0xBD,
457
458 0x00, 0x80, 0x00, 0xE8,
459 0x00, 0x80, 0x00, 0xE8,
460
461 0xB3, 0x68,
462 0x97, 0x25,
463 0x00, 0x80, 0x00, 0xE8,
464
465 0x33, 0xC0, 0x33, 0xAF,
466 0x3C, 0x27, 0x4F, 0xE9,
467
468 0x57, 0x39, 0x20, 0xE9,
469 0x28, 0x19, 0x60, 0xEC,
470
471 0x2B, 0x32, 0x20, 0xE9,
472 0x1D, 0x3B, 0x20, 0xE9,
473
474 0xB3, 0x05,
475 0x00, 0xE0,
476 0x16, 0x28, 0x20, 0xE9,
477
478 0x23, 0x3B, 0x33, 0xAD,
479 0x1E, 0x2B, 0x20, 0xE9,
480
481 0x1C, 0x80, 0x20, 0xE9,
482 0x57, 0x36, 0x20, 0xE9,
483
484 0x00, 0x80, 0xA0, 0xE9,
485 0x40, 0x40, 0xD8, 0xEC,
486
487 0xFF, 0x80, 0xC0, 0xE9,
488 0x90, 0xE2,
489 0x00, 0xE0,
490
491 0x85, 0xFF, 0x20, 0xEA,
492 0x19, 0xC8, 0xC1, 0xCD,
493
494 0x1F, 0xD7, 0x18, 0xBD,
495 0x3F, 0xD7, 0x22, 0xBD,
496
497 0x9F, 0x41, 0x49, 0xBD,
498 0x00, 0x80, 0x00, 0xE8,
499
500 0x25, 0x41, 0x49, 0xBD,
501 0x2D, 0x41, 0x51, 0xBD,
502
503 0x0D, 0x80, 0x07, 0xEA,
504 0x00, 0x80, 0x00, 0xE8,
505
506 0x35, 0x40, 0x48, 0xBD,
507 0x3D, 0x40, 0x50, 0xBD,
508
509 0x00, 0x80, 0x00, 0xE8,
510 0x25, 0x30,
511 0x2D, 0x30,
512
513 0x35, 0x30,
514 0xB5, 0x30,
515 0xBD, 0x30,
516 0x3D, 0x30,
517
518 0x9C, 0xA7, 0x5B, 0x9F,
519 0x00, 0x80, 0x00, 0xE8,
520
521 0x00, 0x80, 0x00, 0xE8,
522 0x00, 0x80, 0x00, 0xE8,
523
524 0x00, 0x80, 0x00, 0xE8,
525 0x00, 0x80, 0x00, 0xE8,
526
527 0x00, 0x80, 0x00, 0xE8,
528 0x00, 0x80, 0x00, 0xE8,
529
530 0x00, 0x80, 0x00, 0xE8,
531 0x00, 0x80, 0x00, 0xE8,
532
533 0x84, 0xFF, 0x0A, 0xEA,
534 0x00, 0x80, 0x00, 0xE8,
535
536 0xC9, 0x41, 0xC8, 0xEC,
537 0x42, 0xE1,
538 0x00, 0xE0,
539
540 0x82, 0xFF, 0x20, 0xEA,
541 0x00, 0x80, 0x00, 0xE8,
542
543 0x00, 0x80, 0x00, 0xE8,
544 0x00, 0x80, 0x00, 0xE8,
545
546 0xC8, 0x40, 0xC0, 0xEC,
547 0x00, 0x80, 0x00, 0xE8,
548
549 0x7F, 0xFF, 0x20, 0xEA,
550 0x00, 0x80, 0x00, 0xE8,
551
552 0x00, 0x80, 0x00, 0xE8,
553 0x00, 0x80, 0x00, 0xE8,
554
555};
556
557static unsigned char warp_g200_tgza[] = {
558
559 0x00, 0x98, 0xA0, 0xE9,
560 0x40, 0x40, 0xD8, 0xEC,
561
562 0xFF, 0x80, 0xC0, 0xE9,
563 0x00, 0x80, 0x00, 0xE8,
564
565 0x1F, 0xD7, 0x18, 0xBD,
566 0x3F, 0xD7, 0x22, 0xBD,
567
568 0x81, 0x04,
569 0x89, 0x04,
570 0x01, 0x04,
571 0x09, 0x04,
572
573 0xC9, 0x41, 0xC0, 0xEC,
574 0x11, 0x04,
575 0x00, 0xE0,
576
577 0x41, 0xCC, 0x41, 0xCD,
578 0x49, 0xCC, 0x49, 0xCD,
579
580 0xD1, 0x41, 0xC0, 0xEC,
581 0x51, 0xCC, 0x51, 0xCD,
582
583 0x80, 0x04,
584 0x10, 0x04,
585 0x08, 0x04,
586 0x00, 0xE0,
587
588 0x00, 0xCC, 0xC0, 0xCD,
589 0xD1, 0x49, 0xC0, 0xEC,
590
591 0x8A, 0x1F, 0x20, 0xE9,
592 0x8B, 0x3F, 0x20, 0xE9,
593
594 0x41, 0x3C, 0x41, 0xAD,
595 0x49, 0x3C, 0x49, 0xAD,
596
597 0x10, 0xCC, 0x10, 0xCD,
598 0x08, 0xCC, 0x08, 0xCD,
599
600 0xB9, 0x41, 0x49, 0xBB,
601 0x1F, 0xF0, 0x41, 0xCD,
602
603 0x51, 0x3C, 0x51, 0xAD,
604 0x00, 0x98, 0x80, 0xE9,
605
606 0x7D, 0x80, 0x07, 0xEA,
607 0x24, 0x1F, 0x20, 0xE9,
608
609 0x15, 0x41, 0x49, 0xBD,
610 0x1D, 0x41, 0x51, 0xBD,
611
612 0x2E, 0x41, 0x2A, 0xB8,
613 0x34, 0x53, 0xA0, 0xE8,
614
615 0x15, 0x30,
616 0x1D, 0x30,
617 0x58, 0xE3,
618 0x00, 0xE0,
619
620 0xB5, 0x40, 0x48, 0xBD,
621 0x3D, 0x40, 0x50, 0xBD,
622
623 0x24, 0x43, 0xA0, 0xE8,
624 0x2C, 0x4B, 0xA0, 0xE8,
625
626 0x15, 0x72,
627 0x09, 0xE3,
628 0x00, 0xE0,
629 0x1D, 0x72,
630
631 0x35, 0x30,
632 0xB5, 0x30,
633 0xBD, 0x30,
634 0x3D, 0x30,
635
636 0x9C, 0x97, 0x57, 0x9F,
637 0x00, 0x80, 0x00, 0xE8,
638
639 0x6C, 0x64, 0xC8, 0xEC,
640 0x98, 0xE1,
641 0xB5, 0x05,
642
643 0xBD, 0x05,
644 0x2E, 0x30,
645 0x32, 0xC0, 0xA0, 0xE8,
646
647 0x33, 0xC0, 0xA0, 0xE8,
648 0x74, 0x64, 0xC8, 0xEC,
649
650 0x40, 0x3C, 0x40, 0xAD,
651 0x32, 0x6A,
652 0x2A, 0x30,
653
654 0x20, 0x73,
655 0x33, 0x6A,
656 0x00, 0xE0,
657 0x28, 0x73,
658
659 0x1C, 0x72,
660 0x83, 0xE2,
661 0x6B, 0x80, 0x15, 0xEA,
662
663 0xB8, 0x3D, 0x28, 0xDF,
664 0x30, 0x35, 0x20, 0xDF,
665
666 0x40, 0x30,
667 0x00, 0xE0,
668 0xCC, 0xE2,
669 0x64, 0x72,
670
671 0x25, 0x42, 0x52, 0xBF,
672 0x2D, 0x42, 0x4A, 0xBF,
673
674 0x30, 0x2E, 0x30, 0xDF,
675 0x38, 0x2E, 0x38, 0xDF,
676
677 0x18, 0x1D, 0x45, 0xE9,
678 0x1E, 0x15, 0x45, 0xE9,
679
680 0x2B, 0x49, 0x51, 0xBD,
681 0x00, 0xE0,
682 0x1F, 0x73,
683
684 0x38, 0x38, 0x40, 0xAF,
685 0x30, 0x30, 0x40, 0xAF,
686
687 0x24, 0x1F, 0x24, 0xDF,
688 0x1D, 0x32, 0x20, 0xE9,
689
690 0x2C, 0x1F, 0x2C, 0xDF,
691 0x1A, 0x33, 0x20, 0xE9,
692
693 0xB0, 0x10,
694 0x08, 0xE3,
695 0x40, 0x10,
696 0xB8, 0x10,
697
698 0x26, 0xF0, 0x30, 0xCD,
699 0x2F, 0xF0, 0x38, 0xCD,
700
701 0x2B, 0x80, 0x20, 0xE9,
702 0x2A, 0x80, 0x20, 0xE9,
703
704 0xA6, 0x20,
705 0x88, 0xE2,
706 0x00, 0xE0,
707 0xAF, 0x20,
708
709 0x28, 0x2A, 0x26, 0xAF,
710 0x20, 0x2A, 0xC0, 0xAF,
711
712 0x34, 0x1F, 0x34, 0xDF,
713 0x46, 0x24, 0x46, 0xDF,
714
715 0x28, 0x30, 0x80, 0xBF,
716 0x20, 0x38, 0x80, 0xBF,
717
718 0x47, 0x24, 0x47, 0xDF,
719 0x4E, 0x2C, 0x4E, 0xDF,
720
721 0x4F, 0x2C, 0x4F, 0xDF,
722 0x56, 0x34, 0x56, 0xDF,
723
724 0x28, 0x15, 0x28, 0xDF,
725 0x20, 0x1D, 0x20, 0xDF,
726
727 0x57, 0x34, 0x57, 0xDF,
728 0x00, 0xE0,
729 0x1D, 0x05,
730
731 0x04, 0x80, 0x10, 0xEA,
732 0x89, 0xE2,
733 0x2B, 0x30,
734
735 0x3F, 0xC1, 0x1D, 0xBD,
736 0x00, 0x80, 0x00, 0xE8,
737
738 0x00, 0x80, 0x00, 0xE8,
739 0x00, 0x80, 0x00, 0xE8,
740
741 0xA0, 0x68,
742 0xBF, 0x25,
743 0x00, 0x80, 0x00, 0xE8,
744
745 0x20, 0xC0, 0x20, 0xAF,
746 0x28, 0x05,
747 0x97, 0x74,
748
749 0x00, 0xE0,
750 0x2A, 0x10,
751 0x16, 0xC0, 0x20, 0xE9,
752
753 0x04, 0x80, 0x10, 0xEA,
754 0x8C, 0xE2,
755 0x95, 0x05,
756
757 0x28, 0xC1, 0x28, 0xAD,
758 0x1F, 0xC1, 0x15, 0xBD,
759
760 0x00, 0x80, 0x00, 0xE8,
761 0x00, 0x80, 0x00, 0xE8,
762
763 0xA8, 0x67,
764 0x9F, 0x6B,
765 0x00, 0x80, 0x00, 0xE8,
766
767 0x28, 0xC0, 0x28, 0xAD,
768 0x1D, 0x25,
769 0x20, 0x05,
770
771 0x28, 0x32, 0x80, 0xAD,
772 0x40, 0x2A, 0x40, 0xBD,
773
774 0x1C, 0x80, 0x20, 0xE9,
775 0x20, 0x33, 0x20, 0xAD,
776
777 0x20, 0x73,
778 0x00, 0xE0,
779 0xB6, 0x49, 0x51, 0xBB,
780
781 0x26, 0x2F, 0xB0, 0xE8,
782 0x19, 0x20, 0x20, 0xE9,
783
784 0x35, 0x20, 0x35, 0xDF,
785 0x3D, 0x20, 0x3D, 0xDF,
786
787 0x15, 0x20, 0x15, 0xDF,
788 0x1D, 0x20, 0x1D, 0xDF,
789
790 0x26, 0xD0, 0x26, 0xCD,
791 0x29, 0x49, 0x2A, 0xB8,
792
793 0x26, 0x40, 0x80, 0xBD,
794 0x3B, 0x48, 0x50, 0xBD,
795
796 0x3E, 0x54, 0x57, 0x9F,
797 0x00, 0xE0,
798 0x82, 0xE1,
799
800 0x1E, 0xAF, 0x59, 0x9F,
801 0x00, 0x80, 0x00, 0xE8,
802
803 0x26, 0x30,
804 0x29, 0x30,
805 0x48, 0x3C, 0x48, 0xAD,
806
807 0x2B, 0x72,
808 0xC2, 0xE1,
809 0x2C, 0xC0, 0x44, 0xC2,
810
811 0x05, 0x24, 0x34, 0xBF,
812 0x0D, 0x24, 0x2C, 0xBF,
813
814 0x2D, 0x46, 0x4E, 0xBF,
815 0x25, 0x46, 0x56, 0xBF,
816
817 0x20, 0x1D, 0x6F, 0x8F,
818 0x32, 0x3E, 0x5F, 0xE9,
819
820 0x3E, 0x50, 0x56, 0x9F,
821 0x00, 0xE0,
822 0x3B, 0x30,
823
824 0x1E, 0x8F, 0x51, 0x9F,
825 0x33, 0x1E, 0x5F, 0xE9,
826
827 0x05, 0x44, 0x54, 0xB2,
828 0x0D, 0x44, 0x4C, 0xB2,
829
830 0x19, 0xC0, 0xB0, 0xE8,
831 0x34, 0xC0, 0x44, 0xC4,
832
833 0x33, 0x73,
834 0x00, 0xE0,
835 0x3E, 0x62, 0x57, 0x9F,
836
837 0x1E, 0xAF, 0x59, 0x9F,
838 0x00, 0xE0,
839 0x0D, 0x20,
840
841 0x84, 0x3E, 0x58, 0xE9,
842 0x28, 0x1D, 0x6F, 0x8F,
843
844 0x05, 0x20,
845 0x00, 0xE0,
846 0x85, 0x1E, 0x58, 0xE9,
847
848 0x9B, 0x3B, 0x33, 0xDF,
849 0x20, 0x20, 0x42, 0xAF,
850
851 0x30, 0x42, 0x56, 0x9F,
852 0x80, 0x3E, 0x57, 0xE9,
853
854 0x3F, 0x8F, 0x51, 0x9F,
855 0x30, 0x80, 0x5F, 0xE9,
856
857 0x28, 0x28, 0x24, 0xAF,
858 0x81, 0x1E, 0x57, 0xE9,
859
860 0x05, 0x47, 0x57, 0xBF,
861 0x0D, 0x47, 0x4F, 0xBF,
862
863 0x88, 0x80, 0x58, 0xE9,
864 0x1B, 0x29, 0x1B, 0xDF,
865
866 0x30, 0x1D, 0x6F, 0x8F,
867 0x3A, 0x30, 0x4F, 0xE9,
868
869 0x1C, 0x30, 0x26, 0xDF,
870 0x09, 0xE3,
871 0x3B, 0x05,
872
873 0x3E, 0x50, 0x56, 0x9F,
874 0x3B, 0x3F, 0x4F, 0xE9,
875
876 0x1E, 0x8F, 0x51, 0x9F,
877 0x00, 0xE0,
878 0xAC, 0x20,
879
880 0x2D, 0x44, 0x4C, 0xB4,
881 0x2C, 0x1C, 0xC0, 0xAF,
882
883 0x25, 0x44, 0x54, 0xB4,
884 0x00, 0xE0,
885 0xC8, 0x30,
886
887 0x30, 0x46, 0x30, 0xAF,
888 0x1B, 0x1B, 0x48, 0xAF,
889
890 0x00, 0xE0,
891 0x25, 0x20,
892 0x38, 0x2C, 0x4F, 0xE9,
893
894 0x86, 0x80, 0x57, 0xE9,
895 0x38, 0x1D, 0x6F, 0x8F,
896
897 0x28, 0x74,
898 0x00, 0xE0,
899 0x0D, 0x44, 0x4C, 0xB0,
900
901 0x05, 0x44, 0x54, 0xB0,
902 0x2D, 0x20,
903 0x9B, 0x10,
904
905 0x82, 0x3E, 0x57, 0xE9,
906 0x32, 0xF0, 0x1B, 0xCD,
907
908 0x1E, 0xBD, 0x59, 0x9F,
909 0x83, 0x1E, 0x57, 0xE9,
910
911 0x38, 0x47, 0x38, 0xAF,
912 0x34, 0x20,
913 0x2A, 0x30,
914
915 0x00, 0xE0,
916 0x0D, 0x20,
917 0x32, 0x20,
918 0x05, 0x20,
919
920 0x87, 0x80, 0x57, 0xE9,
921 0x1F, 0x54, 0x57, 0x9F,
922
923 0x17, 0x42, 0x56, 0x9F,
924 0x00, 0xE0,
925 0x3B, 0x6A,
926
927 0x3F, 0x8F, 0x51, 0x9F,
928 0x37, 0x1E, 0x4F, 0xE9,
929
930 0x37, 0x32, 0x2A, 0xAF,
931 0x00, 0xE0,
932 0x32, 0x00,
933
934 0x00, 0x80, 0x00, 0xE8,
935 0x27, 0xC0, 0x44, 0xC0,
936
937 0x36, 0x1F, 0x4F, 0xE9,
938 0x1F, 0x1F, 0x26, 0xDF,
939
940 0x37, 0x1B, 0x37, 0xBF,
941 0x17, 0x26, 0x17, 0xDF,
942
943 0x3E, 0x17, 0x4F, 0xE9,
944 0x3F, 0x3F, 0x4F, 0xE9,
945
946 0x34, 0x1F, 0x34, 0xAF,
947 0x2B, 0x05,
948 0xA7, 0x20,
949
950 0x33, 0x2B, 0x37, 0xDF,
951 0x27, 0x17, 0xC0, 0xAF,
952
953 0x34, 0x80, 0x4F, 0xE9,
954 0x00, 0x80, 0x00, 0xE8,
955
956 0x2D, 0x44, 0x4C, 0xB6,
957 0x25, 0x44, 0x54, 0xB6,
958
959 0x03, 0x80, 0x2A, 0xEA,
960 0x17, 0xC1, 0x2B, 0xBD,
961
962 0x2D, 0x20,
963 0x25, 0x20,
964 0x07, 0xC0, 0x44, 0xC6,
965
966 0xB3, 0x68,
967 0x97, 0x25,
968 0x00, 0x80, 0x00, 0xE8,
969
970 0x33, 0xC0, 0x33, 0xAF,
971 0x3C, 0x27, 0x4F, 0xE9,
972
973 0x1F, 0x62, 0x57, 0x9F,
974 0x00, 0x80, 0x00, 0xE8,
975
976 0x3F, 0x3D, 0x5D, 0x9F,
977 0x00, 0xE0,
978 0x07, 0x20,
979
980 0x00, 0x80, 0x00, 0xE8,
981 0x28, 0x19, 0x60, 0xEC,
982
983 0xB3, 0x05,
984 0x00, 0xE0,
985 0x00, 0x80, 0x00, 0xE8,
986
987 0x23, 0x3B, 0x33, 0xAD,
988 0x00, 0x80, 0x00, 0xE8,
989
990 0x1F, 0x26, 0x1F, 0xDF,
991 0x9D, 0x1F, 0x4F, 0xE9,
992
993 0x00, 0x80, 0x00, 0xE8,
994 0x00, 0x80, 0x00, 0xE8,
995
996 0x00, 0x80, 0x00, 0xE8,
997 0x9E, 0x3F, 0x4F, 0xE9,
998
999 0x07, 0x07, 0x1F, 0xAF,
1000 0x00, 0x80, 0x00, 0xE8,
1001
1002 0x00, 0x80, 0x00, 0xE8,
1003 0x00, 0x80, 0x00, 0xE8,
1004
1005 0x9C, 0x80, 0x4F, 0xE9,
1006 0x00, 0x80, 0x00, 0xE8,
1007
1008 0x00, 0x80, 0x00, 0xE8,
1009 0x57, 0x39, 0x20, 0xE9,
1010
1011 0x16, 0x28, 0x20, 0xE9,
1012 0x1D, 0x3B, 0x20, 0xE9,
1013
1014 0x1E, 0x2B, 0x20, 0xE9,
1015 0x2B, 0x32, 0x20, 0xE9,
1016
1017 0x1C, 0x23, 0x20, 0xE9,
1018 0x57, 0x36, 0x20, 0xE9,
1019
1020 0x00, 0x80, 0xA0, 0xE9,
1021 0x40, 0x40, 0xD8, 0xEC,
1022
1023 0xFF, 0x80, 0xC0, 0xE9,
1024 0x90, 0xE2,
1025 0x00, 0xE0,
1026
1027 0x7A, 0xFF, 0x20, 0xEA,
1028 0x19, 0xC8, 0xC1, 0xCD,
1029
1030 0x1F, 0xD7, 0x18, 0xBD,
1031 0x3F, 0xD7, 0x22, 0xBD,
1032
1033 0x9F, 0x41, 0x49, 0xBD,
1034 0x00, 0x80, 0x00, 0xE8,
1035
1036 0x25, 0x41, 0x49, 0xBD,
1037 0x2D, 0x41, 0x51, 0xBD,
1038
1039 0x0D, 0x80, 0x07, 0xEA,
1040 0x00, 0x80, 0x00, 0xE8,
1041
1042 0x35, 0x40, 0x48, 0xBD,
1043 0x3D, 0x40, 0x50, 0xBD,
1044
1045 0x00, 0x80, 0x00, 0xE8,
1046 0x25, 0x30,
1047 0x2D, 0x30,
1048
1049 0x35, 0x30,
1050 0xB5, 0x30,
1051 0xBD, 0x30,
1052 0x3D, 0x30,
1053
1054 0x9C, 0xA7, 0x5B, 0x9F,
1055 0x00, 0x80, 0x00, 0xE8,
1056
1057 0x00, 0x80, 0x00, 0xE8,
1058 0x00, 0x80, 0x00, 0xE8,
1059
1060 0x00, 0x80, 0x00, 0xE8,
1061 0x00, 0x80, 0x00, 0xE8,
1062
1063 0x00, 0x80, 0x00, 0xE8,
1064 0x00, 0x80, 0x00, 0xE8,
1065
1066 0x00, 0x80, 0x00, 0xE8,
1067 0x00, 0x80, 0x00, 0xE8,
1068
1069 0x79, 0xFF, 0x0A, 0xEA,
1070 0x00, 0x80, 0x00, 0xE8,
1071
1072 0xC9, 0x41, 0xC8, 0xEC,
1073 0x42, 0xE1,
1074 0x00, 0xE0,
1075
1076 0x77, 0xFF, 0x20, 0xEA,
1077 0x00, 0x80, 0x00, 0xE8,
1078
1079 0x00, 0x80, 0x00, 0xE8,
1080 0x00, 0x80, 0x00, 0xE8,
1081
1082 0xC8, 0x40, 0xC0, 0xEC,
1083 0x00, 0x80, 0x00, 0xE8,
1084
1085 0x74, 0xFF, 0x20, 0xEA,
1086 0x00, 0x80, 0x00, 0xE8,
1087
1088 0x00, 0x80, 0x00, 0xE8,
1089 0x00, 0x80, 0x00, 0xE8,
1090
1091};
1092
1093static unsigned char warp_g200_tgzaf[] = {
1094
1095 0x00, 0x80, 0x00, 0xE8,
1096 0x00, 0x80, 0x00, 0xE8,
1097
1098 0x00, 0x80, 0x00, 0xE8,
1099 0x00, 0x80, 0x00, 0xE8,
1100
1101 0x00, 0x80, 0x00, 0xE8,
1102 0x00, 0x80, 0x00, 0xE8,
1103
1104 0x00, 0x80, 0x00, 0xE8,
1105 0x00, 0x80, 0x00, 0xE8,
1106
1107 0x00, 0x80, 0x00, 0xE8,
1108 0x00, 0x80, 0x00, 0xE8,
1109
1110 0x00, 0x80, 0x00, 0xE8,
1111 0x00, 0x80, 0x00, 0xE8,
1112
1113 0x00, 0x80, 0x00, 0xE8,
1114 0x00, 0x80, 0x00, 0xE8,
1115
1116 0x00, 0x80, 0x00, 0xE8,
1117 0x00, 0x80, 0x00, 0xE8,
1118
1119 0x00, 0x80, 0x00, 0xE8,
1120 0x00, 0x80, 0x00, 0xE8,
1121
1122 0x00, 0x80, 0x00, 0xE8,
1123 0x00, 0x80, 0x00, 0xE8,
1124
1125 0x00, 0x98, 0xA0, 0xE9,
1126 0x40, 0x40, 0xD8, 0xEC,
1127
1128 0xFF, 0x80, 0xC0, 0xE9,
1129 0x00, 0x80, 0x00, 0xE8,
1130
1131 0x1F, 0xD7, 0x18, 0xBD,
1132 0x3F, 0xD7, 0x22, 0xBD,
1133
1134 0x81, 0x04,
1135 0x89, 0x04,
1136 0x01, 0x04,
1137 0x09, 0x04,
1138
1139 0xC9, 0x41, 0xC0, 0xEC,
1140 0x11, 0x04,
1141 0x00, 0xE0,
1142
1143 0x41, 0xCC, 0x41, 0xCD,
1144 0x49, 0xCC, 0x49, 0xCD,
1145
1146 0xD1, 0x41, 0xC0, 0xEC,
1147 0x51, 0xCC, 0x51, 0xCD,
1148
1149 0x80, 0x04,
1150 0x10, 0x04,
1151 0x08, 0x04,
1152 0x00, 0xE0,
1153
1154 0x00, 0xCC, 0xC0, 0xCD,
1155 0xD1, 0x49, 0xC0, 0xEC,
1156
1157 0x8A, 0x1F, 0x20, 0xE9,
1158 0x8B, 0x3F, 0x20, 0xE9,
1159
1160 0x41, 0x3C, 0x41, 0xAD,
1161 0x49, 0x3C, 0x49, 0xAD,
1162
1163 0x10, 0xCC, 0x10, 0xCD,
1164 0x08, 0xCC, 0x08, 0xCD,
1165
1166 0xB9, 0x41, 0x49, 0xBB,
1167 0x1F, 0xF0, 0x41, 0xCD,
1168
1169 0x51, 0x3C, 0x51, 0xAD,
1170 0x00, 0x98, 0x80, 0xE9,
1171
1172 0x83, 0x80, 0x07, 0xEA,
1173 0x24, 0x1F, 0x20, 0xE9,
1174
1175 0x21, 0x45, 0x80, 0xE8,
1176 0x1A, 0x4D, 0x80, 0xE8,
1177
1178 0x31, 0x55, 0x80, 0xE8,
1179 0x00, 0x80, 0x00, 0xE8,
1180
1181 0x15, 0x41, 0x49, 0xBD,
1182 0x1D, 0x41, 0x51, 0xBD,
1183
1184 0x2E, 0x41, 0x2A, 0xB8,
1185 0x34, 0x53, 0xA0, 0xE8,
1186
1187 0x15, 0x30,
1188 0x1D, 0x30,
1189 0x58, 0xE3,
1190 0x00, 0xE0,
1191
1192 0xB5, 0x40, 0x48, 0xBD,
1193 0x3D, 0x40, 0x50, 0xBD,
1194
1195 0x24, 0x43, 0xA0, 0xE8,
1196 0x2C, 0x4B, 0xA0, 0xE8,
1197
1198 0x15, 0x72,
1199 0x09, 0xE3,
1200 0x00, 0xE0,
1201 0x1D, 0x72,
1202
1203 0x35, 0x30,
1204 0xB5, 0x30,
1205 0xBD, 0x30,
1206 0x3D, 0x30,
1207
1208 0x9C, 0x97, 0x57, 0x9F,
1209 0x00, 0x80, 0x00, 0xE8,
1210
1211 0x6C, 0x64, 0xC8, 0xEC,
1212 0x98, 0xE1,
1213 0xB5, 0x05,
1214
1215 0xBD, 0x05,
1216 0x2E, 0x30,
1217 0x32, 0xC0, 0xA0, 0xE8,
1218
1219 0x33, 0xC0, 0xA0, 0xE8,
1220 0x74, 0x64, 0xC8, 0xEC,
1221
1222 0x40, 0x3C, 0x40, 0xAD,
1223 0x32, 0x6A,
1224 0x2A, 0x30,
1225
1226 0x20, 0x73,
1227 0x33, 0x6A,
1228 0x00, 0xE0,
1229 0x28, 0x73,
1230
1231 0x1C, 0x72,
1232 0x83, 0xE2,
1233 0x6F, 0x80, 0x15, 0xEA,
1234
1235 0xB8, 0x3D, 0x28, 0xDF,
1236 0x30, 0x35, 0x20, 0xDF,
1237
1238 0x40, 0x30,
1239 0x00, 0xE0,
1240 0xCC, 0xE2,
1241 0x64, 0x72,
1242
1243 0x25, 0x42, 0x52, 0xBF,
1244 0x2D, 0x42, 0x4A, 0xBF,
1245
1246 0x30, 0x2E, 0x30, 0xDF,
1247 0x38, 0x2E, 0x38, 0xDF,
1248
1249 0x18, 0x1D, 0x45, 0xE9,
1250 0x1E, 0x15, 0x45, 0xE9,
1251
1252 0x2B, 0x49, 0x51, 0xBD,
1253 0x00, 0xE0,
1254 0x1F, 0x73,
1255
1256 0x38, 0x38, 0x40, 0xAF,
1257 0x30, 0x30, 0x40, 0xAF,
1258
1259 0x24, 0x1F, 0x24, 0xDF,
1260 0x1D, 0x32, 0x20, 0xE9,
1261
1262 0x2C, 0x1F, 0x2C, 0xDF,
1263 0x1A, 0x33, 0x20, 0xE9,
1264
1265 0xB0, 0x10,
1266 0x08, 0xE3,
1267 0x40, 0x10,
1268 0xB8, 0x10,
1269
1270 0x26, 0xF0, 0x30, 0xCD,
1271 0x2F, 0xF0, 0x38, 0xCD,
1272
1273 0x2B, 0x80, 0x20, 0xE9,
1274 0x2A, 0x80, 0x20, 0xE9,
1275
1276 0xA6, 0x20,
1277 0x88, 0xE2,
1278 0x00, 0xE0,
1279 0xAF, 0x20,
1280
1281 0x28, 0x2A, 0x26, 0xAF,
1282 0x20, 0x2A, 0xC0, 0xAF,
1283
1284 0x34, 0x1F, 0x34, 0xDF,
1285 0x46, 0x24, 0x46, 0xDF,
1286
1287 0x28, 0x30, 0x80, 0xBF,
1288 0x20, 0x38, 0x80, 0xBF,
1289
1290 0x47, 0x24, 0x47, 0xDF,
1291 0x4E, 0x2C, 0x4E, 0xDF,
1292
1293 0x4F, 0x2C, 0x4F, 0xDF,
1294 0x56, 0x34, 0x56, 0xDF,
1295
1296 0x28, 0x15, 0x28, 0xDF,
1297 0x20, 0x1D, 0x20, 0xDF,
1298
1299 0x57, 0x34, 0x57, 0xDF,
1300 0x00, 0xE0,
1301 0x1D, 0x05,
1302
1303 0x04, 0x80, 0x10, 0xEA,
1304 0x89, 0xE2,
1305 0x2B, 0x30,
1306
1307 0x3F, 0xC1, 0x1D, 0xBD,
1308 0x00, 0x80, 0x00, 0xE8,
1309
1310 0x00, 0x80, 0x00, 0xE8,
1311 0x00, 0x80, 0x00, 0xE8,
1312
1313 0xA0, 0x68,
1314 0xBF, 0x25,
1315 0x00, 0x80, 0x00, 0xE8,
1316
1317 0x20, 0xC0, 0x20, 0xAF,
1318 0x28, 0x05,
1319 0x97, 0x74,
1320
1321 0x00, 0xE0,
1322 0x2A, 0x10,
1323 0x16, 0xC0, 0x20, 0xE9,
1324
1325 0x04, 0x80, 0x10, 0xEA,
1326 0x8C, 0xE2,
1327 0x95, 0x05,
1328
1329 0x28, 0xC1, 0x28, 0xAD,
1330 0x1F, 0xC1, 0x15, 0xBD,
1331
1332 0x00, 0x80, 0x00, 0xE8,
1333 0x00, 0x80, 0x00, 0xE8,
1334
1335 0xA8, 0x67,
1336 0x9F, 0x6B,
1337 0x00, 0x80, 0x00, 0xE8,
1338
1339 0x28, 0xC0, 0x28, 0xAD,
1340 0x1D, 0x25,
1341 0x20, 0x05,
1342
1343 0x28, 0x32, 0x80, 0xAD,
1344 0x40, 0x2A, 0x40, 0xBD,
1345
1346 0x1C, 0x80, 0x20, 0xE9,
1347 0x20, 0x33, 0x20, 0xAD,
1348
1349 0x20, 0x73,
1350 0x00, 0xE0,
1351 0xB6, 0x49, 0x51, 0xBB,
1352
1353 0x26, 0x2F, 0xB0, 0xE8,
1354 0x19, 0x20, 0x20, 0xE9,
1355
1356 0x35, 0x20, 0x35, 0xDF,
1357 0x3D, 0x20, 0x3D, 0xDF,
1358
1359 0x15, 0x20, 0x15, 0xDF,
1360 0x1D, 0x20, 0x1D, 0xDF,
1361
1362 0x26, 0xD0, 0x26, 0xCD,
1363 0x29, 0x49, 0x2A, 0xB8,
1364
1365 0x26, 0x40, 0x80, 0xBD,
1366 0x3B, 0x48, 0x50, 0xBD,
1367
1368 0x3E, 0x54, 0x57, 0x9F,
1369 0x00, 0xE0,
1370 0x82, 0xE1,
1371
1372 0x1E, 0xAF, 0x59, 0x9F,
1373 0x00, 0x80, 0x00, 0xE8,
1374
1375 0x26, 0x30,
1376 0x29, 0x30,
1377 0x48, 0x3C, 0x48, 0xAD,
1378
1379 0x2B, 0x72,
1380 0xC2, 0xE1,
1381 0x2C, 0xC0, 0x44, 0xC2,
1382
1383 0x05, 0x24, 0x34, 0xBF,
1384 0x0D, 0x24, 0x2C, 0xBF,
1385
1386 0x2D, 0x46, 0x4E, 0xBF,
1387 0x25, 0x46, 0x56, 0xBF,
1388
1389 0x20, 0x1D, 0x6F, 0x8F,
1390 0x32, 0x3E, 0x5F, 0xE9,
1391
1392 0x3E, 0x50, 0x56, 0x9F,
1393 0x00, 0xE0,
1394 0x3B, 0x30,
1395
1396 0x1E, 0x8F, 0x51, 0x9F,
1397 0x33, 0x1E, 0x5F, 0xE9,
1398
1399 0x05, 0x44, 0x54, 0xB2,
1400 0x0D, 0x44, 0x4C, 0xB2,
1401
1402 0x19, 0xC0, 0xB0, 0xE8,
1403 0x34, 0xC0, 0x44, 0xC4,
1404
1405 0x33, 0x73,
1406 0x00, 0xE0,
1407 0x3E, 0x62, 0x57, 0x9F,
1408
1409 0x1E, 0xAF, 0x59, 0x9F,
1410 0x00, 0xE0,
1411 0x0D, 0x20,
1412
1413 0x84, 0x3E, 0x58, 0xE9,
1414 0x28, 0x1D, 0x6F, 0x8F,
1415
1416 0x05, 0x20,
1417 0x00, 0xE0,
1418 0x85, 0x1E, 0x58, 0xE9,
1419
1420 0x9B, 0x3B, 0x33, 0xDF,
1421 0x20, 0x20, 0x42, 0xAF,
1422
1423 0x30, 0x42, 0x56, 0x9F,
1424 0x80, 0x3E, 0x57, 0xE9,
1425
1426 0x3F, 0x8F, 0x51, 0x9F,
1427 0x30, 0x80, 0x5F, 0xE9,
1428
1429 0x28, 0x28, 0x24, 0xAF,
1430 0x81, 0x1E, 0x57, 0xE9,
1431
1432 0x05, 0x47, 0x57, 0xBF,
1433 0x0D, 0x47, 0x4F, 0xBF,
1434
1435 0x88, 0x80, 0x58, 0xE9,
1436 0x1B, 0x29, 0x1B, 0xDF,
1437
1438 0x30, 0x1D, 0x6F, 0x8F,
1439 0x3A, 0x30, 0x4F, 0xE9,
1440
1441 0x1C, 0x30, 0x26, 0xDF,
1442 0x09, 0xE3,
1443 0x3B, 0x05,
1444
1445 0x3E, 0x50, 0x56, 0x9F,
1446 0x3B, 0x3F, 0x4F, 0xE9,
1447
1448 0x1E, 0x8F, 0x51, 0x9F,
1449 0x00, 0xE0,
1450 0xAC, 0x20,
1451
1452 0x2D, 0x44, 0x4C, 0xB4,
1453 0x2C, 0x1C, 0xC0, 0xAF,
1454
1455 0x25, 0x44, 0x54, 0xB4,
1456 0x00, 0xE0,
1457 0xC8, 0x30,
1458
1459 0x30, 0x46, 0x30, 0xAF,
1460 0x1B, 0x1B, 0x48, 0xAF,
1461
1462 0x00, 0xE0,
1463 0x25, 0x20,
1464 0x38, 0x2C, 0x4F, 0xE9,
1465
1466 0x86, 0x80, 0x57, 0xE9,
1467 0x38, 0x1D, 0x6F, 0x8F,
1468
1469 0x28, 0x74,
1470 0x00, 0xE0,
1471 0x0D, 0x44, 0x4C, 0xB0,
1472
1473 0x05, 0x44, 0x54, 0xB0,
1474 0x2D, 0x20,
1475 0x9B, 0x10,
1476
1477 0x82, 0x3E, 0x57, 0xE9,
1478 0x32, 0xF0, 0x1B, 0xCD,
1479
1480 0x1E, 0xBD, 0x59, 0x9F,
1481 0x83, 0x1E, 0x57, 0xE9,
1482
1483 0x38, 0x47, 0x38, 0xAF,
1484 0x34, 0x20,
1485 0x2A, 0x30,
1486
1487 0x00, 0xE0,
1488 0x0D, 0x20,
1489 0x32, 0x20,
1490 0x05, 0x20,
1491
1492 0x87, 0x80, 0x57, 0xE9,
1493 0x1F, 0x54, 0x57, 0x9F,
1494
1495 0x17, 0x42, 0x56, 0x9F,
1496 0x00, 0xE0,
1497 0x3B, 0x6A,
1498
1499 0x3F, 0x8F, 0x51, 0x9F,
1500 0x37, 0x1E, 0x4F, 0xE9,
1501
1502 0x37, 0x32, 0x2A, 0xAF,
1503 0x00, 0xE0,
1504 0x32, 0x00,
1505
1506 0x00, 0x80, 0x00, 0xE8,
1507 0x27, 0xC0, 0x44, 0xC0,
1508
1509 0x36, 0x1F, 0x4F, 0xE9,
1510 0x1F, 0x1F, 0x26, 0xDF,
1511
1512 0x37, 0x1B, 0x37, 0xBF,
1513 0x17, 0x26, 0x17, 0xDF,
1514
1515 0x3E, 0x17, 0x4F, 0xE9,
1516 0x3F, 0x3F, 0x4F, 0xE9,
1517
1518 0x34, 0x1F, 0x34, 0xAF,
1519 0x2B, 0x05,
1520 0xA7, 0x20,
1521
1522 0x33, 0x2B, 0x37, 0xDF,
1523 0x27, 0x17, 0xC0, 0xAF,
1524
1525 0x34, 0x80, 0x4F, 0xE9,
1526 0x00, 0x80, 0x00, 0xE8,
1527
1528 0x0D, 0x21, 0x1A, 0xB6,
1529 0x05, 0x21, 0x31, 0xB6,
1530
1531 0x2D, 0x44, 0x4C, 0xB6,
1532 0x25, 0x44, 0x54, 0xB6,
1533
1534 0x03, 0x80, 0x2A, 0xEA,
1535 0x17, 0xC1, 0x2B, 0xBD,
1536
1537 0x0D, 0x20,
1538 0x05, 0x20,
1539 0x2F, 0xC0, 0x21, 0xC6,
1540
1541 0xB3, 0x68,
1542 0x97, 0x25,
1543 0x00, 0x80, 0x00, 0xE8,
1544
1545 0x33, 0xC0, 0x33, 0xAF,
1546 0x3C, 0x27, 0x4F, 0xE9,
1547
1548 0x00, 0xE0,
1549 0x25, 0x20,
1550 0x07, 0xC0, 0x44, 0xC6,
1551
1552 0x17, 0x50, 0x56, 0x9F,
1553 0x00, 0xE0,
1554 0x2D, 0x20,
1555
1556 0x37, 0x0F, 0x5C, 0x9F,
1557 0x00, 0xE0,
1558 0x2F, 0x20,
1559
1560 0x1F, 0x62, 0x57, 0x9F,
1561 0x00, 0xE0,
1562 0x07, 0x20,
1563
1564 0x3F, 0x3D, 0x5D, 0x9F,
1565 0x00, 0x80, 0x00, 0xE8,
1566
1567 0x00, 0x80, 0x00, 0xE8,
1568 0x28, 0x19, 0x60, 0xEC,
1569
1570 0xB3, 0x05,
1571 0x00, 0xE0,
1572 0x17, 0x26, 0x17, 0xDF,
1573
1574 0x23, 0x3B, 0x33, 0xAD,
1575 0x35, 0x17, 0x4F, 0xE9,
1576
1577 0x1F, 0x26, 0x1F, 0xDF,
1578 0x9D, 0x1F, 0x4F, 0xE9,
1579
1580 0x9E, 0x3F, 0x4F, 0xE9,
1581 0x39, 0x37, 0x4F, 0xE9,
1582
1583 0x2F, 0x2F, 0x17, 0xAF,
1584 0x00, 0x80, 0x00, 0xE8,
1585
1586 0x07, 0x07, 0x1F, 0xAF,
1587 0x00, 0x80, 0x00, 0xE8,
1588
1589 0x31, 0x80, 0x4F, 0xE9,
1590 0x00, 0x80, 0x00, 0xE8,
1591
1592 0x9C, 0x80, 0x4F, 0xE9,
1593 0x00, 0x80, 0x00, 0xE8,
1594
1595 0x00, 0x80, 0x00, 0xE8,
1596 0x57, 0x39, 0x20, 0xE9,
1597
1598 0x16, 0x28, 0x20, 0xE9,
1599 0x1D, 0x3B, 0x20, 0xE9,
1600
1601 0x1E, 0x2B, 0x20, 0xE9,
1602 0x2B, 0x32, 0x20, 0xE9,
1603
1604 0x1C, 0x23, 0x20, 0xE9,
1605 0x57, 0x36, 0x20, 0xE9,
1606
1607 0x00, 0x80, 0xA0, 0xE9,
1608 0x40, 0x40, 0xD8, 0xEC,
1609
1610 0xFF, 0x80, 0xC0, 0xE9,
1611 0x90, 0xE2,
1612 0x00, 0xE0,
1613
1614 0x74, 0xFF, 0x20, 0xEA,
1615 0x19, 0xC8, 0xC1, 0xCD,
1616
1617 0x1F, 0xD7, 0x18, 0xBD,
1618 0x3F, 0xD7, 0x22, 0xBD,
1619
1620 0x9F, 0x41, 0x49, 0xBD,
1621 0x00, 0x80, 0x00, 0xE8,
1622
1623 0x25, 0x41, 0x49, 0xBD,
1624 0x2D, 0x41, 0x51, 0xBD,
1625
1626 0x0D, 0x80, 0x07, 0xEA,
1627 0x00, 0x80, 0x00, 0xE8,
1628
1629 0x35, 0x40, 0x48, 0xBD,
1630 0x3D, 0x40, 0x50, 0xBD,
1631
1632 0x00, 0x80, 0x00, 0xE8,
1633 0x25, 0x30,
1634 0x2D, 0x30,
1635
1636 0x35, 0x30,
1637 0xB5, 0x30,
1638 0xBD, 0x30,
1639 0x3D, 0x30,
1640
1641 0x9C, 0xA7, 0x5B, 0x9F,
1642 0x00, 0x80, 0x00, 0xE8,
1643
1644 0x00, 0x80, 0x00, 0xE8,
1645 0x00, 0x80, 0x00, 0xE8,
1646
1647 0x00, 0x80, 0x00, 0xE8,
1648 0x00, 0x80, 0x00, 0xE8,
1649
1650 0x00, 0x80, 0x00, 0xE8,
1651 0x00, 0x80, 0x00, 0xE8,
1652
1653 0x00, 0x80, 0x00, 0xE8,
1654 0x00, 0x80, 0x00, 0xE8,
1655
1656 0x73, 0xFF, 0x0A, 0xEA,
1657 0x00, 0x80, 0x00, 0xE8,
1658
1659 0xC9, 0x41, 0xC8, 0xEC,
1660 0x42, 0xE1,
1661 0x00, 0xE0,
1662
1663 0x71, 0xFF, 0x20, 0xEA,
1664 0x00, 0x80, 0x00, 0xE8,
1665
1666 0x00, 0x80, 0x00, 0xE8,
1667 0x00, 0x80, 0x00, 0xE8,
1668
1669 0xC8, 0x40, 0xC0, 0xEC,
1670 0x00, 0x80, 0x00, 0xE8,
1671
1672 0x6E, 0xFF, 0x20, 0xEA,
1673 0x00, 0x80, 0x00, 0xE8,
1674
1675 0x00, 0x80, 0x00, 0xE8,
1676 0x00, 0x80, 0x00, 0xE8,
1677
1678};
1679
1680static unsigned char warp_g200_tgzf[] = {
1681
1682 0x00, 0x80, 0x00, 0xE8,
1683 0x00, 0x80, 0x00, 0xE8,
1684
1685 0x00, 0x80, 0x00, 0xE8,
1686 0x00, 0x80, 0x00, 0xE8,
1687
1688 0x00, 0x80, 0x00, 0xE8,
1689 0x00, 0x80, 0x00, 0xE8,
1690
1691 0x00, 0x80, 0x00, 0xE8,
1692 0x00, 0x80, 0x00, 0xE8,
1693
1694 0x00, 0x80, 0x00, 0xE8,
1695 0x00, 0x80, 0x00, 0xE8,
1696
1697 0x00, 0x80, 0x00, 0xE8,
1698 0x00, 0x80, 0x00, 0xE8,
1699
1700 0x00, 0x80, 0x00, 0xE8,
1701 0x00, 0x80, 0x00, 0xE8,
1702
1703 0x00, 0x80, 0x00, 0xE8,
1704 0x00, 0x80, 0x00, 0xE8,
1705
1706 0x00, 0x80, 0x00, 0xE8,
1707 0x00, 0x80, 0x00, 0xE8,
1708
1709 0x00, 0x80, 0x00, 0xE8,
1710 0x00, 0x80, 0x00, 0xE8,
1711
1712 0x00, 0x98, 0xA0, 0xE9,
1713 0x40, 0x40, 0xD8, 0xEC,
1714
1715 0xFF, 0x80, 0xC0, 0xE9,
1716 0x00, 0x80, 0x00, 0xE8,
1717
1718 0x1F, 0xD7, 0x18, 0xBD,
1719 0x3F, 0xD7, 0x22, 0xBD,
1720
1721 0x81, 0x04,
1722 0x89, 0x04,
1723 0x01, 0x04,
1724 0x09, 0x04,
1725
1726 0xC9, 0x41, 0xC0, 0xEC,
1727 0x11, 0x04,
1728 0x00, 0xE0,
1729
1730 0x41, 0xCC, 0x41, 0xCD,
1731 0x49, 0xCC, 0x49, 0xCD,
1732
1733 0xD1, 0x41, 0xC0, 0xEC,
1734 0x51, 0xCC, 0x51, 0xCD,
1735
1736 0x80, 0x04,
1737 0x10, 0x04,
1738 0x08, 0x04,
1739 0x00, 0xE0,
1740
1741 0x00, 0xCC, 0xC0, 0xCD,
1742 0xD1, 0x49, 0xC0, 0xEC,
1743
1744 0x8A, 0x1F, 0x20, 0xE9,
1745 0x8B, 0x3F, 0x20, 0xE9,
1746
1747 0x41, 0x3C, 0x41, 0xAD,
1748 0x49, 0x3C, 0x49, 0xAD,
1749
1750 0x10, 0xCC, 0x10, 0xCD,
1751 0x08, 0xCC, 0x08, 0xCD,
1752
1753 0xB9, 0x41, 0x49, 0xBB,
1754 0x1F, 0xF0, 0x41, 0xCD,
1755
1756 0x51, 0x3C, 0x51, 0xAD,
1757 0x00, 0x98, 0x80, 0xE9,
1758
1759 0x7F, 0x80, 0x07, 0xEA,
1760 0x24, 0x1F, 0x20, 0xE9,
1761
1762 0x21, 0x45, 0x80, 0xE8,
1763 0x1A, 0x4D, 0x80, 0xE8,
1764
1765 0x31, 0x55, 0x80, 0xE8,
1766 0x00, 0x80, 0x00, 0xE8,
1767
1768 0x15, 0x41, 0x49, 0xBD,
1769 0x1D, 0x41, 0x51, 0xBD,
1770
1771 0x2E, 0x41, 0x2A, 0xB8,
1772 0x34, 0x53, 0xA0, 0xE8,
1773
1774 0x15, 0x30,
1775 0x1D, 0x30,
1776 0x58, 0xE3,
1777 0x00, 0xE0,
1778
1779 0xB5, 0x40, 0x48, 0xBD,
1780 0x3D, 0x40, 0x50, 0xBD,
1781
1782 0x24, 0x43, 0xA0, 0xE8,
1783 0x2C, 0x4B, 0xA0, 0xE8,
1784
1785 0x15, 0x72,
1786 0x09, 0xE3,
1787 0x00, 0xE0,
1788 0x1D, 0x72,
1789
1790 0x35, 0x30,
1791 0xB5, 0x30,
1792 0xBD, 0x30,
1793 0x3D, 0x30,
1794
1795 0x9C, 0x97, 0x57, 0x9F,
1796 0x00, 0x80, 0x00, 0xE8,
1797
1798 0x6C, 0x64, 0xC8, 0xEC,
1799 0x98, 0xE1,
1800 0xB5, 0x05,
1801
1802 0xBD, 0x05,
1803 0x2E, 0x30,
1804 0x32, 0xC0, 0xA0, 0xE8,
1805
1806 0x33, 0xC0, 0xA0, 0xE8,
1807 0x74, 0x64, 0xC8, 0xEC,
1808
1809 0x40, 0x3C, 0x40, 0xAD,
1810 0x32, 0x6A,
1811 0x2A, 0x30,
1812
1813 0x20, 0x73,
1814 0x33, 0x6A,
1815 0x00, 0xE0,
1816 0x28, 0x73,
1817
1818 0x1C, 0x72,
1819 0x83, 0xE2,
1820 0x6B, 0x80, 0x15, 0xEA,
1821
1822 0xB8, 0x3D, 0x28, 0xDF,
1823 0x30, 0x35, 0x20, 0xDF,
1824
1825 0x40, 0x30,
1826 0x00, 0xE0,
1827 0xCC, 0xE2,
1828 0x64, 0x72,
1829
1830 0x25, 0x42, 0x52, 0xBF,
1831 0x2D, 0x42, 0x4A, 0xBF,
1832
1833 0x30, 0x2E, 0x30, 0xDF,
1834 0x38, 0x2E, 0x38, 0xDF,
1835
1836 0x18, 0x1D, 0x45, 0xE9,
1837 0x1E, 0x15, 0x45, 0xE9,
1838
1839 0x2B, 0x49, 0x51, 0xBD,
1840 0x00, 0xE0,
1841 0x1F, 0x73,
1842
1843 0x38, 0x38, 0x40, 0xAF,
1844 0x30, 0x30, 0x40, 0xAF,
1845
1846 0x24, 0x1F, 0x24, 0xDF,
1847 0x1D, 0x32, 0x20, 0xE9,
1848
1849 0x2C, 0x1F, 0x2C, 0xDF,
1850 0x1A, 0x33, 0x20, 0xE9,
1851
1852 0xB0, 0x10,
1853 0x08, 0xE3,
1854 0x40, 0x10,
1855 0xB8, 0x10,
1856
1857 0x26, 0xF0, 0x30, 0xCD,
1858 0x2F, 0xF0, 0x38, 0xCD,
1859
1860 0x2B, 0x80, 0x20, 0xE9,
1861 0x2A, 0x80, 0x20, 0xE9,
1862
1863 0xA6, 0x20,
1864 0x88, 0xE2,
1865 0x00, 0xE0,
1866 0xAF, 0x20,
1867
1868 0x28, 0x2A, 0x26, 0xAF,
1869 0x20, 0x2A, 0xC0, 0xAF,
1870
1871 0x34, 0x1F, 0x34, 0xDF,
1872 0x46, 0x24, 0x46, 0xDF,
1873
1874 0x28, 0x30, 0x80, 0xBF,
1875 0x20, 0x38, 0x80, 0xBF,
1876
1877 0x47, 0x24, 0x47, 0xDF,
1878 0x4E, 0x2C, 0x4E, 0xDF,
1879
1880 0x4F, 0x2C, 0x4F, 0xDF,
1881 0x56, 0x34, 0x56, 0xDF,
1882
1883 0x28, 0x15, 0x28, 0xDF,
1884 0x20, 0x1D, 0x20, 0xDF,
1885
1886 0x57, 0x34, 0x57, 0xDF,
1887 0x00, 0xE0,
1888 0x1D, 0x05,
1889
1890 0x04, 0x80, 0x10, 0xEA,
1891 0x89, 0xE2,
1892 0x2B, 0x30,
1893
1894 0x3F, 0xC1, 0x1D, 0xBD,
1895 0x00, 0x80, 0x00, 0xE8,
1896
1897 0x00, 0x80, 0x00, 0xE8,
1898 0x00, 0x80, 0x00, 0xE8,
1899
1900 0xA0, 0x68,
1901 0xBF, 0x25,
1902 0x00, 0x80, 0x00, 0xE8,
1903
1904 0x20, 0xC0, 0x20, 0xAF,
1905 0x28, 0x05,
1906 0x97, 0x74,
1907
1908 0x00, 0xE0,
1909 0x2A, 0x10,
1910 0x16, 0xC0, 0x20, 0xE9,
1911
1912 0x04, 0x80, 0x10, 0xEA,
1913 0x8C, 0xE2,
1914 0x95, 0x05,
1915
1916 0x28, 0xC1, 0x28, 0xAD,
1917 0x1F, 0xC1, 0x15, 0xBD,
1918
1919 0x00, 0x80, 0x00, 0xE8,
1920 0x00, 0x80, 0x00, 0xE8,
1921
1922 0xA8, 0x67,
1923 0x9F, 0x6B,
1924 0x00, 0x80, 0x00, 0xE8,
1925
1926 0x28, 0xC0, 0x28, 0xAD,
1927 0x1D, 0x25,
1928 0x20, 0x05,
1929
1930 0x28, 0x32, 0x80, 0xAD,
1931 0x40, 0x2A, 0x40, 0xBD,
1932
1933 0x1C, 0x80, 0x20, 0xE9,
1934 0x20, 0x33, 0x20, 0xAD,
1935
1936 0x20, 0x73,
1937 0x00, 0xE0,
1938 0xB6, 0x49, 0x51, 0xBB,
1939
1940 0x26, 0x2F, 0xB0, 0xE8,
1941 0x19, 0x20, 0x20, 0xE9,
1942
1943 0x35, 0x20, 0x35, 0xDF,
1944 0x3D, 0x20, 0x3D, 0xDF,
1945
1946 0x15, 0x20, 0x15, 0xDF,
1947 0x1D, 0x20, 0x1D, 0xDF,
1948
1949 0x26, 0xD0, 0x26, 0xCD,
1950 0x29, 0x49, 0x2A, 0xB8,
1951
1952 0x26, 0x40, 0x80, 0xBD,
1953 0x3B, 0x48, 0x50, 0xBD,
1954
1955 0x3E, 0x54, 0x57, 0x9F,
1956 0x00, 0xE0,
1957 0x82, 0xE1,
1958
1959 0x1E, 0xAF, 0x59, 0x9F,
1960 0x00, 0x80, 0x00, 0xE8,
1961
1962 0x26, 0x30,
1963 0x29, 0x30,
1964 0x48, 0x3C, 0x48, 0xAD,
1965
1966 0x2B, 0x72,
1967 0xC2, 0xE1,
1968 0x2C, 0xC0, 0x44, 0xC2,
1969
1970 0x05, 0x24, 0x34, 0xBF,
1971 0x0D, 0x24, 0x2C, 0xBF,
1972
1973 0x2D, 0x46, 0x4E, 0xBF,
1974 0x25, 0x46, 0x56, 0xBF,
1975
1976 0x20, 0x1D, 0x6F, 0x8F,
1977 0x32, 0x3E, 0x5F, 0xE9,
1978
1979 0x3E, 0x50, 0x56, 0x9F,
1980 0x00, 0xE0,
1981 0x3B, 0x30,
1982
1983 0x1E, 0x8F, 0x51, 0x9F,
1984 0x33, 0x1E, 0x5F, 0xE9,
1985
1986 0x05, 0x44, 0x54, 0xB2,
1987 0x0D, 0x44, 0x4C, 0xB2,
1988
1989 0x19, 0xC0, 0xB0, 0xE8,
1990 0x34, 0xC0, 0x44, 0xC4,
1991
1992 0x33, 0x73,
1993 0x00, 0xE0,
1994 0x3E, 0x62, 0x57, 0x9F,
1995
1996 0x1E, 0xAF, 0x59, 0x9F,
1997 0x00, 0xE0,
1998 0x0D, 0x20,
1999
2000 0x84, 0x3E, 0x58, 0xE9,
2001 0x28, 0x1D, 0x6F, 0x8F,
2002
2003 0x05, 0x20,
2004 0x00, 0xE0,
2005 0x85, 0x1E, 0x58, 0xE9,
2006
2007 0x9B, 0x3B, 0x33, 0xDF,
2008 0x20, 0x20, 0x42, 0xAF,
2009
2010 0x30, 0x42, 0x56, 0x9F,
2011 0x80, 0x3E, 0x57, 0xE9,
2012
2013 0x3F, 0x8F, 0x51, 0x9F,
2014 0x30, 0x80, 0x5F, 0xE9,
2015
2016 0x28, 0x28, 0x24, 0xAF,
2017 0x81, 0x1E, 0x57, 0xE9,
2018
2019 0x05, 0x47, 0x57, 0xBF,
2020 0x0D, 0x47, 0x4F, 0xBF,
2021
2022 0x88, 0x80, 0x58, 0xE9,
2023 0x1B, 0x29, 0x1B, 0xDF,
2024
2025 0x30, 0x1D, 0x6F, 0x8F,
2026 0x3A, 0x30, 0x4F, 0xE9,
2027
2028 0x1C, 0x30, 0x26, 0xDF,
2029 0x09, 0xE3,
2030 0x3B, 0x05,
2031
2032 0x3E, 0x50, 0x56, 0x9F,
2033 0x3B, 0x3F, 0x4F, 0xE9,
2034
2035 0x1E, 0x8F, 0x51, 0x9F,
2036 0x00, 0xE0,
2037 0xAC, 0x20,
2038
2039 0x2D, 0x44, 0x4C, 0xB4,
2040 0x2C, 0x1C, 0xC0, 0xAF,
2041
2042 0x25, 0x44, 0x54, 0xB4,
2043 0x00, 0xE0,
2044 0xC8, 0x30,
2045
2046 0x30, 0x46, 0x30, 0xAF,
2047 0x1B, 0x1B, 0x48, 0xAF,
2048
2049 0x00, 0xE0,
2050 0x25, 0x20,
2051 0x38, 0x2C, 0x4F, 0xE9,
2052
2053 0x86, 0x80, 0x57, 0xE9,
2054 0x38, 0x1D, 0x6F, 0x8F,
2055
2056 0x28, 0x74,
2057 0x00, 0xE0,
2058 0x0D, 0x44, 0x4C, 0xB0,
2059
2060 0x05, 0x44, 0x54, 0xB0,
2061 0x2D, 0x20,
2062 0x9B, 0x10,
2063
2064 0x82, 0x3E, 0x57, 0xE9,
2065 0x32, 0xF0, 0x1B, 0xCD,
2066
2067 0x1E, 0xBD, 0x59, 0x9F,
2068 0x83, 0x1E, 0x57, 0xE9,
2069
2070 0x38, 0x47, 0x38, 0xAF,
2071 0x34, 0x20,
2072 0x2A, 0x30,
2073
2074 0x00, 0xE0,
2075 0x0D, 0x20,
2076 0x32, 0x20,
2077 0x05, 0x20,
2078
2079 0x87, 0x80, 0x57, 0xE9,
2080 0x1F, 0x54, 0x57, 0x9F,
2081
2082 0x17, 0x42, 0x56, 0x9F,
2083 0x00, 0xE0,
2084 0x3B, 0x6A,
2085
2086 0x3F, 0x8F, 0x51, 0x9F,
2087 0x37, 0x1E, 0x4F, 0xE9,
2088
2089 0x37, 0x32, 0x2A, 0xAF,
2090 0x00, 0xE0,
2091 0x32, 0x00,
2092
2093 0x00, 0x80, 0x00, 0xE8,
2094 0x27, 0xC0, 0x44, 0xC0,
2095
2096 0x36, 0x1F, 0x4F, 0xE9,
2097 0x1F, 0x1F, 0x26, 0xDF,
2098
2099 0x37, 0x1B, 0x37, 0xBF,
2100 0x17, 0x26, 0x17, 0xDF,
2101
2102 0x3E, 0x17, 0x4F, 0xE9,
2103 0x3F, 0x3F, 0x4F, 0xE9,
2104
2105 0x34, 0x1F, 0x34, 0xAF,
2106 0x2B, 0x05,
2107 0xA7, 0x20,
2108
2109 0x33, 0x2B, 0x37, 0xDF,
2110 0x27, 0x17, 0xC0, 0xAF,
2111
2112 0x34, 0x80, 0x4F, 0xE9,
2113 0x00, 0x80, 0x00, 0xE8,
2114
2115 0x0D, 0x21, 0x1A, 0xB6,
2116 0x05, 0x21, 0x31, 0xB6,
2117
2118 0x03, 0x80, 0x2A, 0xEA,
2119 0x17, 0xC1, 0x2B, 0xBD,
2120
2121 0x0D, 0x20,
2122 0x05, 0x20,
2123 0x2F, 0xC0, 0x21, 0xC6,
2124
2125 0xB3, 0x68,
2126 0x97, 0x25,
2127 0x00, 0x80, 0x00, 0xE8,
2128
2129 0x33, 0xC0, 0x33, 0xAF,
2130 0x3C, 0x27, 0x4F, 0xE9,
2131
2132 0x17, 0x50, 0x56, 0x9F,
2133 0x00, 0x80, 0x00, 0xE8,
2134
2135 0x37, 0x0F, 0x5C, 0x9F,
2136 0x00, 0xE0,
2137 0x2F, 0x20,
2138
2139 0x00, 0x80, 0x00, 0xE8,
2140 0x28, 0x19, 0x60, 0xEC,
2141
2142 0xB3, 0x05,
2143 0x00, 0xE0,
2144 0x00, 0x80, 0x00, 0xE8,
2145
2146 0x23, 0x3B, 0x33, 0xAD,
2147 0x00, 0x80, 0x00, 0xE8,
2148
2149 0x17, 0x26, 0x17, 0xDF,
2150 0x35, 0x17, 0x4F, 0xE9,
2151
2152 0x00, 0x80, 0x00, 0xE8,
2153 0x00, 0x80, 0x00, 0xE8,
2154
2155 0x00, 0x80, 0x00, 0xE8,
2156 0x39, 0x37, 0x4F, 0xE9,
2157
2158 0x2F, 0x2F, 0x17, 0xAF,
2159 0x00, 0x80, 0x00, 0xE8,
2160
2161 0x00, 0x80, 0x00, 0xE8,
2162 0x00, 0x80, 0x00, 0xE8,
2163
2164 0x31, 0x80, 0x4F, 0xE9,
2165 0x00, 0x80, 0x00, 0xE8,
2166
2167 0x00, 0x80, 0x00, 0xE8,
2168 0x57, 0x39, 0x20, 0xE9,
2169
2170 0x16, 0x28, 0x20, 0xE9,
2171 0x1D, 0x3B, 0x20, 0xE9,
2172
2173 0x1E, 0x2B, 0x20, 0xE9,
2174 0x2B, 0x32, 0x20, 0xE9,
2175
2176 0x1C, 0x23, 0x20, 0xE9,
2177 0x57, 0x36, 0x20, 0xE9,
2178
2179 0x00, 0x80, 0xA0, 0xE9,
2180 0x40, 0x40, 0xD8, 0xEC,
2181
2182 0xFF, 0x80, 0xC0, 0xE9,
2183 0x90, 0xE2,
2184 0x00, 0xE0,
2185
2186 0x78, 0xFF, 0x20, 0xEA,
2187 0x19, 0xC8, 0xC1, 0xCD,
2188
2189 0x1F, 0xD7, 0x18, 0xBD,
2190 0x3F, 0xD7, 0x22, 0xBD,
2191
2192 0x9F, 0x41, 0x49, 0xBD,
2193 0x00, 0x80, 0x00, 0xE8,
2194
2195 0x25, 0x41, 0x49, 0xBD,
2196 0x2D, 0x41, 0x51, 0xBD,
2197
2198 0x0D, 0x80, 0x07, 0xEA,
2199 0x00, 0x80, 0x00, 0xE8,
2200
2201 0x35, 0x40, 0x48, 0xBD,
2202 0x3D, 0x40, 0x50, 0xBD,
2203
2204 0x00, 0x80, 0x00, 0xE8,
2205 0x25, 0x30,
2206 0x2D, 0x30,
2207
2208 0x35, 0x30,
2209 0xB5, 0x30,
2210 0xBD, 0x30,
2211 0x3D, 0x30,
2212
2213 0x9C, 0xA7, 0x5B, 0x9F,
2214 0x00, 0x80, 0x00, 0xE8,
2215
2216 0x00, 0x80, 0x00, 0xE8,
2217 0x00, 0x80, 0x00, 0xE8,
2218
2219 0x00, 0x80, 0x00, 0xE8,
2220 0x00, 0x80, 0x00, 0xE8,
2221
2222 0x00, 0x80, 0x00, 0xE8,
2223 0x00, 0x80, 0x00, 0xE8,
2224
2225 0x00, 0x80, 0x00, 0xE8,
2226 0x00, 0x80, 0x00, 0xE8,
2227
2228 0x77, 0xFF, 0x0A, 0xEA,
2229 0x00, 0x80, 0x00, 0xE8,
2230
2231 0xC9, 0x41, 0xC8, 0xEC,
2232 0x42, 0xE1,
2233 0x00, 0xE0,
2234
2235 0x75, 0xFF, 0x20, 0xEA,
2236 0x00, 0x80, 0x00, 0xE8,
2237
2238 0x00, 0x80, 0x00, 0xE8,
2239 0x00, 0x80, 0x00, 0xE8,
2240
2241 0xC8, 0x40, 0xC0, 0xEC,
2242 0x00, 0x80, 0x00, 0xE8,
2243
2244 0x72, 0xFF, 0x20, 0xEA,
2245 0x00, 0x80, 0x00, 0xE8,
2246
2247 0x00, 0x80, 0x00, 0xE8,
2248 0x00, 0x80, 0x00, 0xE8,
2249
2250};
2251
2252static unsigned char warp_g200_tgzs[] = {
2253
2254 0x00, 0x80, 0x00, 0xE8,
2255 0x00, 0x80, 0x00, 0xE8,
2256
2257 0x00, 0x80, 0x00, 0xE8,
2258 0x00, 0x80, 0x00, 0xE8,
2259
2260 0x00, 0x80, 0x00, 0xE8,
2261 0x00, 0x80, 0x00, 0xE8,
2262
2263 0x00, 0x80, 0x00, 0xE8,
2264 0x00, 0x80, 0x00, 0xE8,
2265
2266 0x00, 0x80, 0x00, 0xE8,
2267 0x00, 0x80, 0x00, 0xE8,
2268
2269 0x00, 0x80, 0x00, 0xE8,
2270 0x00, 0x80, 0x00, 0xE8,
2271
2272 0x00, 0x80, 0x00, 0xE8,
2273 0x00, 0x80, 0x00, 0xE8,
2274
2275 0x00, 0x80, 0x00, 0xE8,
2276 0x00, 0x80, 0x00, 0xE8,
2277
2278 0x00, 0x80, 0x00, 0xE8,
2279 0x00, 0x80, 0x00, 0xE8,
2280
2281 0x00, 0x80, 0x00, 0xE8,
2282 0x00, 0x80, 0x00, 0xE8,
2283
2284 0x00, 0x80, 0x00, 0xE8,
2285 0x00, 0x80, 0x00, 0xE8,
2286
2287 0x00, 0x80, 0x00, 0xE8,
2288 0x00, 0x80, 0x00, 0xE8,
2289
2290 0x00, 0x80, 0x00, 0xE8,
2291 0x00, 0x80, 0x00, 0xE8,
2292
2293 0x00, 0x98, 0xA0, 0xE9,
2294 0x40, 0x40, 0xD8, 0xEC,
2295
2296 0xFF, 0x80, 0xC0, 0xE9,
2297 0x00, 0x80, 0x00, 0xE8,
2298
2299 0x1F, 0xD7, 0x18, 0xBD,
2300 0x3F, 0xD7, 0x22, 0xBD,
2301
2302 0x81, 0x04,
2303 0x89, 0x04,
2304 0x01, 0x04,
2305 0x09, 0x04,
2306
2307 0xC9, 0x41, 0xC0, 0xEC,
2308 0x11, 0x04,
2309 0x00, 0xE0,
2310
2311 0x41, 0xCC, 0x41, 0xCD,
2312 0x49, 0xCC, 0x49, 0xCD,
2313
2314 0xD1, 0x41, 0xC0, 0xEC,
2315 0x51, 0xCC, 0x51, 0xCD,
2316
2317 0x80, 0x04,
2318 0x10, 0x04,
2319 0x08, 0x04,
2320 0x00, 0xE0,
2321
2322 0x00, 0xCC, 0xC0, 0xCD,
2323 0xD1, 0x49, 0xC0, 0xEC,
2324
2325 0x8A, 0x1F, 0x20, 0xE9,
2326 0x8B, 0x3F, 0x20, 0xE9,
2327
2328 0x41, 0x3C, 0x41, 0xAD,
2329 0x49, 0x3C, 0x49, 0xAD,
2330
2331 0x10, 0xCC, 0x10, 0xCD,
2332 0x08, 0xCC, 0x08, 0xCD,
2333
2334 0xB9, 0x41, 0x49, 0xBB,
2335 0x1F, 0xF0, 0x41, 0xCD,
2336
2337 0x51, 0x3C, 0x51, 0xAD,
2338 0x00, 0x98, 0x80, 0xE9,
2339
2340 0x8B, 0x80, 0x07, 0xEA,
2341 0x24, 0x1F, 0x20, 0xE9,
2342
2343 0x21, 0x45, 0x80, 0xE8,
2344 0x1A, 0x4D, 0x80, 0xE8,
2345
2346 0x31, 0x55, 0x80, 0xE8,
2347 0x00, 0x80, 0x00, 0xE8,
2348
2349 0x15, 0x41, 0x49, 0xBD,
2350 0x1D, 0x41, 0x51, 0xBD,
2351
2352 0x2E, 0x41, 0x2A, 0xB8,
2353 0x34, 0x53, 0xA0, 0xE8,
2354
2355 0x15, 0x30,
2356 0x1D, 0x30,
2357 0x58, 0xE3,
2358 0x00, 0xE0,
2359
2360 0xB5, 0x40, 0x48, 0xBD,
2361 0x3D, 0x40, 0x50, 0xBD,
2362
2363 0x24, 0x43, 0xA0, 0xE8,
2364 0x2C, 0x4B, 0xA0, 0xE8,
2365
2366 0x15, 0x72,
2367 0x09, 0xE3,
2368 0x00, 0xE0,
2369 0x1D, 0x72,
2370
2371 0x35, 0x30,
2372 0xB5, 0x30,
2373 0xBD, 0x30,
2374 0x3D, 0x30,
2375
2376 0x9C, 0x97, 0x57, 0x9F,
2377 0x00, 0x80, 0x00, 0xE8,
2378
2379 0x6C, 0x64, 0xC8, 0xEC,
2380 0x98, 0xE1,
2381 0xB5, 0x05,
2382
2383 0xBD, 0x05,
2384 0x2E, 0x30,
2385 0x32, 0xC0, 0xA0, 0xE8,
2386
2387 0x33, 0xC0, 0xA0, 0xE8,
2388 0x74, 0x64, 0xC8, 0xEC,
2389
2390 0x40, 0x3C, 0x40, 0xAD,
2391 0x32, 0x6A,
2392 0x2A, 0x30,
2393
2394 0x20, 0x73,
2395 0x33, 0x6A,
2396 0x00, 0xE0,
2397 0x28, 0x73,
2398
2399 0x1C, 0x72,
2400 0x83, 0xE2,
2401 0x77, 0x80, 0x15, 0xEA,
2402
2403 0xB8, 0x3D, 0x28, 0xDF,
2404 0x30, 0x35, 0x20, 0xDF,
2405
2406 0x40, 0x30,
2407 0x00, 0xE0,
2408 0xCC, 0xE2,
2409 0x64, 0x72,
2410
2411 0x25, 0x42, 0x52, 0xBF,
2412 0x2D, 0x42, 0x4A, 0xBF,
2413
2414 0x30, 0x2E, 0x30, 0xDF,
2415 0x38, 0x2E, 0x38, 0xDF,
2416
2417 0x18, 0x1D, 0x45, 0xE9,
2418 0x1E, 0x15, 0x45, 0xE9,
2419
2420 0x2B, 0x49, 0x51, 0xBD,
2421 0x00, 0xE0,
2422 0x1F, 0x73,
2423
2424 0x38, 0x38, 0x40, 0xAF,
2425 0x30, 0x30, 0x40, 0xAF,
2426
2427 0x24, 0x1F, 0x24, 0xDF,
2428 0x1D, 0x32, 0x20, 0xE9,
2429
2430 0x2C, 0x1F, 0x2C, 0xDF,
2431 0x1A, 0x33, 0x20, 0xE9,
2432
2433 0xB0, 0x10,
2434 0x08, 0xE3,
2435 0x40, 0x10,
2436 0xB8, 0x10,
2437
2438 0x26, 0xF0, 0x30, 0xCD,
2439 0x2F, 0xF0, 0x38, 0xCD,
2440
2441 0x2B, 0x80, 0x20, 0xE9,
2442 0x2A, 0x80, 0x20, 0xE9,
2443
2444 0xA6, 0x20,
2445 0x88, 0xE2,
2446 0x00, 0xE0,
2447 0xAF, 0x20,
2448
2449 0x28, 0x2A, 0x26, 0xAF,
2450 0x20, 0x2A, 0xC0, 0xAF,
2451
2452 0x34, 0x1F, 0x34, 0xDF,
2453 0x46, 0x24, 0x46, 0xDF,
2454
2455 0x28, 0x30, 0x80, 0xBF,
2456 0x20, 0x38, 0x80, 0xBF,
2457
2458 0x47, 0x24, 0x47, 0xDF,
2459 0x4E, 0x2C, 0x4E, 0xDF,
2460
2461 0x4F, 0x2C, 0x4F, 0xDF,
2462 0x56, 0x34, 0x56, 0xDF,
2463
2464 0x28, 0x15, 0x28, 0xDF,
2465 0x20, 0x1D, 0x20, 0xDF,
2466
2467 0x57, 0x34, 0x57, 0xDF,
2468 0x00, 0xE0,
2469 0x1D, 0x05,
2470
2471 0x04, 0x80, 0x10, 0xEA,
2472 0x89, 0xE2,
2473 0x2B, 0x30,
2474
2475 0x3F, 0xC1, 0x1D, 0xBD,
2476 0x00, 0x80, 0x00, 0xE8,
2477
2478 0x00, 0x80, 0x00, 0xE8,
2479 0x00, 0x80, 0x00, 0xE8,
2480
2481 0xA0, 0x68,
2482 0xBF, 0x25,
2483 0x00, 0x80, 0x00, 0xE8,
2484
2485 0x20, 0xC0, 0x20, 0xAF,
2486 0x28, 0x05,
2487 0x97, 0x74,
2488
2489 0x00, 0xE0,
2490 0x2A, 0x10,
2491 0x16, 0xC0, 0x20, 0xE9,
2492
2493 0x04, 0x80, 0x10, 0xEA,
2494 0x8C, 0xE2,
2495 0x95, 0x05,
2496
2497 0x28, 0xC1, 0x28, 0xAD,
2498 0x1F, 0xC1, 0x15, 0xBD,
2499
2500 0x00, 0x80, 0x00, 0xE8,
2501 0x00, 0x80, 0x00, 0xE8,
2502
2503 0xA8, 0x67,
2504 0x9F, 0x6B,
2505 0x00, 0x80, 0x00, 0xE8,
2506
2507 0x28, 0xC0, 0x28, 0xAD,
2508 0x1D, 0x25,
2509 0x20, 0x05,
2510
2511 0x28, 0x32, 0x80, 0xAD,
2512 0x40, 0x2A, 0x40, 0xBD,
2513
2514 0x1C, 0x80, 0x20, 0xE9,
2515 0x20, 0x33, 0x20, 0xAD,
2516
2517 0x20, 0x73,
2518 0x00, 0xE0,
2519 0xB6, 0x49, 0x51, 0xBB,
2520
2521 0x26, 0x2F, 0xB0, 0xE8,
2522 0x19, 0x20, 0x20, 0xE9,
2523
2524 0x35, 0x20, 0x35, 0xDF,
2525 0x3D, 0x20, 0x3D, 0xDF,
2526
2527 0x15, 0x20, 0x15, 0xDF,
2528 0x1D, 0x20, 0x1D, 0xDF,
2529
2530 0x26, 0xD0, 0x26, 0xCD,
2531 0x29, 0x49, 0x2A, 0xB8,
2532
2533 0x26, 0x40, 0x80, 0xBD,
2534 0x3B, 0x48, 0x50, 0xBD,
2535
2536 0x3E, 0x54, 0x57, 0x9F,
2537 0x00, 0xE0,
2538 0x82, 0xE1,
2539
2540 0x1E, 0xAF, 0x59, 0x9F,
2541 0x00, 0x80, 0x00, 0xE8,
2542
2543 0x26, 0x30,
2544 0x29, 0x30,
2545 0x48, 0x3C, 0x48, 0xAD,
2546
2547 0x2B, 0x72,
2548 0xC2, 0xE1,
2549 0x2C, 0xC0, 0x44, 0xC2,
2550
2551 0x05, 0x24, 0x34, 0xBF,
2552 0x0D, 0x24, 0x2C, 0xBF,
2553
2554 0x2D, 0x46, 0x4E, 0xBF,
2555 0x25, 0x46, 0x56, 0xBF,
2556
2557 0x20, 0x1D, 0x6F, 0x8F,
2558 0x32, 0x3E, 0x5F, 0xE9,
2559
2560 0x3E, 0x50, 0x56, 0x9F,
2561 0x00, 0xE0,
2562 0x3B, 0x30,
2563
2564 0x1E, 0x8F, 0x51, 0x9F,
2565 0x33, 0x1E, 0x5F, 0xE9,
2566
2567 0x05, 0x44, 0x54, 0xB2,
2568 0x0D, 0x44, 0x4C, 0xB2,
2569
2570 0x19, 0xC0, 0xB0, 0xE8,
2571 0x34, 0xC0, 0x44, 0xC4,
2572
2573 0x33, 0x73,
2574 0x00, 0xE0,
2575 0x3E, 0x62, 0x57, 0x9F,
2576
2577 0x1E, 0xAF, 0x59, 0x9F,
2578 0x00, 0xE0,
2579 0x0D, 0x20,
2580
2581 0x84, 0x3E, 0x58, 0xE9,
2582 0x28, 0x1D, 0x6F, 0x8F,
2583
2584 0x05, 0x20,
2585 0x00, 0xE0,
2586 0x85, 0x1E, 0x58, 0xE9,
2587
2588 0x9B, 0x3B, 0x33, 0xDF,
2589 0x20, 0x20, 0x42, 0xAF,
2590
2591 0x30, 0x42, 0x56, 0x9F,
2592 0x80, 0x3E, 0x57, 0xE9,
2593
2594 0x3F, 0x8F, 0x51, 0x9F,
2595 0x30, 0x80, 0x5F, 0xE9,
2596
2597 0x28, 0x28, 0x24, 0xAF,
2598 0x81, 0x1E, 0x57, 0xE9,
2599
2600 0x05, 0x47, 0x57, 0xBF,
2601 0x0D, 0x47, 0x4F, 0xBF,
2602
2603 0x88, 0x80, 0x58, 0xE9,
2604 0x1B, 0x29, 0x1B, 0xDF,
2605
2606 0x30, 0x1D, 0x6F, 0x8F,
2607 0x3A, 0x30, 0x4F, 0xE9,
2608
2609 0x1C, 0x30, 0x26, 0xDF,
2610 0x09, 0xE3,
2611 0x3B, 0x05,
2612
2613 0x3E, 0x50, 0x56, 0x9F,
2614 0x3B, 0x3F, 0x4F, 0xE9,
2615
2616 0x1E, 0x8F, 0x51, 0x9F,
2617 0x00, 0xE0,
2618 0xAC, 0x20,
2619
2620 0x2D, 0x44, 0x4C, 0xB4,
2621 0x2C, 0x1C, 0xC0, 0xAF,
2622
2623 0x25, 0x44, 0x54, 0xB4,
2624 0x00, 0xE0,
2625 0xC8, 0x30,
2626
2627 0x30, 0x46, 0x30, 0xAF,
2628 0x1B, 0x1B, 0x48, 0xAF,
2629
2630 0x00, 0xE0,
2631 0x25, 0x20,
2632 0x38, 0x2C, 0x4F, 0xE9,
2633
2634 0x86, 0x80, 0x57, 0xE9,
2635 0x38, 0x1D, 0x6F, 0x8F,
2636
2637 0x28, 0x74,
2638 0x00, 0xE0,
2639 0x0D, 0x44, 0x4C, 0xB0,
2640
2641 0x05, 0x44, 0x54, 0xB0,
2642 0x2D, 0x20,
2643 0x9B, 0x10,
2644
2645 0x82, 0x3E, 0x57, 0xE9,
2646 0x32, 0xF0, 0x1B, 0xCD,
2647
2648 0x1E, 0xBD, 0x59, 0x9F,
2649 0x83, 0x1E, 0x57, 0xE9,
2650
2651 0x38, 0x47, 0x38, 0xAF,
2652 0x34, 0x20,
2653 0x2A, 0x30,
2654
2655 0x00, 0xE0,
2656 0x0D, 0x20,
2657 0x32, 0x20,
2658 0x05, 0x20,
2659
2660 0x87, 0x80, 0x57, 0xE9,
2661 0x1F, 0x54, 0x57, 0x9F,
2662
2663 0x17, 0x42, 0x56, 0x9F,
2664 0x00, 0xE0,
2665 0x3B, 0x6A,
2666
2667 0x3F, 0x8F, 0x51, 0x9F,
2668 0x37, 0x1E, 0x4F, 0xE9,
2669
2670 0x37, 0x32, 0x2A, 0xAF,
2671 0x00, 0xE0,
2672 0x32, 0x00,
2673
2674 0x00, 0x80, 0x00, 0xE8,
2675 0x27, 0xC0, 0x44, 0xC0,
2676
2677 0x36, 0x1F, 0x4F, 0xE9,
2678 0x1F, 0x1F, 0x26, 0xDF,
2679
2680 0x37, 0x1B, 0x37, 0xBF,
2681 0x17, 0x26, 0x17, 0xDF,
2682
2683 0x3E, 0x17, 0x4F, 0xE9,
2684 0x3F, 0x3F, 0x4F, 0xE9,
2685
2686 0x34, 0x1F, 0x34, 0xAF,
2687 0x2B, 0x05,
2688 0xA7, 0x20,
2689
2690 0x33, 0x2B, 0x37, 0xDF,
2691 0x27, 0x17, 0xC0, 0xAF,
2692
2693 0x34, 0x80, 0x4F, 0xE9,
2694 0x00, 0x80, 0x00, 0xE8,
2695
2696 0x2D, 0x21, 0x1A, 0xB0,
2697 0x25, 0x21, 0x31, 0xB0,
2698
2699 0x0D, 0x21, 0x1A, 0xB2,
2700 0x05, 0x21, 0x31, 0xB2,
2701
2702 0x03, 0x80, 0x2A, 0xEA,
2703 0x17, 0xC1, 0x2B, 0xBD,
2704
2705 0x2D, 0x20,
2706 0x25, 0x20,
2707 0x05, 0x20,
2708 0x0D, 0x20,
2709
2710 0xB3, 0x68,
2711 0x97, 0x25,
2712 0x00, 0x80, 0x00, 0xE8,
2713
2714 0x33, 0xC0, 0x33, 0xAF,
2715 0x2F, 0xC0, 0x21, 0xC0,
2716
2717 0x16, 0x42, 0x56, 0x9F,
2718 0x3C, 0x27, 0x4F, 0xE9,
2719
2720 0x1E, 0x62, 0x57, 0x9F,
2721 0x00, 0x80, 0x00, 0xE8,
2722
2723 0x25, 0x21, 0x31, 0xB4,
2724 0x2D, 0x21, 0x1A, 0xB4,
2725
2726 0x3F, 0x2F, 0x5D, 0x9F,
2727 0x00, 0x80, 0x00, 0xE8,
2728
2729 0x33, 0x05,
2730 0x00, 0xE0,
2731 0x28, 0x19, 0x60, 0xEC,
2732
2733 0x37, 0x0F, 0x5C, 0x9F,
2734 0x00, 0xE0,
2735 0x2F, 0x20,
2736
2737 0x23, 0x3B, 0x33, 0xAD,
2738 0x1E, 0x26, 0x1E, 0xDF,
2739
2740 0xA7, 0x1E, 0x4F, 0xE9,
2741 0x17, 0x26, 0x16, 0xDF,
2742
2743 0x2D, 0x20,
2744 0x00, 0xE0,
2745 0xA8, 0x3F, 0x4F, 0xE9,
2746
2747 0x2F, 0x2F, 0x1E, 0xAF,
2748 0x25, 0x20,
2749 0x00, 0xE0,
2750
2751 0xA4, 0x16, 0x4F, 0xE9,
2752 0x0F, 0xC0, 0x21, 0xC2,
2753
2754 0xA6, 0x80, 0x4F, 0xE9,
2755 0x1F, 0x62, 0x57, 0x9F,
2756
2757 0x3F, 0x2F, 0x5D, 0x9F,
2758 0x00, 0xE0,
2759 0x8F, 0x20,
2760
2761 0xA5, 0x37, 0x4F, 0xE9,
2762 0x0F, 0x17, 0x0F, 0xAF,
2763
2764 0x06, 0xC0, 0x21, 0xC4,
2765 0x00, 0x80, 0x00, 0xE8,
2766
2767 0x00, 0x80, 0x00, 0xE8,
2768 0xA3, 0x80, 0x4F, 0xE9,
2769
2770 0x06, 0x20,
2771 0x00, 0xE0,
2772 0x1F, 0x26, 0x1F, 0xDF,
2773
2774 0xA1, 0x1F, 0x4F, 0xE9,
2775 0xA2, 0x3F, 0x4F, 0xE9,
2776
2777 0x00, 0x80, 0x00, 0xE8,
2778 0x00, 0x80, 0x00, 0xE8,
2779
2780 0x06, 0x06, 0x1F, 0xAF,
2781 0x00, 0x80, 0x00, 0xE8,
2782
2783 0x00, 0x80, 0x00, 0xE8,
2784 0x00, 0x80, 0x00, 0xE8,
2785
2786 0xA0, 0x80, 0x4F, 0xE9,
2787 0x00, 0x80, 0x00, 0xE8,
2788
2789 0x00, 0x80, 0x00, 0xE8,
2790 0x57, 0x39, 0x20, 0xE9,
2791
2792 0x16, 0x28, 0x20, 0xE9,
2793 0x1D, 0x3B, 0x20, 0xE9,
2794
2795 0x1E, 0x2B, 0x20, 0xE9,
2796 0x2B, 0x32, 0x20, 0xE9,
2797
2798 0x1C, 0x23, 0x20, 0xE9,
2799 0x57, 0x36, 0x20, 0xE9,
2800
2801 0x00, 0x80, 0xA0, 0xE9,
2802 0x40, 0x40, 0xD8, 0xEC,
2803
2804 0xFF, 0x80, 0xC0, 0xE9,
2805 0x90, 0xE2,
2806 0x00, 0xE0,
2807
2808 0x6C, 0xFF, 0x20, 0xEA,
2809 0x19, 0xC8, 0xC1, 0xCD,
2810
2811 0x1F, 0xD7, 0x18, 0xBD,
2812 0x3F, 0xD7, 0x22, 0xBD,
2813
2814 0x9F, 0x41, 0x49, 0xBD,
2815 0x00, 0x80, 0x00, 0xE8,
2816
2817 0x25, 0x41, 0x49, 0xBD,
2818 0x2D, 0x41, 0x51, 0xBD,
2819
2820 0x0D, 0x80, 0x07, 0xEA,
2821 0x00, 0x80, 0x00, 0xE8,
2822
2823 0x35, 0x40, 0x48, 0xBD,
2824 0x3D, 0x40, 0x50, 0xBD,
2825
2826 0x00, 0x80, 0x00, 0xE8,
2827 0x25, 0x30,
2828 0x2D, 0x30,
2829
2830 0x35, 0x30,
2831 0xB5, 0x30,
2832 0xBD, 0x30,
2833 0x3D, 0x30,
2834
2835 0x9C, 0xA7, 0x5B, 0x9F,
2836 0x00, 0x80, 0x00, 0xE8,
2837
2838 0x00, 0x80, 0x00, 0xE8,
2839 0x00, 0x80, 0x00, 0xE8,
2840
2841 0x00, 0x80, 0x00, 0xE8,
2842 0x00, 0x80, 0x00, 0xE8,
2843
2844 0x00, 0x80, 0x00, 0xE8,
2845 0x00, 0x80, 0x00, 0xE8,
2846
2847 0x00, 0x80, 0x00, 0xE8,
2848 0x00, 0x80, 0x00, 0xE8,
2849
2850 0x6B, 0xFF, 0x0A, 0xEA,
2851 0x00, 0x80, 0x00, 0xE8,
2852
2853 0xC9, 0x41, 0xC8, 0xEC,
2854 0x42, 0xE1,
2855 0x00, 0xE0,
2856
2857 0x69, 0xFF, 0x20, 0xEA,
2858 0x00, 0x80, 0x00, 0xE8,
2859
2860 0x00, 0x80, 0x00, 0xE8,
2861 0x00, 0x80, 0x00, 0xE8,
2862
2863 0xC8, 0x40, 0xC0, 0xEC,
2864 0x00, 0x80, 0x00, 0xE8,
2865
2866 0x66, 0xFF, 0x20, 0xEA,
2867 0x00, 0x80, 0x00, 0xE8,
2868
2869 0x00, 0x80, 0x00, 0xE8,
2870 0x00, 0x80, 0x00, 0xE8,
2871
2872};
2873
2874static unsigned char warp_g200_tgzsa[] = {
2875
2876 0x00, 0x80, 0x00, 0xE8,
2877 0x00, 0x80, 0x00, 0xE8,
2878
2879 0x00, 0x80, 0x00, 0xE8,
2880 0x00, 0x80, 0x00, 0xE8,
2881
2882 0x00, 0x80, 0x00, 0xE8,
2883 0x00, 0x80, 0x00, 0xE8,
2884
2885 0x00, 0x80, 0x00, 0xE8,
2886 0x00, 0x80, 0x00, 0xE8,
2887
2888 0x00, 0x80, 0x00, 0xE8,
2889 0x00, 0x80, 0x00, 0xE8,
2890
2891 0x00, 0x80, 0x00, 0xE8,
2892 0x00, 0x80, 0x00, 0xE8,
2893
2894 0x00, 0x80, 0x00, 0xE8,
2895 0x00, 0x80, 0x00, 0xE8,
2896
2897 0x00, 0x80, 0x00, 0xE8,
2898 0x00, 0x80, 0x00, 0xE8,
2899
2900 0x00, 0x80, 0x00, 0xE8,
2901 0x00, 0x80, 0x00, 0xE8,
2902
2903 0x00, 0x80, 0x00, 0xE8,
2904 0x00, 0x80, 0x00, 0xE8,
2905
2906 0x00, 0x80, 0x00, 0xE8,
2907 0x00, 0x80, 0x00, 0xE8,
2908
2909 0x00, 0x80, 0x00, 0xE8,
2910 0x00, 0x80, 0x00, 0xE8,
2911
2912 0x00, 0x80, 0x00, 0xE8,
2913 0x00, 0x80, 0x00, 0xE8,
2914
2915 0x00, 0x98, 0xA0, 0xE9,
2916 0x40, 0x40, 0xD8, 0xEC,
2917
2918 0xFF, 0x80, 0xC0, 0xE9,
2919 0x00, 0x80, 0x00, 0xE8,
2920
2921 0x1F, 0xD7, 0x18, 0xBD,
2922 0x3F, 0xD7, 0x22, 0xBD,
2923
2924 0x81, 0x04,
2925 0x89, 0x04,
2926 0x01, 0x04,
2927 0x09, 0x04,
2928
2929 0xC9, 0x41, 0xC0, 0xEC,
2930 0x11, 0x04,
2931 0x00, 0xE0,
2932
2933 0x41, 0xCC, 0x41, 0xCD,
2934 0x49, 0xCC, 0x49, 0xCD,
2935
2936 0xD1, 0x41, 0xC0, 0xEC,
2937 0x51, 0xCC, 0x51, 0xCD,
2938
2939 0x80, 0x04,
2940 0x10, 0x04,
2941 0x08, 0x04,
2942 0x00, 0xE0,
2943
2944 0x00, 0xCC, 0xC0, 0xCD,
2945 0xD1, 0x49, 0xC0, 0xEC,
2946
2947 0x8A, 0x1F, 0x20, 0xE9,
2948 0x8B, 0x3F, 0x20, 0xE9,
2949
2950 0x41, 0x3C, 0x41, 0xAD,
2951 0x49, 0x3C, 0x49, 0xAD,
2952
2953 0x10, 0xCC, 0x10, 0xCD,
2954 0x08, 0xCC, 0x08, 0xCD,
2955
2956 0xB9, 0x41, 0x49, 0xBB,
2957 0x1F, 0xF0, 0x41, 0xCD,
2958
2959 0x51, 0x3C, 0x51, 0xAD,
2960 0x00, 0x98, 0x80, 0xE9,
2961
2962 0x8F, 0x80, 0x07, 0xEA,
2963 0x24, 0x1F, 0x20, 0xE9,
2964
2965 0x21, 0x45, 0x80, 0xE8,
2966 0x1A, 0x4D, 0x80, 0xE8,
2967
2968 0x31, 0x55, 0x80, 0xE8,
2969 0x00, 0x80, 0x00, 0xE8,
2970
2971 0x15, 0x41, 0x49, 0xBD,
2972 0x1D, 0x41, 0x51, 0xBD,
2973
2974 0x2E, 0x41, 0x2A, 0xB8,
2975 0x34, 0x53, 0xA0, 0xE8,
2976
2977 0x15, 0x30,
2978 0x1D, 0x30,
2979 0x58, 0xE3,
2980 0x00, 0xE0,
2981
2982 0xB5, 0x40, 0x48, 0xBD,
2983 0x3D, 0x40, 0x50, 0xBD,
2984
2985 0x24, 0x43, 0xA0, 0xE8,
2986 0x2C, 0x4B, 0xA0, 0xE8,
2987
2988 0x15, 0x72,
2989 0x09, 0xE3,
2990 0x00, 0xE0,
2991 0x1D, 0x72,
2992
2993 0x35, 0x30,
2994 0xB5, 0x30,
2995 0xBD, 0x30,
2996 0x3D, 0x30,
2997
2998 0x9C, 0x97, 0x57, 0x9F,
2999 0x00, 0x80, 0x00, 0xE8,
3000
3001 0x6C, 0x64, 0xC8, 0xEC,
3002 0x98, 0xE1,
3003 0xB5, 0x05,
3004
3005 0xBD, 0x05,
3006 0x2E, 0x30,
3007 0x32, 0xC0, 0xA0, 0xE8,
3008
3009 0x33, 0xC0, 0xA0, 0xE8,
3010 0x74, 0x64, 0xC8, 0xEC,
3011
3012 0x40, 0x3C, 0x40, 0xAD,
3013 0x32, 0x6A,
3014 0x2A, 0x30,
3015
3016 0x20, 0x73,
3017 0x33, 0x6A,
3018 0x00, 0xE0,
3019 0x28, 0x73,
3020
3021 0x1C, 0x72,
3022 0x83, 0xE2,
3023 0x7B, 0x80, 0x15, 0xEA,
3024
3025 0xB8, 0x3D, 0x28, 0xDF,
3026 0x30, 0x35, 0x20, 0xDF,
3027
3028 0x40, 0x30,
3029 0x00, 0xE0,
3030 0xCC, 0xE2,
3031 0x64, 0x72,
3032
3033 0x25, 0x42, 0x52, 0xBF,
3034 0x2D, 0x42, 0x4A, 0xBF,
3035
3036 0x30, 0x2E, 0x30, 0xDF,
3037 0x38, 0x2E, 0x38, 0xDF,
3038
3039 0x18, 0x1D, 0x45, 0xE9,
3040 0x1E, 0x15, 0x45, 0xE9,
3041
3042 0x2B, 0x49, 0x51, 0xBD,
3043 0x00, 0xE0,
3044 0x1F, 0x73,
3045
3046 0x38, 0x38, 0x40, 0xAF,
3047 0x30, 0x30, 0x40, 0xAF,
3048
3049 0x24, 0x1F, 0x24, 0xDF,
3050 0x1D, 0x32, 0x20, 0xE9,
3051
3052 0x2C, 0x1F, 0x2C, 0xDF,
3053 0x1A, 0x33, 0x20, 0xE9,
3054
3055 0xB0, 0x10,
3056 0x08, 0xE3,
3057 0x40, 0x10,
3058 0xB8, 0x10,
3059
3060 0x26, 0xF0, 0x30, 0xCD,
3061 0x2F, 0xF0, 0x38, 0xCD,
3062
3063 0x2B, 0x80, 0x20, 0xE9,
3064 0x2A, 0x80, 0x20, 0xE9,
3065
3066 0xA6, 0x20,
3067 0x88, 0xE2,
3068 0x00, 0xE0,
3069 0xAF, 0x20,
3070
3071 0x28, 0x2A, 0x26, 0xAF,
3072 0x20, 0x2A, 0xC0, 0xAF,
3073
3074 0x34, 0x1F, 0x34, 0xDF,
3075 0x46, 0x24, 0x46, 0xDF,
3076
3077 0x28, 0x30, 0x80, 0xBF,
3078 0x20, 0x38, 0x80, 0xBF,
3079
3080 0x47, 0x24, 0x47, 0xDF,
3081 0x4E, 0x2C, 0x4E, 0xDF,
3082
3083 0x4F, 0x2C, 0x4F, 0xDF,
3084 0x56, 0x34, 0x56, 0xDF,
3085
3086 0x28, 0x15, 0x28, 0xDF,
3087 0x20, 0x1D, 0x20, 0xDF,
3088
3089 0x57, 0x34, 0x57, 0xDF,
3090 0x00, 0xE0,
3091 0x1D, 0x05,
3092
3093 0x04, 0x80, 0x10, 0xEA,
3094 0x89, 0xE2,
3095 0x2B, 0x30,
3096
3097 0x3F, 0xC1, 0x1D, 0xBD,
3098 0x00, 0x80, 0x00, 0xE8,
3099
3100 0x00, 0x80, 0x00, 0xE8,
3101 0x00, 0x80, 0x00, 0xE8,
3102
3103 0xA0, 0x68,
3104 0xBF, 0x25,
3105 0x00, 0x80, 0x00, 0xE8,
3106
3107 0x20, 0xC0, 0x20, 0xAF,
3108 0x28, 0x05,
3109 0x97, 0x74,
3110
3111 0x00, 0xE0,
3112 0x2A, 0x10,
3113 0x16, 0xC0, 0x20, 0xE9,
3114
3115 0x04, 0x80, 0x10, 0xEA,
3116 0x8C, 0xE2,
3117 0x95, 0x05,
3118
3119 0x28, 0xC1, 0x28, 0xAD,
3120 0x1F, 0xC1, 0x15, 0xBD,
3121
3122 0x00, 0x80, 0x00, 0xE8,
3123 0x00, 0x80, 0x00, 0xE8,
3124
3125 0xA8, 0x67,
3126 0x9F, 0x6B,
3127 0x00, 0x80, 0x00, 0xE8,
3128
3129 0x28, 0xC0, 0x28, 0xAD,
3130 0x1D, 0x25,
3131 0x20, 0x05,
3132
3133 0x28, 0x32, 0x80, 0xAD,
3134 0x40, 0x2A, 0x40, 0xBD,
3135
3136 0x1C, 0x80, 0x20, 0xE9,
3137 0x20, 0x33, 0x20, 0xAD,
3138
3139 0x20, 0x73,
3140 0x00, 0xE0,
3141 0xB6, 0x49, 0x51, 0xBB,
3142
3143 0x26, 0x2F, 0xB0, 0xE8,
3144 0x19, 0x20, 0x20, 0xE9,
3145
3146 0x35, 0x20, 0x35, 0xDF,
3147 0x3D, 0x20, 0x3D, 0xDF,
3148
3149 0x15, 0x20, 0x15, 0xDF,
3150 0x1D, 0x20, 0x1D, 0xDF,
3151
3152 0x26, 0xD0, 0x26, 0xCD,
3153 0x29, 0x49, 0x2A, 0xB8,
3154
3155 0x26, 0x40, 0x80, 0xBD,
3156 0x3B, 0x48, 0x50, 0xBD,
3157
3158 0x3E, 0x54, 0x57, 0x9F,
3159 0x00, 0xE0,
3160 0x82, 0xE1,
3161
3162 0x1E, 0xAF, 0x59, 0x9F,
3163 0x00, 0x80, 0x00, 0xE8,
3164
3165 0x26, 0x30,
3166 0x29, 0x30,
3167 0x48, 0x3C, 0x48, 0xAD,
3168
3169 0x2B, 0x72,
3170 0xC2, 0xE1,
3171 0x2C, 0xC0, 0x44, 0xC2,
3172
3173 0x05, 0x24, 0x34, 0xBF,
3174 0x0D, 0x24, 0x2C, 0xBF,
3175
3176 0x2D, 0x46, 0x4E, 0xBF,
3177 0x25, 0x46, 0x56, 0xBF,
3178
3179 0x20, 0x1D, 0x6F, 0x8F,
3180 0x32, 0x3E, 0x5F, 0xE9,
3181
3182 0x3E, 0x50, 0x56, 0x9F,
3183 0x00, 0xE0,
3184 0x3B, 0x30,
3185
3186 0x1E, 0x8F, 0x51, 0x9F,
3187 0x33, 0x1E, 0x5F, 0xE9,
3188
3189 0x05, 0x44, 0x54, 0xB2,
3190 0x0D, 0x44, 0x4C, 0xB2,
3191
3192 0x19, 0xC0, 0xB0, 0xE8,
3193 0x34, 0xC0, 0x44, 0xC4,
3194
3195 0x33, 0x73,
3196 0x00, 0xE0,
3197 0x3E, 0x62, 0x57, 0x9F,
3198
3199 0x1E, 0xAF, 0x59, 0x9F,
3200 0x00, 0xE0,
3201 0x0D, 0x20,
3202
3203 0x84, 0x3E, 0x58, 0xE9,
3204 0x28, 0x1D, 0x6F, 0x8F,
3205
3206 0x05, 0x20,
3207 0x00, 0xE0,
3208 0x85, 0x1E, 0x58, 0xE9,
3209
3210 0x9B, 0x3B, 0x33, 0xDF,
3211 0x20, 0x20, 0x42, 0xAF,
3212
3213 0x30, 0x42, 0x56, 0x9F,
3214 0x80, 0x3E, 0x57, 0xE9,
3215
3216 0x3F, 0x8F, 0x51, 0x9F,
3217 0x30, 0x80, 0x5F, 0xE9,
3218
3219 0x28, 0x28, 0x24, 0xAF,
3220 0x81, 0x1E, 0x57, 0xE9,
3221
3222 0x05, 0x47, 0x57, 0xBF,
3223 0x0D, 0x47, 0x4F, 0xBF,
3224
3225 0x88, 0x80, 0x58, 0xE9,
3226 0x1B, 0x29, 0x1B, 0xDF,
3227
3228 0x30, 0x1D, 0x6F, 0x8F,
3229 0x3A, 0x30, 0x4F, 0xE9,
3230
3231 0x1C, 0x30, 0x26, 0xDF,
3232 0x09, 0xE3,
3233 0x3B, 0x05,
3234
3235 0x3E, 0x50, 0x56, 0x9F,
3236 0x3B, 0x3F, 0x4F, 0xE9,
3237
3238 0x1E, 0x8F, 0x51, 0x9F,
3239 0x00, 0xE0,
3240 0xAC, 0x20,
3241
3242 0x2D, 0x44, 0x4C, 0xB4,
3243 0x2C, 0x1C, 0xC0, 0xAF,
3244
3245 0x25, 0x44, 0x54, 0xB4,
3246 0x00, 0xE0,
3247 0xC8, 0x30,
3248
3249 0x30, 0x46, 0x30, 0xAF,
3250 0x1B, 0x1B, 0x48, 0xAF,
3251
3252 0x00, 0xE0,
3253 0x25, 0x20,
3254 0x38, 0x2C, 0x4F, 0xE9,
3255
3256 0x86, 0x80, 0x57, 0xE9,
3257 0x38, 0x1D, 0x6F, 0x8F,
3258
3259 0x28, 0x74,
3260 0x00, 0xE0,
3261 0x0D, 0x44, 0x4C, 0xB0,
3262
3263 0x05, 0x44, 0x54, 0xB0,
3264 0x2D, 0x20,
3265 0x9B, 0x10,
3266
3267 0x82, 0x3E, 0x57, 0xE9,
3268 0x32, 0xF0, 0x1B, 0xCD,
3269
3270 0x1E, 0xBD, 0x59, 0x9F,
3271 0x83, 0x1E, 0x57, 0xE9,
3272
3273 0x38, 0x47, 0x38, 0xAF,
3274 0x34, 0x20,
3275 0x2A, 0x30,
3276
3277 0x00, 0xE0,
3278 0x0D, 0x20,
3279 0x32, 0x20,
3280 0x05, 0x20,
3281
3282 0x87, 0x80, 0x57, 0xE9,
3283 0x1F, 0x54, 0x57, 0x9F,
3284
3285 0x17, 0x42, 0x56, 0x9F,
3286 0x00, 0xE0,
3287 0x3B, 0x6A,
3288
3289 0x3F, 0x8F, 0x51, 0x9F,
3290 0x37, 0x1E, 0x4F, 0xE9,
3291
3292 0x37, 0x32, 0x2A, 0xAF,
3293 0x00, 0xE0,
3294 0x32, 0x00,
3295
3296 0x00, 0x80, 0x00, 0xE8,
3297 0x27, 0xC0, 0x44, 0xC0,
3298
3299 0x36, 0x1F, 0x4F, 0xE9,
3300 0x1F, 0x1F, 0x26, 0xDF,
3301
3302 0x37, 0x1B, 0x37, 0xBF,
3303 0x17, 0x26, 0x17, 0xDF,
3304
3305 0x3E, 0x17, 0x4F, 0xE9,
3306 0x3F, 0x3F, 0x4F, 0xE9,
3307
3308 0x34, 0x1F, 0x34, 0xAF,
3309 0x2B, 0x05,
3310 0xA7, 0x20,
3311
3312 0x33, 0x2B, 0x37, 0xDF,
3313 0x27, 0x17, 0xC0, 0xAF,
3314
3315 0x34, 0x80, 0x4F, 0xE9,
3316 0x00, 0x80, 0x00, 0xE8,
3317
3318 0x2D, 0x21, 0x1A, 0xB0,
3319 0x25, 0x21, 0x31, 0xB0,
3320
3321 0x0D, 0x21, 0x1A, 0xB2,
3322 0x05, 0x21, 0x31, 0xB2,
3323
3324 0x03, 0x80, 0x2A, 0xEA,
3325 0x17, 0xC1, 0x2B, 0xBD,
3326
3327 0x2D, 0x20,
3328 0x25, 0x20,
3329 0x05, 0x20,
3330 0x0D, 0x20,
3331
3332 0xB3, 0x68,
3333 0x97, 0x25,
3334 0x00, 0x80, 0x00, 0xE8,
3335
3336 0x33, 0xC0, 0x33, 0xAF,
3337 0x2F, 0xC0, 0x21, 0xC0,
3338
3339 0x16, 0x42, 0x56, 0x9F,
3340 0x3C, 0x27, 0x4F, 0xE9,
3341
3342 0x1E, 0x62, 0x57, 0x9F,
3343 0x00, 0x80, 0x00, 0xE8,
3344
3345 0x25, 0x21, 0x31, 0xB4,
3346 0x2D, 0x21, 0x1A, 0xB4,
3347
3348 0x3F, 0x2F, 0x5D, 0x9F,
3349 0x00, 0x80, 0x00, 0xE8,
3350
3351 0x33, 0x05,
3352 0x00, 0xE0,
3353 0x28, 0x19, 0x60, 0xEC,
3354
3355 0x0D, 0x44, 0x4C, 0xB6,
3356 0x05, 0x44, 0x54, 0xB6,
3357
3358 0x37, 0x0F, 0x5C, 0x9F,
3359 0x00, 0xE0,
3360 0x2F, 0x20,
3361
3362 0x23, 0x3B, 0x33, 0xAD,
3363 0x1E, 0x26, 0x1E, 0xDF,
3364
3365 0xA7, 0x1E, 0x4F, 0xE9,
3366 0x17, 0x26, 0x16, 0xDF,
3367
3368 0x2D, 0x20,
3369 0x00, 0xE0,
3370 0xA8, 0x3F, 0x4F, 0xE9,
3371
3372 0x2F, 0x2F, 0x1E, 0xAF,
3373 0x25, 0x20,
3374 0x00, 0xE0,
3375
3376 0xA4, 0x16, 0x4F, 0xE9,
3377 0x0F, 0xC0, 0x21, 0xC2,
3378
3379 0xA6, 0x80, 0x4F, 0xE9,
3380 0x1F, 0x62, 0x57, 0x9F,
3381
3382 0x0D, 0x20,
3383 0x05, 0x20,
3384 0x00, 0x80, 0x00, 0xE8,
3385
3386 0x3F, 0x2F, 0x5D, 0x9F,
3387 0x00, 0xE0,
3388 0x0F, 0x20,
3389
3390 0x17, 0x50, 0x56, 0x9F,
3391 0xA5, 0x37, 0x4F, 0xE9,
3392
3393 0x06, 0xC0, 0x21, 0xC4,
3394 0x0F, 0x17, 0x0F, 0xAF,
3395
3396 0x37, 0x0F, 0x5C, 0x9F,
3397 0x00, 0x80, 0x00, 0xE8,
3398
3399 0x2F, 0xC0, 0x44, 0xC6,
3400 0xA3, 0x80, 0x4F, 0xE9,
3401
3402 0x06, 0x20,
3403 0x00, 0xE0,
3404 0x1F, 0x26, 0x1F, 0xDF,
3405
3406 0x17, 0x26, 0x17, 0xDF,
3407 0x9D, 0x17, 0x4F, 0xE9,
3408
3409 0xA1, 0x1F, 0x4F, 0xE9,
3410 0xA2, 0x3F, 0x4F, 0xE9,
3411
3412 0x06, 0x06, 0x1F, 0xAF,
3413 0x00, 0xE0,
3414 0xAF, 0x20,
3415
3416 0x9E, 0x37, 0x4F, 0xE9,
3417 0x2F, 0x17, 0x2F, 0xAF,
3418
3419 0xA0, 0x80, 0x4F, 0xE9,
3420 0x00, 0x80, 0x00, 0xE8,
3421
3422 0x00, 0x80, 0x00, 0xE8,
3423 0x9C, 0x80, 0x4F, 0xE9,
3424
3425 0x00, 0x80, 0x00, 0xE8,
3426 0x57, 0x39, 0x20, 0xE9,
3427
3428 0x16, 0x28, 0x20, 0xE9,
3429 0x1D, 0x3B, 0x20, 0xE9,
3430
3431 0x1E, 0x2B, 0x20, 0xE9,
3432 0x2B, 0x32, 0x20, 0xE9,
3433
3434 0x1C, 0x23, 0x20, 0xE9,
3435 0x57, 0x36, 0x20, 0xE9,
3436
3437 0x00, 0x80, 0xA0, 0xE9,
3438 0x40, 0x40, 0xD8, 0xEC,
3439
3440 0xFF, 0x80, 0xC0, 0xE9,
3441 0x90, 0xE2,
3442 0x00, 0xE0,
3443
3444 0x68, 0xFF, 0x20, 0xEA,
3445 0x19, 0xC8, 0xC1, 0xCD,
3446
3447 0x1F, 0xD7, 0x18, 0xBD,
3448 0x3F, 0xD7, 0x22, 0xBD,
3449
3450 0x9F, 0x41, 0x49, 0xBD,
3451 0x00, 0x80, 0x00, 0xE8,
3452
3453 0x25, 0x41, 0x49, 0xBD,
3454 0x2D, 0x41, 0x51, 0xBD,
3455
3456 0x0D, 0x80, 0x07, 0xEA,
3457 0x00, 0x80, 0x00, 0xE8,
3458
3459 0x35, 0x40, 0x48, 0xBD,
3460 0x3D, 0x40, 0x50, 0xBD,
3461
3462 0x00, 0x80, 0x00, 0xE8,
3463 0x25, 0x30,
3464 0x2D, 0x30,
3465
3466 0x35, 0x30,
3467 0xB5, 0x30,
3468 0xBD, 0x30,
3469 0x3D, 0x30,
3470
3471 0x9C, 0xA7, 0x5B, 0x9F,
3472 0x00, 0x80, 0x00, 0xE8,
3473
3474 0x00, 0x80, 0x00, 0xE8,
3475 0x00, 0x80, 0x00, 0xE8,
3476
3477 0x00, 0x80, 0x00, 0xE8,
3478 0x00, 0x80, 0x00, 0xE8,
3479
3480 0x00, 0x80, 0x00, 0xE8,
3481 0x00, 0x80, 0x00, 0xE8,
3482
3483 0x00, 0x80, 0x00, 0xE8,
3484 0x00, 0x80, 0x00, 0xE8,
3485
3486 0x67, 0xFF, 0x0A, 0xEA,
3487 0x00, 0x80, 0x00, 0xE8,
3488
3489 0xC9, 0x41, 0xC8, 0xEC,
3490 0x42, 0xE1,
3491 0x00, 0xE0,
3492
3493 0x65, 0xFF, 0x20, 0xEA,
3494 0x00, 0x80, 0x00, 0xE8,
3495
3496 0x00, 0x80, 0x00, 0xE8,
3497 0x00, 0x80, 0x00, 0xE8,
3498
3499 0xC8, 0x40, 0xC0, 0xEC,
3500 0x00, 0x80, 0x00, 0xE8,
3501
3502 0x62, 0xFF, 0x20, 0xEA,
3503 0x00, 0x80, 0x00, 0xE8,
3504
3505 0x00, 0x80, 0x00, 0xE8,
3506 0x00, 0x80, 0x00, 0xE8,
3507
3508};
3509
3510static unsigned char warp_g200_tgzsaf[] = {
3511
3512 0x00, 0x80, 0x00, 0xE8,
3513 0x00, 0x80, 0x00, 0xE8,
3514
3515 0x00, 0x80, 0x00, 0xE8,
3516 0x00, 0x80, 0x00, 0xE8,
3517
3518 0x00, 0x80, 0x00, 0xE8,
3519 0x00, 0x80, 0x00, 0xE8,
3520
3521 0x00, 0x98, 0xA0, 0xE9,
3522 0x40, 0x40, 0xD8, 0xEC,
3523
3524 0xFF, 0x80, 0xC0, 0xE9,
3525 0x00, 0x80, 0x00, 0xE8,
3526
3527 0x1F, 0xD7, 0x18, 0xBD,
3528 0x3F, 0xD7, 0x22, 0xBD,
3529
3530 0x81, 0x04,
3531 0x89, 0x04,
3532 0x01, 0x04,
3533 0x09, 0x04,
3534
3535 0xC9, 0x41, 0xC0, 0xEC,
3536 0x11, 0x04,
3537 0x00, 0xE0,
3538
3539 0x41, 0xCC, 0x41, 0xCD,
3540 0x49, 0xCC, 0x49, 0xCD,
3541
3542 0xD1, 0x41, 0xC0, 0xEC,
3543 0x51, 0xCC, 0x51, 0xCD,
3544
3545 0x80, 0x04,
3546 0x10, 0x04,
3547 0x08, 0x04,
3548 0x00, 0xE0,
3549
3550 0x00, 0xCC, 0xC0, 0xCD,
3551 0xD1, 0x49, 0xC0, 0xEC,
3552
3553 0x8A, 0x1F, 0x20, 0xE9,
3554 0x8B, 0x3F, 0x20, 0xE9,
3555
3556 0x41, 0x3C, 0x41, 0xAD,
3557 0x49, 0x3C, 0x49, 0xAD,
3558
3559 0x10, 0xCC, 0x10, 0xCD,
3560 0x08, 0xCC, 0x08, 0xCD,
3561
3562 0xB9, 0x41, 0x49, 0xBB,
3563 0x1F, 0xF0, 0x41, 0xCD,
3564
3565 0x51, 0x3C, 0x51, 0xAD,
3566 0x00, 0x98, 0x80, 0xE9,
3567
3568 0x94, 0x80, 0x07, 0xEA,
3569 0x24, 0x1F, 0x20, 0xE9,
3570
3571 0x21, 0x45, 0x80, 0xE8,
3572 0x1A, 0x4D, 0x80, 0xE8,
3573
3574 0x31, 0x55, 0x80, 0xE8,
3575 0x00, 0x80, 0x00, 0xE8,
3576
3577 0x15, 0x41, 0x49, 0xBD,
3578 0x1D, 0x41, 0x51, 0xBD,
3579
3580 0x2E, 0x41, 0x2A, 0xB8,
3581 0x34, 0x53, 0xA0, 0xE8,
3582
3583 0x15, 0x30,
3584 0x1D, 0x30,
3585 0x58, 0xE3,
3586 0x00, 0xE0,
3587
3588 0xB5, 0x40, 0x48, 0xBD,
3589 0x3D, 0x40, 0x50, 0xBD,
3590
3591 0x24, 0x43, 0xA0, 0xE8,
3592 0x2C, 0x4B, 0xA0, 0xE8,
3593
3594 0x15, 0x72,
3595 0x09, 0xE3,
3596 0x00, 0xE0,
3597 0x1D, 0x72,
3598
3599 0x35, 0x30,
3600 0xB5, 0x30,
3601 0xBD, 0x30,
3602 0x3D, 0x30,
3603
3604 0x9C, 0x97, 0x57, 0x9F,
3605 0x00, 0x80, 0x00, 0xE8,
3606
3607 0x6C, 0x64, 0xC8, 0xEC,
3608 0x98, 0xE1,
3609 0xB5, 0x05,
3610
3611 0xBD, 0x05,
3612 0x2E, 0x30,
3613 0x32, 0xC0, 0xA0, 0xE8,
3614
3615 0x33, 0xC0, 0xA0, 0xE8,
3616 0x74, 0x64, 0xC8, 0xEC,
3617
3618 0x40, 0x3C, 0x40, 0xAD,
3619 0x32, 0x6A,
3620 0x2A, 0x30,
3621
3622 0x20, 0x73,
3623 0x33, 0x6A,
3624 0x00, 0xE0,
3625 0x28, 0x73,
3626
3627 0x1C, 0x72,
3628 0x83, 0xE2,
3629 0x80, 0x80, 0x15, 0xEA,
3630
3631 0xB8, 0x3D, 0x28, 0xDF,
3632 0x30, 0x35, 0x20, 0xDF,
3633
3634 0x40, 0x30,
3635 0x00, 0xE0,
3636 0xCC, 0xE2,
3637 0x64, 0x72,
3638
3639 0x25, 0x42, 0x52, 0xBF,
3640 0x2D, 0x42, 0x4A, 0xBF,
3641
3642 0x30, 0x2E, 0x30, 0xDF,
3643 0x38, 0x2E, 0x38, 0xDF,
3644
3645 0x18, 0x1D, 0x45, 0xE9,
3646 0x1E, 0x15, 0x45, 0xE9,
3647
3648 0x2B, 0x49, 0x51, 0xBD,
3649 0x00, 0xE0,
3650 0x1F, 0x73,
3651
3652 0x38, 0x38, 0x40, 0xAF,
3653 0x30, 0x30, 0x40, 0xAF,
3654
3655 0x24, 0x1F, 0x24, 0xDF,
3656 0x1D, 0x32, 0x20, 0xE9,
3657
3658 0x2C, 0x1F, 0x2C, 0xDF,
3659 0x1A, 0x33, 0x20, 0xE9,
3660
3661 0xB0, 0x10,
3662 0x08, 0xE3,
3663 0x40, 0x10,
3664 0xB8, 0x10,
3665
3666 0x26, 0xF0, 0x30, 0xCD,
3667 0x2F, 0xF0, 0x38, 0xCD,
3668
3669 0x2B, 0x80, 0x20, 0xE9,
3670 0x2A, 0x80, 0x20, 0xE9,
3671
3672 0xA6, 0x20,
3673 0x88, 0xE2,
3674 0x00, 0xE0,
3675 0xAF, 0x20,
3676
3677 0x28, 0x2A, 0x26, 0xAF,
3678 0x20, 0x2A, 0xC0, 0xAF,
3679
3680 0x34, 0x1F, 0x34, 0xDF,
3681 0x46, 0x24, 0x46, 0xDF,
3682
3683 0x28, 0x30, 0x80, 0xBF,
3684 0x20, 0x38, 0x80, 0xBF,
3685
3686 0x47, 0x24, 0x47, 0xDF,
3687 0x4E, 0x2C, 0x4E, 0xDF,
3688
3689 0x4F, 0x2C, 0x4F, 0xDF,
3690 0x56, 0x34, 0x56, 0xDF,
3691
3692 0x28, 0x15, 0x28, 0xDF,
3693 0x20, 0x1D, 0x20, 0xDF,
3694
3695 0x57, 0x34, 0x57, 0xDF,
3696 0x00, 0xE0,
3697 0x1D, 0x05,
3698
3699 0x04, 0x80, 0x10, 0xEA,
3700 0x89, 0xE2,
3701 0x2B, 0x30,
3702
3703 0x3F, 0xC1, 0x1D, 0xBD,
3704 0x00, 0x80, 0x00, 0xE8,
3705
3706 0x00, 0x80, 0x00, 0xE8,
3707 0x00, 0x80, 0x00, 0xE8,
3708
3709 0xA0, 0x68,
3710 0xBF, 0x25,
3711 0x00, 0x80, 0x00, 0xE8,
3712
3713 0x20, 0xC0, 0x20, 0xAF,
3714 0x28, 0x05,
3715 0x97, 0x74,
3716
3717 0x00, 0xE0,
3718 0x2A, 0x10,
3719 0x16, 0xC0, 0x20, 0xE9,
3720
3721 0x04, 0x80, 0x10, 0xEA,
3722 0x8C, 0xE2,
3723 0x95, 0x05,
3724
3725 0x28, 0xC1, 0x28, 0xAD,
3726 0x1F, 0xC1, 0x15, 0xBD,
3727
3728 0x00, 0x80, 0x00, 0xE8,
3729 0x00, 0x80, 0x00, 0xE8,
3730
3731 0xA8, 0x67,
3732 0x9F, 0x6B,
3733 0x00, 0x80, 0x00, 0xE8,
3734
3735 0x28, 0xC0, 0x28, 0xAD,
3736 0x1D, 0x25,
3737 0x20, 0x05,
3738
3739 0x28, 0x32, 0x80, 0xAD,
3740 0x40, 0x2A, 0x40, 0xBD,
3741
3742 0x1C, 0x80, 0x20, 0xE9,
3743 0x20, 0x33, 0x20, 0xAD,
3744
3745 0x20, 0x73,
3746 0x00, 0xE0,
3747 0xB6, 0x49, 0x51, 0xBB,
3748
3749 0x26, 0x2F, 0xB0, 0xE8,
3750 0x19, 0x20, 0x20, 0xE9,
3751
3752 0x35, 0x20, 0x35, 0xDF,
3753 0x3D, 0x20, 0x3D, 0xDF,
3754
3755 0x15, 0x20, 0x15, 0xDF,
3756 0x1D, 0x20, 0x1D, 0xDF,
3757
3758 0x26, 0xD0, 0x26, 0xCD,
3759 0x29, 0x49, 0x2A, 0xB8,
3760
3761 0x26, 0x40, 0x80, 0xBD,
3762 0x3B, 0x48, 0x50, 0xBD,
3763
3764 0x3E, 0x54, 0x57, 0x9F,
3765 0x00, 0xE0,
3766 0x82, 0xE1,
3767
3768 0x1E, 0xAF, 0x59, 0x9F,
3769 0x00, 0x80, 0x00, 0xE8,
3770
3771 0x26, 0x30,
3772 0x29, 0x30,
3773 0x48, 0x3C, 0x48, 0xAD,
3774
3775 0x2B, 0x72,
3776 0xC2, 0xE1,
3777 0x2C, 0xC0, 0x44, 0xC2,
3778
3779 0x05, 0x24, 0x34, 0xBF,
3780 0x0D, 0x24, 0x2C, 0xBF,
3781
3782 0x2D, 0x46, 0x4E, 0xBF,
3783 0x25, 0x46, 0x56, 0xBF,
3784
3785 0x20, 0x1D, 0x6F, 0x8F,
3786 0x32, 0x3E, 0x5F, 0xE9,
3787
3788 0x3E, 0x50, 0x56, 0x9F,
3789 0x00, 0xE0,
3790 0x3B, 0x30,
3791
3792 0x1E, 0x8F, 0x51, 0x9F,
3793 0x33, 0x1E, 0x5F, 0xE9,
3794
3795 0x05, 0x44, 0x54, 0xB2,
3796 0x0D, 0x44, 0x4C, 0xB2,
3797
3798 0x19, 0xC0, 0xB0, 0xE8,
3799 0x34, 0xC0, 0x44, 0xC4,
3800
3801 0x33, 0x73,
3802 0x00, 0xE0,
3803 0x3E, 0x62, 0x57, 0x9F,
3804
3805 0x1E, 0xAF, 0x59, 0x9F,
3806 0x00, 0xE0,
3807 0x0D, 0x20,
3808
3809 0x84, 0x3E, 0x58, 0xE9,
3810 0x28, 0x1D, 0x6F, 0x8F,
3811
3812 0x05, 0x20,
3813 0x00, 0xE0,
3814 0x85, 0x1E, 0x58, 0xE9,
3815
3816 0x9B, 0x3B, 0x33, 0xDF,
3817 0x20, 0x20, 0x42, 0xAF,
3818
3819 0x30, 0x42, 0x56, 0x9F,
3820 0x80, 0x3E, 0x57, 0xE9,
3821
3822 0x3F, 0x8F, 0x51, 0x9F,
3823 0x30, 0x80, 0x5F, 0xE9,
3824
3825 0x28, 0x28, 0x24, 0xAF,
3826 0x81, 0x1E, 0x57, 0xE9,
3827
3828 0x05, 0x47, 0x57, 0xBF,
3829 0x0D, 0x47, 0x4F, 0xBF,
3830
3831 0x88, 0x80, 0x58, 0xE9,
3832 0x1B, 0x29, 0x1B, 0xDF,
3833
3834 0x30, 0x1D, 0x6F, 0x8F,
3835 0x3A, 0x30, 0x4F, 0xE9,
3836
3837 0x1C, 0x30, 0x26, 0xDF,
3838 0x09, 0xE3,
3839 0x3B, 0x05,
3840
3841 0x3E, 0x50, 0x56, 0x9F,
3842 0x3B, 0x3F, 0x4F, 0xE9,
3843
3844 0x1E, 0x8F, 0x51, 0x9F,
3845 0x00, 0xE0,
3846 0xAC, 0x20,
3847
3848 0x2D, 0x44, 0x4C, 0xB4,
3849 0x2C, 0x1C, 0xC0, 0xAF,
3850
3851 0x25, 0x44, 0x54, 0xB4,
3852 0x00, 0xE0,
3853 0xC8, 0x30,
3854
3855 0x30, 0x46, 0x30, 0xAF,
3856 0x1B, 0x1B, 0x48, 0xAF,
3857
3858 0x00, 0xE0,
3859 0x25, 0x20,
3860 0x38, 0x2C, 0x4F, 0xE9,
3861
3862 0x86, 0x80, 0x57, 0xE9,
3863 0x38, 0x1D, 0x6F, 0x8F,
3864
3865 0x28, 0x74,
3866 0x00, 0xE0,
3867 0x0D, 0x44, 0x4C, 0xB0,
3868
3869 0x05, 0x44, 0x54, 0xB0,
3870 0x2D, 0x20,
3871 0x9B, 0x10,
3872
3873 0x82, 0x3E, 0x57, 0xE9,
3874 0x32, 0xF0, 0x1B, 0xCD,
3875
3876 0x1E, 0xBD, 0x59, 0x9F,
3877 0x83, 0x1E, 0x57, 0xE9,
3878
3879 0x38, 0x47, 0x38, 0xAF,
3880 0x34, 0x20,
3881 0x2A, 0x30,
3882
3883 0x00, 0xE0,
3884 0x0D, 0x20,
3885 0x32, 0x20,
3886 0x05, 0x20,
3887
3888 0x87, 0x80, 0x57, 0xE9,
3889 0x1F, 0x54, 0x57, 0x9F,
3890
3891 0x17, 0x42, 0x56, 0x9F,
3892 0x00, 0xE0,
3893 0x3B, 0x6A,
3894
3895 0x3F, 0x8F, 0x51, 0x9F,
3896 0x37, 0x1E, 0x4F, 0xE9,
3897
3898 0x37, 0x32, 0x2A, 0xAF,
3899 0x00, 0xE0,
3900 0x32, 0x00,
3901
3902 0x00, 0x80, 0x00, 0xE8,
3903 0x27, 0xC0, 0x44, 0xC0,
3904
3905 0x36, 0x1F, 0x4F, 0xE9,
3906 0x1F, 0x1F, 0x26, 0xDF,
3907
3908 0x37, 0x1B, 0x37, 0xBF,
3909 0x17, 0x26, 0x17, 0xDF,
3910
3911 0x3E, 0x17, 0x4F, 0xE9,
3912 0x3F, 0x3F, 0x4F, 0xE9,
3913
3914 0x34, 0x1F, 0x34, 0xAF,
3915 0x2B, 0x05,
3916 0xA7, 0x20,
3917
3918 0x33, 0x2B, 0x37, 0xDF,
3919 0x27, 0x17, 0xC0, 0xAF,
3920
3921 0x34, 0x80, 0x4F, 0xE9,
3922 0x00, 0x80, 0x00, 0xE8,
3923
3924 0x2D, 0x21, 0x1A, 0xB0,
3925 0x25, 0x21, 0x31, 0xB0,
3926
3927 0x0D, 0x21, 0x1A, 0xB2,
3928 0x05, 0x21, 0x31, 0xB2,
3929
3930 0x03, 0x80, 0x2A, 0xEA,
3931 0x17, 0xC1, 0x2B, 0xBD,
3932
3933 0x2D, 0x20,
3934 0x25, 0x20,
3935 0x05, 0x20,
3936 0x0D, 0x20,
3937
3938 0xB3, 0x68,
3939 0x97, 0x25,
3940 0x00, 0x80, 0x00, 0xE8,
3941
3942 0x33, 0xC0, 0x33, 0xAF,
3943 0x2F, 0xC0, 0x21, 0xC0,
3944
3945 0x16, 0x42, 0x56, 0x9F,
3946 0x3C, 0x27, 0x4F, 0xE9,
3947
3948 0x1E, 0x62, 0x57, 0x9F,
3949 0x00, 0x80, 0x00, 0xE8,
3950
3951 0x25, 0x21, 0x31, 0xB4,
3952 0x2D, 0x21, 0x1A, 0xB4,
3953
3954 0x3F, 0x2F, 0x5D, 0x9F,
3955 0x00, 0x80, 0x00, 0xE8,
3956
3957 0x33, 0x05,
3958 0x00, 0xE0,
3959 0x28, 0x19, 0x60, 0xEC,
3960
3961 0x0D, 0x21, 0x1A, 0xB6,
3962 0x05, 0x21, 0x31, 0xB6,
3963
3964 0x37, 0x0F, 0x5C, 0x9F,
3965 0x00, 0xE0,
3966 0x2F, 0x20,
3967
3968 0x23, 0x3B, 0x33, 0xAD,
3969 0x1E, 0x26, 0x1E, 0xDF,
3970
3971 0xA7, 0x1E, 0x4F, 0xE9,
3972 0x17, 0x26, 0x16, 0xDF,
3973
3974 0x2D, 0x20,
3975 0x00, 0xE0,
3976 0xA8, 0x3F, 0x4F, 0xE9,
3977
3978 0x2F, 0x2F, 0x1E, 0xAF,
3979 0x25, 0x20,
3980 0x00, 0xE0,
3981
3982 0xA4, 0x16, 0x4F, 0xE9,
3983 0x0F, 0xC0, 0x21, 0xC2,
3984
3985 0xA6, 0x80, 0x4F, 0xE9,
3986 0x1F, 0x62, 0x57, 0x9F,
3987
3988 0x0D, 0x20,
3989 0x05, 0x20,
3990 0x2F, 0xC0, 0x21, 0xC6,
3991
3992 0x2D, 0x44, 0x4C, 0xB6,
3993 0x25, 0x44, 0x54, 0xB6,
3994
3995 0x3F, 0x2F, 0x5D, 0x9F,
3996 0x00, 0xE0,
3997 0x0F, 0x20,
3998
3999 0x2D, 0x20,
4000 0x25, 0x20,
4001 0x07, 0xC0, 0x44, 0xC6,
4002
4003 0x17, 0x50, 0x56, 0x9F,
4004 0xA5, 0x37, 0x4F, 0xE9,
4005
4006 0x06, 0xC0, 0x21, 0xC4,
4007 0x0F, 0x17, 0x0F, 0xAF,
4008
4009 0x37, 0x0F, 0x5C, 0x9F,
4010 0x00, 0x80, 0x00, 0xE8,
4011
4012 0x1E, 0x62, 0x57, 0x9F,
4013 0x00, 0x80, 0x00, 0xE8,
4014
4015 0x3E, 0x3D, 0x5D, 0x9F,
4016 0x00, 0xE0,
4017 0x07, 0x20,
4018
4019 0x2F, 0x20,
4020 0x00, 0xE0,
4021 0xA3, 0x0F, 0x4F, 0xE9,
4022
4023 0x06, 0x20,
4024 0x00, 0xE0,
4025 0x1F, 0x26, 0x1F, 0xDF,
4026
4027 0x17, 0x26, 0x17, 0xDF,
4028 0xA1, 0x1F, 0x4F, 0xE9,
4029
4030 0x1E, 0x26, 0x1E, 0xDF,
4031 0x9D, 0x1E, 0x4F, 0xE9,
4032
4033 0x35, 0x17, 0x4F, 0xE9,
4034 0xA2, 0x3F, 0x4F, 0xE9,
4035
4036 0x06, 0x06, 0x1F, 0xAF,
4037 0x39, 0x37, 0x4F, 0xE9,
4038
4039 0x2F, 0x2F, 0x17, 0xAF,
4040 0x07, 0x07, 0x1E, 0xAF,
4041
4042 0xA0, 0x80, 0x4F, 0xE9,
4043 0x9E, 0x3E, 0x4F, 0xE9,
4044
4045 0x31, 0x80, 0x4F, 0xE9,
4046 0x9C, 0x80, 0x4F, 0xE9,
4047
4048 0x00, 0x80, 0x00, 0xE8,
4049 0x57, 0x39, 0x20, 0xE9,
4050
4051 0x16, 0x28, 0x20, 0xE9,
4052 0x1D, 0x3B, 0x20, 0xE9,
4053
4054 0x1E, 0x2B, 0x20, 0xE9,
4055 0x2B, 0x32, 0x20, 0xE9,
4056
4057 0x1C, 0x23, 0x20, 0xE9,
4058 0x57, 0x36, 0x20, 0xE9,
4059
4060 0x00, 0x80, 0xA0, 0xE9,
4061 0x40, 0x40, 0xD8, 0xEC,
4062
4063 0xFF, 0x80, 0xC0, 0xE9,
4064 0x90, 0xE2,
4065 0x00, 0xE0,
4066
4067 0x63, 0xFF, 0x20, 0xEA,
4068 0x19, 0xC8, 0xC1, 0xCD,
4069
4070 0x1F, 0xD7, 0x18, 0xBD,
4071 0x3F, 0xD7, 0x22, 0xBD,
4072
4073 0x9F, 0x41, 0x49, 0xBD,
4074 0x00, 0x80, 0x00, 0xE8,
4075
4076 0x25, 0x41, 0x49, 0xBD,
4077 0x2D, 0x41, 0x51, 0xBD,
4078
4079 0x0D, 0x80, 0x07, 0xEA,
4080 0x00, 0x80, 0x00, 0xE8,
4081
4082 0x35, 0x40, 0x48, 0xBD,
4083 0x3D, 0x40, 0x50, 0xBD,
4084
4085 0x00, 0x80, 0x00, 0xE8,
4086 0x25, 0x30,
4087 0x2D, 0x30,
4088
4089 0x35, 0x30,
4090 0xB5, 0x30,
4091 0xBD, 0x30,
4092 0x3D, 0x30,
4093
4094 0x9C, 0xA7, 0x5B, 0x9F,
4095 0x00, 0x80, 0x00, 0xE8,
4096
4097 0x00, 0x80, 0x00, 0xE8,
4098 0x00, 0x80, 0x00, 0xE8,
4099
4100 0x00, 0x80, 0x00, 0xE8,
4101 0x00, 0x80, 0x00, 0xE8,
4102
4103 0x00, 0x80, 0x00, 0xE8,
4104 0x00, 0x80, 0x00, 0xE8,
4105
4106 0x00, 0x80, 0x00, 0xE8,
4107 0x00, 0x80, 0x00, 0xE8,
4108
4109 0x62, 0xFF, 0x0A, 0xEA,
4110 0x00, 0x80, 0x00, 0xE8,
4111
4112 0xC9, 0x41, 0xC8, 0xEC,
4113 0x42, 0xE1,
4114 0x00, 0xE0,
4115
4116 0x60, 0xFF, 0x20, 0xEA,
4117 0x00, 0x80, 0x00, 0xE8,
4118
4119 0x00, 0x80, 0x00, 0xE8,
4120 0x00, 0x80, 0x00, 0xE8,
4121
4122 0xC8, 0x40, 0xC0, 0xEC,
4123 0x00, 0x80, 0x00, 0xE8,
4124
4125 0x5D, 0xFF, 0x20, 0xEA,
4126 0x00, 0x80, 0x00, 0xE8,
4127
4128 0x00, 0x80, 0x00, 0xE8,
4129 0x00, 0x80, 0x00, 0xE8,
4130
4131};
4132
4133static unsigned char warp_g200_tgzsf[] = {
4134
4135 0x00, 0x80, 0x00, 0xE8,
4136 0x00, 0x80, 0x00, 0xE8,
4137
4138 0x00, 0x80, 0x00, 0xE8,
4139 0x00, 0x80, 0x00, 0xE8,
4140
4141 0x00, 0x80, 0x00, 0xE8,
4142 0x00, 0x80, 0x00, 0xE8,
4143
4144 0x00, 0x80, 0x00, 0xE8,
4145 0x00, 0x80, 0x00, 0xE8,
4146
4147 0x00, 0x80, 0x00, 0xE8,
4148 0x00, 0x80, 0x00, 0xE8,
4149
4150 0x00, 0x80, 0x00, 0xE8,
4151 0x00, 0x80, 0x00, 0xE8,
4152
4153 0x00, 0x80, 0x00, 0xE8,
4154 0x00, 0x80, 0x00, 0xE8,
4155
4156 0x00, 0x80, 0x00, 0xE8,
4157 0x00, 0x80, 0x00, 0xE8,
4158
4159 0x00, 0x80, 0x00, 0xE8,
4160 0x00, 0x80, 0x00, 0xE8,
4161
4162 0x00, 0x80, 0x00, 0xE8,
4163 0x00, 0x80, 0x00, 0xE8,
4164
4165 0x00, 0x80, 0x00, 0xE8,
4166 0x00, 0x80, 0x00, 0xE8,
4167
4168 0x00, 0x80, 0x00, 0xE8,
4169 0x00, 0x80, 0x00, 0xE8,
4170
4171 0x00, 0x80, 0x00, 0xE8,
4172 0x00, 0x80, 0x00, 0xE8,
4173
4174 0x00, 0x98, 0xA0, 0xE9,
4175 0x40, 0x40, 0xD8, 0xEC,
4176
4177 0xFF, 0x80, 0xC0, 0xE9,
4178 0x00, 0x80, 0x00, 0xE8,
4179
4180 0x1F, 0xD7, 0x18, 0xBD,
4181 0x3F, 0xD7, 0x22, 0xBD,
4182
4183 0x81, 0x04,
4184 0x89, 0x04,
4185 0x01, 0x04,
4186 0x09, 0x04,
4187
4188 0xC9, 0x41, 0xC0, 0xEC,
4189 0x11, 0x04,
4190 0x00, 0xE0,
4191
4192 0x41, 0xCC, 0x41, 0xCD,
4193 0x49, 0xCC, 0x49, 0xCD,
4194
4195 0xD1, 0x41, 0xC0, 0xEC,
4196 0x51, 0xCC, 0x51, 0xCD,
4197
4198 0x80, 0x04,
4199 0x10, 0x04,
4200 0x08, 0x04,
4201 0x00, 0xE0,
4202
4203 0x00, 0xCC, 0xC0, 0xCD,
4204 0xD1, 0x49, 0xC0, 0xEC,
4205
4206 0x8A, 0x1F, 0x20, 0xE9,
4207 0x8B, 0x3F, 0x20, 0xE9,
4208
4209 0x41, 0x3C, 0x41, 0xAD,
4210 0x49, 0x3C, 0x49, 0xAD,
4211
4212 0x10, 0xCC, 0x10, 0xCD,
4213 0x08, 0xCC, 0x08, 0xCD,
4214
4215 0xB9, 0x41, 0x49, 0xBB,
4216 0x1F, 0xF0, 0x41, 0xCD,
4217
4218 0x51, 0x3C, 0x51, 0xAD,
4219 0x00, 0x98, 0x80, 0xE9,
4220
4221 0x8F, 0x80, 0x07, 0xEA,
4222 0x24, 0x1F, 0x20, 0xE9,
4223
4224 0x21, 0x45, 0x80, 0xE8,
4225 0x1A, 0x4D, 0x80, 0xE8,
4226
4227 0x31, 0x55, 0x80, 0xE8,
4228 0x00, 0x80, 0x00, 0xE8,
4229
4230 0x15, 0x41, 0x49, 0xBD,
4231 0x1D, 0x41, 0x51, 0xBD,
4232
4233 0x2E, 0x41, 0x2A, 0xB8,
4234 0x34, 0x53, 0xA0, 0xE8,
4235
4236 0x15, 0x30,
4237 0x1D, 0x30,
4238 0x58, 0xE3,
4239 0x00, 0xE0,
4240
4241 0xB5, 0x40, 0x48, 0xBD,
4242 0x3D, 0x40, 0x50, 0xBD,
4243
4244 0x24, 0x43, 0xA0, 0xE8,
4245 0x2C, 0x4B, 0xA0, 0xE8,
4246
4247 0x15, 0x72,
4248 0x09, 0xE3,
4249 0x00, 0xE0,
4250 0x1D, 0x72,
4251
4252 0x35, 0x30,
4253 0xB5, 0x30,
4254 0xBD, 0x30,
4255 0x3D, 0x30,
4256
4257 0x9C, 0x97, 0x57, 0x9F,
4258 0x00, 0x80, 0x00, 0xE8,
4259
4260 0x6C, 0x64, 0xC8, 0xEC,
4261 0x98, 0xE1,
4262 0xB5, 0x05,
4263
4264 0xBD, 0x05,
4265 0x2E, 0x30,
4266 0x32, 0xC0, 0xA0, 0xE8,
4267
4268 0x33, 0xC0, 0xA0, 0xE8,
4269 0x74, 0x64, 0xC8, 0xEC,
4270
4271 0x40, 0x3C, 0x40, 0xAD,
4272 0x32, 0x6A,
4273 0x2A, 0x30,
4274
4275 0x20, 0x73,
4276 0x33, 0x6A,
4277 0x00, 0xE0,
4278 0x28, 0x73,
4279
4280 0x1C, 0x72,
4281 0x83, 0xE2,
4282 0x7B, 0x80, 0x15, 0xEA,
4283
4284 0xB8, 0x3D, 0x28, 0xDF,
4285 0x30, 0x35, 0x20, 0xDF,
4286
4287 0x40, 0x30,
4288 0x00, 0xE0,
4289 0xCC, 0xE2,
4290 0x64, 0x72,
4291
4292 0x25, 0x42, 0x52, 0xBF,
4293 0x2D, 0x42, 0x4A, 0xBF,
4294
4295 0x30, 0x2E, 0x30, 0xDF,
4296 0x38, 0x2E, 0x38, 0xDF,
4297
4298 0x18, 0x1D, 0x45, 0xE9,
4299 0x1E, 0x15, 0x45, 0xE9,
4300
4301 0x2B, 0x49, 0x51, 0xBD,
4302 0x00, 0xE0,
4303 0x1F, 0x73,
4304
4305 0x38, 0x38, 0x40, 0xAF,
4306 0x30, 0x30, 0x40, 0xAF,
4307
4308 0x24, 0x1F, 0x24, 0xDF,
4309 0x1D, 0x32, 0x20, 0xE9,
4310
4311 0x2C, 0x1F, 0x2C, 0xDF,
4312 0x1A, 0x33, 0x20, 0xE9,
4313
4314 0xB0, 0x10,
4315 0x08, 0xE3,
4316 0x40, 0x10,
4317 0xB8, 0x10,
4318
4319 0x26, 0xF0, 0x30, 0xCD,
4320 0x2F, 0xF0, 0x38, 0xCD,
4321
4322 0x2B, 0x80, 0x20, 0xE9,
4323 0x2A, 0x80, 0x20, 0xE9,
4324
4325 0xA6, 0x20,
4326 0x88, 0xE2,
4327 0x00, 0xE0,
4328 0xAF, 0x20,
4329
4330 0x28, 0x2A, 0x26, 0xAF,
4331 0x20, 0x2A, 0xC0, 0xAF,
4332
4333 0x34, 0x1F, 0x34, 0xDF,
4334 0x46, 0x24, 0x46, 0xDF,
4335
4336 0x28, 0x30, 0x80, 0xBF,
4337 0x20, 0x38, 0x80, 0xBF,
4338
4339 0x47, 0x24, 0x47, 0xDF,
4340 0x4E, 0x2C, 0x4E, 0xDF,
4341
4342 0x4F, 0x2C, 0x4F, 0xDF,
4343 0x56, 0x34, 0x56, 0xDF,
4344
4345 0x28, 0x15, 0x28, 0xDF,
4346 0x20, 0x1D, 0x20, 0xDF,
4347
4348 0x57, 0x34, 0x57, 0xDF,
4349 0x00, 0xE0,
4350 0x1D, 0x05,
4351
4352 0x04, 0x80, 0x10, 0xEA,
4353 0x89, 0xE2,
4354 0x2B, 0x30,
4355
4356 0x3F, 0xC1, 0x1D, 0xBD,
4357 0x00, 0x80, 0x00, 0xE8,
4358
4359 0x00, 0x80, 0x00, 0xE8,
4360 0x00, 0x80, 0x00, 0xE8,
4361
4362 0xA0, 0x68,
4363 0xBF, 0x25,
4364 0x00, 0x80, 0x00, 0xE8,
4365
4366 0x20, 0xC0, 0x20, 0xAF,
4367 0x28, 0x05,
4368 0x97, 0x74,
4369
4370 0x00, 0xE0,
4371 0x2A, 0x10,
4372 0x16, 0xC0, 0x20, 0xE9,
4373
4374 0x04, 0x80, 0x10, 0xEA,
4375 0x8C, 0xE2,
4376 0x95, 0x05,
4377
4378 0x28, 0xC1, 0x28, 0xAD,
4379 0x1F, 0xC1, 0x15, 0xBD,
4380
4381 0x00, 0x80, 0x00, 0xE8,
4382 0x00, 0x80, 0x00, 0xE8,
4383
4384 0xA8, 0x67,
4385 0x9F, 0x6B,
4386 0x00, 0x80, 0x00, 0xE8,
4387
4388 0x28, 0xC0, 0x28, 0xAD,
4389 0x1D, 0x25,
4390 0x20, 0x05,
4391
4392 0x28, 0x32, 0x80, 0xAD,
4393 0x40, 0x2A, 0x40, 0xBD,
4394
4395 0x1C, 0x80, 0x20, 0xE9,
4396 0x20, 0x33, 0x20, 0xAD,
4397
4398 0x20, 0x73,
4399 0x00, 0xE0,
4400 0xB6, 0x49, 0x51, 0xBB,
4401
4402 0x26, 0x2F, 0xB0, 0xE8,
4403 0x19, 0x20, 0x20, 0xE9,
4404
4405 0x35, 0x20, 0x35, 0xDF,
4406 0x3D, 0x20, 0x3D, 0xDF,
4407
4408 0x15, 0x20, 0x15, 0xDF,
4409 0x1D, 0x20, 0x1D, 0xDF,
4410
4411 0x26, 0xD0, 0x26, 0xCD,
4412 0x29, 0x49, 0x2A, 0xB8,
4413
4414 0x26, 0x40, 0x80, 0xBD,
4415 0x3B, 0x48, 0x50, 0xBD,
4416
4417 0x3E, 0x54, 0x57, 0x9F,
4418 0x00, 0xE0,
4419 0x82, 0xE1,
4420
4421 0x1E, 0xAF, 0x59, 0x9F,
4422 0x00, 0x80, 0x00, 0xE8,
4423
4424 0x26, 0x30,
4425 0x29, 0x30,
4426 0x48, 0x3C, 0x48, 0xAD,
4427
4428 0x2B, 0x72,
4429 0xC2, 0xE1,
4430 0x2C, 0xC0, 0x44, 0xC2,
4431
4432 0x05, 0x24, 0x34, 0xBF,
4433 0x0D, 0x24, 0x2C, 0xBF,
4434
4435 0x2D, 0x46, 0x4E, 0xBF,
4436 0x25, 0x46, 0x56, 0xBF,
4437
4438 0x20, 0x1D, 0x6F, 0x8F,
4439 0x32, 0x3E, 0x5F, 0xE9,
4440
4441 0x3E, 0x50, 0x56, 0x9F,
4442 0x00, 0xE0,
4443 0x3B, 0x30,
4444
4445 0x1E, 0x8F, 0x51, 0x9F,
4446 0x33, 0x1E, 0x5F, 0xE9,
4447
4448 0x05, 0x44, 0x54, 0xB2,
4449 0x0D, 0x44, 0x4C, 0xB2,
4450
4451 0x19, 0xC0, 0xB0, 0xE8,
4452 0x34, 0xC0, 0x44, 0xC4,
4453
4454 0x33, 0x73,
4455 0x00, 0xE0,
4456 0x3E, 0x62, 0x57, 0x9F,
4457
4458 0x1E, 0xAF, 0x59, 0x9F,
4459 0x00, 0xE0,
4460 0x0D, 0x20,
4461
4462 0x84, 0x3E, 0x58, 0xE9,
4463 0x28, 0x1D, 0x6F, 0x8F,
4464
4465 0x05, 0x20,
4466 0x00, 0xE0,
4467 0x85, 0x1E, 0x58, 0xE9,
4468
4469 0x9B, 0x3B, 0x33, 0xDF,
4470 0x20, 0x20, 0x42, 0xAF,
4471
4472 0x30, 0x42, 0x56, 0x9F,
4473 0x80, 0x3E, 0x57, 0xE9,
4474
4475 0x3F, 0x8F, 0x51, 0x9F,
4476 0x30, 0x80, 0x5F, 0xE9,
4477
4478 0x28, 0x28, 0x24, 0xAF,
4479 0x81, 0x1E, 0x57, 0xE9,
4480
4481 0x05, 0x47, 0x57, 0xBF,
4482 0x0D, 0x47, 0x4F, 0xBF,
4483
4484 0x88, 0x80, 0x58, 0xE9,
4485 0x1B, 0x29, 0x1B, 0xDF,
4486
4487 0x30, 0x1D, 0x6F, 0x8F,
4488 0x3A, 0x30, 0x4F, 0xE9,
4489
4490 0x1C, 0x30, 0x26, 0xDF,
4491 0x09, 0xE3,
4492 0x3B, 0x05,
4493
4494 0x3E, 0x50, 0x56, 0x9F,
4495 0x3B, 0x3F, 0x4F, 0xE9,
4496
4497 0x1E, 0x8F, 0x51, 0x9F,
4498 0x00, 0xE0,
4499 0xAC, 0x20,
4500
4501 0x2D, 0x44, 0x4C, 0xB4,
4502 0x2C, 0x1C, 0xC0, 0xAF,
4503
4504 0x25, 0x44, 0x54, 0xB4,
4505 0x00, 0xE0,
4506 0xC8, 0x30,
4507
4508 0x30, 0x46, 0x30, 0xAF,
4509 0x1B, 0x1B, 0x48, 0xAF,
4510
4511 0x00, 0xE0,
4512 0x25, 0x20,
4513 0x38, 0x2C, 0x4F, 0xE9,
4514
4515 0x86, 0x80, 0x57, 0xE9,
4516 0x38, 0x1D, 0x6F, 0x8F,
4517
4518 0x28, 0x74,
4519 0x00, 0xE0,
4520 0x0D, 0x44, 0x4C, 0xB0,
4521
4522 0x05, 0x44, 0x54, 0xB0,
4523 0x2D, 0x20,
4524 0x9B, 0x10,
4525
4526 0x82, 0x3E, 0x57, 0xE9,
4527 0x32, 0xF0, 0x1B, 0xCD,
4528
4529 0x1E, 0xBD, 0x59, 0x9F,
4530 0x83, 0x1E, 0x57, 0xE9,
4531
4532 0x38, 0x47, 0x38, 0xAF,
4533 0x34, 0x20,
4534 0x2A, 0x30,
4535
4536 0x00, 0xE0,
4537 0x0D, 0x20,
4538 0x32, 0x20,
4539 0x05, 0x20,
4540
4541 0x87, 0x80, 0x57, 0xE9,
4542 0x1F, 0x54, 0x57, 0x9F,
4543
4544 0x17, 0x42, 0x56, 0x9F,
4545 0x00, 0xE0,
4546 0x3B, 0x6A,
4547
4548 0x3F, 0x8F, 0x51, 0x9F,
4549 0x37, 0x1E, 0x4F, 0xE9,
4550
4551 0x37, 0x32, 0x2A, 0xAF,
4552 0x00, 0xE0,
4553 0x32, 0x00,
4554
4555 0x00, 0x80, 0x00, 0xE8,
4556 0x27, 0xC0, 0x44, 0xC0,
4557
4558 0x36, 0x1F, 0x4F, 0xE9,
4559 0x1F, 0x1F, 0x26, 0xDF,
4560
4561 0x37, 0x1B, 0x37, 0xBF,
4562 0x17, 0x26, 0x17, 0xDF,
4563
4564 0x3E, 0x17, 0x4F, 0xE9,
4565 0x3F, 0x3F, 0x4F, 0xE9,
4566
4567 0x34, 0x1F, 0x34, 0xAF,
4568 0x2B, 0x05,
4569 0xA7, 0x20,
4570
4571 0x33, 0x2B, 0x37, 0xDF,
4572 0x27, 0x17, 0xC0, 0xAF,
4573
4574 0x34, 0x80, 0x4F, 0xE9,
4575 0x00, 0x80, 0x00, 0xE8,
4576
4577 0x2D, 0x21, 0x1A, 0xB0,
4578 0x25, 0x21, 0x31, 0xB0,
4579
4580 0x0D, 0x21, 0x1A, 0xB2,
4581 0x05, 0x21, 0x31, 0xB2,
4582
4583 0x03, 0x80, 0x2A, 0xEA,
4584 0x17, 0xC1, 0x2B, 0xBD,
4585
4586 0x2D, 0x20,
4587 0x25, 0x20,
4588 0x05, 0x20,
4589 0x0D, 0x20,
4590
4591 0xB3, 0x68,
4592 0x97, 0x25,
4593 0x00, 0x80, 0x00, 0xE8,
4594
4595 0x33, 0xC0, 0x33, 0xAF,
4596 0x2F, 0xC0, 0x21, 0xC0,
4597
4598 0x16, 0x42, 0x56, 0x9F,
4599 0x3C, 0x27, 0x4F, 0xE9,
4600
4601 0x1E, 0x62, 0x57, 0x9F,
4602 0x00, 0x80, 0x00, 0xE8,
4603
4604 0x25, 0x21, 0x31, 0xB4,
4605 0x2D, 0x21, 0x1A, 0xB4,
4606
4607 0x3F, 0x2F, 0x5D, 0x9F,
4608 0x00, 0x80, 0x00, 0xE8,
4609
4610 0x33, 0x05,
4611 0x00, 0xE0,
4612 0x28, 0x19, 0x60, 0xEC,
4613
4614 0x0D, 0x21, 0x1A, 0xB6,
4615 0x05, 0x21, 0x31, 0xB6,
4616
4617 0x37, 0x0F, 0x5C, 0x9F,
4618 0x00, 0xE0,
4619 0x2F, 0x20,
4620
4621 0x23, 0x3B, 0x33, 0xAD,
4622 0x1E, 0x26, 0x1E, 0xDF,
4623
4624 0xA7, 0x1E, 0x4F, 0xE9,
4625 0x17, 0x26, 0x16, 0xDF,
4626
4627 0x2D, 0x20,
4628 0x00, 0xE0,
4629 0xA8, 0x3F, 0x4F, 0xE9,
4630
4631 0x2F, 0x2F, 0x1E, 0xAF,
4632 0x25, 0x20,
4633 0x00, 0xE0,
4634
4635 0xA4, 0x16, 0x4F, 0xE9,
4636 0x0F, 0xC0, 0x21, 0xC2,
4637
4638 0xA6, 0x80, 0x4F, 0xE9,
4639 0x1F, 0x62, 0x57, 0x9F,
4640
4641 0x0D, 0x20,
4642 0x05, 0x20,
4643 0x2F, 0xC0, 0x21, 0xC6,
4644
4645 0x3F, 0x2F, 0x5D, 0x9F,
4646 0x00, 0xE0,
4647 0x0F, 0x20,
4648
4649 0x17, 0x50, 0x56, 0x9F,
4650 0xA5, 0x37, 0x4F, 0xE9,
4651
4652 0x06, 0xC0, 0x21, 0xC4,
4653 0x0F, 0x17, 0x0F, 0xAF,
4654
4655 0x37, 0x0F, 0x5C, 0x9F,
4656 0x00, 0x80, 0x00, 0xE8,
4657
4658 0x2F, 0x20,
4659 0x00, 0xE0,
4660 0xA3, 0x80, 0x4F, 0xE9,
4661
4662 0x06, 0x20,
4663 0x00, 0xE0,
4664 0x1F, 0x26, 0x1F, 0xDF,
4665
4666 0x17, 0x26, 0x17, 0xDF,
4667 0x35, 0x17, 0x4F, 0xE9,
4668
4669 0xA1, 0x1F, 0x4F, 0xE9,
4670 0xA2, 0x3F, 0x4F, 0xE9,
4671
4672 0x06, 0x06, 0x1F, 0xAF,
4673 0x39, 0x37, 0x4F, 0xE9,
4674
4675 0x2F, 0x2F, 0x17, 0xAF,
4676 0x00, 0x80, 0x00, 0xE8,
4677
4678 0xA0, 0x80, 0x4F, 0xE9,
4679 0x00, 0x80, 0x00, 0xE8,
4680
4681 0x31, 0x80, 0x4F, 0xE9,
4682 0x00, 0x80, 0x00, 0xE8,
4683
4684 0x00, 0x80, 0x00, 0xE8,
4685 0x57, 0x39, 0x20, 0xE9,
4686
4687 0x16, 0x28, 0x20, 0xE9,
4688 0x1D, 0x3B, 0x20, 0xE9,
4689
4690 0x1E, 0x2B, 0x20, 0xE9,
4691 0x2B, 0x32, 0x20, 0xE9,
4692
4693 0x1C, 0x23, 0x20, 0xE9,
4694 0x57, 0x36, 0x20, 0xE9,
4695
4696 0x00, 0x80, 0xA0, 0xE9,
4697 0x40, 0x40, 0xD8, 0xEC,
4698
4699 0xFF, 0x80, 0xC0, 0xE9,
4700 0x90, 0xE2,
4701 0x00, 0xE0,
4702
4703 0x68, 0xFF, 0x20, 0xEA,
4704 0x19, 0xC8, 0xC1, 0xCD,
4705
4706 0x1F, 0xD7, 0x18, 0xBD,
4707 0x3F, 0xD7, 0x22, 0xBD,
4708
4709 0x9F, 0x41, 0x49, 0xBD,
4710 0x00, 0x80, 0x00, 0xE8,
4711
4712 0x25, 0x41, 0x49, 0xBD,
4713 0x2D, 0x41, 0x51, 0xBD,
4714
4715 0x0D, 0x80, 0x07, 0xEA,
4716 0x00, 0x80, 0x00, 0xE8,
4717
4718 0x35, 0x40, 0x48, 0xBD,
4719 0x3D, 0x40, 0x50, 0xBD,
4720
4721 0x00, 0x80, 0x00, 0xE8,
4722 0x25, 0x30,
4723 0x2D, 0x30,
4724
4725 0x35, 0x30,
4726 0xB5, 0x30,
4727 0xBD, 0x30,
4728 0x3D, 0x30,
4729
4730 0x9C, 0xA7, 0x5B, 0x9F,
4731 0x00, 0x80, 0x00, 0xE8,
4732
4733 0x00, 0x80, 0x00, 0xE8,
4734 0x00, 0x80, 0x00, 0xE8,
4735
4736 0x00, 0x80, 0x00, 0xE8,
4737 0x00, 0x80, 0x00, 0xE8,
4738
4739 0x00, 0x80, 0x00, 0xE8,
4740 0x00, 0x80, 0x00, 0xE8,
4741
4742 0x00, 0x80, 0x00, 0xE8,
4743 0x00, 0x80, 0x00, 0xE8,
4744
4745 0x67, 0xFF, 0x0A, 0xEA,
4746 0x00, 0x80, 0x00, 0xE8,
4747
4748 0xC9, 0x41, 0xC8, 0xEC,
4749 0x42, 0xE1,
4750 0x00, 0xE0,
4751
4752 0x65, 0xFF, 0x20, 0xEA,
4753 0x00, 0x80, 0x00, 0xE8,
4754
4755 0x00, 0x80, 0x00, 0xE8,
4756 0x00, 0x80, 0x00, 0xE8,
4757
4758 0xC8, 0x40, 0xC0, 0xEC,
4759 0x00, 0x80, 0x00, 0xE8,
4760
4761 0x62, 0xFF, 0x20, 0xEA,
4762 0x00, 0x80, 0x00, 0xE8,
4763
4764 0x00, 0x80, 0x00, 0xE8,
4765 0x00, 0x80, 0x00, 0xE8,
4766
4767};
4768
4769static unsigned char warp_g400_t2gz[] = {
4770
4771 0x00, 0x8A, 0x98, 0xE9,
4772 0x00, 0x80, 0x00, 0xE8,
4773
4774 0x00, 0x80, 0xA0, 0xE9,
4775 0x00, 0x00, 0xD8, 0xEC,
4776
4777 0xFF, 0x80, 0xC0, 0xE9,
4778 0x00, 0x80, 0x00, 0xE8,
4779
4780 0x0A, 0x40, 0x50, 0xBF,
4781 0x2A, 0x40, 0x60, 0xBF,
4782
4783 0x32, 0x41, 0x51, 0xBF,
4784 0x3A, 0x41, 0x61, 0xBF,
4785
4786 0xC3, 0x6B,
4787 0xD3, 0x6B,
4788 0x00, 0x8A, 0x98, 0xE9,
4789
4790 0x73, 0x7B, 0xC8, 0xEC,
4791 0x96, 0xE2,
4792 0x41, 0x04,
4793
4794 0x7B, 0x43, 0xA0, 0xE8,
4795 0x73, 0x53, 0xA0, 0xE8,
4796
4797 0xAD, 0xEE, 0x23, 0x9F,
4798 0x00, 0xE0,
4799 0x51, 0x04,
4800
4801 0x90, 0xE2,
4802 0x61, 0x04,
4803 0x31, 0x46, 0xB1, 0xE8,
4804
4805 0x51, 0x41, 0xE0, 0xEC,
4806 0x39, 0x67, 0xB1, 0xE8,
4807
4808 0x00, 0x04,
4809 0x46, 0xE2,
4810 0x73, 0x63, 0xA0, 0xE8,
4811
4812 0x61, 0x41, 0xE0, 0xEC,
4813 0x31, 0x00,
4814 0x39, 0x00,
4815
4816 0x78, 0x80, 0x15, 0xEA,
4817 0x10, 0x04,
4818 0x20, 0x04,
4819
4820 0x61, 0x51, 0xE0, 0xEC,
4821 0x2F, 0x41, 0x60, 0xEA,
4822
4823 0x31, 0x20,
4824 0x39, 0x20,
4825 0x1F, 0x42, 0xA0, 0xE8,
4826
4827 0x2A, 0x42, 0x52, 0xBF,
4828 0x0F, 0x52, 0xA0, 0xE8,
4829
4830 0x1A, 0x42, 0x62, 0xBF,
4831 0x1E, 0x51, 0x60, 0xEA,
4832
4833 0x73, 0x7B, 0xC8, 0xEC,
4834 0x0E, 0x61, 0x60, 0xEA,
4835
4836 0x32, 0x40, 0x50, 0xBD,
4837 0x22, 0x40, 0x60, 0xBD,
4838
4839 0x12, 0x41, 0x51, 0xBD,
4840 0x3A, 0x41, 0x61, 0xBD,
4841
4842 0xBF, 0x2F, 0x0E, 0xBD,
4843 0x97, 0xE2,
4844 0x7B, 0x72,
4845
4846 0x32, 0x20,
4847 0x22, 0x20,
4848 0x12, 0x20,
4849 0x3A, 0x20,
4850
4851 0x35, 0x48, 0xB1, 0xE8,
4852 0x3D, 0x59, 0xB1, 0xE8,
4853
4854 0x46, 0x31, 0x46, 0xBF,
4855 0x56, 0x31, 0x56, 0xBF,
4856
4857 0xB3, 0xE2, 0x2D, 0x9F,
4858 0x00, 0x80, 0x00, 0xE8,
4859
4860 0x66, 0x31, 0x66, 0xBF,
4861 0x47, 0x39, 0x47, 0xBF,
4862
4863 0x57, 0x39, 0x57, 0xBF,
4864 0x67, 0x39, 0x67, 0xBF,
4865
4866 0x69, 0x80, 0x07, 0xEA,
4867 0x24, 0x41, 0x20, 0xE9,
4868
4869 0x35, 0x00,
4870 0x3D, 0x00,
4871 0x00, 0xE0,
4872 0x2D, 0x73,
4873
4874 0x33, 0x72,
4875 0x0C, 0xE3,
4876 0x8D, 0x2F, 0x1E, 0xBD,
4877
4878 0x43, 0x75, 0xF8, 0xEC,
4879 0x35, 0x20,
4880 0x3D, 0x20,
4881
4882 0x43, 0x43, 0x2D, 0xDF,
4883 0x53, 0x53, 0x2D, 0xDF,
4884
4885 0xAE, 0x1E, 0x0E, 0xBD,
4886 0x58, 0xE3,
4887 0x33, 0x66,
4888
4889 0x48, 0x35, 0x48, 0xBF,
4890 0x58, 0x35, 0x58, 0xBF,
4891
4892 0x68, 0x35, 0x68, 0xBF,
4893 0x49, 0x3D, 0x49, 0xBF,
4894
4895 0x59, 0x3D, 0x59, 0xBF,
4896 0x69, 0x3D, 0x69, 0xBF,
4897
4898 0x63, 0x63, 0x2D, 0xDF,
4899 0x4D, 0x7D, 0xF8, 0xEC,
4900
4901 0x59, 0xE3,
4902 0x00, 0xE0,
4903 0xB8, 0x38, 0x33, 0xBF,
4904
4905 0x2D, 0x73,
4906 0x30, 0x76,
4907 0x18, 0x3A, 0x41, 0xE9,
4908
4909 0x3F, 0x53, 0xA0, 0xE8,
4910 0x05, 0x80, 0x3D, 0xEA,
4911
4912 0x37, 0x43, 0xA0, 0xE8,
4913 0x3D, 0x63, 0xA0, 0xE8,
4914
4915 0x50, 0x70, 0xF8, 0xEC,
4916 0x2B, 0x50, 0x3C, 0xE9,
4917
4918 0x1F, 0x0F, 0xBC, 0xE8,
4919 0x00, 0x80, 0x00, 0xE8,
4920
4921 0x59, 0x78, 0xF8, 0xEC,
4922 0x00, 0x80, 0x00, 0xE8,
4923
4924 0x15, 0xC0, 0x20, 0xE9,
4925 0x15, 0xC0, 0x20, 0xE9,
4926
4927 0x15, 0xC0, 0x20, 0xE9,
4928 0x15, 0xC0, 0x20, 0xE9,
4929
4930 0x1E, 0x12, 0x41, 0xE9,
4931 0x1A, 0x22, 0x41, 0xE9,
4932
4933 0x46, 0x37, 0x46, 0xDF,
4934 0x56, 0x3F, 0x56, 0xDF,
4935
4936 0x2B, 0x40, 0x3D, 0xE9,
4937 0x66, 0x3D, 0x66, 0xDF,
4938
4939 0x1D, 0x32, 0x41, 0xE9,
4940 0x67, 0x3D, 0x67, 0xDF,
4941
4942 0x47, 0x37, 0x47, 0xDF,
4943 0x57, 0x3F, 0x57, 0xDF,
4944
4945 0x2A, 0x40, 0x20, 0xE9,
4946 0x59, 0x3F, 0x59, 0xDF,
4947
4948 0x16, 0x30, 0x20, 0xE9,
4949 0x69, 0x3D, 0x69, 0xDF,
4950
4951 0x48, 0x37, 0x48, 0xDF,
4952 0x58, 0x3F, 0x58, 0xDF,
4953
4954 0x12, 0x12, 0x2D, 0xDF,
4955 0x22, 0x22, 0x2D, 0xDF,
4956
4957 0x32, 0x32, 0x2D, 0xDF,
4958 0x3A, 0x3A, 0x2D, 0xDF,
4959
4960 0x68, 0x3D, 0x68, 0xDF,
4961 0x49, 0x37, 0x49, 0xDF,
4962
4963 0x3D, 0xCF, 0x74, 0xC0,
4964 0x37, 0xCF, 0x74, 0xC4,
4965
4966 0x31, 0x53, 0x2F, 0x9F,
4967 0x34, 0x80, 0x20, 0xE9,
4968
4969 0x39, 0xE5, 0x2C, 0x9F,
4970 0x3C, 0x3D, 0x20, 0xE9,
4971
4972 0x0A, 0x44, 0x54, 0xB0,
4973 0x02, 0x44, 0x64, 0xB0,
4974
4975 0x2A, 0x44, 0x54, 0xB2,
4976 0x1A, 0x44, 0x64, 0xB2,
4977
4978 0x25, 0x80, 0x3A, 0xEA,
4979 0x0A, 0x20,
4980 0x02, 0x20,
4981
4982 0x3D, 0xCF, 0x74, 0xC2,
4983 0x2A, 0x20,
4984 0x1A, 0x20,
4985
4986 0x30, 0x50, 0x2E, 0x9F,
4987 0x32, 0x31, 0x5F, 0xE9,
4988
4989 0x38, 0x21, 0x2C, 0x9F,
4990 0x33, 0x39, 0x5F, 0xE9,
4991
4992 0x31, 0x53, 0x2F, 0x9F,
4993 0x00, 0x80, 0x00, 0xE8,
4994
4995 0x2A, 0x44, 0x54, 0xB4,
4996 0x1A, 0x44, 0x64, 0xB4,
4997
4998 0x39, 0xE5, 0x2C, 0x9F,
4999 0x38, 0x3D, 0x20, 0xE9,
5000
5001 0x88, 0x73, 0x5E, 0xE9,
5002 0x2A, 0x20,
5003 0x1A, 0x20,
5004
5005 0x2A, 0x46, 0x56, 0xBF,
5006 0x1A, 0x46, 0x66, 0xBF,
5007
5008 0x31, 0x53, 0x2F, 0x9F,
5009 0x3E, 0x30, 0x4F, 0xE9,
5010
5011 0x39, 0xE5, 0x2C, 0x9F,
5012 0x3F, 0x38, 0x4F, 0xE9,
5013
5014 0x0A, 0x47, 0x57, 0xBF,
5015 0x02, 0x47, 0x67, 0xBF,
5016
5017 0x31, 0x53, 0x2F, 0x9F,
5018 0x3A, 0x31, 0x4F, 0xE9,
5019
5020 0x39, 0xE5, 0x2C, 0x9F,
5021 0x3B, 0x39, 0x4F, 0xE9,
5022
5023 0x2A, 0x43, 0x53, 0xBF,
5024 0x1A, 0x43, 0x63, 0xBF,
5025
5026 0x30, 0x50, 0x2E, 0x9F,
5027 0x36, 0x31, 0x4F, 0xE9,
5028
5029 0x38, 0x21, 0x2C, 0x9F,
5030 0x37, 0x39, 0x4F, 0xE9,
5031
5032 0x0A, 0x48, 0x58, 0xBF,
5033 0x02, 0x48, 0x68, 0xBF,
5034
5035 0x31, 0x53, 0x2F, 0x9F,
5036 0x80, 0x31, 0x57, 0xE9,
5037
5038 0x39, 0xE5, 0x2C, 0x9F,
5039 0x81, 0x39, 0x57, 0xE9,
5040
5041 0x2A, 0x49, 0x59, 0xBF,
5042 0x1A, 0x49, 0x69, 0xBF,
5043
5044 0x30, 0x50, 0x2E, 0x9F,
5045 0x82, 0x30, 0x57, 0xE9,
5046
5047 0x38, 0x21, 0x2C, 0x9F,
5048 0x83, 0x38, 0x57, 0xE9,
5049
5050 0x31, 0x53, 0x2F, 0x9F,
5051 0x84, 0x31, 0x5E, 0xE9,
5052
5053 0x39, 0xE5, 0x2C, 0x9F,
5054 0x85, 0x39, 0x5E, 0xE9,
5055
5056 0x86, 0x76, 0x57, 0xE9,
5057 0x8A, 0x36, 0x20, 0xE9,
5058
5059 0x87, 0x77, 0x57, 0xE9,
5060 0x8B, 0x3E, 0xBF, 0xEA,
5061
5062 0x80, 0x30, 0x57, 0xE9,
5063 0x81, 0x38, 0x57, 0xE9,
5064
5065 0x82, 0x31, 0x57, 0xE9,
5066 0x86, 0x78, 0x57, 0xE9,
5067
5068 0x83, 0x39, 0x57, 0xE9,
5069 0x87, 0x79, 0x57, 0xE9,
5070
5071 0x30, 0x1F, 0x5F, 0xE9,
5072 0x8A, 0x34, 0x20, 0xE9,
5073
5074 0x8B, 0x3C, 0x20, 0xE9,
5075 0x37, 0x50, 0x60, 0xBD,
5076
5077 0x57, 0x0D, 0x20, 0xE9,
5078 0x35, 0x51, 0x61, 0xBD,
5079
5080 0x2B, 0x50, 0x20, 0xE9,
5081 0x1D, 0x37, 0xE1, 0xEA,
5082
5083 0x1E, 0x35, 0xE1, 0xEA,
5084 0x00, 0xE0,
5085 0x0E, 0x77,
5086
5087 0x24, 0x51, 0x20, 0xE9,
5088 0x9F, 0xFF, 0x20, 0xEA,
5089
5090 0x16, 0x0E, 0x20, 0xE9,
5091 0x57, 0x2E, 0xBF, 0xEA,
5092
5093 0x0B, 0x46, 0xA0, 0xE8,
5094 0x1B, 0x56, 0xA0, 0xE8,
5095
5096 0x2B, 0x66, 0xA0, 0xE8,
5097 0x0C, 0x47, 0xA0, 0xE8,
5098
5099 0x1C, 0x57, 0xA0, 0xE8,
5100 0x2C, 0x67, 0xA0, 0xE8,
5101
5102 0x0B, 0x00,
5103 0x1B, 0x00,
5104 0x2B, 0x00,
5105 0x00, 0xE0,
5106
5107 0x0C, 0x00,
5108 0x1C, 0x00,
5109 0x2C, 0x00,
5110 0x00, 0xE0,
5111
5112 0x0B, 0x65,
5113 0x1B, 0x65,
5114 0x2B, 0x65,
5115 0x00, 0xE0,
5116
5117 0x0C, 0x65,
5118 0x1C, 0x65,
5119 0x2C, 0x65,
5120 0x00, 0xE0,
5121
5122 0x0B, 0x1B, 0x60, 0xEC,
5123 0x36, 0xD7, 0x36, 0xAD,
5124
5125 0x2B, 0x80, 0x60, 0xEC,
5126 0x0C, 0x1C, 0x60, 0xEC,
5127
5128 0x3E, 0xD7, 0x3E, 0xAD,
5129 0x2C, 0x80, 0x60, 0xEC,
5130
5131 0x0B, 0x2B, 0xDE, 0xE8,
5132 0x1B, 0x80, 0xDE, 0xE8,
5133
5134 0x36, 0x80, 0x36, 0xBD,
5135 0x3E, 0x80, 0x3E, 0xBD,
5136
5137 0x33, 0xD7, 0x0B, 0xBD,
5138 0x3B, 0xD7, 0x1B, 0xBD,
5139
5140 0x46, 0x80, 0x46, 0xCF,
5141 0x57, 0x80, 0x57, 0xCF,
5142
5143 0x66, 0x33, 0x66, 0xCF,
5144 0x47, 0x3B, 0x47, 0xCF,
5145
5146 0x56, 0x33, 0x56, 0xCF,
5147 0x67, 0x3B, 0x67, 0xCF,
5148
5149 0x0B, 0x48, 0xA0, 0xE8,
5150 0x1B, 0x58, 0xA0, 0xE8,
5151
5152 0x2B, 0x68, 0xA0, 0xE8,
5153 0x0C, 0x49, 0xA0, 0xE8,
5154
5155 0x1C, 0x59, 0xA0, 0xE8,
5156 0x2C, 0x69, 0xA0, 0xE8,
5157
5158 0x0B, 0x00,
5159 0x1B, 0x00,
5160 0x2B, 0x00,
5161 0x00, 0xE0,
5162
5163 0x0C, 0x00,
5164 0x1C, 0x00,
5165 0x2C, 0x00,
5166 0x00, 0xE0,
5167
5168 0x0B, 0x65,
5169 0x1B, 0x65,
5170 0x2B, 0x65,
5171 0x00, 0xE0,
5172
5173 0x0C, 0x65,
5174 0x1C, 0x65,
5175 0x2C, 0x65,
5176 0x00, 0xE0,
5177
5178 0x0B, 0x1B, 0x60, 0xEC,
5179 0x34, 0xD7, 0x34, 0xAD,
5180
5181 0x2B, 0x80, 0x60, 0xEC,
5182 0x0C, 0x1C, 0x60, 0xEC,
5183
5184 0x3C, 0xD7, 0x3C, 0xAD,
5185 0x2C, 0x80, 0x60, 0xEC,
5186
5187 0x0B, 0x2B, 0xDE, 0xE8,
5188 0x1B, 0x80, 0xDE, 0xE8,
5189
5190 0x34, 0x80, 0x34, 0xBD,
5191 0x3C, 0x80, 0x3C, 0xBD,
5192
5193 0x33, 0xD7, 0x0B, 0xBD,
5194 0x3B, 0xD7, 0x1B, 0xBD,
5195
5196 0x48, 0x80, 0x48, 0xCF,
5197 0x59, 0x80, 0x59, 0xCF,
5198
5199 0x68, 0x33, 0x68, 0xCF,
5200 0x49, 0x3B, 0x49, 0xCF,
5201
5202 0xBE, 0xFF, 0x20, 0xEA,
5203 0x00, 0x80, 0x00, 0xE8,
5204
5205 0x58, 0x33, 0x58, 0xCF,
5206 0x69, 0x3B, 0x69, 0xCF,
5207
5208 0x7D, 0xFF, 0x20, 0xEA,
5209 0x57, 0xC0, 0xBF, 0xEA,
5210
5211 0x00, 0x80, 0xA0, 0xE9,
5212 0x00, 0x00, 0xD8, 0xEC,
5213
5214};
5215
5216static unsigned char warp_g400_t2gza[] = {
5217
5218 0x00, 0x8A, 0x98, 0xE9,
5219 0x00, 0x80, 0x00, 0xE8,
5220
5221 0x00, 0x80, 0xA0, 0xE9,
5222 0x00, 0x00, 0xD8, 0xEC,
5223
5224 0xFF, 0x80, 0xC0, 0xE9,
5225 0x00, 0x80, 0x00, 0xE8,
5226
5227 0x0A, 0x40, 0x50, 0xBF,
5228 0x2A, 0x40, 0x60, 0xBF,
5229
5230 0x32, 0x41, 0x51, 0xBF,
5231 0x3A, 0x41, 0x61, 0xBF,
5232
5233 0xC3, 0x6B,
5234 0xD3, 0x6B,
5235 0x00, 0x8A, 0x98, 0xE9,
5236
5237 0x73, 0x7B, 0xC8, 0xEC,
5238 0x96, 0xE2,
5239 0x41, 0x04,
5240
5241 0x7B, 0x43, 0xA0, 0xE8,
5242 0x73, 0x53, 0xA0, 0xE8,
5243
5244 0xAD, 0xEE, 0x23, 0x9F,
5245 0x00, 0xE0,
5246 0x51, 0x04,
5247
5248 0x90, 0xE2,
5249 0x61, 0x04,
5250 0x31, 0x46, 0xB1, 0xE8,
5251
5252 0x51, 0x41, 0xE0, 0xEC,
5253 0x39, 0x67, 0xB1, 0xE8,
5254
5255 0x00, 0x04,
5256 0x46, 0xE2,
5257 0x73, 0x63, 0xA0, 0xE8,
5258
5259 0x61, 0x41, 0xE0, 0xEC,
5260 0x31, 0x00,
5261 0x39, 0x00,
5262
5263 0x7C, 0x80, 0x15, 0xEA,
5264 0x10, 0x04,
5265 0x20, 0x04,
5266
5267 0x61, 0x51, 0xE0, 0xEC,
5268 0x2F, 0x41, 0x60, 0xEA,
5269
5270 0x31, 0x20,
5271 0x39, 0x20,
5272 0x1F, 0x42, 0xA0, 0xE8,
5273
5274 0x2A, 0x42, 0x52, 0xBF,
5275 0x0F, 0x52, 0xA0, 0xE8,
5276
5277 0x1A, 0x42, 0x62, 0xBF,
5278 0x1E, 0x51, 0x60, 0xEA,
5279
5280 0x73, 0x7B, 0xC8, 0xEC,
5281 0x0E, 0x61, 0x60, 0xEA,
5282
5283 0x32, 0x40, 0x50, 0xBD,
5284 0x22, 0x40, 0x60, 0xBD,
5285
5286 0x12, 0x41, 0x51, 0xBD,
5287 0x3A, 0x41, 0x61, 0xBD,
5288
5289 0xBF, 0x2F, 0x0E, 0xBD,
5290 0x97, 0xE2,
5291 0x7B, 0x72,
5292
5293 0x32, 0x20,
5294 0x22, 0x20,
5295 0x12, 0x20,
5296 0x3A, 0x20,
5297
5298 0x35, 0x48, 0xB1, 0xE8,
5299 0x3D, 0x59, 0xB1, 0xE8,
5300
5301 0x46, 0x31, 0x46, 0xBF,
5302 0x56, 0x31, 0x56, 0xBF,
5303
5304 0xB3, 0xE2, 0x2D, 0x9F,
5305 0x00, 0x80, 0x00, 0xE8,
5306
5307 0x66, 0x31, 0x66, 0xBF,
5308 0x47, 0x39, 0x47, 0xBF,
5309
5310 0x57, 0x39, 0x57, 0xBF,
5311 0x67, 0x39, 0x67, 0xBF,
5312
5313 0x6D, 0x80, 0x07, 0xEA,
5314 0x24, 0x41, 0x20, 0xE9,
5315
5316 0x35, 0x00,
5317 0x3D, 0x00,
5318 0x00, 0xE0,
5319 0x2D, 0x73,
5320
5321 0x33, 0x72,
5322 0x0C, 0xE3,
5323 0x8D, 0x2F, 0x1E, 0xBD,
5324
5325 0x43, 0x75, 0xF8, 0xEC,
5326 0x35, 0x20,
5327 0x3D, 0x20,
5328
5329 0x43, 0x43, 0x2D, 0xDF,
5330 0x53, 0x53, 0x2D, 0xDF,
5331
5332 0xAE, 0x1E, 0x0E, 0xBD,
5333 0x58, 0xE3,
5334 0x33, 0x66,
5335
5336 0x48, 0x35, 0x48, 0xBF,
5337 0x58, 0x35, 0x58, 0xBF,
5338
5339 0x68, 0x35, 0x68, 0xBF,
5340 0x49, 0x3D, 0x49, 0xBF,
5341
5342 0x59, 0x3D, 0x59, 0xBF,
5343 0x69, 0x3D, 0x69, 0xBF,
5344
5345 0x63, 0x63, 0x2D, 0xDF,
5346 0x4D, 0x7D, 0xF8, 0xEC,
5347
5348 0x59, 0xE3,
5349 0x00, 0xE0,
5350 0xB8, 0x38, 0x33, 0xBF,
5351
5352 0x2D, 0x73,
5353 0x30, 0x76,
5354 0x18, 0x3A, 0x41, 0xE9,
5355
5356 0x3F, 0x53, 0xA0, 0xE8,
5357 0x05, 0x80, 0x3D, 0xEA,
5358
5359 0x37, 0x43, 0xA0, 0xE8,
5360 0x3D, 0x63, 0xA0, 0xE8,
5361
5362 0x50, 0x70, 0xF8, 0xEC,
5363 0x2B, 0x50, 0x3C, 0xE9,
5364
5365 0x1F, 0x0F, 0xBC, 0xE8,
5366 0x00, 0x80, 0x00, 0xE8,
5367
5368 0x59, 0x78, 0xF8, 0xEC,
5369 0x00, 0x80, 0x00, 0xE8,
5370
5371 0x15, 0xC0, 0x20, 0xE9,
5372 0x15, 0xC0, 0x20, 0xE9,
5373
5374 0x15, 0xC0, 0x20, 0xE9,
5375 0x15, 0xC0, 0x20, 0xE9,
5376
5377 0x1E, 0x12, 0x41, 0xE9,
5378 0x1A, 0x22, 0x41, 0xE9,
5379
5380 0x46, 0x37, 0x46, 0xDF,
5381 0x56, 0x3F, 0x56, 0xDF,
5382
5383 0x2B, 0x40, 0x3D, 0xE9,
5384 0x66, 0x3D, 0x66, 0xDF,
5385
5386 0x1D, 0x32, 0x41, 0xE9,
5387 0x67, 0x3D, 0x67, 0xDF,
5388
5389 0x47, 0x37, 0x47, 0xDF,
5390 0x57, 0x3F, 0x57, 0xDF,
5391
5392 0x2A, 0x40, 0x20, 0xE9,
5393 0x59, 0x3F, 0x59, 0xDF,
5394
5395 0x16, 0x30, 0x20, 0xE9,
5396 0x69, 0x3D, 0x69, 0xDF,
5397
5398 0x48, 0x37, 0x48, 0xDF,
5399 0x58, 0x3F, 0x58, 0xDF,
5400
5401 0x12, 0x12, 0x2D, 0xDF,
5402 0x22, 0x22, 0x2D, 0xDF,
5403
5404 0x32, 0x32, 0x2D, 0xDF,
5405 0x3A, 0x3A, 0x2D, 0xDF,
5406
5407 0x68, 0x3D, 0x68, 0xDF,
5408 0x49, 0x37, 0x49, 0xDF,
5409
5410 0x3D, 0xCF, 0x74, 0xC0,
5411 0x37, 0xCF, 0x74, 0xC4,
5412
5413 0x31, 0x53, 0x2F, 0x9F,
5414 0x34, 0x80, 0x20, 0xE9,
5415
5416 0x39, 0xE5, 0x2C, 0x9F,
5417 0x3C, 0x3D, 0x20, 0xE9,
5418
5419 0x0A, 0x44, 0x54, 0xB0,
5420 0x02, 0x44, 0x64, 0xB0,
5421
5422 0x2A, 0x44, 0x54, 0xB2,
5423 0x1A, 0x44, 0x64, 0xB2,
5424
5425 0x29, 0x80, 0x3A, 0xEA,
5426 0x0A, 0x20,
5427 0x02, 0x20,
5428
5429 0x0F, 0xCF, 0x74, 0xC6,
5430 0x3D, 0xCF, 0x74, 0xC2,
5431
5432 0x88, 0x73, 0x5E, 0xE9,
5433 0x2A, 0x20,
5434 0x1A, 0x20,
5435
5436 0x30, 0x50, 0x2E, 0x9F,
5437 0x32, 0x31, 0x5F, 0xE9,
5438
5439 0x38, 0x21, 0x2C, 0x9F,
5440 0x33, 0x39, 0x5F, 0xE9,
5441
5442 0x31, 0x53, 0x2F, 0x9F,
5443 0x9C, 0x0F, 0x20, 0xE9,
5444
5445 0x0A, 0x44, 0x54, 0xB4,
5446 0x02, 0x44, 0x64, 0xB4,
5447
5448 0x2A, 0x44, 0x54, 0xB6,
5449 0x1A, 0x44, 0x64, 0xB6,
5450
5451 0x39, 0xE5, 0x2C, 0x9F,
5452 0x38, 0x3D, 0x20, 0xE9,
5453
5454 0x0A, 0x20,
5455 0x02, 0x20,
5456 0x2A, 0x20,
5457 0x1A, 0x20,
5458
5459 0x0A, 0x47, 0x57, 0xBF,
5460 0x02, 0x47, 0x67, 0xBF,
5461
5462 0x30, 0x50, 0x2E, 0x9F,
5463 0x3E, 0x30, 0x4F, 0xE9,
5464
5465 0x38, 0x21, 0x2C, 0x9F,
5466 0x3F, 0x38, 0x4F, 0xE9,
5467
5468 0x2A, 0x46, 0x56, 0xBF,
5469 0x1A, 0x46, 0x66, 0xBF,
5470
5471 0x31, 0x53, 0x2F, 0x9F,
5472 0x3A, 0x31, 0x4F, 0xE9,
5473
5474 0x39, 0xE5, 0x2C, 0x9F,
5475 0x3B, 0x39, 0x4F, 0xE9,
5476
5477 0x31, 0x53, 0x2F, 0x9F,
5478 0x36, 0x30, 0x4F, 0xE9,
5479
5480 0x39, 0xE5, 0x2C, 0x9F,
5481 0x37, 0x38, 0x4F, 0xE9,
5482
5483 0x2A, 0x43, 0x53, 0xBF,
5484 0x1A, 0x43, 0x63, 0xBF,
5485
5486 0x30, 0x50, 0x2E, 0x9F,
5487 0x9D, 0x31, 0x4F, 0xE9,
5488
5489 0x38, 0x21, 0x2C, 0x9F,
5490 0x9E, 0x39, 0x4F, 0xE9,
5491
5492 0x0A, 0x48, 0x58, 0xBF,
5493 0x02, 0x48, 0x68, 0xBF,
5494
5495 0x31, 0x53, 0x2F, 0x9F,
5496 0x80, 0x31, 0x57, 0xE9,
5497
5498 0x39, 0xE5, 0x2C, 0x9F,
5499 0x81, 0x39, 0x57, 0xE9,
5500
5501 0x2A, 0x49, 0x59, 0xBF,
5502 0x1A, 0x49, 0x69, 0xBF,
5503
5504 0x30, 0x50, 0x2E, 0x9F,
5505 0x82, 0x30, 0x57, 0xE9,
5506
5507 0x38, 0x21, 0x2C, 0x9F,
5508 0x83, 0x38, 0x57, 0xE9,
5509
5510 0x31, 0x53, 0x2F, 0x9F,
5511 0x84, 0x31, 0x5E, 0xE9,
5512
5513 0x39, 0xE5, 0x2C, 0x9F,
5514 0x85, 0x39, 0x5E, 0xE9,
5515
5516 0x86, 0x76, 0x57, 0xE9,
5517 0x8A, 0x36, 0x20, 0xE9,
5518
5519 0x87, 0x77, 0x57, 0xE9,
5520 0x8B, 0x3E, 0xBF, 0xEA,
5521
5522 0x80, 0x30, 0x57, 0xE9,
5523 0x81, 0x38, 0x57, 0xE9,
5524
5525 0x82, 0x31, 0x57, 0xE9,
5526 0x86, 0x78, 0x57, 0xE9,
5527
5528 0x83, 0x39, 0x57, 0xE9,
5529 0x87, 0x79, 0x57, 0xE9,
5530
5531 0x30, 0x1F, 0x5F, 0xE9,
5532 0x8A, 0x34, 0x20, 0xE9,
5533
5534 0x8B, 0x3C, 0x20, 0xE9,
5535 0x37, 0x50, 0x60, 0xBD,
5536
5537 0x57, 0x0D, 0x20, 0xE9,
5538 0x35, 0x51, 0x61, 0xBD,
5539
5540 0x2B, 0x50, 0x20, 0xE9,
5541 0x1D, 0x37, 0xE1, 0xEA,
5542
5543 0x1E, 0x35, 0xE1, 0xEA,
5544 0x00, 0xE0,
5545 0x0E, 0x77,
5546
5547 0x24, 0x51, 0x20, 0xE9,
5548 0x9B, 0xFF, 0x20, 0xEA,
5549
5550 0x16, 0x0E, 0x20, 0xE9,
5551 0x57, 0x2E, 0xBF, 0xEA,
5552
5553 0x0B, 0x46, 0xA0, 0xE8,
5554 0x1B, 0x56, 0xA0, 0xE8,
5555
5556 0x2B, 0x66, 0xA0, 0xE8,
5557 0x0C, 0x47, 0xA0, 0xE8,
5558
5559 0x1C, 0x57, 0xA0, 0xE8,
5560 0x2C, 0x67, 0xA0, 0xE8,
5561
5562 0x0B, 0x00,
5563 0x1B, 0x00,
5564 0x2B, 0x00,
5565 0x00, 0xE0,
5566
5567 0x0C, 0x00,
5568 0x1C, 0x00,
5569 0x2C, 0x00,
5570 0x00, 0xE0,
5571
5572 0x0B, 0x65,
5573 0x1B, 0x65,
5574 0x2B, 0x65,
5575 0x00, 0xE0,
5576
5577 0x0C, 0x65,
5578 0x1C, 0x65,
5579 0x2C, 0x65,
5580 0x00, 0xE0,
5581
5582 0x0B, 0x1B, 0x60, 0xEC,
5583 0x36, 0xD7, 0x36, 0xAD,
5584
5585 0x2B, 0x80, 0x60, 0xEC,
5586 0x0C, 0x1C, 0x60, 0xEC,
5587
5588 0x3E, 0xD7, 0x3E, 0xAD,
5589 0x2C, 0x80, 0x60, 0xEC,
5590
5591 0x0B, 0x2B, 0xDE, 0xE8,
5592 0x1B, 0x80, 0xDE, 0xE8,
5593
5594 0x36, 0x80, 0x36, 0xBD,
5595 0x3E, 0x80, 0x3E, 0xBD,
5596
5597 0x33, 0xD7, 0x0B, 0xBD,
5598 0x3B, 0xD7, 0x1B, 0xBD,
5599
5600 0x46, 0x80, 0x46, 0xCF,
5601 0x57, 0x80, 0x57, 0xCF,
5602
5603 0x66, 0x33, 0x66, 0xCF,
5604 0x47, 0x3B, 0x47, 0xCF,
5605
5606 0x56, 0x33, 0x56, 0xCF,
5607 0x67, 0x3B, 0x67, 0xCF,
5608
5609 0x0B, 0x48, 0xA0, 0xE8,
5610 0x1B, 0x58, 0xA0, 0xE8,
5611
5612 0x2B, 0x68, 0xA0, 0xE8,
5613 0x0C, 0x49, 0xA0, 0xE8,
5614
5615 0x1C, 0x59, 0xA0, 0xE8,
5616 0x2C, 0x69, 0xA0, 0xE8,
5617
5618 0x0B, 0x00,
5619 0x1B, 0x00,
5620 0x2B, 0x00,
5621 0x00, 0xE0,
5622
5623 0x0C, 0x00,
5624 0x1C, 0x00,
5625 0x2C, 0x00,
5626 0x00, 0xE0,
5627
5628 0x0B, 0x65,
5629 0x1B, 0x65,
5630 0x2B, 0x65,
5631 0x00, 0xE0,
5632
5633 0x0C, 0x65,
5634 0x1C, 0x65,
5635 0x2C, 0x65,
5636 0x00, 0xE0,
5637
5638 0x0B, 0x1B, 0x60, 0xEC,
5639 0x34, 0xD7, 0x34, 0xAD,
5640
5641 0x2B, 0x80, 0x60, 0xEC,
5642 0x0C, 0x1C, 0x60, 0xEC,
5643
5644 0x3C, 0xD7, 0x3C, 0xAD,
5645 0x2C, 0x80, 0x60, 0xEC,
5646
5647 0x0B, 0x2B, 0xDE, 0xE8,
5648 0x1B, 0x80, 0xDE, 0xE8,
5649
5650 0x34, 0x80, 0x34, 0xBD,
5651 0x3C, 0x80, 0x3C, 0xBD,
5652
5653 0x33, 0xD7, 0x0B, 0xBD,
5654 0x3B, 0xD7, 0x1B, 0xBD,
5655
5656 0x48, 0x80, 0x48, 0xCF,
5657 0x59, 0x80, 0x59, 0xCF,
5658
5659 0x68, 0x33, 0x68, 0xCF,
5660 0x49, 0x3B, 0x49, 0xCF,
5661
5662 0xBA, 0xFF, 0x20, 0xEA,
5663 0x00, 0x80, 0x00, 0xE8,
5664
5665 0x58, 0x33, 0x58, 0xCF,
5666 0x69, 0x3B, 0x69, 0xCF,
5667
5668 0x79, 0xFF, 0x20, 0xEA,
5669 0x57, 0xC0, 0xBF, 0xEA,
5670
5671 0x00, 0x80, 0xA0, 0xE9,
5672 0x00, 0x00, 0xD8, 0xEC,
5673
5674};
5675
5676static unsigned char warp_g400_t2gzaf[] = {
5677
5678 0x00, 0x8A, 0x98, 0xE9,
5679 0x00, 0x80, 0x00, 0xE8,
5680
5681 0x00, 0x80, 0xA0, 0xE9,
5682 0x00, 0x00, 0xD8, 0xEC,
5683
5684 0xFF, 0x80, 0xC0, 0xE9,
5685 0x00, 0x80, 0x00, 0xE8,
5686
5687 0x0A, 0x40, 0x50, 0xBF,
5688 0x2A, 0x40, 0x60, 0xBF,
5689
5690 0x32, 0x41, 0x51, 0xBF,
5691 0x3A, 0x41, 0x61, 0xBF,
5692
5693 0xC3, 0x6B,
5694 0xD3, 0x6B,
5695 0x00, 0x8A, 0x98, 0xE9,
5696
5697 0x73, 0x7B, 0xC8, 0xEC,
5698 0x96, 0xE2,
5699 0x41, 0x04,
5700
5701 0x7B, 0x43, 0xA0, 0xE8,
5702 0x73, 0x53, 0xA0, 0xE8,
5703
5704 0xAD, 0xEE, 0x23, 0x9F,
5705 0x00, 0xE0,
5706 0x51, 0x04,
5707
5708 0x90, 0xE2,
5709 0x61, 0x04,
5710 0x31, 0x46, 0xB1, 0xE8,
5711
5712 0x51, 0x41, 0xE0, 0xEC,
5713 0x39, 0x67, 0xB1, 0xE8,
5714
5715 0x00, 0x04,
5716 0x46, 0xE2,
5717 0x73, 0x63, 0xA0, 0xE8,
5718
5719 0x61, 0x41, 0xE0, 0xEC,
5720 0x31, 0x00,
5721 0x39, 0x00,
5722
5723 0x81, 0x80, 0x15, 0xEA,
5724 0x10, 0x04,
5725 0x20, 0x04,
5726
5727 0x61, 0x51, 0xE0, 0xEC,
5728 0x2F, 0x41, 0x60, 0xEA,
5729
5730 0x31, 0x20,
5731 0x39, 0x20,
5732 0x1F, 0x42, 0xA0, 0xE8,
5733
5734 0x2A, 0x42, 0x52, 0xBF,
5735 0x0F, 0x52, 0xA0, 0xE8,
5736
5737 0x1A, 0x42, 0x62, 0xBF,
5738 0x1E, 0x51, 0x60, 0xEA,
5739
5740 0x73, 0x7B, 0xC8, 0xEC,
5741 0x0E, 0x61, 0x60, 0xEA,
5742
5743 0x32, 0x40, 0x50, 0xBD,
5744 0x22, 0x40, 0x60, 0xBD,
5745
5746 0x12, 0x41, 0x51, 0xBD,
5747 0x3A, 0x41, 0x61, 0xBD,
5748
5749 0xBF, 0x2F, 0x0E, 0xBD,
5750 0x97, 0xE2,
5751 0x7B, 0x72,
5752
5753 0x32, 0x20,
5754 0x22, 0x20,
5755 0x12, 0x20,
5756 0x3A, 0x20,
5757
5758 0x35, 0x48, 0xB1, 0xE8,
5759 0x3D, 0x59, 0xB1, 0xE8,
5760
5761 0x46, 0x31, 0x46, 0xBF,
5762 0x56, 0x31, 0x56, 0xBF,
5763
5764 0xB3, 0xE2, 0x2D, 0x9F,
5765 0x00, 0x80, 0x00, 0xE8,
5766
5767 0x66, 0x31, 0x66, 0xBF,
5768 0x47, 0x39, 0x47, 0xBF,
5769
5770 0x57, 0x39, 0x57, 0xBF,
5771 0x67, 0x39, 0x67, 0xBF,
5772
5773 0x72, 0x80, 0x07, 0xEA,
5774 0x24, 0x41, 0x20, 0xE9,
5775
5776 0x35, 0x00,
5777 0x3D, 0x00,
5778 0x00, 0xE0,
5779 0x2D, 0x73,
5780
5781 0x33, 0x72,
5782 0x0C, 0xE3,
5783 0x8D, 0x2F, 0x1E, 0xBD,
5784
5785 0x43, 0x75, 0xF8, 0xEC,
5786 0x35, 0x20,
5787 0x3D, 0x20,
5788
5789 0x43, 0x43, 0x2D, 0xDF,
5790 0x53, 0x53, 0x2D, 0xDF,
5791
5792 0xAE, 0x1E, 0x0E, 0xBD,
5793 0x58, 0xE3,
5794 0x33, 0x66,
5795
5796 0x48, 0x35, 0x48, 0xBF,
5797 0x58, 0x35, 0x58, 0xBF,
5798
5799 0x68, 0x35, 0x68, 0xBF,
5800 0x49, 0x3D, 0x49, 0xBF,
5801
5802 0x59, 0x3D, 0x59, 0xBF,
5803 0x69, 0x3D, 0x69, 0xBF,
5804
5805 0x63, 0x63, 0x2D, 0xDF,
5806 0x4D, 0x7D, 0xF8, 0xEC,
5807
5808 0x59, 0xE3,
5809 0x00, 0xE0,
5810 0xB8, 0x38, 0x33, 0xBF,
5811
5812 0x2D, 0x73,
5813 0x30, 0x76,
5814 0x18, 0x3A, 0x41, 0xE9,
5815
5816 0x3F, 0x53, 0xA0, 0xE8,
5817 0x05, 0x80, 0x3D, 0xEA,
5818
5819 0x37, 0x43, 0xA0, 0xE8,
5820 0x3D, 0x63, 0xA0, 0xE8,
5821
5822 0x50, 0x70, 0xF8, 0xEC,
5823 0x2B, 0x50, 0x3C, 0xE9,
5824
5825 0x1F, 0x0F, 0xBC, 0xE8,
5826 0x00, 0x80, 0x00, 0xE8,
5827
5828 0x59, 0x78, 0xF8, 0xEC,
5829 0x00, 0x80, 0x00, 0xE8,
5830
5831 0x15, 0xC0, 0x20, 0xE9,
5832 0x15, 0xC0, 0x20, 0xE9,
5833
5834 0x15, 0xC0, 0x20, 0xE9,
5835 0x15, 0xC0, 0x20, 0xE9,
5836
5837 0x1E, 0x12, 0x41, 0xE9,
5838 0x1A, 0x22, 0x41, 0xE9,
5839
5840 0x46, 0x37, 0x46, 0xDF,
5841 0x56, 0x3F, 0x56, 0xDF,
5842
5843 0x2B, 0x40, 0x3D, 0xE9,
5844 0x66, 0x3D, 0x66, 0xDF,
5845
5846 0x1D, 0x32, 0x41, 0xE9,
5847 0x67, 0x3D, 0x67, 0xDF,
5848
5849 0x47, 0x37, 0x47, 0xDF,
5850 0x57, 0x3F, 0x57, 0xDF,
5851
5852 0x2A, 0x40, 0x20, 0xE9,
5853 0x59, 0x3F, 0x59, 0xDF,
5854
5855 0x16, 0x30, 0x20, 0xE9,
5856 0x69, 0x3D, 0x69, 0xDF,
5857
5858 0x48, 0x37, 0x48, 0xDF,
5859 0x58, 0x3F, 0x58, 0xDF,
5860
5861 0x12, 0x12, 0x2D, 0xDF,
5862 0x22, 0x22, 0x2D, 0xDF,
5863
5864 0x32, 0x32, 0x2D, 0xDF,
5865 0x3A, 0x3A, 0x2D, 0xDF,
5866
5867 0x68, 0x3D, 0x68, 0xDF,
5868 0x49, 0x37, 0x49, 0xDF,
5869
5870 0x3D, 0xCF, 0x74, 0xC0,
5871 0x37, 0xCF, 0x74, 0xC4,
5872
5873 0x0A, 0x44, 0x54, 0xB0,
5874 0x02, 0x44, 0x64, 0xB0,
5875
5876 0x31, 0x53, 0x2F, 0x9F,
5877 0x34, 0x37, 0x20, 0xE9,
5878
5879 0x39, 0xE5, 0x2C, 0x9F,
5880 0x3C, 0x3D, 0x20, 0xE9,
5881
5882 0x2A, 0x44, 0x54, 0xB2,
5883 0x1A, 0x44, 0x64, 0xB2,
5884
5885 0x2E, 0x80, 0x3A, 0xEA,
5886 0x0A, 0x20,
5887 0x02, 0x20,
5888
5889 0x88, 0x73, 0x5E, 0xE9,
5890 0x2A, 0x20,
5891 0x1A, 0x20,
5892
5893 0x3D, 0xCF, 0x74, 0xC2,
5894 0x0F, 0xCF, 0x74, 0xC6,
5895
5896 0x30, 0x50, 0x2E, 0x9F,
5897 0x32, 0x31, 0x5F, 0xE9,
5898
5899 0x38, 0x21, 0x2C, 0x9F,
5900 0x33, 0x39, 0x5F, 0xE9,
5901
5902 0x31, 0x53, 0x2F, 0x9F,
5903 0x9C, 0x0F, 0x20, 0xE9,
5904
5905 0x0A, 0x44, 0x54, 0xB4,
5906 0x02, 0x44, 0x64, 0xB4,
5907
5908 0x2A, 0x44, 0x54, 0xB6,
5909 0x1A, 0x44, 0x64, 0xB6,
5910
5911 0x39, 0xE5, 0x2C, 0x9F,
5912 0x38, 0x3D, 0x20, 0xE9,
5913
5914 0x0A, 0x20,
5915 0x02, 0x20,
5916 0x2A, 0x20,
5917 0x1A, 0x20,
5918
5919 0x3D, 0xCF, 0x75, 0xC6,
5920 0x00, 0x80, 0x00, 0xE8,
5921
5922 0x30, 0x50, 0x2E, 0x9F,
5923 0x3E, 0x30, 0x4F, 0xE9,
5924
5925 0x38, 0x21, 0x2C, 0x9F,
5926 0x3F, 0x38, 0x4F, 0xE9,
5927
5928 0x0A, 0x45, 0x55, 0xB6,
5929 0x02, 0x45, 0x65, 0xB6,
5930
5931 0x31, 0x53, 0x2F, 0x9F,
5932 0x3A, 0x31, 0x4F, 0xE9,
5933
5934 0x39, 0xE5, 0x2C, 0x9F,
5935 0x3B, 0x39, 0x4F, 0xE9,
5936
5937 0x31, 0x3D, 0x20, 0xE9,
5938 0x0A, 0x20,
5939 0x02, 0x20,
5940
5941 0x2A, 0x46, 0x56, 0xBF,
5942 0x1A, 0x46, 0x66, 0xBF,
5943
5944 0x0A, 0x47, 0x57, 0xBF,
5945 0x02, 0x47, 0x67, 0xBF,
5946
5947 0x30, 0x50, 0x2E, 0x9F,
5948 0x36, 0x30, 0x4F, 0xE9,
5949
5950 0x38, 0x21, 0x2C, 0x9F,
5951 0x37, 0x38, 0x4F, 0xE9,
5952
5953 0x31, 0x53, 0x2F, 0x9F,
5954 0x9D, 0x31, 0x4F, 0xE9,
5955
5956 0x39, 0xE5, 0x2C, 0x9F,
5957 0x9E, 0x39, 0x4F, 0xE9,
5958
5959 0x2A, 0x43, 0x53, 0xBF,
5960 0x1A, 0x43, 0x63, 0xBF,
5961
5962 0x30, 0x50, 0x2E, 0x9F,
5963 0x35, 0x30, 0x4F, 0xE9,
5964
5965 0x38, 0x21, 0x2C, 0x9F,
5966 0x39, 0x38, 0x4F, 0xE9,
5967
5968 0x0A, 0x48, 0x58, 0xBF,
5969 0x02, 0x48, 0x68, 0xBF,
5970
5971 0x31, 0x53, 0x2F, 0x9F,
5972 0x80, 0x31, 0x57, 0xE9,
5973
5974 0x39, 0xE5, 0x2C, 0x9F,
5975 0x81, 0x39, 0x57, 0xE9,
5976
5977 0x2A, 0x49, 0x59, 0xBF,
5978 0x1A, 0x49, 0x69, 0xBF,
5979
5980 0x30, 0x50, 0x2E, 0x9F,
5981 0x82, 0x30, 0x57, 0xE9,
5982
5983 0x38, 0x21, 0x2C, 0x9F,
5984 0x83, 0x38, 0x57, 0xE9,
5985
5986 0x31, 0x53, 0x2F, 0x9F,
5987 0x84, 0x31, 0x5E, 0xE9,
5988
5989 0x39, 0xE5, 0x2C, 0x9F,
5990 0x85, 0x39, 0x5E, 0xE9,
5991
5992 0x86, 0x76, 0x57, 0xE9,
5993 0x8A, 0x36, 0x20, 0xE9,
5994
5995 0x87, 0x77, 0x57, 0xE9,
5996 0x8B, 0x3E, 0xBF, 0xEA,
5997
5998 0x80, 0x30, 0x57, 0xE9,
5999 0x81, 0x38, 0x57, 0xE9,
6000
6001 0x82, 0x31, 0x57, 0xE9,
6002 0x86, 0x78, 0x57, 0xE9,
6003
6004 0x83, 0x39, 0x57, 0xE9,
6005 0x87, 0x79, 0x57, 0xE9,
6006
6007 0x30, 0x1F, 0x5F, 0xE9,
6008 0x8A, 0x34, 0x20, 0xE9,
6009
6010 0x8B, 0x3C, 0x20, 0xE9,
6011 0x37, 0x50, 0x60, 0xBD,
6012
6013 0x57, 0x0D, 0x20, 0xE9,
6014 0x35, 0x51, 0x61, 0xBD,
6015
6016 0x2B, 0x50, 0x20, 0xE9,
6017 0x1D, 0x37, 0xE1, 0xEA,
6018
6019 0x1E, 0x35, 0xE1, 0xEA,
6020 0x00, 0xE0,
6021 0x0E, 0x77,
6022
6023 0x24, 0x51, 0x20, 0xE9,
6024 0x96, 0xFF, 0x20, 0xEA,
6025
6026 0x16, 0x0E, 0x20, 0xE9,
6027 0x57, 0x2E, 0xBF, 0xEA,
6028
6029 0x0B, 0x46, 0xA0, 0xE8,
6030 0x1B, 0x56, 0xA0, 0xE8,
6031
6032 0x2B, 0x66, 0xA0, 0xE8,
6033 0x0C, 0x47, 0xA0, 0xE8,
6034
6035 0x1C, 0x57, 0xA0, 0xE8,
6036 0x2C, 0x67, 0xA0, 0xE8,
6037
6038 0x0B, 0x00,
6039 0x1B, 0x00,
6040 0x2B, 0x00,
6041 0x00, 0xE0,
6042
6043 0x0C, 0x00,
6044 0x1C, 0x00,
6045 0x2C, 0x00,
6046 0x00, 0xE0,
6047
6048 0x0B, 0x65,
6049 0x1B, 0x65,
6050 0x2B, 0x65,
6051 0x00, 0xE0,
6052
6053 0x0C, 0x65,
6054 0x1C, 0x65,
6055 0x2C, 0x65,
6056 0x00, 0xE0,
6057
6058 0x0B, 0x1B, 0x60, 0xEC,
6059 0x36, 0xD7, 0x36, 0xAD,
6060
6061 0x2B, 0x80, 0x60, 0xEC,
6062 0x0C, 0x1C, 0x60, 0xEC,
6063
6064 0x3E, 0xD7, 0x3E, 0xAD,
6065 0x2C, 0x80, 0x60, 0xEC,
6066
6067 0x0B, 0x2B, 0xDE, 0xE8,
6068 0x1B, 0x80, 0xDE, 0xE8,
6069
6070 0x36, 0x80, 0x36, 0xBD,
6071 0x3E, 0x80, 0x3E, 0xBD,
6072
6073 0x33, 0xD7, 0x0B, 0xBD,
6074 0x3B, 0xD7, 0x1B, 0xBD,
6075
6076 0x46, 0x80, 0x46, 0xCF,
6077 0x57, 0x80, 0x57, 0xCF,
6078
6079 0x66, 0x33, 0x66, 0xCF,
6080 0x47, 0x3B, 0x47, 0xCF,
6081
6082 0x56, 0x33, 0x56, 0xCF,
6083 0x67, 0x3B, 0x67, 0xCF,
6084
6085 0x0B, 0x48, 0xA0, 0xE8,
6086 0x1B, 0x58, 0xA0, 0xE8,
6087
6088 0x2B, 0x68, 0xA0, 0xE8,
6089 0x0C, 0x49, 0xA0, 0xE8,
6090
6091 0x1C, 0x59, 0xA0, 0xE8,
6092 0x2C, 0x69, 0xA0, 0xE8,
6093
6094 0x0B, 0x00,
6095 0x1B, 0x00,
6096 0x2B, 0x00,
6097 0x00, 0xE0,
6098
6099 0x0C, 0x00,
6100 0x1C, 0x00,
6101 0x2C, 0x00,
6102 0x00, 0xE0,
6103
6104 0x0B, 0x65,
6105 0x1B, 0x65,
6106 0x2B, 0x65,
6107 0x00, 0xE0,
6108
6109 0x0C, 0x65,
6110 0x1C, 0x65,
6111 0x2C, 0x65,
6112 0x00, 0xE0,
6113
6114 0x0B, 0x1B, 0x60, 0xEC,
6115 0x34, 0xD7, 0x34, 0xAD,
6116
6117 0x2B, 0x80, 0x60, 0xEC,
6118 0x0C, 0x1C, 0x60, 0xEC,
6119
6120 0x3C, 0xD7, 0x3C, 0xAD,
6121 0x2C, 0x80, 0x60, 0xEC,
6122
6123 0x0B, 0x2B, 0xDE, 0xE8,
6124 0x1B, 0x80, 0xDE, 0xE8,
6125
6126 0x34, 0x80, 0x34, 0xBD,
6127 0x3C, 0x80, 0x3C, 0xBD,
6128
6129 0x33, 0xD7, 0x0B, 0xBD,
6130 0x3B, 0xD7, 0x1B, 0xBD,
6131
6132 0x48, 0x80, 0x48, 0xCF,
6133 0x59, 0x80, 0x59, 0xCF,
6134
6135 0x68, 0x33, 0x68, 0xCF,
6136 0x49, 0x3B, 0x49, 0xCF,
6137
6138 0xB5, 0xFF, 0x20, 0xEA,
6139 0x00, 0x80, 0x00, 0xE8,
6140
6141 0x58, 0x33, 0x58, 0xCF,
6142 0x69, 0x3B, 0x69, 0xCF,
6143
6144 0x74, 0xFF, 0x20, 0xEA,
6145 0x57, 0xC0, 0xBF, 0xEA,
6146
6147 0x00, 0x80, 0xA0, 0xE9,
6148 0x00, 0x00, 0xD8, 0xEC,
6149
6150};
6151
6152static unsigned char warp_g400_t2gzf[] = {
6153
6154 0x00, 0x8A, 0x98, 0xE9,
6155 0x00, 0x80, 0x00, 0xE8,
6156
6157 0x00, 0x80, 0xA0, 0xE9,
6158 0x00, 0x00, 0xD8, 0xEC,
6159
6160 0xFF, 0x80, 0xC0, 0xE9,
6161 0x00, 0x80, 0x00, 0xE8,
6162
6163 0x0A, 0x40, 0x50, 0xBF,
6164 0x2A, 0x40, 0x60, 0xBF,
6165
6166 0x32, 0x41, 0x51, 0xBF,
6167 0x3A, 0x41, 0x61, 0xBF,
6168
6169 0xC3, 0x6B,
6170 0xD3, 0x6B,
6171 0x00, 0x8A, 0x98, 0xE9,
6172
6173 0x73, 0x7B, 0xC8, 0xEC,
6174 0x96, 0xE2,
6175 0x41, 0x04,
6176
6177 0x7B, 0x43, 0xA0, 0xE8,
6178 0x73, 0x53, 0xA0, 0xE8,
6179
6180 0xAD, 0xEE, 0x23, 0x9F,
6181 0x00, 0xE0,
6182 0x51, 0x04,
6183
6184 0x90, 0xE2,
6185 0x61, 0x04,
6186 0x31, 0x46, 0xB1, 0xE8,
6187
6188 0x51, 0x41, 0xE0, 0xEC,
6189 0x39, 0x67, 0xB1, 0xE8,
6190
6191 0x00, 0x04,
6192 0x46, 0xE2,
6193 0x73, 0x63, 0xA0, 0xE8,
6194
6195 0x61, 0x41, 0xE0, 0xEC,
6196 0x31, 0x00,
6197 0x39, 0x00,
6198
6199 0x7D, 0x80, 0x15, 0xEA,
6200 0x10, 0x04,
6201 0x20, 0x04,
6202
6203 0x61, 0x51, 0xE0, 0xEC,
6204 0x2F, 0x41, 0x60, 0xEA,
6205
6206 0x31, 0x20,
6207 0x39, 0x20,
6208 0x1F, 0x42, 0xA0, 0xE8,
6209
6210 0x2A, 0x42, 0x52, 0xBF,
6211 0x0F, 0x52, 0xA0, 0xE8,
6212
6213 0x1A, 0x42, 0x62, 0xBF,
6214 0x1E, 0x51, 0x60, 0xEA,
6215
6216 0x73, 0x7B, 0xC8, 0xEC,
6217 0x0E, 0x61, 0x60, 0xEA,
6218
6219 0x32, 0x40, 0x50, 0xBD,
6220 0x22, 0x40, 0x60, 0xBD,
6221
6222 0x12, 0x41, 0x51, 0xBD,
6223 0x3A, 0x41, 0x61, 0xBD,
6224
6225 0xBF, 0x2F, 0x0E, 0xBD,
6226 0x97, 0xE2,
6227 0x7B, 0x72,
6228
6229 0x32, 0x20,
6230 0x22, 0x20,
6231 0x12, 0x20,
6232 0x3A, 0x20,
6233
6234 0x35, 0x48, 0xB1, 0xE8,
6235 0x3D, 0x59, 0xB1, 0xE8,
6236
6237 0x46, 0x31, 0x46, 0xBF,
6238 0x56, 0x31, 0x56, 0xBF,
6239
6240 0xB3, 0xE2, 0x2D, 0x9F,
6241 0x00, 0x80, 0x00, 0xE8,
6242
6243 0x66, 0x31, 0x66, 0xBF,
6244 0x47, 0x39, 0x47, 0xBF,
6245
6246 0x57, 0x39, 0x57, 0xBF,
6247 0x67, 0x39, 0x67, 0xBF,
6248
6249 0x6E, 0x80, 0x07, 0xEA,
6250 0x24, 0x41, 0x20, 0xE9,
6251
6252 0x35, 0x00,
6253 0x3D, 0x00,
6254 0x00, 0xE0,
6255 0x2D, 0x73,
6256
6257 0x33, 0x72,
6258 0x0C, 0xE3,
6259 0x8D, 0x2F, 0x1E, 0xBD,
6260
6261 0x43, 0x75, 0xF8, 0xEC,
6262 0x35, 0x20,
6263 0x3D, 0x20,
6264
6265 0x43, 0x43, 0x2D, 0xDF,
6266 0x53, 0x53, 0x2D, 0xDF,
6267
6268 0xAE, 0x1E, 0x0E, 0xBD,
6269 0x58, 0xE3,
6270 0x33, 0x66,
6271
6272 0x48, 0x35, 0x48, 0xBF,
6273 0x58, 0x35, 0x58, 0xBF,
6274
6275 0x68, 0x35, 0x68, 0xBF,
6276 0x49, 0x3D, 0x49, 0xBF,
6277
6278 0x59, 0x3D, 0x59, 0xBF,
6279 0x69, 0x3D, 0x69, 0xBF,
6280
6281 0x63, 0x63, 0x2D, 0xDF,
6282 0x4D, 0x7D, 0xF8, 0xEC,
6283
6284 0x59, 0xE3,
6285 0x00, 0xE0,
6286 0xB8, 0x38, 0x33, 0xBF,
6287
6288 0x2D, 0x73,
6289 0x30, 0x76,
6290 0x18, 0x3A, 0x41, 0xE9,
6291
6292 0x3F, 0x53, 0xA0, 0xE8,
6293 0x05, 0x80, 0x3D, 0xEA,
6294
6295 0x37, 0x43, 0xA0, 0xE8,
6296 0x3D, 0x63, 0xA0, 0xE8,
6297
6298 0x50, 0x70, 0xF8, 0xEC,
6299 0x2B, 0x50, 0x3C, 0xE9,
6300
6301 0x1F, 0x0F, 0xBC, 0xE8,
6302 0x00, 0x80, 0x00, 0xE8,
6303
6304 0x59, 0x78, 0xF8, 0xEC,
6305 0x00, 0x80, 0x00, 0xE8,
6306
6307 0x15, 0xC0, 0x20, 0xE9,
6308 0x15, 0xC0, 0x20, 0xE9,
6309
6310 0x15, 0xC0, 0x20, 0xE9,
6311 0x15, 0xC0, 0x20, 0xE9,
6312
6313 0x1E, 0x12, 0x41, 0xE9,
6314 0x1A, 0x22, 0x41, 0xE9,
6315
6316 0x46, 0x37, 0x46, 0xDF,
6317 0x56, 0x3F, 0x56, 0xDF,
6318
6319 0x2B, 0x40, 0x3D, 0xE9,
6320 0x66, 0x3D, 0x66, 0xDF,
6321
6322 0x1D, 0x32, 0x41, 0xE9,
6323 0x67, 0x3D, 0x67, 0xDF,
6324
6325 0x47, 0x37, 0x47, 0xDF,
6326 0x57, 0x3F, 0x57, 0xDF,
6327
6328 0x2A, 0x40, 0x20, 0xE9,
6329 0x59, 0x3F, 0x59, 0xDF,
6330
6331 0x16, 0x30, 0x20, 0xE9,
6332 0x69, 0x3D, 0x69, 0xDF,
6333
6334 0x48, 0x37, 0x48, 0xDF,
6335 0x58, 0x3F, 0x58, 0xDF,
6336
6337 0x12, 0x12, 0x2D, 0xDF,
6338 0x22, 0x22, 0x2D, 0xDF,
6339
6340 0x32, 0x32, 0x2D, 0xDF,
6341 0x3A, 0x3A, 0x2D, 0xDF,
6342
6343 0x68, 0x3D, 0x68, 0xDF,
6344 0x49, 0x37, 0x49, 0xDF,
6345
6346 0x3D, 0xCF, 0x74, 0xC0,
6347 0x37, 0xCF, 0x74, 0xC4,
6348
6349 0x39, 0xE5, 0x2C, 0x9F,
6350 0x34, 0x80, 0x20, 0xE9,
6351
6352 0x31, 0x53, 0x2F, 0x9F,
6353 0x00, 0x80, 0x00, 0xE8,
6354
6355 0x88, 0x73, 0x5E, 0xE9,
6356 0x00, 0x80, 0x00, 0xE8,
6357
6358 0x0F, 0xCF, 0x75, 0xC6,
6359 0x3C, 0x3D, 0x20, 0xE9,
6360
6361 0x0A, 0x44, 0x54, 0xB0,
6362 0x02, 0x44, 0x64, 0xB0,
6363
6364 0x2A, 0x44, 0x54, 0xB2,
6365 0x1A, 0x44, 0x64, 0xB2,
6366
6367 0x28, 0x80, 0x3A, 0xEA,
6368 0x0A, 0x20,
6369 0x02, 0x20,
6370
6371 0x3D, 0xCF, 0x74, 0xC2,
6372 0x2A, 0x20,
6373 0x1A, 0x20,
6374
6375 0x30, 0x50, 0x2E, 0x9F,
6376 0x32, 0x31, 0x5F, 0xE9,
6377
6378 0x38, 0x21, 0x2C, 0x9F,
6379 0x33, 0x39, 0x5F, 0xE9,
6380
6381 0x31, 0x53, 0x2F, 0x9F,
6382 0x31, 0x0F, 0x20, 0xE9,
6383
6384 0x0A, 0x44, 0x54, 0xB4,
6385 0x02, 0x44, 0x64, 0xB4,
6386
6387 0x2A, 0x45, 0x55, 0xB6,
6388 0x1A, 0x45, 0x65, 0xB6,
6389
6390 0x39, 0xE5, 0x2C, 0x9F,
6391 0x38, 0x3D, 0x20, 0xE9,
6392
6393 0x0A, 0x20,
6394 0x02, 0x20,
6395 0x2A, 0x20,
6396 0x1A, 0x20,
6397
6398 0x0A, 0x47, 0x57, 0xBF,
6399 0x02, 0x47, 0x67, 0xBF,
6400
6401 0x30, 0x50, 0x2E, 0x9F,
6402 0x3E, 0x30, 0x4F, 0xE9,
6403
6404 0x38, 0x21, 0x2C, 0x9F,
6405 0x3F, 0x38, 0x4F, 0xE9,
6406
6407 0x2A, 0x46, 0x56, 0xBF,
6408 0x1A, 0x46, 0x66, 0xBF,
6409
6410 0x31, 0x53, 0x2F, 0x9F,
6411 0x3A, 0x31, 0x4F, 0xE9,
6412
6413 0x39, 0xE5, 0x2C, 0x9F,
6414 0x3B, 0x39, 0x4F, 0xE9,
6415
6416 0x31, 0x53, 0x2F, 0x9F,
6417 0x36, 0x30, 0x4F, 0xE9,
6418
6419 0x39, 0xE5, 0x2C, 0x9F,
6420 0x37, 0x38, 0x4F, 0xE9,
6421
6422 0x2A, 0x43, 0x53, 0xBF,
6423 0x1A, 0x43, 0x63, 0xBF,
6424
6425 0x30, 0x50, 0x2E, 0x9F,
6426 0x35, 0x31, 0x4F, 0xE9,
6427
6428 0x38, 0x21, 0x2C, 0x9F,
6429 0x39, 0x39, 0x4F, 0xE9,
6430
6431 0x0A, 0x48, 0x58, 0xBF,
6432 0x02, 0x48, 0x68, 0xBF,
6433
6434 0x31, 0x53, 0x2F, 0x9F,
6435 0x80, 0x31, 0x57, 0xE9,
6436
6437 0x39, 0xE5, 0x2C, 0x9F,
6438 0x81, 0x39, 0x57, 0xE9,
6439
6440 0x2A, 0x49, 0x59, 0xBF,
6441 0x1A, 0x49, 0x69, 0xBF,
6442
6443 0x30, 0x50, 0x2E, 0x9F,
6444 0x82, 0x30, 0x57, 0xE9,
6445
6446 0x38, 0x21, 0x2C, 0x9F,
6447 0x83, 0x38, 0x57, 0xE9,
6448
6449 0x31, 0x53, 0x2F, 0x9F,
6450 0x84, 0x31, 0x5E, 0xE9,
6451
6452 0x39, 0xE5, 0x2C, 0x9F,
6453 0x85, 0x39, 0x5E, 0xE9,
6454
6455 0x86, 0x76, 0x57, 0xE9,
6456 0x8A, 0x36, 0x20, 0xE9,
6457
6458 0x87, 0x77, 0x57, 0xE9,
6459 0x8B, 0x3E, 0xBF, 0xEA,
6460
6461 0x80, 0x30, 0x57, 0xE9,
6462 0x81, 0x38, 0x57, 0xE9,
6463
6464 0x82, 0x31, 0x57, 0xE9,
6465 0x86, 0x78, 0x57, 0xE9,
6466
6467 0x83, 0x39, 0x57, 0xE9,
6468 0x87, 0x79, 0x57, 0xE9,
6469
6470 0x30, 0x1F, 0x5F, 0xE9,
6471 0x8A, 0x34, 0x20, 0xE9,
6472
6473 0x8B, 0x3C, 0x20, 0xE9,
6474 0x37, 0x50, 0x60, 0xBD,
6475
6476 0x57, 0x0D, 0x20, 0xE9,
6477 0x35, 0x51, 0x61, 0xBD,
6478
6479 0x2B, 0x50, 0x20, 0xE9,
6480 0x1D, 0x37, 0xE1, 0xEA,
6481
6482 0x1E, 0x35, 0xE1, 0xEA,
6483 0x00, 0xE0,
6484 0x0E, 0x77,
6485
6486 0x24, 0x51, 0x20, 0xE9,
6487 0x9A, 0xFF, 0x20, 0xEA,
6488
6489 0x16, 0x0E, 0x20, 0xE9,
6490 0x57, 0x2E, 0xBF, 0xEA,
6491
6492 0x0B, 0x46, 0xA0, 0xE8,
6493 0x1B, 0x56, 0xA0, 0xE8,
6494
6495 0x2B, 0x66, 0xA0, 0xE8,
6496 0x0C, 0x47, 0xA0, 0xE8,
6497
6498 0x1C, 0x57, 0xA0, 0xE8,
6499 0x2C, 0x67, 0xA0, 0xE8,
6500
6501 0x0B, 0x00,
6502 0x1B, 0x00,
6503 0x2B, 0x00,
6504 0x00, 0xE0,
6505
6506 0x0C, 0x00,
6507 0x1C, 0x00,
6508 0x2C, 0x00,
6509 0x00, 0xE0,
6510
6511 0x0B, 0x65,
6512 0x1B, 0x65,
6513 0x2B, 0x65,
6514 0x00, 0xE0,
6515
6516 0x0C, 0x65,
6517 0x1C, 0x65,
6518 0x2C, 0x65,
6519 0x00, 0xE0,
6520
6521 0x0B, 0x1B, 0x60, 0xEC,
6522 0x36, 0xD7, 0x36, 0xAD,
6523
6524 0x2B, 0x80, 0x60, 0xEC,
6525 0x0C, 0x1C, 0x60, 0xEC,
6526
6527 0x3E, 0xD7, 0x3E, 0xAD,
6528 0x2C, 0x80, 0x60, 0xEC,
6529
6530 0x0B, 0x2B, 0xDE, 0xE8,
6531 0x1B, 0x80, 0xDE, 0xE8,
6532
6533 0x36, 0x80, 0x36, 0xBD,
6534 0x3E, 0x80, 0x3E, 0xBD,
6535
6536 0x33, 0xD7, 0x0B, 0xBD,
6537 0x3B, 0xD7, 0x1B, 0xBD,
6538
6539 0x46, 0x80, 0x46, 0xCF,
6540 0x57, 0x80, 0x57, 0xCF,
6541
6542 0x66, 0x33, 0x66, 0xCF,
6543 0x47, 0x3B, 0x47, 0xCF,
6544
6545 0x56, 0x33, 0x56, 0xCF,
6546 0x67, 0x3B, 0x67, 0xCF,
6547
6548 0x0B, 0x48, 0xA0, 0xE8,
6549 0x1B, 0x58, 0xA0, 0xE8,
6550
6551 0x2B, 0x68, 0xA0, 0xE8,
6552 0x0C, 0x49, 0xA0, 0xE8,
6553
6554 0x1C, 0x59, 0xA0, 0xE8,
6555 0x2C, 0x69, 0xA0, 0xE8,
6556
6557 0x0B, 0x00,
6558 0x1B, 0x00,
6559 0x2B, 0x00,
6560 0x00, 0xE0,
6561
6562 0x0C, 0x00,
6563 0x1C, 0x00,
6564 0x2C, 0x00,
6565 0x00, 0xE0,
6566
6567 0x0B, 0x65,
6568 0x1B, 0x65,
6569 0x2B, 0x65,
6570 0x00, 0xE0,
6571
6572 0x0C, 0x65,
6573 0x1C, 0x65,
6574 0x2C, 0x65,
6575 0x00, 0xE0,
6576
6577 0x0B, 0x1B, 0x60, 0xEC,
6578 0x34, 0xD7, 0x34, 0xAD,
6579
6580 0x2B, 0x80, 0x60, 0xEC,
6581 0x0C, 0x1C, 0x60, 0xEC,
6582
6583 0x3C, 0xD7, 0x3C, 0xAD,
6584 0x2C, 0x80, 0x60, 0xEC,
6585
6586 0x0B, 0x2B, 0xDE, 0xE8,
6587 0x1B, 0x80, 0xDE, 0xE8,
6588
6589 0x34, 0x80, 0x34, 0xBD,
6590 0x3C, 0x80, 0x3C, 0xBD,
6591
6592 0x33, 0xD7, 0x0B, 0xBD,
6593 0x3B, 0xD7, 0x1B, 0xBD,
6594
6595 0x48, 0x80, 0x48, 0xCF,
6596 0x59, 0x80, 0x59, 0xCF,
6597
6598 0x68, 0x33, 0x68, 0xCF,
6599 0x49, 0x3B, 0x49, 0xCF,
6600
6601 0xBB, 0xFF, 0x20, 0xEA,
6602 0x00, 0x80, 0x00, 0xE8,
6603
6604 0x58, 0x33, 0x58, 0xCF,
6605 0x69, 0x3B, 0x69, 0xCF,
6606
6607 0x78, 0xFF, 0x20, 0xEA,
6608 0x57, 0xC0, 0xBF, 0xEA,
6609
6610 0x00, 0x80, 0xA0, 0xE9,
6611 0x00, 0x00, 0xD8, 0xEC,
6612
6613};
6614
6615static unsigned char warp_g400_t2gzs[] = {
6616
6617 0x00, 0x8A, 0x98, 0xE9,
6618 0x00, 0x80, 0x00, 0xE8,
6619
6620 0x00, 0x80, 0xA0, 0xE9,
6621 0x00, 0x00, 0xD8, 0xEC,
6622
6623 0xFF, 0x80, 0xC0, 0xE9,
6624 0x00, 0x80, 0x00, 0xE8,
6625
6626 0x0A, 0x40, 0x50, 0xBF,
6627 0x2A, 0x40, 0x60, 0xBF,
6628
6629 0x32, 0x41, 0x51, 0xBF,
6630 0x3A, 0x41, 0x61, 0xBF,
6631
6632 0xC3, 0x6B,
6633 0xD3, 0x6B,
6634 0x00, 0x8A, 0x98, 0xE9,
6635
6636 0x73, 0x7B, 0xC8, 0xEC,
6637 0x96, 0xE2,
6638 0x41, 0x04,
6639
6640 0x7B, 0x43, 0xA0, 0xE8,
6641 0x73, 0x53, 0xA0, 0xE8,
6642
6643 0xAD, 0xEE, 0x23, 0x9F,
6644 0x00, 0xE0,
6645 0x51, 0x04,
6646
6647 0x90, 0xE2,
6648 0x61, 0x04,
6649 0x31, 0x46, 0xB1, 0xE8,
6650
6651 0x51, 0x41, 0xE0, 0xEC,
6652 0x39, 0x67, 0xB1, 0xE8,
6653
6654 0x00, 0x04,
6655 0x46, 0xE2,
6656 0x73, 0x63, 0xA0, 0xE8,
6657
6658 0x61, 0x41, 0xE0, 0xEC,
6659 0x31, 0x00,
6660 0x39, 0x00,
6661
6662 0x85, 0x80, 0x15, 0xEA,
6663 0x10, 0x04,
6664 0x20, 0x04,
6665
6666 0x61, 0x51, 0xE0, 0xEC,
6667 0x2F, 0x41, 0x60, 0xEA,
6668
6669 0x31, 0x20,
6670 0x39, 0x20,
6671 0x1F, 0x42, 0xA0, 0xE8,
6672
6673 0x2A, 0x42, 0x52, 0xBF,
6674 0x0F, 0x52, 0xA0, 0xE8,
6675
6676 0x1A, 0x42, 0x62, 0xBF,
6677 0x1E, 0x51, 0x60, 0xEA,
6678
6679 0x73, 0x7B, 0xC8, 0xEC,
6680 0x0E, 0x61, 0x60, 0xEA,
6681
6682 0x32, 0x40, 0x50, 0xBD,
6683 0x22, 0x40, 0x60, 0xBD,
6684
6685 0x12, 0x41, 0x51, 0xBD,
6686 0x3A, 0x41, 0x61, 0xBD,
6687
6688 0xBF, 0x2F, 0x0E, 0xBD,
6689 0x97, 0xE2,
6690 0x7B, 0x72,
6691
6692 0x32, 0x20,
6693 0x22, 0x20,
6694 0x12, 0x20,
6695 0x3A, 0x20,
6696
6697 0x35, 0x48, 0xB1, 0xE8,
6698 0x3D, 0x59, 0xB1, 0xE8,
6699
6700 0x46, 0x31, 0x46, 0xBF,
6701 0x56, 0x31, 0x56, 0xBF,
6702
6703 0xB3, 0xE2, 0x2D, 0x9F,
6704 0x00, 0x80, 0x00, 0xE8,
6705
6706 0x66, 0x31, 0x66, 0xBF,
6707 0x47, 0x39, 0x47, 0xBF,
6708
6709 0x57, 0x39, 0x57, 0xBF,
6710 0x67, 0x39, 0x67, 0xBF,
6711
6712 0x76, 0x80, 0x07, 0xEA,
6713 0x24, 0x41, 0x20, 0xE9,
6714
6715 0x35, 0x00,
6716 0x3D, 0x00,
6717 0x00, 0xE0,
6718 0x2D, 0x73,
6719
6720 0x33, 0x72,
6721 0x0C, 0xE3,
6722 0x8D, 0x2F, 0x1E, 0xBD,
6723
6724 0x43, 0x75, 0xF8, 0xEC,
6725 0x35, 0x20,
6726 0x3D, 0x20,
6727
6728 0x43, 0x43, 0x2D, 0xDF,
6729 0x53, 0x53, 0x2D, 0xDF,
6730
6731 0xAE, 0x1E, 0x0E, 0xBD,
6732 0x58, 0xE3,
6733 0x33, 0x66,
6734
6735 0x48, 0x35, 0x48, 0xBF,
6736 0x58, 0x35, 0x58, 0xBF,
6737
6738 0x68, 0x35, 0x68, 0xBF,
6739 0x49, 0x3D, 0x49, 0xBF,
6740
6741 0x59, 0x3D, 0x59, 0xBF,
6742 0x69, 0x3D, 0x69, 0xBF,
6743
6744 0x63, 0x63, 0x2D, 0xDF,
6745 0x4D, 0x7D, 0xF8, 0xEC,
6746
6747 0x59, 0xE3,
6748 0x00, 0xE0,
6749 0xB8, 0x38, 0x33, 0xBF,
6750
6751 0x2D, 0x73,
6752 0x30, 0x76,
6753 0x18, 0x3A, 0x41, 0xE9,
6754
6755 0x3F, 0x53, 0xA0, 0xE8,
6756 0x05, 0x80, 0x3D, 0xEA,
6757
6758 0x37, 0x43, 0xA0, 0xE8,
6759 0x3D, 0x63, 0xA0, 0xE8,
6760
6761 0x50, 0x70, 0xF8, 0xEC,
6762 0x2B, 0x50, 0x3C, 0xE9,
6763
6764 0x1F, 0x0F, 0xBC, 0xE8,
6765 0x00, 0x80, 0x00, 0xE8,
6766
6767 0x59, 0x78, 0xF8, 0xEC,
6768 0x00, 0x80, 0x00, 0xE8,
6769
6770 0x15, 0xC0, 0x20, 0xE9,
6771 0x15, 0xC0, 0x20, 0xE9,
6772
6773 0x15, 0xC0, 0x20, 0xE9,
6774 0x15, 0xC0, 0x20, 0xE9,
6775
6776 0x1E, 0x12, 0x41, 0xE9,
6777 0x1A, 0x22, 0x41, 0xE9,
6778
6779 0x46, 0x37, 0x46, 0xDF,
6780 0x56, 0x3F, 0x56, 0xDF,
6781
6782 0x2B, 0x40, 0x3D, 0xE9,
6783 0x66, 0x3D, 0x66, 0xDF,
6784
6785 0x1D, 0x32, 0x41, 0xE9,
6786 0x67, 0x3D, 0x67, 0xDF,
6787
6788 0x47, 0x37, 0x47, 0xDF,
6789 0x57, 0x3F, 0x57, 0xDF,
6790
6791 0x2A, 0x40, 0x20, 0xE9,
6792 0x59, 0x3F, 0x59, 0xDF,
6793
6794 0x16, 0x30, 0x20, 0xE9,
6795 0x69, 0x3D, 0x69, 0xDF,
6796
6797 0x48, 0x37, 0x48, 0xDF,
6798 0x58, 0x3F, 0x58, 0xDF,
6799
6800 0x68, 0x3D, 0x68, 0xDF,
6801 0x49, 0x37, 0x49, 0xDF,
6802
6803 0x32, 0x32, 0x2D, 0xDF,
6804 0x22, 0x22, 0x2D, 0xDF,
6805
6806 0x12, 0x12, 0x2D, 0xDF,
6807 0x3A, 0x3A, 0x2D, 0xDF,
6808
6809 0x0F, 0xCF, 0x74, 0xC2,
6810 0x37, 0xCF, 0x74, 0xC4,
6811
6812 0x0A, 0x44, 0x54, 0xB0,
6813 0x02, 0x44, 0x64, 0xB0,
6814
6815 0x3D, 0xCF, 0x74, 0xC0,
6816 0x34, 0x37, 0x20, 0xE9,
6817
6818 0x31, 0x53, 0x2F, 0x9F,
6819 0x38, 0x0F, 0x20, 0xE9,
6820
6821 0x39, 0xE5, 0x2C, 0x9F,
6822 0x3C, 0x3D, 0x20, 0xE9,
6823
6824 0x2A, 0x44, 0x54, 0xB2,
6825 0x1A, 0x44, 0x64, 0xB2,
6826
6827 0x31, 0x80, 0x3A, 0xEA,
6828 0x0A, 0x20,
6829 0x02, 0x20,
6830
6831 0x0F, 0xCF, 0x75, 0xC0,
6832 0x2A, 0x20,
6833 0x1A, 0x20,
6834
6835 0x30, 0x50, 0x2E, 0x9F,
6836 0x32, 0x31, 0x5F, 0xE9,
6837
6838 0x38, 0x21, 0x2C, 0x9F,
6839 0x33, 0x39, 0x5F, 0xE9,
6840
6841 0x3D, 0xCF, 0x75, 0xC2,
6842 0x37, 0xCF, 0x75, 0xC4,
6843
6844 0x31, 0x53, 0x2F, 0x9F,
6845 0xA6, 0x0F, 0x20, 0xE9,
6846
6847 0x39, 0xE5, 0x2C, 0x9F,
6848 0xA3, 0x3D, 0x20, 0xE9,
6849
6850 0x2A, 0x44, 0x54, 0xB4,
6851 0x1A, 0x44, 0x64, 0xB4,
6852
6853 0x0A, 0x45, 0x55, 0xB0,
6854 0x02, 0x45, 0x65, 0xB0,
6855
6856 0x88, 0x73, 0x5E, 0xE9,
6857 0x2A, 0x20,
6858 0x1A, 0x20,
6859
6860 0xA0, 0x37, 0x20, 0xE9,
6861 0x0A, 0x20,
6862 0x02, 0x20,
6863
6864 0x31, 0x53, 0x2F, 0x9F,
6865 0x3E, 0x30, 0x4F, 0xE9,
6866
6867 0x39, 0xE5, 0x2C, 0x9F,
6868 0x3F, 0x38, 0x4F, 0xE9,
6869
6870 0x30, 0x50, 0x2E, 0x9F,
6871 0x3A, 0x31, 0x4F, 0xE9,
6872
6873 0x2A, 0x45, 0x55, 0xB2,
6874 0x1A, 0x45, 0x65, 0xB2,
6875
6876 0x0A, 0x45, 0x55, 0xB4,
6877 0x02, 0x45, 0x65, 0xB4,
6878
6879 0x38, 0x21, 0x2C, 0x9F,
6880 0x3B, 0x39, 0x4F, 0xE9,
6881
6882 0x2A, 0x20,
6883 0x1A, 0x20,
6884 0x0A, 0x20,
6885 0x02, 0x20,
6886
6887 0x2A, 0x46, 0x56, 0xBF,
6888 0x1A, 0x46, 0x66, 0xBF,
6889
6890 0x31, 0x53, 0x2F, 0x9F,
6891 0x36, 0x31, 0x4F, 0xE9,
6892
6893 0x39, 0xE5, 0x2C, 0x9F,
6894 0x37, 0x39, 0x4F, 0xE9,
6895
6896 0x30, 0x50, 0x2E, 0x9F,
6897 0xA7, 0x30, 0x4F, 0xE9,
6898
6899 0x38, 0x21, 0x2C, 0x9F,
6900 0xA8, 0x38, 0x4F, 0xE9,
6901
6902 0x0A, 0x47, 0x57, 0xBF,
6903 0x02, 0x47, 0x67, 0xBF,
6904
6905 0x31, 0x53, 0x2F, 0x9F,
6906 0xA4, 0x31, 0x4F, 0xE9,
6907
6908 0x39, 0xE5, 0x2C, 0x9F,
6909 0xA5, 0x39, 0x4F, 0xE9,
6910
6911 0x2A, 0x43, 0x53, 0xBF,
6912 0x1A, 0x43, 0x63, 0xBF,
6913
6914 0x30, 0x50, 0x2E, 0x9F,
6915 0xA1, 0x30, 0x4F, 0xE9,
6916
6917 0x38, 0x21, 0x2C, 0x9F,
6918 0xA2, 0x38, 0x4F, 0xE9,
6919
6920 0x0A, 0x48, 0x58, 0xBF,
6921 0x02, 0x48, 0x68, 0xBF,
6922
6923 0x31, 0x53, 0x2F, 0x9F,
6924 0x80, 0x31, 0x57, 0xE9,
6925
6926 0x39, 0xE5, 0x2C, 0x9F,
6927 0x81, 0x39, 0x57, 0xE9,
6928
6929 0x2A, 0x49, 0x59, 0xBF,
6930 0x1A, 0x49, 0x69, 0xBF,
6931
6932 0x30, 0x50, 0x2E, 0x9F,
6933 0x82, 0x30, 0x57, 0xE9,
6934
6935 0x38, 0x21, 0x2C, 0x9F,
6936 0x83, 0x38, 0x57, 0xE9,
6937
6938 0x31, 0x53, 0x2F, 0x9F,
6939 0x84, 0x31, 0x5E, 0xE9,
6940
6941 0x39, 0xE5, 0x2C, 0x9F,
6942 0x85, 0x39, 0x5E, 0xE9,
6943
6944 0x86, 0x76, 0x57, 0xE9,
6945 0x8A, 0x36, 0x20, 0xE9,
6946
6947 0x87, 0x77, 0x57, 0xE9,
6948 0x8B, 0x3E, 0xBF, 0xEA,
6949
6950 0x80, 0x30, 0x57, 0xE9,
6951 0x81, 0x38, 0x57, 0xE9,
6952
6953 0x82, 0x31, 0x57, 0xE9,
6954 0x86, 0x78, 0x57, 0xE9,
6955
6956 0x83, 0x39, 0x57, 0xE9,
6957 0x87, 0x79, 0x57, 0xE9,
6958
6959 0x30, 0x1F, 0x5F, 0xE9,
6960 0x8A, 0x34, 0x20, 0xE9,
6961
6962 0x8B, 0x3C, 0x20, 0xE9,
6963 0x37, 0x50, 0x60, 0xBD,
6964
6965 0x57, 0x0D, 0x20, 0xE9,
6966 0x35, 0x51, 0x61, 0xBD,
6967
6968 0x2B, 0x50, 0x20, 0xE9,
6969 0x1D, 0x37, 0xE1, 0xEA,
6970
6971 0x1E, 0x35, 0xE1, 0xEA,
6972 0x00, 0xE0,
6973 0x0E, 0x77,
6974
6975 0x24, 0x51, 0x20, 0xE9,
6976 0x92, 0xFF, 0x20, 0xEA,
6977
6978 0x16, 0x0E, 0x20, 0xE9,
6979 0x57, 0x2E, 0xBF, 0xEA,
6980
6981 0x0B, 0x46, 0xA0, 0xE8,
6982 0x1B, 0x56, 0xA0, 0xE8,
6983
6984 0x2B, 0x66, 0xA0, 0xE8,
6985 0x0C, 0x47, 0xA0, 0xE8,
6986
6987 0x1C, 0x57, 0xA0, 0xE8,
6988 0x2C, 0x67, 0xA0, 0xE8,
6989
6990 0x0B, 0x00,
6991 0x1B, 0x00,
6992 0x2B, 0x00,
6993 0x00, 0xE0,
6994
6995 0x0C, 0x00,
6996 0x1C, 0x00,
6997 0x2C, 0x00,
6998 0x00, 0xE0,
6999
7000 0x0B, 0x65,
7001 0x1B, 0x65,
7002 0x2B, 0x65,
7003 0x00, 0xE0,
7004
7005 0x0C, 0x65,
7006 0x1C, 0x65,
7007 0x2C, 0x65,
7008 0x00, 0xE0,
7009
7010 0x0B, 0x1B, 0x60, 0xEC,
7011 0x36, 0xD7, 0x36, 0xAD,
7012
7013 0x2B, 0x80, 0x60, 0xEC,
7014 0x0C, 0x1C, 0x60, 0xEC,
7015
7016 0x3E, 0xD7, 0x3E, 0xAD,
7017 0x2C, 0x80, 0x60, 0xEC,
7018
7019 0x0B, 0x2B, 0xDE, 0xE8,
7020 0x1B, 0x80, 0xDE, 0xE8,
7021
7022 0x36, 0x80, 0x36, 0xBD,
7023 0x3E, 0x80, 0x3E, 0xBD,
7024
7025 0x33, 0xD7, 0x0B, 0xBD,
7026 0x3B, 0xD7, 0x1B, 0xBD,
7027
7028 0x46, 0x80, 0x46, 0xCF,
7029 0x57, 0x80, 0x57, 0xCF,
7030
7031 0x66, 0x33, 0x66, 0xCF,
7032 0x47, 0x3B, 0x47, 0xCF,
7033
7034 0x56, 0x33, 0x56, 0xCF,
7035 0x67, 0x3B, 0x67, 0xCF,
7036
7037 0x0B, 0x48, 0xA0, 0xE8,
7038 0x1B, 0x58, 0xA0, 0xE8,
7039
7040 0x2B, 0x68, 0xA0, 0xE8,
7041 0x0C, 0x49, 0xA0, 0xE8,
7042
7043 0x1C, 0x59, 0xA0, 0xE8,
7044 0x2C, 0x69, 0xA0, 0xE8,
7045
7046 0x0B, 0x00,
7047 0x1B, 0x00,
7048 0x2B, 0x00,
7049 0x00, 0xE0,
7050
7051 0x0C, 0x00,
7052 0x1C, 0x00,
7053 0x2C, 0x00,
7054 0x00, 0xE0,
7055
7056 0x0B, 0x65,
7057 0x1B, 0x65,
7058 0x2B, 0x65,
7059 0x00, 0xE0,
7060
7061 0x0C, 0x65,
7062 0x1C, 0x65,
7063 0x2C, 0x65,
7064 0x00, 0xE0,
7065
7066 0x0B, 0x1B, 0x60, 0xEC,
7067 0x34, 0xD7, 0x34, 0xAD,
7068
7069 0x2B, 0x80, 0x60, 0xEC,
7070 0x0C, 0x1C, 0x60, 0xEC,
7071
7072 0x3C, 0xD7, 0x3C, 0xAD,
7073 0x2C, 0x80, 0x60, 0xEC,
7074
7075 0x0B, 0x2B, 0xDE, 0xE8,
7076 0x1B, 0x80, 0xDE, 0xE8,
7077
7078 0x34, 0x80, 0x34, 0xBD,
7079 0x3C, 0x80, 0x3C, 0xBD,
7080
7081 0x33, 0xD7, 0x0B, 0xBD,
7082 0x3B, 0xD7, 0x1B, 0xBD,
7083
7084 0x48, 0x80, 0x48, 0xCF,
7085 0x59, 0x80, 0x59, 0xCF,
7086
7087 0x68, 0x33, 0x68, 0xCF,
7088 0x49, 0x3B, 0x49, 0xCF,
7089
7090 0xB2, 0xFF, 0x20, 0xEA,
7091 0x00, 0x80, 0x00, 0xE8,
7092
7093 0x58, 0x33, 0x58, 0xCF,
7094 0x69, 0x3B, 0x69, 0xCF,
7095
7096 0x70, 0xFF, 0x20, 0xEA,
7097 0x57, 0xC0, 0xBF, 0xEA,
7098
7099 0x00, 0x80, 0xA0, 0xE9,
7100 0x00, 0x00, 0xD8, 0xEC,
7101
7102};
7103
7104static unsigned char warp_g400_t2gzsa[] = {
7105
7106 0x00, 0x8A, 0x98, 0xE9,
7107 0x00, 0x80, 0x00, 0xE8,
7108
7109 0x00, 0x80, 0xA0, 0xE9,
7110 0x00, 0x00, 0xD8, 0xEC,
7111
7112 0xFF, 0x80, 0xC0, 0xE9,
7113 0x00, 0x80, 0x00, 0xE8,
7114
7115 0x0A, 0x40, 0x50, 0xBF,
7116 0x2A, 0x40, 0x60, 0xBF,
7117
7118 0x32, 0x41, 0x51, 0xBF,
7119 0x3A, 0x41, 0x61, 0xBF,
7120
7121 0xC3, 0x6B,
7122 0xD3, 0x6B,
7123 0x00, 0x8A, 0x98, 0xE9,
7124
7125 0x73, 0x7B, 0xC8, 0xEC,
7126 0x96, 0xE2,
7127 0x41, 0x04,
7128
7129 0x7B, 0x43, 0xA0, 0xE8,
7130 0x73, 0x53, 0xA0, 0xE8,
7131
7132 0xAD, 0xEE, 0x23, 0x9F,
7133 0x00, 0xE0,
7134 0x51, 0x04,
7135
7136 0x90, 0xE2,
7137 0x61, 0x04,
7138 0x31, 0x46, 0xB1, 0xE8,
7139
7140 0x51, 0x41, 0xE0, 0xEC,
7141 0x39, 0x67, 0xB1, 0xE8,
7142
7143 0x00, 0x04,
7144 0x46, 0xE2,
7145 0x73, 0x63, 0xA0, 0xE8,
7146
7147 0x61, 0x41, 0xE0, 0xEC,
7148 0x31, 0x00,
7149 0x39, 0x00,
7150
7151 0x8A, 0x80, 0x15, 0xEA,
7152 0x10, 0x04,
7153 0x20, 0x04,
7154
7155 0x61, 0x51, 0xE0, 0xEC,
7156 0x2F, 0x41, 0x60, 0xEA,
7157
7158 0x31, 0x20,
7159 0x39, 0x20,
7160 0x1F, 0x42, 0xA0, 0xE8,
7161
7162 0x2A, 0x42, 0x52, 0xBF,
7163 0x0F, 0x52, 0xA0, 0xE8,
7164
7165 0x1A, 0x42, 0x62, 0xBF,
7166 0x1E, 0x51, 0x60, 0xEA,
7167
7168 0x73, 0x7B, 0xC8, 0xEC,
7169 0x0E, 0x61, 0x60, 0xEA,
7170
7171 0x32, 0x40, 0x50, 0xBD,
7172 0x22, 0x40, 0x60, 0xBD,
7173
7174 0x12, 0x41, 0x51, 0xBD,
7175 0x3A, 0x41, 0x61, 0xBD,
7176
7177 0xBF, 0x2F, 0x0E, 0xBD,
7178 0x97, 0xE2,
7179 0x7B, 0x72,
7180
7181 0x32, 0x20,
7182 0x22, 0x20,
7183 0x12, 0x20,
7184 0x3A, 0x20,
7185
7186 0x35, 0x48, 0xB1, 0xE8,
7187 0x3D, 0x59, 0xB1, 0xE8,
7188
7189 0x46, 0x31, 0x46, 0xBF,
7190 0x56, 0x31, 0x56, 0xBF,
7191
7192 0xB3, 0xE2, 0x2D, 0x9F,
7193 0x00, 0x80, 0x00, 0xE8,
7194
7195 0x66, 0x31, 0x66, 0xBF,
7196 0x47, 0x39, 0x47, 0xBF,
7197
7198 0x57, 0x39, 0x57, 0xBF,
7199 0x67, 0x39, 0x67, 0xBF,
7200
7201 0x7B, 0x80, 0x07, 0xEA,
7202 0x24, 0x41, 0x20, 0xE9,
7203
7204 0x35, 0x00,
7205 0x3D, 0x00,
7206 0x00, 0xE0,
7207 0x2D, 0x73,
7208
7209 0x33, 0x72,
7210 0x0C, 0xE3,
7211 0x8D, 0x2F, 0x1E, 0xBD,
7212
7213 0x43, 0x75, 0xF8, 0xEC,
7214 0x35, 0x20,
7215 0x3D, 0x20,
7216
7217 0x43, 0x43, 0x2D, 0xDF,
7218 0x53, 0x53, 0x2D, 0xDF,
7219
7220 0xAE, 0x1E, 0x0E, 0xBD,
7221 0x58, 0xE3,
7222 0x33, 0x66,
7223
7224 0x48, 0x35, 0x48, 0xBF,
7225 0x58, 0x35, 0x58, 0xBF,
7226
7227 0x68, 0x35, 0x68, 0xBF,
7228 0x49, 0x3D, 0x49, 0xBF,
7229
7230 0x59, 0x3D, 0x59, 0xBF,
7231 0x69, 0x3D, 0x69, 0xBF,
7232
7233 0x63, 0x63, 0x2D, 0xDF,
7234 0x4D, 0x7D, 0xF8, 0xEC,
7235
7236 0x59, 0xE3,
7237 0x00, 0xE0,
7238 0xB8, 0x38, 0x33, 0xBF,
7239
7240 0x2D, 0x73,
7241 0x30, 0x76,
7242 0x18, 0x3A, 0x41, 0xE9,
7243
7244 0x3F, 0x53, 0xA0, 0xE8,
7245 0x05, 0x80, 0x3D, 0xEA,
7246
7247 0x37, 0x43, 0xA0, 0xE8,
7248 0x3D, 0x63, 0xA0, 0xE8,
7249
7250 0x50, 0x70, 0xF8, 0xEC,
7251 0x2B, 0x50, 0x3C, 0xE9,
7252
7253 0x1F, 0x0F, 0xBC, 0xE8,
7254 0x00, 0x80, 0x00, 0xE8,
7255
7256 0x59, 0x78, 0xF8, 0xEC,
7257 0x00, 0x80, 0x00, 0xE8,
7258
7259 0x15, 0xC0, 0x20, 0xE9,
7260 0x15, 0xC0, 0x20, 0xE9,
7261
7262 0x15, 0xC0, 0x20, 0xE9,
7263 0x15, 0xC0, 0x20, 0xE9,
7264
7265 0x1E, 0x12, 0x41, 0xE9,
7266 0x1A, 0x22, 0x41, 0xE9,
7267
7268 0x46, 0x37, 0x46, 0xDF,
7269 0x56, 0x3F, 0x56, 0xDF,
7270
7271 0x2B, 0x40, 0x3D, 0xE9,
7272 0x66, 0x3D, 0x66, 0xDF,
7273
7274 0x1D, 0x32, 0x41, 0xE9,
7275 0x67, 0x3D, 0x67, 0xDF,
7276
7277 0x47, 0x37, 0x47, 0xDF,
7278 0x57, 0x3F, 0x57, 0xDF,
7279
7280 0x2A, 0x40, 0x20, 0xE9,
7281 0x59, 0x3F, 0x59, 0xDF,
7282
7283 0x16, 0x30, 0x20, 0xE9,
7284 0x69, 0x3D, 0x69, 0xDF,
7285
7286 0x48, 0x37, 0x48, 0xDF,
7287 0x58, 0x3F, 0x58, 0xDF,
7288
7289 0x68, 0x3D, 0x68, 0xDF,
7290 0x49, 0x37, 0x49, 0xDF,
7291
7292 0x32, 0x32, 0x2D, 0xDF,
7293 0x22, 0x22, 0x2D, 0xDF,
7294
7295 0x12, 0x12, 0x2D, 0xDF,
7296 0x3A, 0x3A, 0x2D, 0xDF,
7297
7298 0x0F, 0xCF, 0x74, 0xC2,
7299 0x37, 0xCF, 0x74, 0xC4,
7300
7301 0x0A, 0x44, 0x54, 0xB0,
7302 0x02, 0x44, 0x64, 0xB0,
7303
7304 0x3D, 0xCF, 0x74, 0xC0,
7305 0x34, 0x37, 0x20, 0xE9,
7306
7307 0x31, 0x53, 0x2F, 0x9F,
7308 0x38, 0x0F, 0x20, 0xE9,
7309
7310 0x39, 0xE5, 0x2C, 0x9F,
7311 0x3C, 0x3D, 0x20, 0xE9,
7312
7313 0x2A, 0x44, 0x54, 0xB2,
7314 0x1A, 0x44, 0x64, 0xB2,
7315
7316 0x36, 0x80, 0x3A, 0xEA,
7317 0x0A, 0x20,
7318 0x02, 0x20,
7319
7320 0x0F, 0xCF, 0x75, 0xC0,
7321 0x2A, 0x20,
7322 0x1A, 0x20,
7323
7324 0x30, 0x50, 0x2E, 0x9F,
7325 0x32, 0x31, 0x5F, 0xE9,
7326
7327 0x38, 0x21, 0x2C, 0x9F,
7328 0x33, 0x39, 0x5F, 0xE9,
7329
7330 0x3D, 0xCF, 0x75, 0xC2,
7331 0x37, 0xCF, 0x75, 0xC4,
7332
7333 0x31, 0x53, 0x2F, 0x9F,
7334 0xA6, 0x0F, 0x20, 0xE9,
7335
7336 0x39, 0xE5, 0x2C, 0x9F,
7337 0xA3, 0x3D, 0x20, 0xE9,
7338
7339 0x2A, 0x44, 0x54, 0xB4,
7340 0x1A, 0x44, 0x64, 0xB4,
7341
7342 0x0A, 0x45, 0x55, 0xB0,
7343 0x02, 0x45, 0x65, 0xB0,
7344
7345 0x88, 0x73, 0x5E, 0xE9,
7346 0x2A, 0x20,
7347 0x1A, 0x20,
7348
7349 0xA0, 0x37, 0x20, 0xE9,
7350 0x0A, 0x20,
7351 0x02, 0x20,
7352
7353 0x31, 0x53, 0x2F, 0x9F,
7354 0x3E, 0x30, 0x4F, 0xE9,
7355
7356 0x39, 0xE5, 0x2C, 0x9F,
7357 0x3F, 0x38, 0x4F, 0xE9,
7358
7359 0x30, 0x50, 0x2E, 0x9F,
7360 0x3A, 0x31, 0x4F, 0xE9,
7361
7362 0x38, 0x21, 0x2C, 0x9F,
7363 0x3B, 0x39, 0x4F, 0xE9,
7364
7365 0x2A, 0x45, 0x55, 0xB2,
7366 0x1A, 0x45, 0x65, 0xB2,
7367
7368 0x0A, 0x45, 0x55, 0xB4,
7369 0x02, 0x45, 0x65, 0xB4,
7370
7371 0x0F, 0xCF, 0x74, 0xC6,
7372 0x2A, 0x20,
7373 0x1A, 0x20,
7374
7375 0xA7, 0x30, 0x4F, 0xE9,
7376 0x0A, 0x20,
7377 0x02, 0x20,
7378
7379 0x31, 0x53, 0x2F, 0x9F,
7380 0x9C, 0x0F, 0x20, 0xE9,
7381
7382 0x39, 0xE5, 0x2C, 0x9F,
7383 0xA8, 0x38, 0x4F, 0xE9,
7384
7385 0x2A, 0x44, 0x54, 0xB6,
7386 0x1A, 0x44, 0x64, 0xB6,
7387
7388 0x30, 0x50, 0x2E, 0x9F,
7389 0x36, 0x31, 0x4F, 0xE9,
7390
7391 0x38, 0x21, 0x2C, 0x9F,
7392 0x37, 0x39, 0x4F, 0xE9,
7393
7394 0x00, 0x80, 0x00, 0xE8,
7395 0x2A, 0x20,
7396 0x1A, 0x20,
7397
7398 0x2A, 0x46, 0x56, 0xBF,
7399 0x1A, 0x46, 0x66, 0xBF,
7400
7401 0x31, 0x53, 0x2F, 0x9F,
7402 0xA4, 0x31, 0x4F, 0xE9,
7403
7404 0x39, 0xE5, 0x2C, 0x9F,
7405 0xA5, 0x39, 0x4F, 0xE9,
7406
7407 0x0A, 0x47, 0x57, 0xBF,
7408 0x02, 0x47, 0x67, 0xBF,
7409
7410 0x31, 0x53, 0x2F, 0x9F,
7411 0xA1, 0x30, 0x4F, 0xE9,
7412
7413 0x39, 0xE5, 0x2C, 0x9F,
7414 0xA2, 0x38, 0x4F, 0xE9,
7415
7416 0x2A, 0x43, 0x53, 0xBF,
7417 0x1A, 0x43, 0x63, 0xBF,
7418
7419 0x30, 0x50, 0x2E, 0x9F,
7420 0x9D, 0x31, 0x4F, 0xE9,
7421
7422 0x38, 0x21, 0x2C, 0x9F,
7423 0x9E, 0x39, 0x4F, 0xE9,
7424
7425 0x0A, 0x48, 0x58, 0xBF,
7426 0x02, 0x48, 0x68, 0xBF,
7427
7428 0x31, 0x53, 0x2F, 0x9F,
7429 0x80, 0x31, 0x57, 0xE9,
7430
7431 0x39, 0xE5, 0x2C, 0x9F,
7432 0x81, 0x39, 0x57, 0xE9,
7433
7434 0x2A, 0x49, 0x59, 0xBF,
7435 0x1A, 0x49, 0x69, 0xBF,
7436
7437 0x30, 0x50, 0x2E, 0x9F,
7438 0x82, 0x30, 0x57, 0xE9,
7439
7440 0x38, 0x21, 0x2C, 0x9F,
7441 0x83, 0x38, 0x57, 0xE9,
7442
7443 0x31, 0x53, 0x2F, 0x9F,
7444 0x84, 0x31, 0x5E, 0xE9,
7445
7446 0x39, 0xE5, 0x2C, 0x9F,
7447 0x85, 0x39, 0x5E, 0xE9,
7448
7449 0x86, 0x76, 0x57, 0xE9,
7450 0x8A, 0x36, 0x20, 0xE9,
7451
7452 0x87, 0x77, 0x57, 0xE9,
7453 0x8B, 0x3E, 0xBF, 0xEA,
7454
7455 0x80, 0x30, 0x57, 0xE9,
7456 0x81, 0x38, 0x57, 0xE9,
7457
7458 0x82, 0x31, 0x57, 0xE9,
7459 0x86, 0x78, 0x57, 0xE9,
7460
7461 0x83, 0x39, 0x57, 0xE9,
7462 0x87, 0x79, 0x57, 0xE9,
7463
7464 0x30, 0x1F, 0x5F, 0xE9,
7465 0x8A, 0x34, 0x20, 0xE9,
7466
7467 0x8B, 0x3C, 0x20, 0xE9,
7468 0x37, 0x50, 0x60, 0xBD,
7469
7470 0x57, 0x0D, 0x20, 0xE9,
7471 0x35, 0x51, 0x61, 0xBD,
7472
7473 0x2B, 0x50, 0x20, 0xE9,
7474 0x1D, 0x37, 0xE1, 0xEA,
7475
7476 0x1E, 0x35, 0xE1, 0xEA,
7477 0x00, 0xE0,
7478 0x0E, 0x77,
7479
7480 0x24, 0x51, 0x20, 0xE9,
7481 0x8D, 0xFF, 0x20, 0xEA,
7482
7483 0x16, 0x0E, 0x20, 0xE9,
7484 0x57, 0x2E, 0xBF, 0xEA,
7485
7486 0x0B, 0x46, 0xA0, 0xE8,
7487 0x1B, 0x56, 0xA0, 0xE8,
7488
7489 0x2B, 0x66, 0xA0, 0xE8,
7490 0x0C, 0x47, 0xA0, 0xE8,
7491
7492 0x1C, 0x57, 0xA0, 0xE8,
7493 0x2C, 0x67, 0xA0, 0xE8,
7494
7495 0x0B, 0x00,
7496 0x1B, 0x00,
7497 0x2B, 0x00,
7498 0x00, 0xE0,
7499
7500 0x0C, 0x00,
7501 0x1C, 0x00,
7502 0x2C, 0x00,
7503 0x00, 0xE0,
7504
7505 0x0B, 0x65,
7506 0x1B, 0x65,
7507 0x2B, 0x65,
7508 0x00, 0xE0,
7509
7510 0x0C, 0x65,
7511 0x1C, 0x65,
7512 0x2C, 0x65,
7513 0x00, 0xE0,
7514
7515 0x0B, 0x1B, 0x60, 0xEC,
7516 0x36, 0xD7, 0x36, 0xAD,
7517
7518 0x2B, 0x80, 0x60, 0xEC,
7519 0x0C, 0x1C, 0x60, 0xEC,
7520
7521 0x3E, 0xD7, 0x3E, 0xAD,
7522 0x2C, 0x80, 0x60, 0xEC,
7523
7524 0x0B, 0x2B, 0xDE, 0xE8,
7525 0x1B, 0x80, 0xDE, 0xE8,
7526
7527 0x36, 0x80, 0x36, 0xBD,
7528 0x3E, 0x80, 0x3E, 0xBD,
7529
7530 0x33, 0xD7, 0x0B, 0xBD,
7531 0x3B, 0xD7, 0x1B, 0xBD,
7532
7533 0x46, 0x80, 0x46, 0xCF,
7534 0x57, 0x80, 0x57, 0xCF,
7535
7536 0x66, 0x33, 0x66, 0xCF,
7537 0x47, 0x3B, 0x47, 0xCF,
7538
7539 0x56, 0x33, 0x56, 0xCF,
7540 0x67, 0x3B, 0x67, 0xCF,
7541
7542 0x0B, 0x48, 0xA0, 0xE8,
7543 0x1B, 0x58, 0xA0, 0xE8,
7544
7545 0x2B, 0x68, 0xA0, 0xE8,
7546 0x0C, 0x49, 0xA0, 0xE8,
7547
7548 0x1C, 0x59, 0xA0, 0xE8,
7549 0x2C, 0x69, 0xA0, 0xE8,
7550
7551 0x0B, 0x00,
7552 0x1B, 0x00,
7553 0x2B, 0x00,
7554 0x00, 0xE0,
7555
7556 0x0C, 0x00,
7557 0x1C, 0x00,
7558 0x2C, 0x00,
7559 0x00, 0xE0,
7560
7561 0x0B, 0x65,
7562 0x1B, 0x65,
7563 0x2B, 0x65,
7564 0x00, 0xE0,
7565
7566 0x0C, 0x65,
7567 0x1C, 0x65,
7568 0x2C, 0x65,
7569 0x00, 0xE0,
7570
7571 0x0B, 0x1B, 0x60, 0xEC,
7572 0x34, 0xD7, 0x34, 0xAD,
7573
7574 0x2B, 0x80, 0x60, 0xEC,
7575 0x0C, 0x1C, 0x60, 0xEC,
7576
7577 0x3C, 0xD7, 0x3C, 0xAD,
7578 0x2C, 0x80, 0x60, 0xEC,
7579
7580 0x0B, 0x2B, 0xDE, 0xE8,
7581 0x1B, 0x80, 0xDE, 0xE8,
7582
7583 0x34, 0x80, 0x34, 0xBD,
7584 0x3C, 0x80, 0x3C, 0xBD,
7585
7586 0x33, 0xD7, 0x0B, 0xBD,
7587 0x3B, 0xD7, 0x1B, 0xBD,
7588
7589 0x48, 0x80, 0x48, 0xCF,
7590 0x59, 0x80, 0x59, 0xCF,
7591
7592 0x68, 0x33, 0x68, 0xCF,
7593 0x49, 0x3B, 0x49, 0xCF,
7594
7595 0xAD, 0xFF, 0x20, 0xEA,
7596 0x00, 0x80, 0x00, 0xE8,
7597
7598 0x58, 0x33, 0x58, 0xCF,
7599 0x69, 0x3B, 0x69, 0xCF,
7600
7601 0x6B, 0xFF, 0x20, 0xEA,
7602 0x57, 0xC0, 0xBF, 0xEA,
7603
7604 0x00, 0x80, 0xA0, 0xE9,
7605 0x00, 0x00, 0xD8, 0xEC,
7606
7607};
7608
7609static unsigned char warp_g400_t2gzsaf[] = {
7610
7611 0x00, 0x8A, 0x98, 0xE9,
7612 0x00, 0x80, 0x00, 0xE8,
7613
7614 0x00, 0x80, 0xA0, 0xE9,
7615 0x00, 0x00, 0xD8, 0xEC,
7616
7617 0xFF, 0x80, 0xC0, 0xE9,
7618 0x00, 0x80, 0x00, 0xE8,
7619
7620 0x0A, 0x40, 0x50, 0xBF,
7621 0x2A, 0x40, 0x60, 0xBF,
7622
7623 0x32, 0x41, 0x51, 0xBF,
7624 0x3A, 0x41, 0x61, 0xBF,
7625
7626 0xC3, 0x6B,
7627 0xD3, 0x6B,
7628 0x00, 0x8A, 0x98, 0xE9,
7629
7630 0x73, 0x7B, 0xC8, 0xEC,
7631 0x96, 0xE2,
7632 0x41, 0x04,
7633
7634 0x7B, 0x43, 0xA0, 0xE8,
7635 0x73, 0x53, 0xA0, 0xE8,
7636
7637 0xAD, 0xEE, 0x23, 0x9F,
7638 0x00, 0xE0,
7639 0x51, 0x04,
7640
7641 0x90, 0xE2,
7642 0x61, 0x04,
7643 0x31, 0x46, 0xB1, 0xE8,
7644
7645 0x51, 0x41, 0xE0, 0xEC,
7646 0x39, 0x67, 0xB1, 0xE8,
7647
7648 0x00, 0x04,
7649 0x46, 0xE2,
7650 0x73, 0x63, 0xA0, 0xE8,
7651
7652 0x61, 0x41, 0xE0, 0xEC,
7653 0x31, 0x00,
7654 0x39, 0x00,
7655
7656 0x8E, 0x80, 0x15, 0xEA,
7657 0x10, 0x04,
7658 0x20, 0x04,
7659
7660 0x61, 0x51, 0xE0, 0xEC,
7661 0x2F, 0x41, 0x60, 0xEA,
7662
7663 0x31, 0x20,
7664 0x39, 0x20,
7665 0x1F, 0x42, 0xA0, 0xE8,
7666
7667 0x2A, 0x42, 0x52, 0xBF,
7668 0x0F, 0x52, 0xA0, 0xE8,
7669
7670 0x1A, 0x42, 0x62, 0xBF,
7671 0x1E, 0x51, 0x60, 0xEA,
7672
7673 0x73, 0x7B, 0xC8, 0xEC,
7674 0x0E, 0x61, 0x60, 0xEA,
7675
7676 0x32, 0x40, 0x50, 0xBD,
7677 0x22, 0x40, 0x60, 0xBD,
7678
7679 0x12, 0x41, 0x51, 0xBD,
7680 0x3A, 0x41, 0x61, 0xBD,
7681
7682 0xBF, 0x2F, 0x0E, 0xBD,
7683 0x97, 0xE2,
7684 0x7B, 0x72,
7685
7686 0x32, 0x20,
7687 0x22, 0x20,
7688 0x12, 0x20,
7689 0x3A, 0x20,
7690
7691 0x35, 0x48, 0xB1, 0xE8,
7692 0x3D, 0x59, 0xB1, 0xE8,
7693
7694 0x46, 0x31, 0x46, 0xBF,
7695 0x56, 0x31, 0x56, 0xBF,
7696
7697 0xB3, 0xE2, 0x2D, 0x9F,
7698 0x00, 0x80, 0x00, 0xE8,
7699
7700 0x66, 0x31, 0x66, 0xBF,
7701 0x47, 0x39, 0x47, 0xBF,
7702
7703 0x57, 0x39, 0x57, 0xBF,
7704 0x67, 0x39, 0x67, 0xBF,
7705
7706 0x7F, 0x80, 0x07, 0xEA,
7707 0x24, 0x41, 0x20, 0xE9,
7708
7709 0x35, 0x00,
7710 0x3D, 0x00,
7711 0x00, 0xE0,
7712 0x2D, 0x73,
7713
7714 0x33, 0x72,
7715 0x0C, 0xE3,
7716 0x8D, 0x2F, 0x1E, 0xBD,
7717
7718 0x43, 0x75, 0xF8, 0xEC,
7719 0x35, 0x20,
7720 0x3D, 0x20,
7721
7722 0x43, 0x43, 0x2D, 0xDF,
7723 0x53, 0x53, 0x2D, 0xDF,
7724
7725 0xAE, 0x1E, 0x0E, 0xBD,
7726 0x58, 0xE3,
7727 0x33, 0x66,
7728
7729 0x48, 0x35, 0x48, 0xBF,
7730 0x58, 0x35, 0x58, 0xBF,
7731
7732 0x68, 0x35, 0x68, 0xBF,
7733 0x49, 0x3D, 0x49, 0xBF,
7734
7735 0x59, 0x3D, 0x59, 0xBF,
7736 0x69, 0x3D, 0x69, 0xBF,
7737
7738 0x63, 0x63, 0x2D, 0xDF,
7739 0x4D, 0x7D, 0xF8, 0xEC,
7740
7741 0x59, 0xE3,
7742 0x00, 0xE0,
7743 0xB8, 0x38, 0x33, 0xBF,
7744
7745 0x2D, 0x73,
7746 0x30, 0x76,
7747 0x18, 0x3A, 0x41, 0xE9,
7748
7749 0x3F, 0x53, 0xA0, 0xE8,
7750 0x05, 0x80, 0x3D, 0xEA,
7751
7752 0x37, 0x43, 0xA0, 0xE8,
7753 0x3D, 0x63, 0xA0, 0xE8,
7754
7755 0x50, 0x70, 0xF8, 0xEC,
7756 0x2B, 0x50, 0x3C, 0xE9,
7757
7758 0x1F, 0x0F, 0xBC, 0xE8,
7759 0x00, 0x80, 0x00, 0xE8,
7760
7761 0x59, 0x78, 0xF8, 0xEC,
7762 0x00, 0x80, 0x00, 0xE8,
7763
7764 0x15, 0xC0, 0x20, 0xE9,
7765 0x15, 0xC0, 0x20, 0xE9,
7766
7767 0x15, 0xC0, 0x20, 0xE9,
7768 0x15, 0xC0, 0x20, 0xE9,
7769
7770 0x1E, 0x12, 0x41, 0xE9,
7771 0x1A, 0x22, 0x41, 0xE9,
7772
7773 0x46, 0x37, 0x46, 0xDF,
7774 0x56, 0x3F, 0x56, 0xDF,
7775
7776 0x2B, 0x40, 0x3D, 0xE9,
7777 0x66, 0x3D, 0x66, 0xDF,
7778
7779 0x1D, 0x32, 0x41, 0xE9,
7780 0x67, 0x3D, 0x67, 0xDF,
7781
7782 0x47, 0x37, 0x47, 0xDF,
7783 0x57, 0x3F, 0x57, 0xDF,
7784
7785 0x2A, 0x40, 0x20, 0xE9,
7786 0x59, 0x3F, 0x59, 0xDF,
7787
7788 0x16, 0x30, 0x20, 0xE9,
7789 0x69, 0x3D, 0x69, 0xDF,
7790
7791 0x48, 0x37, 0x48, 0xDF,
7792 0x58, 0x3F, 0x58, 0xDF,
7793
7794 0x68, 0x3D, 0x68, 0xDF,
7795 0x49, 0x37, 0x49, 0xDF,
7796
7797 0x32, 0x32, 0x2D, 0xDF,
7798 0x22, 0x22, 0x2D, 0xDF,
7799
7800 0x12, 0x12, 0x2D, 0xDF,
7801 0x3A, 0x3A, 0x2D, 0xDF,
7802
7803 0x0F, 0xCF, 0x74, 0xC2,
7804 0x37, 0xCF, 0x74, 0xC4,
7805
7806 0x0A, 0x44, 0x54, 0xB0,
7807 0x02, 0x44, 0x64, 0xB0,
7808
7809 0x3D, 0xCF, 0x74, 0xC0,
7810 0x34, 0x37, 0x20, 0xE9,
7811
7812 0x31, 0x53, 0x2F, 0x9F,
7813 0x38, 0x0F, 0x20, 0xE9,
7814
7815 0x39, 0xE5, 0x2C, 0x9F,
7816 0x3C, 0x3D, 0x20, 0xE9,
7817
7818 0x2A, 0x44, 0x54, 0xB2,
7819 0x1A, 0x44, 0x64, 0xB2,
7820
7821 0x3A, 0x80, 0x3A, 0xEA,
7822 0x0A, 0x20,
7823 0x02, 0x20,
7824
7825 0x0F, 0xCF, 0x75, 0xC0,
7826 0x2A, 0x20,
7827 0x1A, 0x20,
7828
7829 0x30, 0x50, 0x2E, 0x9F,
7830 0x32, 0x31, 0x5F, 0xE9,
7831
7832 0x38, 0x21, 0x2C, 0x9F,
7833 0x33, 0x39, 0x5F, 0xE9,
7834
7835 0x3D, 0xCF, 0x75, 0xC2,
7836 0x37, 0xCF, 0x75, 0xC4,
7837
7838 0x31, 0x53, 0x2F, 0x9F,
7839 0xA6, 0x0F, 0x20, 0xE9,
7840
7841 0x39, 0xE5, 0x2C, 0x9F,
7842 0xA3, 0x3D, 0x20, 0xE9,
7843
7844 0x2A, 0x44, 0x54, 0xB4,
7845 0x1A, 0x44, 0x64, 0xB4,
7846
7847 0x0A, 0x45, 0x55, 0xB0,
7848 0x02, 0x45, 0x65, 0xB0,
7849
7850 0x88, 0x73, 0x5E, 0xE9,
7851 0x2A, 0x20,
7852 0x1A, 0x20,
7853
7854 0xA0, 0x37, 0x20, 0xE9,
7855 0x0A, 0x20,
7856 0x02, 0x20,
7857
7858 0x31, 0x53, 0x2F, 0x9F,
7859 0x3E, 0x30, 0x4F, 0xE9,
7860
7861 0x39, 0xE5, 0x2C, 0x9F,
7862 0x3F, 0x38, 0x4F, 0xE9,
7863
7864 0x30, 0x50, 0x2E, 0x9F,
7865 0x3A, 0x31, 0x4F, 0xE9,
7866
7867 0x38, 0x21, 0x2C, 0x9F,
7868 0x3B, 0x39, 0x4F, 0xE9,
7869
7870 0x2A, 0x45, 0x55, 0xB2,
7871 0x1A, 0x45, 0x65, 0xB2,
7872
7873 0x0A, 0x45, 0x55, 0xB4,
7874 0x02, 0x45, 0x65, 0xB4,
7875
7876 0x0F, 0xCF, 0x74, 0xC6,
7877 0x2A, 0x20,
7878 0x1A, 0x20,
7879
7880 0xA7, 0x30, 0x4F, 0xE9,
7881 0x0A, 0x20,
7882 0x02, 0x20,
7883
7884 0x31, 0x53, 0x2F, 0x9F,
7885 0x9C, 0x0F, 0x20, 0xE9,
7886
7887 0x39, 0xE5, 0x2C, 0x9F,
7888 0xA8, 0x38, 0x4F, 0xE9,
7889
7890 0x2A, 0x44, 0x54, 0xB6,
7891 0x1A, 0x44, 0x64, 0xB6,
7892
7893 0x30, 0x50, 0x2E, 0x9F,
7894 0x36, 0x31, 0x4F, 0xE9,
7895
7896 0x38, 0x21, 0x2C, 0x9F,
7897 0x37, 0x39, 0x4F, 0xE9,
7898
7899 0x0A, 0x45, 0x55, 0xB6,
7900 0x02, 0x45, 0x65, 0xB6,
7901
7902 0x3D, 0xCF, 0x75, 0xC6,
7903 0x2A, 0x20,
7904 0x1A, 0x20,
7905
7906 0x2A, 0x46, 0x56, 0xBF,
7907 0x1A, 0x46, 0x66, 0xBF,
7908
7909 0x31, 0x53, 0x2F, 0x9F,
7910 0xA4, 0x31, 0x4F, 0xE9,
7911
7912 0x39, 0xE5, 0x2C, 0x9F,
7913 0xA5, 0x39, 0x4F, 0xE9,
7914
7915 0x31, 0x3D, 0x20, 0xE9,
7916 0x0A, 0x20,
7917 0x02, 0x20,
7918
7919 0x0A, 0x47, 0x57, 0xBF,
7920 0x02, 0x47, 0x67, 0xBF,
7921
7922 0x30, 0x50, 0x2E, 0x9F,
7923 0xA1, 0x30, 0x4F, 0xE9,
7924
7925 0x38, 0x21, 0x2C, 0x9F,
7926 0xA2, 0x38, 0x4F, 0xE9,
7927
7928 0x31, 0x53, 0x2F, 0x9F,
7929 0x9D, 0x31, 0x4F, 0xE9,
7930
7931 0x39, 0xE5, 0x2C, 0x9F,
7932 0x9E, 0x39, 0x4F, 0xE9,
7933
7934 0x2A, 0x43, 0x53, 0xBF,
7935 0x1A, 0x43, 0x63, 0xBF,
7936
7937 0x30, 0x50, 0x2E, 0x9F,
7938 0x35, 0x30, 0x4F, 0xE9,
7939
7940 0x38, 0x21, 0x2C, 0x9F,
7941 0x39, 0x38, 0x4F, 0xE9,
7942
7943 0x0A, 0x48, 0x58, 0xBF,
7944 0x02, 0x48, 0x68, 0xBF,
7945
7946 0x31, 0x53, 0x2F, 0x9F,
7947 0x80, 0x31, 0x57, 0xE9,
7948
7949 0x39, 0xE5, 0x2C, 0x9F,
7950 0x81, 0x39, 0x57, 0xE9,
7951
7952 0x2A, 0x49, 0x59, 0xBF,
7953 0x1A, 0x49, 0x69, 0xBF,
7954
7955 0x30, 0x50, 0x2E, 0x9F,
7956 0x82, 0x30, 0x57, 0xE9,
7957
7958 0x38, 0x21, 0x2C, 0x9F,
7959 0x83, 0x38, 0x57, 0xE9,
7960
7961 0x31, 0x53, 0x2F, 0x9F,
7962 0x84, 0x31, 0x5E, 0xE9,
7963
7964 0x39, 0xE5, 0x2C, 0x9F,
7965 0x85, 0x39, 0x5E, 0xE9,
7966
7967 0x86, 0x76, 0x57, 0xE9,
7968 0x8A, 0x36, 0x20, 0xE9,
7969
7970 0x87, 0x77, 0x57, 0xE9,
7971 0x8B, 0x3E, 0xBF, 0xEA,
7972
7973 0x80, 0x30, 0x57, 0xE9,
7974 0x81, 0x38, 0x57, 0xE9,
7975
7976 0x82, 0x31, 0x57, 0xE9,
7977 0x86, 0x78, 0x57, 0xE9,
7978
7979 0x83, 0x39, 0x57, 0xE9,
7980 0x87, 0x79, 0x57, 0xE9,
7981
7982 0x30, 0x1F, 0x5F, 0xE9,
7983 0x8A, 0x34, 0x20, 0xE9,
7984
7985 0x8B, 0x3C, 0x20, 0xE9,
7986 0x37, 0x50, 0x60, 0xBD,
7987
7988 0x57, 0x0D, 0x20, 0xE9,
7989 0x35, 0x51, 0x61, 0xBD,
7990
7991 0x2B, 0x50, 0x20, 0xE9,
7992 0x1D, 0x37, 0xE1, 0xEA,
7993
7994 0x1E, 0x35, 0xE1, 0xEA,
7995 0x00, 0xE0,
7996 0x0E, 0x77,
7997
7998 0x24, 0x51, 0x20, 0xE9,
7999 0x89, 0xFF, 0x20, 0xEA,
8000
8001 0x16, 0x0E, 0x20, 0xE9,
8002 0x57, 0x2E, 0xBF, 0xEA,
8003
8004 0x0B, 0x46, 0xA0, 0xE8,
8005 0x1B, 0x56, 0xA0, 0xE8,
8006
8007 0x2B, 0x66, 0xA0, 0xE8,
8008 0x0C, 0x47, 0xA0, 0xE8,
8009
8010 0x1C, 0x57, 0xA0, 0xE8,
8011 0x2C, 0x67, 0xA0, 0xE8,
8012
8013 0x0B, 0x00,
8014 0x1B, 0x00,
8015 0x2B, 0x00,
8016 0x00, 0xE0,
8017
8018 0x0C, 0x00,
8019 0x1C, 0x00,
8020 0x2C, 0x00,
8021 0x00, 0xE0,
8022
8023 0x0B, 0x65,
8024 0x1B, 0x65,
8025 0x2B, 0x65,
8026 0x00, 0xE0,
8027
8028 0x0C, 0x65,
8029 0x1C, 0x65,
8030 0x2C, 0x65,
8031 0x00, 0xE0,
8032
8033 0x0B, 0x1B, 0x60, 0xEC,
8034 0x36, 0xD7, 0x36, 0xAD,
8035
8036 0x2B, 0x80, 0x60, 0xEC,
8037 0x0C, 0x1C, 0x60, 0xEC,
8038
8039 0x3E, 0xD7, 0x3E, 0xAD,
8040 0x2C, 0x80, 0x60, 0xEC,
8041
8042 0x0B, 0x2B, 0xDE, 0xE8,
8043 0x1B, 0x80, 0xDE, 0xE8,
8044
8045 0x36, 0x80, 0x36, 0xBD,
8046 0x3E, 0x80, 0x3E, 0xBD,
8047
8048 0x33, 0xD7, 0x0B, 0xBD,
8049 0x3B, 0xD7, 0x1B, 0xBD,
8050
8051 0x46, 0x80, 0x46, 0xCF,
8052 0x57, 0x80, 0x57, 0xCF,
8053
8054 0x66, 0x33, 0x66, 0xCF,
8055 0x47, 0x3B, 0x47, 0xCF,
8056
8057 0x56, 0x33, 0x56, 0xCF,
8058 0x67, 0x3B, 0x67, 0xCF,
8059
8060 0x0B, 0x48, 0xA0, 0xE8,
8061 0x1B, 0x58, 0xA0, 0xE8,
8062
8063 0x2B, 0x68, 0xA0, 0xE8,
8064 0x0C, 0x49, 0xA0, 0xE8,
8065
8066 0x1C, 0x59, 0xA0, 0xE8,
8067 0x2C, 0x69, 0xA0, 0xE8,
8068
8069 0x0B, 0x00,
8070 0x1B, 0x00,
8071 0x2B, 0x00,
8072 0x00, 0xE0,
8073
8074 0x0C, 0x00,
8075 0x1C, 0x00,
8076 0x2C, 0x00,
8077 0x00, 0xE0,
8078
8079 0x0B, 0x65,
8080 0x1B, 0x65,
8081 0x2B, 0x65,
8082 0x00, 0xE0,
8083
8084 0x0C, 0x65,
8085 0x1C, 0x65,
8086 0x2C, 0x65,
8087 0x00, 0xE0,
8088
8089 0x0B, 0x1B, 0x60, 0xEC,
8090 0x34, 0xD7, 0x34, 0xAD,
8091
8092 0x2B, 0x80, 0x60, 0xEC,
8093 0x0C, 0x1C, 0x60, 0xEC,
8094
8095 0x3C, 0xD7, 0x3C, 0xAD,
8096 0x2C, 0x80, 0x60, 0xEC,
8097
8098 0x0B, 0x2B, 0xDE, 0xE8,
8099 0x1B, 0x80, 0xDE, 0xE8,
8100
8101 0x34, 0x80, 0x34, 0xBD,
8102 0x3C, 0x80, 0x3C, 0xBD,
8103
8104 0x33, 0xD7, 0x0B, 0xBD,
8105 0x3B, 0xD7, 0x1B, 0xBD,
8106
8107 0x48, 0x80, 0x48, 0xCF,
8108 0x59, 0x80, 0x59, 0xCF,
8109
8110 0x68, 0x33, 0x68, 0xCF,
8111 0x49, 0x3B, 0x49, 0xCF,
8112
8113 0xA9, 0xFF, 0x20, 0xEA,
8114 0x00, 0x80, 0x00, 0xE8,
8115
8116 0x58, 0x33, 0x58, 0xCF,
8117 0x69, 0x3B, 0x69, 0xCF,
8118
8119 0x67, 0xFF, 0x20, 0xEA,
8120 0x57, 0xC0, 0xBF, 0xEA,
8121
8122 0x00, 0x80, 0xA0, 0xE9,
8123 0x00, 0x00, 0xD8, 0xEC,
8124
8125};
8126
8127static unsigned char warp_g400_t2gzsf[] = {
8128
8129 0x00, 0x8A, 0x98, 0xE9,
8130 0x00, 0x80, 0x00, 0xE8,
8131
8132 0x00, 0x80, 0xA0, 0xE9,
8133 0x00, 0x00, 0xD8, 0xEC,
8134
8135 0xFF, 0x80, 0xC0, 0xE9,
8136 0x00, 0x80, 0x00, 0xE8,
8137
8138 0x0A, 0x40, 0x50, 0xBF,
8139 0x2A, 0x40, 0x60, 0xBF,
8140
8141 0x32, 0x41, 0x51, 0xBF,
8142 0x3A, 0x41, 0x61, 0xBF,
8143
8144 0xC3, 0x6B,
8145 0xD3, 0x6B,
8146 0x00, 0x8A, 0x98, 0xE9,
8147
8148 0x73, 0x7B, 0xC8, 0xEC,
8149 0x96, 0xE2,
8150 0x41, 0x04,
8151
8152 0x7B, 0x43, 0xA0, 0xE8,
8153 0x73, 0x53, 0xA0, 0xE8,
8154
8155 0xAD, 0xEE, 0x23, 0x9F,
8156 0x00, 0xE0,
8157 0x51, 0x04,
8158
8159 0x90, 0xE2,
8160 0x61, 0x04,
8161 0x31, 0x46, 0xB1, 0xE8,
8162
8163 0x51, 0x41, 0xE0, 0xEC,
8164 0x39, 0x67, 0xB1, 0xE8,
8165
8166 0x00, 0x04,
8167 0x46, 0xE2,
8168 0x73, 0x63, 0xA0, 0xE8,
8169
8170 0x61, 0x41, 0xE0, 0xEC,
8171 0x31, 0x00,
8172 0x39, 0x00,
8173
8174 0x8A, 0x80, 0x15, 0xEA,
8175 0x10, 0x04,
8176 0x20, 0x04,
8177
8178 0x61, 0x51, 0xE0, 0xEC,
8179 0x2F, 0x41, 0x60, 0xEA,
8180
8181 0x31, 0x20,
8182 0x39, 0x20,
8183 0x1F, 0x42, 0xA0, 0xE8,
8184
8185 0x2A, 0x42, 0x52, 0xBF,
8186 0x0F, 0x52, 0xA0, 0xE8,
8187
8188 0x1A, 0x42, 0x62, 0xBF,
8189 0x1E, 0x51, 0x60, 0xEA,
8190
8191 0x73, 0x7B, 0xC8, 0xEC,
8192 0x0E, 0x61, 0x60, 0xEA,
8193
8194 0x32, 0x40, 0x50, 0xBD,
8195 0x22, 0x40, 0x60, 0xBD,
8196
8197 0x12, 0x41, 0x51, 0xBD,
8198 0x3A, 0x41, 0x61, 0xBD,
8199
8200 0xBF, 0x2F, 0x0E, 0xBD,
8201 0x97, 0xE2,
8202 0x7B, 0x72,
8203
8204 0x32, 0x20,
8205 0x22, 0x20,
8206 0x12, 0x20,
8207 0x3A, 0x20,
8208
8209 0x35, 0x48, 0xB1, 0xE8,
8210 0x3D, 0x59, 0xB1, 0xE8,
8211
8212 0x46, 0x31, 0x46, 0xBF,
8213 0x56, 0x31, 0x56, 0xBF,
8214
8215 0xB3, 0xE2, 0x2D, 0x9F,
8216 0x00, 0x80, 0x00, 0xE8,
8217
8218 0x66, 0x31, 0x66, 0xBF,
8219 0x47, 0x39, 0x47, 0xBF,
8220
8221 0x57, 0x39, 0x57, 0xBF,
8222 0x67, 0x39, 0x67, 0xBF,
8223
8224 0x7B, 0x80, 0x07, 0xEA,
8225 0x24, 0x41, 0x20, 0xE9,
8226
8227 0x35, 0x00,
8228 0x3D, 0x00,
8229 0x00, 0xE0,
8230 0x2D, 0x73,
8231
8232 0x33, 0x72,
8233 0x0C, 0xE3,
8234 0x8D, 0x2F, 0x1E, 0xBD,
8235
8236 0x43, 0x75, 0xF8, 0xEC,
8237 0x35, 0x20,
8238 0x3D, 0x20,
8239
8240 0x43, 0x43, 0x2D, 0xDF,
8241 0x53, 0x53, 0x2D, 0xDF,
8242
8243 0xAE, 0x1E, 0x0E, 0xBD,
8244 0x58, 0xE3,
8245 0x33, 0x66,
8246
8247 0x48, 0x35, 0x48, 0xBF,
8248 0x58, 0x35, 0x58, 0xBF,
8249
8250 0x68, 0x35, 0x68, 0xBF,
8251 0x49, 0x3D, 0x49, 0xBF,
8252
8253 0x59, 0x3D, 0x59, 0xBF,
8254 0x69, 0x3D, 0x69, 0xBF,
8255
8256 0x63, 0x63, 0x2D, 0xDF,
8257 0x4D, 0x7D, 0xF8, 0xEC,
8258
8259 0x59, 0xE3,
8260 0x00, 0xE0,
8261 0xB8, 0x38, 0x33, 0xBF,
8262
8263 0x2D, 0x73,
8264 0x30, 0x76,
8265 0x18, 0x3A, 0x41, 0xE9,
8266
8267 0x3F, 0x53, 0xA0, 0xE8,
8268 0x05, 0x80, 0x3D, 0xEA,
8269
8270 0x37, 0x43, 0xA0, 0xE8,
8271 0x3D, 0x63, 0xA0, 0xE8,
8272
8273 0x50, 0x70, 0xF8, 0xEC,
8274 0x2B, 0x50, 0x3C, 0xE9,
8275
8276 0x1F, 0x0F, 0xBC, 0xE8,
8277 0x00, 0x80, 0x00, 0xE8,
8278
8279 0x59, 0x78, 0xF8, 0xEC,
8280 0x00, 0x80, 0x00, 0xE8,
8281
8282 0x15, 0xC0, 0x20, 0xE9,
8283 0x15, 0xC0, 0x20, 0xE9,
8284
8285 0x15, 0xC0, 0x20, 0xE9,
8286 0x15, 0xC0, 0x20, 0xE9,
8287
8288 0x1E, 0x12, 0x41, 0xE9,
8289 0x1A, 0x22, 0x41, 0xE9,
8290
8291 0x46, 0x37, 0x46, 0xDF,
8292 0x56, 0x3F, 0x56, 0xDF,
8293
8294 0x2B, 0x40, 0x3D, 0xE9,
8295 0x66, 0x3D, 0x66, 0xDF,
8296
8297 0x1D, 0x32, 0x41, 0xE9,
8298 0x67, 0x3D, 0x67, 0xDF,
8299
8300 0x47, 0x37, 0x47, 0xDF,
8301 0x57, 0x3F, 0x57, 0xDF,
8302
8303 0x2A, 0x40, 0x20, 0xE9,
8304 0x59, 0x3F, 0x59, 0xDF,
8305
8306 0x16, 0x30, 0x20, 0xE9,
8307 0x69, 0x3D, 0x69, 0xDF,
8308
8309 0x48, 0x37, 0x48, 0xDF,
8310 0x58, 0x3F, 0x58, 0xDF,
8311
8312 0x68, 0x3D, 0x68, 0xDF,
8313 0x49, 0x37, 0x49, 0xDF,
8314
8315 0x32, 0x32, 0x2D, 0xDF,
8316 0x22, 0x22, 0x2D, 0xDF,
8317
8318 0x12, 0x12, 0x2D, 0xDF,
8319 0x3A, 0x3A, 0x2D, 0xDF,
8320
8321 0x0F, 0xCF, 0x74, 0xC2,
8322 0x37, 0xCF, 0x74, 0xC4,
8323
8324 0x0A, 0x44, 0x54, 0xB0,
8325 0x02, 0x44, 0x64, 0xB0,
8326
8327 0x3D, 0xCF, 0x74, 0xC0,
8328 0x34, 0x37, 0x20, 0xE9,
8329
8330 0x31, 0x53, 0x2F, 0x9F,
8331 0x38, 0x0F, 0x20, 0xE9,
8332
8333 0x39, 0xE5, 0x2C, 0x9F,
8334 0x3C, 0x3D, 0x20, 0xE9,
8335
8336 0x2A, 0x44, 0x54, 0xB2,
8337 0x1A, 0x44, 0x64, 0xB2,
8338
8339 0x36, 0x80, 0x3A, 0xEA,
8340 0x0A, 0x20,
8341 0x02, 0x20,
8342
8343 0x0F, 0xCF, 0x75, 0xC0,
8344 0x2A, 0x20,
8345 0x1A, 0x20,
8346
8347 0x30, 0x50, 0x2E, 0x9F,
8348 0x32, 0x31, 0x5F, 0xE9,
8349
8350 0x38, 0x21, 0x2C, 0x9F,
8351 0x33, 0x39, 0x5F, 0xE9,
8352
8353 0x3D, 0xCF, 0x75, 0xC2,
8354 0x37, 0xCF, 0x75, 0xC4,
8355
8356 0x31, 0x53, 0x2F, 0x9F,
8357 0xA6, 0x0F, 0x20, 0xE9,
8358
8359 0x39, 0xE5, 0x2C, 0x9F,
8360 0xA3, 0x3D, 0x20, 0xE9,
8361
8362 0x2A, 0x44, 0x54, 0xB4,
8363 0x1A, 0x44, 0x64, 0xB4,
8364
8365 0x0A, 0x45, 0x55, 0xB0,
8366 0x02, 0x45, 0x65, 0xB0,
8367
8368 0x88, 0x73, 0x5E, 0xE9,
8369 0x2A, 0x20,
8370 0x1A, 0x20,
8371
8372 0xA0, 0x37, 0x20, 0xE9,
8373 0x0A, 0x20,
8374 0x02, 0x20,
8375
8376 0x31, 0x53, 0x2F, 0x9F,
8377 0x3E, 0x30, 0x4F, 0xE9,
8378
8379 0x39, 0xE5, 0x2C, 0x9F,
8380 0x3F, 0x38, 0x4F, 0xE9,
8381
8382 0x30, 0x50, 0x2E, 0x9F,
8383 0x3A, 0x31, 0x4F, 0xE9,
8384
8385 0x38, 0x21, 0x2C, 0x9F,
8386 0x3B, 0x39, 0x4F, 0xE9,
8387
8388 0x2A, 0x45, 0x55, 0xB2,
8389 0x1A, 0x45, 0x65, 0xB2,
8390
8391 0x0A, 0x45, 0x55, 0xB4,
8392 0x02, 0x45, 0x65, 0xB4,
8393
8394 0x0F, 0xCF, 0x75, 0xC6,
8395 0x2A, 0x20,
8396 0x1A, 0x20,
8397
8398 0xA7, 0x30, 0x4F, 0xE9,
8399 0x0A, 0x20,
8400 0x02, 0x20,
8401
8402 0x31, 0x53, 0x2F, 0x9F,
8403 0x31, 0x0F, 0x20, 0xE9,
8404
8405 0x39, 0xE5, 0x2C, 0x9F,
8406 0xA8, 0x38, 0x4F, 0xE9,
8407
8408 0x2A, 0x45, 0x55, 0xB6,
8409 0x1A, 0x45, 0x65, 0xB6,
8410
8411 0x30, 0x50, 0x2E, 0x9F,
8412 0x36, 0x31, 0x4F, 0xE9,
8413
8414 0x38, 0x21, 0x2C, 0x9F,
8415 0x37, 0x39, 0x4F, 0xE9,
8416
8417 0x00, 0x80, 0x00, 0xE8,
8418 0x2A, 0x20,
8419 0x1A, 0x20,
8420
8421 0x2A, 0x46, 0x56, 0xBF,
8422 0x1A, 0x46, 0x66, 0xBF,
8423
8424 0x31, 0x53, 0x2F, 0x9F,
8425 0xA4, 0x31, 0x4F, 0xE9,
8426
8427 0x39, 0xE5, 0x2C, 0x9F,
8428 0xA5, 0x39, 0x4F, 0xE9,
8429
8430 0x0A, 0x47, 0x57, 0xBF,
8431 0x02, 0x47, 0x67, 0xBF,
8432
8433 0x31, 0x53, 0x2F, 0x9F,
8434 0xA1, 0x30, 0x4F, 0xE9,
8435
8436 0x39, 0xE5, 0x2C, 0x9F,
8437 0xA2, 0x38, 0x4F, 0xE9,
8438
8439 0x2A, 0x43, 0x53, 0xBF,
8440 0x1A, 0x43, 0x63, 0xBF,
8441
8442 0x30, 0x50, 0x2E, 0x9F,
8443 0x35, 0x31, 0x4F, 0xE9,
8444
8445 0x38, 0x21, 0x2C, 0x9F,
8446 0x39, 0x39, 0x4F, 0xE9,
8447
8448 0x0A, 0x48, 0x58, 0xBF,
8449 0x02, 0x48, 0x68, 0xBF,
8450
8451 0x31, 0x53, 0x2F, 0x9F,
8452 0x80, 0x31, 0x57, 0xE9,
8453
8454 0x39, 0xE5, 0x2C, 0x9F,
8455 0x81, 0x39, 0x57, 0xE9,
8456
8457 0x2A, 0x49, 0x59, 0xBF,
8458 0x1A, 0x49, 0x69, 0xBF,
8459
8460 0x30, 0x50, 0x2E, 0x9F,
8461 0x82, 0x30, 0x57, 0xE9,
8462
8463 0x38, 0x21, 0x2C, 0x9F,
8464 0x83, 0x38, 0x57, 0xE9,
8465
8466 0x31, 0x53, 0x2F, 0x9F,
8467 0x84, 0x31, 0x5E, 0xE9,
8468
8469 0x39, 0xE5, 0x2C, 0x9F,
8470 0x85, 0x39, 0x5E, 0xE9,
8471
8472 0x86, 0x76, 0x57, 0xE9,
8473 0x8A, 0x36, 0x20, 0xE9,
8474
8475 0x87, 0x77, 0x57, 0xE9,
8476 0x8B, 0x3E, 0xBF, 0xEA,
8477
8478 0x80, 0x30, 0x57, 0xE9,
8479 0x81, 0x38, 0x57, 0xE9,
8480
8481 0x82, 0x31, 0x57, 0xE9,
8482 0x86, 0x78, 0x57, 0xE9,
8483
8484 0x83, 0x39, 0x57, 0xE9,
8485 0x87, 0x79, 0x57, 0xE9,
8486
8487 0x30, 0x1F, 0x5F, 0xE9,
8488 0x8A, 0x34, 0x20, 0xE9,
8489
8490 0x8B, 0x3C, 0x20, 0xE9,
8491 0x37, 0x50, 0x60, 0xBD,
8492
8493 0x57, 0x0D, 0x20, 0xE9,
8494 0x35, 0x51, 0x61, 0xBD,
8495
8496 0x2B, 0x50, 0x20, 0xE9,
8497 0x1D, 0x37, 0xE1, 0xEA,
8498
8499 0x1E, 0x35, 0xE1, 0xEA,
8500 0x00, 0xE0,
8501 0x0E, 0x77,
8502
8503 0x24, 0x51, 0x20, 0xE9,
8504 0x8D, 0xFF, 0x20, 0xEA,
8505
8506 0x16, 0x0E, 0x20, 0xE9,
8507 0x57, 0x2E, 0xBF, 0xEA,
8508
8509 0x0B, 0x46, 0xA0, 0xE8,
8510 0x1B, 0x56, 0xA0, 0xE8,
8511
8512 0x2B, 0x66, 0xA0, 0xE8,
8513 0x0C, 0x47, 0xA0, 0xE8,
8514
8515 0x1C, 0x57, 0xA0, 0xE8,
8516 0x2C, 0x67, 0xA0, 0xE8,
8517
8518 0x0B, 0x00,
8519 0x1B, 0x00,
8520 0x2B, 0x00,
8521 0x00, 0xE0,
8522
8523 0x0C, 0x00,
8524 0x1C, 0x00,
8525 0x2C, 0x00,
8526 0x00, 0xE0,
8527
8528 0x0B, 0x65,
8529 0x1B, 0x65,
8530 0x2B, 0x65,
8531 0x00, 0xE0,
8532
8533 0x0C, 0x65,
8534 0x1C, 0x65,
8535 0x2C, 0x65,
8536 0x00, 0xE0,
8537
8538 0x0B, 0x1B, 0x60, 0xEC,
8539 0x36, 0xD7, 0x36, 0xAD,
8540
8541 0x2B, 0x80, 0x60, 0xEC,
8542 0x0C, 0x1C, 0x60, 0xEC,
8543
8544 0x3E, 0xD7, 0x3E, 0xAD,
8545 0x2C, 0x80, 0x60, 0xEC,
8546
8547 0x0B, 0x2B, 0xDE, 0xE8,
8548 0x1B, 0x80, 0xDE, 0xE8,
8549
8550 0x36, 0x80, 0x36, 0xBD,
8551 0x3E, 0x80, 0x3E, 0xBD,
8552
8553 0x33, 0xD7, 0x0B, 0xBD,
8554 0x3B, 0xD7, 0x1B, 0xBD,
8555
8556 0x46, 0x80, 0x46, 0xCF,
8557 0x57, 0x80, 0x57, 0xCF,
8558
8559 0x66, 0x33, 0x66, 0xCF,
8560 0x47, 0x3B, 0x47, 0xCF,
8561
8562 0x56, 0x33, 0x56, 0xCF,
8563 0x67, 0x3B, 0x67, 0xCF,
8564
8565 0x0B, 0x48, 0xA0, 0xE8,
8566 0x1B, 0x58, 0xA0, 0xE8,
8567
8568 0x2B, 0x68, 0xA0, 0xE8,
8569 0x0C, 0x49, 0xA0, 0xE8,
8570
8571 0x1C, 0x59, 0xA0, 0xE8,
8572 0x2C, 0x69, 0xA0, 0xE8,
8573
8574 0x0B, 0x00,
8575 0x1B, 0x00,
8576 0x2B, 0x00,
8577 0x00, 0xE0,
8578
8579 0x0C, 0x00,
8580 0x1C, 0x00,
8581 0x2C, 0x00,
8582 0x00, 0xE0,
8583
8584 0x0B, 0x65,
8585 0x1B, 0x65,
8586 0x2B, 0x65,
8587 0x00, 0xE0,
8588
8589 0x0C, 0x65,
8590 0x1C, 0x65,
8591 0x2C, 0x65,
8592 0x00, 0xE0,
8593
8594 0x0B, 0x1B, 0x60, 0xEC,
8595 0x34, 0xD7, 0x34, 0xAD,
8596
8597 0x2B, 0x80, 0x60, 0xEC,
8598 0x0C, 0x1C, 0x60, 0xEC,
8599
8600 0x3C, 0xD7, 0x3C, 0xAD,
8601 0x2C, 0x80, 0x60, 0xEC,
8602
8603 0x0B, 0x2B, 0xDE, 0xE8,
8604 0x1B, 0x80, 0xDE, 0xE8,
8605
8606 0x34, 0x80, 0x34, 0xBD,
8607 0x3C, 0x80, 0x3C, 0xBD,
8608
8609 0x33, 0xD7, 0x0B, 0xBD,
8610 0x3B, 0xD7, 0x1B, 0xBD,
8611
8612 0x48, 0x80, 0x48, 0xCF,
8613 0x59, 0x80, 0x59, 0xCF,
8614
8615 0x68, 0x33, 0x68, 0xCF,
8616 0x49, 0x3B, 0x49, 0xCF,
8617
8618 0xAD, 0xFF, 0x20, 0xEA,
8619 0x00, 0x80, 0x00, 0xE8,
8620
8621 0x58, 0x33, 0x58, 0xCF,
8622 0x69, 0x3B, 0x69, 0xCF,
8623
8624 0x6B, 0xFF, 0x20, 0xEA,
8625 0x57, 0xC0, 0xBF, 0xEA,
8626
8627 0x00, 0x80, 0xA0, 0xE9,
8628 0x00, 0x00, 0xD8, 0xEC,
8629
8630};
8631
8632static unsigned char warp_g400_tgz[] = {
8633
8634 0x00, 0x88, 0x98, 0xE9,
8635 0x00, 0x80, 0x00, 0xE8,
8636
8637 0x00, 0x80, 0xA0, 0xE9,
8638 0x00, 0x00, 0xD8, 0xEC,
8639
8640 0xFF, 0x80, 0xC0, 0xE9,
8641 0x00, 0x80, 0x00, 0xE8,
8642
8643 0x22, 0x40, 0x48, 0xBF,
8644 0x2A, 0x40, 0x50, 0xBF,
8645
8646 0x32, 0x41, 0x49, 0xBF,
8647 0x3A, 0x41, 0x51, 0xBF,
8648
8649 0xC3, 0x6B,
8650 0xCB, 0x6B,
8651 0x00, 0x88, 0x98, 0xE9,
8652
8653 0x73, 0x7B, 0xC8, 0xEC,
8654 0x96, 0xE2,
8655 0x41, 0x04,
8656
8657 0x7B, 0x43, 0xA0, 0xE8,
8658 0x73, 0x4B, 0xA0, 0xE8,
8659
8660 0xAD, 0xEE, 0x29, 0x9F,
8661 0x00, 0xE0,
8662 0x49, 0x04,
8663
8664 0x90, 0xE2,
8665 0x51, 0x04,
8666 0x31, 0x46, 0xB1, 0xE8,
8667
8668 0x49, 0x41, 0xC0, 0xEC,
8669 0x39, 0x57, 0xB1, 0xE8,
8670
8671 0x00, 0x04,
8672 0x46, 0xE2,
8673 0x73, 0x53, 0xA0, 0xE8,
8674
8675 0x51, 0x41, 0xC0, 0xEC,
8676 0x31, 0x00,
8677 0x39, 0x00,
8678
8679 0x58, 0x80, 0x15, 0xEA,
8680 0x08, 0x04,
8681 0x10, 0x04,
8682
8683 0x51, 0x49, 0xC0, 0xEC,
8684 0x2F, 0x41, 0x60, 0xEA,
8685
8686 0x31, 0x20,
8687 0x39, 0x20,
8688 0x1F, 0x42, 0xA0, 0xE8,
8689
8690 0x2A, 0x42, 0x4A, 0xBF,
8691 0x27, 0x4A, 0xA0, 0xE8,
8692
8693 0x1A, 0x42, 0x52, 0xBF,
8694 0x1E, 0x49, 0x60, 0xEA,
8695
8696 0x73, 0x7B, 0xC8, 0xEC,
8697 0x26, 0x51, 0x60, 0xEA,
8698
8699 0x32, 0x40, 0x48, 0xBD,
8700 0x22, 0x40, 0x50, 0xBD,
8701
8702 0x12, 0x41, 0x49, 0xBD,
8703 0x3A, 0x41, 0x51, 0xBD,
8704
8705 0xBF, 0x2F, 0x26, 0xBD,
8706 0x00, 0xE0,
8707 0x7B, 0x72,
8708
8709 0x32, 0x20,
8710 0x22, 0x20,
8711 0x12, 0x20,
8712 0x3A, 0x20,
8713
8714 0x46, 0x31, 0x46, 0xBF,
8715 0x4E, 0x31, 0x4E, 0xBF,
8716
8717 0xB3, 0xE2, 0x2D, 0x9F,
8718 0x00, 0x80, 0x00, 0xE8,
8719
8720 0x56, 0x31, 0x56, 0xBF,
8721 0x47, 0x39, 0x47, 0xBF,
8722
8723 0x4F, 0x39, 0x4F, 0xBF,
8724 0x57, 0x39, 0x57, 0xBF,
8725
8726 0x4A, 0x80, 0x07, 0xEA,
8727 0x24, 0x41, 0x20, 0xE9,
8728
8729 0x42, 0x73, 0xF8, 0xEC,
8730 0x00, 0xE0,
8731 0x2D, 0x73,
8732
8733 0x33, 0x72,
8734 0x0C, 0xE3,
8735 0xA5, 0x2F, 0x1E, 0xBD,
8736
8737 0x43, 0x43, 0x2D, 0xDF,
8738 0x4B, 0x4B, 0x2D, 0xDF,
8739
8740 0xAE, 0x1E, 0x26, 0xBD,
8741 0x58, 0xE3,
8742 0x33, 0x66,
8743
8744 0x53, 0x53, 0x2D, 0xDF,
8745 0x00, 0x80, 0x00, 0xE8,
8746
8747 0xB8, 0x38, 0x33, 0xBF,
8748 0x00, 0xE0,
8749 0x59, 0xE3,
8750
8751 0x1E, 0x12, 0x41, 0xE9,
8752 0x1A, 0x22, 0x41, 0xE9,
8753
8754 0x2B, 0x40, 0x3D, 0xE9,
8755 0x3F, 0x4B, 0xA0, 0xE8,
8756
8757 0x2D, 0x73,
8758 0x30, 0x76,
8759 0x05, 0x80, 0x3D, 0xEA,
8760
8761 0x37, 0x43, 0xA0, 0xE8,
8762 0x3D, 0x53, 0xA0, 0xE8,
8763
8764 0x48, 0x70, 0xF8, 0xEC,
8765 0x2B, 0x48, 0x3C, 0xE9,
8766
8767 0x1F, 0x27, 0xBC, 0xE8,
8768 0x00, 0x80, 0x00, 0xE8,
8769
8770 0x00, 0x80, 0x00, 0xE8,
8771 0x00, 0x80, 0x00, 0xE8,
8772
8773 0x15, 0xC0, 0x20, 0xE9,
8774 0x15, 0xC0, 0x20, 0xE9,
8775
8776 0x15, 0xC0, 0x20, 0xE9,
8777 0x15, 0xC0, 0x20, 0xE9,
8778
8779 0x18, 0x3A, 0x41, 0xE9,
8780 0x1D, 0x32, 0x41, 0xE9,
8781
8782 0x2A, 0x40, 0x20, 0xE9,
8783 0x56, 0x3D, 0x56, 0xDF,
8784
8785 0x46, 0x37, 0x46, 0xDF,
8786 0x4E, 0x3F, 0x4E, 0xDF,
8787
8788 0x16, 0x30, 0x20, 0xE9,
8789 0x4F, 0x3F, 0x4F, 0xDF,
8790
8791 0x32, 0x32, 0x2D, 0xDF,
8792 0x22, 0x22, 0x2D, 0xDF,
8793
8794 0x12, 0x12, 0x2D, 0xDF,
8795 0x3A, 0x3A, 0x2D, 0xDF,
8796
8797 0x47, 0x37, 0x47, 0xDF,
8798 0x57, 0x3D, 0x57, 0xDF,
8799
8800 0x3D, 0xCF, 0x74, 0xC0,
8801 0x37, 0xCF, 0x74, 0xC4,
8802
8803 0x31, 0x53, 0x2F, 0x9F,
8804 0x34, 0x80, 0x20, 0xE9,
8805
8806 0x39, 0xE5, 0x2C, 0x9F,
8807 0x3C, 0x3D, 0x20, 0xE9,
8808
8809 0x0A, 0x44, 0x4C, 0xB0,
8810 0x02, 0x44, 0x54, 0xB0,
8811
8812 0x2A, 0x44, 0x4C, 0xB2,
8813 0x1A, 0x44, 0x54, 0xB2,
8814
8815 0x1D, 0x80, 0x3A, 0xEA,
8816 0x0A, 0x20,
8817 0x02, 0x20,
8818
8819 0x3D, 0xCF, 0x74, 0xC2,
8820 0x2A, 0x20,
8821 0x1A, 0x20,
8822
8823 0x30, 0x50, 0x2E, 0x9F,
8824 0x32, 0x31, 0x5F, 0xE9,
8825
8826 0x38, 0x21, 0x2C, 0x9F,
8827 0x33, 0x39, 0x5F, 0xE9,
8828
8829 0x31, 0x53, 0x2F, 0x9F,
8830 0x00, 0x80, 0x00, 0xE8,
8831
8832 0x2A, 0x44, 0x4C, 0xB4,
8833 0x1A, 0x44, 0x54, 0xB4,
8834
8835 0x39, 0xE5, 0x2C, 0x9F,
8836 0x38, 0x3D, 0x20, 0xE9,
8837
8838 0x88, 0x73, 0x5E, 0xE9,
8839 0x2A, 0x20,
8840 0x1A, 0x20,
8841
8842 0x2A, 0x46, 0x4E, 0xBF,
8843 0x1A, 0x46, 0x56, 0xBF,
8844
8845 0x31, 0x53, 0x2F, 0x9F,
8846 0x3E, 0x30, 0x4F, 0xE9,
8847
8848 0x39, 0xE5, 0x2C, 0x9F,
8849 0x3F, 0x38, 0x4F, 0xE9,
8850
8851 0x0A, 0x47, 0x4F, 0xBF,
8852 0x02, 0x47, 0x57, 0xBF,
8853
8854 0x31, 0x53, 0x2F, 0x9F,
8855 0x3A, 0x31, 0x4F, 0xE9,
8856
8857 0x39, 0xE5, 0x2C, 0x9F,
8858 0x3B, 0x39, 0x4F, 0xE9,
8859
8860 0x2A, 0x43, 0x4B, 0xBF,
8861 0x1A, 0x43, 0x53, 0xBF,
8862
8863 0x30, 0x50, 0x2E, 0x9F,
8864 0x36, 0x31, 0x4F, 0xE9,
8865
8866 0x38, 0x21, 0x2C, 0x9F,
8867 0x37, 0x39, 0x4F, 0xE9,
8868
8869 0x31, 0x53, 0x2F, 0x9F,
8870 0x80, 0x31, 0x57, 0xE9,
8871
8872 0x39, 0xE5, 0x2C, 0x9F,
8873 0x81, 0x39, 0x57, 0xE9,
8874
8875 0x37, 0x48, 0x50, 0xBD,
8876 0x8A, 0x36, 0x20, 0xE9,
8877
8878 0x86, 0x76, 0x57, 0xE9,
8879 0x8B, 0x3E, 0x20, 0xE9,
8880
8881 0x82, 0x30, 0x57, 0xE9,
8882 0x87, 0x77, 0x57, 0xE9,
8883
8884 0x83, 0x38, 0x57, 0xE9,
8885 0x35, 0x49, 0x51, 0xBD,
8886
8887 0x84, 0x31, 0x5E, 0xE9,
8888 0x30, 0x1F, 0x5F, 0xE9,
8889
8890 0x85, 0x39, 0x5E, 0xE9,
8891 0x57, 0x25, 0x20, 0xE9,
8892
8893 0x2B, 0x48, 0x20, 0xE9,
8894 0x1D, 0x37, 0xE1, 0xEA,
8895
8896 0x1E, 0x35, 0xE1, 0xEA,
8897 0x00, 0xE0,
8898 0x26, 0x77,
8899
8900 0x24, 0x49, 0x20, 0xE9,
8901 0xAF, 0xFF, 0x20, 0xEA,
8902
8903 0x16, 0x26, 0x20, 0xE9,
8904 0x57, 0x2E, 0xBF, 0xEA,
8905
8906 0x1C, 0x46, 0xA0, 0xE8,
8907 0x23, 0x4E, 0xA0, 0xE8,
8908
8909 0x2B, 0x56, 0xA0, 0xE8,
8910 0x1D, 0x47, 0xA0, 0xE8,
8911
8912 0x24, 0x4F, 0xA0, 0xE8,
8913 0x2C, 0x57, 0xA0, 0xE8,
8914
8915 0x1C, 0x00,
8916 0x23, 0x00,
8917 0x2B, 0x00,
8918 0x00, 0xE0,
8919
8920 0x1D, 0x00,
8921 0x24, 0x00,
8922 0x2C, 0x00,
8923 0x00, 0xE0,
8924
8925 0x1C, 0x65,
8926 0x23, 0x65,
8927 0x2B, 0x65,
8928 0x00, 0xE0,
8929
8930 0x1D, 0x65,
8931 0x24, 0x65,
8932 0x2C, 0x65,
8933 0x00, 0xE0,
8934
8935 0x1C, 0x23, 0x60, 0xEC,
8936 0x36, 0xD7, 0x36, 0xAD,
8937
8938 0x2B, 0x80, 0x60, 0xEC,
8939 0x1D, 0x24, 0x60, 0xEC,
8940
8941 0x3E, 0xD7, 0x3E, 0xAD,
8942 0x2C, 0x80, 0x60, 0xEC,
8943
8944 0x1C, 0x2B, 0xDE, 0xE8,
8945 0x23, 0x80, 0xDE, 0xE8,
8946
8947 0x36, 0x80, 0x36, 0xBD,
8948 0x3E, 0x80, 0x3E, 0xBD,
8949
8950 0x33, 0xD7, 0x1C, 0xBD,
8951 0x3B, 0xD7, 0x23, 0xBD,
8952
8953 0x46, 0x80, 0x46, 0xCF,
8954 0x4F, 0x80, 0x4F, 0xCF,
8955
8956 0x56, 0x33, 0x56, 0xCF,
8957 0x47, 0x3B, 0x47, 0xCF,
8958
8959 0xD6, 0xFF, 0x20, 0xEA,
8960 0x00, 0x80, 0x00, 0xE8,
8961
8962 0x4E, 0x33, 0x4E, 0xCF,
8963 0x57, 0x3B, 0x57, 0xCF,
8964
8965 0x9D, 0xFF, 0x20, 0xEA,
8966 0x57, 0xC0, 0xBF, 0xEA,
8967
8968 0x00, 0x80, 0xA0, 0xE9,
8969 0x00, 0x00, 0xD8, 0xEC,
8970
8971};
8972
8973static unsigned char warp_g400_tgza[] = {
8974
8975 0x00, 0x88, 0x98, 0xE9,
8976 0x00, 0x80, 0x00, 0xE8,
8977
8978 0x00, 0x80, 0xA0, 0xE9,
8979 0x00, 0x00, 0xD8, 0xEC,
8980
8981 0xFF, 0x80, 0xC0, 0xE9,
8982 0x00, 0x80, 0x00, 0xE8,
8983
8984 0x22, 0x40, 0x48, 0xBF,
8985 0x2A, 0x40, 0x50, 0xBF,
8986
8987 0x32, 0x41, 0x49, 0xBF,
8988 0x3A, 0x41, 0x51, 0xBF,
8989
8990 0xC3, 0x6B,
8991 0xCB, 0x6B,
8992 0x00, 0x88, 0x98, 0xE9,
8993
8994 0x73, 0x7B, 0xC8, 0xEC,
8995 0x96, 0xE2,
8996 0x41, 0x04,
8997
8998 0x7B, 0x43, 0xA0, 0xE8,
8999 0x73, 0x4B, 0xA0, 0xE8,
9000
9001 0xAD, 0xEE, 0x29, 0x9F,
9002 0x00, 0xE0,
9003 0x49, 0x04,
9004
9005 0x90, 0xE2,
9006 0x51, 0x04,
9007 0x31, 0x46, 0xB1, 0xE8,
9008
9009 0x49, 0x41, 0xC0, 0xEC,
9010 0x39, 0x57, 0xB1, 0xE8,
9011
9012 0x00, 0x04,
9013 0x46, 0xE2,
9014 0x73, 0x53, 0xA0, 0xE8,
9015
9016 0x51, 0x41, 0xC0, 0xEC,
9017 0x31, 0x00,
9018 0x39, 0x00,
9019
9020 0x5C, 0x80, 0x15, 0xEA,
9021 0x08, 0x04,
9022 0x10, 0x04,
9023
9024 0x51, 0x49, 0xC0, 0xEC,
9025 0x2F, 0x41, 0x60, 0xEA,
9026
9027 0x31, 0x20,
9028 0x39, 0x20,
9029 0x1F, 0x42, 0xA0, 0xE8,
9030
9031 0x2A, 0x42, 0x4A, 0xBF,
9032 0x27, 0x4A, 0xA0, 0xE8,
9033
9034 0x1A, 0x42, 0x52, 0xBF,
9035 0x1E, 0x49, 0x60, 0xEA,
9036
9037 0x73, 0x7B, 0xC8, 0xEC,
9038 0x26, 0x51, 0x60, 0xEA,
9039
9040 0x32, 0x40, 0x48, 0xBD,
9041 0x22, 0x40, 0x50, 0xBD,
9042
9043 0x12, 0x41, 0x49, 0xBD,
9044 0x3A, 0x41, 0x51, 0xBD,
9045
9046 0xBF, 0x2F, 0x26, 0xBD,
9047 0x00, 0xE0,
9048 0x7B, 0x72,
9049
9050 0x32, 0x20,
9051 0x22, 0x20,
9052 0x12, 0x20,
9053 0x3A, 0x20,
9054
9055 0x46, 0x31, 0x46, 0xBF,
9056 0x4E, 0x31, 0x4E, 0xBF,
9057
9058 0xB3, 0xE2, 0x2D, 0x9F,
9059 0x00, 0x80, 0x00, 0xE8,
9060
9061 0x56, 0x31, 0x56, 0xBF,
9062 0x47, 0x39, 0x47, 0xBF,
9063
9064 0x4F, 0x39, 0x4F, 0xBF,
9065 0x57, 0x39, 0x57, 0xBF,
9066
9067 0x4E, 0x80, 0x07, 0xEA,
9068 0x24, 0x41, 0x20, 0xE9,
9069
9070 0x42, 0x73, 0xF8, 0xEC,
9071 0x00, 0xE0,
9072 0x2D, 0x73,
9073
9074 0x33, 0x72,
9075 0x0C, 0xE3,
9076 0xA5, 0x2F, 0x1E, 0xBD,
9077
9078 0x43, 0x43, 0x2D, 0xDF,
9079 0x4B, 0x4B, 0x2D, 0xDF,
9080
9081 0xAE, 0x1E, 0x26, 0xBD,
9082 0x58, 0xE3,
9083 0x33, 0x66,
9084
9085 0x53, 0x53, 0x2D, 0xDF,
9086 0x00, 0x80, 0x00, 0xE8,
9087
9088 0xB8, 0x38, 0x33, 0xBF,
9089 0x00, 0xE0,
9090 0x59, 0xE3,
9091
9092 0x1E, 0x12, 0x41, 0xE9,
9093 0x1A, 0x22, 0x41, 0xE9,
9094
9095 0x2B, 0x40, 0x3D, 0xE9,
9096 0x3F, 0x4B, 0xA0, 0xE8,
9097
9098 0x2D, 0x73,
9099 0x30, 0x76,
9100 0x05, 0x80, 0x3D, 0xEA,
9101
9102 0x37, 0x43, 0xA0, 0xE8,
9103 0x3D, 0x53, 0xA0, 0xE8,
9104
9105 0x48, 0x70, 0xF8, 0xEC,
9106 0x2B, 0x48, 0x3C, 0xE9,
9107
9108 0x1F, 0x27, 0xBC, 0xE8,
9109 0x00, 0x80, 0x00, 0xE8,
9110
9111 0x00, 0x80, 0x00, 0xE8,
9112 0x00, 0x80, 0x00, 0xE8,
9113
9114 0x15, 0xC0, 0x20, 0xE9,
9115 0x15, 0xC0, 0x20, 0xE9,
9116
9117 0x15, 0xC0, 0x20, 0xE9,
9118 0x15, 0xC0, 0x20, 0xE9,
9119
9120 0x18, 0x3A, 0x41, 0xE9,
9121 0x1D, 0x32, 0x41, 0xE9,
9122
9123 0x2A, 0x40, 0x20, 0xE9,
9124 0x56, 0x3D, 0x56, 0xDF,
9125
9126 0x46, 0x37, 0x46, 0xDF,
9127 0x4E, 0x3F, 0x4E, 0xDF,
9128
9129 0x16, 0x30, 0x20, 0xE9,
9130 0x4F, 0x3F, 0x4F, 0xDF,
9131
9132 0x32, 0x32, 0x2D, 0xDF,
9133 0x22, 0x22, 0x2D, 0xDF,
9134
9135 0x12, 0x12, 0x2D, 0xDF,
9136 0x3A, 0x3A, 0x2D, 0xDF,
9137
9138 0x47, 0x37, 0x47, 0xDF,
9139 0x57, 0x3D, 0x57, 0xDF,
9140
9141 0x3D, 0xCF, 0x74, 0xC0,
9142 0x37, 0xCF, 0x74, 0xC4,
9143
9144 0x31, 0x53, 0x2F, 0x9F,
9145 0x34, 0x80, 0x20, 0xE9,
9146
9147 0x39, 0xE5, 0x2C, 0x9F,
9148 0x3C, 0x3D, 0x20, 0xE9,
9149
9150 0x27, 0xCF, 0x74, 0xC6,
9151 0x3D, 0xCF, 0x74, 0xC2,
9152
9153 0x0A, 0x44, 0x4C, 0xB0,
9154 0x02, 0x44, 0x54, 0xB0,
9155
9156 0x2A, 0x44, 0x4C, 0xB2,
9157 0x1A, 0x44, 0x54, 0xB2,
9158
9159 0x20, 0x80, 0x3A, 0xEA,
9160 0x0A, 0x20,
9161 0x02, 0x20,
9162
9163 0x88, 0x73, 0x5E, 0xE9,
9164 0x2A, 0x20,
9165 0x1A, 0x20,
9166
9167 0x30, 0x50, 0x2E, 0x9F,
9168 0x32, 0x31, 0x5F, 0xE9,
9169
9170 0x38, 0x21, 0x2C, 0x9F,
9171 0x33, 0x39, 0x5F, 0xE9,
9172
9173 0x31, 0x53, 0x2F, 0x9F,
9174 0x9C, 0x27, 0x20, 0xE9,
9175
9176 0x0A, 0x44, 0x4C, 0xB4,
9177 0x02, 0x44, 0x54, 0xB4,
9178
9179 0x2A, 0x44, 0x4C, 0xB6,
9180 0x1A, 0x44, 0x54, 0xB6,
9181
9182 0x39, 0xE5, 0x2C, 0x9F,
9183 0x38, 0x3D, 0x20, 0xE9,
9184
9185 0x0A, 0x20,
9186 0x02, 0x20,
9187 0x2A, 0x20,
9188 0x1A, 0x20,
9189
9190 0x0A, 0x47, 0x4F, 0xBF,
9191 0x02, 0x47, 0x57, 0xBF,
9192
9193 0x30, 0x50, 0x2E, 0x9F,
9194 0x3E, 0x30, 0x4F, 0xE9,
9195
9196 0x38, 0x21, 0x2C, 0x9F,
9197 0x3F, 0x38, 0x4F, 0xE9,
9198
9199 0x2A, 0x46, 0x4E, 0xBF,
9200 0x1A, 0x46, 0x56, 0xBF,
9201
9202 0x31, 0x53, 0x2F, 0x9F,
9203 0x3A, 0x31, 0x4F, 0xE9,
9204
9205 0x39, 0xE5, 0x2C, 0x9F,
9206 0x3B, 0x39, 0x4F, 0xE9,
9207
9208 0x31, 0x53, 0x2F, 0x9F,
9209 0x36, 0x30, 0x4F, 0xE9,
9210
9211 0x39, 0xE5, 0x2C, 0x9F,
9212 0x37, 0x38, 0x4F, 0xE9,
9213
9214 0x2A, 0x43, 0x4B, 0xBF,
9215 0x1A, 0x43, 0x53, 0xBF,
9216
9217 0x30, 0x50, 0x2E, 0x9F,
9218 0x9D, 0x31, 0x4F, 0xE9,
9219
9220 0x38, 0x21, 0x2C, 0x9F,
9221 0x9E, 0x39, 0x4F, 0xE9,
9222
9223 0x31, 0x53, 0x2F, 0x9F,
9224 0x80, 0x31, 0x57, 0xE9,
9225
9226 0x39, 0xE5, 0x2C, 0x9F,
9227 0x81, 0x39, 0x57, 0xE9,
9228
9229 0x37, 0x48, 0x50, 0xBD,
9230 0x8A, 0x36, 0x20, 0xE9,
9231
9232 0x86, 0x76, 0x57, 0xE9,
9233 0x8B, 0x3E, 0x20, 0xE9,
9234
9235 0x82, 0x30, 0x57, 0xE9,
9236 0x87, 0x77, 0x57, 0xE9,
9237
9238 0x83, 0x38, 0x57, 0xE9,
9239 0x35, 0x49, 0x51, 0xBD,
9240
9241 0x84, 0x31, 0x5E, 0xE9,
9242 0x30, 0x1F, 0x5F, 0xE9,
9243
9244 0x85, 0x39, 0x5E, 0xE9,
9245 0x57, 0x25, 0x20, 0xE9,
9246
9247 0x2B, 0x48, 0x20, 0xE9,
9248 0x1D, 0x37, 0xE1, 0xEA,
9249
9250 0x1E, 0x35, 0xE1, 0xEA,
9251 0x00, 0xE0,
9252 0x26, 0x77,
9253
9254 0x24, 0x49, 0x20, 0xE9,
9255 0xAB, 0xFF, 0x20, 0xEA,
9256
9257 0x16, 0x26, 0x20, 0xE9,
9258 0x57, 0x2E, 0xBF, 0xEA,
9259
9260 0x1C, 0x46, 0xA0, 0xE8,
9261 0x23, 0x4E, 0xA0, 0xE8,
9262
9263 0x2B, 0x56, 0xA0, 0xE8,
9264 0x1D, 0x47, 0xA0, 0xE8,
9265
9266 0x24, 0x4F, 0xA0, 0xE8,
9267 0x2C, 0x57, 0xA0, 0xE8,
9268
9269 0x1C, 0x00,
9270 0x23, 0x00,
9271 0x2B, 0x00,
9272 0x00, 0xE0,
9273
9274 0x1D, 0x00,
9275 0x24, 0x00,
9276 0x2C, 0x00,
9277 0x00, 0xE0,
9278
9279 0x1C, 0x65,
9280 0x23, 0x65,
9281 0x2B, 0x65,
9282 0x00, 0xE0,
9283
9284 0x1D, 0x65,
9285 0x24, 0x65,
9286 0x2C, 0x65,
9287 0x00, 0xE0,
9288
9289 0x1C, 0x23, 0x60, 0xEC,
9290 0x36, 0xD7, 0x36, 0xAD,
9291
9292 0x2B, 0x80, 0x60, 0xEC,
9293 0x1D, 0x24, 0x60, 0xEC,
9294
9295 0x3E, 0xD7, 0x3E, 0xAD,
9296 0x2C, 0x80, 0x60, 0xEC,
9297
9298 0x1C, 0x2B, 0xDE, 0xE8,
9299 0x23, 0x80, 0xDE, 0xE8,
9300
9301 0x36, 0x80, 0x36, 0xBD,
9302 0x3E, 0x80, 0x3E, 0xBD,
9303
9304 0x33, 0xD7, 0x1C, 0xBD,
9305 0x3B, 0xD7, 0x23, 0xBD,
9306
9307 0x46, 0x80, 0x46, 0xCF,
9308 0x4F, 0x80, 0x4F, 0xCF,
9309
9310 0x56, 0x33, 0x56, 0xCF,
9311 0x47, 0x3B, 0x47, 0xCF,
9312
9313 0xD3, 0xFF, 0x20, 0xEA,
9314 0x00, 0x80, 0x00, 0xE8,
9315
9316 0x4E, 0x33, 0x4E, 0xCF,
9317 0x57, 0x3B, 0x57, 0xCF,
9318
9319 0x99, 0xFF, 0x20, 0xEA,
9320 0x57, 0xC0, 0xBF, 0xEA,
9321
9322 0x00, 0x80, 0xA0, 0xE9,
9323 0x00, 0x00, 0xD8, 0xEC,
9324
9325};
9326
9327static unsigned char warp_g400_tgzaf[] = {
9328
9329 0x00, 0x88, 0x98, 0xE9,
9330 0x00, 0x80, 0x00, 0xE8,
9331
9332 0x00, 0x80, 0xA0, 0xE9,
9333 0x00, 0x00, 0xD8, 0xEC,
9334
9335 0xFF, 0x80, 0xC0, 0xE9,
9336 0x00, 0x80, 0x00, 0xE8,
9337
9338 0x22, 0x40, 0x48, 0xBF,
9339 0x2A, 0x40, 0x50, 0xBF,
9340
9341 0x32, 0x41, 0x49, 0xBF,
9342 0x3A, 0x41, 0x51, 0xBF,
9343
9344 0xC3, 0x6B,
9345 0xCB, 0x6B,
9346 0x00, 0x88, 0x98, 0xE9,
9347
9348 0x73, 0x7B, 0xC8, 0xEC,
9349 0x96, 0xE2,
9350 0x41, 0x04,
9351
9352 0x7B, 0x43, 0xA0, 0xE8,
9353 0x73, 0x4B, 0xA0, 0xE8,
9354
9355 0xAD, 0xEE, 0x29, 0x9F,
9356 0x00, 0xE0,
9357 0x49, 0x04,
9358
9359 0x90, 0xE2,
9360 0x51, 0x04,
9361 0x31, 0x46, 0xB1, 0xE8,
9362
9363 0x49, 0x41, 0xC0, 0xEC,
9364 0x39, 0x57, 0xB1, 0xE8,
9365
9366 0x00, 0x04,
9367 0x46, 0xE2,
9368 0x73, 0x53, 0xA0, 0xE8,
9369
9370 0x51, 0x41, 0xC0, 0xEC,
9371 0x31, 0x00,
9372 0x39, 0x00,
9373
9374 0x61, 0x80, 0x15, 0xEA,
9375 0x08, 0x04,
9376 0x10, 0x04,
9377
9378 0x51, 0x49, 0xC0, 0xEC,
9379 0x2F, 0x41, 0x60, 0xEA,
9380
9381 0x31, 0x20,
9382 0x39, 0x20,
9383 0x1F, 0x42, 0xA0, 0xE8,
9384
9385 0x2A, 0x42, 0x4A, 0xBF,
9386 0x27, 0x4A, 0xA0, 0xE8,
9387
9388 0x1A, 0x42, 0x52, 0xBF,
9389 0x1E, 0x49, 0x60, 0xEA,
9390
9391 0x73, 0x7B, 0xC8, 0xEC,
9392 0x26, 0x51, 0x60, 0xEA,
9393
9394 0x32, 0x40, 0x48, 0xBD,
9395 0x22, 0x40, 0x50, 0xBD,
9396
9397 0x12, 0x41, 0x49, 0xBD,
9398 0x3A, 0x41, 0x51, 0xBD,
9399
9400 0xBF, 0x2F, 0x26, 0xBD,
9401 0x00, 0xE0,
9402 0x7B, 0x72,
9403
9404 0x32, 0x20,
9405 0x22, 0x20,
9406 0x12, 0x20,
9407 0x3A, 0x20,
9408
9409 0x46, 0x31, 0x46, 0xBF,
9410 0x4E, 0x31, 0x4E, 0xBF,
9411
9412 0xB3, 0xE2, 0x2D, 0x9F,
9413 0x00, 0x80, 0x00, 0xE8,
9414
9415 0x56, 0x31, 0x56, 0xBF,
9416 0x47, 0x39, 0x47, 0xBF,
9417
9418 0x4F, 0x39, 0x4F, 0xBF,
9419 0x57, 0x39, 0x57, 0xBF,
9420
9421 0x53, 0x80, 0x07, 0xEA,
9422 0x24, 0x41, 0x20, 0xE9,
9423
9424 0x42, 0x73, 0xF8, 0xEC,
9425 0x00, 0xE0,
9426 0x2D, 0x73,
9427
9428 0x33, 0x72,
9429 0x0C, 0xE3,
9430 0xA5, 0x2F, 0x1E, 0xBD,
9431
9432 0x43, 0x43, 0x2D, 0xDF,
9433 0x4B, 0x4B, 0x2D, 0xDF,
9434
9435 0xAE, 0x1E, 0x26, 0xBD,
9436 0x58, 0xE3,
9437 0x33, 0x66,
9438
9439 0x53, 0x53, 0x2D, 0xDF,
9440 0x00, 0x80, 0x00, 0xE8,
9441
9442 0xB8, 0x38, 0x33, 0xBF,
9443 0x00, 0xE0,
9444 0x59, 0xE3,
9445
9446 0x1E, 0x12, 0x41, 0xE9,
9447 0x1A, 0x22, 0x41, 0xE9,
9448
9449 0x2B, 0x40, 0x3D, 0xE9,
9450 0x3F, 0x4B, 0xA0, 0xE8,
9451
9452 0x2D, 0x73,
9453 0x30, 0x76,
9454 0x05, 0x80, 0x3D, 0xEA,
9455
9456 0x37, 0x43, 0xA0, 0xE8,
9457 0x3D, 0x53, 0xA0, 0xE8,
9458
9459 0x48, 0x70, 0xF8, 0xEC,
9460 0x2B, 0x48, 0x3C, 0xE9,
9461
9462 0x1F, 0x27, 0xBC, 0xE8,
9463 0x00, 0x80, 0x00, 0xE8,
9464
9465 0x00, 0x80, 0x00, 0xE8,
9466 0x00, 0x80, 0x00, 0xE8,
9467
9468 0x15, 0xC0, 0x20, 0xE9,
9469 0x15, 0xC0, 0x20, 0xE9,
9470
9471 0x15, 0xC0, 0x20, 0xE9,
9472 0x15, 0xC0, 0x20, 0xE9,
9473
9474 0x18, 0x3A, 0x41, 0xE9,
9475 0x1D, 0x32, 0x41, 0xE9,
9476
9477 0x2A, 0x40, 0x20, 0xE9,
9478 0x56, 0x3D, 0x56, 0xDF,
9479
9480 0x46, 0x37, 0x46, 0xDF,
9481 0x4E, 0x3F, 0x4E, 0xDF,
9482
9483 0x16, 0x30, 0x20, 0xE9,
9484 0x4F, 0x3F, 0x4F, 0xDF,
9485
9486 0x32, 0x32, 0x2D, 0xDF,
9487 0x22, 0x22, 0x2D, 0xDF,
9488
9489 0x12, 0x12, 0x2D, 0xDF,
9490 0x3A, 0x3A, 0x2D, 0xDF,
9491
9492 0x47, 0x37, 0x47, 0xDF,
9493 0x57, 0x3D, 0x57, 0xDF,
9494
9495 0x3D, 0xCF, 0x74, 0xC0,
9496 0x37, 0xCF, 0x74, 0xC4,
9497
9498 0x0A, 0x44, 0x4C, 0xB0,
9499 0x02, 0x44, 0x54, 0xB0,
9500
9501 0x31, 0x53, 0x2F, 0x9F,
9502 0x34, 0x37, 0x20, 0xE9,
9503
9504 0x39, 0xE5, 0x2C, 0x9F,
9505 0x3C, 0x3D, 0x20, 0xE9,
9506
9507 0x2A, 0x44, 0x4C, 0xB2,
9508 0x1A, 0x44, 0x54, 0xB2,
9509
9510 0x26, 0x80, 0x3A, 0xEA,
9511 0x0A, 0x20,
9512 0x02, 0x20,
9513
9514 0x88, 0x73, 0x5E, 0xE9,
9515 0x2A, 0x20,
9516 0x1A, 0x20,
9517
9518 0x3D, 0xCF, 0x74, 0xC2,
9519 0x27, 0xCF, 0x74, 0xC6,
9520
9521 0x30, 0x50, 0x2E, 0x9F,
9522 0x32, 0x31, 0x5F, 0xE9,
9523
9524 0x38, 0x21, 0x2C, 0x9F,
9525 0x33, 0x39, 0x5F, 0xE9,
9526
9527 0x31, 0x53, 0x2F, 0x9F,
9528 0x9C, 0x27, 0x20, 0xE9,
9529
9530 0x0A, 0x44, 0x4C, 0xB4,
9531 0x02, 0x44, 0x54, 0xB4,
9532
9533 0x2A, 0x44, 0x4C, 0xB6,
9534 0x1A, 0x44, 0x54, 0xB6,
9535
9536 0x39, 0xE5, 0x2C, 0x9F,
9537 0x38, 0x3D, 0x20, 0xE9,
9538
9539 0x0A, 0x20,
9540 0x02, 0x20,
9541 0x2A, 0x20,
9542 0x1A, 0x20,
9543
9544 0x3D, 0xCF, 0x75, 0xC6,
9545 0x00, 0x80, 0x00, 0xE8,
9546
9547 0x30, 0x50, 0x2E, 0x9F,
9548 0x3E, 0x30, 0x4F, 0xE9,
9549
9550 0x38, 0x21, 0x2C, 0x9F,
9551 0x3F, 0x38, 0x4F, 0xE9,
9552
9553 0x0A, 0x45, 0x4D, 0xB6,
9554 0x02, 0x45, 0x55, 0xB6,
9555
9556 0x31, 0x53, 0x2F, 0x9F,
9557 0x3A, 0x31, 0x4F, 0xE9,
9558
9559 0x39, 0xE5, 0x2C, 0x9F,
9560 0x3B, 0x39, 0x4F, 0xE9,
9561
9562 0x31, 0x3D, 0x20, 0xE9,
9563 0x0A, 0x20,
9564 0x02, 0x20,
9565
9566 0x2A, 0x46, 0x4E, 0xBF,
9567 0x1A, 0x46, 0x56, 0xBF,
9568
9569 0x0A, 0x47, 0x4F, 0xBF,
9570 0x02, 0x47, 0x57, 0xBF,
9571
9572 0x30, 0x50, 0x2E, 0x9F,
9573 0x36, 0x30, 0x4F, 0xE9,
9574
9575 0x38, 0x21, 0x2C, 0x9F,
9576 0x37, 0x38, 0x4F, 0xE9,
9577
9578 0x31, 0x53, 0x2F, 0x9F,
9579 0x9D, 0x31, 0x4F, 0xE9,
9580
9581 0x39, 0xE5, 0x2C, 0x9F,
9582 0x9E, 0x39, 0x4F, 0xE9,
9583
9584 0x2A, 0x43, 0x4B, 0xBF,
9585 0x1A, 0x43, 0x53, 0xBF,
9586
9587 0x30, 0x50, 0x2E, 0x9F,
9588 0x35, 0x30, 0x4F, 0xE9,
9589
9590 0x38, 0x21, 0x2C, 0x9F,
9591 0x39, 0x38, 0x4F, 0xE9,
9592
9593 0x31, 0x53, 0x2F, 0x9F,
9594 0x80, 0x31, 0x57, 0xE9,
9595
9596 0x39, 0xE5, 0x2C, 0x9F,
9597 0x81, 0x39, 0x57, 0xE9,
9598
9599 0x37, 0x48, 0x50, 0xBD,
9600 0x8A, 0x36, 0x20, 0xE9,
9601
9602 0x86, 0x76, 0x57, 0xE9,
9603 0x8B, 0x3E, 0x20, 0xE9,
9604
9605 0x82, 0x30, 0x57, 0xE9,
9606 0x87, 0x77, 0x57, 0xE9,
9607
9608 0x83, 0x38, 0x57, 0xE9,
9609 0x35, 0x49, 0x51, 0xBD,
9610
9611 0x84, 0x31, 0x5E, 0xE9,
9612 0x30, 0x1F, 0x5F, 0xE9,
9613
9614 0x85, 0x39, 0x5E, 0xE9,
9615 0x57, 0x25, 0x20, 0xE9,
9616
9617 0x2B, 0x48, 0x20, 0xE9,
9618 0x1D, 0x37, 0xE1, 0xEA,
9619
9620 0x1E, 0x35, 0xE1, 0xEA,
9621 0x00, 0xE0,
9622 0x26, 0x77,
9623
9624 0x24, 0x49, 0x20, 0xE9,
9625 0xA6, 0xFF, 0x20, 0xEA,
9626
9627 0x16, 0x26, 0x20, 0xE9,
9628 0x57, 0x2E, 0xBF, 0xEA,
9629
9630 0x1C, 0x46, 0xA0, 0xE8,
9631 0x23, 0x4E, 0xA0, 0xE8,
9632
9633 0x2B, 0x56, 0xA0, 0xE8,
9634 0x1D, 0x47, 0xA0, 0xE8,
9635
9636 0x24, 0x4F, 0xA0, 0xE8,
9637 0x2C, 0x57, 0xA0, 0xE8,
9638
9639 0x1C, 0x00,
9640 0x23, 0x00,
9641 0x2B, 0x00,
9642 0x00, 0xE0,
9643
9644 0x1D, 0x00,
9645 0x24, 0x00,
9646 0x2C, 0x00,
9647 0x00, 0xE0,
9648
9649 0x1C, 0x65,
9650 0x23, 0x65,
9651 0x2B, 0x65,
9652 0x00, 0xE0,
9653
9654 0x1D, 0x65,
9655 0x24, 0x65,
9656 0x2C, 0x65,
9657 0x00, 0xE0,
9658
9659 0x1C, 0x23, 0x60, 0xEC,
9660 0x36, 0xD7, 0x36, 0xAD,
9661
9662 0x2B, 0x80, 0x60, 0xEC,
9663 0x1D, 0x24, 0x60, 0xEC,
9664
9665 0x3E, 0xD7, 0x3E, 0xAD,
9666 0x2C, 0x80, 0x60, 0xEC,
9667
9668 0x1C, 0x2B, 0xDE, 0xE8,
9669 0x23, 0x80, 0xDE, 0xE8,
9670
9671 0x36, 0x80, 0x36, 0xBD,
9672 0x3E, 0x80, 0x3E, 0xBD,
9673
9674 0x33, 0xD7, 0x1C, 0xBD,
9675 0x3B, 0xD7, 0x23, 0xBD,
9676
9677 0x46, 0x80, 0x46, 0xCF,
9678 0x4F, 0x80, 0x4F, 0xCF,
9679
9680 0x56, 0x33, 0x56, 0xCF,
9681 0x47, 0x3B, 0x47, 0xCF,
9682
9683 0xCD, 0xFF, 0x20, 0xEA,
9684 0x00, 0x80, 0x00, 0xE8,
9685
9686 0x4E, 0x33, 0x4E, 0xCF,
9687 0x57, 0x3B, 0x57, 0xCF,
9688
9689 0x94, 0xFF, 0x20, 0xEA,
9690 0x57, 0xC0, 0xBF, 0xEA,
9691
9692 0x00, 0x80, 0xA0, 0xE9,
9693 0x00, 0x00, 0xD8, 0xEC,
9694
9695};
9696
9697static unsigned char warp_g400_tgzf[] = {
9698
9699 0x00, 0x88, 0x98, 0xE9,
9700 0x00, 0x80, 0x00, 0xE8,
9701
9702 0x00, 0x80, 0xA0, 0xE9,
9703 0x00, 0x00, 0xD8, 0xEC,
9704
9705 0xFF, 0x80, 0xC0, 0xE9,
9706 0x00, 0x80, 0x00, 0xE8,
9707
9708 0x22, 0x40, 0x48, 0xBF,
9709 0x2A, 0x40, 0x50, 0xBF,
9710
9711 0x32, 0x41, 0x49, 0xBF,
9712 0x3A, 0x41, 0x51, 0xBF,
9713
9714 0xC3, 0x6B,
9715 0xCB, 0x6B,
9716 0x00, 0x88, 0x98, 0xE9,
9717
9718 0x73, 0x7B, 0xC8, 0xEC,
9719 0x96, 0xE2,
9720 0x41, 0x04,
9721
9722 0x7B, 0x43, 0xA0, 0xE8,
9723 0x73, 0x4B, 0xA0, 0xE8,
9724
9725 0xAD, 0xEE, 0x29, 0x9F,
9726 0x00, 0xE0,
9727 0x49, 0x04,
9728
9729 0x90, 0xE2,
9730 0x51, 0x04,
9731 0x31, 0x46, 0xB1, 0xE8,
9732
9733 0x49, 0x41, 0xC0, 0xEC,
9734 0x39, 0x57, 0xB1, 0xE8,
9735
9736 0x00, 0x04,
9737 0x46, 0xE2,
9738 0x73, 0x53, 0xA0, 0xE8,
9739
9740 0x51, 0x41, 0xC0, 0xEC,
9741 0x31, 0x00,
9742 0x39, 0x00,
9743
9744 0x5D, 0x80, 0x15, 0xEA,
9745 0x08, 0x04,
9746 0x10, 0x04,
9747
9748 0x51, 0x49, 0xC0, 0xEC,
9749 0x2F, 0x41, 0x60, 0xEA,
9750
9751 0x31, 0x20,
9752 0x39, 0x20,
9753 0x1F, 0x42, 0xA0, 0xE8,
9754
9755 0x2A, 0x42, 0x4A, 0xBF,
9756 0x27, 0x4A, 0xA0, 0xE8,
9757
9758 0x1A, 0x42, 0x52, 0xBF,
9759 0x1E, 0x49, 0x60, 0xEA,
9760
9761 0x73, 0x7B, 0xC8, 0xEC,
9762 0x26, 0x51, 0x60, 0xEA,
9763
9764 0x32, 0x40, 0x48, 0xBD,
9765 0x22, 0x40, 0x50, 0xBD,
9766
9767 0x12, 0x41, 0x49, 0xBD,
9768 0x3A, 0x41, 0x51, 0xBD,
9769
9770 0xBF, 0x2F, 0x26, 0xBD,
9771 0x00, 0xE0,
9772 0x7B, 0x72,
9773
9774 0x32, 0x20,
9775 0x22, 0x20,
9776 0x12, 0x20,
9777 0x3A, 0x20,
9778
9779 0x46, 0x31, 0x46, 0xBF,
9780 0x4E, 0x31, 0x4E, 0xBF,
9781
9782 0xB3, 0xE2, 0x2D, 0x9F,
9783 0x00, 0x80, 0x00, 0xE8,
9784
9785 0x56, 0x31, 0x56, 0xBF,
9786 0x47, 0x39, 0x47, 0xBF,
9787
9788 0x4F, 0x39, 0x4F, 0xBF,
9789 0x57, 0x39, 0x57, 0xBF,
9790
9791 0x4F, 0x80, 0x07, 0xEA,
9792 0x24, 0x41, 0x20, 0xE9,
9793
9794 0x42, 0x73, 0xF8, 0xEC,
9795 0x00, 0xE0,
9796 0x2D, 0x73,
9797
9798 0x33, 0x72,
9799 0x0C, 0xE3,
9800 0xA5, 0x2F, 0x1E, 0xBD,
9801
9802 0x43, 0x43, 0x2D, 0xDF,
9803 0x4B, 0x4B, 0x2D, 0xDF,
9804
9805 0xAE, 0x1E, 0x26, 0xBD,
9806 0x58, 0xE3,
9807 0x33, 0x66,
9808
9809 0x53, 0x53, 0x2D, 0xDF,
9810 0x00, 0x80, 0x00, 0xE8,
9811
9812 0xB8, 0x38, 0x33, 0xBF,
9813 0x00, 0xE0,
9814 0x59, 0xE3,
9815
9816 0x1E, 0x12, 0x41, 0xE9,
9817 0x1A, 0x22, 0x41, 0xE9,
9818
9819 0x2B, 0x40, 0x3D, 0xE9,
9820 0x3F, 0x4B, 0xA0, 0xE8,
9821
9822 0x2D, 0x73,
9823 0x30, 0x76,
9824 0x05, 0x80, 0x3D, 0xEA,
9825
9826 0x37, 0x43, 0xA0, 0xE8,
9827 0x3D, 0x53, 0xA0, 0xE8,
9828
9829 0x48, 0x70, 0xF8, 0xEC,
9830 0x2B, 0x48, 0x3C, 0xE9,
9831
9832 0x1F, 0x27, 0xBC, 0xE8,
9833 0x00, 0x80, 0x00, 0xE8,
9834
9835 0x00, 0x80, 0x00, 0xE8,
9836 0x00, 0x80, 0x00, 0xE8,
9837
9838 0x15, 0xC0, 0x20, 0xE9,
9839 0x15, 0xC0, 0x20, 0xE9,
9840
9841 0x15, 0xC0, 0x20, 0xE9,
9842 0x15, 0xC0, 0x20, 0xE9,
9843
9844 0x18, 0x3A, 0x41, 0xE9,
9845 0x1D, 0x32, 0x41, 0xE9,
9846
9847 0x2A, 0x40, 0x20, 0xE9,
9848 0x56, 0x3D, 0x56, 0xDF,
9849
9850 0x46, 0x37, 0x46, 0xDF,
9851 0x4E, 0x3F, 0x4E, 0xDF,
9852
9853 0x16, 0x30, 0x20, 0xE9,
9854 0x4F, 0x3F, 0x4F, 0xDF,
9855
9856 0x32, 0x32, 0x2D, 0xDF,
9857 0x22, 0x22, 0x2D, 0xDF,
9858
9859 0x12, 0x12, 0x2D, 0xDF,
9860 0x3A, 0x3A, 0x2D, 0xDF,
9861
9862 0x47, 0x37, 0x47, 0xDF,
9863 0x57, 0x3D, 0x57, 0xDF,
9864
9865 0x3D, 0xCF, 0x74, 0xC0,
9866 0x37, 0xCF, 0x74, 0xC4,
9867
9868 0x39, 0xE5, 0x2C, 0x9F,
9869 0x34, 0x80, 0x20, 0xE9,
9870
9871 0x31, 0x53, 0x2F, 0x9F,
9872 0x00, 0x80, 0x00, 0xE8,
9873
9874 0x88, 0x73, 0x5E, 0xE9,
9875 0x00, 0x80, 0x00, 0xE8,
9876
9877 0x27, 0xCF, 0x75, 0xC6,
9878 0x3C, 0x3D, 0x20, 0xE9,
9879
9880 0x0A, 0x44, 0x4C, 0xB0,
9881 0x02, 0x44, 0x54, 0xB0,
9882
9883 0x2A, 0x44, 0x4C, 0xB2,
9884 0x1A, 0x44, 0x54, 0xB2,
9885
9886 0x20, 0x80, 0x3A, 0xEA,
9887 0x0A, 0x20,
9888 0x02, 0x20,
9889
9890 0x3D, 0xCF, 0x74, 0xC2,
9891 0x2A, 0x20,
9892 0x1A, 0x20,
9893
9894 0x30, 0x50, 0x2E, 0x9F,
9895 0x32, 0x31, 0x5F, 0xE9,
9896
9897 0x38, 0x21, 0x2C, 0x9F,
9898 0x33, 0x39, 0x5F, 0xE9,
9899
9900 0x31, 0x53, 0x2F, 0x9F,
9901 0x31, 0x27, 0x20, 0xE9,
9902
9903 0x0A, 0x44, 0x4C, 0xB4,
9904 0x02, 0x44, 0x54, 0xB4,
9905
9906 0x2A, 0x45, 0x4D, 0xB6,
9907 0x1A, 0x45, 0x55, 0xB6,
9908
9909 0x39, 0xE5, 0x2C, 0x9F,
9910 0x38, 0x3D, 0x20, 0xE9,
9911
9912 0x0A, 0x20,
9913 0x02, 0x20,
9914 0x2A, 0x20,
9915 0x1A, 0x20,
9916
9917 0x0A, 0x47, 0x4F, 0xBF,
9918 0x02, 0x47, 0x57, 0xBF,
9919
9920 0x30, 0x50, 0x2E, 0x9F,
9921 0x3E, 0x30, 0x4F, 0xE9,
9922
9923 0x38, 0x21, 0x2C, 0x9F,
9924 0x3F, 0x38, 0x4F, 0xE9,
9925
9926 0x2A, 0x46, 0x4E, 0xBF,
9927 0x1A, 0x46, 0x56, 0xBF,
9928
9929 0x31, 0x53, 0x2F, 0x9F,
9930 0x3A, 0x31, 0x4F, 0xE9,
9931
9932 0x39, 0xE5, 0x2C, 0x9F,
9933 0x3B, 0x39, 0x4F, 0xE9,
9934
9935 0x31, 0x53, 0x2F, 0x9F,
9936 0x36, 0x30, 0x4F, 0xE9,
9937
9938 0x39, 0xE5, 0x2C, 0x9F,
9939 0x37, 0x38, 0x4F, 0xE9,
9940
9941 0x2A, 0x43, 0x4B, 0xBF,
9942 0x1A, 0x43, 0x53, 0xBF,
9943
9944 0x30, 0x50, 0x2E, 0x9F,
9945 0x35, 0x31, 0x4F, 0xE9,
9946
9947 0x38, 0x21, 0x2C, 0x9F,
9948 0x39, 0x39, 0x4F, 0xE9,
9949
9950 0x31, 0x53, 0x2F, 0x9F,
9951 0x80, 0x31, 0x57, 0xE9,
9952
9953 0x39, 0xE5, 0x2C, 0x9F,
9954 0x81, 0x39, 0x57, 0xE9,
9955
9956 0x37, 0x48, 0x50, 0xBD,
9957 0x8A, 0x36, 0x20, 0xE9,
9958
9959 0x86, 0x76, 0x57, 0xE9,
9960 0x8B, 0x3E, 0x20, 0xE9,
9961
9962 0x82, 0x30, 0x57, 0xE9,
9963 0x87, 0x77, 0x57, 0xE9,
9964
9965 0x83, 0x38, 0x57, 0xE9,
9966 0x35, 0x49, 0x51, 0xBD,
9967
9968 0x84, 0x31, 0x5E, 0xE9,
9969 0x30, 0x1F, 0x5F, 0xE9,
9970
9971 0x85, 0x39, 0x5E, 0xE9,
9972 0x57, 0x25, 0x20, 0xE9,
9973
9974 0x2B, 0x48, 0x20, 0xE9,
9975 0x1D, 0x37, 0xE1, 0xEA,
9976
9977 0x1E, 0x35, 0xE1, 0xEA,
9978 0x00, 0xE0,
9979 0x26, 0x77,
9980
9981 0x24, 0x49, 0x20, 0xE9,
9982 0xAA, 0xFF, 0x20, 0xEA,
9983
9984 0x16, 0x26, 0x20, 0xE9,
9985 0x57, 0x2E, 0xBF, 0xEA,
9986
9987 0x1C, 0x46, 0xA0, 0xE8,
9988 0x23, 0x4E, 0xA0, 0xE8,
9989
9990 0x2B, 0x56, 0xA0, 0xE8,
9991 0x1D, 0x47, 0xA0, 0xE8,
9992
9993 0x24, 0x4F, 0xA0, 0xE8,
9994 0x2C, 0x57, 0xA0, 0xE8,
9995
9996 0x1C, 0x00,
9997 0x23, 0x00,
9998 0x2B, 0x00,
9999 0x00, 0xE0,
10000
10001 0x1D, 0x00,
10002 0x24, 0x00,
10003 0x2C, 0x00,
10004 0x00, 0xE0,
10005
10006 0x1C, 0x65,
10007 0x23, 0x65,
10008 0x2B, 0x65,
10009 0x00, 0xE0,
10010
10011 0x1D, 0x65,
10012 0x24, 0x65,
10013 0x2C, 0x65,
10014 0x00, 0xE0,
10015
10016 0x1C, 0x23, 0x60, 0xEC,
10017 0x36, 0xD7, 0x36, 0xAD,
10018
10019 0x2B, 0x80, 0x60, 0xEC,
10020 0x1D, 0x24, 0x60, 0xEC,
10021
10022 0x3E, 0xD7, 0x3E, 0xAD,
10023 0x2C, 0x80, 0x60, 0xEC,
10024
10025 0x1C, 0x2B, 0xDE, 0xE8,
10026 0x23, 0x80, 0xDE, 0xE8,
10027
10028 0x36, 0x80, 0x36, 0xBD,
10029 0x3E, 0x80, 0x3E, 0xBD,
10030
10031 0x33, 0xD7, 0x1C, 0xBD,
10032 0x3B, 0xD7, 0x23, 0xBD,
10033
10034 0x46, 0x80, 0x46, 0xCF,
10035 0x4F, 0x80, 0x4F, 0xCF,
10036
10037 0x56, 0x33, 0x56, 0xCF,
10038 0x47, 0x3B, 0x47, 0xCF,
10039
10040 0xD3, 0xFF, 0x20, 0xEA,
10041 0x00, 0x80, 0x00, 0xE8,
10042
10043 0x4E, 0x33, 0x4E, 0xCF,
10044 0x57, 0x3B, 0x57, 0xCF,
10045
10046 0x98, 0xFF, 0x20, 0xEA,
10047 0x57, 0xC0, 0xBF, 0xEA,
10048
10049 0x00, 0x80, 0xA0, 0xE9,
10050 0x00, 0x00, 0xD8, 0xEC,
10051
10052};
10053
10054static unsigned char warp_g400_tgzs[] = {
10055
10056 0x00, 0x88, 0x98, 0xE9,
10057 0x00, 0x80, 0x00, 0xE8,
10058
10059 0x00, 0x80, 0xA0, 0xE9,
10060 0x00, 0x00, 0xD8, 0xEC,
10061
10062 0xFF, 0x80, 0xC0, 0xE9,
10063 0x00, 0x80, 0x00, 0xE8,
10064
10065 0x22, 0x40, 0x48, 0xBF,
10066 0x2A, 0x40, 0x50, 0xBF,
10067
10068 0x32, 0x41, 0x49, 0xBF,
10069 0x3A, 0x41, 0x51, 0xBF,
10070
10071 0xC3, 0x6B,
10072 0xCB, 0x6B,
10073 0x00, 0x88, 0x98, 0xE9,
10074
10075 0x73, 0x7B, 0xC8, 0xEC,
10076 0x96, 0xE2,
10077 0x41, 0x04,
10078
10079 0x7B, 0x43, 0xA0, 0xE8,
10080 0x73, 0x4B, 0xA0, 0xE8,
10081
10082 0xAD, 0xEE, 0x29, 0x9F,
10083 0x00, 0xE0,
10084 0x49, 0x04,
10085
10086 0x90, 0xE2,
10087 0x51, 0x04,
10088 0x31, 0x46, 0xB1, 0xE8,
10089
10090 0x49, 0x41, 0xC0, 0xEC,
10091 0x39, 0x57, 0xB1, 0xE8,
10092
10093 0x00, 0x04,
10094 0x46, 0xE2,
10095 0x73, 0x53, 0xA0, 0xE8,
10096
10097 0x51, 0x41, 0xC0, 0xEC,
10098 0x31, 0x00,
10099 0x39, 0x00,
10100
10101 0x65, 0x80, 0x15, 0xEA,
10102 0x08, 0x04,
10103 0x10, 0x04,
10104
10105 0x51, 0x49, 0xC0, 0xEC,
10106 0x2F, 0x41, 0x60, 0xEA,
10107
10108 0x31, 0x20,
10109 0x39, 0x20,
10110 0x1F, 0x42, 0xA0, 0xE8,
10111
10112 0x2A, 0x42, 0x4A, 0xBF,
10113 0x27, 0x4A, 0xA0, 0xE8,
10114
10115 0x1A, 0x42, 0x52, 0xBF,
10116 0x1E, 0x49, 0x60, 0xEA,
10117
10118 0x73, 0x7B, 0xC8, 0xEC,
10119 0x26, 0x51, 0x60, 0xEA,
10120
10121 0x32, 0x40, 0x48, 0xBD,
10122 0x22, 0x40, 0x50, 0xBD,
10123
10124 0x12, 0x41, 0x49, 0xBD,
10125 0x3A, 0x41, 0x51, 0xBD,
10126
10127 0xBF, 0x2F, 0x26, 0xBD,
10128 0x00, 0xE0,
10129 0x7B, 0x72,
10130
10131 0x32, 0x20,
10132 0x22, 0x20,
10133 0x12, 0x20,
10134 0x3A, 0x20,
10135
10136 0x46, 0x31, 0x46, 0xBF,
10137 0x4E, 0x31, 0x4E, 0xBF,
10138
10139 0xB3, 0xE2, 0x2D, 0x9F,
10140 0x00, 0x80, 0x00, 0xE8,
10141
10142 0x56, 0x31, 0x56, 0xBF,
10143 0x47, 0x39, 0x47, 0xBF,
10144
10145 0x4F, 0x39, 0x4F, 0xBF,
10146 0x57, 0x39, 0x57, 0xBF,
10147
10148 0x57, 0x80, 0x07, 0xEA,
10149 0x24, 0x41, 0x20, 0xE9,
10150
10151 0x42, 0x73, 0xF8, 0xEC,
10152 0x00, 0xE0,
10153 0x2D, 0x73,
10154
10155 0x33, 0x72,
10156 0x0C, 0xE3,
10157 0xA5, 0x2F, 0x1E, 0xBD,
10158
10159 0x43, 0x43, 0x2D, 0xDF,
10160 0x4B, 0x4B, 0x2D, 0xDF,
10161
10162 0xAE, 0x1E, 0x26, 0xBD,
10163 0x58, 0xE3,
10164 0x33, 0x66,
10165
10166 0x53, 0x53, 0x2D, 0xDF,
10167 0x00, 0x80, 0x00, 0xE8,
10168
10169 0xB8, 0x38, 0x33, 0xBF,
10170 0x00, 0xE0,
10171 0x59, 0xE3,
10172
10173 0x1E, 0x12, 0x41, 0xE9,
10174 0x1A, 0x22, 0x41, 0xE9,
10175
10176 0x2B, 0x40, 0x3D, 0xE9,
10177 0x3F, 0x4B, 0xA0, 0xE8,
10178
10179 0x2D, 0x73,
10180 0x30, 0x76,
10181 0x05, 0x80, 0x3D, 0xEA,
10182
10183 0x37, 0x43, 0xA0, 0xE8,
10184 0x3D, 0x53, 0xA0, 0xE8,
10185
10186 0x48, 0x70, 0xF8, 0xEC,
10187 0x2B, 0x48, 0x3C, 0xE9,
10188
10189 0x1F, 0x27, 0xBC, 0xE8,
10190 0x00, 0x80, 0x00, 0xE8,
10191
10192 0x00, 0x80, 0x00, 0xE8,
10193 0x00, 0x80, 0x00, 0xE8,
10194
10195 0x15, 0xC0, 0x20, 0xE9,
10196 0x15, 0xC0, 0x20, 0xE9,
10197
10198 0x15, 0xC0, 0x20, 0xE9,
10199 0x15, 0xC0, 0x20, 0xE9,
10200
10201 0x18, 0x3A, 0x41, 0xE9,
10202 0x1D, 0x32, 0x41, 0xE9,
10203
10204 0x2A, 0x40, 0x20, 0xE9,
10205 0x56, 0x3D, 0x56, 0xDF,
10206
10207 0x46, 0x37, 0x46, 0xDF,
10208 0x4E, 0x3F, 0x4E, 0xDF,
10209
10210 0x16, 0x30, 0x20, 0xE9,
10211 0x4F, 0x3F, 0x4F, 0xDF,
10212
10213 0x47, 0x37, 0x47, 0xDF,
10214 0x57, 0x3D, 0x57, 0xDF,
10215
10216 0x32, 0x32, 0x2D, 0xDF,
10217 0x22, 0x22, 0x2D, 0xDF,
10218
10219 0x12, 0x12, 0x2D, 0xDF,
10220 0x3A, 0x3A, 0x2D, 0xDF,
10221
10222 0x27, 0xCF, 0x74, 0xC2,
10223 0x37, 0xCF, 0x74, 0xC4,
10224
10225 0x0A, 0x44, 0x4C, 0xB0,
10226 0x02, 0x44, 0x54, 0xB0,
10227
10228 0x3D, 0xCF, 0x74, 0xC0,
10229 0x34, 0x37, 0x20, 0xE9,
10230
10231 0x31, 0x53, 0x2F, 0x9F,
10232 0x38, 0x27, 0x20, 0xE9,
10233
10234 0x39, 0xE5, 0x2C, 0x9F,
10235 0x3C, 0x3D, 0x20, 0xE9,
10236
10237 0x2A, 0x44, 0x4C, 0xB2,
10238 0x1A, 0x44, 0x54, 0xB2,
10239
10240 0x29, 0x80, 0x3A, 0xEA,
10241 0x0A, 0x20,
10242 0x02, 0x20,
10243
10244 0x27, 0xCF, 0x75, 0xC0,
10245 0x2A, 0x20,
10246 0x1A, 0x20,
10247
10248 0x30, 0x50, 0x2E, 0x9F,
10249 0x32, 0x31, 0x5F, 0xE9,
10250
10251 0x38, 0x21, 0x2C, 0x9F,
10252 0x33, 0x39, 0x5F, 0xE9,
10253
10254 0x3D, 0xCF, 0x75, 0xC2,
10255 0x37, 0xCF, 0x75, 0xC4,
10256
10257 0x31, 0x53, 0x2F, 0x9F,
10258 0xA6, 0x27, 0x20, 0xE9,
10259
10260 0x39, 0xE5, 0x2C, 0x9F,
10261 0xA3, 0x3D, 0x20, 0xE9,
10262
10263 0x2A, 0x44, 0x4C, 0xB4,
10264 0x1A, 0x44, 0x54, 0xB4,
10265
10266 0x0A, 0x45, 0x4D, 0xB0,
10267 0x02, 0x45, 0x55, 0xB0,
10268
10269 0x88, 0x73, 0x5E, 0xE9,
10270 0x2A, 0x20,
10271 0x1A, 0x20,
10272
10273 0xA0, 0x37, 0x20, 0xE9,
10274 0x0A, 0x20,
10275 0x02, 0x20,
10276
10277 0x31, 0x53, 0x2F, 0x9F,
10278 0x3E, 0x30, 0x4F, 0xE9,
10279
10280 0x39, 0xE5, 0x2C, 0x9F,
10281 0x3F, 0x38, 0x4F, 0xE9,
10282
10283 0x30, 0x50, 0x2E, 0x9F,
10284 0x3A, 0x31, 0x4F, 0xE9,
10285
10286 0x2A, 0x45, 0x4D, 0xB2,
10287 0x1A, 0x45, 0x55, 0xB2,
10288
10289 0x0A, 0x45, 0x4D, 0xB4,
10290 0x02, 0x45, 0x55, 0xB4,
10291
10292 0x38, 0x21, 0x2C, 0x9F,
10293 0x3B, 0x39, 0x4F, 0xE9,
10294
10295 0x0A, 0x20,
10296 0x02, 0x20,
10297 0x2A, 0x20,
10298 0x1A, 0x20,
10299
10300 0x2A, 0x46, 0x4E, 0xBF,
10301 0x1A, 0x46, 0x56, 0xBF,
10302
10303 0x31, 0x53, 0x2F, 0x9F,
10304 0x36, 0x31, 0x4F, 0xE9,
10305
10306 0x39, 0xE5, 0x2C, 0x9F,
10307 0x37, 0x39, 0x4F, 0xE9,
10308
10309 0x30, 0x50, 0x2E, 0x9F,
10310 0xA7, 0x30, 0x4F, 0xE9,
10311
10312 0x38, 0x21, 0x2C, 0x9F,
10313 0xA8, 0x38, 0x4F, 0xE9,
10314
10315 0x0A, 0x47, 0x4F, 0xBF,
10316 0x02, 0x47, 0x57, 0xBF,
10317
10318 0x31, 0x53, 0x2F, 0x9F,
10319 0xA4, 0x31, 0x4F, 0xE9,
10320
10321 0x39, 0xE5, 0x2C, 0x9F,
10322 0xA5, 0x39, 0x4F, 0xE9,
10323
10324 0x2A, 0x43, 0x4B, 0xBF,
10325 0x1A, 0x43, 0x53, 0xBF,
10326
10327 0x30, 0x50, 0x2E, 0x9F,
10328 0xA1, 0x30, 0x4F, 0xE9,
10329
10330 0x38, 0x21, 0x2C, 0x9F,
10331 0xA2, 0x38, 0x4F, 0xE9,
10332
10333 0x31, 0x53, 0x2F, 0x9F,
10334 0x80, 0x31, 0x57, 0xE9,
10335
10336 0x39, 0xE5, 0x2C, 0x9F,
10337 0x81, 0x39, 0x57, 0xE9,
10338
10339 0x37, 0x48, 0x50, 0xBD,
10340 0x8A, 0x36, 0x20, 0xE9,
10341
10342 0x86, 0x76, 0x57, 0xE9,
10343 0x8B, 0x3E, 0x20, 0xE9,
10344
10345 0x82, 0x30, 0x57, 0xE9,
10346 0x87, 0x77, 0x57, 0xE9,
10347
10348 0x83, 0x38, 0x57, 0xE9,
10349 0x35, 0x49, 0x51, 0xBD,
10350
10351 0x84, 0x31, 0x5E, 0xE9,
10352 0x30, 0x1F, 0x5F, 0xE9,
10353
10354 0x85, 0x39, 0x5E, 0xE9,
10355 0x57, 0x25, 0x20, 0xE9,
10356
10357 0x2B, 0x48, 0x20, 0xE9,
10358 0x1D, 0x37, 0xE1, 0xEA,
10359
10360 0x1E, 0x35, 0xE1, 0xEA,
10361 0x00, 0xE0,
10362 0x26, 0x77,
10363
10364 0x24, 0x49, 0x20, 0xE9,
10365 0xA2, 0xFF, 0x20, 0xEA,
10366
10367 0x16, 0x26, 0x20, 0xE9,
10368 0x57, 0x2E, 0xBF, 0xEA,
10369
10370 0x1C, 0x46, 0xA0, 0xE8,
10371 0x23, 0x4E, 0xA0, 0xE8,
10372
10373 0x2B, 0x56, 0xA0, 0xE8,
10374 0x1D, 0x47, 0xA0, 0xE8,
10375
10376 0x24, 0x4F, 0xA0, 0xE8,
10377 0x2C, 0x57, 0xA0, 0xE8,
10378
10379 0x1C, 0x00,
10380 0x23, 0x00,
10381 0x2B, 0x00,
10382 0x00, 0xE0,
10383
10384 0x1D, 0x00,
10385 0x24, 0x00,
10386 0x2C, 0x00,
10387 0x00, 0xE0,
10388
10389 0x1C, 0x65,
10390 0x23, 0x65,
10391 0x2B, 0x65,
10392 0x00, 0xE0,
10393
10394 0x1D, 0x65,
10395 0x24, 0x65,
10396 0x2C, 0x65,
10397 0x00, 0xE0,
10398
10399 0x1C, 0x23, 0x60, 0xEC,
10400 0x36, 0xD7, 0x36, 0xAD,
10401
10402 0x2B, 0x80, 0x60, 0xEC,
10403 0x1D, 0x24, 0x60, 0xEC,
10404
10405 0x3E, 0xD7, 0x3E, 0xAD,
10406 0x2C, 0x80, 0x60, 0xEC,
10407
10408 0x1C, 0x2B, 0xDE, 0xE8,
10409 0x23, 0x80, 0xDE, 0xE8,
10410
10411 0x36, 0x80, 0x36, 0xBD,
10412 0x3E, 0x80, 0x3E, 0xBD,
10413
10414 0x33, 0xD7, 0x1C, 0xBD,
10415 0x3B, 0xD7, 0x23, 0xBD,
10416
10417 0x46, 0x80, 0x46, 0xCF,
10418 0x4F, 0x80, 0x4F, 0xCF,
10419
10420 0x56, 0x33, 0x56, 0xCF,
10421 0x47, 0x3B, 0x47, 0xCF,
10422
10423 0xCA, 0xFF, 0x20, 0xEA,
10424 0x00, 0x80, 0x00, 0xE8,
10425
10426 0x4E, 0x33, 0x4E, 0xCF,
10427 0x57, 0x3B, 0x57, 0xCF,
10428
10429 0x90, 0xFF, 0x20, 0xEA,
10430 0x57, 0xC0, 0xBF, 0xEA,
10431
10432 0x00, 0x80, 0xA0, 0xE9,
10433 0x00, 0x00, 0xD8, 0xEC,
10434
10435};
10436
10437static unsigned char warp_g400_tgzsa[] = {
10438
10439 0x00, 0x88, 0x98, 0xE9,
10440 0x00, 0x80, 0x00, 0xE8,
10441
10442 0x00, 0x80, 0xA0, 0xE9,
10443 0x00, 0x00, 0xD8, 0xEC,
10444
10445 0xFF, 0x80, 0xC0, 0xE9,
10446 0x00, 0x80, 0x00, 0xE8,
10447
10448 0x22, 0x40, 0x48, 0xBF,
10449 0x2A, 0x40, 0x50, 0xBF,
10450
10451 0x32, 0x41, 0x49, 0xBF,
10452 0x3A, 0x41, 0x51, 0xBF,
10453
10454 0xC3, 0x6B,
10455 0xCB, 0x6B,
10456 0x00, 0x88, 0x98, 0xE9,
10457
10458 0x73, 0x7B, 0xC8, 0xEC,
10459 0x96, 0xE2,
10460 0x41, 0x04,
10461
10462 0x7B, 0x43, 0xA0, 0xE8,
10463 0x73, 0x4B, 0xA0, 0xE8,
10464
10465 0xAD, 0xEE, 0x29, 0x9F,
10466 0x00, 0xE0,
10467 0x49, 0x04,
10468
10469 0x90, 0xE2,
10470 0x51, 0x04,
10471 0x31, 0x46, 0xB1, 0xE8,
10472
10473 0x49, 0x41, 0xC0, 0xEC,
10474 0x39, 0x57, 0xB1, 0xE8,
10475
10476 0x00, 0x04,
10477 0x46, 0xE2,
10478 0x73, 0x53, 0xA0, 0xE8,
10479
10480 0x51, 0x41, 0xC0, 0xEC,
10481 0x31, 0x00,
10482 0x39, 0x00,
10483
10484 0x6A, 0x80, 0x15, 0xEA,
10485 0x08, 0x04,
10486 0x10, 0x04,
10487
10488 0x51, 0x49, 0xC0, 0xEC,
10489 0x2F, 0x41, 0x60, 0xEA,
10490
10491 0x31, 0x20,
10492 0x39, 0x20,
10493 0x1F, 0x42, 0xA0, 0xE8,
10494
10495 0x2A, 0x42, 0x4A, 0xBF,
10496 0x27, 0x4A, 0xA0, 0xE8,
10497
10498 0x1A, 0x42, 0x52, 0xBF,
10499 0x1E, 0x49, 0x60, 0xEA,
10500
10501 0x73, 0x7B, 0xC8, 0xEC,
10502 0x26, 0x51, 0x60, 0xEA,
10503
10504 0x32, 0x40, 0x48, 0xBD,
10505 0x22, 0x40, 0x50, 0xBD,
10506
10507 0x12, 0x41, 0x49, 0xBD,
10508 0x3A, 0x41, 0x51, 0xBD,
10509
10510 0xBF, 0x2F, 0x26, 0xBD,
10511 0x00, 0xE0,
10512 0x7B, 0x72,
10513
10514 0x32, 0x20,
10515 0x22, 0x20,
10516 0x12, 0x20,
10517 0x3A, 0x20,
10518
10519 0x46, 0x31, 0x46, 0xBF,
10520 0x4E, 0x31, 0x4E, 0xBF,
10521
10522 0xB3, 0xE2, 0x2D, 0x9F,
10523 0x00, 0x80, 0x00, 0xE8,
10524
10525 0x56, 0x31, 0x56, 0xBF,
10526 0x47, 0x39, 0x47, 0xBF,
10527
10528 0x4F, 0x39, 0x4F, 0xBF,
10529 0x57, 0x39, 0x57, 0xBF,
10530
10531 0x5C, 0x80, 0x07, 0xEA,
10532 0x24, 0x41, 0x20, 0xE9,
10533
10534 0x42, 0x73, 0xF8, 0xEC,
10535 0x00, 0xE0,
10536 0x2D, 0x73,
10537
10538 0x33, 0x72,
10539 0x0C, 0xE3,
10540 0xA5, 0x2F, 0x1E, 0xBD,
10541
10542 0x43, 0x43, 0x2D, 0xDF,
10543 0x4B, 0x4B, 0x2D, 0xDF,
10544
10545 0xAE, 0x1E, 0x26, 0xBD,
10546 0x58, 0xE3,
10547 0x33, 0x66,
10548
10549 0x53, 0x53, 0x2D, 0xDF,
10550 0x00, 0x80, 0x00, 0xE8,
10551
10552 0xB8, 0x38, 0x33, 0xBF,
10553 0x00, 0xE0,
10554 0x59, 0xE3,
10555
10556 0x1E, 0x12, 0x41, 0xE9,
10557 0x1A, 0x22, 0x41, 0xE9,
10558
10559 0x2B, 0x40, 0x3D, 0xE9,
10560 0x3F, 0x4B, 0xA0, 0xE8,
10561
10562 0x2D, 0x73,
10563 0x30, 0x76,
10564 0x05, 0x80, 0x3D, 0xEA,
10565
10566 0x37, 0x43, 0xA0, 0xE8,
10567 0x3D, 0x53, 0xA0, 0xE8,
10568
10569 0x48, 0x70, 0xF8, 0xEC,
10570 0x2B, 0x48, 0x3C, 0xE9,
10571
10572 0x1F, 0x27, 0xBC, 0xE8,
10573 0x00, 0x80, 0x00, 0xE8,
10574
10575 0x00, 0x80, 0x00, 0xE8,
10576 0x00, 0x80, 0x00, 0xE8,
10577
10578 0x15, 0xC0, 0x20, 0xE9,
10579 0x15, 0xC0, 0x20, 0xE9,
10580
10581 0x15, 0xC0, 0x20, 0xE9,
10582 0x15, 0xC0, 0x20, 0xE9,
10583
10584 0x18, 0x3A, 0x41, 0xE9,
10585 0x1D, 0x32, 0x41, 0xE9,
10586
10587 0x2A, 0x40, 0x20, 0xE9,
10588 0x56, 0x3D, 0x56, 0xDF,
10589
10590 0x46, 0x37, 0x46, 0xDF,
10591 0x4E, 0x3F, 0x4E, 0xDF,
10592
10593 0x16, 0x30, 0x20, 0xE9,
10594 0x4F, 0x3F, 0x4F, 0xDF,
10595
10596 0x47, 0x37, 0x47, 0xDF,
10597 0x57, 0x3D, 0x57, 0xDF,
10598
10599 0x32, 0x32, 0x2D, 0xDF,
10600 0x22, 0x22, 0x2D, 0xDF,
10601
10602 0x12, 0x12, 0x2D, 0xDF,
10603 0x3A, 0x3A, 0x2D, 0xDF,
10604
10605 0x27, 0xCF, 0x74, 0xC2,
10606 0x37, 0xCF, 0x74, 0xC4,
10607
10608 0x0A, 0x44, 0x4C, 0xB0,
10609 0x02, 0x44, 0x54, 0xB0,
10610
10611 0x3D, 0xCF, 0x74, 0xC0,
10612 0x34, 0x37, 0x20, 0xE9,
10613
10614 0x31, 0x53, 0x2F, 0x9F,
10615 0x38, 0x27, 0x20, 0xE9,
10616
10617 0x39, 0xE5, 0x2C, 0x9F,
10618 0x3C, 0x3D, 0x20, 0xE9,
10619
10620 0x2A, 0x44, 0x4C, 0xB2,
10621 0x1A, 0x44, 0x54, 0xB2,
10622
10623 0x2E, 0x80, 0x3A, 0xEA,
10624 0x0A, 0x20,
10625 0x02, 0x20,
10626
10627 0x27, 0xCF, 0x75, 0xC0,
10628 0x2A, 0x20,
10629 0x1A, 0x20,
10630
10631 0x30, 0x50, 0x2E, 0x9F,
10632 0x32, 0x31, 0x5F, 0xE9,
10633
10634 0x38, 0x21, 0x2C, 0x9F,
10635 0x33, 0x39, 0x5F, 0xE9,
10636
10637 0x3D, 0xCF, 0x75, 0xC2,
10638 0x37, 0xCF, 0x75, 0xC4,
10639
10640 0x31, 0x53, 0x2F, 0x9F,
10641 0xA6, 0x27, 0x20, 0xE9,
10642
10643 0x39, 0xE5, 0x2C, 0x9F,
10644 0xA3, 0x3D, 0x20, 0xE9,
10645
10646 0x2A, 0x44, 0x4C, 0xB4,
10647 0x1A, 0x44, 0x54, 0xB4,
10648
10649 0x0A, 0x45, 0x4D, 0xB0,
10650 0x02, 0x45, 0x55, 0xB0,
10651
10652 0x88, 0x73, 0x5E, 0xE9,
10653 0x2A, 0x20,
10654 0x1A, 0x20,
10655
10656 0xA0, 0x37, 0x20, 0xE9,
10657 0x0A, 0x20,
10658 0x02, 0x20,
10659
10660 0x31, 0x53, 0x2F, 0x9F,
10661 0x3E, 0x30, 0x4F, 0xE9,
10662
10663 0x39, 0xE5, 0x2C, 0x9F,
10664 0x3F, 0x38, 0x4F, 0xE9,
10665
10666 0x30, 0x50, 0x2E, 0x9F,
10667 0x3A, 0x31, 0x4F, 0xE9,
10668
10669 0x38, 0x21, 0x2C, 0x9F,
10670 0x3B, 0x39, 0x4F, 0xE9,
10671
10672 0x2A, 0x45, 0x4D, 0xB2,
10673 0x1A, 0x45, 0x55, 0xB2,
10674
10675 0x0A, 0x45, 0x4D, 0xB4,
10676 0x02, 0x45, 0x55, 0xB4,
10677
10678 0x27, 0xCF, 0x74, 0xC6,
10679 0x2A, 0x20,
10680 0x1A, 0x20,
10681
10682 0xA7, 0x30, 0x4F, 0xE9,
10683 0x0A, 0x20,
10684 0x02, 0x20,
10685
10686 0x31, 0x53, 0x2F, 0x9F,
10687 0x9C, 0x27, 0x20, 0xE9,
10688
10689 0x39, 0xE5, 0x2C, 0x9F,
10690 0xA8, 0x38, 0x4F, 0xE9,
10691
10692 0x2A, 0x44, 0x4C, 0xB6,
10693 0x1A, 0x44, 0x54, 0xB6,
10694
10695 0x30, 0x50, 0x2E, 0x9F,
10696 0x36, 0x31, 0x4F, 0xE9,
10697
10698 0x38, 0x21, 0x2C, 0x9F,
10699 0x37, 0x39, 0x4F, 0xE9,
10700
10701 0x00, 0x80, 0x00, 0xE8,
10702 0x2A, 0x20,
10703 0x1A, 0x20,
10704
10705 0x2A, 0x46, 0x4E, 0xBF,
10706 0x1A, 0x46, 0x56, 0xBF,
10707
10708 0x31, 0x53, 0x2F, 0x9F,
10709 0xA4, 0x31, 0x4F, 0xE9,
10710
10711 0x39, 0xE5, 0x2C, 0x9F,
10712 0xA5, 0x39, 0x4F, 0xE9,
10713
10714 0x0A, 0x47, 0x4F, 0xBF,
10715 0x02, 0x47, 0x57, 0xBF,
10716
10717 0x31, 0x53, 0x2F, 0x9F,
10718 0xA1, 0x30, 0x4F, 0xE9,
10719
10720 0x39, 0xE5, 0x2C, 0x9F,
10721 0xA2, 0x38, 0x4F, 0xE9,
10722
10723 0x2A, 0x43, 0x4B, 0xBF,
10724 0x1A, 0x43, 0x53, 0xBF,
10725
10726 0x30, 0x50, 0x2E, 0x9F,
10727 0x9D, 0x31, 0x4F, 0xE9,
10728
10729 0x38, 0x21, 0x2C, 0x9F,
10730 0x9E, 0x39, 0x4F, 0xE9,
10731
10732 0x31, 0x53, 0x2F, 0x9F,
10733 0x80, 0x31, 0x57, 0xE9,
10734
10735 0x39, 0xE5, 0x2C, 0x9F,
10736 0x81, 0x39, 0x57, 0xE9,
10737
10738 0x37, 0x48, 0x50, 0xBD,
10739 0x8A, 0x36, 0x20, 0xE9,
10740
10741 0x86, 0x76, 0x57, 0xE9,
10742 0x8B, 0x3E, 0x20, 0xE9,
10743
10744 0x82, 0x30, 0x57, 0xE9,
10745 0x87, 0x77, 0x57, 0xE9,
10746
10747 0x83, 0x38, 0x57, 0xE9,
10748 0x35, 0x49, 0x51, 0xBD,
10749
10750 0x84, 0x31, 0x5E, 0xE9,
10751 0x30, 0x1F, 0x5F, 0xE9,
10752
10753 0x85, 0x39, 0x5E, 0xE9,
10754 0x57, 0x25, 0x20, 0xE9,
10755
10756 0x2B, 0x48, 0x20, 0xE9,
10757 0x1D, 0x37, 0xE1, 0xEA,
10758
10759 0x1E, 0x35, 0xE1, 0xEA,
10760 0x00, 0xE0,
10761 0x26, 0x77,
10762
10763 0x24, 0x49, 0x20, 0xE9,
10764 0x9D, 0xFF, 0x20, 0xEA,
10765
10766 0x16, 0x26, 0x20, 0xE9,
10767 0x57, 0x2E, 0xBF, 0xEA,
10768
10769 0x1C, 0x46, 0xA0, 0xE8,
10770 0x23, 0x4E, 0xA0, 0xE8,
10771
10772 0x2B, 0x56, 0xA0, 0xE8,
10773 0x1D, 0x47, 0xA0, 0xE8,
10774
10775 0x24, 0x4F, 0xA0, 0xE8,
10776 0x2C, 0x57, 0xA0, 0xE8,
10777
10778 0x1C, 0x00,
10779 0x23, 0x00,
10780 0x2B, 0x00,
10781 0x00, 0xE0,
10782
10783 0x1D, 0x00,
10784 0x24, 0x00,
10785 0x2C, 0x00,
10786 0x00, 0xE0,
10787
10788 0x1C, 0x65,
10789 0x23, 0x65,
10790 0x2B, 0x65,
10791 0x00, 0xE0,
10792
10793 0x1D, 0x65,
10794 0x24, 0x65,
10795 0x2C, 0x65,
10796 0x00, 0xE0,
10797
10798 0x1C, 0x23, 0x60, 0xEC,
10799 0x36, 0xD7, 0x36, 0xAD,
10800
10801 0x2B, 0x80, 0x60, 0xEC,
10802 0x1D, 0x24, 0x60, 0xEC,
10803
10804 0x3E, 0xD7, 0x3E, 0xAD,
10805 0x2C, 0x80, 0x60, 0xEC,
10806
10807 0x1C, 0x2B, 0xDE, 0xE8,
10808 0x23, 0x80, 0xDE, 0xE8,
10809
10810 0x36, 0x80, 0x36, 0xBD,
10811 0x3E, 0x80, 0x3E, 0xBD,
10812
10813 0x33, 0xD7, 0x1C, 0xBD,
10814 0x3B, 0xD7, 0x23, 0xBD,
10815
10816 0x46, 0x80, 0x46, 0xCF,
10817 0x4F, 0x80, 0x4F, 0xCF,
10818
10819 0x56, 0x33, 0x56, 0xCF,
10820 0x47, 0x3B, 0x47, 0xCF,
10821
10822 0xC5, 0xFF, 0x20, 0xEA,
10823 0x00, 0x80, 0x00, 0xE8,
10824
10825 0x4E, 0x33, 0x4E, 0xCF,
10826 0x57, 0x3B, 0x57, 0xCF,
10827
10828 0x8B, 0xFF, 0x20, 0xEA,
10829 0x57, 0xC0, 0xBF, 0xEA,
10830
10831 0x00, 0x80, 0xA0, 0xE9,
10832 0x00, 0x00, 0xD8, 0xEC,
10833
10834};
10835
10836static unsigned char warp_g400_tgzsaf[] = {
10837
10838 0x00, 0x88, 0x98, 0xE9,
10839 0x00, 0x80, 0x00, 0xE8,
10840
10841 0x00, 0x80, 0xA0, 0xE9,
10842 0x00, 0x00, 0xD8, 0xEC,
10843
10844 0xFF, 0x80, 0xC0, 0xE9,
10845 0x00, 0x80, 0x00, 0xE8,
10846
10847 0x22, 0x40, 0x48, 0xBF,
10848 0x2A, 0x40, 0x50, 0xBF,
10849
10850 0x32, 0x41, 0x49, 0xBF,
10851 0x3A, 0x41, 0x51, 0xBF,
10852
10853 0xC3, 0x6B,
10854 0xCB, 0x6B,
10855 0x00, 0x88, 0x98, 0xE9,
10856
10857 0x73, 0x7B, 0xC8, 0xEC,
10858 0x96, 0xE2,
10859 0x41, 0x04,
10860
10861 0x7B, 0x43, 0xA0, 0xE8,
10862 0x73, 0x4B, 0xA0, 0xE8,
10863
10864 0xAD, 0xEE, 0x29, 0x9F,
10865 0x00, 0xE0,
10866 0x49, 0x04,
10867
10868 0x90, 0xE2,
10869 0x51, 0x04,
10870 0x31, 0x46, 0xB1, 0xE8,
10871
10872 0x49, 0x41, 0xC0, 0xEC,
10873 0x39, 0x57, 0xB1, 0xE8,
10874
10875 0x00, 0x04,
10876 0x46, 0xE2,
10877 0x73, 0x53, 0xA0, 0xE8,
10878
10879 0x51, 0x41, 0xC0, 0xEC,
10880 0x31, 0x00,
10881 0x39, 0x00,
10882
10883 0x6E, 0x80, 0x15, 0xEA,
10884 0x08, 0x04,
10885 0x10, 0x04,
10886
10887 0x51, 0x49, 0xC0, 0xEC,
10888 0x2F, 0x41, 0x60, 0xEA,
10889
10890 0x31, 0x20,
10891 0x39, 0x20,
10892 0x1F, 0x42, 0xA0, 0xE8,
10893
10894 0x2A, 0x42, 0x4A, 0xBF,
10895 0x27, 0x4A, 0xA0, 0xE8,
10896
10897 0x1A, 0x42, 0x52, 0xBF,
10898 0x1E, 0x49, 0x60, 0xEA,
10899
10900 0x73, 0x7B, 0xC8, 0xEC,
10901 0x26, 0x51, 0x60, 0xEA,
10902
10903 0x32, 0x40, 0x48, 0xBD,
10904 0x22, 0x40, 0x50, 0xBD,
10905
10906 0x12, 0x41, 0x49, 0xBD,
10907 0x3A, 0x41, 0x51, 0xBD,
10908
10909 0xBF, 0x2F, 0x26, 0xBD,
10910 0x00, 0xE0,
10911 0x7B, 0x72,
10912
10913 0x32, 0x20,
10914 0x22, 0x20,
10915 0x12, 0x20,
10916 0x3A, 0x20,
10917
10918 0x46, 0x31, 0x46, 0xBF,
10919 0x4E, 0x31, 0x4E, 0xBF,
10920
10921 0xB3, 0xE2, 0x2D, 0x9F,
10922 0x00, 0x80, 0x00, 0xE8,
10923
10924 0x56, 0x31, 0x56, 0xBF,
10925 0x47, 0x39, 0x47, 0xBF,
10926
10927 0x4F, 0x39, 0x4F, 0xBF,
10928 0x57, 0x39, 0x57, 0xBF,
10929
10930 0x60, 0x80, 0x07, 0xEA,
10931 0x24, 0x41, 0x20, 0xE9,
10932
10933 0x42, 0x73, 0xF8, 0xEC,
10934 0x00, 0xE0,
10935 0x2D, 0x73,
10936
10937 0x33, 0x72,
10938 0x0C, 0xE3,
10939 0xA5, 0x2F, 0x1E, 0xBD,
10940
10941 0x43, 0x43, 0x2D, 0xDF,
10942 0x4B, 0x4B, 0x2D, 0xDF,
10943
10944 0xAE, 0x1E, 0x26, 0xBD,
10945 0x58, 0xE3,
10946 0x33, 0x66,
10947
10948 0x53, 0x53, 0x2D, 0xDF,
10949 0x00, 0x80, 0x00, 0xE8,
10950
10951 0xB8, 0x38, 0x33, 0xBF,
10952 0x00, 0xE0,
10953 0x59, 0xE3,
10954
10955 0x1E, 0x12, 0x41, 0xE9,
10956 0x1A, 0x22, 0x41, 0xE9,
10957
10958 0x2B, 0x40, 0x3D, 0xE9,
10959 0x3F, 0x4B, 0xA0, 0xE8,
10960
10961 0x2D, 0x73,
10962 0x30, 0x76,
10963 0x05, 0x80, 0x3D, 0xEA,
10964
10965 0x37, 0x43, 0xA0, 0xE8,
10966 0x3D, 0x53, 0xA0, 0xE8,
10967
10968 0x48, 0x70, 0xF8, 0xEC,
10969 0x2B, 0x48, 0x3C, 0xE9,
10970
10971 0x1F, 0x27, 0xBC, 0xE8,
10972 0x00, 0x80, 0x00, 0xE8,
10973
10974 0x00, 0x80, 0x00, 0xE8,
10975 0x00, 0x80, 0x00, 0xE8,
10976
10977 0x15, 0xC0, 0x20, 0xE9,
10978 0x15, 0xC0, 0x20, 0xE9,
10979
10980 0x15, 0xC0, 0x20, 0xE9,
10981 0x15, 0xC0, 0x20, 0xE9,
10982
10983 0x18, 0x3A, 0x41, 0xE9,
10984 0x1D, 0x32, 0x41, 0xE9,
10985
10986 0x2A, 0x40, 0x20, 0xE9,
10987 0x56, 0x3D, 0x56, 0xDF,
10988
10989 0x46, 0x37, 0x46, 0xDF,
10990 0x4E, 0x3F, 0x4E, 0xDF,
10991
10992 0x16, 0x30, 0x20, 0xE9,
10993 0x4F, 0x3F, 0x4F, 0xDF,
10994
10995 0x47, 0x37, 0x47, 0xDF,
10996 0x57, 0x3D, 0x57, 0xDF,
10997
10998 0x32, 0x32, 0x2D, 0xDF,
10999 0x22, 0x22, 0x2D, 0xDF,
11000
11001 0x12, 0x12, 0x2D, 0xDF,
11002 0x3A, 0x3A, 0x2D, 0xDF,
11003
11004 0x27, 0xCF, 0x74, 0xC2,
11005 0x37, 0xCF, 0x74, 0xC4,
11006
11007 0x0A, 0x44, 0x4C, 0xB0,
11008 0x02, 0x44, 0x54, 0xB0,
11009
11010 0x3D, 0xCF, 0x74, 0xC0,
11011 0x34, 0x37, 0x20, 0xE9,
11012
11013 0x31, 0x53, 0x2F, 0x9F,
11014 0x38, 0x27, 0x20, 0xE9,
11015
11016 0x39, 0xE5, 0x2C, 0x9F,
11017 0x3C, 0x3D, 0x20, 0xE9,
11018
11019 0x2A, 0x44, 0x4C, 0xB2,
11020 0x1A, 0x44, 0x54, 0xB2,
11021
11022 0x32, 0x80, 0x3A, 0xEA,
11023 0x0A, 0x20,
11024 0x02, 0x20,
11025
11026 0x27, 0xCF, 0x75, 0xC0,
11027 0x2A, 0x20,
11028 0x1A, 0x20,
11029
11030 0x30, 0x50, 0x2E, 0x9F,
11031 0x32, 0x31, 0x5F, 0xE9,
11032
11033 0x38, 0x21, 0x2C, 0x9F,
11034 0x33, 0x39, 0x5F, 0xE9,
11035
11036 0x3D, 0xCF, 0x75, 0xC2,
11037 0x37, 0xCF, 0x75, 0xC4,
11038
11039 0x31, 0x53, 0x2F, 0x9F,
11040 0xA6, 0x27, 0x20, 0xE9,
11041
11042 0x39, 0xE5, 0x2C, 0x9F,
11043 0xA3, 0x3D, 0x20, 0xE9,
11044
11045 0x2A, 0x44, 0x4C, 0xB4,
11046 0x1A, 0x44, 0x54, 0xB4,
11047
11048 0x0A, 0x45, 0x4D, 0xB0,
11049 0x02, 0x45, 0x55, 0xB0,
11050
11051 0x88, 0x73, 0x5E, 0xE9,
11052 0x2A, 0x20,
11053 0x1A, 0x20,
11054
11055 0xA0, 0x37, 0x20, 0xE9,
11056 0x0A, 0x20,
11057 0x02, 0x20,
11058
11059 0x31, 0x53, 0x2F, 0x9F,
11060 0x3E, 0x30, 0x4F, 0xE9,
11061
11062 0x39, 0xE5, 0x2C, 0x9F,
11063 0x3F, 0x38, 0x4F, 0xE9,
11064
11065 0x30, 0x50, 0x2E, 0x9F,
11066 0x3A, 0x31, 0x4F, 0xE9,
11067
11068 0x38, 0x21, 0x2C, 0x9F,
11069 0x3B, 0x39, 0x4F, 0xE9,
11070
11071 0x2A, 0x45, 0x4D, 0xB2,
11072 0x1A, 0x45, 0x55, 0xB2,
11073
11074 0x0A, 0x45, 0x4D, 0xB4,
11075 0x02, 0x45, 0x55, 0xB4,
11076
11077 0x27, 0xCF, 0x74, 0xC6,
11078 0x2A, 0x20,
11079 0x1A, 0x20,
11080
11081 0xA7, 0x30, 0x4F, 0xE9,
11082 0x0A, 0x20,
11083 0x02, 0x20,
11084
11085 0x31, 0x53, 0x2F, 0x9F,
11086 0x9C, 0x27, 0x20, 0xE9,
11087
11088 0x39, 0xE5, 0x2C, 0x9F,
11089 0xA8, 0x38, 0x4F, 0xE9,
11090
11091 0x2A, 0x44, 0x4C, 0xB6,
11092 0x1A, 0x44, 0x54, 0xB6,
11093
11094 0x30, 0x50, 0x2E, 0x9F,
11095 0x36, 0x31, 0x4F, 0xE9,
11096
11097 0x38, 0x21, 0x2C, 0x9F,
11098 0x37, 0x39, 0x4F, 0xE9,
11099
11100 0x0A, 0x45, 0x4D, 0xB6,
11101 0x02, 0x45, 0x55, 0xB6,
11102
11103 0x3D, 0xCF, 0x75, 0xC6,
11104 0x2A, 0x20,
11105 0x1A, 0x20,
11106
11107 0x2A, 0x46, 0x4E, 0xBF,
11108 0x1A, 0x46, 0x56, 0xBF,
11109
11110 0x31, 0x53, 0x2F, 0x9F,
11111 0xA4, 0x31, 0x4F, 0xE9,
11112
11113 0x39, 0xE5, 0x2C, 0x9F,
11114 0xA5, 0x39, 0x4F, 0xE9,
11115
11116 0x31, 0x3D, 0x20, 0xE9,
11117 0x0A, 0x20,
11118 0x02, 0x20,
11119
11120 0x0A, 0x47, 0x4F, 0xBF,
11121 0x02, 0x47, 0x57, 0xBF,
11122
11123 0x30, 0x50, 0x2E, 0x9F,
11124 0xA1, 0x30, 0x4F, 0xE9,
11125
11126 0x38, 0x21, 0x2C, 0x9F,
11127 0xA2, 0x38, 0x4F, 0xE9,
11128
11129 0x31, 0x53, 0x2F, 0x9F,
11130 0x9D, 0x31, 0x4F, 0xE9,
11131
11132 0x39, 0xE5, 0x2C, 0x9F,
11133 0x9E, 0x39, 0x4F, 0xE9,
11134
11135 0x2A, 0x43, 0x4B, 0xBF,
11136 0x1A, 0x43, 0x53, 0xBF,
11137
11138 0x30, 0x50, 0x2E, 0x9F,
11139 0x35, 0x30, 0x4F, 0xE9,
11140
11141 0x38, 0x21, 0x2C, 0x9F,
11142 0x39, 0x38, 0x4F, 0xE9,
11143
11144 0x31, 0x53, 0x2F, 0x9F,
11145 0x80, 0x31, 0x57, 0xE9,
11146
11147 0x39, 0xE5, 0x2C, 0x9F,
11148 0x81, 0x39, 0x57, 0xE9,
11149
11150 0x37, 0x48, 0x50, 0xBD,
11151 0x8A, 0x36, 0x20, 0xE9,
11152
11153 0x86, 0x76, 0x57, 0xE9,
11154 0x8B, 0x3E, 0x20, 0xE9,
11155
11156 0x82, 0x30, 0x57, 0xE9,
11157 0x87, 0x77, 0x57, 0xE9,
11158
11159 0x83, 0x38, 0x57, 0xE9,
11160 0x35, 0x49, 0x51, 0xBD,
11161
11162 0x84, 0x31, 0x5E, 0xE9,
11163 0x30, 0x1F, 0x5F, 0xE9,
11164
11165 0x85, 0x39, 0x5E, 0xE9,
11166 0x57, 0x25, 0x20, 0xE9,
11167
11168 0x2B, 0x48, 0x20, 0xE9,
11169 0x1D, 0x37, 0xE1, 0xEA,
11170
11171 0x1E, 0x35, 0xE1, 0xEA,
11172 0x00, 0xE0,
11173 0x26, 0x77,
11174
11175 0x24, 0x49, 0x20, 0xE9,
11176 0x99, 0xFF, 0x20, 0xEA,
11177
11178 0x16, 0x26, 0x20, 0xE9,
11179 0x57, 0x2E, 0xBF, 0xEA,
11180
11181 0x1C, 0x46, 0xA0, 0xE8,
11182 0x23, 0x4E, 0xA0, 0xE8,
11183
11184 0x2B, 0x56, 0xA0, 0xE8,
11185 0x1D, 0x47, 0xA0, 0xE8,
11186
11187 0x24, 0x4F, 0xA0, 0xE8,
11188 0x2C, 0x57, 0xA0, 0xE8,
11189
11190 0x1C, 0x00,
11191 0x23, 0x00,
11192 0x2B, 0x00,
11193 0x00, 0xE0,
11194
11195 0x1D, 0x00,
11196 0x24, 0x00,
11197 0x2C, 0x00,
11198 0x00, 0xE0,
11199
11200 0x1C, 0x65,
11201 0x23, 0x65,
11202 0x2B, 0x65,
11203 0x00, 0xE0,
11204
11205 0x1D, 0x65,
11206 0x24, 0x65,
11207 0x2C, 0x65,
11208 0x00, 0xE0,
11209
11210 0x1C, 0x23, 0x60, 0xEC,
11211 0x36, 0xD7, 0x36, 0xAD,
11212
11213 0x2B, 0x80, 0x60, 0xEC,
11214 0x1D, 0x24, 0x60, 0xEC,
11215
11216 0x3E, 0xD7, 0x3E, 0xAD,
11217 0x2C, 0x80, 0x60, 0xEC,
11218
11219 0x1C, 0x2B, 0xDE, 0xE8,
11220 0x23, 0x80, 0xDE, 0xE8,
11221
11222 0x36, 0x80, 0x36, 0xBD,
11223 0x3E, 0x80, 0x3E, 0xBD,
11224
11225 0x33, 0xD7, 0x1C, 0xBD,
11226 0x3B, 0xD7, 0x23, 0xBD,
11227
11228 0x46, 0x80, 0x46, 0xCF,
11229 0x4F, 0x80, 0x4F, 0xCF,
11230
11231 0x56, 0x33, 0x56, 0xCF,
11232 0x47, 0x3B, 0x47, 0xCF,
11233
11234 0xC1, 0xFF, 0x20, 0xEA,
11235 0x00, 0x80, 0x00, 0xE8,
11236
11237 0x4E, 0x33, 0x4E, 0xCF,
11238 0x57, 0x3B, 0x57, 0xCF,
11239
11240 0x87, 0xFF, 0x20, 0xEA,
11241 0x57, 0xC0, 0xBF, 0xEA,
11242
11243 0x00, 0x80, 0xA0, 0xE9,
11244 0x00, 0x00, 0xD8, 0xEC,
11245
11246};
11247
11248static unsigned char warp_g400_tgzsf[] = {
11249
11250 0x00, 0x88, 0x98, 0xE9,
11251 0x00, 0x80, 0x00, 0xE8,
11252
11253 0x00, 0x80, 0xA0, 0xE9,
11254 0x00, 0x00, 0xD8, 0xEC,
11255
11256 0xFF, 0x80, 0xC0, 0xE9,
11257 0x00, 0x80, 0x00, 0xE8,
11258
11259 0x22, 0x40, 0x48, 0xBF,
11260 0x2A, 0x40, 0x50, 0xBF,
11261
11262 0x32, 0x41, 0x49, 0xBF,
11263 0x3A, 0x41, 0x51, 0xBF,
11264
11265 0xC3, 0x6B,
11266 0xCB, 0x6B,
11267 0x00, 0x88, 0x98, 0xE9,
11268
11269 0x73, 0x7B, 0xC8, 0xEC,
11270 0x96, 0xE2,
11271 0x41, 0x04,
11272
11273 0x7B, 0x43, 0xA0, 0xE8,
11274 0x73, 0x4B, 0xA0, 0xE8,
11275
11276 0xAD, 0xEE, 0x29, 0x9F,
11277 0x00, 0xE0,
11278 0x49, 0x04,
11279
11280 0x90, 0xE2,
11281 0x51, 0x04,
11282 0x31, 0x46, 0xB1, 0xE8,
11283
11284 0x49, 0x41, 0xC0, 0xEC,
11285 0x39, 0x57, 0xB1, 0xE8,
11286
11287 0x00, 0x04,
11288 0x46, 0xE2,
11289 0x73, 0x53, 0xA0, 0xE8,
11290
11291 0x51, 0x41, 0xC0, 0xEC,
11292 0x31, 0x00,
11293 0x39, 0x00,
11294
11295 0x6A, 0x80, 0x15, 0xEA,
11296 0x08, 0x04,
11297 0x10, 0x04,
11298
11299 0x51, 0x49, 0xC0, 0xEC,
11300 0x2F, 0x41, 0x60, 0xEA,
11301
11302 0x31, 0x20,
11303 0x39, 0x20,
11304 0x1F, 0x42, 0xA0, 0xE8,
11305
11306 0x2A, 0x42, 0x4A, 0xBF,
11307 0x27, 0x4A, 0xA0, 0xE8,
11308
11309 0x1A, 0x42, 0x52, 0xBF,
11310 0x1E, 0x49, 0x60, 0xEA,
11311
11312 0x73, 0x7B, 0xC8, 0xEC,
11313 0x26, 0x51, 0x60, 0xEA,
11314
11315 0x32, 0x40, 0x48, 0xBD,
11316 0x22, 0x40, 0x50, 0xBD,
11317
11318 0x12, 0x41, 0x49, 0xBD,
11319 0x3A, 0x41, 0x51, 0xBD,
11320
11321 0xBF, 0x2F, 0x26, 0xBD,
11322 0x00, 0xE0,
11323 0x7B, 0x72,
11324
11325 0x32, 0x20,
11326 0x22, 0x20,
11327 0x12, 0x20,
11328 0x3A, 0x20,
11329
11330 0x46, 0x31, 0x46, 0xBF,
11331 0x4E, 0x31, 0x4E, 0xBF,
11332
11333 0xB3, 0xE2, 0x2D, 0x9F,
11334 0x00, 0x80, 0x00, 0xE8,
11335
11336 0x56, 0x31, 0x56, 0xBF,
11337 0x47, 0x39, 0x47, 0xBF,
11338
11339 0x4F, 0x39, 0x4F, 0xBF,
11340 0x57, 0x39, 0x57, 0xBF,
11341
11342 0x5C, 0x80, 0x07, 0xEA,
11343 0x24, 0x41, 0x20, 0xE9,
11344
11345 0x42, 0x73, 0xF8, 0xEC,
11346 0x00, 0xE0,
11347 0x2D, 0x73,
11348
11349 0x33, 0x72,
11350 0x0C, 0xE3,
11351 0xA5, 0x2F, 0x1E, 0xBD,
11352
11353 0x43, 0x43, 0x2D, 0xDF,
11354 0x4B, 0x4B, 0x2D, 0xDF,
11355
11356 0xAE, 0x1E, 0x26, 0xBD,
11357 0x58, 0xE3,
11358 0x33, 0x66,
11359
11360 0x53, 0x53, 0x2D, 0xDF,
11361 0x00, 0x80, 0x00, 0xE8,
11362
11363 0xB8, 0x38, 0x33, 0xBF,
11364 0x00, 0xE0,
11365 0x59, 0xE3,
11366
11367 0x1E, 0x12, 0x41, 0xE9,
11368 0x1A, 0x22, 0x41, 0xE9,
11369
11370 0x2B, 0x40, 0x3D, 0xE9,
11371 0x3F, 0x4B, 0xA0, 0xE8,
11372
11373 0x2D, 0x73,
11374 0x30, 0x76,
11375 0x05, 0x80, 0x3D, 0xEA,
11376
11377 0x37, 0x43, 0xA0, 0xE8,
11378 0x3D, 0x53, 0xA0, 0xE8,
11379
11380 0x48, 0x70, 0xF8, 0xEC,
11381 0x2B, 0x48, 0x3C, 0xE9,
11382
11383 0x1F, 0x27, 0xBC, 0xE8,
11384 0x00, 0x80, 0x00, 0xE8,
11385
11386 0x00, 0x80, 0x00, 0xE8,
11387 0x00, 0x80, 0x00, 0xE8,
11388
11389 0x15, 0xC0, 0x20, 0xE9,
11390 0x15, 0xC0, 0x20, 0xE9,
11391
11392 0x15, 0xC0, 0x20, 0xE9,
11393 0x15, 0xC0, 0x20, 0xE9,
11394
11395 0x18, 0x3A, 0x41, 0xE9,
11396 0x1D, 0x32, 0x41, 0xE9,
11397
11398 0x2A, 0x40, 0x20, 0xE9,
11399 0x56, 0x3D, 0x56, 0xDF,
11400
11401 0x46, 0x37, 0x46, 0xDF,
11402 0x4E, 0x3F, 0x4E, 0xDF,
11403
11404 0x16, 0x30, 0x20, 0xE9,
11405 0x4F, 0x3F, 0x4F, 0xDF,
11406
11407 0x47, 0x37, 0x47, 0xDF,
11408 0x57, 0x3D, 0x57, 0xDF,
11409
11410 0x32, 0x32, 0x2D, 0xDF,
11411 0x22, 0x22, 0x2D, 0xDF,
11412
11413 0x12, 0x12, 0x2D, 0xDF,
11414 0x3A, 0x3A, 0x2D, 0xDF,
11415
11416 0x27, 0xCF, 0x74, 0xC2,
11417 0x37, 0xCF, 0x74, 0xC4,
11418
11419 0x0A, 0x44, 0x4C, 0xB0,
11420 0x02, 0x44, 0x54, 0xB0,
11421
11422 0x3D, 0xCF, 0x74, 0xC0,
11423 0x34, 0x37, 0x20, 0xE9,
11424
11425 0x31, 0x53, 0x2F, 0x9F,
11426 0x38, 0x27, 0x20, 0xE9,
11427
11428 0x39, 0xE5, 0x2C, 0x9F,
11429 0x3C, 0x3D, 0x20, 0xE9,
11430
11431 0x2A, 0x44, 0x4C, 0xB2,
11432 0x1A, 0x44, 0x54, 0xB2,
11433
11434 0x2E, 0x80, 0x3A, 0xEA,
11435 0x0A, 0x20,
11436 0x02, 0x20,
11437
11438 0x27, 0xCF, 0x75, 0xC0,
11439 0x2A, 0x20,
11440 0x1A, 0x20,
11441
11442 0x30, 0x50, 0x2E, 0x9F,
11443 0x32, 0x31, 0x5F, 0xE9,
11444
11445 0x38, 0x21, 0x2C, 0x9F,
11446 0x33, 0x39, 0x5F, 0xE9,
11447
11448 0x3D, 0xCF, 0x75, 0xC2,
11449 0x37, 0xCF, 0x75, 0xC4,
11450
11451 0x31, 0x53, 0x2F, 0x9F,
11452 0xA6, 0x27, 0x20, 0xE9,
11453
11454 0x39, 0xE5, 0x2C, 0x9F,
11455 0xA3, 0x3D, 0x20, 0xE9,
11456
11457 0x2A, 0x44, 0x4C, 0xB4,
11458 0x1A, 0x44, 0x54, 0xB4,
11459
11460 0x0A, 0x45, 0x4D, 0xB0,
11461 0x02, 0x45, 0x55, 0xB0,
11462
11463 0x88, 0x73, 0x5E, 0xE9,
11464 0x2A, 0x20,
11465 0x1A, 0x20,
11466
11467 0xA0, 0x37, 0x20, 0xE9,
11468 0x0A, 0x20,
11469 0x02, 0x20,
11470
11471 0x31, 0x53, 0x2F, 0x9F,
11472 0x3E, 0x30, 0x4F, 0xE9,
11473
11474 0x39, 0xE5, 0x2C, 0x9F,
11475 0x3F, 0x38, 0x4F, 0xE9,
11476
11477 0x30, 0x50, 0x2E, 0x9F,
11478 0x3A, 0x31, 0x4F, 0xE9,
11479
11480 0x38, 0x21, 0x2C, 0x9F,
11481 0x3B, 0x39, 0x4F, 0xE9,
11482
11483 0x2A, 0x45, 0x4D, 0xB2,
11484 0x1A, 0x45, 0x55, 0xB2,
11485
11486 0x0A, 0x45, 0x4D, 0xB4,
11487 0x02, 0x45, 0x55, 0xB4,
11488
11489 0x27, 0xCF, 0x75, 0xC6,
11490 0x2A, 0x20,
11491 0x1A, 0x20,
11492
11493 0xA7, 0x30, 0x4F, 0xE9,
11494 0x0A, 0x20,
11495 0x02, 0x20,
11496
11497 0x31, 0x53, 0x2F, 0x9F,
11498 0x31, 0x27, 0x20, 0xE9,
11499
11500 0x39, 0xE5, 0x2C, 0x9F,
11501 0xA8, 0x38, 0x4F, 0xE9,
11502
11503 0x2A, 0x45, 0x4D, 0xB6,
11504 0x1A, 0x45, 0x55, 0xB6,
11505
11506 0x30, 0x50, 0x2E, 0x9F,
11507 0x36, 0x31, 0x4F, 0xE9,
11508
11509 0x38, 0x21, 0x2C, 0x9F,
11510 0x37, 0x39, 0x4F, 0xE9,
11511
11512 0x00, 0x80, 0x00, 0xE8,
11513 0x2A, 0x20,
11514 0x1A, 0x20,
11515
11516 0x2A, 0x46, 0x4E, 0xBF,
11517 0x1A, 0x46, 0x56, 0xBF,
11518
11519 0x31, 0x53, 0x2F, 0x9F,
11520 0xA4, 0x31, 0x4F, 0xE9,
11521
11522 0x39, 0xE5, 0x2C, 0x9F,
11523 0xA5, 0x39, 0x4F, 0xE9,
11524
11525 0x0A, 0x47, 0x4F, 0xBF,
11526 0x02, 0x47, 0x57, 0xBF,
11527
11528 0x31, 0x53, 0x2F, 0x9F,
11529 0xA1, 0x30, 0x4F, 0xE9,
11530
11531 0x39, 0xE5, 0x2C, 0x9F,
11532 0xA2, 0x38, 0x4F, 0xE9,
11533
11534 0x2A, 0x43, 0x4B, 0xBF,
11535 0x1A, 0x43, 0x53, 0xBF,
11536
11537 0x30, 0x50, 0x2E, 0x9F,
11538 0x35, 0x31, 0x4F, 0xE9,
11539
11540 0x38, 0x21, 0x2C, 0x9F,
11541 0x39, 0x39, 0x4F, 0xE9,
11542
11543 0x31, 0x53, 0x2F, 0x9F,
11544 0x80, 0x31, 0x57, 0xE9,
11545
11546 0x39, 0xE5, 0x2C, 0x9F,
11547 0x81, 0x39, 0x57, 0xE9,
11548
11549 0x37, 0x48, 0x50, 0xBD,
11550 0x8A, 0x36, 0x20, 0xE9,
11551
11552 0x86, 0x76, 0x57, 0xE9,
11553 0x8B, 0x3E, 0x20, 0xE9,
11554
11555 0x82, 0x30, 0x57, 0xE9,
11556 0x87, 0x77, 0x57, 0xE9,
11557
11558 0x83, 0x38, 0x57, 0xE9,
11559 0x35, 0x49, 0x51, 0xBD,
11560
11561 0x84, 0x31, 0x5E, 0xE9,
11562 0x30, 0x1F, 0x5F, 0xE9,
11563
11564 0x85, 0x39, 0x5E, 0xE9,
11565 0x57, 0x25, 0x20, 0xE9,
11566
11567 0x2B, 0x48, 0x20, 0xE9,
11568 0x1D, 0x37, 0xE1, 0xEA,
11569
11570 0x1E, 0x35, 0xE1, 0xEA,
11571 0x00, 0xE0,
11572 0x26, 0x77,
11573
11574 0x24, 0x49, 0x20, 0xE9,
11575 0x9D, 0xFF, 0x20, 0xEA,
11576
11577 0x16, 0x26, 0x20, 0xE9,
11578 0x57, 0x2E, 0xBF, 0xEA,
11579
11580 0x1C, 0x46, 0xA0, 0xE8,
11581 0x23, 0x4E, 0xA0, 0xE8,
11582
11583 0x2B, 0x56, 0xA0, 0xE8,
11584 0x1D, 0x47, 0xA0, 0xE8,
11585
11586 0x24, 0x4F, 0xA0, 0xE8,
11587 0x2C, 0x57, 0xA0, 0xE8,
11588
11589 0x1C, 0x00,
11590 0x23, 0x00,
11591 0x2B, 0x00,
11592 0x00, 0xE0,
11593
11594 0x1D, 0x00,
11595 0x24, 0x00,
11596 0x2C, 0x00,
11597 0x00, 0xE0,
11598
11599 0x1C, 0x65,
11600 0x23, 0x65,
11601 0x2B, 0x65,
11602 0x00, 0xE0,
11603
11604 0x1D, 0x65,
11605 0x24, 0x65,
11606 0x2C, 0x65,
11607 0x00, 0xE0,
11608
11609 0x1C, 0x23, 0x60, 0xEC,
11610 0x36, 0xD7, 0x36, 0xAD,
11611
11612 0x2B, 0x80, 0x60, 0xEC,
11613 0x1D, 0x24, 0x60, 0xEC,
11614
11615 0x3E, 0xD7, 0x3E, 0xAD,
11616 0x2C, 0x80, 0x60, 0xEC,
11617
11618 0x1C, 0x2B, 0xDE, 0xE8,
11619 0x23, 0x80, 0xDE, 0xE8,
11620
11621 0x36, 0x80, 0x36, 0xBD,
11622 0x3E, 0x80, 0x3E, 0xBD,
11623
11624 0x33, 0xD7, 0x1C, 0xBD,
11625 0x3B, 0xD7, 0x23, 0xBD,
11626
11627 0x46, 0x80, 0x46, 0xCF,
11628 0x4F, 0x80, 0x4F, 0xCF,
11629
11630 0x56, 0x33, 0x56, 0xCF,
11631 0x47, 0x3B, 0x47, 0xCF,
11632
11633 0xC5, 0xFF, 0x20, 0xEA,
11634 0x00, 0x80, 0x00, 0xE8,
11635
11636 0x4E, 0x33, 0x4E, 0xCF,
11637 0x57, 0x3B, 0x57, 0xCF,
11638
11639 0x8B, 0xFF, 0x20, 0xEA,
11640 0x57, 0xC0, 0xBF, 0xEA,
11641
11642 0x00, 0x80, 0xA0, 0xE9,
11643 0x00, 0x00, 0xD8, 0xEC,
11644
11645};
diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c
index 651b93c8ab5d..9aad4847afdf 100644
--- a/drivers/gpu/drm/mga/mga_warp.c
+++ b/drivers/gpu/drm/mga/mga_warp.c
@@ -27,132 +27,108 @@
27 * Gareth Hughes <gareth@valinux.com> 27 * Gareth Hughes <gareth@valinux.com>
28 */ 28 */
29 29
30#include <linux/firmware.h>
31#include <linux/ihex.h>
32#include <linux/platform_device.h>
33
30#include "drmP.h" 34#include "drmP.h"
31#include "drm.h" 35#include "drm.h"
32#include "mga_drm.h" 36#include "mga_drm.h"
33#include "mga_drv.h" 37#include "mga_drv.h"
34#include "mga_ucode.h" 38
39#define FIRMWARE_G200 "matrox/g200_warp.fw"
40#define FIRMWARE_G400 "matrox/g400_warp.fw"
41
42MODULE_FIRMWARE(FIRMWARE_G200);
43MODULE_FIRMWARE(FIRMWARE_G400);
35 44
36#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ 45#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
37 46
38#define WARP_UCODE_SIZE( which ) \ 47#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN)
39 ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) 48
40 49int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
41#define WARP_UCODE_INSTALL( which, where ) \
42do { \
43 DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\
44 dev_priv->warp_pipe_phys[where] = pcbase; \
45 memcpy( vcbase, which, sizeof(which) ); \
46 pcbase += WARP_UCODE_SIZE( which ); \
47 vcbase += WARP_UCODE_SIZE( which ); \
48} while (0)
49
50static const unsigned int mga_warp_g400_microcode_size =
51 (WARP_UCODE_SIZE(warp_g400_tgz) +
52 WARP_UCODE_SIZE(warp_g400_tgza) +
53 WARP_UCODE_SIZE(warp_g400_tgzaf) +
54 WARP_UCODE_SIZE(warp_g400_tgzf) +
55 WARP_UCODE_SIZE(warp_g400_tgzs) +
56 WARP_UCODE_SIZE(warp_g400_tgzsa) +
57 WARP_UCODE_SIZE(warp_g400_tgzsaf) +
58 WARP_UCODE_SIZE(warp_g400_tgzsf) +
59 WARP_UCODE_SIZE(warp_g400_t2gz) +
60 WARP_UCODE_SIZE(warp_g400_t2gza) +
61 WARP_UCODE_SIZE(warp_g400_t2gzaf) +
62 WARP_UCODE_SIZE(warp_g400_t2gzf) +
63 WARP_UCODE_SIZE(warp_g400_t2gzs) +
64 WARP_UCODE_SIZE(warp_g400_t2gzsa) +
65 WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
66
67static const unsigned int mga_warp_g200_microcode_size =
68 (WARP_UCODE_SIZE(warp_g200_tgz) +
69 WARP_UCODE_SIZE(warp_g200_tgza) +
70 WARP_UCODE_SIZE(warp_g200_tgzaf) +
71 WARP_UCODE_SIZE(warp_g200_tgzf) +
72 WARP_UCODE_SIZE(warp_g200_tgzs) +
73 WARP_UCODE_SIZE(warp_g200_tgzsa) +
74 WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
75
76unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
77{ 50{
51 unsigned char *vcbase = dev_priv->warp->handle;
52 unsigned long pcbase = dev_priv->warp->offset;
53 const char *firmware_name;
54 struct platform_device *pdev;
55 const struct firmware *fw = NULL;
56 const struct ihex_binrec *rec;
57 unsigned int size;
58 int n_pipes, where;
59 int rc = 0;
60
78 switch (dev_priv->chipset) { 61 switch (dev_priv->chipset) {
79 case MGA_CARD_TYPE_G400: 62 case MGA_CARD_TYPE_G400:
80 case MGA_CARD_TYPE_G550: 63 case MGA_CARD_TYPE_G550:
81 return PAGE_ALIGN(mga_warp_g400_microcode_size); 64 firmware_name = FIRMWARE_G400;
65 n_pipes = MGA_MAX_G400_PIPES;
66 break;
82 case MGA_CARD_TYPE_G200: 67 case MGA_CARD_TYPE_G200:
83 return PAGE_ALIGN(mga_warp_g200_microcode_size); 68 firmware_name = FIRMWARE_G200;
69 n_pipes = MGA_MAX_G200_PIPES;
70 break;
84 default: 71 default:
85 return 0; 72 return -EINVAL;
86 } 73 }
87}
88
89static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
90{
91 unsigned char *vcbase = dev_priv->warp->handle;
92 unsigned long pcbase = dev_priv->warp->offset;
93
94 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
95
96 WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
97 WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
98 WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
99 WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
100 WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
101 WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
102 WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
103 WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
104
105 WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
106 WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
107 WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
108 WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
109 WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
110 WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
111 WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
112 WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
113
114 return 0;
115}
116
117static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
118{
119 unsigned char *vcbase = dev_priv->warp->handle;
120 unsigned long pcbase = dev_priv->warp->offset;
121
122 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
123
124 WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ);
125 WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF);
126 WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA);
127 WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF);
128 WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS);
129 WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF);
130 WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA);
131 WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF);
132 74
133 return 0; 75 pdev = platform_device_register_simple("mga_warp", 0, NULL, 0);
134} 76 if (IS_ERR(pdev)) {
77 DRM_ERROR("mga: Failed to register microcode\n");
78 return PTR_ERR(pdev);
79 }
80 rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev);
81 platform_device_unregister(pdev);
82 if (rc) {
83 DRM_ERROR("mga: Failed to load microcode \"%s\"\n",
84 firmware_name);
85 return rc;
86 }
135 87
136int mga_warp_install_microcode(drm_mga_private_t * dev_priv) 88 size = 0;
137{ 89 where = 0;
138 const unsigned int size = mga_warp_microcode_size(dev_priv); 90 for (rec = (const struct ihex_binrec *)fw->data;
91 rec;
92 rec = ihex_next_binrec(rec)) {
93 size += WARP_UCODE_SIZE(be16_to_cpu(rec->len));
94 where++;
95 }
139 96
97 if (where != n_pipes) {
98 DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name);
99 rc = -EINVAL;
100 goto out;
101 }
102 size = PAGE_ALIGN(size);
140 DRM_DEBUG("MGA ucode size = %d bytes\n", size); 103 DRM_DEBUG("MGA ucode size = %d bytes\n", size);
141 if (size > dev_priv->warp->size) { 104 if (size > dev_priv->warp->size) {
142 DRM_ERROR("microcode too large! (%u > %lu)\n", 105 DRM_ERROR("microcode too large! (%u > %lu)\n",
143 size, dev_priv->warp->size); 106 size, dev_priv->warp->size);
144 return -ENOMEM; 107 rc = -ENOMEM;
108 goto out;
145 } 109 }
146 110
147 switch (dev_priv->chipset) { 111 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
148 case MGA_CARD_TYPE_G400: 112
149 case MGA_CARD_TYPE_G550: 113 where = 0;
150 return mga_warp_install_g400_microcode(dev_priv); 114 for (rec = (const struct ihex_binrec *)fw->data;
151 case MGA_CARD_TYPE_G200: 115 rec;
152 return mga_warp_install_g200_microcode(dev_priv); 116 rec = ihex_next_binrec(rec)) {
153 default: 117 unsigned int src_size, dst_size;
154 return -EINVAL; 118
119 DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase);
120 dev_priv->warp_pipe_phys[where] = pcbase;
121 src_size = be16_to_cpu(rec->len);
122 dst_size = WARP_UCODE_SIZE(src_size);
123 memcpy(vcbase, rec->data, src_size);
124 pcbase += dst_size;
125 vcbase += dst_size;
126 where++;
155 } 127 }
128
129out:
130 release_firmware(fw);
131 return rc;
156} 132}
157 133
158#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) 134#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index c75fd3564040..4c39a407aa4a 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -29,6 +29,9 @@
29 * Gareth Hughes <gareth@valinux.com> 29 * Gareth Hughes <gareth@valinux.com>
30 */ 30 */
31 31
32#include <linux/firmware.h>
33#include <linux/platform_device.h>
34
32#include "drmP.h" 35#include "drmP.h"
33#include "drm.h" 36#include "drm.h"
34#include "r128_drm.h" 37#include "r128_drm.h"
@@ -36,50 +39,9 @@
36 39
37#define R128_FIFO_DEBUG 0 40#define R128_FIFO_DEBUG 0
38 41
39/* CCE microcode (from ATI) */ 42#define FIRMWARE_NAME "r128/r128_cce.bin"
40static u32 r128_cce_microcode[] = { 43
41 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 44MODULE_FIRMWARE(FIRMWARE_NAME);
42 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
43 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
44 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
45 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
46 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
47 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
48 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
49 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
50 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
51 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
52 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
53 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
54 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
55 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
56 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
57 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
58 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
59 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
60 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
61 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
62 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
63 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
64 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
65 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
66 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
67 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
68 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
69 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
70 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
71 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
72 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
73 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
74 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
75 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82};
83 45
84static int R128_READ_PLL(struct drm_device * dev, int addr) 46static int R128_READ_PLL(struct drm_device * dev, int addr)
85{ 47{
@@ -176,20 +138,50 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
176 */ 138 */
177 139
178/* Load the microcode for the CCE */ 140/* Load the microcode for the CCE */
179static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) 141static int r128_cce_load_microcode(drm_r128_private_t *dev_priv)
180{ 142{
181 int i; 143 struct platform_device *pdev;
144 const struct firmware *fw;
145 const __be32 *fw_data;
146 int rc, i;
182 147
183 DRM_DEBUG("\n"); 148 DRM_DEBUG("\n");
184 149
150 pdev = platform_device_register_simple("r128_cce", 0, NULL, 0);
151 if (IS_ERR(pdev)) {
152 printk(KERN_ERR "r128_cce: Failed to register firmware\n");
153 return PTR_ERR(pdev);
154 }
155 rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev);
156 platform_device_unregister(pdev);
157 if (rc) {
158 printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n",
159 FIRMWARE_NAME);
160 return rc;
161 }
162
163 if (fw->size != 256 * 8) {
164 printk(KERN_ERR
165 "r128_cce: Bogus length %zu in firmware \"%s\"\n",
166 fw->size, FIRMWARE_NAME);
167 rc = -EINVAL;
168 goto out_release;
169 }
170
185 r128_do_wait_for_idle(dev_priv); 171 r128_do_wait_for_idle(dev_priv);
186 172
173 fw_data = (const __be32 *)fw->data;
187 R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); 174 R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
188 for (i = 0; i < 256; i++) { 175 for (i = 0; i < 256; i++) {
189 R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); 176 R128_WRITE(R128_PM4_MICROCODE_DATAH,
177 be32_to_cpup(&fw_data[i * 2]));
190 R128_WRITE(R128_PM4_MICROCODE_DATAL, 178 R128_WRITE(R128_PM4_MICROCODE_DATAL,
191 r128_cce_microcode[i * 2 + 1]); 179 be32_to_cpup(&fw_data[i * 2 + 1]));
192 } 180 }
181
182out_release:
183 release_firmware(fw);
184 return rc;
193} 185}
194 186
195/* Flush any pending commands to the CCE. This should only be used just 187/* Flush any pending commands to the CCE. This should only be used just
@@ -350,9 +342,15 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev,
350static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) 342static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
351{ 343{
352 drm_r128_private_t *dev_priv; 344 drm_r128_private_t *dev_priv;
345 int rc;
353 346
354 DRM_DEBUG("\n"); 347 DRM_DEBUG("\n");
355 348
349 if (dev->dev_private) {
350 DRM_DEBUG("called when already initialized\n");
351 return -EINVAL;
352 }
353
356 dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL); 354 dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL);
357 if (dev_priv == NULL) 355 if (dev_priv == NULL)
358 return -ENOMEM; 356 return -ENOMEM;
@@ -575,13 +573,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
575#endif 573#endif
576 574
577 r128_cce_init_ring_buffer(dev, dev_priv); 575 r128_cce_init_ring_buffer(dev, dev_priv);
578 r128_cce_load_microcode(dev_priv); 576 rc = r128_cce_load_microcode(dev_priv);
579 577
580 dev->dev_private = (void *)dev_priv; 578 dev->dev_private = (void *)dev_priv;
581 579
582 r128_do_engine_reset(dev); 580 r128_do_engine_reset(dev);
583 581
584 return 0; 582 if (rc) {
583 DRM_ERROR("Failed to load firmware!\n");
584 r128_do_cleanup_cce(dev);
585 }
586
587 return rc;
585} 588}
586 589
587int r128_do_cleanup_cce(struct drm_device * dev) 590int r128_do_cleanup_cce(struct drm_device * dev)
@@ -649,6 +652,8 @@ int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_pri
649 652
650 LOCK_TEST_WITH_RETURN(dev, file_priv); 653 LOCK_TEST_WITH_RETURN(dev, file_priv);
651 654
655 DEV_INIT_TEST_WITH_RETURN(dev_priv);
656
652 if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { 657 if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
653 DRM_DEBUG("while CCE running\n"); 658 DRM_DEBUG("while CCE running\n");
654 return 0; 659 return 0;
@@ -671,6 +676,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv
671 676
672 LOCK_TEST_WITH_RETURN(dev, file_priv); 677 LOCK_TEST_WITH_RETURN(dev, file_priv);
673 678
679 DEV_INIT_TEST_WITH_RETURN(dev_priv);
680
674 /* Flush any pending CCE commands. This ensures any outstanding 681 /* Flush any pending CCE commands. This ensures any outstanding
675 * commands are exectuted by the engine before we turn it off. 682 * commands are exectuted by the engine before we turn it off.
676 */ 683 */
@@ -708,10 +715,7 @@ int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_pri
708 715
709 LOCK_TEST_WITH_RETURN(dev, file_priv); 716 LOCK_TEST_WITH_RETURN(dev, file_priv);
710 717
711 if (!dev_priv) { 718 DEV_INIT_TEST_WITH_RETURN(dev_priv);
712 DRM_DEBUG("called before init done\n");
713 return -EINVAL;
714 }
715 719
716 r128_do_cce_reset(dev_priv); 720 r128_do_cce_reset(dev_priv);
717 721
@@ -728,6 +732,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv
728 732
729 LOCK_TEST_WITH_RETURN(dev, file_priv); 733 LOCK_TEST_WITH_RETURN(dev, file_priv);
730 734
735 DEV_INIT_TEST_WITH_RETURN(dev_priv);
736
731 if (dev_priv->cce_running) { 737 if (dev_priv->cce_running) {
732 r128_do_cce_flush(dev_priv); 738 r128_do_cce_flush(dev_priv);
733 } 739 }
@@ -741,6 +747,8 @@ int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_
741 747
742 LOCK_TEST_WITH_RETURN(dev, file_priv); 748 LOCK_TEST_WITH_RETURN(dev, file_priv);
743 749
750 DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
751
744 return r128_do_engine_reset(dev); 752 return r128_do_engine_reset(dev);
745} 753}
746 754
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
index 797a26c42dab..3c60829d82e9 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -422,6 +422,14 @@ static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
422 * Misc helper macros 422 * Misc helper macros
423 */ 423 */
424 424
425#define DEV_INIT_TEST_WITH_RETURN(_dev_priv) \
426do { \
427 if (!_dev_priv) { \
428 DRM_ERROR("called with no initialization\n"); \
429 return -EINVAL; \
430 } \
431} while (0)
432
425#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ 433#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
426do { \ 434do { \
427 drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ 435 drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c
index 026a48c95c8f..af2665cf4718 100644
--- a/drivers/gpu/drm/r128/r128_state.c
+++ b/drivers/gpu/drm/r128/r128_state.c
@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1244static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) 1244static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
1245{ 1245{
1246 drm_r128_private_t *dev_priv = dev->dev_private; 1246 drm_r128_private_t *dev_priv = dev->dev_private;
1247 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; 1247 drm_r128_sarea_t *sarea_priv;
1248 drm_r128_clear_t *clear = data; 1248 drm_r128_clear_t *clear = data;
1249 DRM_DEBUG("\n"); 1249 DRM_DEBUG("\n");
1250 1250
1251 LOCK_TEST_WITH_RETURN(dev, file_priv); 1251 LOCK_TEST_WITH_RETURN(dev, file_priv);
1252 1252
1253 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1254
1253 RING_SPACE_TEST_WITH_RETURN(dev_priv); 1255 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1254 1256
1257 sarea_priv = dev_priv->sarea_priv;
1258
1255 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) 1259 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1256 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; 1260 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1257 1261
@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *fi
1312 1316
1313 LOCK_TEST_WITH_RETURN(dev, file_priv); 1317 LOCK_TEST_WITH_RETURN(dev, file_priv);
1314 1318
1319 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1320
1315 RING_SPACE_TEST_WITH_RETURN(dev_priv); 1321 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1316 1322
1317 if (!dev_priv->page_flipping) 1323 if (!dev_priv->page_flipping)
@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *fi
1331 1337
1332 LOCK_TEST_WITH_RETURN(dev, file_priv); 1338 LOCK_TEST_WITH_RETURN(dev, file_priv);
1333 1339
1340 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1341
1334 RING_SPACE_TEST_WITH_RETURN(dev_priv); 1342 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1335 1343
1336 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) 1344 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *
1354 1362
1355 LOCK_TEST_WITH_RETURN(dev, file_priv); 1363 LOCK_TEST_WITH_RETURN(dev, file_priv);
1356 1364
1357 if (!dev_priv) { 1365 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1358 DRM_ERROR("called with no initialization\n");
1359 return -EINVAL;
1360 }
1361 1366
1362 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", 1367 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
1363 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); 1368 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file
1410 1415
1411 LOCK_TEST_WITH_RETURN(dev, file_priv); 1416 LOCK_TEST_WITH_RETURN(dev, file_priv);
1412 1417
1413 if (!dev_priv) { 1418 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1414 DRM_ERROR("called with no initialization\n");
1415 return -EINVAL;
1416 }
1417 1419
1418 DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, 1420 DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
1419 elts->idx, elts->start, elts->end, elts->discard); 1421 elts->idx, elts->start, elts->end, elts->discard);
@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *fi
1476 1478
1477 LOCK_TEST_WITH_RETURN(dev, file_priv); 1479 LOCK_TEST_WITH_RETURN(dev, file_priv);
1478 1480
1481 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1482
1479 DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); 1483 DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
1480 1484
1481 if (blit->idx < 0 || blit->idx >= dma->buf_count) { 1485 if (blit->idx < 0 || blit->idx >= dma->buf_count) {
@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *f
1501 1505
1502 LOCK_TEST_WITH_RETURN(dev, file_priv); 1506 LOCK_TEST_WITH_RETURN(dev, file_priv);
1503 1507
1508 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1509
1504 RING_SPACE_TEST_WITH_RETURN(dev_priv); 1510 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1505 1511
1506 ret = -EINVAL; 1512 ret = -EINVAL;
@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file
1531 1537
1532 LOCK_TEST_WITH_RETURN(dev, file_priv); 1538 LOCK_TEST_WITH_RETURN(dev, file_priv);
1533 1539
1540 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1541
1534 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) 1542 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
1535 return -EFAULT; 1543 return -EFAULT;
1536 1544
@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file
1555 1563
1556 LOCK_TEST_WITH_RETURN(dev, file_priv); 1564 LOCK_TEST_WITH_RETURN(dev, file_priv);
1557 1565
1558 if (!dev_priv) { 1566 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1559 DRM_ERROR("called with no initialization\n");
1560 return -EINVAL;
1561 }
1562 1567
1563 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", 1568 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
1564 indirect->idx, indirect->start, indirect->end, 1569 indirect->idx, indirect->start, indirect->end,
@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
1620 drm_r128_getparam_t *param = data; 1625 drm_r128_getparam_t *param = data;
1621 int value; 1626 int value;
1622 1627
1623 if (!dev_priv) { 1628 DEV_INIT_TEST_WITH_RETURN(dev_priv);
1624 DRM_ERROR("called with no initialization\n");
1625 return -EINVAL;
1626 }
1627 1629
1628 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); 1630 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1629 1631
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index 2168d67f09a6..5982321be4d5 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -1,7 +1,6 @@
1config DRM_RADEON_KMS 1config DRM_RADEON_KMS
2 bool "Enable modesetting on radeon by default" 2 bool "Enable modesetting on radeon by default"
3 depends on DRM_RADEON 3 depends on DRM_RADEON
4 select DRM_TTM
5 help 4 help
6 Choose this option if you want kernel modesetting enabled by default, 5 Choose this option if you want kernel modesetting enabled by default,
7 and you have a new enough userspace to support this. Running old 6 and you have a new enough userspace to support this. Running old
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 013d38059943..09a28923f46e 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -3,18 +3,53 @@
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5ccflags-y := -Iinclude/drm 5ccflags-y := -Iinclude/drm
6
7hostprogs-y := mkregtable
8
9quiet_cmd_mkregtable = MKREGTABLE $@
10 cmd_mkregtable = $(obj)/mkregtable $< > $@
11
12$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable
13 $(call if_changed,mkregtable)
14
15$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable
16 $(call if_changed,mkregtable)
17
18$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable
19 $(call if_changed,mkregtable)
20
21$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable
22 $(call if_changed,mkregtable)
23
24$(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable
25 $(call if_changed,mkregtable)
26
27$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
28 $(call if_changed,mkregtable)
29
30$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
31
32$(obj)/r200.o: $(obj)/r200_reg_safe.h
33
34$(obj)/rv515.o: $(obj)/rv515_reg_safe.h
35
36$(obj)/r300.o: $(obj)/r300_reg_safe.h
37
38$(obj)/rs600.o: $(obj)/rs600_reg_safe.h
39
6radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ 40radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
7 radeon_irq.o r300_cmdbuf.o r600_cp.o 41 radeon_irq.o r300_cmdbuf.o r600_cp.o
8 42# add KMS driver
9radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \ 43radeon-y += radeon_device.o radeon_kms.o \
10 radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \ 44 radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
11 atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \ 45 atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
12 radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ 46 radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
13 radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \ 47 radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \
14 radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ 48 radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \
15 radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ 49 radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
16 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \ 50 rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
17 radeon_test.o 51 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
52 r600_blit_kms.o
18 53
19radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 54radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
20 55
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index cf67928abbc8..5d402086bc47 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -2374,6 +2374,17 @@ typedef struct _ATOM_ANALOG_TV_INFO {
2374 ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; 2374 ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING];
2375} ATOM_ANALOG_TV_INFO; 2375} ATOM_ANALOG_TV_INFO;
2376 2376
2377#define MAX_SUPPORTED_TV_TIMING_V1_2 3
2378
2379typedef struct _ATOM_ANALOG_TV_INFO_V1_2 {
2380 ATOM_COMMON_TABLE_HEADER sHeader;
2381 UCHAR ucTV_SupportedStandard;
2382 UCHAR ucTV_BootUpDefaultStandard;
2383 UCHAR ucExt_TV_ASIC_ID;
2384 UCHAR ucExt_TV_ASIC_SlaveAddr;
2385 ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING];
2386} ATOM_ANALOG_TV_INFO_V1_2;
2387
2377/**************************************************************************/ 2388/**************************************************************************/
2378/* VRAM usage and their defintions */ 2389/* VRAM usage and their defintions */
2379 2390
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74d034f77c6b..6a015929deee 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -31,6 +31,10 @@
31#include "atom.h" 31#include "atom.h"
32#include "atom-bits.h" 32#include "atom-bits.h"
33 33
34/* evil but including atombios.h is much worse */
35bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
36 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
37 int32_t *pixel_clock);
34static void atombios_overscan_setup(struct drm_crtc *crtc, 38static void atombios_overscan_setup(struct drm_crtc *crtc,
35 struct drm_display_mode *mode, 39 struct drm_display_mode *mode,
36 struct drm_display_mode *adjusted_mode) 40 struct drm_display_mode *adjusted_mode)
@@ -89,17 +93,32 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
89 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 93 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
90 ENABLE_SCALER_PS_ALLOCATION args; 94 ENABLE_SCALER_PS_ALLOCATION args;
91 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); 95 int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
96
92 /* fixme - fill in enc_priv for atom dac */ 97 /* fixme - fill in enc_priv for atom dac */
93 enum radeon_tv_std tv_std = TV_STD_NTSC; 98 enum radeon_tv_std tv_std = TV_STD_NTSC;
99 bool is_tv = false, is_cv = false;
100 struct drm_encoder *encoder;
94 101
95 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) 102 if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
96 return; 103 return;
97 104
105 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
106 /* find tv std */
107 if (encoder->crtc == crtc) {
108 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
109 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
110 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
111 tv_std = tv_dac->tv_std;
112 is_tv = true;
113 }
114 }
115 }
116
98 memset(&args, 0, sizeof(args)); 117 memset(&args, 0, sizeof(args));
99 118
100 args.ucScaler = radeon_crtc->crtc_id; 119 args.ucScaler = radeon_crtc->crtc_id;
101 120
102 if (radeon_crtc->devices & (ATOM_DEVICE_TV_SUPPORT)) { 121 if (is_tv) {
103 switch (tv_std) { 122 switch (tv_std) {
104 case TV_STD_NTSC: 123 case TV_STD_NTSC:
105 default: 124 default:
@@ -128,7 +147,7 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
128 break; 147 break;
129 } 148 }
130 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 149 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
131 } else if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT)) { 150 } else if (is_cv) {
132 args.ucTVStandard = ATOM_TV_CV; 151 args.ucTVStandard = ATOM_TV_CV;
133 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 152 args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
134 } else { 153 } else {
@@ -151,9 +170,9 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
151 } 170 }
152 } 171 }
153 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 172 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
154 if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) 173 if ((is_tv || is_cv)
155 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) { 174 && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
156 atom_rv515_force_tv_scaler(rdev); 175 atom_rv515_force_tv_scaler(rdev, radeon_crtc);
157 } 176 }
158} 177}
159 178
@@ -370,6 +389,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
370 pll_flags |= RADEON_PLL_USE_REF_DIV; 389 pll_flags |= RADEON_PLL_USE_REF_DIV;
371 } 390 }
372 radeon_encoder = to_radeon_encoder(encoder); 391 radeon_encoder = to_radeon_encoder(encoder);
392 break;
373 } 393 }
374 } 394 }
375 395
@@ -468,6 +488,11 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
468 } 488 }
469 489
470 switch (crtc->fb->bits_per_pixel) { 490 switch (crtc->fb->bits_per_pixel) {
491 case 8:
492 fb_format =
493 AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
494 AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
495 break;
471 case 15: 496 case 15:
472 fb_format = 497 fb_format =
473 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | 498 AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
@@ -551,42 +576,68 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
551 struct radeon_device *rdev = dev->dev_private; 576 struct radeon_device *rdev = dev->dev_private;
552 struct drm_encoder *encoder; 577 struct drm_encoder *encoder;
553 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; 578 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
579 int need_tv_timings = 0;
580 bool ret;
554 581
555 /* TODO color tiling */ 582 /* TODO color tiling */
556 memset(&crtc_timing, 0, sizeof(crtc_timing)); 583 memset(&crtc_timing, 0, sizeof(crtc_timing));
557 584
558 /* TODO tv */
559 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 585 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
560 586 /* find tv std */
587 if (encoder->crtc == crtc) {
588 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
589
590 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
591 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
592 if (tv_dac) {
593 if (tv_dac->tv_std == TV_STD_NTSC ||
594 tv_dac->tv_std == TV_STD_NTSC_J ||
595 tv_dac->tv_std == TV_STD_PAL_M)
596 need_tv_timings = 1;
597 else
598 need_tv_timings = 2;
599 break;
600 }
601 }
602 }
561 } 603 }
562 604
563 crtc_timing.ucCRTC = radeon_crtc->crtc_id; 605 crtc_timing.ucCRTC = radeon_crtc->crtc_id;
564 crtc_timing.usH_Total = adjusted_mode->crtc_htotal; 606 if (need_tv_timings) {
565 crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; 607 ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
566 crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; 608 &crtc_timing, &adjusted_mode->clock);
567 crtc_timing.usH_SyncWidth = 609 if (ret == false)
568 adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; 610 need_tv_timings = 0;
611 }
569 612
570 crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; 613 if (!need_tv_timings) {
571 crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; 614 crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
572 crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; 615 crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
573 crtc_timing.usV_SyncWidth = 616 crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
574 adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; 617 crtc_timing.usH_SyncWidth =
618 adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
575 619
576 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) 620 crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
577 crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; 621 crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
622 crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
623 crtc_timing.usV_SyncWidth =
624 adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
578 625
579 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) 626 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
580 crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; 627 crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
581 628
582 if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) 629 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
583 crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; 630 crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
584 631
585 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 632 if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
586 crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; 633 crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
587 634
588 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 635 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
589 crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; 636 crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
637
638 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
639 crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
640 }
590 641
591 atombios_crtc_set_pll(crtc, adjusted_mode); 642 atombios_crtc_set_pll(crtc, adjusted_mode);
592 atombios_crtc_set_timing(crtc, &crtc_timing); 643 atombios_crtc_set_timing(crtc, &crtc_timing);
diff --git a/drivers/gpu/drm/radeon/avivod.h b/drivers/gpu/drm/radeon/avivod.h
new file mode 100644
index 000000000000..e2b92c445bab
--- /dev/null
+++ b/drivers/gpu/drm/radeon/avivod.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright 2009 Advanced Micro Devices, Inc.
3 * Copyright 2009 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 * Jerome Glisse
26 */
27#ifndef AVIVOD_H
28#define AVIVOD_H
29
30
31#define D1CRTC_CONTROL 0x6080
32#define CRTC_EN (1 << 0)
33#define D1CRTC_UPDATE_LOCK 0x60E8
34#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
35#define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118
36
37#define D2CRTC_CONTROL 0x6880
38#define D2CRTC_UPDATE_LOCK 0x68E8
39#define D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910
40#define D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918
41
42#define D1VGA_CONTROL 0x0330
43#define DVGA_CONTROL_MODE_ENABLE (1 << 0)
44#define DVGA_CONTROL_TIMING_SELECT (1 << 8)
45#define DVGA_CONTROL_SYNC_POLARITY_SELECT (1 << 9)
46#define DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1 << 10)
47#define DVGA_CONTROL_OVERSCAN_COLOR_EN (1 << 16)
48#define DVGA_CONTROL_ROTATE (1 << 24)
49#define D2VGA_CONTROL 0x0338
50
51#define VGA_HDP_CONTROL 0x328
52#define VGA_MEM_PAGE_SELECT_EN (1 << 0)
53#define VGA_MEMORY_DISABLE (1 << 4)
54#define VGA_RBBM_LOCK_DISABLE (1 << 8)
55#define VGA_SOFT_RESET (1 << 16)
56#define VGA_MEMORY_BASE_ADDRESS 0x0310
57#define VGA_RENDER_CONTROL 0x0300
58#define VGA_VSTATUS_CNTL_MASK 0x00030000
59
60/* AVIVO disable VGA rendering */
61static inline void radeon_avivo_vga_render_disable(struct radeon_device *rdev)
62{
63 u32 vga_render;
64 vga_render = RREG32(VGA_RENDER_CONTROL);
65 vga_render &= ~VGA_VSTATUS_CNTL_MASK;
66 WREG32(VGA_RENDER_CONTROL, vga_render);
67}
68
69#endif
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c
new file mode 100644
index 000000000000..fb211e585dea
--- /dev/null
+++ b/drivers/gpu/drm/radeon/mkregtable.c
@@ -0,0 +1,720 @@
1/* utility to create the register check tables
2 * this includes inlined list.h safe for userspace.
3 *
4 * Copyright 2009 Jerome Glisse
5 * Copyright 2009 Red Hat Inc.
6 *
7 * Authors:
8 * Jerome Glisse
9 * Dave Airlie
10 */
11
12#include <sys/types.h>
13#include <stdlib.h>
14#include <string.h>
15#include <stdio.h>
16#include <regex.h>
17#include <libgen.h>
18
19#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
20/**
21 * container_of - cast a member of a structure out to the containing structure
22 * @ptr: the pointer to the member.
23 * @type: the type of the container struct this is embedded in.
24 * @member: the name of the member within the struct.
25 *
26 */
27#define container_of(ptr, type, member) ({ \
28 const typeof(((type *)0)->member)*__mptr = (ptr); \
29 (type *)((char *)__mptr - offsetof(type, member)); })
30
31/*
32 * Simple doubly linked list implementation.
33 *
34 * Some of the internal functions ("__xxx") are useful when
35 * manipulating whole lists rather than single entries, as
36 * sometimes we already know the next/prev entries and we can
37 * generate better code by using them directly rather than
38 * using the generic single-entry routines.
39 */
40
41struct list_head {
42 struct list_head *next, *prev;
43};
44
45#define LIST_HEAD_INIT(name) { &(name), &(name) }
46
47#define LIST_HEAD(name) \
48 struct list_head name = LIST_HEAD_INIT(name)
49
50static inline void INIT_LIST_HEAD(struct list_head *list)
51{
52 list->next = list;
53 list->prev = list;
54}
55
56/*
57 * Insert a new entry between two known consecutive entries.
58 *
59 * This is only for internal list manipulation where we know
60 * the prev/next entries already!
61 */
62#ifndef CONFIG_DEBUG_LIST
63static inline void __list_add(struct list_head *new,
64 struct list_head *prev, struct list_head *next)
65{
66 next->prev = new;
67 new->next = next;
68 new->prev = prev;
69 prev->next = new;
70}
71#else
72extern void __list_add(struct list_head *new,
73 struct list_head *prev, struct list_head *next);
74#endif
75
76/**
77 * list_add - add a new entry
78 * @new: new entry to be added
79 * @head: list head to add it after
80 *
81 * Insert a new entry after the specified head.
82 * This is good for implementing stacks.
83 */
84static inline void list_add(struct list_head *new, struct list_head *head)
85{
86 __list_add(new, head, head->next);
87}
88
89/**
90 * list_add_tail - add a new entry
91 * @new: new entry to be added
92 * @head: list head to add it before
93 *
94 * Insert a new entry before the specified head.
95 * This is useful for implementing queues.
96 */
97static inline void list_add_tail(struct list_head *new, struct list_head *head)
98{
99 __list_add(new, head->prev, head);
100}
101
102/*
103 * Delete a list entry by making the prev/next entries
104 * point to each other.
105 *
106 * This is only for internal list manipulation where we know
107 * the prev/next entries already!
108 */
109static inline void __list_del(struct list_head *prev, struct list_head *next)
110{
111 next->prev = prev;
112 prev->next = next;
113}
114
115/**
116 * list_del - deletes entry from list.
117 * @entry: the element to delete from the list.
118 * Note: list_empty() on entry does not return true after this, the entry is
119 * in an undefined state.
120 */
121#ifndef CONFIG_DEBUG_LIST
122static inline void list_del(struct list_head *entry)
123{
124 __list_del(entry->prev, entry->next);
125 entry->next = (void *)0xDEADBEEF;
126 entry->prev = (void *)0xBEEFDEAD;
127}
128#else
129extern void list_del(struct list_head *entry);
130#endif
131
132/**
133 * list_replace - replace old entry by new one
134 * @old : the element to be replaced
135 * @new : the new element to insert
136 *
137 * If @old was empty, it will be overwritten.
138 */
139static inline void list_replace(struct list_head *old, struct list_head *new)
140{
141 new->next = old->next;
142 new->next->prev = new;
143 new->prev = old->prev;
144 new->prev->next = new;
145}
146
147static inline void list_replace_init(struct list_head *old,
148 struct list_head *new)
149{
150 list_replace(old, new);
151 INIT_LIST_HEAD(old);
152}
153
154/**
155 * list_del_init - deletes entry from list and reinitialize it.
156 * @entry: the element to delete from the list.
157 */
158static inline void list_del_init(struct list_head *entry)
159{
160 __list_del(entry->prev, entry->next);
161 INIT_LIST_HEAD(entry);
162}
163
164/**
165 * list_move - delete from one list and add as another's head
166 * @list: the entry to move
167 * @head: the head that will precede our entry
168 */
169static inline void list_move(struct list_head *list, struct list_head *head)
170{
171 __list_del(list->prev, list->next);
172 list_add(list, head);
173}
174
175/**
176 * list_move_tail - delete from one list and add as another's tail
177 * @list: the entry to move
178 * @head: the head that will follow our entry
179 */
180static inline void list_move_tail(struct list_head *list,
181 struct list_head *head)
182{
183 __list_del(list->prev, list->next);
184 list_add_tail(list, head);
185}
186
187/**
188 * list_is_last - tests whether @list is the last entry in list @head
189 * @list: the entry to test
190 * @head: the head of the list
191 */
192static inline int list_is_last(const struct list_head *list,
193 const struct list_head *head)
194{
195 return list->next == head;
196}
197
198/**
199 * list_empty - tests whether a list is empty
200 * @head: the list to test.
201 */
202static inline int list_empty(const struct list_head *head)
203{
204 return head->next == head;
205}
206
207/**
208 * list_empty_careful - tests whether a list is empty and not being modified
209 * @head: the list to test
210 *
211 * Description:
212 * tests whether a list is empty _and_ checks that no other CPU might be
213 * in the process of modifying either member (next or prev)
214 *
215 * NOTE: using list_empty_careful() without synchronization
216 * can only be safe if the only activity that can happen
217 * to the list entry is list_del_init(). Eg. it cannot be used
218 * if another CPU could re-list_add() it.
219 */
220static inline int list_empty_careful(const struct list_head *head)
221{
222 struct list_head *next = head->next;
223 return (next == head) && (next == head->prev);
224}
225
226/**
227 * list_is_singular - tests whether a list has just one entry.
228 * @head: the list to test.
229 */
230static inline int list_is_singular(const struct list_head *head)
231{
232 return !list_empty(head) && (head->next == head->prev);
233}
234
235static inline void __list_cut_position(struct list_head *list,
236 struct list_head *head,
237 struct list_head *entry)
238{
239 struct list_head *new_first = entry->next;
240 list->next = head->next;
241 list->next->prev = list;
242 list->prev = entry;
243 entry->next = list;
244 head->next = new_first;
245 new_first->prev = head;
246}
247
248/**
249 * list_cut_position - cut a list into two
250 * @list: a new list to add all removed entries
251 * @head: a list with entries
252 * @entry: an entry within head, could be the head itself
253 * and if so we won't cut the list
254 *
255 * This helper moves the initial part of @head, up to and
256 * including @entry, from @head to @list. You should
257 * pass on @entry an element you know is on @head. @list
258 * should be an empty list or a list you do not care about
259 * losing its data.
260 *
261 */
262static inline void list_cut_position(struct list_head *list,
263 struct list_head *head,
264 struct list_head *entry)
265{
266 if (list_empty(head))
267 return;
268 if (list_is_singular(head) && (head->next != entry && head != entry))
269 return;
270 if (entry == head)
271 INIT_LIST_HEAD(list);
272 else
273 __list_cut_position(list, head, entry);
274}
275
276static inline void __list_splice(const struct list_head *list,
277 struct list_head *prev, struct list_head *next)
278{
279 struct list_head *first = list->next;
280 struct list_head *last = list->prev;
281
282 first->prev = prev;
283 prev->next = first;
284
285 last->next = next;
286 next->prev = last;
287}
288
289/**
290 * list_splice - join two lists, this is designed for stacks
291 * @list: the new list to add.
292 * @head: the place to add it in the first list.
293 */
294static inline void list_splice(const struct list_head *list,
295 struct list_head *head)
296{
297 if (!list_empty(list))
298 __list_splice(list, head, head->next);
299}
300
301/**
302 * list_splice_tail - join two lists, each list being a queue
303 * @list: the new list to add.
304 * @head: the place to add it in the first list.
305 */
306static inline void list_splice_tail(struct list_head *list,
307 struct list_head *head)
308{
309 if (!list_empty(list))
310 __list_splice(list, head->prev, head);
311}
312
313/**
314 * list_splice_init - join two lists and reinitialise the emptied list.
315 * @list: the new list to add.
316 * @head: the place to add it in the first list.
317 *
318 * The list at @list is reinitialised
319 */
320static inline void list_splice_init(struct list_head *list,
321 struct list_head *head)
322{
323 if (!list_empty(list)) {
324 __list_splice(list, head, head->next);
325 INIT_LIST_HEAD(list);
326 }
327}
328
329/**
330 * list_splice_tail_init - join two lists and reinitialise the emptied list
331 * @list: the new list to add.
332 * @head: the place to add it in the first list.
333 *
334 * Each of the lists is a queue.
335 * The list at @list is reinitialised
336 */
337static inline void list_splice_tail_init(struct list_head *list,
338 struct list_head *head)
339{
340 if (!list_empty(list)) {
341 __list_splice(list, head->prev, head);
342 INIT_LIST_HEAD(list);
343 }
344}
345
346/**
347 * list_entry - get the struct for this entry
348 * @ptr: the &struct list_head pointer.
349 * @type: the type of the struct this is embedded in.
350 * @member: the name of the list_struct within the struct.
351 */
352#define list_entry(ptr, type, member) \
353 container_of(ptr, type, member)
354
355/**
356 * list_first_entry - get the first element from a list
357 * @ptr: the list head to take the element from.
358 * @type: the type of the struct this is embedded in.
359 * @member: the name of the list_struct within the struct.
360 *
361 * Note, that list is expected to be not empty.
362 */
363#define list_first_entry(ptr, type, member) \
364 list_entry((ptr)->next, type, member)
365
366/**
367 * list_for_each - iterate over a list
368 * @pos: the &struct list_head to use as a loop cursor.
369 * @head: the head for your list.
370 */
371#define list_for_each(pos, head) \
372 for (pos = (head)->next; prefetch(pos->next), pos != (head); \
373 pos = pos->next)
374
375/**
376 * __list_for_each - iterate over a list
377 * @pos: the &struct list_head to use as a loop cursor.
378 * @head: the head for your list.
379 *
380 * This variant differs from list_for_each() in that it's the
381 * simplest possible list iteration code, no prefetching is done.
382 * Use this for code that knows the list to be very short (empty
383 * or 1 entry) most of the time.
384 */
385#define __list_for_each(pos, head) \
386 for (pos = (head)->next; pos != (head); pos = pos->next)
387
388/**
389 * list_for_each_prev - iterate over a list backwards
390 * @pos: the &struct list_head to use as a loop cursor.
391 * @head: the head for your list.
392 */
393#define list_for_each_prev(pos, head) \
394 for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
395 pos = pos->prev)
396
397/**
398 * list_for_each_safe - iterate over a list safe against removal of list entry
399 * @pos: the &struct list_head to use as a loop cursor.
400 * @n: another &struct list_head to use as temporary storage
401 * @head: the head for your list.
402 */
403#define list_for_each_safe(pos, n, head) \
404 for (pos = (head)->next, n = pos->next; pos != (head); \
405 pos = n, n = pos->next)
406
407/**
408 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
409 * @pos: the &struct list_head to use as a loop cursor.
410 * @n: another &struct list_head to use as temporary storage
411 * @head: the head for your list.
412 */
413#define list_for_each_prev_safe(pos, n, head) \
414 for (pos = (head)->prev, n = pos->prev; \
415 prefetch(pos->prev), pos != (head); \
416 pos = n, n = pos->prev)
417
418/**
419 * list_for_each_entry - iterate over list of given type
420 * @pos: the type * to use as a loop cursor.
421 * @head: the head for your list.
422 * @member: the name of the list_struct within the struct.
423 */
424#define list_for_each_entry(pos, head, member) \
425 for (pos = list_entry((head)->next, typeof(*pos), member); \
426 &pos->member != (head); \
427 pos = list_entry(pos->member.next, typeof(*pos), member))
428
429/**
430 * list_for_each_entry_reverse - iterate backwards over list of given type.
431 * @pos: the type * to use as a loop cursor.
432 * @head: the head for your list.
433 * @member: the name of the list_struct within the struct.
434 */
435#define list_for_each_entry_reverse(pos, head, member) \
436 for (pos = list_entry((head)->prev, typeof(*pos), member); \
437 prefetch(pos->member.prev), &pos->member != (head); \
438 pos = list_entry(pos->member.prev, typeof(*pos), member))
439
440/**
441 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
442 * @pos: the type * to use as a start point
443 * @head: the head of the list
444 * @member: the name of the list_struct within the struct.
445 *
446 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
447 */
448#define list_prepare_entry(pos, head, member) \
449 ((pos) ? : list_entry(head, typeof(*pos), member))
450
451/**
452 * list_for_each_entry_continue - continue iteration over list of given type
453 * @pos: the type * to use as a loop cursor.
454 * @head: the head for your list.
455 * @member: the name of the list_struct within the struct.
456 *
457 * Continue to iterate over list of given type, continuing after
458 * the current position.
459 */
460#define list_for_each_entry_continue(pos, head, member) \
461 for (pos = list_entry(pos->member.next, typeof(*pos), member); \
462 prefetch(pos->member.next), &pos->member != (head); \
463 pos = list_entry(pos->member.next, typeof(*pos), member))
464
465/**
466 * list_for_each_entry_continue_reverse - iterate backwards from the given point
467 * @pos: the type * to use as a loop cursor.
468 * @head: the head for your list.
469 * @member: the name of the list_struct within the struct.
470 *
471 * Start to iterate over list of given type backwards, continuing after
472 * the current position.
473 */
474#define list_for_each_entry_continue_reverse(pos, head, member) \
475 for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
476 prefetch(pos->member.prev), &pos->member != (head); \
477 pos = list_entry(pos->member.prev, typeof(*pos), member))
478
479/**
480 * list_for_each_entry_from - iterate over list of given type from the current point
481 * @pos: the type * to use as a loop cursor.
482 * @head: the head for your list.
483 * @member: the name of the list_struct within the struct.
484 *
485 * Iterate over list of given type, continuing from current position.
486 */
487#define list_for_each_entry_from(pos, head, member) \
488 for (; prefetch(pos->member.next), &pos->member != (head); \
489 pos = list_entry(pos->member.next, typeof(*pos), member))
490
491/**
492 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
493 * @pos: the type * to use as a loop cursor.
494 * @n: another type * to use as temporary storage
495 * @head: the head for your list.
496 * @member: the name of the list_struct within the struct.
497 */
498#define list_for_each_entry_safe(pos, n, head, member) \
499 for (pos = list_entry((head)->next, typeof(*pos), member), \
500 n = list_entry(pos->member.next, typeof(*pos), member); \
501 &pos->member != (head); \
502 pos = n, n = list_entry(n->member.next, typeof(*n), member))
503
504/**
505 * list_for_each_entry_safe_continue
506 * @pos: the type * to use as a loop cursor.
507 * @n: another type * to use as temporary storage
508 * @head: the head for your list.
509 * @member: the name of the list_struct within the struct.
510 *
511 * Iterate over list of given type, continuing after current point,
512 * safe against removal of list entry.
513 */
514#define list_for_each_entry_safe_continue(pos, n, head, member) \
515 for (pos = list_entry(pos->member.next, typeof(*pos), member), \
516 n = list_entry(pos->member.next, typeof(*pos), member); \
517 &pos->member != (head); \
518 pos = n, n = list_entry(n->member.next, typeof(*n), member))
519
520/**
521 * list_for_each_entry_safe_from
522 * @pos: the type * to use as a loop cursor.
523 * @n: another type * to use as temporary storage
524 * @head: the head for your list.
525 * @member: the name of the list_struct within the struct.
526 *
527 * Iterate over list of given type from current point, safe against
528 * removal of list entry.
529 */
530#define list_for_each_entry_safe_from(pos, n, head, member) \
531 for (n = list_entry(pos->member.next, typeof(*pos), member); \
532 &pos->member != (head); \
533 pos = n, n = list_entry(n->member.next, typeof(*n), member))
534
535/**
536 * list_for_each_entry_safe_reverse
537 * @pos: the type * to use as a loop cursor.
538 * @n: another type * to use as temporary storage
539 * @head: the head for your list.
540 * @member: the name of the list_struct within the struct.
541 *
542 * Iterate backwards over list of given type, safe against removal
543 * of list entry.
544 */
545#define list_for_each_entry_safe_reverse(pos, n, head, member) \
546 for (pos = list_entry((head)->prev, typeof(*pos), member), \
547 n = list_entry(pos->member.prev, typeof(*pos), member); \
548 &pos->member != (head); \
549 pos = n, n = list_entry(n->member.prev, typeof(*n), member))
550
551struct offset {
552 struct list_head list;
553 unsigned offset;
554};
555
556struct table {
557 struct list_head offsets;
558 unsigned offset_max;
559 unsigned nentry;
560 unsigned *table;
561 char *gpu_prefix;
562};
563
564struct offset *offset_new(unsigned o)
565{
566 struct offset *offset;
567
568 offset = (struct offset *)malloc(sizeof(struct offset));
569 if (offset) {
570 INIT_LIST_HEAD(&offset->list);
571 offset->offset = o;
572 }
573 return offset;
574}
575
576void table_offset_add(struct table *t, struct offset *offset)
577{
578 list_add_tail(&offset->list, &t->offsets);
579}
580
581void table_init(struct table *t)
582{
583 INIT_LIST_HEAD(&t->offsets);
584 t->offset_max = 0;
585 t->nentry = 0;
586 t->table = NULL;
587}
588
589void table_print(struct table *t)
590{
591 unsigned nlloop, i, j, n, c, id;
592
593 nlloop = (t->nentry + 3) / 4;
594 c = t->nentry;
595 printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
596 t->nentry);
597 for (i = 0, id = 0; i < nlloop; i++) {
598 n = 4;
599 if (n > c)
600 n = c;
601 c -= n;
602 for (j = 0; j < n; j++) {
603 if (j == 0)
604 printf("\t");
605 else
606 printf(" ");
607 printf("0x%08X,", t->table[id++]);
608 }
609 printf("\n");
610 }
611 printf("};\n");
612}
613
614int table_build(struct table *t)
615{
616 struct offset *offset;
617 unsigned i, m;
618
619 t->nentry = ((t->offset_max >> 2) + 31) / 32;
620 t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
621 if (t->table == NULL)
622 return -1;
623 memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
624 list_for_each_entry(offset, &t->offsets, list) {
625 i = (offset->offset >> 2) / 32;
626 m = (offset->offset >> 2) & 31;
627 m = 1 << m;
628 t->table[i] ^= m;
629 }
630 return 0;
631}
632
633static char gpu_name[10];
634int parser_auth(struct table *t, const char *filename)
635{
636 FILE *file;
637 regex_t mask_rex;
638 regmatch_t match[4];
639 char buf[1024];
640 size_t end;
641 int len;
642 int done = 0;
643 int r;
644 unsigned o;
645 struct offset *offset;
646 char last_reg_s[10];
647 int last_reg;
648
649 if (regcomp
650 (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
651 fprintf(stderr, "Failed to compile regular expression\n");
652 return -1;
653 }
654 file = fopen(filename, "r");
655 if (file == NULL) {
656 fprintf(stderr, "Failed to open: %s\n", filename);
657 return -1;
658 }
659 fseek(file, 0, SEEK_END);
660 end = ftell(file);
661 fseek(file, 0, SEEK_SET);
662
663 /* get header */
664 if (fgets(buf, 1024, file) == NULL)
665 return -1;
666
667 /* first line will contain the last register
668 * and gpu name */
669 sscanf(buf, "%s %s", gpu_name, last_reg_s);
670 t->gpu_prefix = gpu_name;
671 last_reg = strtol(last_reg_s, NULL, 16);
672
673 do {
674 if (fgets(buf, 1024, file) == NULL)
675 return -1;
676 len = strlen(buf);
677 if (ftell(file) == end)
678 done = 1;
679 if (len) {
680 r = regexec(&mask_rex, buf, 4, match, 0);
681 if (r == REG_NOMATCH) {
682 } else if (r) {
683 fprintf(stderr,
684 "Error matching regular expression %d in %s\n",
685 r, filename);
686 return -1;
687 } else {
688 buf[match[0].rm_eo] = 0;
689 buf[match[1].rm_eo] = 0;
690 buf[match[2].rm_eo] = 0;
691 o = strtol(&buf[match[1].rm_so], NULL, 16);
692 offset = offset_new(o);
693 table_offset_add(t, offset);
694 if (o > t->offset_max)
695 t->offset_max = o;
696 }
697 }
698 } while (!done);
699 fclose(file);
700 if (t->offset_max < last_reg)
701 t->offset_max = last_reg;
702 return table_build(t);
703}
704
705int main(int argc, char *argv[])
706{
707 struct table t;
708
709 if (argc != 2) {
710 fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
711 exit(1);
712 }
713 table_init(&t);
714 if (parser_auth(&t, argv[1])) {
715 fprintf(stderr, "Failed to parse file %s\n", argv[1]);
716 return -1;
717 }
718 table_print(&t);
719 return 0;
720}
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 68e728e8be4d..be51c5f7d0f6 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -29,15 +29,41 @@
29#include "drmP.h" 29#include "drmP.h"
30#include "drm.h" 30#include "drm.h"
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32#include "radeon_microcode.h"
33#include "radeon_reg.h" 32#include "radeon_reg.h"
34#include "radeon.h" 33#include "radeon.h"
34#include "r100d.h"
35
36#include <linux/firmware.h>
37#include <linux/platform_device.h>
38
39#include "r100_reg_safe.h"
40#include "rn50_reg_safe.h"
41
42/* Firmware Names */
43#define FIRMWARE_R100 "radeon/R100_cp.bin"
44#define FIRMWARE_R200 "radeon/R200_cp.bin"
45#define FIRMWARE_R300 "radeon/R300_cp.bin"
46#define FIRMWARE_R420 "radeon/R420_cp.bin"
47#define FIRMWARE_RS690 "radeon/RS690_cp.bin"
48#define FIRMWARE_RS600 "radeon/RS600_cp.bin"
49#define FIRMWARE_R520 "radeon/R520_cp.bin"
50
51MODULE_FIRMWARE(FIRMWARE_R100);
52MODULE_FIRMWARE(FIRMWARE_R200);
53MODULE_FIRMWARE(FIRMWARE_R300);
54MODULE_FIRMWARE(FIRMWARE_R420);
55MODULE_FIRMWARE(FIRMWARE_RS690);
56MODULE_FIRMWARE(FIRMWARE_RS600);
57MODULE_FIRMWARE(FIRMWARE_R520);
58
59#include "r100_track.h"
35 60
36/* This files gather functions specifics to: 61/* This files gather functions specifics to:
37 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 62 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
38 * 63 *
39 * Some of these functions might be used by newer ASICs. 64 * Some of these functions might be used by newer ASICs.
40 */ 65 */
66int r200_init(struct radeon_device *rdev);
41void r100_hdp_reset(struct radeon_device *rdev); 67void r100_hdp_reset(struct radeon_device *rdev);
42void r100_gpu_init(struct radeon_device *rdev); 68void r100_gpu_init(struct radeon_device *rdev);
43int r100_gui_wait_for_idle(struct radeon_device *rdev); 69int r100_gui_wait_for_idle(struct radeon_device *rdev);
@@ -58,23 +84,28 @@ void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
58 * could end up in wrong address. */ 84 * could end up in wrong address. */
59} 85}
60 86
61int r100_pci_gart_enable(struct radeon_device *rdev) 87int r100_pci_gart_init(struct radeon_device *rdev)
62{ 88{
63 uint32_t tmp;
64 int r; 89 int r;
65 90
91 if (rdev->gart.table.ram.ptr) {
92 WARN(1, "R100 PCI GART already initialized.\n");
93 return 0;
94 }
66 /* Initialize common gart structure */ 95 /* Initialize common gart structure */
67 r = radeon_gart_init(rdev); 96 r = radeon_gart_init(rdev);
68 if (r) { 97 if (r)
69 return r; 98 return r;
70 } 99 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
71 if (rdev->gart.table.ram.ptr == NULL) { 100 rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
72 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; 101 rdev->asic->gart_set_page = &r100_pci_gart_set_page;
73 r = radeon_gart_table_ram_alloc(rdev); 102 return radeon_gart_table_ram_alloc(rdev);
74 if (r) { 103}
75 return r; 104
76 } 105int r100_pci_gart_enable(struct radeon_device *rdev)
77 } 106{
107 uint32_t tmp;
108
78 /* discard memory request outside of configured range */ 109 /* discard memory request outside of configured range */
79 tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; 110 tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
80 WREG32(RADEON_AIC_CNTL, tmp); 111 WREG32(RADEON_AIC_CNTL, tmp);
@@ -114,13 +145,11 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
114 return 0; 145 return 0;
115} 146}
116 147
117int r100_gart_enable(struct radeon_device *rdev) 148void r100_pci_gart_fini(struct radeon_device *rdev)
118{ 149{
119 if (rdev->flags & RADEON_IS_AGP) { 150 r100_pci_gart_disable(rdev);
120 r100_pci_gart_disable(rdev); 151 radeon_gart_table_ram_free(rdev);
121 return 0; 152 radeon_gart_fini(rdev);
122 }
123 return r100_pci_gart_enable(rdev);
124} 153}
125 154
126 155
@@ -247,9 +276,6 @@ int r100_mc_init(struct radeon_device *rdev)
247 276
248void r100_mc_fini(struct radeon_device *rdev) 277void r100_mc_fini(struct radeon_device *rdev)
249{ 278{
250 r100_pci_gart_disable(rdev);
251 radeon_gart_table_ram_free(rdev);
252 radeon_gart_fini(rdev);
253} 279}
254 280
255 281
@@ -273,6 +299,17 @@ int r100_irq_set(struct radeon_device *rdev)
273 return 0; 299 return 0;
274} 300}
275 301
302void r100_irq_disable(struct radeon_device *rdev)
303{
304 u32 tmp;
305
306 WREG32(R_000040_GEN_INT_CNTL, 0);
307 /* Wait and acknowledge irq */
308 mdelay(1);
309 tmp = RREG32(R_000044_GEN_INT_STATUS);
310 WREG32(R_000044_GEN_INT_STATUS, tmp);
311}
312
276static inline uint32_t r100_irq_ack(struct radeon_device *rdev) 313static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
277{ 314{
278 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); 315 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
@@ -293,6 +330,9 @@ int r100_irq_process(struct radeon_device *rdev)
293 if (!status) { 330 if (!status) {
294 return IRQ_NONE; 331 return IRQ_NONE;
295 } 332 }
333 if (rdev->shutdown) {
334 return IRQ_NONE;
335 }
296 while (status) { 336 while (status) {
297 /* SW interrupt */ 337 /* SW interrupt */
298 if (status & RADEON_SW_INT_TEST) { 338 if (status & RADEON_SW_INT_TEST) {
@@ -367,14 +407,21 @@ int r100_wb_init(struct radeon_device *rdev)
367 return r; 407 return r;
368 } 408 }
369 } 409 }
370 WREG32(0x774, rdev->wb.gpu_addr); 410 WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr);
371 WREG32(0x70C, rdev->wb.gpu_addr + 1024); 411 WREG32(R_00070C_CP_RB_RPTR_ADDR,
372 WREG32(0x770, 0xff); 412 S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + 1024) >> 2));
413 WREG32(R_000770_SCRATCH_UMSK, 0xff);
373 return 0; 414 return 0;
374} 415}
375 416
417void r100_wb_disable(struct radeon_device *rdev)
418{
419 WREG32(R_000770_SCRATCH_UMSK, 0);
420}
421
376void r100_wb_fini(struct radeon_device *rdev) 422void r100_wb_fini(struct radeon_device *rdev)
377{ 423{
424 r100_wb_disable(rdev);
378 if (rdev->wb.wb_obj) { 425 if (rdev->wb.wb_obj) {
379 radeon_object_kunmap(rdev->wb.wb_obj); 426 radeon_object_kunmap(rdev->wb.wb_obj);
380 radeon_object_unpin(rdev->wb.wb_obj); 427 radeon_object_unpin(rdev->wb.wb_obj);
@@ -461,6 +508,21 @@ int r100_copy_blit(struct radeon_device *rdev,
461/* 508/*
462 * CP 509 * CP
463 */ 510 */
511static int r100_cp_wait_for_idle(struct radeon_device *rdev)
512{
513 unsigned i;
514 u32 tmp;
515
516 for (i = 0; i < rdev->usec_timeout; i++) {
517 tmp = RREG32(R_000E40_RBBM_STATUS);
518 if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) {
519 return 0;
520 }
521 udelay(1);
522 }
523 return -1;
524}
525
464void r100_ring_start(struct radeon_device *rdev) 526void r100_ring_start(struct radeon_device *rdev)
465{ 527{
466 int r; 528 int r;
@@ -478,33 +540,33 @@ void r100_ring_start(struct radeon_device *rdev)
478 radeon_ring_unlock_commit(rdev); 540 radeon_ring_unlock_commit(rdev);
479} 541}
480 542
481static void r100_cp_load_microcode(struct radeon_device *rdev) 543
544/* Load the microcode for the CP */
545static int r100_cp_init_microcode(struct radeon_device *rdev)
482{ 546{
483 int i; 547 struct platform_device *pdev;
548 const char *fw_name = NULL;
549 int err;
484 550
485 if (r100_gui_wait_for_idle(rdev)) { 551 DRM_DEBUG("\n");
486 printk(KERN_WARNING "Failed to wait GUI idle while "
487 "programming pipes. Bad things might happen.\n");
488 }
489 552
490 WREG32(RADEON_CP_ME_RAM_ADDR, 0); 553 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
554 err = IS_ERR(pdev);
555 if (err) {
556 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
557 return -EINVAL;
558 }
491 if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || 559 if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
492 (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || 560 (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
493 (rdev->family == CHIP_RS200)) { 561 (rdev->family == CHIP_RS200)) {
494 DRM_INFO("Loading R100 Microcode\n"); 562 DRM_INFO("Loading R100 Microcode\n");
495 for (i = 0; i < 256; i++) { 563 fw_name = FIRMWARE_R100;
496 WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]);
497 WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]);
498 }
499 } else if ((rdev->family == CHIP_R200) || 564 } else if ((rdev->family == CHIP_R200) ||
500 (rdev->family == CHIP_RV250) || 565 (rdev->family == CHIP_RV250) ||
501 (rdev->family == CHIP_RV280) || 566 (rdev->family == CHIP_RV280) ||
502 (rdev->family == CHIP_RS300)) { 567 (rdev->family == CHIP_RS300)) {
503 DRM_INFO("Loading R200 Microcode\n"); 568 DRM_INFO("Loading R200 Microcode\n");
504 for (i = 0; i < 256; i++) { 569 fw_name = FIRMWARE_R200;
505 WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]);
506 WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]);
507 }
508 } else if ((rdev->family == CHIP_R300) || 570 } else if ((rdev->family == CHIP_R300) ||
509 (rdev->family == CHIP_R350) || 571 (rdev->family == CHIP_R350) ||
510 (rdev->family == CHIP_RV350) || 572 (rdev->family == CHIP_RV350) ||
@@ -512,31 +574,19 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
512 (rdev->family == CHIP_RS400) || 574 (rdev->family == CHIP_RS400) ||
513 (rdev->family == CHIP_RS480)) { 575 (rdev->family == CHIP_RS480)) {
514 DRM_INFO("Loading R300 Microcode\n"); 576 DRM_INFO("Loading R300 Microcode\n");
515 for (i = 0; i < 256; i++) { 577 fw_name = FIRMWARE_R300;
516 WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
517 WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
518 }
519 } else if ((rdev->family == CHIP_R420) || 578 } else if ((rdev->family == CHIP_R420) ||
520 (rdev->family == CHIP_R423) || 579 (rdev->family == CHIP_R423) ||
521 (rdev->family == CHIP_RV410)) { 580 (rdev->family == CHIP_RV410)) {
522 DRM_INFO("Loading R400 Microcode\n"); 581 DRM_INFO("Loading R400 Microcode\n");
523 for (i = 0; i < 256; i++) { 582 fw_name = FIRMWARE_R420;
524 WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]);
525 WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]);
526 }
527 } else if ((rdev->family == CHIP_RS690) || 583 } else if ((rdev->family == CHIP_RS690) ||
528 (rdev->family == CHIP_RS740)) { 584 (rdev->family == CHIP_RS740)) {
529 DRM_INFO("Loading RS690/RS740 Microcode\n"); 585 DRM_INFO("Loading RS690/RS740 Microcode\n");
530 for (i = 0; i < 256; i++) { 586 fw_name = FIRMWARE_RS690;
531 WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]);
532 WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]);
533 }
534 } else if (rdev->family == CHIP_RS600) { 587 } else if (rdev->family == CHIP_RS600) {
535 DRM_INFO("Loading RS600 Microcode\n"); 588 DRM_INFO("Loading RS600 Microcode\n");
536 for (i = 0; i < 256; i++) { 589 fw_name = FIRMWARE_RS600;
537 WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]);
538 WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]);
539 }
540 } else if ((rdev->family == CHIP_RV515) || 590 } else if ((rdev->family == CHIP_RV515) ||
541 (rdev->family == CHIP_R520) || 591 (rdev->family == CHIP_R520) ||
542 (rdev->family == CHIP_RV530) || 592 (rdev->family == CHIP_RV530) ||
@@ -544,9 +594,43 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
544 (rdev->family == CHIP_RV560) || 594 (rdev->family == CHIP_RV560) ||
545 (rdev->family == CHIP_RV570)) { 595 (rdev->family == CHIP_RV570)) {
546 DRM_INFO("Loading R500 Microcode\n"); 596 DRM_INFO("Loading R500 Microcode\n");
547 for (i = 0; i < 256; i++) { 597 fw_name = FIRMWARE_R520;
548 WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]); 598 }
549 WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); 599
600 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
601 platform_device_unregister(pdev);
602 if (err) {
603 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
604 fw_name);
605 } else if (rdev->me_fw->size % 8) {
606 printk(KERN_ERR
607 "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
608 rdev->me_fw->size, fw_name);
609 err = -EINVAL;
610 release_firmware(rdev->me_fw);
611 rdev->me_fw = NULL;
612 }
613 return err;
614}
615static void r100_cp_load_microcode(struct radeon_device *rdev)
616{
617 const __be32 *fw_data;
618 int i, size;
619
620 if (r100_gui_wait_for_idle(rdev)) {
621 printk(KERN_WARNING "Failed to wait GUI idle while "
622 "programming pipes. Bad things might happen.\n");
623 }
624
625 if (rdev->me_fw) {
626 size = rdev->me_fw->size / 4;
627 fw_data = (const __be32 *)&rdev->me_fw->data[0];
628 WREG32(RADEON_CP_ME_RAM_ADDR, 0);
629 for (i = 0; i < size; i += 2) {
630 WREG32(RADEON_CP_ME_RAM_DATAH,
631 be32_to_cpup(&fw_data[i]));
632 WREG32(RADEON_CP_ME_RAM_DATAL,
633 be32_to_cpup(&fw_data[i + 1]));
550 } 634 }
551 } 635 }
552} 636}
@@ -585,6 +669,15 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
585 } else { 669 } else {
586 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); 670 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
587 } 671 }
672
673 if (!rdev->me_fw) {
674 r = r100_cp_init_microcode(rdev);
675 if (r) {
676 DRM_ERROR("Failed to load firmware!\n");
677 return r;
678 }
679 }
680
588 /* Align ring size */ 681 /* Align ring size */
589 rb_bufsz = drm_order(ring_size / 8); 682 rb_bufsz = drm_order(ring_size / 8);
590 ring_size = (1 << (rb_bufsz + 1)) * 4; 683 ring_size = (1 << (rb_bufsz + 1)) * 4;
@@ -658,9 +751,11 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
658 751
659void r100_cp_fini(struct radeon_device *rdev) 752void r100_cp_fini(struct radeon_device *rdev)
660{ 753{
754 if (r100_cp_wait_for_idle(rdev)) {
755 DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n");
756 }
661 /* Disable ring */ 757 /* Disable ring */
662 rdev->cp.ready = false; 758 r100_cp_disable(rdev);
663 WREG32(RADEON_CP_CSQ_CNTL, 0);
664 radeon_ring_fini(rdev); 759 radeon_ring_fini(rdev);
665 DRM_INFO("radeon: cp finalized\n"); 760 DRM_INFO("radeon: cp finalized\n");
666} 761}
@@ -710,6 +805,12 @@ int r100_cp_reset(struct radeon_device *rdev)
710 return -1; 805 return -1;
711} 806}
712 807
808void r100_cp_commit(struct radeon_device *rdev)
809{
810 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
811 (void)RREG32(RADEON_CP_RB_WPTR);
812}
813
713 814
714/* 815/*
715 * CS functions 816 * CS functions
@@ -968,147 +1069,356 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
968 return 0; 1069 return 0;
969} 1070}
970 1071
1072static int r100_get_vtx_size(uint32_t vtx_fmt)
1073{
1074 int vtx_size;
1075 vtx_size = 2;
1076 /* ordered according to bits in spec */
1077 if (vtx_fmt & RADEON_SE_VTX_FMT_W0)
1078 vtx_size++;
1079 if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR)
1080 vtx_size += 3;
1081 if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA)
1082 vtx_size++;
1083 if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR)
1084 vtx_size++;
1085 if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC)
1086 vtx_size += 3;
1087 if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG)
1088 vtx_size++;
1089 if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC)
1090 vtx_size++;
1091 if (vtx_fmt & RADEON_SE_VTX_FMT_ST0)
1092 vtx_size += 2;
1093 if (vtx_fmt & RADEON_SE_VTX_FMT_ST1)
1094 vtx_size += 2;
1095 if (vtx_fmt & RADEON_SE_VTX_FMT_Q1)
1096 vtx_size++;
1097 if (vtx_fmt & RADEON_SE_VTX_FMT_ST2)
1098 vtx_size += 2;
1099 if (vtx_fmt & RADEON_SE_VTX_FMT_Q2)
1100 vtx_size++;
1101 if (vtx_fmt & RADEON_SE_VTX_FMT_ST3)
1102 vtx_size += 2;
1103 if (vtx_fmt & RADEON_SE_VTX_FMT_Q3)
1104 vtx_size++;
1105 if (vtx_fmt & RADEON_SE_VTX_FMT_Q0)
1106 vtx_size++;
1107 /* blend weight */
1108 if (vtx_fmt & (0x7 << 15))
1109 vtx_size += (vtx_fmt >> 15) & 0x7;
1110 if (vtx_fmt & RADEON_SE_VTX_FMT_N0)
1111 vtx_size += 3;
1112 if (vtx_fmt & RADEON_SE_VTX_FMT_XY1)
1113 vtx_size += 2;
1114 if (vtx_fmt & RADEON_SE_VTX_FMT_Z1)
1115 vtx_size++;
1116 if (vtx_fmt & RADEON_SE_VTX_FMT_W1)
1117 vtx_size++;
1118 if (vtx_fmt & RADEON_SE_VTX_FMT_N1)
1119 vtx_size++;
1120 if (vtx_fmt & RADEON_SE_VTX_FMT_Z)
1121 vtx_size++;
1122 return vtx_size;
1123}
1124
971static int r100_packet0_check(struct radeon_cs_parser *p, 1125static int r100_packet0_check(struct radeon_cs_parser *p,
972 struct radeon_cs_packet *pkt) 1126 struct radeon_cs_packet *pkt,
1127 unsigned idx, unsigned reg)
973{ 1128{
974 struct radeon_cs_chunk *ib_chunk; 1129 struct radeon_cs_chunk *ib_chunk;
975 struct radeon_cs_reloc *reloc; 1130 struct radeon_cs_reloc *reloc;
1131 struct r100_cs_track *track;
976 volatile uint32_t *ib; 1132 volatile uint32_t *ib;
977 uint32_t tmp; 1133 uint32_t tmp;
978 unsigned reg;
979 unsigned i;
980 unsigned idx;
981 bool onereg;
982 int r; 1134 int r;
1135 int i, face;
983 u32 tile_flags = 0; 1136 u32 tile_flags = 0;
984 1137
985 ib = p->ib->ptr; 1138 ib = p->ib->ptr;
986 ib_chunk = &p->chunks[p->chunk_ib_idx]; 1139 ib_chunk = &p->chunks[p->chunk_ib_idx];
987 idx = pkt->idx + 1; 1140 track = (struct r100_cs_track *)p->track;
988 reg = pkt->reg; 1141
989 onereg = false; 1142 switch (reg) {
990 if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) { 1143 case RADEON_CRTC_GUI_TRIG_VLINE:
991 onereg = true; 1144 r = r100_cs_packet_parse_vline(p);
992 } 1145 if (r) {
993 for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { 1146 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
994 switch (reg) { 1147 idx, reg);
995 case RADEON_CRTC_GUI_TRIG_VLINE: 1148 r100_cs_dump_packet(p, pkt);
996 r = r100_cs_packet_parse_vline(p); 1149 return r;
997 if (r) { 1150 }
998 DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1151 break;
999 idx, reg);
1000 r100_cs_dump_packet(p, pkt);
1001 return r;
1002 }
1003 break;
1004 /* FIXME: only allow PACKET3 blit? easier to check for out of 1152 /* FIXME: only allow PACKET3 blit? easier to check for out of
1005 * range access */ 1153 * range access */
1006 case RADEON_DST_PITCH_OFFSET: 1154 case RADEON_DST_PITCH_OFFSET:
1007 case RADEON_SRC_PITCH_OFFSET: 1155 case RADEON_SRC_PITCH_OFFSET:
1008 r = r100_cs_packet_next_reloc(p, &reloc); 1156 r = r100_reloc_pitch_offset(p, pkt, idx, reg);
1009 if (r) { 1157 if (r)
1010 DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1158 return r;
1011 idx, reg); 1159 break;
1012 r100_cs_dump_packet(p, pkt); 1160 case RADEON_RB3D_DEPTHOFFSET:
1013 return r; 1161 r = r100_cs_packet_next_reloc(p, &reloc);
1014 } 1162 if (r) {
1015 tmp = ib_chunk->kdata[idx] & 0x003fffff; 1163 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1016 tmp += (((u32)reloc->lobj.gpu_offset) >> 10); 1164 idx, reg);
1017 1165 r100_cs_dump_packet(p, pkt);
1018 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 1166 return r;
1019 tile_flags |= RADEON_DST_TILE_MACRO; 1167 }
1020 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { 1168 track->zb.robj = reloc->robj;
1021 if (reg == RADEON_SRC_PITCH_OFFSET) { 1169 track->zb.offset = ib_chunk->kdata[idx];
1022 DRM_ERROR("Cannot src blit from microtiled surface\n"); 1170 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1023 r100_cs_dump_packet(p, pkt); 1171 break;
1024 return -EINVAL; 1172 case RADEON_RB3D_COLOROFFSET:
1025 } 1173 r = r100_cs_packet_next_reloc(p, &reloc);
1026 tile_flags |= RADEON_DST_TILE_MICRO; 1174 if (r) {
1027 } 1175 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1176 idx, reg);
1177 r100_cs_dump_packet(p, pkt);
1178 return r;
1179 }
1180 track->cb[0].robj = reloc->robj;
1181 track->cb[0].offset = ib_chunk->kdata[idx];
1182 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1183 break;
1184 case RADEON_PP_TXOFFSET_0:
1185 case RADEON_PP_TXOFFSET_1:
1186 case RADEON_PP_TXOFFSET_2:
1187 i = (reg - RADEON_PP_TXOFFSET_0) / 24;
1188 r = r100_cs_packet_next_reloc(p, &reloc);
1189 if (r) {
1190 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1191 idx, reg);
1192 r100_cs_dump_packet(p, pkt);
1193 return r;
1194 }
1195 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1196 track->textures[i].robj = reloc->robj;
1197 break;
1198 case RADEON_PP_CUBIC_OFFSET_T0_0:
1199 case RADEON_PP_CUBIC_OFFSET_T0_1:
1200 case RADEON_PP_CUBIC_OFFSET_T0_2:
1201 case RADEON_PP_CUBIC_OFFSET_T0_3:
1202 case RADEON_PP_CUBIC_OFFSET_T0_4:
1203 i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4;
1204 r = r100_cs_packet_next_reloc(p, &reloc);
1205 if (r) {
1206 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1207 idx, reg);
1208 r100_cs_dump_packet(p, pkt);
1209 return r;
1210 }
1211 track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx];
1212 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1213 track->textures[0].cube_info[i].robj = reloc->robj;
1214 break;
1215 case RADEON_PP_CUBIC_OFFSET_T1_0:
1216 case RADEON_PP_CUBIC_OFFSET_T1_1:
1217 case RADEON_PP_CUBIC_OFFSET_T1_2:
1218 case RADEON_PP_CUBIC_OFFSET_T1_3:
1219 case RADEON_PP_CUBIC_OFFSET_T1_4:
1220 i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4;
1221 r = r100_cs_packet_next_reloc(p, &reloc);
1222 if (r) {
1223 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1224 idx, reg);
1225 r100_cs_dump_packet(p, pkt);
1226 return r;
1227 }
1228 track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx];
1229 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1230 track->textures[1].cube_info[i].robj = reloc->robj;
1231 break;
1232 case RADEON_PP_CUBIC_OFFSET_T2_0:
1233 case RADEON_PP_CUBIC_OFFSET_T2_1:
1234 case RADEON_PP_CUBIC_OFFSET_T2_2:
1235 case RADEON_PP_CUBIC_OFFSET_T2_3:
1236 case RADEON_PP_CUBIC_OFFSET_T2_4:
1237 i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4;
1238 r = r100_cs_packet_next_reloc(p, &reloc);
1239 if (r) {
1240 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1241 idx, reg);
1242 r100_cs_dump_packet(p, pkt);
1243 return r;
1244 }
1245 track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx];
1246 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1247 track->textures[2].cube_info[i].robj = reloc->robj;
1248 break;
1249 case RADEON_RE_WIDTH_HEIGHT:
1250 track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
1251 break;
1252 case RADEON_RB3D_COLORPITCH:
1253 r = r100_cs_packet_next_reloc(p, &reloc);
1254 if (r) {
1255 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1256 idx, reg);
1257 r100_cs_dump_packet(p, pkt);
1258 return r;
1259 }
1028 1260
1029 tmp |= tile_flags; 1261 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1030 ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp; 1262 tile_flags |= RADEON_COLOR_TILE_ENABLE;
1031 break; 1263 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1032 case RADEON_RB3D_DEPTHOFFSET: 1264 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
1033 case RADEON_RB3D_COLOROFFSET:
1034 case R300_RB3D_COLOROFFSET0:
1035 case R300_ZB_DEPTHOFFSET:
1036 case R200_PP_TXOFFSET_0:
1037 case R200_PP_TXOFFSET_1:
1038 case R200_PP_TXOFFSET_2:
1039 case R200_PP_TXOFFSET_3:
1040 case R200_PP_TXOFFSET_4:
1041 case R200_PP_TXOFFSET_5:
1042 case RADEON_PP_TXOFFSET_0:
1043 case RADEON_PP_TXOFFSET_1:
1044 case RADEON_PP_TXOFFSET_2:
1045 case R300_TX_OFFSET_0:
1046 case R300_TX_OFFSET_0+4:
1047 case R300_TX_OFFSET_0+8:
1048 case R300_TX_OFFSET_0+12:
1049 case R300_TX_OFFSET_0+16:
1050 case R300_TX_OFFSET_0+20:
1051 case R300_TX_OFFSET_0+24:
1052 case R300_TX_OFFSET_0+28:
1053 case R300_TX_OFFSET_0+32:
1054 case R300_TX_OFFSET_0+36:
1055 case R300_TX_OFFSET_0+40:
1056 case R300_TX_OFFSET_0+44:
1057 case R300_TX_OFFSET_0+48:
1058 case R300_TX_OFFSET_0+52:
1059 case R300_TX_OFFSET_0+56:
1060 case R300_TX_OFFSET_0+60:
1061 /* rn50 has no 3D engine so fail on any 3d setup */
1062 if (ASIC_IS_RN50(p->rdev)) {
1063 DRM_ERROR("attempt to use RN50 3D engine failed\n");
1064 return -EINVAL;
1065 }
1066 r = r100_cs_packet_next_reloc(p, &reloc);
1067 if (r) {
1068 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1069 idx, reg);
1070 r100_cs_dump_packet(p, pkt);
1071 return r;
1072 }
1073 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1074 break;
1075 case R300_RB3D_COLORPITCH0:
1076 case RADEON_RB3D_COLORPITCH:
1077 r = r100_cs_packet_next_reloc(p, &reloc);
1078 if (r) {
1079 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1080 idx, reg);
1081 r100_cs_dump_packet(p, pkt);
1082 return r;
1083 }
1084 1265
1085 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 1266 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
1086 tile_flags |= RADEON_COLOR_TILE_ENABLE; 1267 tmp |= tile_flags;
1087 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 1268 ib[idx] = tmp;
1088 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
1089 1269
1090 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); 1270 track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
1091 tmp |= tile_flags; 1271 break;
1092 ib[idx] = tmp; 1272 case RADEON_RB3D_DEPTHPITCH:
1273 track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
1274 break;
1275 case RADEON_RB3D_CNTL:
1276 switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
1277 case 7:
1278 case 8:
1279 case 9:
1280 case 11:
1281 case 12:
1282 track->cb[0].cpp = 1;
1093 break; 1283 break;
1094 case RADEON_RB3D_ZPASS_ADDR: 1284 case 3:
1095 r = r100_cs_packet_next_reloc(p, &reloc); 1285 case 4:
1096 if (r) { 1286 case 15:
1097 DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 1287 track->cb[0].cpp = 2;
1098 idx, reg); 1288 break;
1099 r100_cs_dump_packet(p, pkt); 1289 case 6:
1100 return r; 1290 track->cb[0].cpp = 4;
1101 }
1102 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1103 break; 1291 break;
1104 default: 1292 default:
1105 /* FIXME: we don't want to allow anyothers packet */ 1293 DRM_ERROR("Invalid color buffer format (%d) !\n",
1294 ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
1295 return -EINVAL;
1296 }
1297 track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
1298 break;
1299 case RADEON_RB3D_ZSTENCILCNTL:
1300 switch (ib_chunk->kdata[idx] & 0xf) {
1301 case 0:
1302 track->zb.cpp = 2;
1303 break;
1304 case 2:
1305 case 3:
1306 case 4:
1307 case 5:
1308 case 9:
1309 case 11:
1310 track->zb.cpp = 4;
1106 break; 1311 break;
1312 default:
1313 break;
1314 }
1315 break;
1316 case RADEON_RB3D_ZPASS_ADDR:
1317 r = r100_cs_packet_next_reloc(p, &reloc);
1318 if (r) {
1319 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1320 idx, reg);
1321 r100_cs_dump_packet(p, pkt);
1322 return r;
1323 }
1324 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1325 break;
1326 case RADEON_PP_CNTL:
1327 {
1328 uint32_t temp = ib_chunk->kdata[idx] >> 4;
1329 for (i = 0; i < track->num_texture; i++)
1330 track->textures[i].enabled = !!(temp & (1 << i));
1107 } 1331 }
1108 if (onereg) { 1332 break;
1109 /* FIXME: forbid onereg write to register on relocate */ 1333 case RADEON_SE_VF_CNTL:
1334 track->vap_vf_cntl = ib_chunk->kdata[idx];
1335 break;
1336 case RADEON_SE_VTX_FMT:
1337 track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]);
1338 break;
1339 case RADEON_PP_TEX_SIZE_0:
1340 case RADEON_PP_TEX_SIZE_1:
1341 case RADEON_PP_TEX_SIZE_2:
1342 i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
1343 track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
1344 track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
1345 break;
1346 case RADEON_PP_TEX_PITCH_0:
1347 case RADEON_PP_TEX_PITCH_1:
1348 case RADEON_PP_TEX_PITCH_2:
1349 i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
1350 track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
1351 break;
1352 case RADEON_PP_TXFILTER_0:
1353 case RADEON_PP_TXFILTER_1:
1354 case RADEON_PP_TXFILTER_2:
1355 i = (reg - RADEON_PP_TXFILTER_0) / 24;
1356 track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK)
1357 >> RADEON_MAX_MIP_LEVEL_SHIFT);
1358 tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
1359 if (tmp == 2 || tmp == 6)
1360 track->textures[i].roundup_w = false;
1361 tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
1362 if (tmp == 2 || tmp == 6)
1363 track->textures[i].roundup_h = false;
1364 break;
1365 case RADEON_PP_TXFORMAT_0:
1366 case RADEON_PP_TXFORMAT_1:
1367 case RADEON_PP_TXFORMAT_2:
1368 i = (reg - RADEON_PP_TXFORMAT_0) / 24;
1369 if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) {
1370 track->textures[i].use_pitch = 1;
1371 } else {
1372 track->textures[i].use_pitch = 0;
1373 track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
1374 track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
1375 }
1376 if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
1377 track->textures[i].tex_coord_type = 2;
1378 switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
1379 case RADEON_TXFORMAT_I8:
1380 case RADEON_TXFORMAT_RGB332:
1381 case RADEON_TXFORMAT_Y8:
1382 track->textures[i].cpp = 1;
1110 break; 1383 break;
1384 case RADEON_TXFORMAT_AI88:
1385 case RADEON_TXFORMAT_ARGB1555:
1386 case RADEON_TXFORMAT_RGB565:
1387 case RADEON_TXFORMAT_ARGB4444:
1388 case RADEON_TXFORMAT_VYUY422:
1389 case RADEON_TXFORMAT_YVYU422:
1390 case RADEON_TXFORMAT_DXT1:
1391 case RADEON_TXFORMAT_SHADOW16:
1392 case RADEON_TXFORMAT_LDUDV655:
1393 case RADEON_TXFORMAT_DUDV88:
1394 track->textures[i].cpp = 2;
1395 break;
1396 case RADEON_TXFORMAT_ARGB8888:
1397 case RADEON_TXFORMAT_RGBA8888:
1398 case RADEON_TXFORMAT_DXT23:
1399 case RADEON_TXFORMAT_DXT45:
1400 case RADEON_TXFORMAT_SHADOW32:
1401 case RADEON_TXFORMAT_LDUDUV8888:
1402 track->textures[i].cpp = 4;
1403 break;
1404 }
1405 track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
1406 track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
1407 break;
1408 case RADEON_PP_CUBIC_FACES_0:
1409 case RADEON_PP_CUBIC_FACES_1:
1410 case RADEON_PP_CUBIC_FACES_2:
1411 tmp = ib_chunk->kdata[idx];
1412 i = (reg - RADEON_PP_CUBIC_FACES_0) / 4;
1413 for (face = 0; face < 4; face++) {
1414 track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
1415 track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
1111 } 1416 }
1417 break;
1418 default:
1419 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
1420 reg, idx);
1421 return -EINVAL;
1112 } 1422 }
1113 return 0; 1423 return 0;
1114} 1424}
@@ -1137,6 +1447,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1137{ 1447{
1138 struct radeon_cs_chunk *ib_chunk; 1448 struct radeon_cs_chunk *ib_chunk;
1139 struct radeon_cs_reloc *reloc; 1449 struct radeon_cs_reloc *reloc;
1450 struct r100_cs_track *track;
1140 unsigned idx; 1451 unsigned idx;
1141 unsigned i, c; 1452 unsigned i, c;
1142 volatile uint32_t *ib; 1453 volatile uint32_t *ib;
@@ -1145,9 +1456,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1145 ib = p->ib->ptr; 1456 ib = p->ib->ptr;
1146 ib_chunk = &p->chunks[p->chunk_ib_idx]; 1457 ib_chunk = &p->chunks[p->chunk_ib_idx];
1147 idx = pkt->idx + 1; 1458 idx = pkt->idx + 1;
1459 track = (struct r100_cs_track *)p->track;
1148 switch (pkt->opcode) { 1460 switch (pkt->opcode) {
1149 case PACKET3_3D_LOAD_VBPNTR: 1461 case PACKET3_3D_LOAD_VBPNTR:
1150 c = ib_chunk->kdata[idx++]; 1462 c = ib_chunk->kdata[idx++];
1463 track->num_arrays = c;
1151 for (i = 0; i < (c - 1); i += 2, idx += 3) { 1464 for (i = 0; i < (c - 1); i += 2, idx += 3) {
1152 r = r100_cs_packet_next_reloc(p, &reloc); 1465 r = r100_cs_packet_next_reloc(p, &reloc);
1153 if (r) { 1466 if (r) {
@@ -1157,6 +1470,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1157 return r; 1470 return r;
1158 } 1471 }
1159 ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); 1472 ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
1473 track->arrays[i + 0].robj = reloc->robj;
1474 track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
1475 track->arrays[i + 0].esize &= 0x7F;
1160 r = r100_cs_packet_next_reloc(p, &reloc); 1476 r = r100_cs_packet_next_reloc(p, &reloc);
1161 if (r) { 1477 if (r) {
1162 DRM_ERROR("No reloc for packet3 %d\n", 1478 DRM_ERROR("No reloc for packet3 %d\n",
@@ -1165,6 +1481,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1165 return r; 1481 return r;
1166 } 1482 }
1167 ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); 1483 ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
1484 track->arrays[i + 1].robj = reloc->robj;
1485 track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24;
1486 track->arrays[i + 1].esize &= 0x7F;
1168 } 1487 }
1169 if (c & 1) { 1488 if (c & 1) {
1170 r = r100_cs_packet_next_reloc(p, &reloc); 1489 r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1175,6 +1494,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1175 return r; 1494 return r;
1176 } 1495 }
1177 ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); 1496 ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
1497 track->arrays[i + 0].robj = reloc->robj;
1498 track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
1499 track->arrays[i + 0].esize &= 0x7F;
1178 } 1500 }
1179 break; 1501 break;
1180 case PACKET3_INDX_BUFFER: 1502 case PACKET3_INDX_BUFFER:
@@ -1191,7 +1513,6 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1191 } 1513 }
1192 break; 1514 break;
1193 case 0x23: 1515 case 0x23:
1194 /* FIXME: cleanup */
1195 /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ 1516 /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */
1196 r = r100_cs_packet_next_reloc(p, &reloc); 1517 r = r100_cs_packet_next_reloc(p, &reloc);
1197 if (r) { 1518 if (r) {
@@ -1200,18 +1521,71 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1200 return r; 1521 return r;
1201 } 1522 }
1202 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); 1523 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
1524 track->num_arrays = 1;
1525 track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]);
1526
1527 track->arrays[0].robj = reloc->robj;
1528 track->arrays[0].esize = track->vtx_size;
1529
1530 track->max_indx = ib_chunk->kdata[idx+1];
1531
1532 track->vap_vf_cntl = ib_chunk->kdata[idx+3];
1533 track->immd_dwords = pkt->count - 1;
1534 r = r100_cs_track_check(p->rdev, track);
1535 if (r)
1536 return r;
1203 break; 1537 break;
1204 case PACKET3_3D_DRAW_IMMD: 1538 case PACKET3_3D_DRAW_IMMD:
1539 if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) {
1540 DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
1541 return -EINVAL;
1542 }
1543 track->vap_vf_cntl = ib_chunk->kdata[idx+1];
1544 track->immd_dwords = pkt->count - 1;
1545 r = r100_cs_track_check(p->rdev, track);
1546 if (r)
1547 return r;
1548 break;
1205 /* triggers drawing using in-packet vertex data */ 1549 /* triggers drawing using in-packet vertex data */
1206 case PACKET3_3D_DRAW_IMMD_2: 1550 case PACKET3_3D_DRAW_IMMD_2:
1551 if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) {
1552 DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
1553 return -EINVAL;
1554 }
1555 track->vap_vf_cntl = ib_chunk->kdata[idx];
1556 track->immd_dwords = pkt->count;
1557 r = r100_cs_track_check(p->rdev, track);
1558 if (r)
1559 return r;
1560 break;
1207 /* triggers drawing using in-packet vertex data */ 1561 /* triggers drawing using in-packet vertex data */
1208 case PACKET3_3D_DRAW_VBUF_2: 1562 case PACKET3_3D_DRAW_VBUF_2:
1563 track->vap_vf_cntl = ib_chunk->kdata[idx];
1564 r = r100_cs_track_check(p->rdev, track);
1565 if (r)
1566 return r;
1567 break;
1209 /* triggers drawing of vertex buffers setup elsewhere */ 1568 /* triggers drawing of vertex buffers setup elsewhere */
1210 case PACKET3_3D_DRAW_INDX_2: 1569 case PACKET3_3D_DRAW_INDX_2:
1570 track->vap_vf_cntl = ib_chunk->kdata[idx];
1571 r = r100_cs_track_check(p->rdev, track);
1572 if (r)
1573 return r;
1574 break;
1211 /* triggers drawing using indices to vertex buffer */ 1575 /* triggers drawing using indices to vertex buffer */
1212 case PACKET3_3D_DRAW_VBUF: 1576 case PACKET3_3D_DRAW_VBUF:
1577 track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
1578 r = r100_cs_track_check(p->rdev, track);
1579 if (r)
1580 return r;
1581 break;
1213 /* triggers drawing of vertex buffers setup elsewhere */ 1582 /* triggers drawing of vertex buffers setup elsewhere */
1214 case PACKET3_3D_DRAW_INDX: 1583 case PACKET3_3D_DRAW_INDX:
1584 track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
1585 r = r100_cs_track_check(p->rdev, track);
1586 if (r)
1587 return r;
1588 break;
1215 /* triggers drawing using indices to vertex buffer */ 1589 /* triggers drawing using indices to vertex buffer */
1216 case PACKET3_NOP: 1590 case PACKET3_NOP:
1217 break; 1591 break;
@@ -1225,8 +1599,12 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
1225int r100_cs_parse(struct radeon_cs_parser *p) 1599int r100_cs_parse(struct radeon_cs_parser *p)
1226{ 1600{
1227 struct radeon_cs_packet pkt; 1601 struct radeon_cs_packet pkt;
1602 struct r100_cs_track *track;
1228 int r; 1603 int r;
1229 1604
1605 track = kzalloc(sizeof(*track), GFP_KERNEL);
1606 r100_cs_track_clear(p->rdev, track);
1607 p->track = track;
1230 do { 1608 do {
1231 r = r100_cs_packet_parse(p, &pkt, p->idx); 1609 r = r100_cs_packet_parse(p, &pkt, p->idx);
1232 if (r) { 1610 if (r) {
@@ -1235,7 +1613,16 @@ int r100_cs_parse(struct radeon_cs_parser *p)
1235 p->idx += pkt.count + 2; 1613 p->idx += pkt.count + 2;
1236 switch (pkt.type) { 1614 switch (pkt.type) {
1237 case PACKET_TYPE0: 1615 case PACKET_TYPE0:
1238 r = r100_packet0_check(p, &pkt); 1616 if (p->rdev->family >= CHIP_R200)
1617 r = r100_cs_parse_packet0(p, &pkt,
1618 p->rdev->config.r100.reg_safe_bm,
1619 p->rdev->config.r100.reg_safe_bm_size,
1620 &r200_packet0_check);
1621 else
1622 r = r100_cs_parse_packet0(p, &pkt,
1623 p->rdev->config.r100.reg_safe_bm,
1624 p->rdev->config.r100.reg_safe_bm_size,
1625 &r100_packet0_check);
1239 break; 1626 break;
1240 case PACKET_TYPE2: 1627 case PACKET_TYPE2:
1241 break; 1628 break;
@@ -1568,6 +1955,20 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
1568 rdev->mc.real_vram_size = rdev->mc.aper_size; 1955 rdev->mc.real_vram_size = rdev->mc.aper_size;
1569} 1956}
1570 1957
1958void r100_vga_set_state(struct radeon_device *rdev, bool state)
1959{
1960 uint32_t temp;
1961
1962 temp = RREG32(RADEON_CONFIG_CNTL);
1963 if (state == false) {
1964 temp &= ~(1<<8);
1965 temp |= (1<<9);
1966 } else {
1967 temp &= ~(1<<9);
1968 }
1969 WREG32(RADEON_CONFIG_CNTL, temp);
1970}
1971
1571void r100_vram_info(struct radeon_device *rdev) 1972void r100_vram_info(struct radeon_device *rdev)
1572{ 1973{
1573 r100_vram_get_type(rdev); 1974 r100_vram_get_type(rdev);
@@ -1634,6 +2035,15 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
1634 2035
1635int r100_init(struct radeon_device *rdev) 2036int r100_init(struct radeon_device *rdev)
1636{ 2037{
2038 if (ASIC_IS_RN50(rdev)) {
2039 rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
2040 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm);
2041 } else if (rdev->family < CHIP_R200) {
2042 rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
2043 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
2044 } else {
2045 return r200_init(rdev);
2046 }
1637 return 0; 2047 return 0;
1638} 2048}
1639 2049
@@ -1839,6 +2249,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
1839 flags |= R300_SURF_TILE_MICRO; 2249 flags |= R300_SURF_TILE_MICRO;
1840 } 2250 }
1841 2251
2252 if (tiling_flags & RADEON_TILING_SWAP_16BIT)
2253 flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
2254 if (tiling_flags & RADEON_TILING_SWAP_32BIT)
2255 flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
2256
1842 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); 2257 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
1843 WREG32(RADEON_SURFACE0_INFO + surf_index, flags); 2258 WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
1844 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); 2259 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
@@ -2334,3 +2749,460 @@ void r100_bandwidth_update(struct radeon_device *rdev)
2334 (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); 2749 (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
2335 } 2750 }
2336} 2751}
2752
2753static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
2754{
2755 DRM_ERROR("pitch %d\n", t->pitch);
2756 DRM_ERROR("width %d\n", t->width);
2757 DRM_ERROR("height %d\n", t->height);
2758 DRM_ERROR("num levels %d\n", t->num_levels);
2759 DRM_ERROR("depth %d\n", t->txdepth);
2760 DRM_ERROR("bpp %d\n", t->cpp);
2761 DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
2762 DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
2763 DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
2764}
2765
2766static int r100_cs_track_cube(struct radeon_device *rdev,
2767 struct r100_cs_track *track, unsigned idx)
2768{
2769 unsigned face, w, h;
2770 struct radeon_object *cube_robj;
2771 unsigned long size;
2772
2773 for (face = 0; face < 5; face++) {
2774 cube_robj = track->textures[idx].cube_info[face].robj;
2775 w = track->textures[idx].cube_info[face].width;
2776 h = track->textures[idx].cube_info[face].height;
2777
2778 size = w * h;
2779 size *= track->textures[idx].cpp;
2780
2781 size += track->textures[idx].cube_info[face].offset;
2782
2783 if (size > radeon_object_size(cube_robj)) {
2784 DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
2785 size, radeon_object_size(cube_robj));
2786 r100_cs_track_texture_print(&track->textures[idx]);
2787 return -1;
2788 }
2789 }
2790 return 0;
2791}
2792
2793static int r100_cs_track_texture_check(struct radeon_device *rdev,
2794 struct r100_cs_track *track)
2795{
2796 struct radeon_object *robj;
2797 unsigned long size;
2798 unsigned u, i, w, h;
2799 int ret;
2800
2801 for (u = 0; u < track->num_texture; u++) {
2802 if (!track->textures[u].enabled)
2803 continue;
2804 robj = track->textures[u].robj;
2805 if (robj == NULL) {
2806 DRM_ERROR("No texture bound to unit %u\n", u);
2807 return -EINVAL;
2808 }
2809 size = 0;
2810 for (i = 0; i <= track->textures[u].num_levels; i++) {
2811 if (track->textures[u].use_pitch) {
2812 if (rdev->family < CHIP_R300)
2813 w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i);
2814 else
2815 w = track->textures[u].pitch / (1 << i);
2816 } else {
2817 w = track->textures[u].width / (1 << i);
2818 if (rdev->family >= CHIP_RV515)
2819 w |= track->textures[u].width_11;
2820 if (track->textures[u].roundup_w)
2821 w = roundup_pow_of_two(w);
2822 }
2823 h = track->textures[u].height / (1 << i);
2824 if (rdev->family >= CHIP_RV515)
2825 h |= track->textures[u].height_11;
2826 if (track->textures[u].roundup_h)
2827 h = roundup_pow_of_two(h);
2828 size += w * h;
2829 }
2830 size *= track->textures[u].cpp;
2831 switch (track->textures[u].tex_coord_type) {
2832 case 0:
2833 break;
2834 case 1:
2835 size *= (1 << track->textures[u].txdepth);
2836 break;
2837 case 2:
2838 if (track->separate_cube) {
2839 ret = r100_cs_track_cube(rdev, track, u);
2840 if (ret)
2841 return ret;
2842 } else
2843 size *= 6;
2844 break;
2845 default:
2846 DRM_ERROR("Invalid texture coordinate type %u for unit "
2847 "%u\n", track->textures[u].tex_coord_type, u);
2848 return -EINVAL;
2849 }
2850 if (size > radeon_object_size(robj)) {
2851 DRM_ERROR("Texture of unit %u needs %lu bytes but is "
2852 "%lu\n", u, size, radeon_object_size(robj));
2853 r100_cs_track_texture_print(&track->textures[u]);
2854 return -EINVAL;
2855 }
2856 }
2857 return 0;
2858}
2859
2860int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
2861{
2862 unsigned i;
2863 unsigned long size;
2864 unsigned prim_walk;
2865 unsigned nverts;
2866
2867 for (i = 0; i < track->num_cb; i++) {
2868 if (track->cb[i].robj == NULL) {
2869 DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
2870 return -EINVAL;
2871 }
2872 size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
2873 size += track->cb[i].offset;
2874 if (size > radeon_object_size(track->cb[i].robj)) {
2875 DRM_ERROR("[drm] Buffer too small for color buffer %d "
2876 "(need %lu have %lu) !\n", i, size,
2877 radeon_object_size(track->cb[i].robj));
2878 DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
2879 i, track->cb[i].pitch, track->cb[i].cpp,
2880 track->cb[i].offset, track->maxy);
2881 return -EINVAL;
2882 }
2883 }
2884 if (track->z_enabled) {
2885 if (track->zb.robj == NULL) {
2886 DRM_ERROR("[drm] No buffer for z buffer !\n");
2887 return -EINVAL;
2888 }
2889 size = track->zb.pitch * track->zb.cpp * track->maxy;
2890 size += track->zb.offset;
2891 if (size > radeon_object_size(track->zb.robj)) {
2892 DRM_ERROR("[drm] Buffer too small for z buffer "
2893 "(need %lu have %lu) !\n", size,
2894 radeon_object_size(track->zb.robj));
2895 DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
2896 track->zb.pitch, track->zb.cpp,
2897 track->zb.offset, track->maxy);
2898 return -EINVAL;
2899 }
2900 }
2901 prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
2902 nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
2903 switch (prim_walk) {
2904 case 1:
2905 for (i = 0; i < track->num_arrays; i++) {
2906 size = track->arrays[i].esize * track->max_indx * 4;
2907 if (track->arrays[i].robj == NULL) {
2908 DRM_ERROR("(PW %u) Vertex array %u no buffer "
2909 "bound\n", prim_walk, i);
2910 return -EINVAL;
2911 }
2912 if (size > radeon_object_size(track->arrays[i].robj)) {
2913 DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
2914 "have %lu dwords\n", prim_walk, i,
2915 size >> 2,
2916 radeon_object_size(track->arrays[i].robj) >> 2);
2917 DRM_ERROR("Max indices %u\n", track->max_indx);
2918 return -EINVAL;
2919 }
2920 }
2921 break;
2922 case 2:
2923 for (i = 0; i < track->num_arrays; i++) {
2924 size = track->arrays[i].esize * (nverts - 1) * 4;
2925 if (track->arrays[i].robj == NULL) {
2926 DRM_ERROR("(PW %u) Vertex array %u no buffer "
2927 "bound\n", prim_walk, i);
2928 return -EINVAL;
2929 }
2930 if (size > radeon_object_size(track->arrays[i].robj)) {
2931 DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
2932 "have %lu dwords\n", prim_walk, i, size >> 2,
2933 radeon_object_size(track->arrays[i].robj) >> 2);
2934 return -EINVAL;
2935 }
2936 }
2937 break;
2938 case 3:
2939 size = track->vtx_size * nverts;
2940 if (size != track->immd_dwords) {
2941 DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
2942 track->immd_dwords, size);
2943 DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
2944 nverts, track->vtx_size);
2945 return -EINVAL;
2946 }
2947 break;
2948 default:
2949 DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
2950 prim_walk);
2951 return -EINVAL;
2952 }
2953 return r100_cs_track_texture_check(rdev, track);
2954}
2955
2956void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
2957{
2958 unsigned i, face;
2959
2960 if (rdev->family < CHIP_R300) {
2961 track->num_cb = 1;
2962 if (rdev->family <= CHIP_RS200)
2963 track->num_texture = 3;
2964 else
2965 track->num_texture = 6;
2966 track->maxy = 2048;
2967 track->separate_cube = 1;
2968 } else {
2969 track->num_cb = 4;
2970 track->num_texture = 16;
2971 track->maxy = 4096;
2972 track->separate_cube = 0;
2973 }
2974
2975 for (i = 0; i < track->num_cb; i++) {
2976 track->cb[i].robj = NULL;
2977 track->cb[i].pitch = 8192;
2978 track->cb[i].cpp = 16;
2979 track->cb[i].offset = 0;
2980 }
2981 track->z_enabled = true;
2982 track->zb.robj = NULL;
2983 track->zb.pitch = 8192;
2984 track->zb.cpp = 4;
2985 track->zb.offset = 0;
2986 track->vtx_size = 0x7F;
2987 track->immd_dwords = 0xFFFFFFFFUL;
2988 track->num_arrays = 11;
2989 track->max_indx = 0x00FFFFFFUL;
2990 for (i = 0; i < track->num_arrays; i++) {
2991 track->arrays[i].robj = NULL;
2992 track->arrays[i].esize = 0x7F;
2993 }
2994 for (i = 0; i < track->num_texture; i++) {
2995 track->textures[i].pitch = 16536;
2996 track->textures[i].width = 16536;
2997 track->textures[i].height = 16536;
2998 track->textures[i].width_11 = 1 << 11;
2999 track->textures[i].height_11 = 1 << 11;
3000 track->textures[i].num_levels = 12;
3001 if (rdev->family <= CHIP_RS200) {
3002 track->textures[i].tex_coord_type = 0;
3003 track->textures[i].txdepth = 0;
3004 } else {
3005 track->textures[i].txdepth = 16;
3006 track->textures[i].tex_coord_type = 1;
3007 }
3008 track->textures[i].cpp = 64;
3009 track->textures[i].robj = NULL;
3010 /* CS IB emission code makes sure texture unit are disabled */
3011 track->textures[i].enabled = false;
3012 track->textures[i].roundup_w = true;
3013 track->textures[i].roundup_h = true;
3014 if (track->separate_cube)
3015 for (face = 0; face < 5; face++) {
3016 track->textures[i].cube_info[face].robj = NULL;
3017 track->textures[i].cube_info[face].width = 16536;
3018 track->textures[i].cube_info[face].height = 16536;
3019 track->textures[i].cube_info[face].offset = 0;
3020 }
3021 }
3022}
3023
3024int r100_ring_test(struct radeon_device *rdev)
3025{
3026 uint32_t scratch;
3027 uint32_t tmp = 0;
3028 unsigned i;
3029 int r;
3030
3031 r = radeon_scratch_get(rdev, &scratch);
3032 if (r) {
3033 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
3034 return r;
3035 }
3036 WREG32(scratch, 0xCAFEDEAD);
3037 r = radeon_ring_lock(rdev, 2);
3038 if (r) {
3039 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3040 radeon_scratch_free(rdev, scratch);
3041 return r;
3042 }
3043 radeon_ring_write(rdev, PACKET0(scratch, 0));
3044 radeon_ring_write(rdev, 0xDEADBEEF);
3045 radeon_ring_unlock_commit(rdev);
3046 for (i = 0; i < rdev->usec_timeout; i++) {
3047 tmp = RREG32(scratch);
3048 if (tmp == 0xDEADBEEF) {
3049 break;
3050 }
3051 DRM_UDELAY(1);
3052 }
3053 if (i < rdev->usec_timeout) {
3054 DRM_INFO("ring test succeeded in %d usecs\n", i);
3055 } else {
3056 DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
3057 scratch, tmp);
3058 r = -EINVAL;
3059 }
3060 radeon_scratch_free(rdev, scratch);
3061 return r;
3062}
3063
3064void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3065{
3066 radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
3067 radeon_ring_write(rdev, ib->gpu_addr);
3068 radeon_ring_write(rdev, ib->length_dw);
3069}
3070
3071int r100_ib_test(struct radeon_device *rdev)
3072{
3073 struct radeon_ib *ib;
3074 uint32_t scratch;
3075 uint32_t tmp = 0;
3076 unsigned i;
3077 int r;
3078
3079 r = radeon_scratch_get(rdev, &scratch);
3080 if (r) {
3081 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
3082 return r;
3083 }
3084 WREG32(scratch, 0xCAFEDEAD);
3085 r = radeon_ib_get(rdev, &ib);
3086 if (r) {
3087 return r;
3088 }
3089 ib->ptr[0] = PACKET0(scratch, 0);
3090 ib->ptr[1] = 0xDEADBEEF;
3091 ib->ptr[2] = PACKET2(0);
3092 ib->ptr[3] = PACKET2(0);
3093 ib->ptr[4] = PACKET2(0);
3094 ib->ptr[5] = PACKET2(0);
3095 ib->ptr[6] = PACKET2(0);
3096 ib->ptr[7] = PACKET2(0);
3097 ib->length_dw = 8;
3098 r = radeon_ib_schedule(rdev, ib);
3099 if (r) {
3100 radeon_scratch_free(rdev, scratch);
3101 radeon_ib_free(rdev, &ib);
3102 return r;
3103 }
3104 r = radeon_fence_wait(ib->fence, false);
3105 if (r) {
3106 return r;
3107 }
3108 for (i = 0; i < rdev->usec_timeout; i++) {
3109 tmp = RREG32(scratch);
3110 if (tmp == 0xDEADBEEF) {
3111 break;
3112 }
3113 DRM_UDELAY(1);
3114 }
3115 if (i < rdev->usec_timeout) {
3116 DRM_INFO("ib test succeeded in %u usecs\n", i);
3117 } else {
3118 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
3119 scratch, tmp);
3120 r = -EINVAL;
3121 }
3122 radeon_scratch_free(rdev, scratch);
3123 radeon_ib_free(rdev, &ib);
3124 return r;
3125}
3126
3127void r100_ib_fini(struct radeon_device *rdev)
3128{
3129 radeon_ib_pool_fini(rdev);
3130}
3131
3132int r100_ib_init(struct radeon_device *rdev)
3133{
3134 int r;
3135
3136 r = radeon_ib_pool_init(rdev);
3137 if (r) {
3138 dev_err(rdev->dev, "failled initializing IB pool (%d).\n", r);
3139 r100_ib_fini(rdev);
3140 return r;
3141 }
3142 r = r100_ib_test(rdev);
3143 if (r) {
3144 dev_err(rdev->dev, "failled testing IB (%d).\n", r);
3145 r100_ib_fini(rdev);
3146 return r;
3147 }
3148 return 0;
3149}
3150
3151void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
3152{
3153 /* Shutdown CP we shouldn't need to do that but better be safe than
3154 * sorry
3155 */
3156 rdev->cp.ready = false;
3157 WREG32(R_000740_CP_CSQ_CNTL, 0);
3158
3159 /* Save few CRTC registers */
3160 save->GENMO_WT = RREG32(R_0003C0_GENMO_WT);
3161 save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
3162 save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
3163 save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
3164 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3165 save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL);
3166 save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET);
3167 }
3168
3169 /* Disable VGA aperture access */
3170 WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT);
3171 /* Disable cursor, overlay, crtc */
3172 WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
3173 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
3174 S_000054_CRTC_DISPLAY_DIS(1));
3175 WREG32(R_000050_CRTC_GEN_CNTL,
3176 (C_000050_CRTC_CUR_EN & save->CRTC_GEN_CNTL) |
3177 S_000050_CRTC_DISP_REQ_EN_B(1));
3178 WREG32(R_000420_OV0_SCALE_CNTL,
3179 C_000420_OV0_OVERLAY_EN & RREG32(R_000420_OV0_SCALE_CNTL));
3180 WREG32(R_000260_CUR_OFFSET, C_000260_CUR_LOCK & save->CUR_OFFSET);
3181 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3182 WREG32(R_000360_CUR2_OFFSET, save->CUR2_OFFSET |
3183 S_000360_CUR2_LOCK(1));
3184 WREG32(R_0003F8_CRTC2_GEN_CNTL,
3185 (C_0003F8_CRTC2_CUR_EN & save->CRTC2_GEN_CNTL) |
3186 S_0003F8_CRTC2_DISPLAY_DIS(1) |
3187 S_0003F8_CRTC2_DISP_REQ_EN_B(1));
3188 WREG32(R_000360_CUR2_OFFSET,
3189 C_000360_CUR2_LOCK & save->CUR2_OFFSET);
3190 }
3191}
3192
3193void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
3194{
3195 /* Update base address for crtc */
3196 WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location);
3197 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3198 WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR,
3199 rdev->mc.vram_location);
3200 }
3201 /* Restore CRTC registers */
3202 WREG32(R_0003C0_GENMO_WT, save->GENMO_WT);
3203 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
3204 WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
3205 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3206 WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
3207 }
3208}
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
new file mode 100644
index 000000000000..70a82eda394a
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -0,0 +1,124 @@
1
2#define R100_TRACK_MAX_TEXTURE 3
3#define R200_TRACK_MAX_TEXTURE 6
4#define R300_TRACK_MAX_TEXTURE 16
5
6#define R100_MAX_CB 1
7#define R300_MAX_CB 4
8
9/*
10 * CS functions
11 */
12struct r100_cs_track_cb {
13 struct radeon_object *robj;
14 unsigned pitch;
15 unsigned cpp;
16 unsigned offset;
17};
18
19struct r100_cs_track_array {
20 struct radeon_object *robj;
21 unsigned esize;
22};
23
24struct r100_cs_cube_info {
25 struct radeon_object *robj;
26 unsigned offset;
27 unsigned width;
28 unsigned height;
29};
30
31struct r100_cs_track_texture {
32 struct radeon_object *robj;
33 struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
34 unsigned pitch;
35 unsigned width;
36 unsigned height;
37 unsigned num_levels;
38 unsigned cpp;
39 unsigned tex_coord_type;
40 unsigned txdepth;
41 unsigned width_11;
42 unsigned height_11;
43 bool use_pitch;
44 bool enabled;
45 bool roundup_w;
46 bool roundup_h;
47};
48
49struct r100_cs_track_limits {
50 unsigned num_cb;
51 unsigned num_texture;
52 unsigned max_levels;
53};
54
55struct r100_cs_track {
56 struct radeon_device *rdev;
57 unsigned num_cb;
58 unsigned num_texture;
59 unsigned maxy;
60 unsigned vtx_size;
61 unsigned vap_vf_cntl;
62 unsigned immd_dwords;
63 unsigned num_arrays;
64 unsigned max_indx;
65 struct r100_cs_track_array arrays[11];
66 struct r100_cs_track_cb cb[R300_MAX_CB];
67 struct r100_cs_track_cb zb;
68 struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
69 bool z_enabled;
70 bool separate_cube;
71
72};
73
74int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
75void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track);
76int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
77 struct radeon_cs_reloc **cs_reloc);
78void r100_cs_dump_packet(struct radeon_cs_parser *p,
79 struct radeon_cs_packet *pkt);
80
81int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
82
83int r200_packet0_check(struct radeon_cs_parser *p,
84 struct radeon_cs_packet *pkt,
85 unsigned idx, unsigned reg);
86
87static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
88 struct radeon_cs_packet *pkt,
89 unsigned idx,
90 unsigned reg)
91{
92 int r;
93 u32 tile_flags = 0;
94 u32 tmp;
95 struct radeon_cs_reloc *reloc;
96 struct radeon_cs_chunk *ib_chunk;
97
98 ib_chunk = &p->chunks[p->chunk_ib_idx];
99
100 r = r100_cs_packet_next_reloc(p, &reloc);
101 if (r) {
102 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
103 idx, reg);
104 r100_cs_dump_packet(p, pkt);
105 return r;
106 }
107 tmp = ib_chunk->kdata[idx] & 0x003fffff;
108 tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
109
110 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
111 tile_flags |= RADEON_DST_TILE_MACRO;
112 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
113 if (reg == RADEON_SRC_PITCH_OFFSET) {
114 DRM_ERROR("Cannot src blit from microtiled surface\n");
115 r100_cs_dump_packet(p, pkt);
116 return -EINVAL;
117 }
118 tile_flags |= RADEON_DST_TILE_MICRO;
119 }
120
121 tmp |= tile_flags;
122 p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
123 return 0;
124}
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h
new file mode 100644
index 000000000000..c4b257ec920e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r100d.h
@@ -0,0 +1,607 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __R100D_H__
29#define __R100D_H__
30
31#define CP_PACKET0 0x00000000
32#define PACKET0_BASE_INDEX_SHIFT 0
33#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0)
34#define PACKET0_COUNT_SHIFT 16
35#define PACKET0_COUNT_MASK (0x3fff << 16)
36#define CP_PACKET1 0x40000000
37#define CP_PACKET2 0x80000000
38#define PACKET2_PAD_SHIFT 0
39#define PACKET2_PAD_MASK (0x3fffffff << 0)
40#define CP_PACKET3 0xC0000000
41#define PACKET3_IT_OPCODE_SHIFT 8
42#define PACKET3_IT_OPCODE_MASK (0xff << 8)
43#define PACKET3_COUNT_SHIFT 16
44#define PACKET3_COUNT_MASK (0x3fff << 16)
45/* PACKET3 op code */
46#define PACKET3_NOP 0x10
47#define PACKET3_3D_DRAW_VBUF 0x28
48#define PACKET3_3D_DRAW_IMMD 0x29
49#define PACKET3_3D_DRAW_INDX 0x2A
50#define PACKET3_3D_LOAD_VBPNTR 0x2F
51#define PACKET3_INDX_BUFFER 0x33
52#define PACKET3_3D_DRAW_VBUF_2 0x34
53#define PACKET3_3D_DRAW_IMMD_2 0x35
54#define PACKET3_3D_DRAW_INDX_2 0x36
55#define PACKET3_BITBLT_MULTI 0x9B
56
57#define PACKET0(reg, n) (CP_PACKET0 | \
58 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \
59 REG_SET(PACKET0_COUNT, (n)))
60#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
61#define PACKET3(op, n) (CP_PACKET3 | \
62 REG_SET(PACKET3_IT_OPCODE, (op)) | \
63 REG_SET(PACKET3_COUNT, (n)))
64
65#define PACKET_TYPE0 0
66#define PACKET_TYPE1 1
67#define PACKET_TYPE2 2
68#define PACKET_TYPE3 3
69
70#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
71#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
72#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
73#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
74#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
75
76/* Registers */
77#define R_000040_GEN_INT_CNTL 0x000040
78#define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0)
79#define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1)
80#define C_000040_CRTC_VBLANK 0xFFFFFFFE
81#define S_000040_CRTC_VLINE(x) (((x) & 0x1) << 1)
82#define G_000040_CRTC_VLINE(x) (((x) >> 1) & 0x1)
83#define C_000040_CRTC_VLINE 0xFFFFFFFD
84#define S_000040_CRTC_VSYNC(x) (((x) & 0x1) << 2)
85#define G_000040_CRTC_VSYNC(x) (((x) >> 2) & 0x1)
86#define C_000040_CRTC_VSYNC 0xFFFFFFFB
87#define S_000040_SNAPSHOT(x) (((x) & 0x1) << 3)
88#define G_000040_SNAPSHOT(x) (((x) >> 3) & 0x1)
89#define C_000040_SNAPSHOT 0xFFFFFFF7
90#define S_000040_FP_DETECT(x) (((x) & 0x1) << 4)
91#define G_000040_FP_DETECT(x) (((x) >> 4) & 0x1)
92#define C_000040_FP_DETECT 0xFFFFFFEF
93#define S_000040_CRTC2_VLINE(x) (((x) & 0x1) << 5)
94#define G_000040_CRTC2_VLINE(x) (((x) >> 5) & 0x1)
95#define C_000040_CRTC2_VLINE 0xFFFFFFDF
96#define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12)
97#define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1)
98#define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF
99#define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6)
100#define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1)
101#define C_000040_CRTC2_VSYNC 0xFFFFFFBF
102#define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7)
103#define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1)
104#define C_000040_SNAPSHOT2 0xFFFFFF7F
105#define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9)
106#define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1)
107#define C_000040_CRTC2_VBLANK 0xFFFFFDFF
108#define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10)
109#define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1)
110#define C_000040_FP2_DETECT 0xFFFFFBFF
111#define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11)
112#define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1)
113#define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF
114#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13)
115#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1)
116#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF
117#define S_000040_DMA_VIPH2_INT_EN(x) (((x) & 0x1) << 14)
118#define G_000040_DMA_VIPH2_INT_EN(x) (((x) >> 14) & 0x1)
119#define C_000040_DMA_VIPH2_INT_EN 0xFFFFBFFF
120#define S_000040_DMA_VIPH3_INT_EN(x) (((x) & 0x1) << 15)
121#define G_000040_DMA_VIPH3_INT_EN(x) (((x) >> 15) & 0x1)
122#define C_000040_DMA_VIPH3_INT_EN 0xFFFF7FFF
123#define S_000040_I2C_INT_EN(x) (((x) & 0x1) << 17)
124#define G_000040_I2C_INT_EN(x) (((x) >> 17) & 0x1)
125#define C_000040_I2C_INT_EN 0xFFFDFFFF
126#define S_000040_GUI_IDLE(x) (((x) & 0x1) << 19)
127#define G_000040_GUI_IDLE(x) (((x) >> 19) & 0x1)
128#define C_000040_GUI_IDLE 0xFFF7FFFF
129#define S_000040_VIPH_INT_EN(x) (((x) & 0x1) << 24)
130#define G_000040_VIPH_INT_EN(x) (((x) >> 24) & 0x1)
131#define C_000040_VIPH_INT_EN 0xFEFFFFFF
132#define S_000040_SW_INT_EN(x) (((x) & 0x1) << 25)
133#define G_000040_SW_INT_EN(x) (((x) >> 25) & 0x1)
134#define C_000040_SW_INT_EN 0xFDFFFFFF
135#define S_000040_GEYSERVILLE(x) (((x) & 0x1) << 27)
136#define G_000040_GEYSERVILLE(x) (((x) >> 27) & 0x1)
137#define C_000040_GEYSERVILLE 0xF7FFFFFF
138#define S_000040_HDCP_AUTHORIZED_INT(x) (((x) & 0x1) << 28)
139#define G_000040_HDCP_AUTHORIZED_INT(x) (((x) >> 28) & 0x1)
140#define C_000040_HDCP_AUTHORIZED_INT 0xEFFFFFFF
141#define S_000040_DVI_I2C_INT(x) (((x) & 0x1) << 29)
142#define G_000040_DVI_I2C_INT(x) (((x) >> 29) & 0x1)
143#define C_000040_DVI_I2C_INT 0xDFFFFFFF
144#define S_000040_GUIDMA(x) (((x) & 0x1) << 30)
145#define G_000040_GUIDMA(x) (((x) >> 30) & 0x1)
146#define C_000040_GUIDMA 0xBFFFFFFF
147#define S_000040_VIDDMA(x) (((x) & 0x1) << 31)
148#define G_000040_VIDDMA(x) (((x) >> 31) & 0x1)
149#define C_000040_VIDDMA 0x7FFFFFFF
150#define R_000044_GEN_INT_STATUS 0x000044
151#define S_000044_CRTC_VBLANK_STAT(x) (((x) & 0x1) << 0)
152#define G_000044_CRTC_VBLANK_STAT(x) (((x) >> 0) & 0x1)
153#define C_000044_CRTC_VBLANK_STAT 0xFFFFFFFE
154#define S_000044_CRTC_VBLANK_STAT_AK(x) (((x) & 0x1) << 0)
155#define G_000044_CRTC_VBLANK_STAT_AK(x) (((x) >> 0) & 0x1)
156#define C_000044_CRTC_VBLANK_STAT_AK 0xFFFFFFFE
157#define S_000044_CRTC_VLINE_STAT(x) (((x) & 0x1) << 1)
158#define G_000044_CRTC_VLINE_STAT(x) (((x) >> 1) & 0x1)
159#define C_000044_CRTC_VLINE_STAT 0xFFFFFFFD
160#define S_000044_CRTC_VLINE_STAT_AK(x) (((x) & 0x1) << 1)
161#define G_000044_CRTC_VLINE_STAT_AK(x) (((x) >> 1) & 0x1)
162#define C_000044_CRTC_VLINE_STAT_AK 0xFFFFFFFD
163#define S_000044_CRTC_VSYNC_STAT(x) (((x) & 0x1) << 2)
164#define G_000044_CRTC_VSYNC_STAT(x) (((x) >> 2) & 0x1)
165#define C_000044_CRTC_VSYNC_STAT 0xFFFFFFFB
166#define S_000044_CRTC_VSYNC_STAT_AK(x) (((x) & 0x1) << 2)
167#define G_000044_CRTC_VSYNC_STAT_AK(x) (((x) >> 2) & 0x1)
168#define C_000044_CRTC_VSYNC_STAT_AK 0xFFFFFFFB
169#define S_000044_SNAPSHOT_STAT(x) (((x) & 0x1) << 3)
170#define G_000044_SNAPSHOT_STAT(x) (((x) >> 3) & 0x1)
171#define C_000044_SNAPSHOT_STAT 0xFFFFFFF7
172#define S_000044_SNAPSHOT_STAT_AK(x) (((x) & 0x1) << 3)
173#define G_000044_SNAPSHOT_STAT_AK(x) (((x) >> 3) & 0x1)
174#define C_000044_SNAPSHOT_STAT_AK 0xFFFFFFF7
175#define S_000044_FP_DETECT_STAT(x) (((x) & 0x1) << 4)
176#define G_000044_FP_DETECT_STAT(x) (((x) >> 4) & 0x1)
177#define C_000044_FP_DETECT_STAT 0xFFFFFFEF
178#define S_000044_FP_DETECT_STAT_AK(x) (((x) & 0x1) << 4)
179#define G_000044_FP_DETECT_STAT_AK(x) (((x) >> 4) & 0x1)
180#define C_000044_FP_DETECT_STAT_AK 0xFFFFFFEF
181#define S_000044_CRTC2_VLINE_STAT(x) (((x) & 0x1) << 5)
182#define G_000044_CRTC2_VLINE_STAT(x) (((x) >> 5) & 0x1)
183#define C_000044_CRTC2_VLINE_STAT 0xFFFFFFDF
184#define S_000044_CRTC2_VLINE_STAT_AK(x) (((x) & 0x1) << 5)
185#define G_000044_CRTC2_VLINE_STAT_AK(x) (((x) >> 5) & 0x1)
186#define C_000044_CRTC2_VLINE_STAT_AK 0xFFFFFFDF
187#define S_000044_CRTC2_VSYNC_STAT(x) (((x) & 0x1) << 6)
188#define G_000044_CRTC2_VSYNC_STAT(x) (((x) >> 6) & 0x1)
189#define C_000044_CRTC2_VSYNC_STAT 0xFFFFFFBF
190#define S_000044_CRTC2_VSYNC_STAT_AK(x) (((x) & 0x1) << 6)
191#define G_000044_CRTC2_VSYNC_STAT_AK(x) (((x) >> 6) & 0x1)
192#define C_000044_CRTC2_VSYNC_STAT_AK 0xFFFFFFBF
193#define S_000044_SNAPSHOT2_STAT(x) (((x) & 0x1) << 7)
194#define G_000044_SNAPSHOT2_STAT(x) (((x) >> 7) & 0x1)
195#define C_000044_SNAPSHOT2_STAT 0xFFFFFF7F
196#define S_000044_SNAPSHOT2_STAT_AK(x) (((x) & 0x1) << 7)
197#define G_000044_SNAPSHOT2_STAT_AK(x) (((x) >> 7) & 0x1)
198#define C_000044_SNAPSHOT2_STAT_AK 0xFFFFFF7F
199#define S_000044_CAP0_INT_ACTIVE(x) (((x) & 0x1) << 8)
200#define G_000044_CAP0_INT_ACTIVE(x) (((x) >> 8) & 0x1)
201#define C_000044_CAP0_INT_ACTIVE 0xFFFFFEFF
202#define S_000044_CRTC2_VBLANK_STAT(x) (((x) & 0x1) << 9)
203#define G_000044_CRTC2_VBLANK_STAT(x) (((x) >> 9) & 0x1)
204#define C_000044_CRTC2_VBLANK_STAT 0xFFFFFDFF
205#define S_000044_CRTC2_VBLANK_STAT_AK(x) (((x) & 0x1) << 9)
206#define G_000044_CRTC2_VBLANK_STAT_AK(x) (((x) >> 9) & 0x1)
207#define C_000044_CRTC2_VBLANK_STAT_AK 0xFFFFFDFF
208#define S_000044_FP2_DETECT_STAT(x) (((x) & 0x1) << 10)
209#define G_000044_FP2_DETECT_STAT(x) (((x) >> 10) & 0x1)
210#define C_000044_FP2_DETECT_STAT 0xFFFFFBFF
211#define S_000044_FP2_DETECT_STAT_AK(x) (((x) & 0x1) << 10)
212#define G_000044_FP2_DETECT_STAT_AK(x) (((x) >> 10) & 0x1)
213#define C_000044_FP2_DETECT_STAT_AK 0xFFFFFBFF
214#define S_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x) (((x) & 0x1) << 11)
215#define G_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x) (((x) >> 11) & 0x1)
216#define C_000044_VSYNC_DIFF_OVER_LIMIT_STAT 0xFFFFF7FF
217#define S_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x) (((x) & 0x1) << 11)
218#define G_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x) (((x) >> 11) & 0x1)
219#define C_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK 0xFFFFF7FF
220#define S_000044_DMA_VIPH0_INT(x) (((x) & 0x1) << 12)
221#define G_000044_DMA_VIPH0_INT(x) (((x) >> 12) & 0x1)
222#define C_000044_DMA_VIPH0_INT 0xFFFFEFFF
223#define S_000044_DMA_VIPH0_INT_AK(x) (((x) & 0x1) << 12)
224#define G_000044_DMA_VIPH0_INT_AK(x) (((x) >> 12) & 0x1)
225#define C_000044_DMA_VIPH0_INT_AK 0xFFFFEFFF
226#define S_000044_DMA_VIPH1_INT(x) (((x) & 0x1) << 13)
227#define G_000044_DMA_VIPH1_INT(x) (((x) >> 13) & 0x1)
228#define C_000044_DMA_VIPH1_INT 0xFFFFDFFF
229#define S_000044_DMA_VIPH1_INT_AK(x) (((x) & 0x1) << 13)
230#define G_000044_DMA_VIPH1_INT_AK(x) (((x) >> 13) & 0x1)
231#define C_000044_DMA_VIPH1_INT_AK 0xFFFFDFFF
232#define S_000044_DMA_VIPH2_INT(x) (((x) & 0x1) << 14)
233#define G_000044_DMA_VIPH2_INT(x) (((x) >> 14) & 0x1)
234#define C_000044_DMA_VIPH2_INT 0xFFFFBFFF
235#define S_000044_DMA_VIPH2_INT_AK(x) (((x) & 0x1) << 14)
236#define G_000044_DMA_VIPH2_INT_AK(x) (((x) >> 14) & 0x1)
237#define C_000044_DMA_VIPH2_INT_AK 0xFFFFBFFF
238#define S_000044_DMA_VIPH3_INT(x) (((x) & 0x1) << 15)
239#define G_000044_DMA_VIPH3_INT(x) (((x) >> 15) & 0x1)
240#define C_000044_DMA_VIPH3_INT 0xFFFF7FFF
241#define S_000044_DMA_VIPH3_INT_AK(x) (((x) & 0x1) << 15)
242#define G_000044_DMA_VIPH3_INT_AK(x) (((x) >> 15) & 0x1)
243#define C_000044_DMA_VIPH3_INT_AK 0xFFFF7FFF
244#define S_000044_I2C_INT(x) (((x) & 0x1) << 17)
245#define G_000044_I2C_INT(x) (((x) >> 17) & 0x1)
246#define C_000044_I2C_INT 0xFFFDFFFF
247#define S_000044_I2C_INT_AK(x) (((x) & 0x1) << 17)
248#define G_000044_I2C_INT_AK(x) (((x) >> 17) & 0x1)
249#define C_000044_I2C_INT_AK 0xFFFDFFFF
250#define S_000044_GUI_IDLE_STAT(x) (((x) & 0x1) << 19)
251#define G_000044_GUI_IDLE_STAT(x) (((x) >> 19) & 0x1)
252#define C_000044_GUI_IDLE_STAT 0xFFF7FFFF
253#define S_000044_GUI_IDLE_STAT_AK(x) (((x) & 0x1) << 19)
254#define G_000044_GUI_IDLE_STAT_AK(x) (((x) >> 19) & 0x1)
255#define C_000044_GUI_IDLE_STAT_AK 0xFFF7FFFF
256#define S_000044_VIPH_INT(x) (((x) & 0x1) << 24)
257#define G_000044_VIPH_INT(x) (((x) >> 24) & 0x1)
258#define C_000044_VIPH_INT 0xFEFFFFFF
259#define S_000044_SW_INT(x) (((x) & 0x1) << 25)
260#define G_000044_SW_INT(x) (((x) >> 25) & 0x1)
261#define C_000044_SW_INT 0xFDFFFFFF
262#define S_000044_SW_INT_AK(x) (((x) & 0x1) << 25)
263#define G_000044_SW_INT_AK(x) (((x) >> 25) & 0x1)
264#define C_000044_SW_INT_AK 0xFDFFFFFF
265#define S_000044_SW_INT_SET(x) (((x) & 0x1) << 26)
266#define G_000044_SW_INT_SET(x) (((x) >> 26) & 0x1)
267#define C_000044_SW_INT_SET 0xFBFFFFFF
268#define S_000044_GEYSERVILLE_STAT(x) (((x) & 0x1) << 27)
269#define G_000044_GEYSERVILLE_STAT(x) (((x) >> 27) & 0x1)
270#define C_000044_GEYSERVILLE_STAT 0xF7FFFFFF
271#define S_000044_GEYSERVILLE_STAT_AK(x) (((x) & 0x1) << 27)
272#define G_000044_GEYSERVILLE_STAT_AK(x) (((x) >> 27) & 0x1)
273#define C_000044_GEYSERVILLE_STAT_AK 0xF7FFFFFF
274#define S_000044_HDCP_AUTHORIZED_INT_STAT(x) (((x) & 0x1) << 28)
275#define G_000044_HDCP_AUTHORIZED_INT_STAT(x) (((x) >> 28) & 0x1)
276#define C_000044_HDCP_AUTHORIZED_INT_STAT 0xEFFFFFFF
277#define S_000044_HDCP_AUTHORIZED_INT_AK(x) (((x) & 0x1) << 28)
278#define G_000044_HDCP_AUTHORIZED_INT_AK(x) (((x) >> 28) & 0x1)
279#define C_000044_HDCP_AUTHORIZED_INT_AK 0xEFFFFFFF
280#define S_000044_DVI_I2C_INT_STAT(x) (((x) & 0x1) << 29)
281#define G_000044_DVI_I2C_INT_STAT(x) (((x) >> 29) & 0x1)
282#define C_000044_DVI_I2C_INT_STAT 0xDFFFFFFF
283#define S_000044_DVI_I2C_INT_AK(x) (((x) & 0x1) << 29)
284#define G_000044_DVI_I2C_INT_AK(x) (((x) >> 29) & 0x1)
285#define C_000044_DVI_I2C_INT_AK 0xDFFFFFFF
286#define S_000044_GUIDMA_STAT(x) (((x) & 0x1) << 30)
287#define G_000044_GUIDMA_STAT(x) (((x) >> 30) & 0x1)
288#define C_000044_GUIDMA_STAT 0xBFFFFFFF
289#define S_000044_GUIDMA_AK(x) (((x) & 0x1) << 30)
290#define G_000044_GUIDMA_AK(x) (((x) >> 30) & 0x1)
291#define C_000044_GUIDMA_AK 0xBFFFFFFF
292#define S_000044_VIDDMA_STAT(x) (((x) & 0x1) << 31)
293#define G_000044_VIDDMA_STAT(x) (((x) >> 31) & 0x1)
294#define C_000044_VIDDMA_STAT 0x7FFFFFFF
295#define S_000044_VIDDMA_AK(x) (((x) & 0x1) << 31)
296#define G_000044_VIDDMA_AK(x) (((x) >> 31) & 0x1)
297#define C_000044_VIDDMA_AK 0x7FFFFFFF
298#define R_000050_CRTC_GEN_CNTL 0x000050
299#define S_000050_CRTC_DBL_SCAN_EN(x) (((x) & 0x1) << 0)
300#define G_000050_CRTC_DBL_SCAN_EN(x) (((x) >> 0) & 0x1)
301#define C_000050_CRTC_DBL_SCAN_EN 0xFFFFFFFE
302#define S_000050_CRTC_INTERLACE_EN(x) (((x) & 0x1) << 1)
303#define G_000050_CRTC_INTERLACE_EN(x) (((x) >> 1) & 0x1)
304#define C_000050_CRTC_INTERLACE_EN 0xFFFFFFFD
305#define S_000050_CRTC_C_SYNC_EN(x) (((x) & 0x1) << 4)
306#define G_000050_CRTC_C_SYNC_EN(x) (((x) >> 4) & 0x1)
307#define C_000050_CRTC_C_SYNC_EN 0xFFFFFFEF
308#define S_000050_CRTC_PIX_WIDTH(x) (((x) & 0xF) << 8)
309#define G_000050_CRTC_PIX_WIDTH(x) (((x) >> 8) & 0xF)
310#define C_000050_CRTC_PIX_WIDTH 0xFFFFF0FF
311#define S_000050_CRTC_ICON_EN(x) (((x) & 0x1) << 15)
312#define G_000050_CRTC_ICON_EN(x) (((x) >> 15) & 0x1)
313#define C_000050_CRTC_ICON_EN 0xFFFF7FFF
314#define S_000050_CRTC_CUR_EN(x) (((x) & 0x1) << 16)
315#define G_000050_CRTC_CUR_EN(x) (((x) >> 16) & 0x1)
316#define C_000050_CRTC_CUR_EN 0xFFFEFFFF
317#define S_000050_CRTC_VSTAT_MODE(x) (((x) & 0x3) << 17)
318#define G_000050_CRTC_VSTAT_MODE(x) (((x) >> 17) & 0x3)
319#define C_000050_CRTC_VSTAT_MODE 0xFFF9FFFF
320#define S_000050_CRTC_CUR_MODE(x) (((x) & 0x7) << 20)
321#define G_000050_CRTC_CUR_MODE(x) (((x) >> 20) & 0x7)
322#define C_000050_CRTC_CUR_MODE 0xFF8FFFFF
323#define S_000050_CRTC_EXT_DISP_EN(x) (((x) & 0x1) << 24)
324#define G_000050_CRTC_EXT_DISP_EN(x) (((x) >> 24) & 0x1)
325#define C_000050_CRTC_EXT_DISP_EN 0xFEFFFFFF
326#define S_000050_CRTC_EN(x) (((x) & 0x1) << 25)
327#define G_000050_CRTC_EN(x) (((x) >> 25) & 0x1)
328#define C_000050_CRTC_EN 0xFDFFFFFF
329#define S_000050_CRTC_DISP_REQ_EN_B(x) (((x) & 0x1) << 26)
330#define G_000050_CRTC_DISP_REQ_EN_B(x) (((x) >> 26) & 0x1)
331#define C_000050_CRTC_DISP_REQ_EN_B 0xFBFFFFFF
332#define R_000054_CRTC_EXT_CNTL 0x000054
333#define S_000054_CRTC_VGA_XOVERSCAN(x) (((x) & 0x1) << 0)
334#define G_000054_CRTC_VGA_XOVERSCAN(x) (((x) >> 0) & 0x1)
335#define C_000054_CRTC_VGA_XOVERSCAN 0xFFFFFFFE
336#define S_000054_VGA_BLINK_RATE(x) (((x) & 0x3) << 1)
337#define G_000054_VGA_BLINK_RATE(x) (((x) >> 1) & 0x3)
338#define C_000054_VGA_BLINK_RATE 0xFFFFFFF9
339#define S_000054_VGA_ATI_LINEAR(x) (((x) & 0x1) << 3)
340#define G_000054_VGA_ATI_LINEAR(x) (((x) >> 3) & 0x1)
341#define C_000054_VGA_ATI_LINEAR 0xFFFFFFF7
342#define S_000054_VGA_128KAP_PAGING(x) (((x) & 0x1) << 4)
343#define G_000054_VGA_128KAP_PAGING(x) (((x) >> 4) & 0x1)
344#define C_000054_VGA_128KAP_PAGING 0xFFFFFFEF
345#define S_000054_VGA_TEXT_132(x) (((x) & 0x1) << 5)
346#define G_000054_VGA_TEXT_132(x) (((x) >> 5) & 0x1)
347#define C_000054_VGA_TEXT_132 0xFFFFFFDF
348#define S_000054_VGA_XCRT_CNT_EN(x) (((x) & 0x1) << 6)
349#define G_000054_VGA_XCRT_CNT_EN(x) (((x) >> 6) & 0x1)
350#define C_000054_VGA_XCRT_CNT_EN 0xFFFFFFBF
351#define S_000054_CRTC_HSYNC_DIS(x) (((x) & 0x1) << 8)
352#define G_000054_CRTC_HSYNC_DIS(x) (((x) >> 8) & 0x1)
353#define C_000054_CRTC_HSYNC_DIS 0xFFFFFEFF
354#define S_000054_CRTC_VSYNC_DIS(x) (((x) & 0x1) << 9)
355#define G_000054_CRTC_VSYNC_DIS(x) (((x) >> 9) & 0x1)
356#define C_000054_CRTC_VSYNC_DIS 0xFFFFFDFF
357#define S_000054_CRTC_DISPLAY_DIS(x) (((x) & 0x1) << 10)
358#define G_000054_CRTC_DISPLAY_DIS(x) (((x) >> 10) & 0x1)
359#define C_000054_CRTC_DISPLAY_DIS 0xFFFFFBFF
360#define S_000054_CRTC_SYNC_TRISTATE(x) (((x) & 0x1) << 11)
361#define G_000054_CRTC_SYNC_TRISTATE(x) (((x) >> 11) & 0x1)
362#define C_000054_CRTC_SYNC_TRISTATE 0xFFFFF7FF
363#define S_000054_CRTC_HSYNC_TRISTATE(x) (((x) & 0x1) << 12)
364#define G_000054_CRTC_HSYNC_TRISTATE(x) (((x) >> 12) & 0x1)
365#define C_000054_CRTC_HSYNC_TRISTATE 0xFFFFEFFF
366#define S_000054_CRTC_VSYNC_TRISTATE(x) (((x) & 0x1) << 13)
367#define G_000054_CRTC_VSYNC_TRISTATE(x) (((x) >> 13) & 0x1)
368#define C_000054_CRTC_VSYNC_TRISTATE 0xFFFFDFFF
369#define S_000054_CRT_ON(x) (((x) & 0x1) << 15)
370#define G_000054_CRT_ON(x) (((x) >> 15) & 0x1)
371#define C_000054_CRT_ON 0xFFFF7FFF
372#define S_000054_VGA_CUR_B_TEST(x) (((x) & 0x1) << 17)
373#define G_000054_VGA_CUR_B_TEST(x) (((x) >> 17) & 0x1)
374#define C_000054_VGA_CUR_B_TEST 0xFFFDFFFF
375#define S_000054_VGA_PACK_DIS(x) (((x) & 0x1) << 18)
376#define G_000054_VGA_PACK_DIS(x) (((x) >> 18) & 0x1)
377#define C_000054_VGA_PACK_DIS 0xFFFBFFFF
378#define S_000054_VGA_MEM_PS_EN(x) (((x) & 0x1) << 19)
379#define G_000054_VGA_MEM_PS_EN(x) (((x) >> 19) & 0x1)
380#define C_000054_VGA_MEM_PS_EN 0xFFF7FFFF
381#define S_000054_VCRTC_IDX_MASTER(x) (((x) & 0x7F) << 24)
382#define G_000054_VCRTC_IDX_MASTER(x) (((x) >> 24) & 0x7F)
383#define C_000054_VCRTC_IDX_MASTER 0x80FFFFFF
384#define R_00023C_DISPLAY_BASE_ADDR 0x00023C
385#define S_00023C_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
386#define G_00023C_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
387#define C_00023C_DISPLAY_BASE_ADDR 0x00000000
388#define R_000260_CUR_OFFSET 0x000260
389#define S_000260_CUR_OFFSET(x) (((x) & 0x7FFFFFF) << 0)
390#define G_000260_CUR_OFFSET(x) (((x) >> 0) & 0x7FFFFFF)
391#define C_000260_CUR_OFFSET 0xF8000000
392#define S_000260_CUR_LOCK(x) (((x) & 0x1) << 31)
393#define G_000260_CUR_LOCK(x) (((x) >> 31) & 0x1)
394#define C_000260_CUR_LOCK 0x7FFFFFFF
395#define R_00033C_CRTC2_DISPLAY_BASE_ADDR 0x00033C
396#define S_00033C_CRTC2_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
397#define G_00033C_CRTC2_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
398#define C_00033C_CRTC2_DISPLAY_BASE_ADDR 0x00000000
399#define R_000360_CUR2_OFFSET 0x000360
400#define S_000360_CUR2_OFFSET(x) (((x) & 0x7FFFFFF) << 0)
401#define G_000360_CUR2_OFFSET(x) (((x) >> 0) & 0x7FFFFFF)
402#define C_000360_CUR2_OFFSET 0xF8000000
403#define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31)
404#define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1)
405#define C_000360_CUR2_LOCK 0x7FFFFFFF
406#define R_0003C0_GENMO_WT 0x0003C0
407#define S_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0)
408#define G_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1)
409#define C_0003C0_GENMO_MONO_ADDRESS_B 0xFFFFFFFE
410#define S_0003C0_VGA_RAM_EN(x) (((x) & 0x1) << 1)
411#define G_0003C0_VGA_RAM_EN(x) (((x) >> 1) & 0x1)
412#define C_0003C0_VGA_RAM_EN 0xFFFFFFFD
413#define S_0003C0_VGA_CKSEL(x) (((x) & 0x3) << 2)
414#define G_0003C0_VGA_CKSEL(x) (((x) >> 2) & 0x3)
415#define C_0003C0_VGA_CKSEL 0xFFFFFFF3
416#define S_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5)
417#define G_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1)
418#define C_0003C0_ODD_EVEN_MD_PGSEL 0xFFFFFFDF
419#define S_0003C0_VGA_HSYNC_POL(x) (((x) & 0x1) << 6)
420#define G_0003C0_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1)
421#define C_0003C0_VGA_HSYNC_POL 0xFFFFFFBF
422#define S_0003C0_VGA_VSYNC_POL(x) (((x) & 0x1) << 7)
423#define G_0003C0_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1)
424#define C_0003C0_VGA_VSYNC_POL 0xFFFFFF7F
425#define R_0003F8_CRTC2_GEN_CNTL 0x0003F8
426#define S_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) & 0x1) << 0)
427#define G_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) >> 0) & 0x1)
428#define C_0003F8_CRTC2_DBL_SCAN_EN 0xFFFFFFFE
429#define S_0003F8_CRTC2_INTERLACE_EN(x) (((x) & 0x1) << 1)
430#define G_0003F8_CRTC2_INTERLACE_EN(x) (((x) >> 1) & 0x1)
431#define C_0003F8_CRTC2_INTERLACE_EN 0xFFFFFFFD
432#define S_0003F8_CRTC2_SYNC_TRISTATE(x) (((x) & 0x1) << 4)
433#define G_0003F8_CRTC2_SYNC_TRISTATE(x) (((x) >> 4) & 0x1)
434#define C_0003F8_CRTC2_SYNC_TRISTATE 0xFFFFFFEF
435#define S_0003F8_CRTC2_HSYNC_TRISTATE(x) (((x) & 0x1) << 5)
436#define G_0003F8_CRTC2_HSYNC_TRISTATE(x) (((x) >> 5) & 0x1)
437#define C_0003F8_CRTC2_HSYNC_TRISTATE 0xFFFFFFDF
438#define S_0003F8_CRTC2_VSYNC_TRISTATE(x) (((x) & 0x1) << 6)
439#define G_0003F8_CRTC2_VSYNC_TRISTATE(x) (((x) >> 6) & 0x1)
440#define C_0003F8_CRTC2_VSYNC_TRISTATE 0xFFFFFFBF
441#define S_0003F8_CRT2_ON(x) (((x) & 0x1) << 7)
442#define G_0003F8_CRT2_ON(x) (((x) >> 7) & 0x1)
443#define C_0003F8_CRT2_ON 0xFFFFFF7F
444#define S_0003F8_CRTC2_PIX_WIDTH(x) (((x) & 0xF) << 8)
445#define G_0003F8_CRTC2_PIX_WIDTH(x) (((x) >> 8) & 0xF)
446#define C_0003F8_CRTC2_PIX_WIDTH 0xFFFFF0FF
447#define S_0003F8_CRTC2_ICON_EN(x) (((x) & 0x1) << 15)
448#define G_0003F8_CRTC2_ICON_EN(x) (((x) >> 15) & 0x1)
449#define C_0003F8_CRTC2_ICON_EN 0xFFFF7FFF
450#define S_0003F8_CRTC2_CUR_EN(x) (((x) & 0x1) << 16)
451#define G_0003F8_CRTC2_CUR_EN(x) (((x) >> 16) & 0x1)
452#define C_0003F8_CRTC2_CUR_EN 0xFFFEFFFF
453#define S_0003F8_CRTC2_CUR_MODE(x) (((x) & 0x7) << 20)
454#define G_0003F8_CRTC2_CUR_MODE(x) (((x) >> 20) & 0x7)
455#define C_0003F8_CRTC2_CUR_MODE 0xFF8FFFFF
456#define S_0003F8_CRTC2_DISPLAY_DIS(x) (((x) & 0x1) << 23)
457#define G_0003F8_CRTC2_DISPLAY_DIS(x) (((x) >> 23) & 0x1)
458#define C_0003F8_CRTC2_DISPLAY_DIS 0xFF7FFFFF
459#define S_0003F8_CRTC2_EN(x) (((x) & 0x1) << 25)
460#define G_0003F8_CRTC2_EN(x) (((x) >> 25) & 0x1)
461#define C_0003F8_CRTC2_EN 0xFDFFFFFF
462#define S_0003F8_CRTC2_DISP_REQ_EN_B(x) (((x) & 0x1) << 26)
463#define G_0003F8_CRTC2_DISP_REQ_EN_B(x) (((x) >> 26) & 0x1)
464#define C_0003F8_CRTC2_DISP_REQ_EN_B 0xFBFFFFFF
465#define S_0003F8_CRTC2_C_SYNC_EN(x) (((x) & 0x1) << 27)
466#define G_0003F8_CRTC2_C_SYNC_EN(x) (((x) >> 27) & 0x1)
467#define C_0003F8_CRTC2_C_SYNC_EN 0xF7FFFFFF
468#define S_0003F8_CRTC2_HSYNC_DIS(x) (((x) & 0x1) << 28)
469#define G_0003F8_CRTC2_HSYNC_DIS(x) (((x) >> 28) & 0x1)
470#define C_0003F8_CRTC2_HSYNC_DIS 0xEFFFFFFF
471#define S_0003F8_CRTC2_VSYNC_DIS(x) (((x) & 0x1) << 29)
472#define G_0003F8_CRTC2_VSYNC_DIS(x) (((x) >> 29) & 0x1)
473#define C_0003F8_CRTC2_VSYNC_DIS 0xDFFFFFFF
474#define R_000420_OV0_SCALE_CNTL 0x000420
475#define S_000420_OV0_NO_READ_BEHIND_SCAN(x) (((x) & 0x1) << 1)
476#define G_000420_OV0_NO_READ_BEHIND_SCAN(x) (((x) >> 1) & 0x1)
477#define C_000420_OV0_NO_READ_BEHIND_SCAN 0xFFFFFFFD
478#define S_000420_OV0_HORZ_PICK_NEAREST(x) (((x) & 0x1) << 2)
479#define G_000420_OV0_HORZ_PICK_NEAREST(x) (((x) >> 2) & 0x1)
480#define C_000420_OV0_HORZ_PICK_NEAREST 0xFFFFFFFB
481#define S_000420_OV0_VERT_PICK_NEAREST(x) (((x) & 0x1) << 3)
482#define G_000420_OV0_VERT_PICK_NEAREST(x) (((x) >> 3) & 0x1)
483#define C_000420_OV0_VERT_PICK_NEAREST 0xFFFFFFF7
484#define S_000420_OV0_SIGNED_UV(x) (((x) & 0x1) << 4)
485#define G_000420_OV0_SIGNED_UV(x) (((x) >> 4) & 0x1)
486#define C_000420_OV0_SIGNED_UV 0xFFFFFFEF
487#define S_000420_OV0_GAMMA_SEL(x) (((x) & 0x7) << 5)
488#define G_000420_OV0_GAMMA_SEL(x) (((x) >> 5) & 0x7)
489#define C_000420_OV0_GAMMA_SEL 0xFFFFFF1F
490#define S_000420_OV0_SURFACE_FORMAT(x) (((x) & 0xF) << 8)
491#define G_000420_OV0_SURFACE_FORMAT(x) (((x) >> 8) & 0xF)
492#define C_000420_OV0_SURFACE_FORMAT 0xFFFFF0FF
493#define S_000420_OV0_ADAPTIVE_DEINT(x) (((x) & 0x1) << 12)
494#define G_000420_OV0_ADAPTIVE_DEINT(x) (((x) >> 12) & 0x1)
495#define C_000420_OV0_ADAPTIVE_DEINT 0xFFFFEFFF
496#define S_000420_OV0_CRTC_SEL(x) (((x) & 0x1) << 14)
497#define G_000420_OV0_CRTC_SEL(x) (((x) >> 14) & 0x1)
498#define C_000420_OV0_CRTC_SEL 0xFFFFBFFF
499#define S_000420_OV0_BURST_PER_PLANE(x) (((x) & 0x7F) << 16)
500#define G_000420_OV0_BURST_PER_PLANE(x) (((x) >> 16) & 0x7F)
501#define C_000420_OV0_BURST_PER_PLANE 0xFF80FFFF
502#define S_000420_OV0_DOUBLE_BUFFER_REGS(x) (((x) & 0x1) << 24)
503#define G_000420_OV0_DOUBLE_BUFFER_REGS(x) (((x) >> 24) & 0x1)
504#define C_000420_OV0_DOUBLE_BUFFER_REGS 0xFEFFFFFF
505#define S_000420_OV0_BANDWIDTH(x) (((x) & 0x1) << 26)
506#define G_000420_OV0_BANDWIDTH(x) (((x) >> 26) & 0x1)
507#define C_000420_OV0_BANDWIDTH 0xFBFFFFFF
508#define S_000420_OV0_LIN_TRANS_BYPASS(x) (((x) & 0x1) << 28)
509#define G_000420_OV0_LIN_TRANS_BYPASS(x) (((x) >> 28) & 0x1)
510#define C_000420_OV0_LIN_TRANS_BYPASS 0xEFFFFFFF
511#define S_000420_OV0_INT_EMU(x) (((x) & 0x1) << 29)
512#define G_000420_OV0_INT_EMU(x) (((x) >> 29) & 0x1)
513#define C_000420_OV0_INT_EMU 0xDFFFFFFF
514#define S_000420_OV0_OVERLAY_EN(x) (((x) & 0x1) << 30)
515#define G_000420_OV0_OVERLAY_EN(x) (((x) >> 30) & 0x1)
516#define C_000420_OV0_OVERLAY_EN 0xBFFFFFFF
517#define S_000420_OV0_SOFT_RESET(x) (((x) & 0x1) << 31)
518#define G_000420_OV0_SOFT_RESET(x) (((x) >> 31) & 0x1)
519#define C_000420_OV0_SOFT_RESET 0x7FFFFFFF
520#define R_00070C_CP_RB_RPTR_ADDR 0x00070C
521#define S_00070C_RB_RPTR_SWAP(x) (((x) & 0x3) << 0)
522#define G_00070C_RB_RPTR_SWAP(x) (((x) >> 0) & 0x3)
523#define C_00070C_RB_RPTR_SWAP 0xFFFFFFFC
524#define S_00070C_RB_RPTR_ADDR(x) (((x) & 0x3FFFFFFF) << 2)
525#define G_00070C_RB_RPTR_ADDR(x) (((x) >> 2) & 0x3FFFFFFF)
526#define C_00070C_RB_RPTR_ADDR 0x00000003
527#define R_000740_CP_CSQ_CNTL 0x000740
528#define S_000740_CSQ_CNT_PRIMARY(x) (((x) & 0xFF) << 0)
529#define G_000740_CSQ_CNT_PRIMARY(x) (((x) >> 0) & 0xFF)
530#define C_000740_CSQ_CNT_PRIMARY 0xFFFFFF00
531#define S_000740_CSQ_CNT_INDIRECT(x) (((x) & 0xFF) << 8)
532#define G_000740_CSQ_CNT_INDIRECT(x) (((x) >> 8) & 0xFF)
533#define C_000740_CSQ_CNT_INDIRECT 0xFFFF00FF
534#define S_000740_CSQ_MODE(x) (((x) & 0xF) << 28)
535#define G_000740_CSQ_MODE(x) (((x) >> 28) & 0xF)
536#define C_000740_CSQ_MODE 0x0FFFFFFF
537#define R_000770_SCRATCH_UMSK 0x000770
538#define S_000770_SCRATCH_UMSK(x) (((x) & 0x3F) << 0)
539#define G_000770_SCRATCH_UMSK(x) (((x) >> 0) & 0x3F)
540#define C_000770_SCRATCH_UMSK 0xFFFFFFC0
541#define S_000770_SCRATCH_SWAP(x) (((x) & 0x3) << 16)
542#define G_000770_SCRATCH_SWAP(x) (((x) >> 16) & 0x3)
543#define C_000770_SCRATCH_SWAP 0xFFFCFFFF
544#define R_000774_SCRATCH_ADDR 0x000774
545#define S_000774_SCRATCH_ADDR(x) (((x) & 0x7FFFFFF) << 5)
546#define G_000774_SCRATCH_ADDR(x) (((x) >> 5) & 0x7FFFFFF)
547#define C_000774_SCRATCH_ADDR 0x0000001F
548#define R_000E40_RBBM_STATUS 0x000E40
549#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
550#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
551#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
552#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
553#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
554#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
555#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
556#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
557#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
558#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
559#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
560#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
561#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
562#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
563#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
564#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
565#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
566#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
567#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
568#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
569#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
570#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
571#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
572#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
573#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
574#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
575#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
576#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
577#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
578#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
579#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
580#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
581#define C_000E40_E2_BUSY 0xFFFDFFFF
582#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
583#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
584#define C_000E40_RB2D_BUSY 0xFFFBFFFF
585#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
586#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
587#define C_000E40_RB3D_BUSY 0xFFF7FFFF
588#define S_000E40_SE_BUSY(x) (((x) & 0x1) << 20)
589#define G_000E40_SE_BUSY(x) (((x) >> 20) & 0x1)
590#define C_000E40_SE_BUSY 0xFFEFFFFF
591#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
592#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
593#define C_000E40_RE_BUSY 0xFFDFFFFF
594#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
595#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
596#define C_000E40_TAM_BUSY 0xFFBFFFFF
597#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
598#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
599#define C_000E40_TDM_BUSY 0xFF7FFFFF
600#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
601#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
602#define C_000E40_PB_BUSY 0xFEFFFFFF
603#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
604#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
605#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
606
607#endif
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
new file mode 100644
index 000000000000..568c74bfba3d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -0,0 +1,456 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include "drmP.h"
29#include "drm.h"
30#include "radeon_drm.h"
31#include "radeon_reg.h"
32#include "radeon.h"
33
34#include "r200_reg_safe.h"
35
36#include "r100_track.h"
37
38static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
39{
40 int vtx_size, i;
41 vtx_size = 2;
42
43 if (vtx_fmt_0 & R200_VTX_Z0)
44 vtx_size++;
45 if (vtx_fmt_0 & R200_VTX_W0)
46 vtx_size++;
47 /* blend weight */
48 if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
49 vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
50 if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
51 vtx_size++;
52 if (vtx_fmt_0 & R200_VTX_N0)
53 vtx_size += 3;
54 if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
55 vtx_size++;
56 if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
57 vtx_size++;
58 if (vtx_fmt_0 & R200_VTX_SHININESS_0)
59 vtx_size++;
60 if (vtx_fmt_0 & R200_VTX_SHININESS_1)
61 vtx_size++;
62 for (i = 0; i < 8; i++) {
63 int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
64 switch (color_size) {
65 case 0: break;
66 case 1: vtx_size++; break;
67 case 2: vtx_size += 3; break;
68 case 3: vtx_size += 4; break;
69 }
70 }
71 if (vtx_fmt_0 & R200_VTX_XY1)
72 vtx_size += 2;
73 if (vtx_fmt_0 & R200_VTX_Z1)
74 vtx_size++;
75 if (vtx_fmt_0 & R200_VTX_W1)
76 vtx_size++;
77 if (vtx_fmt_0 & R200_VTX_N1)
78 vtx_size += 3;
79 return vtx_size;
80}
81
82static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
83{
84 int vtx_size, i, tex_size;
85 vtx_size = 0;
86 for (i = 0; i < 6; i++) {
87 tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
88 if (tex_size > 4)
89 continue;
90 vtx_size += tex_size;
91 }
92 return vtx_size;
93}
94
95int r200_packet0_check(struct radeon_cs_parser *p,
96 struct radeon_cs_packet *pkt,
97 unsigned idx, unsigned reg)
98{
99 struct radeon_cs_chunk *ib_chunk;
100 struct radeon_cs_reloc *reloc;
101 struct r100_cs_track *track;
102 volatile uint32_t *ib;
103 uint32_t tmp;
104 int r;
105 int i;
106 int face;
107 u32 tile_flags = 0;
108
109 ib = p->ib->ptr;
110 ib_chunk = &p->chunks[p->chunk_ib_idx];
111 track = (struct r100_cs_track *)p->track;
112
113 switch (reg) {
114 case RADEON_CRTC_GUI_TRIG_VLINE:
115 r = r100_cs_packet_parse_vline(p);
116 if (r) {
117 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
118 idx, reg);
119 r100_cs_dump_packet(p, pkt);
120 return r;
121 }
122 break;
123 /* FIXME: only allow PACKET3 blit? easier to check for out of
124 * range access */
125 case RADEON_DST_PITCH_OFFSET:
126 case RADEON_SRC_PITCH_OFFSET:
127 r = r100_reloc_pitch_offset(p, pkt, idx, reg);
128 if (r)
129 return r;
130 break;
131 case RADEON_RB3D_DEPTHOFFSET:
132 r = r100_cs_packet_next_reloc(p, &reloc);
133 if (r) {
134 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
135 idx, reg);
136 r100_cs_dump_packet(p, pkt);
137 return r;
138 }
139 track->zb.robj = reloc->robj;
140 track->zb.offset = ib_chunk->kdata[idx];
141 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
142 break;
143 case RADEON_RB3D_COLOROFFSET:
144 r = r100_cs_packet_next_reloc(p, &reloc);
145 if (r) {
146 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
147 idx, reg);
148 r100_cs_dump_packet(p, pkt);
149 return r;
150 }
151 track->cb[0].robj = reloc->robj;
152 track->cb[0].offset = ib_chunk->kdata[idx];
153 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
154 break;
155 case R200_PP_TXOFFSET_0:
156 case R200_PP_TXOFFSET_1:
157 case R200_PP_TXOFFSET_2:
158 case R200_PP_TXOFFSET_3:
159 case R200_PP_TXOFFSET_4:
160 case R200_PP_TXOFFSET_5:
161 i = (reg - R200_PP_TXOFFSET_0) / 24;
162 r = r100_cs_packet_next_reloc(p, &reloc);
163 if (r) {
164 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
165 idx, reg);
166 r100_cs_dump_packet(p, pkt);
167 return r;
168 }
169 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
170 track->textures[i].robj = reloc->robj;
171 break;
172 case R200_PP_CUBIC_OFFSET_F1_0:
173 case R200_PP_CUBIC_OFFSET_F2_0:
174 case R200_PP_CUBIC_OFFSET_F3_0:
175 case R200_PP_CUBIC_OFFSET_F4_0:
176 case R200_PP_CUBIC_OFFSET_F5_0:
177 case R200_PP_CUBIC_OFFSET_F1_1:
178 case R200_PP_CUBIC_OFFSET_F2_1:
179 case R200_PP_CUBIC_OFFSET_F3_1:
180 case R200_PP_CUBIC_OFFSET_F4_1:
181 case R200_PP_CUBIC_OFFSET_F5_1:
182 case R200_PP_CUBIC_OFFSET_F1_2:
183 case R200_PP_CUBIC_OFFSET_F2_2:
184 case R200_PP_CUBIC_OFFSET_F3_2:
185 case R200_PP_CUBIC_OFFSET_F4_2:
186 case R200_PP_CUBIC_OFFSET_F5_2:
187 case R200_PP_CUBIC_OFFSET_F1_3:
188 case R200_PP_CUBIC_OFFSET_F2_3:
189 case R200_PP_CUBIC_OFFSET_F3_3:
190 case R200_PP_CUBIC_OFFSET_F4_3:
191 case R200_PP_CUBIC_OFFSET_F5_3:
192 case R200_PP_CUBIC_OFFSET_F1_4:
193 case R200_PP_CUBIC_OFFSET_F2_4:
194 case R200_PP_CUBIC_OFFSET_F3_4:
195 case R200_PP_CUBIC_OFFSET_F4_4:
196 case R200_PP_CUBIC_OFFSET_F5_4:
197 case R200_PP_CUBIC_OFFSET_F1_5:
198 case R200_PP_CUBIC_OFFSET_F2_5:
199 case R200_PP_CUBIC_OFFSET_F3_5:
200 case R200_PP_CUBIC_OFFSET_F4_5:
201 case R200_PP_CUBIC_OFFSET_F5_5:
202 i = (reg - R200_PP_TXOFFSET_0) / 24;
203 face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
204 r = r100_cs_packet_next_reloc(p, &reloc);
205 if (r) {
206 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
207 idx, reg);
208 r100_cs_dump_packet(p, pkt);
209 return r;
210 }
211 track->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx];
212 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
213 track->textures[i].cube_info[face - 1].robj = reloc->robj;
214 break;
215 case RADEON_RE_WIDTH_HEIGHT:
216 track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
217 break;
218 case RADEON_RB3D_COLORPITCH:
219 r = r100_cs_packet_next_reloc(p, &reloc);
220 if (r) {
221 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
222 idx, reg);
223 r100_cs_dump_packet(p, pkt);
224 return r;
225 }
226
227 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
228 tile_flags |= RADEON_COLOR_TILE_ENABLE;
229 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
230 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
231
232 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
233 tmp |= tile_flags;
234 ib[idx] = tmp;
235
236 track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
237 break;
238 case RADEON_RB3D_DEPTHPITCH:
239 track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
240 break;
241 case RADEON_RB3D_CNTL:
242 switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
243 case 7:
244 case 8:
245 case 9:
246 case 11:
247 case 12:
248 track->cb[0].cpp = 1;
249 break;
250 case 3:
251 case 4:
252 case 15:
253 track->cb[0].cpp = 2;
254 break;
255 case 6:
256 track->cb[0].cpp = 4;
257 break;
258 default:
259 DRM_ERROR("Invalid color buffer format (%d) !\n",
260 ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
261 return -EINVAL;
262 }
263 if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) {
264 DRM_ERROR("No support for depth xy offset in kms\n");
265 return -EINVAL;
266 }
267
268 track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
269 break;
270 case RADEON_RB3D_ZSTENCILCNTL:
271 switch (ib_chunk->kdata[idx] & 0xf) {
272 case 0:
273 track->zb.cpp = 2;
274 break;
275 case 2:
276 case 3:
277 case 4:
278 case 5:
279 case 9:
280 case 11:
281 track->zb.cpp = 4;
282 break;
283 default:
284 break;
285 }
286 break;
287 case RADEON_RB3D_ZPASS_ADDR:
288 r = r100_cs_packet_next_reloc(p, &reloc);
289 if (r) {
290 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
291 idx, reg);
292 r100_cs_dump_packet(p, pkt);
293 return r;
294 }
295 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
296 break;
297 case RADEON_PP_CNTL:
298 {
299 uint32_t temp = ib_chunk->kdata[idx] >> 4;
300 for (i = 0; i < track->num_texture; i++)
301 track->textures[i].enabled = !!(temp & (1 << i));
302 }
303 break;
304 case RADEON_SE_VF_CNTL:
305 track->vap_vf_cntl = ib_chunk->kdata[idx];
306 break;
307 case 0x210c:
308 /* VAP_VF_MAX_VTX_INDX */
309 track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL;
310 break;
311 case R200_SE_VTX_FMT_0:
312 track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]);
313 break;
314 case R200_SE_VTX_FMT_1:
315 track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]);
316 break;
317 case R200_PP_TXSIZE_0:
318 case R200_PP_TXSIZE_1:
319 case R200_PP_TXSIZE_2:
320 case R200_PP_TXSIZE_3:
321 case R200_PP_TXSIZE_4:
322 case R200_PP_TXSIZE_5:
323 i = (reg - R200_PP_TXSIZE_0) / 32;
324 track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
325 track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
326 break;
327 case R200_PP_TXPITCH_0:
328 case R200_PP_TXPITCH_1:
329 case R200_PP_TXPITCH_2:
330 case R200_PP_TXPITCH_3:
331 case R200_PP_TXPITCH_4:
332 case R200_PP_TXPITCH_5:
333 i = (reg - R200_PP_TXPITCH_0) / 32;
334 track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
335 break;
336 case R200_PP_TXFILTER_0:
337 case R200_PP_TXFILTER_1:
338 case R200_PP_TXFILTER_2:
339 case R200_PP_TXFILTER_3:
340 case R200_PP_TXFILTER_4:
341 case R200_PP_TXFILTER_5:
342 i = (reg - R200_PP_TXFILTER_0) / 32;
343 track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK)
344 >> R200_MAX_MIP_LEVEL_SHIFT);
345 tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
346 if (tmp == 2 || tmp == 6)
347 track->textures[i].roundup_w = false;
348 tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
349 if (tmp == 2 || tmp == 6)
350 track->textures[i].roundup_h = false;
351 break;
352 case R200_PP_TXMULTI_CTL_0:
353 case R200_PP_TXMULTI_CTL_1:
354 case R200_PP_TXMULTI_CTL_2:
355 case R200_PP_TXMULTI_CTL_3:
356 case R200_PP_TXMULTI_CTL_4:
357 case R200_PP_TXMULTI_CTL_5:
358 i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
359 break;
360 case R200_PP_TXFORMAT_X_0:
361 case R200_PP_TXFORMAT_X_1:
362 case R200_PP_TXFORMAT_X_2:
363 case R200_PP_TXFORMAT_X_3:
364 case R200_PP_TXFORMAT_X_4:
365 case R200_PP_TXFORMAT_X_5:
366 i = (reg - R200_PP_TXFORMAT_X_0) / 32;
367 track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7;
368 tmp = (ib_chunk->kdata[idx] >> 16) & 0x3;
369 /* 2D, 3D, CUBE */
370 switch (tmp) {
371 case 0:
372 case 5:
373 case 6:
374 case 7:
375 track->textures[i].tex_coord_type = 0;
376 break;
377 case 1:
378 track->textures[i].tex_coord_type = 1;
379 break;
380 case 2:
381 track->textures[i].tex_coord_type = 2;
382 break;
383 }
384 break;
385 case R200_PP_TXFORMAT_0:
386 case R200_PP_TXFORMAT_1:
387 case R200_PP_TXFORMAT_2:
388 case R200_PP_TXFORMAT_3:
389 case R200_PP_TXFORMAT_4:
390 case R200_PP_TXFORMAT_5:
391 i = (reg - R200_PP_TXFORMAT_0) / 32;
392 if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) {
393 track->textures[i].use_pitch = 1;
394 } else {
395 track->textures[i].use_pitch = 0;
396 track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
397 track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
398 }
399 switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
400 case R200_TXFORMAT_I8:
401 case R200_TXFORMAT_RGB332:
402 case R200_TXFORMAT_Y8:
403 track->textures[i].cpp = 1;
404 break;
405 case R200_TXFORMAT_DXT1:
406 case R200_TXFORMAT_AI88:
407 case R200_TXFORMAT_ARGB1555:
408 case R200_TXFORMAT_RGB565:
409 case R200_TXFORMAT_ARGB4444:
410 case R200_TXFORMAT_VYUY422:
411 case R200_TXFORMAT_YVYU422:
412 case R200_TXFORMAT_LDVDU655:
413 case R200_TXFORMAT_DVDU88:
414 case R200_TXFORMAT_AVYU4444:
415 track->textures[i].cpp = 2;
416 break;
417 case R200_TXFORMAT_ARGB8888:
418 case R200_TXFORMAT_RGBA8888:
419 case R200_TXFORMAT_ABGR8888:
420 case R200_TXFORMAT_BGR111110:
421 case R200_TXFORMAT_LDVDU8888:
422 case R200_TXFORMAT_DXT23:
423 case R200_TXFORMAT_DXT45:
424 track->textures[i].cpp = 4;
425 break;
426 }
427 track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
428 track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
429 break;
430 case R200_PP_CUBIC_FACES_0:
431 case R200_PP_CUBIC_FACES_1:
432 case R200_PP_CUBIC_FACES_2:
433 case R200_PP_CUBIC_FACES_3:
434 case R200_PP_CUBIC_FACES_4:
435 case R200_PP_CUBIC_FACES_5:
436 tmp = ib_chunk->kdata[idx];
437 i = (reg - R200_PP_CUBIC_FACES_0) / 32;
438 for (face = 0; face < 4; face++) {
439 track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
440 track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
441 }
442 break;
443 default:
444 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
445 reg, idx);
446 return -EINVAL;
447 }
448 return 0;
449}
450
451int r200_init(struct radeon_device *rdev)
452{
453 rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
454 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
455 return 0;
456}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 051bca6e3a4f..bb151ecdf8fc 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -31,7 +31,10 @@
31#include "radeon_reg.h" 31#include "radeon_reg.h"
32#include "radeon.h" 32#include "radeon.h"
33#include "radeon_drm.h" 33#include "radeon_drm.h"
34#include "radeon_share.h" 34#include "r100_track.h"
35#include "r300d.h"
36
37#include "r300_reg_safe.h"
35 38
36/* r300,r350,rv350,rv370,rv380 depends on : */ 39/* r300,r350,rv350,rv370,rv380 depends on : */
37void r100_hdp_reset(struct radeon_device *rdev); 40void r100_hdp_reset(struct radeon_device *rdev);
@@ -39,7 +42,6 @@ int r100_cp_reset(struct radeon_device *rdev);
39int r100_rb2d_reset(struct radeon_device *rdev); 42int r100_rb2d_reset(struct radeon_device *rdev);
40int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); 43int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
41int r100_pci_gart_enable(struct radeon_device *rdev); 44int r100_pci_gart_enable(struct radeon_device *rdev);
42void r100_pci_gart_disable(struct radeon_device *rdev);
43void r100_mc_setup(struct radeon_device *rdev); 45void r100_mc_setup(struct radeon_device *rdev);
44void r100_mc_disable_clients(struct radeon_device *rdev); 46void r100_mc_disable_clients(struct radeon_device *rdev);
45int r100_gui_wait_for_idle(struct radeon_device *rdev); 47int r100_gui_wait_for_idle(struct radeon_device *rdev);
@@ -47,14 +49,10 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
47 struct radeon_cs_packet *pkt, 49 struct radeon_cs_packet *pkt,
48 unsigned idx); 50 unsigned idx);
49int r100_cs_packet_parse_vline(struct radeon_cs_parser *p); 51int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
50int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
51 struct radeon_cs_reloc **cs_reloc);
52int r100_cs_parse_packet0(struct radeon_cs_parser *p, 52int r100_cs_parse_packet0(struct radeon_cs_parser *p,
53 struct radeon_cs_packet *pkt, 53 struct radeon_cs_packet *pkt,
54 const unsigned *auth, unsigned n, 54 const unsigned *auth, unsigned n,
55 radeon_packet0_check_t check); 55 radeon_packet0_check_t check);
56void r100_cs_dump_packet(struct radeon_cs_parser *p,
57 struct radeon_cs_packet *pkt);
58int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, 56int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
59 struct radeon_cs_packet *pkt, 57 struct radeon_cs_packet *pkt,
60 struct radeon_object *robj); 58 struct radeon_object *robj);
@@ -87,26 +85,57 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
87 mb(); 85 mb();
88} 86}
89 87
90int rv370_pcie_gart_enable(struct radeon_device *rdev) 88int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
89{
90 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
91
92 if (i < 0 || i > rdev->gart.num_gpu_pages) {
93 return -EINVAL;
94 }
95 addr = (lower_32_bits(addr) >> 8) |
96 ((upper_32_bits(addr) & 0xff) << 24) |
97 0xc;
98 /* on x86 we want this to be CPU endian, on powerpc
99 * on powerpc without HW swappers, it'll get swapped on way
100 * into VRAM - so no need for cpu_to_le32 on VRAM tables */
101 writel(addr, ((void __iomem *)ptr) + (i * 4));
102 return 0;
103}
104
105int rv370_pcie_gart_init(struct radeon_device *rdev)
91{ 106{
92 uint32_t table_addr;
93 uint32_t tmp;
94 int r; 107 int r;
95 108
109 if (rdev->gart.table.vram.robj) {
110 WARN(1, "RV370 PCIE GART already initialized.\n");
111 return 0;
112 }
96 /* Initialize common gart structure */ 113 /* Initialize common gart structure */
97 r = radeon_gart_init(rdev); 114 r = radeon_gart_init(rdev);
98 if (r) { 115 if (r)
99 return r; 116 return r;
100 }
101 r = rv370_debugfs_pcie_gart_info_init(rdev); 117 r = rv370_debugfs_pcie_gart_info_init(rdev);
102 if (r) { 118 if (r)
103 DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); 119 DRM_ERROR("Failed to register debugfs file for PCIE gart !\n");
104 }
105 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; 120 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
106 r = radeon_gart_table_vram_alloc(rdev); 121 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
107 if (r) { 122 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
108 return r; 123 return radeon_gart_table_vram_alloc(rdev);
124}
125
126int rv370_pcie_gart_enable(struct radeon_device *rdev)
127{
128 uint32_t table_addr;
129 uint32_t tmp;
130 int r;
131
132 if (rdev->gart.table.vram.robj == NULL) {
133 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
134 return -EINVAL;
109 } 135 }
136 r = radeon_gart_table_vram_pin(rdev);
137 if (r)
138 return r;
110 /* discard memory request outside of configured range */ 139 /* discard memory request outside of configured range */
111 tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; 140 tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
112 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); 141 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
@@ -128,7 +157,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
128 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); 157 WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
129 rv370_pcie_gart_tlb_flush(rdev); 158 rv370_pcie_gart_tlb_flush(rdev);
130 DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n", 159 DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n",
131 rdev->mc.gtt_size >> 20, table_addr); 160 (unsigned)(rdev->mc.gtt_size >> 20), table_addr);
132 rdev->gart.ready = true; 161 rdev->gart.ready = true;
133 return 0; 162 return 0;
134} 163}
@@ -146,45 +175,13 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
146 } 175 }
147} 176}
148 177
149int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 178void rv370_pcie_gart_fini(struct radeon_device *rdev)
150{ 179{
151 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; 180 rv370_pcie_gart_disable(rdev);
152 181 radeon_gart_table_vram_free(rdev);
153 if (i < 0 || i > rdev->gart.num_gpu_pages) { 182 radeon_gart_fini(rdev);
154 return -EINVAL;
155 }
156 addr = (lower_32_bits(addr) >> 8) |
157 ((upper_32_bits(addr) & 0xff) << 24) |
158 0xc;
159 /* on x86 we want this to be CPU endian, on powerpc
160 * on powerpc without HW swappers, it'll get swapped on way
161 * into VRAM - so no need for cpu_to_le32 on VRAM tables */
162 writel(addr, ((void __iomem *)ptr) + (i * 4));
163 return 0;
164}
165
166int r300_gart_enable(struct radeon_device *rdev)
167{
168#if __OS_HAS_AGP
169 if (rdev->flags & RADEON_IS_AGP) {
170 if (rdev->family > CHIP_RV350) {
171 rv370_pcie_gart_disable(rdev);
172 } else {
173 r100_pci_gart_disable(rdev);
174 }
175 return 0;
176 }
177#endif
178 if (rdev->flags & RADEON_IS_PCIE) {
179 rdev->asic->gart_disable = &rv370_pcie_gart_disable;
180 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
181 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
182 return rv370_pcie_gart_enable(rdev);
183 }
184 return r100_pci_gart_enable(rdev);
185} 183}
186 184
187
188/* 185/*
189 * MC 186 * MC
190 */ 187 */
@@ -232,14 +229,6 @@ int r300_mc_init(struct radeon_device *rdev)
232 229
233void r300_mc_fini(struct radeon_device *rdev) 230void r300_mc_fini(struct radeon_device *rdev)
234{ 231{
235 if (rdev->flags & RADEON_IS_PCIE) {
236 rv370_pcie_gart_disable(rdev);
237 radeon_gart_table_vram_free(rdev);
238 } else {
239 r100_pci_gart_disable(rdev);
240 radeon_gart_table_ram_free(rdev);
241 }
242 radeon_gart_fini(rdev);
243} 232}
244 233
245 234
@@ -704,307 +693,13 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
704/* 693/*
705 * CS functions 694 * CS functions
706 */ 695 */
707struct r300_cs_track_cb {
708 struct radeon_object *robj;
709 unsigned pitch;
710 unsigned cpp;
711 unsigned offset;
712};
713
714struct r300_cs_track_array {
715 struct radeon_object *robj;
716 unsigned esize;
717};
718
719struct r300_cs_track_texture {
720 struct radeon_object *robj;
721 unsigned pitch;
722 unsigned width;
723 unsigned height;
724 unsigned num_levels;
725 unsigned cpp;
726 unsigned tex_coord_type;
727 unsigned txdepth;
728 unsigned width_11;
729 unsigned height_11;
730 bool use_pitch;
731 bool enabled;
732 bool roundup_w;
733 bool roundup_h;
734};
735
736struct r300_cs_track {
737 unsigned num_cb;
738 unsigned maxy;
739 unsigned vtx_size;
740 unsigned vap_vf_cntl;
741 unsigned immd_dwords;
742 unsigned num_arrays;
743 unsigned max_indx;
744 struct r300_cs_track_array arrays[11];
745 struct r300_cs_track_cb cb[4];
746 struct r300_cs_track_cb zb;
747 struct r300_cs_track_texture textures[16];
748 bool z_enabled;
749};
750
751static inline void r300_cs_track_texture_print(struct r300_cs_track_texture *t)
752{
753 DRM_ERROR("pitch %d\n", t->pitch);
754 DRM_ERROR("width %d\n", t->width);
755 DRM_ERROR("height %d\n", t->height);
756 DRM_ERROR("num levels %d\n", t->num_levels);
757 DRM_ERROR("depth %d\n", t->txdepth);
758 DRM_ERROR("bpp %d\n", t->cpp);
759 DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
760 DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
761 DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
762}
763
764static inline int r300_cs_track_texture_check(struct radeon_device *rdev,
765 struct r300_cs_track *track)
766{
767 struct radeon_object *robj;
768 unsigned long size;
769 unsigned u, i, w, h;
770
771 for (u = 0; u < 16; u++) {
772 if (!track->textures[u].enabled)
773 continue;
774 robj = track->textures[u].robj;
775 if (robj == NULL) {
776 DRM_ERROR("No texture bound to unit %u\n", u);
777 return -EINVAL;
778 }
779 size = 0;
780 for (i = 0; i <= track->textures[u].num_levels; i++) {
781 if (track->textures[u].use_pitch) {
782 w = track->textures[u].pitch / (1 << i);
783 } else {
784 w = track->textures[u].width / (1 << i);
785 if (rdev->family >= CHIP_RV515)
786 w |= track->textures[u].width_11;
787 if (track->textures[u].roundup_w)
788 w = roundup_pow_of_two(w);
789 }
790 h = track->textures[u].height / (1 << i);
791 if (rdev->family >= CHIP_RV515)
792 h |= track->textures[u].height_11;
793 if (track->textures[u].roundup_h)
794 h = roundup_pow_of_two(h);
795 size += w * h;
796 }
797 size *= track->textures[u].cpp;
798 switch (track->textures[u].tex_coord_type) {
799 case 0:
800 break;
801 case 1:
802 size *= (1 << track->textures[u].txdepth);
803 break;
804 case 2:
805 size *= 6;
806 break;
807 default:
808 DRM_ERROR("Invalid texture coordinate type %u for unit "
809 "%u\n", track->textures[u].tex_coord_type, u);
810 return -EINVAL;
811 }
812 if (size > radeon_object_size(robj)) {
813 DRM_ERROR("Texture of unit %u needs %lu bytes but is "
814 "%lu\n", u, size, radeon_object_size(robj));
815 r300_cs_track_texture_print(&track->textures[u]);
816 return -EINVAL;
817 }
818 }
819 return 0;
820}
821
822int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track)
823{
824 unsigned i;
825 unsigned long size;
826 unsigned prim_walk;
827 unsigned nverts;
828
829 for (i = 0; i < track->num_cb; i++) {
830 if (track->cb[i].robj == NULL) {
831 DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
832 return -EINVAL;
833 }
834 size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
835 size += track->cb[i].offset;
836 if (size > radeon_object_size(track->cb[i].robj)) {
837 DRM_ERROR("[drm] Buffer too small for color buffer %d "
838 "(need %lu have %lu) !\n", i, size,
839 radeon_object_size(track->cb[i].robj));
840 DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
841 i, track->cb[i].pitch, track->cb[i].cpp,
842 track->cb[i].offset, track->maxy);
843 return -EINVAL;
844 }
845 }
846 if (track->z_enabled) {
847 if (track->zb.robj == NULL) {
848 DRM_ERROR("[drm] No buffer for z buffer !\n");
849 return -EINVAL;
850 }
851 size = track->zb.pitch * track->zb.cpp * track->maxy;
852 size += track->zb.offset;
853 if (size > radeon_object_size(track->zb.robj)) {
854 DRM_ERROR("[drm] Buffer too small for z buffer "
855 "(need %lu have %lu) !\n", size,
856 radeon_object_size(track->zb.robj));
857 return -EINVAL;
858 }
859 }
860 prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
861 nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
862 switch (prim_walk) {
863 case 1:
864 for (i = 0; i < track->num_arrays; i++) {
865 size = track->arrays[i].esize * track->max_indx * 4;
866 if (track->arrays[i].robj == NULL) {
867 DRM_ERROR("(PW %u) Vertex array %u no buffer "
868 "bound\n", prim_walk, i);
869 return -EINVAL;
870 }
871 if (size > radeon_object_size(track->arrays[i].robj)) {
872 DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
873 "have %lu dwords\n", prim_walk, i,
874 size >> 2,
875 radeon_object_size(track->arrays[i].robj) >> 2);
876 DRM_ERROR("Max indices %u\n", track->max_indx);
877 return -EINVAL;
878 }
879 }
880 break;
881 case 2:
882 for (i = 0; i < track->num_arrays; i++) {
883 size = track->arrays[i].esize * (nverts - 1) * 4;
884 if (track->arrays[i].robj == NULL) {
885 DRM_ERROR("(PW %u) Vertex array %u no buffer "
886 "bound\n", prim_walk, i);
887 return -EINVAL;
888 }
889 if (size > radeon_object_size(track->arrays[i].robj)) {
890 DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
891 "have %lu dwords\n", prim_walk, i, size >> 2,
892 radeon_object_size(track->arrays[i].robj) >> 2);
893 return -EINVAL;
894 }
895 }
896 break;
897 case 3:
898 size = track->vtx_size * nverts;
899 if (size != track->immd_dwords) {
900 DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
901 track->immd_dwords, size);
902 DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
903 nverts, track->vtx_size);
904 return -EINVAL;
905 }
906 break;
907 default:
908 DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
909 prim_walk);
910 return -EINVAL;
911 }
912 return r300_cs_track_texture_check(rdev, track);
913}
914
915static inline void r300_cs_track_clear(struct r300_cs_track *track)
916{
917 unsigned i;
918
919 track->num_cb = 4;
920 track->maxy = 4096;
921 for (i = 0; i < track->num_cb; i++) {
922 track->cb[i].robj = NULL;
923 track->cb[i].pitch = 8192;
924 track->cb[i].cpp = 16;
925 track->cb[i].offset = 0;
926 }
927 track->z_enabled = true;
928 track->zb.robj = NULL;
929 track->zb.pitch = 8192;
930 track->zb.cpp = 4;
931 track->zb.offset = 0;
932 track->vtx_size = 0x7F;
933 track->immd_dwords = 0xFFFFFFFFUL;
934 track->num_arrays = 11;
935 track->max_indx = 0x00FFFFFFUL;
936 for (i = 0; i < track->num_arrays; i++) {
937 track->arrays[i].robj = NULL;
938 track->arrays[i].esize = 0x7F;
939 }
940 for (i = 0; i < 16; i++) {
941 track->textures[i].pitch = 16536;
942 track->textures[i].width = 16536;
943 track->textures[i].height = 16536;
944 track->textures[i].width_11 = 1 << 11;
945 track->textures[i].height_11 = 1 << 11;
946 track->textures[i].num_levels = 12;
947 track->textures[i].txdepth = 16;
948 track->textures[i].cpp = 64;
949 track->textures[i].tex_coord_type = 1;
950 track->textures[i].robj = NULL;
951 /* CS IB emission code makes sure texture unit are disabled */
952 track->textures[i].enabled = false;
953 track->textures[i].roundup_w = true;
954 track->textures[i].roundup_h = true;
955 }
956}
957
958static const unsigned r300_reg_safe_bm[159] = {
959 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
960 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
961 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
962 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
963 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
964 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
965 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
966 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
967 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
968 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
969 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
970 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
971 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
972 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
973 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
974 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
975 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
976 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
977 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
978 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
979 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
980 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
981 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
982 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
983 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
984 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
985 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
986 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
987 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
988 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
989 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
990 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
991 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
992 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
993 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
994 0x00000000, 0x0000C100, 0x00000000, 0x00000000,
995 0x00000000, 0x00000000, 0x00000000, 0x00000000,
996 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
997 0x00000000, 0x00000000, 0x00000000, 0x00000000,
998 0x0003FC01, 0xFFFFFCF8, 0xFF800B19,
999};
1000
1001static int r300_packet0_check(struct radeon_cs_parser *p, 696static int r300_packet0_check(struct radeon_cs_parser *p,
1002 struct radeon_cs_packet *pkt, 697 struct radeon_cs_packet *pkt,
1003 unsigned idx, unsigned reg) 698 unsigned idx, unsigned reg)
1004{ 699{
1005 struct radeon_cs_chunk *ib_chunk; 700 struct radeon_cs_chunk *ib_chunk;
1006 struct radeon_cs_reloc *reloc; 701 struct radeon_cs_reloc *reloc;
1007 struct r300_cs_track *track; 702 struct r100_cs_track *track;
1008 volatile uint32_t *ib; 703 volatile uint32_t *ib;
1009 uint32_t tmp, tile_flags = 0; 704 uint32_t tmp, tile_flags = 0;
1010 unsigned i; 705 unsigned i;
@@ -1012,7 +707,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1012 707
1013 ib = p->ib->ptr; 708 ib = p->ib->ptr;
1014 ib_chunk = &p->chunks[p->chunk_ib_idx]; 709 ib_chunk = &p->chunks[p->chunk_ib_idx];
1015 track = (struct r300_cs_track*)p->track; 710 track = (struct r100_cs_track *)p->track;
1016 switch(reg) { 711 switch(reg) {
1017 case AVIVO_D1MODE_VLINE_START_END: 712 case AVIVO_D1MODE_VLINE_START_END:
1018 case RADEON_CRTC_GUI_TRIG_VLINE: 713 case RADEON_CRTC_GUI_TRIG_VLINE:
@@ -1026,28 +721,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1026 break; 721 break;
1027 case RADEON_DST_PITCH_OFFSET: 722 case RADEON_DST_PITCH_OFFSET:
1028 case RADEON_SRC_PITCH_OFFSET: 723 case RADEON_SRC_PITCH_OFFSET:
1029 r = r100_cs_packet_next_reloc(p, &reloc); 724 r = r100_reloc_pitch_offset(p, pkt, idx, reg);
1030 if (r) { 725 if (r)
1031 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1032 idx, reg);
1033 r100_cs_dump_packet(p, pkt);
1034 return r; 726 return r;
1035 }
1036 tmp = ib_chunk->kdata[idx] & 0x003fffff;
1037 tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
1038
1039 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1040 tile_flags |= RADEON_DST_TILE_MACRO;
1041 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
1042 if (reg == RADEON_SRC_PITCH_OFFSET) {
1043 DRM_ERROR("Cannot src blit from microtiled surface\n");
1044 r100_cs_dump_packet(p, pkt);
1045 return -EINVAL;
1046 }
1047 tile_flags |= RADEON_DST_TILE_MICRO;
1048 }
1049 tmp |= tile_flags;
1050 ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
1051 break; 727 break;
1052 case R300_RB3D_COLOROFFSET0: 728 case R300_RB3D_COLOROFFSET0:
1053 case R300_RB3D_COLOROFFSET1: 729 case R300_RB3D_COLOROFFSET1:
@@ -1256,42 +932,41 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1256 tmp = (ib_chunk->kdata[idx] >> 25) & 0x3; 932 tmp = (ib_chunk->kdata[idx] >> 25) & 0x3;
1257 track->textures[i].tex_coord_type = tmp; 933 track->textures[i].tex_coord_type = tmp;
1258 switch ((ib_chunk->kdata[idx] & 0x1F)) { 934 switch ((ib_chunk->kdata[idx] & 0x1F)) {
1259 case 0: 935 case R300_TX_FORMAT_X8:
1260 case 2: 936 case R300_TX_FORMAT_Y4X4:
1261 case 5: 937 case R300_TX_FORMAT_Z3Y3X2:
1262 case 18:
1263 case 20:
1264 case 21:
1265 track->textures[i].cpp = 1; 938 track->textures[i].cpp = 1;
1266 break; 939 break;
1267 case 1: 940 case R300_TX_FORMAT_X16:
1268 case 3: 941 case R300_TX_FORMAT_Y8X8:
1269 case 6: 942 case R300_TX_FORMAT_Z5Y6X5:
1270 case 7: 943 case R300_TX_FORMAT_Z6Y5X5:
1271 case 10: 944 case R300_TX_FORMAT_W4Z4Y4X4:
1272 case 11: 945 case R300_TX_FORMAT_W1Z5Y5X5:
1273 case 19: 946 case R300_TX_FORMAT_DXT1:
1274 case 22: 947 case R300_TX_FORMAT_D3DMFT_CxV8U8:
1275 case 24: 948 case R300_TX_FORMAT_B8G8_B8G8:
949 case R300_TX_FORMAT_G8R8_G8B8:
1276 track->textures[i].cpp = 2; 950 track->textures[i].cpp = 2;
1277 break; 951 break;
1278 case 4: 952 case R300_TX_FORMAT_Y16X16:
1279 case 8: 953 case R300_TX_FORMAT_Z11Y11X10:
1280 case 9: 954 case R300_TX_FORMAT_Z10Y11X11:
1281 case 12: 955 case R300_TX_FORMAT_W8Z8Y8X8:
1282 case 13: 956 case R300_TX_FORMAT_W2Z10Y10X10:
1283 case 23: 957 case 0x17:
1284 case 25: 958 case R300_TX_FORMAT_FL_I32:
1285 case 27: 959 case 0x1e:
1286 case 30: 960 case R300_TX_FORMAT_DXT3:
961 case R300_TX_FORMAT_DXT5:
1287 track->textures[i].cpp = 4; 962 track->textures[i].cpp = 4;
1288 break; 963 break;
1289 case 14: 964 case R300_TX_FORMAT_W16Z16Y16X16:
1290 case 26: 965 case R300_TX_FORMAT_FL_R16G16B16A16:
1291 case 28: 966 case R300_TX_FORMAT_FL_I32A32:
1292 track->textures[i].cpp = 8; 967 track->textures[i].cpp = 8;
1293 break; 968 break;
1294 case 29: 969 case R300_TX_FORMAT_FL_R32G32B32A32:
1295 track->textures[i].cpp = 16; 970 track->textures[i].cpp = 16;
1296 break; 971 break;
1297 default: 972 default:
@@ -1319,11 +994,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1319 case 0x443C: 994 case 0x443C:
1320 /* TX_FILTER0_[0-15] */ 995 /* TX_FILTER0_[0-15] */
1321 i = (reg - 0x4400) >> 2; 996 i = (reg - 0x4400) >> 2;
1322 tmp = ib_chunk->kdata[idx] & 0x7;; 997 tmp = ib_chunk->kdata[idx] & 0x7;
1323 if (tmp == 2 || tmp == 4 || tmp == 6) { 998 if (tmp == 2 || tmp == 4 || tmp == 6) {
1324 track->textures[i].roundup_w = false; 999 track->textures[i].roundup_w = false;
1325 } 1000 }
1326 tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;; 1001 tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;
1327 if (tmp == 2 || tmp == 4 || tmp == 6) { 1002 if (tmp == 2 || tmp == 4 || tmp == 6) {
1328 track->textures[i].roundup_h = false; 1003 track->textures[i].roundup_h = false;
1329 } 1004 }
@@ -1411,8 +1086,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
1411 struct radeon_cs_packet *pkt) 1086 struct radeon_cs_packet *pkt)
1412{ 1087{
1413 struct radeon_cs_chunk *ib_chunk; 1088 struct radeon_cs_chunk *ib_chunk;
1089
1414 struct radeon_cs_reloc *reloc; 1090 struct radeon_cs_reloc *reloc;
1415 struct r300_cs_track *track; 1091 struct r100_cs_track *track;
1416 volatile uint32_t *ib; 1092 volatile uint32_t *ib;
1417 unsigned idx; 1093 unsigned idx;
1418 unsigned i, c; 1094 unsigned i, c;
@@ -1421,7 +1097,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
1421 ib = p->ib->ptr; 1097 ib = p->ib->ptr;
1422 ib_chunk = &p->chunks[p->chunk_ib_idx]; 1098 ib_chunk = &p->chunks[p->chunk_ib_idx];
1423 idx = pkt->idx + 1; 1099 idx = pkt->idx + 1;
1424 track = (struct r300_cs_track*)p->track; 1100 track = (struct r100_cs_track *)p->track;
1425 switch(pkt->opcode) { 1101 switch(pkt->opcode) {
1426 case PACKET3_3D_LOAD_VBPNTR: 1102 case PACKET3_3D_LOAD_VBPNTR:
1427 c = ib_chunk->kdata[idx++] & 0x1F; 1103 c = ib_chunk->kdata[idx++] & 0x1F;
@@ -1488,7 +1164,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
1488 } 1164 }
1489 track->vap_vf_cntl = ib_chunk->kdata[idx+1]; 1165 track->vap_vf_cntl = ib_chunk->kdata[idx+1];
1490 track->immd_dwords = pkt->count - 1; 1166 track->immd_dwords = pkt->count - 1;
1491 r = r300_cs_track_check(p->rdev, track); 1167 r = r100_cs_track_check(p->rdev, track);
1492 if (r) { 1168 if (r) {
1493 return r; 1169 return r;
1494 } 1170 }
@@ -1503,35 +1179,35 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
1503 } 1179 }
1504 track->vap_vf_cntl = ib_chunk->kdata[idx]; 1180 track->vap_vf_cntl = ib_chunk->kdata[idx];
1505 track->immd_dwords = pkt->count; 1181 track->immd_dwords = pkt->count;
1506 r = r300_cs_track_check(p->rdev, track); 1182 r = r100_cs_track_check(p->rdev, track);
1507 if (r) { 1183 if (r) {
1508 return r; 1184 return r;
1509 } 1185 }
1510 break; 1186 break;
1511 case PACKET3_3D_DRAW_VBUF: 1187 case PACKET3_3D_DRAW_VBUF:
1512 track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; 1188 track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
1513 r = r300_cs_track_check(p->rdev, track); 1189 r = r100_cs_track_check(p->rdev, track);
1514 if (r) { 1190 if (r) {
1515 return r; 1191 return r;
1516 } 1192 }
1517 break; 1193 break;
1518 case PACKET3_3D_DRAW_VBUF_2: 1194 case PACKET3_3D_DRAW_VBUF_2:
1519 track->vap_vf_cntl = ib_chunk->kdata[idx]; 1195 track->vap_vf_cntl = ib_chunk->kdata[idx];
1520 r = r300_cs_track_check(p->rdev, track); 1196 r = r100_cs_track_check(p->rdev, track);
1521 if (r) { 1197 if (r) {
1522 return r; 1198 return r;
1523 } 1199 }
1524 break; 1200 break;
1525 case PACKET3_3D_DRAW_INDX: 1201 case PACKET3_3D_DRAW_INDX:
1526 track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; 1202 track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
1527 r = r300_cs_track_check(p->rdev, track); 1203 r = r100_cs_track_check(p->rdev, track);
1528 if (r) { 1204 if (r) {
1529 return r; 1205 return r;
1530 } 1206 }
1531 break; 1207 break;
1532 case PACKET3_3D_DRAW_INDX_2: 1208 case PACKET3_3D_DRAW_INDX_2:
1533 track->vap_vf_cntl = ib_chunk->kdata[idx]; 1209 track->vap_vf_cntl = ib_chunk->kdata[idx];
1534 r = r300_cs_track_check(p->rdev, track); 1210 r = r100_cs_track_check(p->rdev, track);
1535 if (r) { 1211 if (r) {
1536 return r; 1212 return r;
1537 } 1213 }
@@ -1548,11 +1224,12 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
1548int r300_cs_parse(struct radeon_cs_parser *p) 1224int r300_cs_parse(struct radeon_cs_parser *p)
1549{ 1225{
1550 struct radeon_cs_packet pkt; 1226 struct radeon_cs_packet pkt;
1551 struct r300_cs_track track; 1227 struct r100_cs_track *track;
1552 int r; 1228 int r;
1553 1229
1554 r300_cs_track_clear(&track); 1230 track = kzalloc(sizeof(*track), GFP_KERNEL);
1555 p->track = &track; 1231 r100_cs_track_clear(p->rdev, track);
1232 p->track = track;
1556 do { 1233 do {
1557 r = r100_cs_packet_parse(p, &pkt, p->idx); 1234 r = r100_cs_packet_parse(p, &pkt, p->idx);
1558 if (r) { 1235 if (r) {
@@ -1582,9 +1259,48 @@ int r300_cs_parse(struct radeon_cs_parser *p)
1582 return 0; 1259 return 0;
1583} 1260}
1584 1261
1585int r300_init(struct radeon_device *rdev) 1262void r300_set_reg_safe(struct radeon_device *rdev)
1586{ 1263{
1587 rdev->config.r300.reg_safe_bm = r300_reg_safe_bm; 1264 rdev->config.r300.reg_safe_bm = r300_reg_safe_bm;
1588 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm); 1265 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm);
1266}
1267
1268int r300_init(struct radeon_device *rdev)
1269{
1270 r300_set_reg_safe(rdev);
1589 return 0; 1271 return 0;
1590} 1272}
1273
1274void r300_mc_program(struct radeon_device *rdev)
1275{
1276 struct r100_mc_save save;
1277 int r;
1278
1279 r = r100_debugfs_mc_info_init(rdev);
1280 if (r) {
1281 dev_err(rdev->dev, "Failed to create r100_mc debugfs file.\n");
1282 }
1283
1284 /* Stops all mc clients */
1285 r100_mc_stop(rdev, &save);
1286 if (rdev->flags & RADEON_IS_AGP) {
1287 WREG32(R_00014C_MC_AGP_LOCATION,
1288 S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
1289 S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
1290 WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
1291 WREG32(R_00015C_AGP_BASE_2,
1292 upper_32_bits(rdev->mc.agp_base) & 0xff);
1293 } else {
1294 WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
1295 WREG32(R_000170_AGP_BASE, 0);
1296 WREG32(R_00015C_AGP_BASE_2, 0);
1297 }
1298 /* Wait for mc idle */
1299 if (r300_mc_wait_for_idle(rdev))
1300 DRM_INFO("Failed to wait MC idle before programming MC.\n");
1301 /* Program MC, should be a 32bits limited address space */
1302 WREG32(R_000148_MC_FB_LOCATION,
1303 S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
1304 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
1305 r100_mc_resume(rdev, &save);
1306}
diff --git a/drivers/gpu/drm/radeon/r300.h b/drivers/gpu/drm/radeon/r300.h
deleted file mode 100644
index 8486b4da9d69..000000000000
--- a/drivers/gpu/drm/radeon/r300.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef R300_H
29#define R300_H
30
31struct r300_asic {
32 const unsigned *reg_safe_bm;
33 unsigned reg_safe_bm_size;
34};
35
36#endif
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
new file mode 100644
index 000000000000..d4fa3eb1074f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -0,0 +1,101 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __R300D_H__
29#define __R300D_H__
30
31#define CP_PACKET0 0x00000000
32#define PACKET0_BASE_INDEX_SHIFT 0
33#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0)
34#define PACKET0_COUNT_SHIFT 16
35#define PACKET0_COUNT_MASK (0x3fff << 16)
36#define CP_PACKET1 0x40000000
37#define CP_PACKET2 0x80000000
38#define PACKET2_PAD_SHIFT 0
39#define PACKET2_PAD_MASK (0x3fffffff << 0)
40#define CP_PACKET3 0xC0000000
41#define PACKET3_IT_OPCODE_SHIFT 8
42#define PACKET3_IT_OPCODE_MASK (0xff << 8)
43#define PACKET3_COUNT_SHIFT 16
44#define PACKET3_COUNT_MASK (0x3fff << 16)
45/* PACKET3 op code */
46#define PACKET3_NOP 0x10
47#define PACKET3_3D_DRAW_VBUF 0x28
48#define PACKET3_3D_DRAW_IMMD 0x29
49#define PACKET3_3D_DRAW_INDX 0x2A
50#define PACKET3_3D_LOAD_VBPNTR 0x2F
51#define PACKET3_INDX_BUFFER 0x33
52#define PACKET3_3D_DRAW_VBUF_2 0x34
53#define PACKET3_3D_DRAW_IMMD_2 0x35
54#define PACKET3_3D_DRAW_INDX_2 0x36
55#define PACKET3_BITBLT_MULTI 0x9B
56
57#define PACKET0(reg, n) (CP_PACKET0 | \
58 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \
59 REG_SET(PACKET0_COUNT, (n)))
60#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
61#define PACKET3(op, n) (CP_PACKET3 | \
62 REG_SET(PACKET3_IT_OPCODE, (op)) | \
63 REG_SET(PACKET3_COUNT, (n)))
64
65#define PACKET_TYPE0 0
66#define PACKET_TYPE1 1
67#define PACKET_TYPE2 2
68#define PACKET_TYPE3 3
69
70#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
71#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
72#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
73#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
74#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
75
76/* Registers */
77#define R_000148_MC_FB_LOCATION 0x000148
78#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0)
79#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
80#define C_000148_MC_FB_START 0xFFFF0000
81#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
82#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
83#define C_000148_MC_FB_TOP 0x0000FFFF
84#define R_00014C_MC_AGP_LOCATION 0x00014C
85#define S_00014C_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
86#define G_00014C_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
87#define C_00014C_MC_AGP_START 0xFFFF0000
88#define S_00014C_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
89#define G_00014C_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
90#define C_00014C_MC_AGP_TOP 0x0000FFFF
91#define R_00015C_AGP_BASE_2 0x00015C
92#define S_00015C_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
93#define G_00015C_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
94#define C_00015C_AGP_BASE_ADDR_2 0xFFFFFFF0
95#define R_000170_AGP_BASE 0x000170
96#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
97#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
98#define C_000170_AGP_BASE_ADDR 0x00000000
99
100
101#endif
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 97426a6f370f..49a2fdc57d27 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -29,47 +29,13 @@
29#include "drmP.h" 29#include "drmP.h"
30#include "radeon_reg.h" 30#include "radeon_reg.h"
31#include "radeon.h" 31#include "radeon.h"
32#include "atom.h"
33#include "r420d.h"
32 34
33/* r420,r423,rv410 depends on : */
34void r100_pci_gart_disable(struct radeon_device *rdev);
35void r100_hdp_reset(struct radeon_device *rdev);
36void r100_mc_setup(struct radeon_device *rdev);
37int r100_gui_wait_for_idle(struct radeon_device *rdev);
38void r100_mc_disable_clients(struct radeon_device *rdev);
39void r300_vram_info(struct radeon_device *rdev);
40int r300_mc_wait_for_idle(struct radeon_device *rdev);
41int rv370_pcie_gart_enable(struct radeon_device *rdev);
42void rv370_pcie_gart_disable(struct radeon_device *rdev);
43
44/* This files gather functions specifics to :
45 * r420,r423,rv410
46 *
47 * Some of these functions might be used by newer ASICs.
48 */
49void r420_gpu_init(struct radeon_device *rdev);
50int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
51
52
53/*
54 * MC
55 */
56int r420_mc_init(struct radeon_device *rdev) 35int r420_mc_init(struct radeon_device *rdev)
57{ 36{
58 int r; 37 int r;
59 38
60 if (r100_debugfs_rbbm_init(rdev)) {
61 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
62 }
63 if (r420_debugfs_pipes_info_init(rdev)) {
64 DRM_ERROR("Failed to register debugfs file for pipes !\n");
65 }
66
67 r420_gpu_init(rdev);
68 r100_pci_gart_disable(rdev);
69 if (rdev->flags & RADEON_IS_PCIE) {
70 rv370_pcie_gart_disable(rdev);
71 }
72
73 /* Setup GPU memory space */ 39 /* Setup GPU memory space */
74 rdev->mc.vram_location = 0xFFFFFFFFUL; 40 rdev->mc.vram_location = 0xFFFFFFFFUL;
75 rdev->mc.gtt_location = 0xFFFFFFFFUL; 41 rdev->mc.gtt_location = 0xFFFFFFFFUL;
@@ -87,33 +53,9 @@ int r420_mc_init(struct radeon_device *rdev)
87 if (r) { 53 if (r) {
88 return r; 54 return r;
89 } 55 }
90
91 /* Program GPU memory space */
92 r100_mc_disable_clients(rdev);
93 if (r300_mc_wait_for_idle(rdev)) {
94 printk(KERN_WARNING "Failed to wait MC idle while "
95 "programming pipes. Bad things might happen.\n");
96 }
97 r100_mc_setup(rdev);
98 return 0; 56 return 0;
99} 57}
100 58
101void r420_mc_fini(struct radeon_device *rdev)
102{
103 rv370_pcie_gart_disable(rdev);
104 radeon_gart_table_vram_free(rdev);
105 radeon_gart_fini(rdev);
106}
107
108
109/*
110 * Global GPU functions
111 */
112void r420_errata(struct radeon_device *rdev)
113{
114 rdev->pll_errata = 0;
115}
116
117void r420_pipes_init(struct radeon_device *rdev) 59void r420_pipes_init(struct radeon_device *rdev)
118{ 60{
119 unsigned tmp; 61 unsigned tmp;
@@ -122,6 +64,11 @@ void r420_pipes_init(struct radeon_device *rdev)
122 64
123 /* GA_ENHANCE workaround TCL deadlock issue */ 65 /* GA_ENHANCE workaround TCL deadlock issue */
124 WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); 66 WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));
67 /* add idle wait as per freedesktop.org bug 24041 */
68 if (r100_gui_wait_for_idle(rdev)) {
69 printk(KERN_WARNING "Failed to wait GUI idle while "
70 "programming pipes. Bad things might happen.\n");
71 }
125 /* get max number of pipes */ 72 /* get max number of pipes */
126 gb_pipe_select = RREG32(0x402C); 73 gb_pipe_select = RREG32(0x402C);
127 num_pipes = ((gb_pipe_select >> 12) & 3) + 1; 74 num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
@@ -179,25 +126,239 @@ void r420_pipes_init(struct radeon_device *rdev)
179 rdev->num_gb_pipes, rdev->num_z_pipes); 126 rdev->num_gb_pipes, rdev->num_z_pipes);
180} 127}
181 128
182void r420_gpu_init(struct radeon_device *rdev) 129u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg)
130{
131 u32 r;
132
133 WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg));
134 r = RREG32(R_0001FC_MC_IND_DATA);
135 return r;
136}
137
138void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
139{
140 WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) |
141 S_0001F8_MC_IND_WR_EN(1));
142 WREG32(R_0001FC_MC_IND_DATA, v);
143}
144
145static void r420_debugfs(struct radeon_device *rdev)
146{
147 if (r100_debugfs_rbbm_init(rdev)) {
148 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
149 }
150 if (r420_debugfs_pipes_info_init(rdev)) {
151 DRM_ERROR("Failed to register debugfs file for pipes !\n");
152 }
153}
154
155static void r420_clock_resume(struct radeon_device *rdev)
156{
157 u32 sclk_cntl;
158 sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
159 sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
160 if (rdev->family == CHIP_R420)
161 sclk_cntl |= S_00000D_FORCE_PX(1) | S_00000D_FORCE_TX(1);
162 WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);
163}
164
165static int r420_startup(struct radeon_device *rdev)
183{ 166{
184 r100_hdp_reset(rdev); 167 int r;
168
169 r300_mc_program(rdev);
170 /* Initialize GART (initialize after TTM so we can allocate
171 * memory through TTM but finalize after TTM) */
172 if (rdev->flags & RADEON_IS_PCIE) {
173 r = rv370_pcie_gart_enable(rdev);
174 if (r)
175 return r;
176 }
177 if (rdev->flags & RADEON_IS_PCI) {
178 r = r100_pci_gart_enable(rdev);
179 if (r)
180 return r;
181 }
185 r420_pipes_init(rdev); 182 r420_pipes_init(rdev);
186 if (r300_mc_wait_for_idle(rdev)) { 183 /* Enable IRQ */
187 printk(KERN_WARNING "Failed to wait MC idle while " 184 rdev->irq.sw_int = true;
188 "programming pipes. Bad things might happen.\n"); 185 r100_irq_set(rdev);
186 /* 1M ring buffer */
187 r = r100_cp_init(rdev, 1024 * 1024);
188 if (r) {
189 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
190 return r;
191 }
192 r = r100_wb_init(rdev);
193 if (r) {
194 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
195 }
196 r = r100_ib_init(rdev);
197 if (r) {
198 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
199 return r;
189 } 200 }
201 return 0;
190} 202}
191 203
204int r420_resume(struct radeon_device *rdev)
205{
206 /* Make sur GART are not working */
207 if (rdev->flags & RADEON_IS_PCIE)
208 rv370_pcie_gart_disable(rdev);
209 if (rdev->flags & RADEON_IS_PCI)
210 r100_pci_gart_disable(rdev);
211 /* Resume clock before doing reset */
212 r420_clock_resume(rdev);
213 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
214 if (radeon_gpu_reset(rdev)) {
215 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
216 RREG32(R_000E40_RBBM_STATUS),
217 RREG32(R_0007C0_CP_STAT));
218 }
219 /* check if cards are posted or not */
220 if (rdev->is_atom_bios) {
221 atom_asic_init(rdev->mode_info.atom_context);
222 } else {
223 radeon_combios_asic_init(rdev->ddev);
224 }
225 /* Resume clock after posting */
226 r420_clock_resume(rdev);
192 227
193/* 228 return r420_startup(rdev);
194 * r420,r423,rv410 VRAM info 229}
195 */ 230
196void r420_vram_info(struct radeon_device *rdev) 231int r420_suspend(struct radeon_device *rdev)
197{ 232{
198 r300_vram_info(rdev); 233 r100_cp_disable(rdev);
234 r100_wb_disable(rdev);
235 r100_irq_disable(rdev);
236 if (rdev->flags & RADEON_IS_PCIE)
237 rv370_pcie_gart_disable(rdev);
238 if (rdev->flags & RADEON_IS_PCI)
239 r100_pci_gart_disable(rdev);
240 return 0;
241}
242
243void r420_fini(struct radeon_device *rdev)
244{
245 r100_cp_fini(rdev);
246 r100_wb_fini(rdev);
247 r100_ib_fini(rdev);
248 radeon_gem_fini(rdev);
249 if (rdev->flags & RADEON_IS_PCIE)
250 rv370_pcie_gart_fini(rdev);
251 if (rdev->flags & RADEON_IS_PCI)
252 r100_pci_gart_fini(rdev);
253 radeon_agp_fini(rdev);
254 radeon_irq_kms_fini(rdev);
255 radeon_fence_driver_fini(rdev);
256 radeon_object_fini(rdev);
257 if (rdev->is_atom_bios) {
258 radeon_atombios_fini(rdev);
259 } else {
260 radeon_combios_fini(rdev);
261 }
262 kfree(rdev->bios);
263 rdev->bios = NULL;
199} 264}
200 265
266int r420_init(struct radeon_device *rdev)
267{
268 int r;
269
270 rdev->new_init_path = true;
271 /* Initialize scratch registers */
272 radeon_scratch_init(rdev);
273 /* Initialize surface registers */
274 radeon_surface_init(rdev);
275 /* TODO: disable VGA need to use VGA request */
276 /* BIOS*/
277 if (!radeon_get_bios(rdev)) {
278 if (ASIC_IS_AVIVO(rdev))
279 return -EINVAL;
280 }
281 if (rdev->is_atom_bios) {
282 r = radeon_atombios_init(rdev);
283 if (r) {
284 return r;
285 }
286 } else {
287 r = radeon_combios_init(rdev);
288 if (r) {
289 return r;
290 }
291 }
292 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
293 if (radeon_gpu_reset(rdev)) {
294 dev_warn(rdev->dev,
295 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
296 RREG32(R_000E40_RBBM_STATUS),
297 RREG32(R_0007C0_CP_STAT));
298 }
299 /* check if cards are posted or not */
300 if (!radeon_card_posted(rdev) && rdev->bios) {
301 DRM_INFO("GPU not posted. posting now...\n");
302 if (rdev->is_atom_bios) {
303 atom_asic_init(rdev->mode_info.atom_context);
304 } else {
305 radeon_combios_asic_init(rdev->ddev);
306 }
307 }
308 /* Initialize clocks */
309 radeon_get_clock_info(rdev->ddev);
310 /* Get vram informations */
311 r300_vram_info(rdev);
312 /* Initialize memory controller (also test AGP) */
313 r = r420_mc_init(rdev);
314 if (r) {
315 return r;
316 }
317 r420_debugfs(rdev);
318 /* Fence driver */
319 r = radeon_fence_driver_init(rdev);
320 if (r) {
321 return r;
322 }
323 r = radeon_irq_kms_init(rdev);
324 if (r) {
325 return r;
326 }
327 /* Memory manager */
328 r = radeon_object_init(rdev);
329 if (r) {
330 return r;
331 }
332 if (rdev->flags & RADEON_IS_PCIE) {
333 r = rv370_pcie_gart_init(rdev);
334 if (r)
335 return r;
336 }
337 if (rdev->flags & RADEON_IS_PCI) {
338 r = r100_pci_gart_init(rdev);
339 if (r)
340 return r;
341 }
342 r300_set_reg_safe(rdev);
343 rdev->accel_working = true;
344 r = r420_startup(rdev);
345 if (r) {
346 /* Somethings want wront with the accel init stop accel */
347 dev_err(rdev->dev, "Disabling GPU acceleration\n");
348 r420_suspend(rdev);
349 r100_cp_fini(rdev);
350 r100_wb_fini(rdev);
351 r100_ib_fini(rdev);
352 if (rdev->flags & RADEON_IS_PCIE)
353 rv370_pcie_gart_fini(rdev);
354 if (rdev->flags & RADEON_IS_PCI)
355 r100_pci_gart_fini(rdev);
356 radeon_agp_fini(rdev);
357 radeon_irq_kms_fini(rdev);
358 rdev->accel_working = false;
359 }
360 return 0;
361}
201 362
202/* 363/*
203 * Debugfs info 364 * Debugfs info
diff --git a/drivers/gpu/drm/radeon/r420d.h b/drivers/gpu/drm/radeon/r420d.h
new file mode 100644
index 000000000000..a48a7db1e2aa
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r420d.h
@@ -0,0 +1,249 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef R420D_H
29#define R420D_H
30
31#define R_0001F8_MC_IND_INDEX 0x0001F8
32#define S_0001F8_MC_IND_ADDR(x) (((x) & 0x7F) << 0)
33#define G_0001F8_MC_IND_ADDR(x) (((x) >> 0) & 0x7F)
34#define C_0001F8_MC_IND_ADDR 0xFFFFFF80
35#define S_0001F8_MC_IND_WR_EN(x) (((x) & 0x1) << 8)
36#define G_0001F8_MC_IND_WR_EN(x) (((x) >> 8) & 0x1)
37#define C_0001F8_MC_IND_WR_EN 0xFFFFFEFF
38#define R_0001FC_MC_IND_DATA 0x0001FC
39#define S_0001FC_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0)
40#define G_0001FC_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
41#define C_0001FC_MC_IND_DATA 0x00000000
42#define R_0007C0_CP_STAT 0x0007C0
43#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
44#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
45#define C_0007C0_MRU_BUSY 0xFFFFFFFE
46#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
47#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
48#define C_0007C0_MWU_BUSY 0xFFFFFFFD
49#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
50#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
51#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
52#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
53#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
54#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
55#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
56#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
57#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
58#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
59#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
60#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
61#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
62#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
63#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
64#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
65#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
66#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
67#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
68#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
69#define C_0007C0_CSI_BUSY 0xFFFFDFFF
70#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
71#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
72#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
73#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
74#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
75#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
76#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
77#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
78#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
79#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
80#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
81#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
82#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
83#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
84#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
85#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
86#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
87#define C_0007C0_CP_BUSY 0x7FFFFFFF
88#define R_000E40_RBBM_STATUS 0x000E40
89#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
90#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
91#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
92#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
93#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
94#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
95#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
96#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
97#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
98#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
99#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
100#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
101#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
102#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
103#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
104#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
105#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
106#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
107#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
108#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
109#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
110#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
111#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
112#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
113#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
114#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
115#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
116#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
117#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
118#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
119#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
120#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
121#define C_000E40_E2_BUSY 0xFFFDFFFF
122#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
123#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
124#define C_000E40_RB2D_BUSY 0xFFFBFFFF
125#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
126#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
127#define C_000E40_RB3D_BUSY 0xFFF7FFFF
128#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
129#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
130#define C_000E40_VAP_BUSY 0xFFEFFFFF
131#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
132#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
133#define C_000E40_RE_BUSY 0xFFDFFFFF
134#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
135#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
136#define C_000E40_TAM_BUSY 0xFFBFFFFF
137#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
138#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
139#define C_000E40_TDM_BUSY 0xFF7FFFFF
140#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
141#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
142#define C_000E40_PB_BUSY 0xFEFFFFFF
143#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
144#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
145#define C_000E40_TIM_BUSY 0xFDFFFFFF
146#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
147#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
148#define C_000E40_GA_BUSY 0xFBFFFFFF
149#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
150#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
151#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
152#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
153#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
154#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
155
156/* CLK registers */
157#define R_00000D_SCLK_CNTL 0x00000D
158#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
159#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
160#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
161#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3)
162#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1)
163#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7
164#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4)
165#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1)
166#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF
167#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5)
168#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1)
169#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF
170#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6)
171#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1)
172#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF
173#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7)
174#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1)
175#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F
176#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8)
177#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1)
178#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF
179#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9)
180#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1)
181#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF
182#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10)
183#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1)
184#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF
185#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11)
186#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1)
187#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF
188#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12)
189#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1)
190#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF
191#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13)
192#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1)
193#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF
194#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14)
195#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1)
196#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF
197#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15)
198#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1)
199#define C_00000D_FORCE_DISP2 0xFFFF7FFF
200#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
201#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
202#define C_00000D_FORCE_CP 0xFFFEFFFF
203#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
204#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
205#define C_00000D_FORCE_HDP 0xFFFDFFFF
206#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18)
207#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1)
208#define C_00000D_FORCE_DISP1 0xFFFBFFFF
209#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
210#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
211#define C_00000D_FORCE_TOP 0xFFF7FFFF
212#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
213#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
214#define C_00000D_FORCE_E2 0xFFEFFFFF
215#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
216#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
217#define C_00000D_FORCE_SE 0xFFDFFFFF
218#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
219#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
220#define C_00000D_FORCE_IDCT 0xFFBFFFFF
221#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
222#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
223#define C_00000D_FORCE_VIP 0xFF7FFFFF
224#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
225#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
226#define C_00000D_FORCE_RE 0xFEFFFFFF
227#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
228#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
229#define C_00000D_FORCE_PB 0xFDFFFFFF
230#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26)
231#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1)
232#define C_00000D_FORCE_PX 0xFBFFFFFF
233#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27)
234#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1)
235#define C_00000D_FORCE_TX 0xF7FFFFFF
236#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
237#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
238#define C_00000D_FORCE_RB 0xEFFFFFFF
239#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
240#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
241#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
242#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
243#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
244#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
245#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
246#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
247#define C_00000D_FORCE_OV0 0x7FFFFFFF
248
249#endif
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index ebd6b0f7bdff..d4b0b9d2e39b 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -28,12 +28,9 @@
28#include "drmP.h" 28#include "drmP.h"
29#include "radeon_reg.h" 29#include "radeon_reg.h"
30#include "radeon.h" 30#include "radeon.h"
31#include "radeon_share.h"
32 31
33/* r520,rv530,rv560,rv570,r580 depends on : */ 32/* r520,rv530,rv560,rv570,r580 depends on : */
34void r100_hdp_reset(struct radeon_device *rdev); 33void r100_hdp_reset(struct radeon_device *rdev);
35int rv370_pcie_gart_enable(struct radeon_device *rdev);
36void rv370_pcie_gart_disable(struct radeon_device *rdev);
37void r420_pipes_init(struct radeon_device *rdev); 34void r420_pipes_init(struct radeon_device *rdev);
38void rs600_mc_disable_clients(struct radeon_device *rdev); 35void rs600_mc_disable_clients(struct radeon_device *rdev);
39void rs600_disable_vga(struct radeon_device *rdev); 36void rs600_disable_vga(struct radeon_device *rdev);
@@ -119,9 +116,6 @@ int r520_mc_init(struct radeon_device *rdev)
119 116
120void r520_mc_fini(struct radeon_device *rdev) 117void r520_mc_fini(struct radeon_device *rdev)
121{ 118{
122 rv370_pcie_gart_disable(rdev);
123 radeon_gart_table_vram_free(rdev);
124 radeon_gart_fini(rdev);
125} 119}
126 120
127 121
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 538cd907df69..eab31c1d6df1 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -25,12 +25,45 @@
25 * Alex Deucher 25 * Alex Deucher
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include <linux/seq_file.h>
29#include <linux/firmware.h>
30#include <linux/platform_device.h>
28#include "drmP.h" 31#include "drmP.h"
29#include "radeon_reg.h" 32#include "radeon_drm.h"
30#include "radeon.h" 33#include "radeon.h"
34#include "radeon_mode.h"
35#include "r600d.h"
36#include "avivod.h"
37#include "atom.h"
31 38
32/* r600,rv610,rv630,rv620,rv635,rv670 depends on : */ 39#define PFP_UCODE_SIZE 576
33void rs600_mc_disable_clients(struct radeon_device *rdev); 40#define PM4_UCODE_SIZE 1792
41#define R700_PFP_UCODE_SIZE 848
42#define R700_PM4_UCODE_SIZE 1360
43
44/* Firmware Names */
45MODULE_FIRMWARE("radeon/R600_pfp.bin");
46MODULE_FIRMWARE("radeon/R600_me.bin");
47MODULE_FIRMWARE("radeon/RV610_pfp.bin");
48MODULE_FIRMWARE("radeon/RV610_me.bin");
49MODULE_FIRMWARE("radeon/RV630_pfp.bin");
50MODULE_FIRMWARE("radeon/RV630_me.bin");
51MODULE_FIRMWARE("radeon/RV620_pfp.bin");
52MODULE_FIRMWARE("radeon/RV620_me.bin");
53MODULE_FIRMWARE("radeon/RV635_pfp.bin");
54MODULE_FIRMWARE("radeon/RV635_me.bin");
55MODULE_FIRMWARE("radeon/RV670_pfp.bin");
56MODULE_FIRMWARE("radeon/RV670_me.bin");
57MODULE_FIRMWARE("radeon/RS780_pfp.bin");
58MODULE_FIRMWARE("radeon/RS780_me.bin");
59MODULE_FIRMWARE("radeon/RV770_pfp.bin");
60MODULE_FIRMWARE("radeon/RV770_me.bin");
61MODULE_FIRMWARE("radeon/RV730_pfp.bin");
62MODULE_FIRMWARE("radeon/RV730_me.bin");
63MODULE_FIRMWARE("radeon/RV710_pfp.bin");
64MODULE_FIRMWARE("radeon/RV710_me.bin");
65
66int r600_debugfs_mc_info_init(struct radeon_device *rdev);
34 67
35/* This files gather functions specifics to: 68/* This files gather functions specifics to:
36 * r600,rv610,rv630,rv620,rv635,rv670 69 * r600,rv610,rv630,rv620,rv635,rv670
@@ -39,87 +72,293 @@ void rs600_mc_disable_clients(struct radeon_device *rdev);
39 */ 72 */
40int r600_mc_wait_for_idle(struct radeon_device *rdev); 73int r600_mc_wait_for_idle(struct radeon_device *rdev);
41void r600_gpu_init(struct radeon_device *rdev); 74void r600_gpu_init(struct radeon_device *rdev);
75void r600_fini(struct radeon_device *rdev);
42 76
43 77
44/* 78/*
45 * MC 79 * R600 PCIE GART
46 */ 80 */
47int r600_mc_init(struct radeon_device *rdev) 81int r600_gart_clear_page(struct radeon_device *rdev, int i)
48{ 82{
49 uint32_t tmp; 83 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
84 u64 pte;
50 85
51 r600_gpu_init(rdev); 86 if (i < 0 || i > rdev->gart.num_gpu_pages)
87 return -EINVAL;
88 pte = 0;
89 writeq(pte, ((void __iomem *)ptr) + (i * 8));
90 return 0;
91}
52 92
53 /* setup the gart before changing location so we can ask to 93void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
54 * discard unmapped mc request 94{
55 */ 95 unsigned i;
56 /* FIXME: disable out of gart access */ 96 u32 tmp;
57 tmp = rdev->mc.gtt_location / 4096; 97
58 tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); 98 WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
59 WREG32(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp); 99 WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
60 tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096; 100 WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
61 tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); 101 for (i = 0; i < rdev->usec_timeout; i++) {
62 WREG32(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp); 102 /* read MC_STATUS */
63 103 tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
64 rs600_mc_disable_clients(rdev); 104 tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
65 if (r600_mc_wait_for_idle(rdev)) { 105 if (tmp == 2) {
66 printk(KERN_WARNING "Failed to wait MC idle while " 106 printk(KERN_WARNING "[drm] r600 flush TLB failed\n");
67 "programming pipes. Bad things might happen.\n"); 107 return;
108 }
109 if (tmp) {
110 return;
111 }
112 udelay(1);
68 } 113 }
114}
69 115
70 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; 116int r600_pcie_gart_init(struct radeon_device *rdev)
71 tmp = REG_SET(R600_MC_FB_TOP, tmp >> 24); 117{
72 tmp |= REG_SET(R600_MC_FB_BASE, rdev->mc.vram_location >> 24); 118 int r;
73 WREG32(R600_MC_VM_FB_LOCATION, tmp); 119
74 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; 120 if (rdev->gart.table.vram.robj) {
75 tmp = REG_SET(R600_MC_AGP_TOP, tmp >> 22); 121 WARN(1, "R600 PCIE GART already initialized.\n");
76 WREG32(R600_MC_VM_AGP_TOP, tmp); 122 return 0;
77 tmp = REG_SET(R600_MC_AGP_BOT, rdev->mc.gtt_location >> 22); 123 }
78 WREG32(R600_MC_VM_AGP_BOT, tmp); 124 /* Initialize common gart structure */
79 return 0; 125 r = radeon_gart_init(rdev);
126 if (r)
127 return r;
128 rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
129 return radeon_gart_table_vram_alloc(rdev);
80} 130}
81 131
82void r600_mc_fini(struct radeon_device *rdev) 132int r600_pcie_gart_enable(struct radeon_device *rdev)
83{ 133{
84 /* FIXME: implement */ 134 u32 tmp;
135 int r, i;
136
137 if (rdev->gart.table.vram.robj == NULL) {
138 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
139 return -EINVAL;
140 }
141 r = radeon_gart_table_vram_pin(rdev);
142 if (r)
143 return r;
144
145 /* Setup L2 cache */
146 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
147 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
148 EFFECTIVE_L2_QUEUE_SIZE(7));
149 WREG32(VM_L2_CNTL2, 0);
150 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
151 /* Setup TLB control */
152 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
153 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
154 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
155 ENABLE_WAIT_L2_QUERY;
156 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
157 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
158 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
159 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
160 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
161 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
162 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
163 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
164 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
165 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
166 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
167 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
168 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
169 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
170 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
171 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
172 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
173 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
174 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
175 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
176 (u32)(rdev->dummy_page.addr >> 12));
177 for (i = 1; i < 7; i++)
178 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
179
180 r600_pcie_gart_tlb_flush(rdev);
181 rdev->gart.ready = true;
182 return 0;
85} 183}
86 184
185void r600_pcie_gart_disable(struct radeon_device *rdev)
186{
187 u32 tmp;
188 int i;
87 189
88/* 190 /* Disable all tables */
89 * Global GPU functions 191 for (i = 0; i < 7; i++)
90 */ 192 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
91void r600_errata(struct radeon_device *rdev) 193
194 /* Disable L2 cache */
195 WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
196 EFFECTIVE_L2_QUEUE_SIZE(7));
197 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
198 /* Setup L1 TLB control */
199 tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
200 ENABLE_WAIT_L2_QUERY;
201 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
202 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
203 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
204 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
205 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
206 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
207 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
208 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
209 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp);
210 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp);
211 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
212 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
213 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
214 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
215 if (rdev->gart.table.vram.robj) {
216 radeon_object_kunmap(rdev->gart.table.vram.robj);
217 radeon_object_unpin(rdev->gart.table.vram.robj);
218 }
219}
220
221void r600_pcie_gart_fini(struct radeon_device *rdev)
92{ 222{
93 rdev->pll_errata = 0; 223 r600_pcie_gart_disable(rdev);
224 radeon_gart_table_vram_free(rdev);
225 radeon_gart_fini(rdev);
94} 226}
95 227
96int r600_mc_wait_for_idle(struct radeon_device *rdev) 228int r600_mc_wait_for_idle(struct radeon_device *rdev)
97{ 229{
98 /* FIXME: implement */ 230 unsigned i;
99 return 0; 231 u32 tmp;
232
233 for (i = 0; i < rdev->usec_timeout; i++) {
234 /* read MC_STATUS */
235 tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00;
236 if (!tmp)
237 return 0;
238 udelay(1);
239 }
240 return -1;
100} 241}
101 242
102void r600_gpu_init(struct radeon_device *rdev) 243static void r600_mc_resume(struct radeon_device *rdev)
103{ 244{
104 /* FIXME: implement */ 245 u32 d1vga_control, d2vga_control;
105} 246 u32 vga_render_control, vga_hdp_control;
247 u32 d1crtc_control, d2crtc_control;
248 u32 new_d1grph_primary, new_d1grph_secondary;
249 u32 new_d2grph_primary, new_d2grph_secondary;
250 u64 old_vram_start;
251 u32 tmp;
252 int i, j;
106 253
254 /* Initialize HDP */
255 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
256 WREG32((0x2c14 + j), 0x00000000);
257 WREG32((0x2c18 + j), 0x00000000);
258 WREG32((0x2c1c + j), 0x00000000);
259 WREG32((0x2c20 + j), 0x00000000);
260 WREG32((0x2c24 + j), 0x00000000);
261 }
262 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
107 263
108/* 264 d1vga_control = RREG32(D1VGA_CONTROL);
109 * VRAM info 265 d2vga_control = RREG32(D2VGA_CONTROL);
110 */ 266 vga_render_control = RREG32(VGA_RENDER_CONTROL);
111void r600_vram_get_type(struct radeon_device *rdev) 267 vga_hdp_control = RREG32(VGA_HDP_CONTROL);
268 d1crtc_control = RREG32(D1CRTC_CONTROL);
269 d2crtc_control = RREG32(D2CRTC_CONTROL);
270 old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
271 new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
272 new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
273 new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
274 new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
275 new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
276 new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
277 new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
278 new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
279
280 /* Stop all video */
281 WREG32(D1VGA_CONTROL, 0);
282 WREG32(D2VGA_CONTROL, 0);
283 WREG32(VGA_RENDER_CONTROL, 0);
284 WREG32(D1CRTC_UPDATE_LOCK, 1);
285 WREG32(D2CRTC_UPDATE_LOCK, 1);
286 WREG32(D1CRTC_CONTROL, 0);
287 WREG32(D2CRTC_CONTROL, 0);
288 WREG32(D1CRTC_UPDATE_LOCK, 0);
289 WREG32(D2CRTC_UPDATE_LOCK, 0);
290
291 mdelay(1);
292 if (r600_mc_wait_for_idle(rdev)) {
293 printk(KERN_WARNING "[drm] MC not idle !\n");
294 }
295
296 /* Lockout access through VGA aperture*/
297 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
298
299 /* Update configuration */
300 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
301 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
302 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
303 tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
304 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
305 WREG32(MC_VM_FB_LOCATION, tmp);
306 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
307 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
308 WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
309 if (rdev->flags & RADEON_IS_AGP) {
310 WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
311 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
312 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
313 } else {
314 WREG32(MC_VM_AGP_BASE, 0);
315 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
316 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
317 }
318 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
319 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
320 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
321 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
322 WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
323
324 /* Unlock host access */
325 WREG32(VGA_HDP_CONTROL, vga_hdp_control);
326
327 mdelay(1);
328 if (r600_mc_wait_for_idle(rdev)) {
329 printk(KERN_WARNING "[drm] MC not idle !\n");
330 }
331
332 /* Restore video state */
333 WREG32(D1CRTC_UPDATE_LOCK, 1);
334 WREG32(D2CRTC_UPDATE_LOCK, 1);
335 WREG32(D1CRTC_CONTROL, d1crtc_control);
336 WREG32(D2CRTC_CONTROL, d2crtc_control);
337 WREG32(D1CRTC_UPDATE_LOCK, 0);
338 WREG32(D2CRTC_UPDATE_LOCK, 0);
339 WREG32(D1VGA_CONTROL, d1vga_control);
340 WREG32(D2VGA_CONTROL, d2vga_control);
341 WREG32(VGA_RENDER_CONTROL, vga_render_control);
342
343 /* we need to own VRAM, so turn off the VGA renderer here
344 * to stop it overwriting our objects */
345 radeon_avivo_vga_render_disable(rdev);
346}
347
348int r600_mc_init(struct radeon_device *rdev)
112{ 349{
113 uint32_t tmp; 350 fixed20_12 a;
351 u32 tmp;
114 int chansize; 352 int chansize;
353 int r;
115 354
355 /* Get VRAM informations */
116 rdev->mc.vram_width = 128; 356 rdev->mc.vram_width = 128;
117 rdev->mc.vram_is_ddr = true; 357 rdev->mc.vram_is_ddr = true;
118 358 tmp = RREG32(RAMCFG);
119 tmp = RREG32(R600_RAMCFG); 359 if (tmp & CHANSIZE_OVERRIDE) {
120 if (tmp & R600_CHANSIZE_OVERRIDE) {
121 chansize = 16; 360 chansize = 16;
122 } else if (tmp & R600_CHANSIZE) { 361 } else if (tmp & CHANSIZE_MASK) {
123 chansize = 64; 362 chansize = 64;
124 } else { 363 } else {
125 chansize = 32; 364 chansize = 32;
@@ -135,36 +374,1459 @@ void r600_vram_get_type(struct radeon_device *rdev)
135 (rdev->family == CHIP_RV635)) { 374 (rdev->family == CHIP_RV635)) {
136 rdev->mc.vram_width = 2 * chansize; 375 rdev->mc.vram_width = 2 * chansize;
137 } 376 }
377 /* Could aper size report 0 ? */
378 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
379 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
380 /* Setup GPU memory space */
381 rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
382 rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
383 if (rdev->flags & RADEON_IS_AGP) {
384 r = radeon_agp_init(rdev);
385 if (r)
386 return r;
387 /* gtt_size is setup by radeon_agp_init */
388 rdev->mc.gtt_location = rdev->mc.agp_base;
389 tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
390 /* Try to put vram before or after AGP because we
391 * we want SYSTEM_APERTURE to cover both VRAM and
392 * AGP so that GPU can catch out of VRAM/AGP access
393 */
394 if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
395 /* Enought place before */
396 rdev->mc.vram_location = rdev->mc.gtt_location -
397 rdev->mc.mc_vram_size;
398 } else if (tmp > rdev->mc.mc_vram_size) {
399 /* Enought place after */
400 rdev->mc.vram_location = rdev->mc.gtt_location +
401 rdev->mc.gtt_size;
402 } else {
403 /* Try to setup VRAM then AGP might not
404 * not work on some card
405 */
406 rdev->mc.vram_location = 0x00000000UL;
407 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
408 }
409 } else {
410 if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
411 rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
412 0xFFFF) << 24;
413 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
414 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
415 if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
416 /* Enough place after vram */
417 rdev->mc.gtt_location = tmp;
418 } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
419 /* Enough place before vram */
420 rdev->mc.gtt_location = 0;
421 } else {
422 /* Not enough place after or before shrink
423 * gart size
424 */
425 if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
426 rdev->mc.gtt_location = 0;
427 rdev->mc.gtt_size = rdev->mc.vram_location;
428 } else {
429 rdev->mc.gtt_location = tmp;
430 rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
431 }
432 }
433 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
434 } else {
435 rdev->mc.vram_location = 0x00000000UL;
436 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
437 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
438 }
439 }
440 rdev->mc.vram_start = rdev->mc.vram_location;
441 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
442 rdev->mc.gtt_start = rdev->mc.gtt_location;
443 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
444 /* FIXME: we should enforce default clock in case GPU is not in
445 * default setup
446 */
447 a.full = rfixed_const(100);
448 rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
449 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
450 return 0;
138} 451}
139 452
140void r600_vram_info(struct radeon_device *rdev) 453/* We doesn't check that the GPU really needs a reset we simply do the
454 * reset, it's up to the caller to determine if the GPU needs one. We
455 * might add an helper function to check that.
456 */
457int r600_gpu_soft_reset(struct radeon_device *rdev)
141{ 458{
142 r600_vram_get_type(rdev); 459 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
143 rdev->mc.real_vram_size = RREG32(R600_CONFIG_MEMSIZE); 460 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
144 rdev->mc.mc_vram_size = rdev->mc.real_vram_size; 461 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
462 S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) |
463 S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) |
464 S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) |
465 S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) |
466 S_008010_GUI_ACTIVE(1);
467 u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) |
468 S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) |
469 S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) |
470 S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) |
471 S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) |
472 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
473 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
474 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
475 u32 srbm_reset = 0;
145 476
146 /* Could aper size report 0 ? */ 477 /* Disable CP parsing/prefetching */
147 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); 478 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
148 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); 479 /* Check if any of the rendering block is busy and reset it */
480 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
481 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
482 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) |
483 S_008020_SOFT_RESET_DB(1) |
484 S_008020_SOFT_RESET_CB(1) |
485 S_008020_SOFT_RESET_PA(1) |
486 S_008020_SOFT_RESET_SC(1) |
487 S_008020_SOFT_RESET_SMX(1) |
488 S_008020_SOFT_RESET_SPI(1) |
489 S_008020_SOFT_RESET_SX(1) |
490 S_008020_SOFT_RESET_SH(1) |
491 S_008020_SOFT_RESET_TC(1) |
492 S_008020_SOFT_RESET_TA(1) |
493 S_008020_SOFT_RESET_VC(1) |
494 S_008020_SOFT_RESET_VGT(1));
495 (void)RREG32(R_008020_GRBM_SOFT_RESET);
496 udelay(50);
497 WREG32(R_008020_GRBM_SOFT_RESET, 0);
498 (void)RREG32(R_008020_GRBM_SOFT_RESET);
499 }
500 /* Reset CP (we always reset CP) */
501 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1));
502 (void)RREG32(R_008020_GRBM_SOFT_RESET);
503 udelay(50);
504 WREG32(R_008020_GRBM_SOFT_RESET, 0);
505 (void)RREG32(R_008020_GRBM_SOFT_RESET);
506 /* Reset others GPU block if necessary */
507 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
508 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
509 if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
510 srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
511 if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
512 srbm_reset |= S_000E60_SOFT_RESET_IH(1);
513 if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
514 srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
515 if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
516 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
517 if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
518 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
519 if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
520 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
521 if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
522 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
523 if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
524 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
525 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
526 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
527 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
528 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
529 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
530 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
531 udelay(50);
532 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
533 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
534 /* Wait a little for things to settle down */
535 udelay(50);
536 return 0;
149} 537}
150 538
539int r600_gpu_reset(struct radeon_device *rdev)
540{
541 return r600_gpu_soft_reset(rdev);
542}
543
544static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
545 u32 num_backends,
546 u32 backend_disable_mask)
547{
548 u32 backend_map = 0;
549 u32 enabled_backends_mask;
550 u32 enabled_backends_count;
551 u32 cur_pipe;
552 u32 swizzle_pipe[R6XX_MAX_PIPES];
553 u32 cur_backend;
554 u32 i;
555
556 if (num_tile_pipes > R6XX_MAX_PIPES)
557 num_tile_pipes = R6XX_MAX_PIPES;
558 if (num_tile_pipes < 1)
559 num_tile_pipes = 1;
560 if (num_backends > R6XX_MAX_BACKENDS)
561 num_backends = R6XX_MAX_BACKENDS;
562 if (num_backends < 1)
563 num_backends = 1;
564
565 enabled_backends_mask = 0;
566 enabled_backends_count = 0;
567 for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
568 if (((backend_disable_mask >> i) & 1) == 0) {
569 enabled_backends_mask |= (1 << i);
570 ++enabled_backends_count;
571 }
572 if (enabled_backends_count == num_backends)
573 break;
574 }
575
576 if (enabled_backends_count == 0) {
577 enabled_backends_mask = 1;
578 enabled_backends_count = 1;
579 }
580
581 if (enabled_backends_count != num_backends)
582 num_backends = enabled_backends_count;
583
584 memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
585 switch (num_tile_pipes) {
586 case 1:
587 swizzle_pipe[0] = 0;
588 break;
589 case 2:
590 swizzle_pipe[0] = 0;
591 swizzle_pipe[1] = 1;
592 break;
593 case 3:
594 swizzle_pipe[0] = 0;
595 swizzle_pipe[1] = 1;
596 swizzle_pipe[2] = 2;
597 break;
598 case 4:
599 swizzle_pipe[0] = 0;
600 swizzle_pipe[1] = 1;
601 swizzle_pipe[2] = 2;
602 swizzle_pipe[3] = 3;
603 break;
604 case 5:
605 swizzle_pipe[0] = 0;
606 swizzle_pipe[1] = 1;
607 swizzle_pipe[2] = 2;
608 swizzle_pipe[3] = 3;
609 swizzle_pipe[4] = 4;
610 break;
611 case 6:
612 swizzle_pipe[0] = 0;
613 swizzle_pipe[1] = 2;
614 swizzle_pipe[2] = 4;
615 swizzle_pipe[3] = 5;
616 swizzle_pipe[4] = 1;
617 swizzle_pipe[5] = 3;
618 break;
619 case 7:
620 swizzle_pipe[0] = 0;
621 swizzle_pipe[1] = 2;
622 swizzle_pipe[2] = 4;
623 swizzle_pipe[3] = 6;
624 swizzle_pipe[4] = 1;
625 swizzle_pipe[5] = 3;
626 swizzle_pipe[6] = 5;
627 break;
628 case 8:
629 swizzle_pipe[0] = 0;
630 swizzle_pipe[1] = 2;
631 swizzle_pipe[2] = 4;
632 swizzle_pipe[3] = 6;
633 swizzle_pipe[4] = 1;
634 swizzle_pipe[5] = 3;
635 swizzle_pipe[6] = 5;
636 swizzle_pipe[7] = 7;
637 break;
638 }
639
640 cur_backend = 0;
641 for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
642 while (((1 << cur_backend) & enabled_backends_mask) == 0)
643 cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
644
645 backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
646
647 cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
648 }
649
650 return backend_map;
651}
652
653int r600_count_pipe_bits(uint32_t val)
654{
655 int i, ret = 0;
656
657 for (i = 0; i < 32; i++) {
658 ret += val & 1;
659 val >>= 1;
660 }
661 return ret;
662}
663
664void r600_gpu_init(struct radeon_device *rdev)
665{
666 u32 tiling_config;
667 u32 ramcfg;
668 u32 tmp;
669 int i, j;
670 u32 sq_config;
671 u32 sq_gpr_resource_mgmt_1 = 0;
672 u32 sq_gpr_resource_mgmt_2 = 0;
673 u32 sq_thread_resource_mgmt = 0;
674 u32 sq_stack_resource_mgmt_1 = 0;
675 u32 sq_stack_resource_mgmt_2 = 0;
676
677 /* FIXME: implement */
678 switch (rdev->family) {
679 case CHIP_R600:
680 rdev->config.r600.max_pipes = 4;
681 rdev->config.r600.max_tile_pipes = 8;
682 rdev->config.r600.max_simds = 4;
683 rdev->config.r600.max_backends = 4;
684 rdev->config.r600.max_gprs = 256;
685 rdev->config.r600.max_threads = 192;
686 rdev->config.r600.max_stack_entries = 256;
687 rdev->config.r600.max_hw_contexts = 8;
688 rdev->config.r600.max_gs_threads = 16;
689 rdev->config.r600.sx_max_export_size = 128;
690 rdev->config.r600.sx_max_export_pos_size = 16;
691 rdev->config.r600.sx_max_export_smx_size = 128;
692 rdev->config.r600.sq_num_cf_insts = 2;
693 break;
694 case CHIP_RV630:
695 case CHIP_RV635:
696 rdev->config.r600.max_pipes = 2;
697 rdev->config.r600.max_tile_pipes = 2;
698 rdev->config.r600.max_simds = 3;
699 rdev->config.r600.max_backends = 1;
700 rdev->config.r600.max_gprs = 128;
701 rdev->config.r600.max_threads = 192;
702 rdev->config.r600.max_stack_entries = 128;
703 rdev->config.r600.max_hw_contexts = 8;
704 rdev->config.r600.max_gs_threads = 4;
705 rdev->config.r600.sx_max_export_size = 128;
706 rdev->config.r600.sx_max_export_pos_size = 16;
707 rdev->config.r600.sx_max_export_smx_size = 128;
708 rdev->config.r600.sq_num_cf_insts = 2;
709 break;
710 case CHIP_RV610:
711 case CHIP_RV620:
712 case CHIP_RS780:
713 case CHIP_RS880:
714 rdev->config.r600.max_pipes = 1;
715 rdev->config.r600.max_tile_pipes = 1;
716 rdev->config.r600.max_simds = 2;
717 rdev->config.r600.max_backends = 1;
718 rdev->config.r600.max_gprs = 128;
719 rdev->config.r600.max_threads = 192;
720 rdev->config.r600.max_stack_entries = 128;
721 rdev->config.r600.max_hw_contexts = 4;
722 rdev->config.r600.max_gs_threads = 4;
723 rdev->config.r600.sx_max_export_size = 128;
724 rdev->config.r600.sx_max_export_pos_size = 16;
725 rdev->config.r600.sx_max_export_smx_size = 128;
726 rdev->config.r600.sq_num_cf_insts = 1;
727 break;
728 case CHIP_RV670:
729 rdev->config.r600.max_pipes = 4;
730 rdev->config.r600.max_tile_pipes = 4;
731 rdev->config.r600.max_simds = 4;
732 rdev->config.r600.max_backends = 4;
733 rdev->config.r600.max_gprs = 192;
734 rdev->config.r600.max_threads = 192;
735 rdev->config.r600.max_stack_entries = 256;
736 rdev->config.r600.max_hw_contexts = 8;
737 rdev->config.r600.max_gs_threads = 16;
738 rdev->config.r600.sx_max_export_size = 128;
739 rdev->config.r600.sx_max_export_pos_size = 16;
740 rdev->config.r600.sx_max_export_smx_size = 128;
741 rdev->config.r600.sq_num_cf_insts = 2;
742 break;
743 default:
744 break;
745 }
746
747 /* Initialize HDP */
748 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
749 WREG32((0x2c14 + j), 0x00000000);
750 WREG32((0x2c18 + j), 0x00000000);
751 WREG32((0x2c1c + j), 0x00000000);
752 WREG32((0x2c20 + j), 0x00000000);
753 WREG32((0x2c24 + j), 0x00000000);
754 }
755
756 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
757
758 /* Setup tiling */
759 tiling_config = 0;
760 ramcfg = RREG32(RAMCFG);
761 switch (rdev->config.r600.max_tile_pipes) {
762 case 1:
763 tiling_config |= PIPE_TILING(0);
764 break;
765 case 2:
766 tiling_config |= PIPE_TILING(1);
767 break;
768 case 4:
769 tiling_config |= PIPE_TILING(2);
770 break;
771 case 8:
772 tiling_config |= PIPE_TILING(3);
773 break;
774 default:
775 break;
776 }
777 tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
778 tiling_config |= GROUP_SIZE(0);
779 tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
780 if (tmp > 3) {
781 tiling_config |= ROW_TILING(3);
782 tiling_config |= SAMPLE_SPLIT(3);
783 } else {
784 tiling_config |= ROW_TILING(tmp);
785 tiling_config |= SAMPLE_SPLIT(tmp);
786 }
787 tiling_config |= BANK_SWAPS(1);
788 tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes,
789 rdev->config.r600.max_backends,
790 (0xff << rdev->config.r600.max_backends) & 0xff);
791 tiling_config |= BACKEND_MAP(tmp);
792 WREG32(GB_TILING_CONFIG, tiling_config);
793 WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
794 WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
795
796 tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK);
797 WREG32(CC_RB_BACKEND_DISABLE, tmp);
798
799 /* Setup pipes */
800 tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK);
801 tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK);
802 WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp);
803 WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp);
804
805 tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK);
806 WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
807 WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK);
808
809 /* Setup some CP states */
810 WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b)));
811 WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40)));
812
813 WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT |
814 SYNC_WALKER | SYNC_ALIGNER));
815 /* Setup various GPU states */
816 if (rdev->family == CHIP_RV670)
817 WREG32(ARB_GDEC_RD_CNTL, 0x00000021);
818
819 tmp = RREG32(SX_DEBUG_1);
820 tmp |= SMX_EVENT_RELEASE;
821 if ((rdev->family > CHIP_R600))
822 tmp |= ENABLE_NEW_SMX_ADDRESS;
823 WREG32(SX_DEBUG_1, tmp);
824
825 if (((rdev->family) == CHIP_R600) ||
826 ((rdev->family) == CHIP_RV630) ||
827 ((rdev->family) == CHIP_RV610) ||
828 ((rdev->family) == CHIP_RV620) ||
829 ((rdev->family) == CHIP_RS780)) {
830 WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
831 } else {
832 WREG32(DB_DEBUG, 0);
833 }
834 WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) |
835 DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4)));
836
837 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
838 WREG32(VGT_NUM_INSTANCES, 0);
839
840 WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
841 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0));
842
843 tmp = RREG32(SQ_MS_FIFO_SIZES);
844 if (((rdev->family) == CHIP_RV610) ||
845 ((rdev->family) == CHIP_RV620) ||
846 ((rdev->family) == CHIP_RS780)) {
847 tmp = (CACHE_FIFO_SIZE(0xa) |
848 FETCH_FIFO_HIWATER(0xa) |
849 DONE_FIFO_HIWATER(0xe0) |
850 ALU_UPDATE_FIFO_HIWATER(0x8));
851 } else if (((rdev->family) == CHIP_R600) ||
852 ((rdev->family) == CHIP_RV630)) {
853 tmp &= ~DONE_FIFO_HIWATER(0xff);
854 tmp |= DONE_FIFO_HIWATER(0x4);
855 }
856 WREG32(SQ_MS_FIFO_SIZES, tmp);
857
858 /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
859 * should be adjusted as needed by the 2D/3D drivers. This just sets default values
860 */
861 sq_config = RREG32(SQ_CONFIG);
862 sq_config &= ~(PS_PRIO(3) |
863 VS_PRIO(3) |
864 GS_PRIO(3) |
865 ES_PRIO(3));
866 sq_config |= (DX9_CONSTS |
867 VC_ENABLE |
868 PS_PRIO(0) |
869 VS_PRIO(1) |
870 GS_PRIO(2) |
871 ES_PRIO(3));
872
873 if ((rdev->family) == CHIP_R600) {
874 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) |
875 NUM_VS_GPRS(124) |
876 NUM_CLAUSE_TEMP_GPRS(4));
877 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) |
878 NUM_ES_GPRS(0));
879 sq_thread_resource_mgmt = (NUM_PS_THREADS(136) |
880 NUM_VS_THREADS(48) |
881 NUM_GS_THREADS(4) |
882 NUM_ES_THREADS(4));
883 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) |
884 NUM_VS_STACK_ENTRIES(128));
885 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) |
886 NUM_ES_STACK_ENTRIES(0));
887 } else if (((rdev->family) == CHIP_RV610) ||
888 ((rdev->family) == CHIP_RV620) ||
889 ((rdev->family) == CHIP_RS780)) {
890 /* no vertex cache */
891 sq_config &= ~VC_ENABLE;
892
893 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
894 NUM_VS_GPRS(44) |
895 NUM_CLAUSE_TEMP_GPRS(2));
896 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
897 NUM_ES_GPRS(17));
898 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
899 NUM_VS_THREADS(78) |
900 NUM_GS_THREADS(4) |
901 NUM_ES_THREADS(31));
902 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
903 NUM_VS_STACK_ENTRIES(40));
904 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
905 NUM_ES_STACK_ENTRIES(16));
906 } else if (((rdev->family) == CHIP_RV630) ||
907 ((rdev->family) == CHIP_RV635)) {
908 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
909 NUM_VS_GPRS(44) |
910 NUM_CLAUSE_TEMP_GPRS(2));
911 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) |
912 NUM_ES_GPRS(18));
913 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
914 NUM_VS_THREADS(78) |
915 NUM_GS_THREADS(4) |
916 NUM_ES_THREADS(31));
917 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
918 NUM_VS_STACK_ENTRIES(40));
919 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
920 NUM_ES_STACK_ENTRIES(16));
921 } else if ((rdev->family) == CHIP_RV670) {
922 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
923 NUM_VS_GPRS(44) |
924 NUM_CLAUSE_TEMP_GPRS(2));
925 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
926 NUM_ES_GPRS(17));
927 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
928 NUM_VS_THREADS(78) |
929 NUM_GS_THREADS(4) |
930 NUM_ES_THREADS(31));
931 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) |
932 NUM_VS_STACK_ENTRIES(64));
933 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) |
934 NUM_ES_STACK_ENTRIES(64));
935 }
936
937 WREG32(SQ_CONFIG, sq_config);
938 WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
939 WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
940 WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
941 WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
942 WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
943
944 if (((rdev->family) == CHIP_RV610) ||
945 ((rdev->family) == CHIP_RV620) ||
946 ((rdev->family) == CHIP_RS780)) {
947 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
948 } else {
949 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
950 }
951
952 /* More default values. 2D/3D driver should adjust as needed */
953 WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) |
954 S1_X(0x4) | S1_Y(0xc)));
955 WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) |
956 S1_X(0x2) | S1_Y(0x2) |
957 S2_X(0xa) | S2_Y(0x6) |
958 S3_X(0x6) | S3_Y(0xa)));
959 WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) |
960 S1_X(0x4) | S1_Y(0xc) |
961 S2_X(0x1) | S2_Y(0x6) |
962 S3_X(0xa) | S3_Y(0xe)));
963 WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) |
964 S5_X(0x0) | S5_Y(0x0) |
965 S6_X(0xb) | S6_Y(0x4) |
966 S7_X(0x7) | S7_Y(0x8)));
967
968 WREG32(VGT_STRMOUT_EN, 0);
969 tmp = rdev->config.r600.max_pipes * 16;
970 switch (rdev->family) {
971 case CHIP_RV610:
972 case CHIP_RS780:
973 case CHIP_RV620:
974 tmp += 32;
975 break;
976 case CHIP_RV670:
977 tmp += 128;
978 break;
979 default:
980 break;
981 }
982 if (tmp > 256) {
983 tmp = 256;
984 }
985 WREG32(VGT_ES_PER_GS, 128);
986 WREG32(VGT_GS_PER_ES, tmp);
987 WREG32(VGT_GS_PER_VS, 2);
988 WREG32(VGT_GS_VERTEX_REUSE, 16);
989
990 /* more default values. 2D/3D driver should adjust as needed */
991 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
992 WREG32(VGT_STRMOUT_EN, 0);
993 WREG32(SX_MISC, 0);
994 WREG32(PA_SC_MODE_CNTL, 0);
995 WREG32(PA_SC_AA_CONFIG, 0);
996 WREG32(PA_SC_LINE_STIPPLE, 0);
997 WREG32(SPI_INPUT_Z, 0);
998 WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
999 WREG32(CB_COLOR7_FRAG, 0);
1000
1001 /* Clear render buffer base addresses */
1002 WREG32(CB_COLOR0_BASE, 0);
1003 WREG32(CB_COLOR1_BASE, 0);
1004 WREG32(CB_COLOR2_BASE, 0);
1005 WREG32(CB_COLOR3_BASE, 0);
1006 WREG32(CB_COLOR4_BASE, 0);
1007 WREG32(CB_COLOR5_BASE, 0);
1008 WREG32(CB_COLOR6_BASE, 0);
1009 WREG32(CB_COLOR7_BASE, 0);
1010 WREG32(CB_COLOR7_FRAG, 0);
1011
1012 switch (rdev->family) {
1013 case CHIP_RV610:
1014 case CHIP_RS780:
1015 case CHIP_RV620:
1016 tmp = TC_L2_SIZE(8);
1017 break;
1018 case CHIP_RV630:
1019 case CHIP_RV635:
1020 tmp = TC_L2_SIZE(4);
1021 break;
1022 case CHIP_R600:
1023 tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT;
1024 break;
1025 default:
1026 tmp = TC_L2_SIZE(0);
1027 break;
1028 }
1029 WREG32(TC_CNTL, tmp);
1030
1031 tmp = RREG32(HDP_HOST_PATH_CNTL);
1032 WREG32(HDP_HOST_PATH_CNTL, tmp);
1033
1034 tmp = RREG32(ARB_POP);
1035 tmp |= ENABLE_TC128;
1036 WREG32(ARB_POP, tmp);
1037
1038 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1039 WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
1040 NUM_CLIP_SEQ(3)));
1041 WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095));
1042}
1043
1044
151/* 1045/*
152 * Indirect registers accessor 1046 * Indirect registers accessor
153 */ 1047 */
154uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg) 1048u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg)
155{ 1049{
156 uint32_t r; 1050 u32 r;
157 1051
158 WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); 1052 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
159 (void)RREG32(R600_PCIE_PORT_INDEX); 1053 (void)RREG32(PCIE_PORT_INDEX);
160 r = RREG32(R600_PCIE_PORT_DATA); 1054 r = RREG32(PCIE_PORT_DATA);
161 return r; 1055 return r;
162} 1056}
163 1057
164void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 1058void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
165{ 1059{
166 WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); 1060 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
167 (void)RREG32(R600_PCIE_PORT_INDEX); 1061 (void)RREG32(PCIE_PORT_INDEX);
168 WREG32(R600_PCIE_PORT_DATA, (v)); 1062 WREG32(PCIE_PORT_DATA, (v));
169 (void)RREG32(R600_PCIE_PORT_DATA); 1063 (void)RREG32(PCIE_PORT_DATA);
1064}
1065
1066
1067/*
1068 * CP & Ring
1069 */
1070void r600_cp_stop(struct radeon_device *rdev)
1071{
1072 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1073}
1074
1075int r600_cp_init_microcode(struct radeon_device *rdev)
1076{
1077 struct platform_device *pdev;
1078 const char *chip_name;
1079 size_t pfp_req_size, me_req_size;
1080 char fw_name[30];
1081 int err;
1082
1083 DRM_DEBUG("\n");
1084
1085 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
1086 err = IS_ERR(pdev);
1087 if (err) {
1088 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
1089 return -EINVAL;
1090 }
1091
1092 switch (rdev->family) {
1093 case CHIP_R600: chip_name = "R600"; break;
1094 case CHIP_RV610: chip_name = "RV610"; break;
1095 case CHIP_RV630: chip_name = "RV630"; break;
1096 case CHIP_RV620: chip_name = "RV620"; break;
1097 case CHIP_RV635: chip_name = "RV635"; break;
1098 case CHIP_RV670: chip_name = "RV670"; break;
1099 case CHIP_RS780:
1100 case CHIP_RS880: chip_name = "RS780"; break;
1101 case CHIP_RV770: chip_name = "RV770"; break;
1102 case CHIP_RV730:
1103 case CHIP_RV740: chip_name = "RV730"; break;
1104 case CHIP_RV710: chip_name = "RV710"; break;
1105 default: BUG();
1106 }
1107
1108 if (rdev->family >= CHIP_RV770) {
1109 pfp_req_size = R700_PFP_UCODE_SIZE * 4;
1110 me_req_size = R700_PM4_UCODE_SIZE * 4;
1111 } else {
1112 pfp_req_size = PFP_UCODE_SIZE * 4;
1113 me_req_size = PM4_UCODE_SIZE * 12;
1114 }
1115
1116 DRM_INFO("Loading %s CP Microcode\n", chip_name);
1117
1118 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
1119 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
1120 if (err)
1121 goto out;
1122 if (rdev->pfp_fw->size != pfp_req_size) {
1123 printk(KERN_ERR
1124 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
1125 rdev->pfp_fw->size, fw_name);
1126 err = -EINVAL;
1127 goto out;
1128 }
1129
1130 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
1131 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
1132 if (err)
1133 goto out;
1134 if (rdev->me_fw->size != me_req_size) {
1135 printk(KERN_ERR
1136 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
1137 rdev->me_fw->size, fw_name);
1138 err = -EINVAL;
1139 }
1140out:
1141 platform_device_unregister(pdev);
1142
1143 if (err) {
1144 if (err != -EINVAL)
1145 printk(KERN_ERR
1146 "r600_cp: Failed to load firmware \"%s\"\n",
1147 fw_name);
1148 release_firmware(rdev->pfp_fw);
1149 rdev->pfp_fw = NULL;
1150 release_firmware(rdev->me_fw);
1151 rdev->me_fw = NULL;
1152 }
1153 return err;
1154}
1155
1156static int r600_cp_load_microcode(struct radeon_device *rdev)
1157{
1158 const __be32 *fw_data;
1159 int i;
1160
1161 if (!rdev->me_fw || !rdev->pfp_fw)
1162 return -EINVAL;
1163
1164 r600_cp_stop(rdev);
1165
1166 WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
1167
1168 /* Reset cp */
1169 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1170 RREG32(GRBM_SOFT_RESET);
1171 mdelay(15);
1172 WREG32(GRBM_SOFT_RESET, 0);
1173
1174 WREG32(CP_ME_RAM_WADDR, 0);
1175
1176 fw_data = (const __be32 *)rdev->me_fw->data;
1177 WREG32(CP_ME_RAM_WADDR, 0);
1178 for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
1179 WREG32(CP_ME_RAM_DATA,
1180 be32_to_cpup(fw_data++));
1181
1182 fw_data = (const __be32 *)rdev->pfp_fw->data;
1183 WREG32(CP_PFP_UCODE_ADDR, 0);
1184 for (i = 0; i < PFP_UCODE_SIZE; i++)
1185 WREG32(CP_PFP_UCODE_DATA,
1186 be32_to_cpup(fw_data++));
1187
1188 WREG32(CP_PFP_UCODE_ADDR, 0);
1189 WREG32(CP_ME_RAM_WADDR, 0);
1190 WREG32(CP_ME_RAM_RADDR, 0);
1191 return 0;
1192}
1193
1194int r600_cp_start(struct radeon_device *rdev)
1195{
1196 int r;
1197 uint32_t cp_me;
1198
1199 r = radeon_ring_lock(rdev, 7);
1200 if (r) {
1201 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1202 return r;
1203 }
1204 radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
1205 radeon_ring_write(rdev, 0x1);
1206 if (rdev->family < CHIP_RV770) {
1207 radeon_ring_write(rdev, 0x3);
1208 radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1);
1209 } else {
1210 radeon_ring_write(rdev, 0x0);
1211 radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
1212 }
1213 radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1214 radeon_ring_write(rdev, 0);
1215 radeon_ring_write(rdev, 0);
1216 radeon_ring_unlock_commit(rdev);
1217
1218 cp_me = 0xff;
1219 WREG32(R_0086D8_CP_ME_CNTL, cp_me);
1220 return 0;
1221}
1222
1223int r600_cp_resume(struct radeon_device *rdev)
1224{
1225 u32 tmp;
1226 u32 rb_bufsz;
1227 int r;
1228
1229 /* Reset cp */
1230 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1231 RREG32(GRBM_SOFT_RESET);
1232 mdelay(15);
1233 WREG32(GRBM_SOFT_RESET, 0);
1234
1235 /* Set ring buffer size */
1236 rb_bufsz = drm_order(rdev->cp.ring_size / 8);
1237#ifdef __BIG_ENDIAN
1238 WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE |
1239 (drm_order(4096/8) << 8) | rb_bufsz);
1240#else
1241 WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz);
1242#endif
1243 WREG32(CP_SEM_WAIT_TIMER, 0x4);
1244
1245 /* Set the write pointer delay */
1246 WREG32(CP_RB_WPTR_DELAY, 0);
1247
1248 /* Initialize the ring buffer's read and write pointers */
1249 tmp = RREG32(CP_RB_CNTL);
1250 WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
1251 WREG32(CP_RB_RPTR_WR, 0);
1252 WREG32(CP_RB_WPTR, 0);
1253 WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF);
1254 WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr));
1255 mdelay(1);
1256 WREG32(CP_RB_CNTL, tmp);
1257
1258 WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8);
1259 WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
1260
1261 rdev->cp.rptr = RREG32(CP_RB_RPTR);
1262 rdev->cp.wptr = RREG32(CP_RB_WPTR);
1263
1264 r600_cp_start(rdev);
1265 rdev->cp.ready = true;
1266 r = radeon_ring_test(rdev);
1267 if (r) {
1268 rdev->cp.ready = false;
1269 return r;
1270 }
1271 return 0;
1272}
1273
1274void r600_cp_commit(struct radeon_device *rdev)
1275{
1276 WREG32(CP_RB_WPTR, rdev->cp.wptr);
1277 (void)RREG32(CP_RB_WPTR);
1278}
1279
1280void r600_ring_init(struct radeon_device *rdev, unsigned ring_size)
1281{
1282 u32 rb_bufsz;
1283
1284 /* Align ring size */
1285 rb_bufsz = drm_order(ring_size / 8);
1286 ring_size = (1 << (rb_bufsz + 1)) * 4;
1287 rdev->cp.ring_size = ring_size;
1288 rdev->cp.align_mask = 16 - 1;
1289}
1290
1291
1292/*
1293 * GPU scratch registers helpers function.
1294 */
1295void r600_scratch_init(struct radeon_device *rdev)
1296{
1297 int i;
1298
1299 rdev->scratch.num_reg = 7;
1300 for (i = 0; i < rdev->scratch.num_reg; i++) {
1301 rdev->scratch.free[i] = true;
1302 rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4);
1303 }
1304}
1305
1306int r600_ring_test(struct radeon_device *rdev)
1307{
1308 uint32_t scratch;
1309 uint32_t tmp = 0;
1310 unsigned i;
1311 int r;
1312
1313 r = radeon_scratch_get(rdev, &scratch);
1314 if (r) {
1315 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
1316 return r;
1317 }
1318 WREG32(scratch, 0xCAFEDEAD);
1319 r = radeon_ring_lock(rdev, 3);
1320 if (r) {
1321 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1322 radeon_scratch_free(rdev, scratch);
1323 return r;
1324 }
1325 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1326 radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
1327 radeon_ring_write(rdev, 0xDEADBEEF);
1328 radeon_ring_unlock_commit(rdev);
1329 for (i = 0; i < rdev->usec_timeout; i++) {
1330 tmp = RREG32(scratch);
1331 if (tmp == 0xDEADBEEF)
1332 break;
1333 DRM_UDELAY(1);
1334 }
1335 if (i < rdev->usec_timeout) {
1336 DRM_INFO("ring test succeeded in %d usecs\n", i);
1337 } else {
1338 DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n",
1339 scratch, tmp);
1340 r = -EINVAL;
1341 }
1342 radeon_scratch_free(rdev, scratch);
1343 return r;
1344}
1345
1346/*
1347 * Writeback
1348 */
1349int r600_wb_init(struct radeon_device *rdev)
1350{
1351 int r;
1352
1353 if (rdev->wb.wb_obj == NULL) {
1354 r = radeon_object_create(rdev, NULL, 4096,
1355 true,
1356 RADEON_GEM_DOMAIN_GTT,
1357 false, &rdev->wb.wb_obj);
1358 if (r) {
1359 DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
1360 return r;
1361 }
1362 r = radeon_object_pin(rdev->wb.wb_obj,
1363 RADEON_GEM_DOMAIN_GTT,
1364 &rdev->wb.gpu_addr);
1365 if (r) {
1366 DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
1367 return r;
1368 }
1369 r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
1370 if (r) {
1371 DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
1372 return r;
1373 }
1374 }
1375 WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF);
1376 WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC);
1377 WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF);
1378 WREG32(SCRATCH_UMSK, 0xff);
1379 return 0;
1380}
1381
1382void r600_wb_fini(struct radeon_device *rdev)
1383{
1384 if (rdev->wb.wb_obj) {
1385 radeon_object_kunmap(rdev->wb.wb_obj);
1386 radeon_object_unpin(rdev->wb.wb_obj);
1387 radeon_object_unref(&rdev->wb.wb_obj);
1388 rdev->wb.wb = NULL;
1389 rdev->wb.wb_obj = NULL;
1390 }
1391}
1392
1393
1394/*
1395 * CS
1396 */
1397void r600_fence_ring_emit(struct radeon_device *rdev,
1398 struct radeon_fence *fence)
1399{
1400 /* Emit fence sequence & fire IRQ */
1401 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1402 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
1403 radeon_ring_write(rdev, fence->seq);
1404}
1405
1406int r600_copy_dma(struct radeon_device *rdev,
1407 uint64_t src_offset,
1408 uint64_t dst_offset,
1409 unsigned num_pages,
1410 struct radeon_fence *fence)
1411{
1412 /* FIXME: implement */
1413 return 0;
1414}
1415
1416int r600_copy_blit(struct radeon_device *rdev,
1417 uint64_t src_offset, uint64_t dst_offset,
1418 unsigned num_pages, struct radeon_fence *fence)
1419{
1420 r600_blit_prepare_copy(rdev, num_pages * 4096);
1421 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096);
1422 r600_blit_done_copy(rdev, fence);
1423 return 0;
1424}
1425
1426int r600_irq_process(struct radeon_device *rdev)
1427{
1428 /* FIXME: implement */
1429 return 0;
1430}
1431
1432int r600_irq_set(struct radeon_device *rdev)
1433{
1434 /* FIXME: implement */
1435 return 0;
1436}
1437
1438int r600_set_surface_reg(struct radeon_device *rdev, int reg,
1439 uint32_t tiling_flags, uint32_t pitch,
1440 uint32_t offset, uint32_t obj_size)
1441{
1442 /* FIXME: implement */
1443 return 0;
1444}
1445
1446void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
1447{
1448 /* FIXME: implement */
1449}
1450
1451
1452bool r600_card_posted(struct radeon_device *rdev)
1453{
1454 uint32_t reg;
1455
1456 /* first check CRTCs */
1457 reg = RREG32(D1CRTC_CONTROL) |
1458 RREG32(D2CRTC_CONTROL);
1459 if (reg & CRTC_EN)
1460 return true;
1461
1462 /* then check MEM_SIZE, in case the crtcs are off */
1463 if (RREG32(CONFIG_MEMSIZE))
1464 return true;
1465
1466 return false;
1467}
1468
1469int r600_startup(struct radeon_device *rdev)
1470{
1471 int r;
1472
1473 r600_gpu_reset(rdev);
1474 r600_mc_resume(rdev);
1475 r = r600_pcie_gart_enable(rdev);
1476 if (r)
1477 return r;
1478 r600_gpu_init(rdev);
1479
1480 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
1481 &rdev->r600_blit.shader_gpu_addr);
1482 if (r) {
1483 DRM_ERROR("failed to pin blit object %d\n", r);
1484 return r;
1485 }
1486
1487 r = radeon_ring_init(rdev, rdev->cp.ring_size);
1488 if (r)
1489 return r;
1490 r = r600_cp_load_microcode(rdev);
1491 if (r)
1492 return r;
1493 r = r600_cp_resume(rdev);
1494 if (r)
1495 return r;
1496 r = r600_wb_init(rdev);
1497 if (r)
1498 return r;
1499 return 0;
1500}
1501
1502void r600_vga_set_state(struct radeon_device *rdev, bool state)
1503{
1504 uint32_t temp;
1505
1506 temp = RREG32(CONFIG_CNTL);
1507 if (state == false) {
1508 temp &= ~(1<<0);
1509 temp |= (1<<1);
1510 } else {
1511 temp &= ~(1<<1);
1512 }
1513 WREG32(CONFIG_CNTL, temp);
1514}
1515
1516int r600_resume(struct radeon_device *rdev)
1517{
1518 int r;
1519
1520 if (radeon_gpu_reset(rdev)) {
1521 /* FIXME: what do we want to do here ? */
1522 }
1523 /* post card */
1524 if (rdev->is_atom_bios) {
1525 atom_asic_init(rdev->mode_info.atom_context);
1526 } else {
1527 radeon_combios_asic_init(rdev->ddev);
1528 }
1529 /* Initialize clocks */
1530 r = radeon_clocks_init(rdev);
1531 if (r) {
1532 return r;
1533 }
1534
1535 r = r600_startup(rdev);
1536 if (r) {
1537 DRM_ERROR("r600 startup failed on resume\n");
1538 return r;
1539 }
1540
1541 r = radeon_ib_test(rdev);
1542 if (r) {
1543 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1544 return r;
1545 }
1546 return r;
1547}
1548
1549
1550int r600_suspend(struct radeon_device *rdev)
1551{
1552 /* FIXME: we should wait for ring to be empty */
1553 r600_cp_stop(rdev);
1554 rdev->cp.ready = false;
1555
1556 r600_pcie_gart_disable(rdev);
1557 /* unpin shaders bo */
1558 radeon_object_unpin(rdev->r600_blit.shader_obj);
1559 return 0;
1560}
1561
1562/* Plan is to move initialization in that function and use
1563 * helper function so that radeon_device_init pretty much
1564 * do nothing more than calling asic specific function. This
1565 * should also allow to remove a bunch of callback function
1566 * like vram_info.
1567 */
1568int r600_init(struct radeon_device *rdev)
1569{
1570 int r;
1571
1572 rdev->new_init_path = true;
1573 r = radeon_dummy_page_init(rdev);
1574 if (r)
1575 return r;
1576 if (r600_debugfs_mc_info_init(rdev)) {
1577 DRM_ERROR("Failed to register debugfs file for mc !\n");
1578 }
1579 /* This don't do much */
1580 r = radeon_gem_init(rdev);
1581 if (r)
1582 return r;
1583 /* Read BIOS */
1584 if (!radeon_get_bios(rdev)) {
1585 if (ASIC_IS_AVIVO(rdev))
1586 return -EINVAL;
1587 }
1588 /* Must be an ATOMBIOS */
1589 if (!rdev->is_atom_bios)
1590 return -EINVAL;
1591 r = radeon_atombios_init(rdev);
1592 if (r)
1593 return r;
1594 /* Post card if necessary */
1595 if (!r600_card_posted(rdev) && rdev->bios) {
1596 DRM_INFO("GPU not posted. posting now...\n");
1597 atom_asic_init(rdev->mode_info.atom_context);
1598 }
1599 /* Initialize scratch registers */
1600 r600_scratch_init(rdev);
1601 /* Initialize surface registers */
1602 radeon_surface_init(rdev);
1603 radeon_get_clock_info(rdev->ddev);
1604 r = radeon_clocks_init(rdev);
1605 if (r)
1606 return r;
1607 /* Fence driver */
1608 r = radeon_fence_driver_init(rdev);
1609 if (r)
1610 return r;
1611 r = r600_mc_init(rdev);
1612 if (r) {
1613 if (rdev->flags & RADEON_IS_AGP) {
1614 /* Retry with disabling AGP */
1615 r600_fini(rdev);
1616 rdev->flags &= ~RADEON_IS_AGP;
1617 return r600_init(rdev);
1618 }
1619 return r;
1620 }
1621 /* Memory manager */
1622 r = radeon_object_init(rdev);
1623 if (r)
1624 return r;
1625 rdev->cp.ring_obj = NULL;
1626 r600_ring_init(rdev, 1024 * 1024);
1627
1628 if (!rdev->me_fw || !rdev->pfp_fw) {
1629 r = r600_cp_init_microcode(rdev);
1630 if (r) {
1631 DRM_ERROR("Failed to load firmware!\n");
1632 return r;
1633 }
1634 }
1635
1636 r = r600_pcie_gart_init(rdev);
1637 if (r)
1638 return r;
1639
1640 rdev->accel_working = true;
1641 r = r600_blit_init(rdev);
1642 if (r) {
1643 DRM_ERROR("radeon: failled blitter (%d).\n", r);
1644 return r;
1645 }
1646
1647 r = r600_startup(rdev);
1648 if (r) {
1649 if (rdev->flags & RADEON_IS_AGP) {
1650 /* Retry with disabling AGP */
1651 r600_fini(rdev);
1652 rdev->flags &= ~RADEON_IS_AGP;
1653 return r600_init(rdev);
1654 }
1655 rdev->accel_working = false;
1656 }
1657 if (rdev->accel_working) {
1658 r = radeon_ib_pool_init(rdev);
1659 if (r) {
1660 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
1661 rdev->accel_working = false;
1662 }
1663 r = radeon_ib_test(rdev);
1664 if (r) {
1665 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1666 rdev->accel_working = false;
1667 }
1668 }
1669 return 0;
1670}
1671
1672void r600_fini(struct radeon_device *rdev)
1673{
1674 /* Suspend operations */
1675 r600_suspend(rdev);
1676
1677 r600_blit_fini(rdev);
1678 radeon_ring_fini(rdev);
1679 r600_pcie_gart_fini(rdev);
1680 radeon_gem_fini(rdev);
1681 radeon_fence_driver_fini(rdev);
1682 radeon_clocks_fini(rdev);
1683#if __OS_HAS_AGP
1684 if (rdev->flags & RADEON_IS_AGP)
1685 radeon_agp_fini(rdev);
1686#endif
1687 radeon_object_fini(rdev);
1688 if (rdev->is_atom_bios)
1689 radeon_atombios_fini(rdev);
1690 else
1691 radeon_combios_fini(rdev);
1692 kfree(rdev->bios);
1693 rdev->bios = NULL;
1694 radeon_dummy_page_fini(rdev);
1695}
1696
1697
1698/*
1699 * CS stuff
1700 */
1701void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1702{
1703 /* FIXME: implement */
1704 radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1705 radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC);
1706 radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF);
1707 radeon_ring_write(rdev, ib->length_dw);
1708}
1709
1710int r600_ib_test(struct radeon_device *rdev)
1711{
1712 struct radeon_ib *ib;
1713 uint32_t scratch;
1714 uint32_t tmp = 0;
1715 unsigned i;
1716 int r;
1717
1718 r = radeon_scratch_get(rdev, &scratch);
1719 if (r) {
1720 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
1721 return r;
1722 }
1723 WREG32(scratch, 0xCAFEDEAD);
1724 r = radeon_ib_get(rdev, &ib);
1725 if (r) {
1726 DRM_ERROR("radeon: failed to get ib (%d).\n", r);
1727 return r;
1728 }
1729 ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1);
1730 ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
1731 ib->ptr[2] = 0xDEADBEEF;
1732 ib->ptr[3] = PACKET2(0);
1733 ib->ptr[4] = PACKET2(0);
1734 ib->ptr[5] = PACKET2(0);
1735 ib->ptr[6] = PACKET2(0);
1736 ib->ptr[7] = PACKET2(0);
1737 ib->ptr[8] = PACKET2(0);
1738 ib->ptr[9] = PACKET2(0);
1739 ib->ptr[10] = PACKET2(0);
1740 ib->ptr[11] = PACKET2(0);
1741 ib->ptr[12] = PACKET2(0);
1742 ib->ptr[13] = PACKET2(0);
1743 ib->ptr[14] = PACKET2(0);
1744 ib->ptr[15] = PACKET2(0);
1745 ib->length_dw = 16;
1746 r = radeon_ib_schedule(rdev, ib);
1747 if (r) {
1748 radeon_scratch_free(rdev, scratch);
1749 radeon_ib_free(rdev, &ib);
1750 DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
1751 return r;
1752 }
1753 r = radeon_fence_wait(ib->fence, false);
1754 if (r) {
1755 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
1756 return r;
1757 }
1758 for (i = 0; i < rdev->usec_timeout; i++) {
1759 tmp = RREG32(scratch);
1760 if (tmp == 0xDEADBEEF)
1761 break;
1762 DRM_UDELAY(1);
1763 }
1764 if (i < rdev->usec_timeout) {
1765 DRM_INFO("ib test succeeded in %u usecs\n", i);
1766 } else {
1767 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
1768 scratch, tmp);
1769 r = -EINVAL;
1770 }
1771 radeon_scratch_free(rdev, scratch);
1772 radeon_ib_free(rdev, &ib);
1773 return r;
1774}
1775
1776
1777
1778
1779/*
1780 * Debugfs info
1781 */
1782#if defined(CONFIG_DEBUG_FS)
1783
1784static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data)
1785{
1786 struct drm_info_node *node = (struct drm_info_node *) m->private;
1787 struct drm_device *dev = node->minor->dev;
1788 struct radeon_device *rdev = dev->dev_private;
1789 uint32_t rdp, wdp;
1790 unsigned count, i, j;
1791
1792 radeon_ring_free_size(rdev);
1793 rdp = RREG32(CP_RB_RPTR);
1794 wdp = RREG32(CP_RB_WPTR);
1795 count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
1796 seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
1797 seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
1798 seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
1799 seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
1800 seq_printf(m, "%u dwords in ring\n", count);
1801 for (j = 0; j <= count; j++) {
1802 i = (rdp + j) & rdev->cp.ptr_mask;
1803 seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
1804 }
1805 return 0;
1806}
1807
1808static int r600_debugfs_mc_info(struct seq_file *m, void *data)
1809{
1810 struct drm_info_node *node = (struct drm_info_node *) m->private;
1811 struct drm_device *dev = node->minor->dev;
1812 struct radeon_device *rdev = dev->dev_private;
1813
1814 DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS);
1815 DREG32_SYS(m, rdev, VM_L2_STATUS);
1816 return 0;
1817}
1818
1819static struct drm_info_list r600_mc_info_list[] = {
1820 {"r600_mc_info", r600_debugfs_mc_info, 0, NULL},
1821 {"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL},
1822};
1823#endif
1824
1825int r600_debugfs_mc_info_init(struct radeon_device *rdev)
1826{
1827#if defined(CONFIG_DEBUG_FS)
1828 return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list));
1829#else
1830 return 0;
1831#endif
170} 1832}
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
new file mode 100644
index 000000000000..dde2ccbf1d15
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -0,0 +1,850 @@
1/*
2 * Copyright 2009 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Alex Deucher <alexander.deucher@amd.com>
25 */
26#include "drmP.h"
27#include "drm.h"
28#include "radeon_drm.h"
29#include "radeon_drv.h"
30
31#include "r600_blit_shaders.h"
32
33#define DI_PT_RECTLIST 0x11
34#define DI_INDEX_SIZE_16_BIT 0x0
35#define DI_SRC_SEL_AUTO_INDEX 0x2
36
37#define FMT_8 0x1
38#define FMT_5_6_5 0x8
39#define FMT_8_8_8_8 0x1a
40#define COLOR_8 0x1
41#define COLOR_5_6_5 0x8
42#define COLOR_8_8_8_8 0x1a
43
44static inline void
45set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr)
46{
47 u32 cb_color_info;
48 int pitch, slice;
49 RING_LOCALS;
50 DRM_DEBUG("\n");
51
52 h = (h + 7) & ~7;
53 if (h < 8)
54 h = 8;
55
56 cb_color_info = ((format << 2) | (1 << 27));
57 pitch = (w / 8) - 1;
58 slice = ((w * h) / 64) - 1;
59
60 if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) &&
61 ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) {
62 BEGIN_RING(21 + 2);
63 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
64 OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
65 OUT_RING(gpu_addr >> 8);
66 OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
67 OUT_RING(2 << 0);
68 } else {
69 BEGIN_RING(21);
70 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
71 OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
72 OUT_RING(gpu_addr >> 8);
73 }
74
75 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
76 OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
77 OUT_RING((pitch << 0) | (slice << 10));
78
79 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
80 OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2);
81 OUT_RING(0);
82
83 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
84 OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2);
85 OUT_RING(cb_color_info);
86
87 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
88 OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
89 OUT_RING(0);
90
91 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
92 OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2);
93 OUT_RING(0);
94
95 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
96 OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2);
97 OUT_RING(0);
98
99 ADVANCE_RING();
100}
101
102static inline void
103cp_set_surface_sync(drm_radeon_private_t *dev_priv,
104 u32 sync_type, u32 size, u64 mc_addr)
105{
106 u32 cp_coher_size;
107 RING_LOCALS;
108 DRM_DEBUG("\n");
109
110 if (size == 0xffffffff)
111 cp_coher_size = 0xffffffff;
112 else
113 cp_coher_size = ((size + 255) >> 8);
114
115 BEGIN_RING(5);
116 OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
117 OUT_RING(sync_type);
118 OUT_RING(cp_coher_size);
119 OUT_RING((mc_addr >> 8));
120 OUT_RING(10); /* poll interval */
121 ADVANCE_RING();
122}
123
124static inline void
125set_shaders(struct drm_device *dev)
126{
127 drm_radeon_private_t *dev_priv = dev->dev_private;
128 u64 gpu_addr;
129 int i;
130 u32 *vs, *ps;
131 uint32_t sq_pgm_resources;
132 RING_LOCALS;
133 DRM_DEBUG("\n");
134
135 /* load shaders */
136 vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset);
137 ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
138
139 for (i = 0; i < r6xx_vs_size; i++)
140 vs[i] = r6xx_vs[i];
141 for (i = 0; i < r6xx_ps_size; i++)
142 ps[i] = r6xx_ps[i];
143
144 dev_priv->blit_vb->used = 512;
145
146 gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset;
147
148 /* setup shader regs */
149 sq_pgm_resources = (1 << 0);
150
151 BEGIN_RING(9 + 12);
152 /* VS */
153 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
154 OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
155 OUT_RING(gpu_addr >> 8);
156
157 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
158 OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
159 OUT_RING(sq_pgm_resources);
160
161 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
162 OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
163 OUT_RING(0);
164
165 /* PS */
166 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
167 OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
168 OUT_RING((gpu_addr + 256) >> 8);
169
170 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
171 OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
172 OUT_RING(sq_pgm_resources | (1 << 28));
173
174 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
175 OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
176 OUT_RING(2);
177
178 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
179 OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
180 OUT_RING(0);
181 ADVANCE_RING();
182
183 cp_set_surface_sync(dev_priv,
184 R600_SH_ACTION_ENA, 512, gpu_addr);
185}
186
187static inline void
188set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
189{
190 uint32_t sq_vtx_constant_word2;
191 RING_LOCALS;
192 DRM_DEBUG("\n");
193
194 sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8));
195
196 BEGIN_RING(9);
197 OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
198 OUT_RING(0x460);
199 OUT_RING(gpu_addr & 0xffffffff);
200 OUT_RING(48 - 1);
201 OUT_RING(sq_vtx_constant_word2);
202 OUT_RING(1 << 0);
203 OUT_RING(0);
204 OUT_RING(0);
205 OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30);
206 ADVANCE_RING();
207
208 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
209 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
210 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
211 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
212 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
213 cp_set_surface_sync(dev_priv,
214 R600_TC_ACTION_ENA, 48, gpu_addr);
215 else
216 cp_set_surface_sync(dev_priv,
217 R600_VC_ACTION_ENA, 48, gpu_addr);
218}
219
220static inline void
221set_tex_resource(drm_radeon_private_t *dev_priv,
222 int format, int w, int h, int pitch, u64 gpu_addr)
223{
224 uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
225 RING_LOCALS;
226 DRM_DEBUG("\n");
227
228 if (h < 1)
229 h = 1;
230
231 sq_tex_resource_word0 = (1 << 0);
232 sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
233 ((w - 1) << 19));
234
235 sq_tex_resource_word1 = (format << 26);
236 sq_tex_resource_word1 |= ((h - 1) << 0);
237
238 sq_tex_resource_word4 = ((1 << 14) |
239 (0 << 16) |
240 (1 << 19) |
241 (2 << 22) |
242 (3 << 25));
243
244 BEGIN_RING(9);
245 OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
246 OUT_RING(0);
247 OUT_RING(sq_tex_resource_word0);
248 OUT_RING(sq_tex_resource_word1);
249 OUT_RING(gpu_addr >> 8);
250 OUT_RING(gpu_addr >> 8);
251 OUT_RING(sq_tex_resource_word4);
252 OUT_RING(0);
253 OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30);
254 ADVANCE_RING();
255
256}
257
258static inline void
259set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2)
260{
261 RING_LOCALS;
262 DRM_DEBUG("\n");
263
264 BEGIN_RING(12);
265 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
266 OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
267 OUT_RING((x1 << 0) | (y1 << 16));
268 OUT_RING((x2 << 0) | (y2 << 16));
269
270 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
271 OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
272 OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
273 OUT_RING((x2 << 0) | (y2 << 16));
274
275 OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
276 OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
277 OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
278 OUT_RING((x2 << 0) | (y2 << 16));
279 ADVANCE_RING();
280}
281
282static inline void
283draw_auto(drm_radeon_private_t *dev_priv)
284{
285 RING_LOCALS;
286 DRM_DEBUG("\n");
287
288 BEGIN_RING(10);
289 OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
290 OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2);
291 OUT_RING(DI_PT_RECTLIST);
292
293 OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
294 OUT_RING(DI_INDEX_SIZE_16_BIT);
295
296 OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
297 OUT_RING(1);
298
299 OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
300 OUT_RING(3);
301 OUT_RING(DI_SRC_SEL_AUTO_INDEX);
302
303 ADVANCE_RING();
304 COMMIT_RING();
305}
306
307static inline void
308set_default_state(drm_radeon_private_t *dev_priv)
309{
310 int i;
311 u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
312 u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
313 int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
314 int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
315 int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
316 RING_LOCALS;
317
318 switch ((dev_priv->flags & RADEON_FAMILY_MASK)) {
319 case CHIP_R600:
320 num_ps_gprs = 192;
321 num_vs_gprs = 56;
322 num_temp_gprs = 4;
323 num_gs_gprs = 0;
324 num_es_gprs = 0;
325 num_ps_threads = 136;
326 num_vs_threads = 48;
327 num_gs_threads = 4;
328 num_es_threads = 4;
329 num_ps_stack_entries = 128;
330 num_vs_stack_entries = 128;
331 num_gs_stack_entries = 0;
332 num_es_stack_entries = 0;
333 break;
334 case CHIP_RV630:
335 case CHIP_RV635:
336 num_ps_gprs = 84;
337 num_vs_gprs = 36;
338 num_temp_gprs = 4;
339 num_gs_gprs = 0;
340 num_es_gprs = 0;
341 num_ps_threads = 144;
342 num_vs_threads = 40;
343 num_gs_threads = 4;
344 num_es_threads = 4;
345 num_ps_stack_entries = 40;
346 num_vs_stack_entries = 40;
347 num_gs_stack_entries = 32;
348 num_es_stack_entries = 16;
349 break;
350 case CHIP_RV610:
351 case CHIP_RV620:
352 case CHIP_RS780:
353 case CHIP_RS880:
354 default:
355 num_ps_gprs = 84;
356 num_vs_gprs = 36;
357 num_temp_gprs = 4;
358 num_gs_gprs = 0;
359 num_es_gprs = 0;
360 num_ps_threads = 136;
361 num_vs_threads = 48;
362 num_gs_threads = 4;
363 num_es_threads = 4;
364 num_ps_stack_entries = 40;
365 num_vs_stack_entries = 40;
366 num_gs_stack_entries = 32;
367 num_es_stack_entries = 16;
368 break;
369 case CHIP_RV670:
370 num_ps_gprs = 144;
371 num_vs_gprs = 40;
372 num_temp_gprs = 4;
373 num_gs_gprs = 0;
374 num_es_gprs = 0;
375 num_ps_threads = 136;
376 num_vs_threads = 48;
377 num_gs_threads = 4;
378 num_es_threads = 4;
379 num_ps_stack_entries = 40;
380 num_vs_stack_entries = 40;
381 num_gs_stack_entries = 32;
382 num_es_stack_entries = 16;
383 break;
384 case CHIP_RV770:
385 num_ps_gprs = 192;
386 num_vs_gprs = 56;
387 num_temp_gprs = 4;
388 num_gs_gprs = 0;
389 num_es_gprs = 0;
390 num_ps_threads = 188;
391 num_vs_threads = 60;
392 num_gs_threads = 0;
393 num_es_threads = 0;
394 num_ps_stack_entries = 256;
395 num_vs_stack_entries = 256;
396 num_gs_stack_entries = 0;
397 num_es_stack_entries = 0;
398 break;
399 case CHIP_RV730:
400 case CHIP_RV740:
401 num_ps_gprs = 84;
402 num_vs_gprs = 36;
403 num_temp_gprs = 4;
404 num_gs_gprs = 0;
405 num_es_gprs = 0;
406 num_ps_threads = 188;
407 num_vs_threads = 60;
408 num_gs_threads = 0;
409 num_es_threads = 0;
410 num_ps_stack_entries = 128;
411 num_vs_stack_entries = 128;
412 num_gs_stack_entries = 0;
413 num_es_stack_entries = 0;
414 break;
415 case CHIP_RV710:
416 num_ps_gprs = 192;
417 num_vs_gprs = 56;
418 num_temp_gprs = 4;
419 num_gs_gprs = 0;
420 num_es_gprs = 0;
421 num_ps_threads = 144;
422 num_vs_threads = 48;
423 num_gs_threads = 0;
424 num_es_threads = 0;
425 num_ps_stack_entries = 128;
426 num_vs_stack_entries = 128;
427 num_gs_stack_entries = 0;
428 num_es_stack_entries = 0;
429 break;
430 }
431
432 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
433 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
434 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
435 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
436 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
437 sq_config = 0;
438 else
439 sq_config = R600_VC_ENABLE;
440
441 sq_config |= (R600_DX9_CONSTS |
442 R600_ALU_INST_PREFER_VECTOR |
443 R600_PS_PRIO(0) |
444 R600_VS_PRIO(1) |
445 R600_GS_PRIO(2) |
446 R600_ES_PRIO(3));
447
448 sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) |
449 R600_NUM_VS_GPRS(num_vs_gprs) |
450 R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
451 sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) |
452 R600_NUM_ES_GPRS(num_es_gprs));
453 sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) |
454 R600_NUM_VS_THREADS(num_vs_threads) |
455 R600_NUM_GS_THREADS(num_gs_threads) |
456 R600_NUM_ES_THREADS(num_es_threads));
457 sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
458 R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
459 sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
460 R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries));
461
462 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
463 BEGIN_RING(r7xx_default_size + 10);
464 for (i = 0; i < r7xx_default_size; i++)
465 OUT_RING(r7xx_default_state[i]);
466 } else {
467 BEGIN_RING(r6xx_default_size + 10);
468 for (i = 0; i < r6xx_default_size; i++)
469 OUT_RING(r6xx_default_state[i]);
470 }
471 OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
472 OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
473 /* SQ config */
474 OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6));
475 OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2);
476 OUT_RING(sq_config);
477 OUT_RING(sq_gpr_resource_mgmt_1);
478 OUT_RING(sq_gpr_resource_mgmt_2);
479 OUT_RING(sq_thread_resource_mgmt);
480 OUT_RING(sq_stack_resource_mgmt_1);
481 OUT_RING(sq_stack_resource_mgmt_2);
482 ADVANCE_RING();
483}
484
485static inline uint32_t i2f(uint32_t input)
486{
487 u32 result, i, exponent, fraction;
488
489 if ((input & 0x3fff) == 0)
490 result = 0; /* 0 is a special case */
491 else {
492 exponent = 140; /* exponent biased by 127; */
493 fraction = (input & 0x3fff) << 10; /* cheat and only
494 handle numbers below 2^^15 */
495 for (i = 0; i < 14; i++) {
496 if (fraction & 0x800000)
497 break;
498 else {
499 fraction = fraction << 1; /* keep
500 shifting left until top bit = 1 */
501 exponent = exponent - 1;
502 }
503 }
504 result = exponent << 23 | (fraction & 0x7fffff); /* mask
505 off top bit; assumed 1 */
506 }
507 return result;
508}
509
510
511static inline int r600_nomm_get_vb(struct drm_device *dev)
512{
513 drm_radeon_private_t *dev_priv = dev->dev_private;
514 dev_priv->blit_vb = radeon_freelist_get(dev);
515 if (!dev_priv->blit_vb) {
516 DRM_ERROR("Unable to allocate vertex buffer for blit\n");
517 return -EAGAIN;
518 }
519 return 0;
520}
521
522static inline void r600_nomm_put_vb(struct drm_device *dev)
523{
524 drm_radeon_private_t *dev_priv = dev->dev_private;
525
526 dev_priv->blit_vb->used = 0;
527 radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb);
528}
529
530static inline void *r600_nomm_get_vb_ptr(struct drm_device *dev)
531{
532 drm_radeon_private_t *dev_priv = dev->dev_private;
533 return (((char *)dev->agp_buffer_map->handle +
534 dev_priv->blit_vb->offset + dev_priv->blit_vb->used));
535}
536
537int
538r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv)
539{
540 drm_radeon_private_t *dev_priv = dev->dev_private;
541 DRM_DEBUG("\n");
542
543 r600_nomm_get_vb(dev);
544
545 dev_priv->blit_vb->file_priv = file_priv;
546
547 set_default_state(dev_priv);
548 set_shaders(dev);
549
550 return 0;
551}
552
553
554void
555r600_done_blit_copy(struct drm_device *dev)
556{
557 drm_radeon_private_t *dev_priv = dev->dev_private;
558 RING_LOCALS;
559 DRM_DEBUG("\n");
560
561 BEGIN_RING(5);
562 OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
563 OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
564 /* wait for 3D idle clean */
565 OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
566 OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
567 OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
568
569 ADVANCE_RING();
570 COMMIT_RING();
571
572 r600_nomm_put_vb(dev);
573}
574
575void
576r600_blit_copy(struct drm_device *dev,
577 uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
578 int size_bytes)
579{
580 drm_radeon_private_t *dev_priv = dev->dev_private;
581 int max_bytes;
582 u64 vb_addr;
583 u32 *vb;
584
585 vb = r600_nomm_get_vb_ptr(dev);
586
587 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
588 max_bytes = 8192;
589
590 while (size_bytes) {
591 int cur_size = size_bytes;
592 int src_x = src_gpu_addr & 255;
593 int dst_x = dst_gpu_addr & 255;
594 int h = 1;
595 src_gpu_addr = src_gpu_addr & ~255;
596 dst_gpu_addr = dst_gpu_addr & ~255;
597
598 if (!src_x && !dst_x) {
599 h = (cur_size / max_bytes);
600 if (h > 8192)
601 h = 8192;
602 if (h == 0)
603 h = 1;
604 else
605 cur_size = max_bytes;
606 } else {
607 if (cur_size > max_bytes)
608 cur_size = max_bytes;
609 if (cur_size > (max_bytes - dst_x))
610 cur_size = (max_bytes - dst_x);
611 if (cur_size > (max_bytes - src_x))
612 cur_size = (max_bytes - src_x);
613 }
614
615 if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
616
617 r600_nomm_put_vb(dev);
618 r600_nomm_get_vb(dev);
619 if (!dev_priv->blit_vb)
620 return;
621 set_shaders(dev);
622 vb = r600_nomm_get_vb_ptr(dev);
623 }
624
625 vb[0] = i2f(dst_x);
626 vb[1] = 0;
627 vb[2] = i2f(src_x);
628 vb[3] = 0;
629
630 vb[4] = i2f(dst_x);
631 vb[5] = i2f(h);
632 vb[6] = i2f(src_x);
633 vb[7] = i2f(h);
634
635 vb[8] = i2f(dst_x + cur_size);
636 vb[9] = i2f(h);
637 vb[10] = i2f(src_x + cur_size);
638 vb[11] = i2f(h);
639
640 /* src */
641 set_tex_resource(dev_priv, FMT_8,
642 src_x + cur_size, h, src_x + cur_size,
643 src_gpu_addr);
644
645 cp_set_surface_sync(dev_priv,
646 R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
647
648 /* dst */
649 set_render_target(dev_priv, COLOR_8,
650 dst_x + cur_size, h,
651 dst_gpu_addr);
652
653 /* scissors */
654 set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h);
655
656 /* Vertex buffer setup */
657 vb_addr = dev_priv->gart_buffers_offset +
658 dev_priv->blit_vb->offset +
659 dev_priv->blit_vb->used;
660 set_vtx_resource(dev_priv, vb_addr);
661
662 /* draw */
663 draw_auto(dev_priv);
664
665 cp_set_surface_sync(dev_priv,
666 R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
667 cur_size * h, dst_gpu_addr);
668
669 vb += 12;
670 dev_priv->blit_vb->used += 12 * 4;
671
672 src_gpu_addr += cur_size * h;
673 dst_gpu_addr += cur_size * h;
674 size_bytes -= cur_size * h;
675 }
676 } else {
677 max_bytes = 8192 * 4;
678
679 while (size_bytes) {
680 int cur_size = size_bytes;
681 int src_x = (src_gpu_addr & 255);
682 int dst_x = (dst_gpu_addr & 255);
683 int h = 1;
684 src_gpu_addr = src_gpu_addr & ~255;
685 dst_gpu_addr = dst_gpu_addr & ~255;
686
687 if (!src_x && !dst_x) {
688 h = (cur_size / max_bytes);
689 if (h > 8192)
690 h = 8192;
691 if (h == 0)
692 h = 1;
693 else
694 cur_size = max_bytes;
695 } else {
696 if (cur_size > max_bytes)
697 cur_size = max_bytes;
698 if (cur_size > (max_bytes - dst_x))
699 cur_size = (max_bytes - dst_x);
700 if (cur_size > (max_bytes - src_x))
701 cur_size = (max_bytes - src_x);
702 }
703
704 if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
705 r600_nomm_put_vb(dev);
706 r600_nomm_get_vb(dev);
707 if (!dev_priv->blit_vb)
708 return;
709
710 set_shaders(dev);
711 vb = r600_nomm_get_vb_ptr(dev);
712 }
713
714 vb[0] = i2f(dst_x / 4);
715 vb[1] = 0;
716 vb[2] = i2f(src_x / 4);
717 vb[3] = 0;
718
719 vb[4] = i2f(dst_x / 4);
720 vb[5] = i2f(h);
721 vb[6] = i2f(src_x / 4);
722 vb[7] = i2f(h);
723
724 vb[8] = i2f((dst_x + cur_size) / 4);
725 vb[9] = i2f(h);
726 vb[10] = i2f((src_x + cur_size) / 4);
727 vb[11] = i2f(h);
728
729 /* src */
730 set_tex_resource(dev_priv, FMT_8_8_8_8,
731 (src_x + cur_size) / 4,
732 h, (src_x + cur_size) / 4,
733 src_gpu_addr);
734
735 cp_set_surface_sync(dev_priv,
736 R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
737
738 /* dst */
739 set_render_target(dev_priv, COLOR_8_8_8_8,
740 dst_x + cur_size, h,
741 dst_gpu_addr);
742
743 /* scissors */
744 set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
745
746 /* Vertex buffer setup */
747 vb_addr = dev_priv->gart_buffers_offset +
748 dev_priv->blit_vb->offset +
749 dev_priv->blit_vb->used;
750 set_vtx_resource(dev_priv, vb_addr);
751
752 /* draw */
753 draw_auto(dev_priv);
754
755 cp_set_surface_sync(dev_priv,
756 R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
757 cur_size * h, dst_gpu_addr);
758
759 vb += 12;
760 dev_priv->blit_vb->used += 12 * 4;
761
762 src_gpu_addr += cur_size * h;
763 dst_gpu_addr += cur_size * h;
764 size_bytes -= cur_size * h;
765 }
766 }
767}
768
769void
770r600_blit_swap(struct drm_device *dev,
771 uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
772 int sx, int sy, int dx, int dy,
773 int w, int h, int src_pitch, int dst_pitch, int cpp)
774{
775 drm_radeon_private_t *dev_priv = dev->dev_private;
776 int cb_format, tex_format;
777 u64 vb_addr;
778 u32 *vb;
779
780 vb = r600_nomm_get_vb_ptr(dev);
781
782 if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
783
784 r600_nomm_put_vb(dev);
785 r600_nomm_get_vb(dev);
786 if (!dev_priv->blit_vb)
787 return;
788
789 set_shaders(dev);
790 vb = r600_nomm_get_vb_ptr(dev);
791 }
792
793 if (cpp == 4) {
794 cb_format = COLOR_8_8_8_8;
795 tex_format = FMT_8_8_8_8;
796 } else if (cpp == 2) {
797 cb_format = COLOR_5_6_5;
798 tex_format = FMT_5_6_5;
799 } else {
800 cb_format = COLOR_8;
801 tex_format = FMT_8;
802 }
803
804 vb[0] = i2f(dx);
805 vb[1] = i2f(dy);
806 vb[2] = i2f(sx);
807 vb[3] = i2f(sy);
808
809 vb[4] = i2f(dx);
810 vb[5] = i2f(dy + h);
811 vb[6] = i2f(sx);
812 vb[7] = i2f(sy + h);
813
814 vb[8] = i2f(dx + w);
815 vb[9] = i2f(dy + h);
816 vb[10] = i2f(sx + w);
817 vb[11] = i2f(sy + h);
818
819 /* src */
820 set_tex_resource(dev_priv, tex_format,
821 src_pitch / cpp,
822 sy + h, src_pitch / cpp,
823 src_gpu_addr);
824
825 cp_set_surface_sync(dev_priv,
826 R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
827
828 /* dst */
829 set_render_target(dev_priv, cb_format,
830 dst_pitch / cpp, dy + h,
831 dst_gpu_addr);
832
833 /* scissors */
834 set_scissors(dev_priv, dx, dy, dx + w, dy + h);
835
836 /* Vertex buffer setup */
837 vb_addr = dev_priv->gart_buffers_offset +
838 dev_priv->blit_vb->offset +
839 dev_priv->blit_vb->used;
840 set_vtx_resource(dev_priv, vb_addr);
841
842 /* draw */
843 draw_auto(dev_priv);
844
845 cp_set_surface_sync(dev_priv,
846 R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
847 dst_pitch * (dy + h), dst_gpu_addr);
848
849 dev_priv->blit_vb->used += 12 * 4;
850}
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
new file mode 100644
index 000000000000..0a6f4681f468
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -0,0 +1,805 @@
1#include "drmP.h"
2#include "drm.h"
3#include "radeon_drm.h"
4#include "radeon.h"
5
6#include "r600d.h"
7#include "r600_blit_shaders.h"
8
9#define DI_PT_RECTLIST 0x11
10#define DI_INDEX_SIZE_16_BIT 0x0
11#define DI_SRC_SEL_AUTO_INDEX 0x2
12
13#define FMT_8 0x1
14#define FMT_5_6_5 0x8
15#define FMT_8_8_8_8 0x1a
16#define COLOR_8 0x1
17#define COLOR_5_6_5 0x8
18#define COLOR_8_8_8_8 0x1a
19
20/* emits 21 on rv770+, 23 on r600 */
21static void
22set_render_target(struct radeon_device *rdev, int format,
23 int w, int h, u64 gpu_addr)
24{
25 u32 cb_color_info;
26 int pitch, slice;
27
28 h = (h + 7) & ~7;
29 if (h < 8)
30 h = 8;
31
32 cb_color_info = ((format << 2) | (1 << 27));
33 pitch = (w / 8) - 1;
34 slice = ((w * h) / 64) - 1;
35
36 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
37 radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
38 radeon_ring_write(rdev, gpu_addr >> 8);
39
40 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) {
41 radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0));
42 radeon_ring_write(rdev, 2 << 0);
43 }
44
45 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
46 radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
47 radeon_ring_write(rdev, (pitch << 0) | (slice << 10));
48
49 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
50 radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
51 radeon_ring_write(rdev, 0);
52
53 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
54 radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
55 radeon_ring_write(rdev, cb_color_info);
56
57 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
58 radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
59 radeon_ring_write(rdev, 0);
60
61 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
62 radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
63 radeon_ring_write(rdev, 0);
64
65 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
66 radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
67 radeon_ring_write(rdev, 0);
68}
69
70/* emits 5dw */
71static void
72cp_set_surface_sync(struct radeon_device *rdev,
73 u32 sync_type, u32 size,
74 u64 mc_addr)
75{
76 u32 cp_coher_size;
77
78 if (size == 0xffffffff)
79 cp_coher_size = 0xffffffff;
80 else
81 cp_coher_size = ((size + 255) >> 8);
82
83 radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
84 radeon_ring_write(rdev, sync_type);
85 radeon_ring_write(rdev, cp_coher_size);
86 radeon_ring_write(rdev, mc_addr >> 8);
87 radeon_ring_write(rdev, 10); /* poll interval */
88}
89
90/* emits 21dw + 1 surface sync = 26dw */
91static void
92set_shaders(struct radeon_device *rdev)
93{
94 u64 gpu_addr;
95 u32 sq_pgm_resources;
96
97 /* setup shader regs */
98 sq_pgm_resources = (1 << 0);
99
100 /* VS */
101 gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
102 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
103 radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
104 radeon_ring_write(rdev, gpu_addr >> 8);
105
106 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
107 radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
108 radeon_ring_write(rdev, sq_pgm_resources);
109
110 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
111 radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
112 radeon_ring_write(rdev, 0);
113
114 /* PS */
115 gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset;
116 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
117 radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
118 radeon_ring_write(rdev, gpu_addr >> 8);
119
120 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
121 radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
122 radeon_ring_write(rdev, sq_pgm_resources | (1 << 28));
123
124 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
125 radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
126 radeon_ring_write(rdev, 2);
127
128 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
129 radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
130 radeon_ring_write(rdev, 0);
131
132 gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
133 cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr);
134}
135
136/* emits 9 + 1 sync (5) = 14*/
137static void
138set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
139{
140 u32 sq_vtx_constant_word2;
141
142 sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8));
143
144 radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
145 radeon_ring_write(rdev, 0x460);
146 radeon_ring_write(rdev, gpu_addr & 0xffffffff);
147 radeon_ring_write(rdev, 48 - 1);
148 radeon_ring_write(rdev, sq_vtx_constant_word2);
149 radeon_ring_write(rdev, 1 << 0);
150 radeon_ring_write(rdev, 0);
151 radeon_ring_write(rdev, 0);
152 radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30);
153
154 if ((rdev->family == CHIP_RV610) ||
155 (rdev->family == CHIP_RV620) ||
156 (rdev->family == CHIP_RS780) ||
157 (rdev->family == CHIP_RS880) ||
158 (rdev->family == CHIP_RV710))
159 cp_set_surface_sync(rdev,
160 PACKET3_TC_ACTION_ENA, 48, gpu_addr);
161 else
162 cp_set_surface_sync(rdev,
163 PACKET3_VC_ACTION_ENA, 48, gpu_addr);
164}
165
166/* emits 9 */
167static void
168set_tex_resource(struct radeon_device *rdev,
169 int format, int w, int h, int pitch,
170 u64 gpu_addr)
171{
172 uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
173
174 if (h < 1)
175 h = 1;
176
177 sq_tex_resource_word0 = (1 << 0);
178 sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
179 ((w - 1) << 19));
180
181 sq_tex_resource_word1 = (format << 26);
182 sq_tex_resource_word1 |= ((h - 1) << 0);
183
184 sq_tex_resource_word4 = ((1 << 14) |
185 (0 << 16) |
186 (1 << 19) |
187 (2 << 22) |
188 (3 << 25));
189
190 radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
191 radeon_ring_write(rdev, 0);
192 radeon_ring_write(rdev, sq_tex_resource_word0);
193 radeon_ring_write(rdev, sq_tex_resource_word1);
194 radeon_ring_write(rdev, gpu_addr >> 8);
195 radeon_ring_write(rdev, gpu_addr >> 8);
196 radeon_ring_write(rdev, sq_tex_resource_word4);
197 radeon_ring_write(rdev, 0);
198 radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30);
199}
200
201/* emits 12 */
202static void
203set_scissors(struct radeon_device *rdev, int x1, int y1,
204 int x2, int y2)
205{
206 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
207 radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
208 radeon_ring_write(rdev, (x1 << 0) | (y1 << 16));
209 radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
210
211 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
212 radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
213 radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
214 radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
215
216 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
217 radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
218 radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
219 radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
220}
221
222/* emits 10 */
223static void
224draw_auto(struct radeon_device *rdev)
225{
226 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
227 radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
228 radeon_ring_write(rdev, DI_PT_RECTLIST);
229
230 radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0));
231 radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT);
232
233 radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0));
234 radeon_ring_write(rdev, 1);
235
236 radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1));
237 radeon_ring_write(rdev, 3);
238 radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX);
239
240}
241
242/* emits 14 */
243static void
244set_default_state(struct radeon_device *rdev)
245{
246 u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
247 u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
248 int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
249 int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
250 int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
251 u64 gpu_addr;
252 int dwords;
253
254 switch (rdev->family) {
255 case CHIP_R600:
256 num_ps_gprs = 192;
257 num_vs_gprs = 56;
258 num_temp_gprs = 4;
259 num_gs_gprs = 0;
260 num_es_gprs = 0;
261 num_ps_threads = 136;
262 num_vs_threads = 48;
263 num_gs_threads = 4;
264 num_es_threads = 4;
265 num_ps_stack_entries = 128;
266 num_vs_stack_entries = 128;
267 num_gs_stack_entries = 0;
268 num_es_stack_entries = 0;
269 break;
270 case CHIP_RV630:
271 case CHIP_RV635:
272 num_ps_gprs = 84;
273 num_vs_gprs = 36;
274 num_temp_gprs = 4;
275 num_gs_gprs = 0;
276 num_es_gprs = 0;
277 num_ps_threads = 144;
278 num_vs_threads = 40;
279 num_gs_threads = 4;
280 num_es_threads = 4;
281 num_ps_stack_entries = 40;
282 num_vs_stack_entries = 40;
283 num_gs_stack_entries = 32;
284 num_es_stack_entries = 16;
285 break;
286 case CHIP_RV610:
287 case CHIP_RV620:
288 case CHIP_RS780:
289 case CHIP_RS880:
290 default:
291 num_ps_gprs = 84;
292 num_vs_gprs = 36;
293 num_temp_gprs = 4;
294 num_gs_gprs = 0;
295 num_es_gprs = 0;
296 num_ps_threads = 136;
297 num_vs_threads = 48;
298 num_gs_threads = 4;
299 num_es_threads = 4;
300 num_ps_stack_entries = 40;
301 num_vs_stack_entries = 40;
302 num_gs_stack_entries = 32;
303 num_es_stack_entries = 16;
304 break;
305 case CHIP_RV670:
306 num_ps_gprs = 144;
307 num_vs_gprs = 40;
308 num_temp_gprs = 4;
309 num_gs_gprs = 0;
310 num_es_gprs = 0;
311 num_ps_threads = 136;
312 num_vs_threads = 48;
313 num_gs_threads = 4;
314 num_es_threads = 4;
315 num_ps_stack_entries = 40;
316 num_vs_stack_entries = 40;
317 num_gs_stack_entries = 32;
318 num_es_stack_entries = 16;
319 break;
320 case CHIP_RV770:
321 num_ps_gprs = 192;
322 num_vs_gprs = 56;
323 num_temp_gprs = 4;
324 num_gs_gprs = 0;
325 num_es_gprs = 0;
326 num_ps_threads = 188;
327 num_vs_threads = 60;
328 num_gs_threads = 0;
329 num_es_threads = 0;
330 num_ps_stack_entries = 256;
331 num_vs_stack_entries = 256;
332 num_gs_stack_entries = 0;
333 num_es_stack_entries = 0;
334 break;
335 case CHIP_RV730:
336 case CHIP_RV740:
337 num_ps_gprs = 84;
338 num_vs_gprs = 36;
339 num_temp_gprs = 4;
340 num_gs_gprs = 0;
341 num_es_gprs = 0;
342 num_ps_threads = 188;
343 num_vs_threads = 60;
344 num_gs_threads = 0;
345 num_es_threads = 0;
346 num_ps_stack_entries = 128;
347 num_vs_stack_entries = 128;
348 num_gs_stack_entries = 0;
349 num_es_stack_entries = 0;
350 break;
351 case CHIP_RV710:
352 num_ps_gprs = 192;
353 num_vs_gprs = 56;
354 num_temp_gprs = 4;
355 num_gs_gprs = 0;
356 num_es_gprs = 0;
357 num_ps_threads = 144;
358 num_vs_threads = 48;
359 num_gs_threads = 0;
360 num_es_threads = 0;
361 num_ps_stack_entries = 128;
362 num_vs_stack_entries = 128;
363 num_gs_stack_entries = 0;
364 num_es_stack_entries = 0;
365 break;
366 }
367
368 if ((rdev->family == CHIP_RV610) ||
369 (rdev->family == CHIP_RV620) ||
370 (rdev->family == CHIP_RS780) ||
371 (rdev->family == CHIP_RS780) ||
372 (rdev->family == CHIP_RV710))
373 sq_config = 0;
374 else
375 sq_config = VC_ENABLE;
376
377 sq_config |= (DX9_CONSTS |
378 ALU_INST_PREFER_VECTOR |
379 PS_PRIO(0) |
380 VS_PRIO(1) |
381 GS_PRIO(2) |
382 ES_PRIO(3));
383
384 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
385 NUM_VS_GPRS(num_vs_gprs) |
386 NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
387 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
388 NUM_ES_GPRS(num_es_gprs));
389 sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
390 NUM_VS_THREADS(num_vs_threads) |
391 NUM_GS_THREADS(num_gs_threads) |
392 NUM_ES_THREADS(num_es_threads));
393 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
394 NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
395 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
396 NUM_ES_STACK_ENTRIES(num_es_stack_entries));
397
398 /* emit an IB pointing at default state */
399 dwords = (rdev->r600_blit.state_len + 0xf) & ~0xf;
400 gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
401 radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
402 radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
403 radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
404 radeon_ring_write(rdev, dwords);
405
406 radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
407 radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
408 /* SQ config */
409 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6));
410 radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
411 radeon_ring_write(rdev, sq_config);
412 radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
413 radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
414 radeon_ring_write(rdev, sq_thread_resource_mgmt);
415 radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
416 radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
417}
418
419static inline uint32_t i2f(uint32_t input)
420{
421 u32 result, i, exponent, fraction;
422
423 if ((input & 0x3fff) == 0)
424 result = 0; /* 0 is a special case */
425 else {
426 exponent = 140; /* exponent biased by 127; */
427 fraction = (input & 0x3fff) << 10; /* cheat and only
428 handle numbers below 2^^15 */
429 for (i = 0; i < 14; i++) {
430 if (fraction & 0x800000)
431 break;
432 else {
433 fraction = fraction << 1; /* keep
434 shifting left until top bit = 1 */
435 exponent = exponent - 1;
436 }
437 }
438 result = exponent << 23 | (fraction & 0x7fffff); /* mask
439 off top bit; assumed 1 */
440 }
441 return result;
442}
443
444int r600_blit_init(struct radeon_device *rdev)
445{
446 u32 obj_size;
447 int r, dwords;
448 void *ptr;
449 u32 packet2s[16];
450 int num_packet2s = 0;
451
452 rdev->r600_blit.state_offset = 0;
453
454 if (rdev->family >= CHIP_RV770)
455 rdev->r600_blit.state_len = r7xx_default_size;
456 else
457 rdev->r600_blit.state_len = r6xx_default_size;
458
459 dwords = rdev->r600_blit.state_len;
460 while (dwords & 0xf) {
461 packet2s[num_packet2s++] = PACKET2(0);
462 dwords++;
463 }
464
465 obj_size = dwords * 4;
466 obj_size = ALIGN(obj_size, 256);
467
468 rdev->r600_blit.vs_offset = obj_size;
469 obj_size += r6xx_vs_size * 4;
470 obj_size = ALIGN(obj_size, 256);
471
472 rdev->r600_blit.ps_offset = obj_size;
473 obj_size += r6xx_ps_size * 4;
474 obj_size = ALIGN(obj_size, 256);
475
476 r = radeon_object_create(rdev, NULL, obj_size,
477 true, RADEON_GEM_DOMAIN_VRAM,
478 false, &rdev->r600_blit.shader_obj);
479 if (r) {
480 DRM_ERROR("r600 failed to allocate shader\n");
481 return r;
482 }
483
484 DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n",
485 obj_size,
486 rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
487
488 r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr);
489 if (r) {
490 DRM_ERROR("failed to map blit object %d\n", r);
491 return r;
492 }
493
494 if (rdev->family >= CHIP_RV770)
495 memcpy_toio(ptr + rdev->r600_blit.state_offset,
496 r7xx_default_state, rdev->r600_blit.state_len * 4);
497 else
498 memcpy_toio(ptr + rdev->r600_blit.state_offset,
499 r6xx_default_state, rdev->r600_blit.state_len * 4);
500 if (num_packet2s)
501 memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
502 packet2s, num_packet2s * 4);
503
504
505 memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
506 memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
507
508 radeon_object_kunmap(rdev->r600_blit.shader_obj);
509 return 0;
510}
511
512void r600_blit_fini(struct radeon_device *rdev)
513{
514 radeon_object_unpin(rdev->r600_blit.shader_obj);
515 radeon_object_unref(&rdev->r600_blit.shader_obj);
516}
517
518int r600_vb_ib_get(struct radeon_device *rdev)
519{
520 int r;
521 r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib);
522 if (r) {
523 DRM_ERROR("failed to get IB for vertex buffer\n");
524 return r;
525 }
526
527 rdev->r600_blit.vb_total = 64*1024;
528 rdev->r600_blit.vb_used = 0;
529 return 0;
530}
531
532void r600_vb_ib_put(struct radeon_device *rdev)
533{
534 radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
535 mutex_lock(&rdev->ib_pool.mutex);
536 list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
537 mutex_unlock(&rdev->ib_pool.mutex);
538 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
539}
540
541int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
542{
543 int r;
544 int ring_size, line_size;
545 int max_size;
546 /* loops of emits 64 + fence emit possible */
547 int dwords_per_loop = 76, num_loops;
548
549 r = r600_vb_ib_get(rdev);
550 WARN_ON(r);
551
552 /* set_render_target emits 2 extra dwords on rv6xx */
553 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
554 dwords_per_loop += 2;
555
556 /* 8 bpp vs 32 bpp for xfer unit */
557 if (size_bytes & 3)
558 line_size = 8192;
559 else
560 line_size = 8192*4;
561
562 max_size = 8192 * line_size;
563
564 /* major loops cover the max size transfer */
565 num_loops = ((size_bytes + max_size) / max_size);
566 /* minor loops cover the extra non aligned bits */
567 num_loops += ((size_bytes % line_size) ? 1 : 0);
568 /* calculate number of loops correctly */
569 ring_size = num_loops * dwords_per_loop;
570 /* set default + shaders */
571 ring_size += 40; /* shaders + def state */
572 ring_size += 3; /* fence emit for VB IB */
573 ring_size += 5; /* done copy */
574 ring_size += 3; /* fence emit for done copy */
575 r = radeon_ring_lock(rdev, ring_size);
576 WARN_ON(r);
577
578 set_default_state(rdev); /* 14 */
579 set_shaders(rdev); /* 26 */
580 return 0;
581}
582
583void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence)
584{
585 int r;
586
587 radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
588 radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
589 /* wait for 3D idle clean */
590 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
591 radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
592 radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
593
594 if (rdev->r600_blit.vb_ib)
595 r600_vb_ib_put(rdev);
596
597 if (fence)
598 r = radeon_fence_emit(rdev, fence);
599
600 radeon_ring_unlock_commit(rdev);
601}
602
603void r600_kms_blit_copy(struct radeon_device *rdev,
604 u64 src_gpu_addr, u64 dst_gpu_addr,
605 int size_bytes)
606{
607 int max_bytes;
608 u64 vb_gpu_addr;
609 u32 *vb;
610
611 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
612 size_bytes, rdev->r600_blit.vb_used);
613 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
614 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
615 max_bytes = 8192;
616
617 while (size_bytes) {
618 int cur_size = size_bytes;
619 int src_x = src_gpu_addr & 255;
620 int dst_x = dst_gpu_addr & 255;
621 int h = 1;
622 src_gpu_addr = src_gpu_addr & ~255;
623 dst_gpu_addr = dst_gpu_addr & ~255;
624
625 if (!src_x && !dst_x) {
626 h = (cur_size / max_bytes);
627 if (h > 8192)
628 h = 8192;
629 if (h == 0)
630 h = 1;
631 else
632 cur_size = max_bytes;
633 } else {
634 if (cur_size > max_bytes)
635 cur_size = max_bytes;
636 if (cur_size > (max_bytes - dst_x))
637 cur_size = (max_bytes - dst_x);
638 if (cur_size > (max_bytes - src_x))
639 cur_size = (max_bytes - src_x);
640 }
641
642 if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) {
643 WARN_ON(1);
644
645#if 0
646 r600_vb_ib_put(rdev);
647
648 r600_nomm_put_vb(dev);
649 r600_nomm_get_vb(dev);
650 if (!dev_priv->blit_vb)
651 return;
652 set_shaders(dev);
653 vb = r600_nomm_get_vb_ptr(dev);
654#endif
655 }
656
657 vb[0] = i2f(dst_x);
658 vb[1] = 0;
659 vb[2] = i2f(src_x);
660 vb[3] = 0;
661
662 vb[4] = i2f(dst_x);
663 vb[5] = i2f(h);
664 vb[6] = i2f(src_x);
665 vb[7] = i2f(h);
666
667 vb[8] = i2f(dst_x + cur_size);
668 vb[9] = i2f(h);
669 vb[10] = i2f(src_x + cur_size);
670 vb[11] = i2f(h);
671
672 /* src 9 */
673 set_tex_resource(rdev, FMT_8,
674 src_x + cur_size, h, src_x + cur_size,
675 src_gpu_addr);
676
677 /* 5 */
678 cp_set_surface_sync(rdev,
679 PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
680
681 /* dst 23 */
682 set_render_target(rdev, COLOR_8,
683 dst_x + cur_size, h,
684 dst_gpu_addr);
685
686 /* scissors 12 */
687 set_scissors(rdev, dst_x, 0, dst_x + cur_size, h);
688
689 /* 14 */
690 vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
691 set_vtx_resource(rdev, vb_gpu_addr);
692
693 /* draw 10 */
694 draw_auto(rdev);
695
696 /* 5 */
697 cp_set_surface_sync(rdev,
698 PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
699 cur_size * h, dst_gpu_addr);
700
701 vb += 12;
702 rdev->r600_blit.vb_used += 12 * 4;
703
704 src_gpu_addr += cur_size * h;
705 dst_gpu_addr += cur_size * h;
706 size_bytes -= cur_size * h;
707 }
708 } else {
709 max_bytes = 8192 * 4;
710
711 while (size_bytes) {
712 int cur_size = size_bytes;
713 int src_x = (src_gpu_addr & 255);
714 int dst_x = (dst_gpu_addr & 255);
715 int h = 1;
716 src_gpu_addr = src_gpu_addr & ~255;
717 dst_gpu_addr = dst_gpu_addr & ~255;
718
719 if (!src_x && !dst_x) {
720 h = (cur_size / max_bytes);
721 if (h > 8192)
722 h = 8192;
723 if (h == 0)
724 h = 1;
725 else
726 cur_size = max_bytes;
727 } else {
728 if (cur_size > max_bytes)
729 cur_size = max_bytes;
730 if (cur_size > (max_bytes - dst_x))
731 cur_size = (max_bytes - dst_x);
732 if (cur_size > (max_bytes - src_x))
733 cur_size = (max_bytes - src_x);
734 }
735
736 if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) {
737 WARN_ON(1);
738 }
739#if 0
740 if ((rdev->blit_vb->used + 48) > rdev->blit_vb->total) {
741 r600_nomm_put_vb(dev);
742 r600_nomm_get_vb(dev);
743 if (!rdev->blit_vb)
744 return;
745
746 set_shaders(dev);
747 vb = r600_nomm_get_vb_ptr(dev);
748 }
749#endif
750
751 vb[0] = i2f(dst_x / 4);
752 vb[1] = 0;
753 vb[2] = i2f(src_x / 4);
754 vb[3] = 0;
755
756 vb[4] = i2f(dst_x / 4);
757 vb[5] = i2f(h);
758 vb[6] = i2f(src_x / 4);
759 vb[7] = i2f(h);
760
761 vb[8] = i2f((dst_x + cur_size) / 4);
762 vb[9] = i2f(h);
763 vb[10] = i2f((src_x + cur_size) / 4);
764 vb[11] = i2f(h);
765
766 /* src 9 */
767 set_tex_resource(rdev, FMT_8_8_8_8,
768 (src_x + cur_size) / 4,
769 h, (src_x + cur_size) / 4,
770 src_gpu_addr);
771 /* 5 */
772 cp_set_surface_sync(rdev,
773 PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
774
775 /* dst 23 */
776 set_render_target(rdev, COLOR_8_8_8_8,
777 dst_x + cur_size, h,
778 dst_gpu_addr);
779
780 /* scissors 12 */
781 set_scissors(rdev, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
782
783 /* Vertex buffer setup 14 */
784 vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
785 set_vtx_resource(rdev, vb_gpu_addr);
786
787 /* draw 10 */
788 draw_auto(rdev);
789
790 /* 5 */
791 cp_set_surface_sync(rdev,
792 PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
793 cur_size * h, dst_gpu_addr);
794
795 /* 78 ring dwords per loop */
796 vb += 12;
797 rdev->r600_blit.vb_used += 12 * 4;
798
799 src_gpu_addr += cur_size * h;
800 dst_gpu_addr += cur_size * h;
801 size_bytes -= cur_size * h;
802 }
803 }
804}
805
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c
new file mode 100644
index 000000000000..d745e815c2e8
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c
@@ -0,0 +1,1072 @@
1
2#include <linux/types.h>
3#include <linux/kernel.h>
4
5const u32 r6xx_default_state[] =
6{
7 0xc0002400,
8 0x00000000,
9 0xc0012800,
10 0x80000000,
11 0x80000000,
12 0xc0004600,
13 0x00000016,
14 0xc0016800,
15 0x00000010,
16 0x00028000,
17 0xc0016800,
18 0x00000010,
19 0x00008000,
20 0xc0016800,
21 0x00000542,
22 0x07000003,
23 0xc0016800,
24 0x000005c5,
25 0x00000000,
26 0xc0016800,
27 0x00000363,
28 0x00000000,
29 0xc0016800,
30 0x0000060c,
31 0x82000000,
32 0xc0016800,
33 0x0000060e,
34 0x01020204,
35 0xc0016f00,
36 0x00000000,
37 0x00000000,
38 0xc0016f00,
39 0x00000001,
40 0x00000000,
41 0xc0096900,
42 0x0000022a,
43 0x00000000,
44 0x00000000,
45 0x00000000,
46 0x00000000,
47 0x00000000,
48 0x00000000,
49 0x00000000,
50 0x00000000,
51 0x00000000,
52 0xc0016900,
53 0x00000004,
54 0x00000000,
55 0xc0016900,
56 0x0000000a,
57 0x00000000,
58 0xc0016900,
59 0x0000000b,
60 0x00000000,
61 0xc0016900,
62 0x0000010c,
63 0x00000000,
64 0xc0016900,
65 0x0000010d,
66 0x00000000,
67 0xc0016900,
68 0x00000200,
69 0x00000000,
70 0xc0016900,
71 0x00000343,
72 0x00000060,
73 0xc0016900,
74 0x00000344,
75 0x00000040,
76 0xc0016900,
77 0x00000351,
78 0x0000aa00,
79 0xc0016900,
80 0x00000104,
81 0x00000000,
82 0xc0016900,
83 0x0000010e,
84 0x00000000,
85 0xc0046900,
86 0x00000105,
87 0x00000000,
88 0x00000000,
89 0x00000000,
90 0x00000000,
91 0xc0036900,
92 0x00000109,
93 0x00000000,
94 0x00000000,
95 0x00000000,
96 0xc0046900,
97 0x0000030c,
98 0x01000000,
99 0x00000000,
100 0x00000000,
101 0x00000000,
102 0xc0046900,
103 0x00000048,
104 0x3f800000,
105 0x00000000,
106 0x3f800000,
107 0x3f800000,
108 0xc0016900,
109 0x0000008e,
110 0x0000000f,
111 0xc0016900,
112 0x00000080,
113 0x00000000,
114 0xc0016900,
115 0x00000083,
116 0x0000ffff,
117 0xc0016900,
118 0x00000084,
119 0x00000000,
120 0xc0016900,
121 0x00000085,
122 0x20002000,
123 0xc0016900,
124 0x00000086,
125 0x00000000,
126 0xc0016900,
127 0x00000087,
128 0x20002000,
129 0xc0016900,
130 0x00000088,
131 0x00000000,
132 0xc0016900,
133 0x00000089,
134 0x20002000,
135 0xc0016900,
136 0x0000008a,
137 0x00000000,
138 0xc0016900,
139 0x0000008b,
140 0x20002000,
141 0xc0016900,
142 0x0000008c,
143 0x00000000,
144 0xc0016900,
145 0x00000094,
146 0x80000000,
147 0xc0016900,
148 0x00000095,
149 0x20002000,
150 0xc0026900,
151 0x000000b4,
152 0x00000000,
153 0x3f800000,
154 0xc0016900,
155 0x00000096,
156 0x80000000,
157 0xc0016900,
158 0x00000097,
159 0x20002000,
160 0xc0026900,
161 0x000000b6,
162 0x00000000,
163 0x3f800000,
164 0xc0016900,
165 0x00000098,
166 0x80000000,
167 0xc0016900,
168 0x00000099,
169 0x20002000,
170 0xc0026900,
171 0x000000b8,
172 0x00000000,
173 0x3f800000,
174 0xc0016900,
175 0x0000009a,
176 0x80000000,
177 0xc0016900,
178 0x0000009b,
179 0x20002000,
180 0xc0026900,
181 0x000000ba,
182 0x00000000,
183 0x3f800000,
184 0xc0016900,
185 0x0000009c,
186 0x80000000,
187 0xc0016900,
188 0x0000009d,
189 0x20002000,
190 0xc0026900,
191 0x000000bc,
192 0x00000000,
193 0x3f800000,
194 0xc0016900,
195 0x0000009e,
196 0x80000000,
197 0xc0016900,
198 0x0000009f,
199 0x20002000,
200 0xc0026900,
201 0x000000be,
202 0x00000000,
203 0x3f800000,
204 0xc0016900,
205 0x000000a0,
206 0x80000000,
207 0xc0016900,
208 0x000000a1,
209 0x20002000,
210 0xc0026900,
211 0x000000c0,
212 0x00000000,
213 0x3f800000,
214 0xc0016900,
215 0x000000a2,
216 0x80000000,
217 0xc0016900,
218 0x000000a3,
219 0x20002000,
220 0xc0026900,
221 0x000000c2,
222 0x00000000,
223 0x3f800000,
224 0xc0016900,
225 0x000000a4,
226 0x80000000,
227 0xc0016900,
228 0x000000a5,
229 0x20002000,
230 0xc0026900,
231 0x000000c4,
232 0x00000000,
233 0x3f800000,
234 0xc0016900,
235 0x000000a6,
236 0x80000000,
237 0xc0016900,
238 0x000000a7,
239 0x20002000,
240 0xc0026900,
241 0x000000c6,
242 0x00000000,
243 0x3f800000,
244 0xc0016900,
245 0x000000a8,
246 0x80000000,
247 0xc0016900,
248 0x000000a9,
249 0x20002000,
250 0xc0026900,
251 0x000000c8,
252 0x00000000,
253 0x3f800000,
254 0xc0016900,
255 0x000000aa,
256 0x80000000,
257 0xc0016900,
258 0x000000ab,
259 0x20002000,
260 0xc0026900,
261 0x000000ca,
262 0x00000000,
263 0x3f800000,
264 0xc0016900,
265 0x000000ac,
266 0x80000000,
267 0xc0016900,
268 0x000000ad,
269 0x20002000,
270 0xc0026900,
271 0x000000cc,
272 0x00000000,
273 0x3f800000,
274 0xc0016900,
275 0x000000ae,
276 0x80000000,
277 0xc0016900,
278 0x000000af,
279 0x20002000,
280 0xc0026900,
281 0x000000ce,
282 0x00000000,
283 0x3f800000,
284 0xc0016900,
285 0x000000b0,
286 0x80000000,
287 0xc0016900,
288 0x000000b1,
289 0x20002000,
290 0xc0026900,
291 0x000000d0,
292 0x00000000,
293 0x3f800000,
294 0xc0016900,
295 0x000000b2,
296 0x80000000,
297 0xc0016900,
298 0x000000b3,
299 0x20002000,
300 0xc0026900,
301 0x000000d2,
302 0x00000000,
303 0x3f800000,
304 0xc0016900,
305 0x00000293,
306 0x00004010,
307 0xc0016900,
308 0x00000300,
309 0x00000000,
310 0xc0016900,
311 0x00000301,
312 0x00000000,
313 0xc0016900,
314 0x00000312,
315 0xffffffff,
316 0xc0016900,
317 0x00000307,
318 0x00000000,
319 0xc0016900,
320 0x00000308,
321 0x00000000,
322 0xc0016900,
323 0x00000283,
324 0x00000000,
325 0xc0016900,
326 0x00000292,
327 0x00000000,
328 0xc0066900,
329 0x0000010f,
330 0x00000000,
331 0x00000000,
332 0x00000000,
333 0x00000000,
334 0x00000000,
335 0x00000000,
336 0xc0016900,
337 0x00000206,
338 0x00000000,
339 0xc0016900,
340 0x00000207,
341 0x00000000,
342 0xc0016900,
343 0x00000208,
344 0x00000000,
345 0xc0046900,
346 0x00000303,
347 0x3f800000,
348 0x3f800000,
349 0x3f800000,
350 0x3f800000,
351 0xc0016900,
352 0x00000205,
353 0x00000004,
354 0xc0016900,
355 0x00000280,
356 0x00000000,
357 0xc0016900,
358 0x00000281,
359 0x00000000,
360 0xc0016900,
361 0x0000037e,
362 0x00000000,
363 0xc0016900,
364 0x00000382,
365 0x00000000,
366 0xc0016900,
367 0x00000380,
368 0x00000000,
369 0xc0016900,
370 0x00000383,
371 0x00000000,
372 0xc0016900,
373 0x00000381,
374 0x00000000,
375 0xc0016900,
376 0x00000282,
377 0x00000008,
378 0xc0016900,
379 0x00000302,
380 0x0000002d,
381 0xc0016900,
382 0x0000037f,
383 0x00000000,
384 0xc0016900,
385 0x000001b2,
386 0x00000000,
387 0xc0016900,
388 0x000001b6,
389 0x00000000,
390 0xc0016900,
391 0x000001b7,
392 0x00000000,
393 0xc0016900,
394 0x000001b8,
395 0x00000000,
396 0xc0016900,
397 0x000001b9,
398 0x00000000,
399 0xc0016900,
400 0x00000225,
401 0x00000000,
402 0xc0016900,
403 0x00000229,
404 0x00000000,
405 0xc0016900,
406 0x00000237,
407 0x00000000,
408 0xc0016900,
409 0x00000100,
410 0x00000800,
411 0xc0016900,
412 0x00000101,
413 0x00000000,
414 0xc0016900,
415 0x00000102,
416 0x00000000,
417 0xc0016900,
418 0x000002a8,
419 0x00000000,
420 0xc0016900,
421 0x000002a9,
422 0x00000000,
423 0xc0016900,
424 0x00000103,
425 0x00000000,
426 0xc0016900,
427 0x00000284,
428 0x00000000,
429 0xc0016900,
430 0x00000290,
431 0x00000000,
432 0xc0016900,
433 0x00000285,
434 0x00000000,
435 0xc0016900,
436 0x00000286,
437 0x00000000,
438 0xc0016900,
439 0x00000287,
440 0x00000000,
441 0xc0016900,
442 0x00000288,
443 0x00000000,
444 0xc0016900,
445 0x00000289,
446 0x00000000,
447 0xc0016900,
448 0x0000028a,
449 0x00000000,
450 0xc0016900,
451 0x0000028b,
452 0x00000000,
453 0xc0016900,
454 0x0000028c,
455 0x00000000,
456 0xc0016900,
457 0x0000028d,
458 0x00000000,
459 0xc0016900,
460 0x0000028e,
461 0x00000000,
462 0xc0016900,
463 0x0000028f,
464 0x00000000,
465 0xc0016900,
466 0x000002a1,
467 0x00000000,
468 0xc0016900,
469 0x000002a5,
470 0x00000000,
471 0xc0016900,
472 0x000002ac,
473 0x00000000,
474 0xc0016900,
475 0x000002ad,
476 0x00000000,
477 0xc0016900,
478 0x000002ae,
479 0x00000000,
480 0xc0016900,
481 0x000002c8,
482 0x00000000,
483 0xc0016900,
484 0x00000206,
485 0x00000100,
486 0xc0016900,
487 0x00000204,
488 0x00010000,
489 0xc0036e00,
490 0x00000000,
491 0x00000012,
492 0x00000000,
493 0x00000000,
494 0xc0016900,
495 0x0000008f,
496 0x0000000f,
497 0xc0016900,
498 0x000001e8,
499 0x00000001,
500 0xc0016900,
501 0x00000202,
502 0x00cc0000,
503 0xc0016900,
504 0x00000205,
505 0x00000244,
506 0xc0016900,
507 0x00000203,
508 0x00000210,
509 0xc0016900,
510 0x000001b1,
511 0x00000000,
512 0xc0016900,
513 0x00000185,
514 0x00000000,
515 0xc0016900,
516 0x000001b3,
517 0x00000001,
518 0xc0016900,
519 0x000001b4,
520 0x00000000,
521 0xc0016900,
522 0x00000191,
523 0x00000b00,
524 0xc0016900,
525 0x000001b5,
526 0x00000000,
527};
528
529const u32 r7xx_default_state[] =
530{
531 0xc0012800,
532 0x80000000,
533 0x80000000,
534 0xc0004600,
535 0x00000016,
536 0xc0016800,
537 0x00000010,
538 0x00028000,
539 0xc0016800,
540 0x00000010,
541 0x00008000,
542 0xc0016800,
543 0x00000542,
544 0x07000002,
545 0xc0016800,
546 0x000005c5,
547 0x00000000,
548 0xc0016800,
549 0x00000363,
550 0x00004000,
551 0xc0016800,
552 0x0000060c,
553 0x00000000,
554 0xc0016800,
555 0x0000060e,
556 0x00420204,
557 0xc0016f00,
558 0x00000000,
559 0x00000000,
560 0xc0016f00,
561 0x00000001,
562 0x00000000,
563 0xc0096900,
564 0x0000022a,
565 0x00000000,
566 0x00000000,
567 0x00000000,
568 0x00000000,
569 0x00000000,
570 0x00000000,
571 0x00000000,
572 0x00000000,
573 0x00000000,
574 0xc0016900,
575 0x00000004,
576 0x00000000,
577 0xc0016900,
578 0x0000000a,
579 0x00000000,
580 0xc0016900,
581 0x0000000b,
582 0x00000000,
583 0xc0016900,
584 0x0000010c,
585 0x00000000,
586 0xc0016900,
587 0x0000010d,
588 0x00000000,
589 0xc0016900,
590 0x00000200,
591 0x00000000,
592 0xc0016900,
593 0x00000343,
594 0x00000060,
595 0xc0016900,
596 0x00000344,
597 0x00000000,
598 0xc0016900,
599 0x00000351,
600 0x0000aa00,
601 0xc0016900,
602 0x00000104,
603 0x00000000,
604 0xc0016900,
605 0x0000010e,
606 0x00000000,
607 0xc0046900,
608 0x00000105,
609 0x00000000,
610 0x00000000,
611 0x00000000,
612 0x00000000,
613 0xc0046900,
614 0x0000030c,
615 0x01000000,
616 0x00000000,
617 0x00000000,
618 0x00000000,
619 0xc0016900,
620 0x0000008e,
621 0x0000000f,
622 0xc0016900,
623 0x00000080,
624 0x00000000,
625 0xc0016900,
626 0x00000083,
627 0x0000ffff,
628 0xc0016900,
629 0x00000084,
630 0x00000000,
631 0xc0016900,
632 0x00000085,
633 0x20002000,
634 0xc0016900,
635 0x00000086,
636 0x00000000,
637 0xc0016900,
638 0x00000087,
639 0x20002000,
640 0xc0016900,
641 0x00000088,
642 0x00000000,
643 0xc0016900,
644 0x00000089,
645 0x20002000,
646 0xc0016900,
647 0x0000008a,
648 0x00000000,
649 0xc0016900,
650 0x0000008b,
651 0x20002000,
652 0xc0016900,
653 0x0000008c,
654 0xaaaaaaaa,
655 0xc0016900,
656 0x00000094,
657 0x80000000,
658 0xc0016900,
659 0x00000095,
660 0x20002000,
661 0xc0026900,
662 0x000000b4,
663 0x00000000,
664 0x3f800000,
665 0xc0016900,
666 0x00000096,
667 0x80000000,
668 0xc0016900,
669 0x00000097,
670 0x20002000,
671 0xc0026900,
672 0x000000b6,
673 0x00000000,
674 0x3f800000,
675 0xc0016900,
676 0x00000098,
677 0x80000000,
678 0xc0016900,
679 0x00000099,
680 0x20002000,
681 0xc0026900,
682 0x000000b8,
683 0x00000000,
684 0x3f800000,
685 0xc0016900,
686 0x0000009a,
687 0x80000000,
688 0xc0016900,
689 0x0000009b,
690 0x20002000,
691 0xc0026900,
692 0x000000ba,
693 0x00000000,
694 0x3f800000,
695 0xc0016900,
696 0x0000009c,
697 0x80000000,
698 0xc0016900,
699 0x0000009d,
700 0x20002000,
701 0xc0026900,
702 0x000000bc,
703 0x00000000,
704 0x3f800000,
705 0xc0016900,
706 0x0000009e,
707 0x80000000,
708 0xc0016900,
709 0x0000009f,
710 0x20002000,
711 0xc0026900,
712 0x000000be,
713 0x00000000,
714 0x3f800000,
715 0xc0016900,
716 0x000000a0,
717 0x80000000,
718 0xc0016900,
719 0x000000a1,
720 0x20002000,
721 0xc0026900,
722 0x000000c0,
723 0x00000000,
724 0x3f800000,
725 0xc0016900,
726 0x000000a2,
727 0x80000000,
728 0xc0016900,
729 0x000000a3,
730 0x20002000,
731 0xc0026900,
732 0x000000c2,
733 0x00000000,
734 0x3f800000,
735 0xc0016900,
736 0x000000a4,
737 0x80000000,
738 0xc0016900,
739 0x000000a5,
740 0x20002000,
741 0xc0026900,
742 0x000000c4,
743 0x00000000,
744 0x3f800000,
745 0xc0016900,
746 0x000000a6,
747 0x80000000,
748 0xc0016900,
749 0x000000a7,
750 0x20002000,
751 0xc0026900,
752 0x000000c6,
753 0x00000000,
754 0x3f800000,
755 0xc0016900,
756 0x000000a8,
757 0x80000000,
758 0xc0016900,
759 0x000000a9,
760 0x20002000,
761 0xc0026900,
762 0x000000c8,
763 0x00000000,
764 0x3f800000,
765 0xc0016900,
766 0x000000aa,
767 0x80000000,
768 0xc0016900,
769 0x000000ab,
770 0x20002000,
771 0xc0026900,
772 0x000000ca,
773 0x00000000,
774 0x3f800000,
775 0xc0016900,
776 0x000000ac,
777 0x80000000,
778 0xc0016900,
779 0x000000ad,
780 0x20002000,
781 0xc0026900,
782 0x000000cc,
783 0x00000000,
784 0x3f800000,
785 0xc0016900,
786 0x000000ae,
787 0x80000000,
788 0xc0016900,
789 0x000000af,
790 0x20002000,
791 0xc0026900,
792 0x000000ce,
793 0x00000000,
794 0x3f800000,
795 0xc0016900,
796 0x000000b0,
797 0x80000000,
798 0xc0016900,
799 0x000000b1,
800 0x20002000,
801 0xc0026900,
802 0x000000d0,
803 0x00000000,
804 0x3f800000,
805 0xc0016900,
806 0x000000b2,
807 0x80000000,
808 0xc0016900,
809 0x000000b3,
810 0x20002000,
811 0xc0026900,
812 0x000000d2,
813 0x00000000,
814 0x3f800000,
815 0xc0016900,
816 0x00000293,
817 0x00514000,
818 0xc0016900,
819 0x00000300,
820 0x00000000,
821 0xc0016900,
822 0x00000301,
823 0x00000000,
824 0xc0016900,
825 0x00000312,
826 0xffffffff,
827 0xc0016900,
828 0x00000307,
829 0x00000000,
830 0xc0016900,
831 0x00000308,
832 0x00000000,
833 0xc0016900,
834 0x00000283,
835 0x00000000,
836 0xc0016900,
837 0x00000292,
838 0x00000000,
839 0xc0066900,
840 0x0000010f,
841 0x00000000,
842 0x00000000,
843 0x00000000,
844 0x00000000,
845 0x00000000,
846 0x00000000,
847 0xc0016900,
848 0x00000206,
849 0x00000000,
850 0xc0016900,
851 0x00000207,
852 0x00000000,
853 0xc0016900,
854 0x00000208,
855 0x00000000,
856 0xc0046900,
857 0x00000303,
858 0x3f800000,
859 0x3f800000,
860 0x3f800000,
861 0x3f800000,
862 0xc0016900,
863 0x00000205,
864 0x00000004,
865 0xc0016900,
866 0x00000280,
867 0x00000000,
868 0xc0016900,
869 0x00000281,
870 0x00000000,
871 0xc0016900,
872 0x0000037e,
873 0x00000000,
874 0xc0016900,
875 0x00000382,
876 0x00000000,
877 0xc0016900,
878 0x00000380,
879 0x00000000,
880 0xc0016900,
881 0x00000383,
882 0x00000000,
883 0xc0016900,
884 0x00000381,
885 0x00000000,
886 0xc0016900,
887 0x00000282,
888 0x00000008,
889 0xc0016900,
890 0x00000302,
891 0x0000002d,
892 0xc0016900,
893 0x0000037f,
894 0x00000000,
895 0xc0016900,
896 0x000001b2,
897 0x00000001,
898 0xc0016900,
899 0x000001b6,
900 0x00000000,
901 0xc0016900,
902 0x000001b7,
903 0x00000000,
904 0xc0016900,
905 0x000001b8,
906 0x00000000,
907 0xc0016900,
908 0x000001b9,
909 0x00000000,
910 0xc0016900,
911 0x00000225,
912 0x00000000,
913 0xc0016900,
914 0x00000229,
915 0x00000000,
916 0xc0016900,
917 0x00000237,
918 0x00000000,
919 0xc0016900,
920 0x00000100,
921 0x00000800,
922 0xc0016900,
923 0x00000101,
924 0x00000000,
925 0xc0016900,
926 0x00000102,
927 0x00000000,
928 0xc0016900,
929 0x000002a8,
930 0x00000000,
931 0xc0016900,
932 0x000002a9,
933 0x00000000,
934 0xc0016900,
935 0x00000103,
936 0x00000000,
937 0xc0016900,
938 0x00000284,
939 0x00000000,
940 0xc0016900,
941 0x00000290,
942 0x00000000,
943 0xc0016900,
944 0x00000285,
945 0x00000000,
946 0xc0016900,
947 0x00000286,
948 0x00000000,
949 0xc0016900,
950 0x00000287,
951 0x00000000,
952 0xc0016900,
953 0x00000288,
954 0x00000000,
955 0xc0016900,
956 0x00000289,
957 0x00000000,
958 0xc0016900,
959 0x0000028a,
960 0x00000000,
961 0xc0016900,
962 0x0000028b,
963 0x00000000,
964 0xc0016900,
965 0x0000028c,
966 0x00000000,
967 0xc0016900,
968 0x0000028d,
969 0x00000000,
970 0xc0016900,
971 0x0000028e,
972 0x00000000,
973 0xc0016900,
974 0x0000028f,
975 0x00000000,
976 0xc0016900,
977 0x000002a1,
978 0x00000000,
979 0xc0016900,
980 0x000002a5,
981 0x00000000,
982 0xc0016900,
983 0x000002ac,
984 0x00000000,
985 0xc0016900,
986 0x000002ad,
987 0x00000000,
988 0xc0016900,
989 0x000002ae,
990 0x00000000,
991 0xc0016900,
992 0x000002c8,
993 0x00000000,
994 0xc0016900,
995 0x00000206,
996 0x00000100,
997 0xc0016900,
998 0x00000204,
999 0x00010000,
1000 0xc0036e00,
1001 0x00000000,
1002 0x00000012,
1003 0x00000000,
1004 0x00000000,
1005 0xc0016900,
1006 0x0000008f,
1007 0x0000000f,
1008 0xc0016900,
1009 0x000001e8,
1010 0x00000001,
1011 0xc0016900,
1012 0x00000202,
1013 0x00cc0000,
1014 0xc0016900,
1015 0x00000205,
1016 0x00000244,
1017 0xc0016900,
1018 0x00000203,
1019 0x00000210,
1020 0xc0016900,
1021 0x000001b1,
1022 0x00000000,
1023 0xc0016900,
1024 0x00000185,
1025 0x00000000,
1026 0xc0016900,
1027 0x000001b3,
1028 0x00000001,
1029 0xc0016900,
1030 0x000001b4,
1031 0x00000000,
1032 0xc0016900,
1033 0x00000191,
1034 0x00000b00,
1035 0xc0016900,
1036 0x000001b5,
1037 0x00000000,
1038};
1039
1040/* same for r6xx/r7xx */
1041const u32 r6xx_vs[] =
1042{
1043 0x00000004,
1044 0x81000000,
1045 0x0000203c,
1046 0x94000b08,
1047 0x00004000,
1048 0x14200b1a,
1049 0x00000000,
1050 0x00000000,
1051 0x3c000000,
1052 0x68cd1000,
1053 0x00080000,
1054 0x00000000,
1055};
1056
1057const u32 r6xx_ps[] =
1058{
1059 0x00000002,
1060 0x80800000,
1061 0x00000000,
1062 0x94200688,
1063 0x00000010,
1064 0x000d1000,
1065 0xb0800000,
1066 0x00000000,
1067};
1068
1069const u32 r6xx_ps_size = ARRAY_SIZE(r6xx_ps);
1070const u32 r6xx_vs_size = ARRAY_SIZE(r6xx_vs);
1071const u32 r6xx_default_size = ARRAY_SIZE(r6xx_default_state);
1072const u32 r7xx_default_size = ARRAY_SIZE(r7xx_default_state);
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h
new file mode 100644
index 000000000000..fdc3b378cbb0
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h
@@ -0,0 +1,14 @@
1
2#ifndef R600_BLIT_SHADERS_H
3#define R600_BLIT_SHADERS_H
4
5extern const u32 r6xx_ps[];
6extern const u32 r6xx_vs[];
7extern const u32 r7xx_default_state[];
8extern const u32 r6xx_default_state[];
9
10
11extern const u32 r6xx_ps_size, r6xx_vs_size;
12extern const u32 r6xx_default_size, r7xx_default_size;
13
14#endif
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 20f17908b036..6d5a711c2e91 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -31,7 +31,38 @@
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32#include "radeon_drv.h" 32#include "radeon_drv.h"
33 33
34#include "r600_microcode.h" 34#define PFP_UCODE_SIZE 576
35#define PM4_UCODE_SIZE 1792
36#define R700_PFP_UCODE_SIZE 848
37#define R700_PM4_UCODE_SIZE 1360
38
39/* Firmware Names */
40MODULE_FIRMWARE("radeon/R600_pfp.bin");
41MODULE_FIRMWARE("radeon/R600_me.bin");
42MODULE_FIRMWARE("radeon/RV610_pfp.bin");
43MODULE_FIRMWARE("radeon/RV610_me.bin");
44MODULE_FIRMWARE("radeon/RV630_pfp.bin");
45MODULE_FIRMWARE("radeon/RV630_me.bin");
46MODULE_FIRMWARE("radeon/RV620_pfp.bin");
47MODULE_FIRMWARE("radeon/RV620_me.bin");
48MODULE_FIRMWARE("radeon/RV635_pfp.bin");
49MODULE_FIRMWARE("radeon/RV635_me.bin");
50MODULE_FIRMWARE("radeon/RV670_pfp.bin");
51MODULE_FIRMWARE("radeon/RV670_me.bin");
52MODULE_FIRMWARE("radeon/RS780_pfp.bin");
53MODULE_FIRMWARE("radeon/RS780_me.bin");
54MODULE_FIRMWARE("radeon/RV770_pfp.bin");
55MODULE_FIRMWARE("radeon/RV770_me.bin");
56MODULE_FIRMWARE("radeon/RV730_pfp.bin");
57MODULE_FIRMWARE("radeon/RV730_me.bin");
58MODULE_FIRMWARE("radeon/RV710_pfp.bin");
59MODULE_FIRMWARE("radeon/RV710_me.bin");
60
61
62int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
63 unsigned family, u32 *ib, int *l);
64void r600_cs_legacy_init(void);
65
35 66
36# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ 67# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
37# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) 68# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
@@ -275,11 +306,93 @@ static void r600_vm_init(struct drm_device *dev)
275 r600_vm_flush_gart_range(dev); 306 r600_vm_flush_gart_range(dev);
276} 307}
277 308
278/* load r600 microcode */ 309static int r600_cp_init_microcode(drm_radeon_private_t *dev_priv)
310{
311 struct platform_device *pdev;
312 const char *chip_name;
313 size_t pfp_req_size, me_req_size;
314 char fw_name[30];
315 int err;
316
317 pdev = platform_device_register_simple("r600_cp", 0, NULL, 0);
318 err = IS_ERR(pdev);
319 if (err) {
320 printk(KERN_ERR "r600_cp: Failed to register firmware\n");
321 return -EINVAL;
322 }
323
324 switch (dev_priv->flags & RADEON_FAMILY_MASK) {
325 case CHIP_R600: chip_name = "R600"; break;
326 case CHIP_RV610: chip_name = "RV610"; break;
327 case CHIP_RV630: chip_name = "RV630"; break;
328 case CHIP_RV620: chip_name = "RV620"; break;
329 case CHIP_RV635: chip_name = "RV635"; break;
330 case CHIP_RV670: chip_name = "RV670"; break;
331 case CHIP_RS780:
332 case CHIP_RS880: chip_name = "RS780"; break;
333 case CHIP_RV770: chip_name = "RV770"; break;
334 case CHIP_RV730:
335 case CHIP_RV740: chip_name = "RV730"; break;
336 case CHIP_RV710: chip_name = "RV710"; break;
337 default: BUG();
338 }
339
340 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
341 pfp_req_size = R700_PFP_UCODE_SIZE * 4;
342 me_req_size = R700_PM4_UCODE_SIZE * 4;
343 } else {
344 pfp_req_size = PFP_UCODE_SIZE * 4;
345 me_req_size = PM4_UCODE_SIZE * 12;
346 }
347
348 DRM_INFO("Loading %s CP Microcode\n", chip_name);
349
350 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
351 err = request_firmware(&dev_priv->pfp_fw, fw_name, &pdev->dev);
352 if (err)
353 goto out;
354 if (dev_priv->pfp_fw->size != pfp_req_size) {
355 printk(KERN_ERR
356 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
357 dev_priv->pfp_fw->size, fw_name);
358 err = -EINVAL;
359 goto out;
360 }
361
362 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
363 err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev);
364 if (err)
365 goto out;
366 if (dev_priv->me_fw->size != me_req_size) {
367 printk(KERN_ERR
368 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
369 dev_priv->me_fw->size, fw_name);
370 err = -EINVAL;
371 }
372out:
373 platform_device_unregister(pdev);
374
375 if (err) {
376 if (err != -EINVAL)
377 printk(KERN_ERR
378 "r600_cp: Failed to load firmware \"%s\"\n",
379 fw_name);
380 release_firmware(dev_priv->pfp_fw);
381 dev_priv->pfp_fw = NULL;
382 release_firmware(dev_priv->me_fw);
383 dev_priv->me_fw = NULL;
384 }
385 return err;
386}
387
279static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) 388static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
280{ 389{
390 const __be32 *fw_data;
281 int i; 391 int i;
282 392
393 if (!dev_priv->me_fw || !dev_priv->pfp_fw)
394 return;
395
283 r600_do_cp_stop(dev_priv); 396 r600_do_cp_stop(dev_priv);
284 397
285 RADEON_WRITE(R600_CP_RB_CNTL, 398 RADEON_WRITE(R600_CP_RB_CNTL,
@@ -292,115 +405,18 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
292 DRM_UDELAY(15000); 405 DRM_UDELAY(15000);
293 RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 406 RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
294 407
408 fw_data = (const __be32 *)dev_priv->me_fw->data;
295 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 409 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
410 for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
411 RADEON_WRITE(R600_CP_ME_RAM_DATA,
412 be32_to_cpup(fw_data++));
296 413
297 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { 414 fw_data = (const __be32 *)dev_priv->pfp_fw->data;
298 DRM_INFO("Loading R600 CP Microcode\n"); 415 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
299 for (i = 0; i < PM4_UCODE_SIZE; i++) { 416 for (i = 0; i < PFP_UCODE_SIZE; i++)
300 RADEON_WRITE(R600_CP_ME_RAM_DATA, 417 RADEON_WRITE(R600_CP_PFP_UCODE_DATA,
301 R600_cp_microcode[i][0]); 418 be32_to_cpup(fw_data++));
302 RADEON_WRITE(R600_CP_ME_RAM_DATA,
303 R600_cp_microcode[i][1]);
304 RADEON_WRITE(R600_CP_ME_RAM_DATA,
305 R600_cp_microcode[i][2]);
306 }
307
308 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
309 DRM_INFO("Loading R600 PFP Microcode\n");
310 for (i = 0; i < PFP_UCODE_SIZE; i++)
311 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]);
312 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) {
313 DRM_INFO("Loading RV610 CP Microcode\n");
314 for (i = 0; i < PM4_UCODE_SIZE; i++) {
315 RADEON_WRITE(R600_CP_ME_RAM_DATA,
316 RV610_cp_microcode[i][0]);
317 RADEON_WRITE(R600_CP_ME_RAM_DATA,
318 RV610_cp_microcode[i][1]);
319 RADEON_WRITE(R600_CP_ME_RAM_DATA,
320 RV610_cp_microcode[i][2]);
321 }
322
323 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
324 DRM_INFO("Loading RV610 PFP Microcode\n");
325 for (i = 0; i < PFP_UCODE_SIZE; i++)
326 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]);
327 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
328 DRM_INFO("Loading RV630 CP Microcode\n");
329 for (i = 0; i < PM4_UCODE_SIZE; i++) {
330 RADEON_WRITE(R600_CP_ME_RAM_DATA,
331 RV630_cp_microcode[i][0]);
332 RADEON_WRITE(R600_CP_ME_RAM_DATA,
333 RV630_cp_microcode[i][1]);
334 RADEON_WRITE(R600_CP_ME_RAM_DATA,
335 RV630_cp_microcode[i][2]);
336 }
337
338 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
339 DRM_INFO("Loading RV630 PFP Microcode\n");
340 for (i = 0; i < PFP_UCODE_SIZE; i++)
341 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]);
342 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) {
343 DRM_INFO("Loading RV620 CP Microcode\n");
344 for (i = 0; i < PM4_UCODE_SIZE; i++) {
345 RADEON_WRITE(R600_CP_ME_RAM_DATA,
346 RV620_cp_microcode[i][0]);
347 RADEON_WRITE(R600_CP_ME_RAM_DATA,
348 RV620_cp_microcode[i][1]);
349 RADEON_WRITE(R600_CP_ME_RAM_DATA,
350 RV620_cp_microcode[i][2]);
351 }
352
353 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
354 DRM_INFO("Loading RV620 PFP Microcode\n");
355 for (i = 0; i < PFP_UCODE_SIZE; i++)
356 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]);
357 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
358 DRM_INFO("Loading RV635 CP Microcode\n");
359 for (i = 0; i < PM4_UCODE_SIZE; i++) {
360 RADEON_WRITE(R600_CP_ME_RAM_DATA,
361 RV635_cp_microcode[i][0]);
362 RADEON_WRITE(R600_CP_ME_RAM_DATA,
363 RV635_cp_microcode[i][1]);
364 RADEON_WRITE(R600_CP_ME_RAM_DATA,
365 RV635_cp_microcode[i][2]);
366 }
367
368 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
369 DRM_INFO("Loading RV635 PFP Microcode\n");
370 for (i = 0; i < PFP_UCODE_SIZE; i++)
371 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]);
372 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) {
373 DRM_INFO("Loading RV670 CP Microcode\n");
374 for (i = 0; i < PM4_UCODE_SIZE; i++) {
375 RADEON_WRITE(R600_CP_ME_RAM_DATA,
376 RV670_cp_microcode[i][0]);
377 RADEON_WRITE(R600_CP_ME_RAM_DATA,
378 RV670_cp_microcode[i][1]);
379 RADEON_WRITE(R600_CP_ME_RAM_DATA,
380 RV670_cp_microcode[i][2]);
381 }
382
383 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
384 DRM_INFO("Loading RV670 PFP Microcode\n");
385 for (i = 0; i < PFP_UCODE_SIZE; i++)
386 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
387 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
388 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) {
389 DRM_INFO("Loading RS780/RS880 CP Microcode\n");
390 for (i = 0; i < PM4_UCODE_SIZE; i++) {
391 RADEON_WRITE(R600_CP_ME_RAM_DATA,
392 RS780_cp_microcode[i][0]);
393 RADEON_WRITE(R600_CP_ME_RAM_DATA,
394 RS780_cp_microcode[i][1]);
395 RADEON_WRITE(R600_CP_ME_RAM_DATA,
396 RS780_cp_microcode[i][2]);
397 }
398 419
399 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
400 DRM_INFO("Loading RS780/RS880 PFP Microcode\n");
401 for (i = 0; i < PFP_UCODE_SIZE; i++)
402 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]);
403 }
404 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 420 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
405 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 421 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
406 RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 422 RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
@@ -459,11 +475,14 @@ static void r700_vm_init(struct drm_device *dev)
459 r600_vm_flush_gart_range(dev); 475 r600_vm_flush_gart_range(dev);
460} 476}
461 477
462/* load r600 microcode */
463static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) 478static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
464{ 479{
480 const __be32 *fw_data;
465 int i; 481 int i;
466 482
483 if (!dev_priv->me_fw || !dev_priv->pfp_fw)
484 return;
485
467 r600_do_cp_stop(dev_priv); 486 r600_do_cp_stop(dev_priv);
468 487
469 RADEON_WRITE(R600_CP_RB_CNTL, 488 RADEON_WRITE(R600_CP_RB_CNTL,
@@ -476,48 +495,18 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
476 DRM_UDELAY(15000); 495 DRM_UDELAY(15000);
477 RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); 496 RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
478 497
498 fw_data = (const __be32 *)dev_priv->pfp_fw->data;
499 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
500 for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
501 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
502 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
479 503
480 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { 504 fw_data = (const __be32 *)dev_priv->me_fw->data;
481 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 505 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
482 DRM_INFO("Loading RV770/RV790 PFP Microcode\n"); 506 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
483 for (i = 0; i < R700_PFP_UCODE_SIZE; i++) 507 RADEON_WRITE(R600_CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
484 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); 508 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
485 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
486
487 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
488 DRM_INFO("Loading RV770/RV790 CP Microcode\n");
489 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
490 RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]);
491 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
492
493 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730) ||
494 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)) {
495 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
496 DRM_INFO("Loading RV730/RV740 PFP Microcode\n");
497 for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
498 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]);
499 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
500
501 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
502 DRM_INFO("Loading RV730/RV740 CP Microcode\n");
503 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
504 RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]);
505 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
506
507 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) {
508 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
509 DRM_INFO("Loading RV710 PFP Microcode\n");
510 for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
511 RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]);
512 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
513
514 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
515 DRM_INFO("Loading RV710 CP Microcode\n");
516 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
517 RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]);
518 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
519 509
520 }
521 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); 510 RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
522 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); 511 RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
523 RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); 512 RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
@@ -1874,6 +1863,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
1874 1863
1875 DRM_DEBUG("\n"); 1864 DRM_DEBUG("\n");
1876 1865
1866 mutex_init(&dev_priv->cs_mutex);
1867 r600_cs_legacy_init();
1877 /* if we require new memory map but we don't have it fail */ 1868 /* if we require new memory map but we don't have it fail */
1878 if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { 1869 if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
1879 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); 1870 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
@@ -1905,7 +1896,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
1905 /* Enable vblank on CRTC1 for older X servers 1896 /* Enable vblank on CRTC1 for older X servers
1906 */ 1897 */
1907 dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; 1898 dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
1908 1899 dev_priv->do_boxes = 0;
1909 dev_priv->cp_mode = init->cp_mode; 1900 dev_priv->cp_mode = init->cp_mode;
1910 1901
1911 /* We don't support anything other than bus-mastering ring mode, 1902 /* We don't support anything other than bus-mastering ring mode,
@@ -1991,11 +1982,11 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
1991 } else 1982 } else
1992#endif 1983#endif
1993 { 1984 {
1994 dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; 1985 dev_priv->cp_ring->handle = (void *)(unsigned long)dev_priv->cp_ring->offset;
1995 dev_priv->ring_rptr->handle = 1986 dev_priv->ring_rptr->handle =
1996 (void *)dev_priv->ring_rptr->offset; 1987 (void *)(unsigned long)dev_priv->ring_rptr->offset;
1997 dev->agp_buffer_map->handle = 1988 dev->agp_buffer_map->handle =
1998 (void *)dev->agp_buffer_map->offset; 1989 (void *)(unsigned long)dev->agp_buffer_map->offset;
1999 1990
2000 DRM_DEBUG("dev_priv->cp_ring->handle %p\n", 1991 DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
2001 dev_priv->cp_ring->handle); 1992 dev_priv->cp_ring->handle);
@@ -2147,6 +2138,14 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
2147 r600_vm_init(dev); 2138 r600_vm_init(dev);
2148 } 2139 }
2149 2140
2141 if (!dev_priv->me_fw || !dev_priv->pfp_fw) {
2142 int err = r600_cp_init_microcode(dev_priv);
2143 if (err) {
2144 DRM_ERROR("Failed to load firmware!\n");
2145 r600_do_cleanup_cp(dev);
2146 return err;
2147 }
2148 }
2150 if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) 2149 if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
2151 r700_cp_load_microcode(dev_priv); 2150 r700_cp_load_microcode(dev_priv);
2152 else 2151 else
@@ -2291,3 +2290,239 @@ int r600_cp_dispatch_indirect(struct drm_device *dev,
2291 2290
2292 return 0; 2291 return 0;
2293} 2292}
2293
2294void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv)
2295{
2296 drm_radeon_private_t *dev_priv = dev->dev_private;
2297 struct drm_master *master = file_priv->master;
2298 struct drm_radeon_master_private *master_priv = master->driver_priv;
2299 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
2300 int nbox = sarea_priv->nbox;
2301 struct drm_clip_rect *pbox = sarea_priv->boxes;
2302 int i, cpp, src_pitch, dst_pitch;
2303 uint64_t src, dst;
2304 RING_LOCALS;
2305 DRM_DEBUG("\n");
2306
2307 if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888)
2308 cpp = 4;
2309 else
2310 cpp = 2;
2311
2312 if (sarea_priv->pfCurrentPage == 0) {
2313 src_pitch = dev_priv->back_pitch;
2314 dst_pitch = dev_priv->front_pitch;
2315 src = dev_priv->back_offset + dev_priv->fb_location;
2316 dst = dev_priv->front_offset + dev_priv->fb_location;
2317 } else {
2318 src_pitch = dev_priv->front_pitch;
2319 dst_pitch = dev_priv->back_pitch;
2320 src = dev_priv->front_offset + dev_priv->fb_location;
2321 dst = dev_priv->back_offset + dev_priv->fb_location;
2322 }
2323
2324 if (r600_prepare_blit_copy(dev, file_priv)) {
2325 DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
2326 return;
2327 }
2328 for (i = 0; i < nbox; i++) {
2329 int x = pbox[i].x1;
2330 int y = pbox[i].y1;
2331 int w = pbox[i].x2 - x;
2332 int h = pbox[i].y2 - y;
2333
2334 DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
2335
2336 r600_blit_swap(dev,
2337 src, dst,
2338 x, y, x, y, w, h,
2339 src_pitch, dst_pitch, cpp);
2340 }
2341 r600_done_blit_copy(dev);
2342
2343 /* Increment the frame counter. The client-side 3D driver must
2344 * throttle the framerate by waiting for this value before
2345 * performing the swapbuffer ioctl.
2346 */
2347 sarea_priv->last_frame++;
2348
2349 BEGIN_RING(3);
2350 R600_FRAME_AGE(sarea_priv->last_frame);
2351 ADVANCE_RING();
2352}
2353
2354int r600_cp_dispatch_texture(struct drm_device *dev,
2355 struct drm_file *file_priv,
2356 drm_radeon_texture_t *tex,
2357 drm_radeon_tex_image_t *image)
2358{
2359 drm_radeon_private_t *dev_priv = dev->dev_private;
2360 struct drm_buf *buf;
2361 u32 *buffer;
2362 const u8 __user *data;
2363 int size, pass_size;
2364 u64 src_offset, dst_offset;
2365
2366 if (!radeon_check_offset(dev_priv, tex->offset)) {
2367 DRM_ERROR("Invalid destination offset\n");
2368 return -EINVAL;
2369 }
2370
2371 /* this might fail for zero-sized uploads - are those illegal? */
2372 if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) {
2373 DRM_ERROR("Invalid final destination offset\n");
2374 return -EINVAL;
2375 }
2376
2377 size = tex->height * tex->pitch;
2378
2379 if (size == 0)
2380 return 0;
2381
2382 dst_offset = tex->offset;
2383
2384 if (r600_prepare_blit_copy(dev, file_priv)) {
2385 DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
2386 return -EAGAIN;
2387 }
2388 do {
2389 data = (const u8 __user *)image->data;
2390 pass_size = size;
2391
2392 buf = radeon_freelist_get(dev);
2393 if (!buf) {
2394 DRM_DEBUG("EAGAIN\n");
2395 if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
2396 return -EFAULT;
2397 return -EAGAIN;
2398 }
2399
2400 if (pass_size > buf->total)
2401 pass_size = buf->total;
2402
2403 /* Dispatch the indirect buffer.
2404 */
2405 buffer =
2406 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
2407
2408 if (DRM_COPY_FROM_USER(buffer, data, pass_size)) {
2409 DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size);
2410 return -EFAULT;
2411 }
2412
2413 buf->file_priv = file_priv;
2414 buf->used = pass_size;
2415 src_offset = dev_priv->gart_buffers_offset + buf->offset;
2416
2417 r600_blit_copy(dev, src_offset, dst_offset, pass_size);
2418
2419 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2420
2421 /* Update the input parameters for next time */
2422 image->data = (const u8 __user *)image->data + pass_size;
2423 dst_offset += pass_size;
2424 size -= pass_size;
2425 } while (size > 0);
2426 r600_done_blit_copy(dev);
2427
2428 return 0;
2429}
2430
2431/*
2432 * Legacy cs ioctl
2433 */
2434static u32 radeon_cs_id_get(struct drm_radeon_private *radeon)
2435{
2436 /* FIXME: check if wrap affect last reported wrap & sequence */
2437 radeon->cs_id_scnt = (radeon->cs_id_scnt + 1) & 0x00FFFFFF;
2438 if (!radeon->cs_id_scnt) {
2439 /* increment wrap counter */
2440 radeon->cs_id_wcnt += 0x01000000;
2441 /* valid sequence counter start at 1 */
2442 radeon->cs_id_scnt = 1;
2443 }
2444 return (radeon->cs_id_scnt | radeon->cs_id_wcnt);
2445}
2446
2447static void r600_cs_id_emit(drm_radeon_private_t *dev_priv, u32 *id)
2448{
2449 RING_LOCALS;
2450
2451 *id = radeon_cs_id_get(dev_priv);
2452
2453 /* SCRATCH 2 */
2454 BEGIN_RING(3);
2455 R600_CLEAR_AGE(*id);
2456 ADVANCE_RING();
2457 COMMIT_RING();
2458}
2459
2460static int r600_ib_get(struct drm_device *dev,
2461 struct drm_file *fpriv,
2462 struct drm_buf **buffer)
2463{
2464 struct drm_buf *buf;
2465
2466 *buffer = NULL;
2467 buf = radeon_freelist_get(dev);
2468 if (!buf) {
2469 return -EBUSY;
2470 }
2471 buf->file_priv = fpriv;
2472 *buffer = buf;
2473 return 0;
2474}
2475
2476static void r600_ib_free(struct drm_device *dev, struct drm_buf *buf,
2477 struct drm_file *fpriv, int l, int r)
2478{
2479 drm_radeon_private_t *dev_priv = dev->dev_private;
2480
2481 if (buf) {
2482 if (!r)
2483 r600_cp_dispatch_indirect(dev, buf, 0, l * 4);
2484 radeon_cp_discard_buffer(dev, fpriv->master, buf);
2485 COMMIT_RING();
2486 }
2487}
2488
2489int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
2490{
2491 struct drm_radeon_private *dev_priv = dev->dev_private;
2492 struct drm_radeon_cs *cs = data;
2493 struct drm_buf *buf;
2494 unsigned family;
2495 int l, r = 0;
2496 u32 *ib, cs_id = 0;
2497
2498 if (dev_priv == NULL) {
2499 DRM_ERROR("called with no initialization\n");
2500 return -EINVAL;
2501 }
2502 family = dev_priv->flags & RADEON_FAMILY_MASK;
2503 if (family < CHIP_R600) {
2504 DRM_ERROR("cs ioctl valid only for R6XX & R7XX in legacy mode\n");
2505 return -EINVAL;
2506 }
2507 mutex_lock(&dev_priv->cs_mutex);
2508 /* get ib */
2509 r = r600_ib_get(dev, fpriv, &buf);
2510 if (r) {
2511 DRM_ERROR("ib_get failed\n");
2512 goto out;
2513 }
2514 ib = dev->agp_buffer_map->handle + buf->offset;
2515 /* now parse command stream */
2516 r = r600_cs_legacy(dev, data, fpriv, family, ib, &l);
2517 if (r) {
2518 goto out;
2519 }
2520
2521out:
2522 r600_ib_free(dev, buf, fpriv, l, r);
2523 /* emit cs id sequence */
2524 r600_cs_id_emit(dev_priv, &cs_id);
2525 cs->cs_id = cs_id;
2526 mutex_unlock(&dev_priv->cs_mutex);
2527 return r;
2528}
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
new file mode 100644
index 000000000000..33b89cd8743e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -0,0 +1,657 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include "drmP.h"
29#include "radeon.h"
30#include "r600d.h"
31#include "avivod.h"
32
33static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
34 struct radeon_cs_reloc **cs_reloc);
35static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
36 struct radeon_cs_reloc **cs_reloc);
37typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
38static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
39
40/**
41 * r600_cs_packet_parse() - parse cp packet and point ib index to next packet
42 * @parser: parser structure holding parsing context.
43 * @pkt: where to store packet informations
44 *
45 * Assume that chunk_ib_index is properly set. Will return -EINVAL
46 * if packet is bigger than remaining ib size. or if packets is unknown.
47 **/
48int r600_cs_packet_parse(struct radeon_cs_parser *p,
49 struct radeon_cs_packet *pkt,
50 unsigned idx)
51{
52 struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
53 uint32_t header;
54
55 if (idx >= ib_chunk->length_dw) {
56 DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
57 idx, ib_chunk->length_dw);
58 return -EINVAL;
59 }
60 header = ib_chunk->kdata[idx];
61 pkt->idx = idx;
62 pkt->type = CP_PACKET_GET_TYPE(header);
63 pkt->count = CP_PACKET_GET_COUNT(header);
64 pkt->one_reg_wr = 0;
65 switch (pkt->type) {
66 case PACKET_TYPE0:
67 pkt->reg = CP_PACKET0_GET_REG(header);
68 break;
69 case PACKET_TYPE3:
70 pkt->opcode = CP_PACKET3_GET_OPCODE(header);
71 break;
72 case PACKET_TYPE2:
73 pkt->count = -1;
74 break;
75 default:
76 DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
77 return -EINVAL;
78 }
79 if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
80 DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
81 pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
82 return -EINVAL;
83 }
84 return 0;
85}
86
87/**
88 * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3
89 * @parser: parser structure holding parsing context.
90 * @data: pointer to relocation data
91 * @offset_start: starting offset
92 * @offset_mask: offset mask (to align start offset on)
93 * @reloc: reloc informations
94 *
95 * Check next packet is relocation packet3, do bo validation and compute
96 * GPU offset using the provided start.
97 **/
98static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
99 struct radeon_cs_reloc **cs_reloc)
100{
101 struct radeon_cs_chunk *ib_chunk;
102 struct radeon_cs_chunk *relocs_chunk;
103 struct radeon_cs_packet p3reloc;
104 unsigned idx;
105 int r;
106
107 if (p->chunk_relocs_idx == -1) {
108 DRM_ERROR("No relocation chunk !\n");
109 return -EINVAL;
110 }
111 *cs_reloc = NULL;
112 ib_chunk = &p->chunks[p->chunk_ib_idx];
113 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
114 r = r600_cs_packet_parse(p, &p3reloc, p->idx);
115 if (r) {
116 return r;
117 }
118 p->idx += p3reloc.count + 2;
119 if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
120 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
121 p3reloc.idx);
122 return -EINVAL;
123 }
124 idx = ib_chunk->kdata[p3reloc.idx + 1];
125 if (idx >= relocs_chunk->length_dw) {
126 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
127 idx, relocs_chunk->length_dw);
128 return -EINVAL;
129 }
130 /* FIXME: we assume reloc size is 4 dwords */
131 *cs_reloc = p->relocs_ptr[(idx / 4)];
132 return 0;
133}
134
135/**
136 * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3
137 * @parser: parser structure holding parsing context.
138 * @data: pointer to relocation data
139 * @offset_start: starting offset
140 * @offset_mask: offset mask (to align start offset on)
141 * @reloc: reloc informations
142 *
143 * Check next packet is relocation packet3, do bo validation and compute
144 * GPU offset using the provided start.
145 **/
146static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
147 struct radeon_cs_reloc **cs_reloc)
148{
149 struct radeon_cs_chunk *ib_chunk;
150 struct radeon_cs_chunk *relocs_chunk;
151 struct radeon_cs_packet p3reloc;
152 unsigned idx;
153 int r;
154
155 if (p->chunk_relocs_idx == -1) {
156 DRM_ERROR("No relocation chunk !\n");
157 return -EINVAL;
158 }
159 *cs_reloc = NULL;
160 ib_chunk = &p->chunks[p->chunk_ib_idx];
161 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
162 r = r600_cs_packet_parse(p, &p3reloc, p->idx);
163 if (r) {
164 return r;
165 }
166 p->idx += p3reloc.count + 2;
167 if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
168 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
169 p3reloc.idx);
170 return -EINVAL;
171 }
172 idx = ib_chunk->kdata[p3reloc.idx + 1];
173 if (idx >= relocs_chunk->length_dw) {
174 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
175 idx, relocs_chunk->length_dw);
176 return -EINVAL;
177 }
178 *cs_reloc = &p->relocs[0];
179 (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32;
180 (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0];
181 return 0;
182}
183
184static int r600_packet0_check(struct radeon_cs_parser *p,
185 struct radeon_cs_packet *pkt,
186 unsigned idx, unsigned reg)
187{
188 switch (reg) {
189 case AVIVO_D1MODE_VLINE_START_END:
190 case AVIVO_D2MODE_VLINE_START_END:
191 break;
192 default:
193 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
194 reg, idx);
195 return -EINVAL;
196 }
197 return 0;
198}
199
200static int r600_cs_parse_packet0(struct radeon_cs_parser *p,
201 struct radeon_cs_packet *pkt)
202{
203 unsigned reg, i;
204 unsigned idx;
205 int r;
206
207 idx = pkt->idx + 1;
208 reg = pkt->reg;
209 for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
210 r = r600_packet0_check(p, pkt, idx, reg);
211 if (r) {
212 return r;
213 }
214 }
215 return 0;
216}
217
218static int r600_packet3_check(struct radeon_cs_parser *p,
219 struct radeon_cs_packet *pkt)
220{
221 struct radeon_cs_chunk *ib_chunk;
222 struct radeon_cs_reloc *reloc;
223 volatile u32 *ib;
224 unsigned idx;
225 unsigned i;
226 unsigned start_reg, end_reg, reg;
227 int r;
228
229 ib = p->ib->ptr;
230 ib_chunk = &p->chunks[p->chunk_ib_idx];
231 idx = pkt->idx + 1;
232 switch (pkt->opcode) {
233 case PACKET3_START_3D_CMDBUF:
234 if (p->family >= CHIP_RV770 || pkt->count) {
235 DRM_ERROR("bad START_3D\n");
236 return -EINVAL;
237 }
238 break;
239 case PACKET3_CONTEXT_CONTROL:
240 if (pkt->count != 1) {
241 DRM_ERROR("bad CONTEXT_CONTROL\n");
242 return -EINVAL;
243 }
244 break;
245 case PACKET3_INDEX_TYPE:
246 case PACKET3_NUM_INSTANCES:
247 if (pkt->count) {
248 DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n");
249 return -EINVAL;
250 }
251 break;
252 case PACKET3_DRAW_INDEX:
253 if (pkt->count != 3) {
254 DRM_ERROR("bad DRAW_INDEX\n");
255 return -EINVAL;
256 }
257 r = r600_cs_packet_next_reloc(p, &reloc);
258 if (r) {
259 DRM_ERROR("bad DRAW_INDEX\n");
260 return -EINVAL;
261 }
262 ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
263 ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
264 break;
265 case PACKET3_DRAW_INDEX_AUTO:
266 if (pkt->count != 1) {
267 DRM_ERROR("bad DRAW_INDEX_AUTO\n");
268 return -EINVAL;
269 }
270 break;
271 case PACKET3_DRAW_INDEX_IMMD_BE:
272 case PACKET3_DRAW_INDEX_IMMD:
273 if (pkt->count < 2) {
274 DRM_ERROR("bad DRAW_INDEX_IMMD\n");
275 return -EINVAL;
276 }
277 break;
278 case PACKET3_WAIT_REG_MEM:
279 if (pkt->count != 5) {
280 DRM_ERROR("bad WAIT_REG_MEM\n");
281 return -EINVAL;
282 }
283 /* bit 4 is reg (0) or mem (1) */
284 if (ib_chunk->kdata[idx+0] & 0x10) {
285 r = r600_cs_packet_next_reloc(p, &reloc);
286 if (r) {
287 DRM_ERROR("bad WAIT_REG_MEM\n");
288 return -EINVAL;
289 }
290 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
291 ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
292 }
293 break;
294 case PACKET3_SURFACE_SYNC:
295 if (pkt->count != 3) {
296 DRM_ERROR("bad SURFACE_SYNC\n");
297 return -EINVAL;
298 }
299 /* 0xffffffff/0x0 is flush all cache flag */
300 if (ib_chunk->kdata[idx+1] != 0xffffffff ||
301 ib_chunk->kdata[idx+2] != 0) {
302 r = r600_cs_packet_next_reloc(p, &reloc);
303 if (r) {
304 DRM_ERROR("bad SURFACE_SYNC\n");
305 return -EINVAL;
306 }
307 ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
308 }
309 break;
310 case PACKET3_EVENT_WRITE:
311 if (pkt->count != 2 && pkt->count != 0) {
312 DRM_ERROR("bad EVENT_WRITE\n");
313 return -EINVAL;
314 }
315 if (pkt->count) {
316 r = r600_cs_packet_next_reloc(p, &reloc);
317 if (r) {
318 DRM_ERROR("bad EVENT_WRITE\n");
319 return -EINVAL;
320 }
321 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
322 ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
323 }
324 break;
325 case PACKET3_EVENT_WRITE_EOP:
326 if (pkt->count != 4) {
327 DRM_ERROR("bad EVENT_WRITE_EOP\n");
328 return -EINVAL;
329 }
330 r = r600_cs_packet_next_reloc(p, &reloc);
331 if (r) {
332 DRM_ERROR("bad EVENT_WRITE\n");
333 return -EINVAL;
334 }
335 ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
336 ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
337 break;
338 case PACKET3_SET_CONFIG_REG:
339 start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET;
340 end_reg = 4 * pkt->count + start_reg - 4;
341 if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) ||
342 (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
343 (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
344 DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
345 return -EINVAL;
346 }
347 for (i = 0; i < pkt->count; i++) {
348 reg = start_reg + (4 * i);
349 switch (reg) {
350 case CP_COHER_BASE:
351 /* use PACKET3_SURFACE_SYNC */
352 return -EINVAL;
353 default:
354 break;
355 }
356 }
357 break;
358 case PACKET3_SET_CONTEXT_REG:
359 start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET;
360 end_reg = 4 * pkt->count + start_reg - 4;
361 if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) ||
362 (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
363 (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
364 DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
365 return -EINVAL;
366 }
367 for (i = 0; i < pkt->count; i++) {
368 reg = start_reg + (4 * i);
369 switch (reg) {
370 case DB_DEPTH_BASE:
371 case CB_COLOR0_BASE:
372 case CB_COLOR1_BASE:
373 case CB_COLOR2_BASE:
374 case CB_COLOR3_BASE:
375 case CB_COLOR4_BASE:
376 case CB_COLOR5_BASE:
377 case CB_COLOR6_BASE:
378 case CB_COLOR7_BASE:
379 case SQ_PGM_START_FS:
380 case SQ_PGM_START_ES:
381 case SQ_PGM_START_VS:
382 case SQ_PGM_START_GS:
383 case SQ_PGM_START_PS:
384 r = r600_cs_packet_next_reloc(p, &reloc);
385 if (r) {
386 DRM_ERROR("bad SET_CONTEXT_REG "
387 "0x%04X\n", reg);
388 return -EINVAL;
389 }
390 ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
391 break;
392 case VGT_DMA_BASE:
393 case VGT_DMA_BASE_HI:
394 /* These should be handled by DRAW_INDEX packet 3 */
395 case VGT_STRMOUT_BASE_OFFSET_0:
396 case VGT_STRMOUT_BASE_OFFSET_1:
397 case VGT_STRMOUT_BASE_OFFSET_2:
398 case VGT_STRMOUT_BASE_OFFSET_3:
399 case VGT_STRMOUT_BASE_OFFSET_HI_0:
400 case VGT_STRMOUT_BASE_OFFSET_HI_1:
401 case VGT_STRMOUT_BASE_OFFSET_HI_2:
402 case VGT_STRMOUT_BASE_OFFSET_HI_3:
403 case VGT_STRMOUT_BUFFER_BASE_0:
404 case VGT_STRMOUT_BUFFER_BASE_1:
405 case VGT_STRMOUT_BUFFER_BASE_2:
406 case VGT_STRMOUT_BUFFER_BASE_3:
407 case VGT_STRMOUT_BUFFER_OFFSET_0:
408 case VGT_STRMOUT_BUFFER_OFFSET_1:
409 case VGT_STRMOUT_BUFFER_OFFSET_2:
410 case VGT_STRMOUT_BUFFER_OFFSET_3:
411 /* These should be handled by STRMOUT_BUFFER packet 3 */
412 DRM_ERROR("bad context reg: 0x%08x\n", reg);
413 return -EINVAL;
414 default:
415 break;
416 }
417 }
418 break;
419 case PACKET3_SET_RESOURCE:
420 if (pkt->count % 7) {
421 DRM_ERROR("bad SET_RESOURCE\n");
422 return -EINVAL;
423 }
424 start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET;
425 end_reg = 4 * pkt->count + start_reg - 4;
426 if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) ||
427 (start_reg >= PACKET3_SET_RESOURCE_END) ||
428 (end_reg >= PACKET3_SET_RESOURCE_END)) {
429 DRM_ERROR("bad SET_RESOURCE\n");
430 return -EINVAL;
431 }
432 for (i = 0; i < (pkt->count / 7); i++) {
433 switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) {
434 case SQ_TEX_VTX_VALID_TEXTURE:
435 /* tex base */
436 r = r600_cs_packet_next_reloc(p, &reloc);
437 if (r) {
438 DRM_ERROR("bad SET_RESOURCE\n");
439 return -EINVAL;
440 }
441 ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
442 /* tex mip base */
443 r = r600_cs_packet_next_reloc(p, &reloc);
444 if (r) {
445 DRM_ERROR("bad SET_RESOURCE\n");
446 return -EINVAL;
447 }
448 ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
449 break;
450 case SQ_TEX_VTX_VALID_BUFFER:
451 /* vtx base */
452 r = r600_cs_packet_next_reloc(p, &reloc);
453 if (r) {
454 DRM_ERROR("bad SET_RESOURCE\n");
455 return -EINVAL;
456 }
457 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
458 ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
459 break;
460 case SQ_TEX_VTX_INVALID_TEXTURE:
461 case SQ_TEX_VTX_INVALID_BUFFER:
462 default:
463 DRM_ERROR("bad SET_RESOURCE\n");
464 return -EINVAL;
465 }
466 }
467 break;
468 case PACKET3_SET_ALU_CONST:
469 start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET;
470 end_reg = 4 * pkt->count + start_reg - 4;
471 if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
472 (start_reg >= PACKET3_SET_ALU_CONST_END) ||
473 (end_reg >= PACKET3_SET_ALU_CONST_END)) {
474 DRM_ERROR("bad SET_ALU_CONST\n");
475 return -EINVAL;
476 }
477 break;
478 case PACKET3_SET_BOOL_CONST:
479 start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET;
480 end_reg = 4 * pkt->count + start_reg - 4;
481 if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) ||
482 (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
483 (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
484 DRM_ERROR("bad SET_BOOL_CONST\n");
485 return -EINVAL;
486 }
487 break;
488 case PACKET3_SET_LOOP_CONST:
489 start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET;
490 end_reg = 4 * pkt->count + start_reg - 4;
491 if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) ||
492 (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
493 (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
494 DRM_ERROR("bad SET_LOOP_CONST\n");
495 return -EINVAL;
496 }
497 break;
498 case PACKET3_SET_CTL_CONST:
499 start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET;
500 end_reg = 4 * pkt->count + start_reg - 4;
501 if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) ||
502 (start_reg >= PACKET3_SET_CTL_CONST_END) ||
503 (end_reg >= PACKET3_SET_CTL_CONST_END)) {
504 DRM_ERROR("bad SET_CTL_CONST\n");
505 return -EINVAL;
506 }
507 break;
508 case PACKET3_SET_SAMPLER:
509 if (pkt->count % 3) {
510 DRM_ERROR("bad SET_SAMPLER\n");
511 return -EINVAL;
512 }
513 start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET;
514 end_reg = 4 * pkt->count + start_reg - 4;
515 if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) ||
516 (start_reg >= PACKET3_SET_SAMPLER_END) ||
517 (end_reg >= PACKET3_SET_SAMPLER_END)) {
518 DRM_ERROR("bad SET_SAMPLER\n");
519 return -EINVAL;
520 }
521 break;
522 case PACKET3_SURFACE_BASE_UPDATE:
523 if (p->family >= CHIP_RV770 || p->family == CHIP_R600) {
524 DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
525 return -EINVAL;
526 }
527 if (pkt->count) {
528 DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
529 return -EINVAL;
530 }
531 break;
532 case PACKET3_NOP:
533 break;
534 default:
535 DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
536 return -EINVAL;
537 }
538 return 0;
539}
540
541int r600_cs_parse(struct radeon_cs_parser *p)
542{
543 struct radeon_cs_packet pkt;
544 int r;
545
546 do {
547 r = r600_cs_packet_parse(p, &pkt, p->idx);
548 if (r) {
549 return r;
550 }
551 p->idx += pkt.count + 2;
552 switch (pkt.type) {
553 case PACKET_TYPE0:
554 r = r600_cs_parse_packet0(p, &pkt);
555 break;
556 case PACKET_TYPE2:
557 break;
558 case PACKET_TYPE3:
559 r = r600_packet3_check(p, &pkt);
560 break;
561 default:
562 DRM_ERROR("Unknown packet type %d !\n", pkt.type);
563 return -EINVAL;
564 }
565 if (r) {
566 return r;
567 }
568 } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
569#if 0
570 for (r = 0; r < p->ib->length_dw; r++) {
571 printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]);
572 mdelay(1);
573 }
574#endif
575 return 0;
576}
577
578static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p)
579{
580 if (p->chunk_relocs_idx == -1) {
581 return 0;
582 }
583 p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
584 if (p->relocs == NULL) {
585 return -ENOMEM;
586 }
587 return 0;
588}
589
590/**
591 * cs_parser_fini() - clean parser states
592 * @parser: parser structure holding parsing context.
593 * @error: error number
594 *
595 * If error is set than unvalidate buffer, otherwise just free memory
596 * used by parsing context.
597 **/
598static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
599{
600 unsigned i;
601
602 kfree(parser->relocs);
603 for (i = 0; i < parser->nchunks; i++) {
604 kfree(parser->chunks[i].kdata);
605 }
606 kfree(parser->chunks);
607 kfree(parser->chunks_array);
608}
609
610int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
611 unsigned family, u32 *ib, int *l)
612{
613 struct radeon_cs_parser parser;
614 struct radeon_cs_chunk *ib_chunk;
615 struct radeon_ib fake_ib;
616 int r;
617
618 /* initialize parser */
619 memset(&parser, 0, sizeof(struct radeon_cs_parser));
620 parser.filp = filp;
621 parser.rdev = NULL;
622 parser.family = family;
623 parser.ib = &fake_ib;
624 fake_ib.ptr = ib;
625 r = radeon_cs_parser_init(&parser, data);
626 if (r) {
627 DRM_ERROR("Failed to initialize parser !\n");
628 r600_cs_parser_fini(&parser, r);
629 return r;
630 }
631 r = r600_cs_parser_relocs_legacy(&parser);
632 if (r) {
633 DRM_ERROR("Failed to parse relocation !\n");
634 r600_cs_parser_fini(&parser, r);
635 return r;
636 }
637 /* Copy the packet into the IB, the parser will read from the
638 * input memory (cached) and write to the IB (which can be
639 * uncached). */
640 ib_chunk = &parser.chunks[parser.chunk_ib_idx];
641 parser.ib->length_dw = ib_chunk->length_dw;
642 memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4);
643 *l = parser.ib->length_dw;
644 r = r600_cs_parse(&parser);
645 if (r) {
646 DRM_ERROR("Invalid command stream !\n");
647 r600_cs_parser_fini(&parser, r);
648 return r;
649 }
650 r600_cs_parser_fini(&parser, r);
651 return r;
652}
653
654void r600_cs_legacy_init(void)
655{
656 r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm;
657}
diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h
deleted file mode 100644
index 778c8b4b2fd9..000000000000
--- a/drivers/gpu/drm/radeon/r600_microcode.h
+++ /dev/null
@@ -1,23297 +0,0 @@
1/*
2 * Copyright 2008-2009 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#ifndef R600_MICROCODE_H
27#define R600_MICROCODE_H
28
29static const int ME_JUMP_TABLE_START = 1764;
30static const int ME_JUMP_TABLE_END = 1792;
31
32#define PFP_UCODE_SIZE 576
33#define PM4_UCODE_SIZE 1792
34#define R700_PFP_UCODE_SIZE 848
35#define R700_PM4_UCODE_SIZE 1360
36
37static const u32 R600_cp_microcode[][3] = {
38 { 0x00000000, 0xc0200400, 0x000 },
39 { 0x00000000, 0x00a0000a, 0x000 },
40 { 0x0000ffff, 0x00284621, 0x000 },
41 { 0x00000000, 0xd9004800, 0x000 },
42 { 0x00000000, 0xc0200400, 0x000 },
43 { 0x00000000, 0x00a0000a, 0x000 },
44 { 0x00000000, 0x00e00000, 0x000 },
45 { 0x00010000, 0xc0294620, 0x000 },
46 { 0x00000000, 0xd9004800, 0x000 },
47 { 0x00000000, 0xc0200400, 0x000 },
48 { 0x00000000, 0x00a0000a, 0x000 },
49 { 0x81000000, 0x00204411, 0x000 },
50 { 0x00000001, 0x00204811, 0x000 },
51 { 0x00042004, 0x00604411, 0x614 },
52 { 0x00000000, 0x00600000, 0x5b2 },
53 { 0x00000000, 0x00600000, 0x5c5 },
54 { 0x00000000, 0xc0200800, 0x000 },
55 { 0x00000f00, 0x00281622, 0x000 },
56 { 0x00000008, 0x00211625, 0x000 },
57 { 0x00000020, 0x00203625, 0x000 },
58 { 0x8d000000, 0x00204411, 0x000 },
59 { 0x00000004, 0x002f0225, 0x000 },
60 { 0x00000000, 0x0ce00000, 0x018 },
61 { 0x00412000, 0x00404811, 0x019 },
62 { 0x00422000, 0x00204811, 0x000 },
63 { 0x8e000000, 0x00204411, 0x000 },
64 { 0x00000031, 0x00204a2d, 0x000 },
65 { 0x90000000, 0x00204411, 0x000 },
66 { 0x00000000, 0x00204805, 0x000 },
67 { 0x0000000c, 0x00211622, 0x000 },
68 { 0x00000003, 0x00281625, 0x000 },
69 { 0x00000019, 0x00211a22, 0x000 },
70 { 0x00000004, 0x00281a26, 0x000 },
71 { 0x00000000, 0x002914c5, 0x000 },
72 { 0x00000021, 0x00203625, 0x000 },
73 { 0x00000000, 0x003a1402, 0x000 },
74 { 0x00000016, 0x00211625, 0x000 },
75 { 0x00000003, 0x00281625, 0x000 },
76 { 0x0000001d, 0x00200e2d, 0x000 },
77 { 0xfffffffc, 0x00280e23, 0x000 },
78 { 0x00000000, 0x002914a3, 0x000 },
79 { 0x0000001d, 0x00203625, 0x000 },
80 { 0x00008000, 0x00280e22, 0x000 },
81 { 0x00000007, 0x00220e23, 0x000 },
82 { 0x00000000, 0x0029386e, 0x000 },
83 { 0x20000000, 0x00280e22, 0x000 },
84 { 0x00000006, 0x00210e23, 0x000 },
85 { 0x00000000, 0x0029386e, 0x000 },
86 { 0x00000000, 0x00220222, 0x000 },
87 { 0x00000000, 0x14e00000, 0x038 },
88 { 0x00000000, 0x2ee00000, 0x035 },
89 { 0x00000000, 0x2ce00000, 0x037 },
90 { 0x00000000, 0x00400e2d, 0x039 },
91 { 0x00000008, 0x00200e2d, 0x000 },
92 { 0x00000009, 0x0040122d, 0x046 },
93 { 0x00000001, 0x00400e2d, 0x039 },
94 { 0x00000000, 0xc0200c00, 0x000 },
95 { 0x003ffffc, 0x00281223, 0x000 },
96 { 0x00000002, 0x00221224, 0x000 },
97 { 0x0000001f, 0x00211e23, 0x000 },
98 { 0x00000000, 0x14e00000, 0x03e },
99 { 0x00000008, 0x00401c11, 0x041 },
100 { 0x0000000d, 0x00201e2d, 0x000 },
101 { 0x0000000f, 0x00281e27, 0x000 },
102 { 0x00000003, 0x00221e27, 0x000 },
103 { 0x7fc00000, 0x00281a23, 0x000 },
104 { 0x00000014, 0x00211a26, 0x000 },
105 { 0x00000001, 0x00331a26, 0x000 },
106 { 0x00000008, 0x00221a26, 0x000 },
107 { 0x00000000, 0x00290cc7, 0x000 },
108 { 0x00000030, 0x00203624, 0x000 },
109 { 0x00007f00, 0x00281221, 0x000 },
110 { 0x00001400, 0x002f0224, 0x000 },
111 { 0x00000000, 0x0ce00000, 0x04b },
112 { 0x00000001, 0x00290e23, 0x000 },
113 { 0x00000010, 0x00203623, 0x000 },
114 { 0x0000e000, 0x00204411, 0x000 },
115 { 0xfff80000, 0x00294a23, 0x000 },
116 { 0x00000000, 0x003a2c02, 0x000 },
117 { 0x00000002, 0x00220e2b, 0x000 },
118 { 0xfc000000, 0x00280e23, 0x000 },
119 { 0x00000011, 0x00203623, 0x000 },
120 { 0x00001fff, 0x00294a23, 0x000 },
121 { 0x00000030, 0x00204a2d, 0x000 },
122 { 0x00000000, 0x00204811, 0x000 },
123 { 0x00000032, 0x00200e2d, 0x000 },
124 { 0x060a0200, 0x00294a23, 0x000 },
125 { 0x00000000, 0x00204811, 0x000 },
126 { 0x00000000, 0x00204811, 0x000 },
127 { 0x00000001, 0x00210222, 0x000 },
128 { 0x00000000, 0x14e00000, 0x061 },
129 { 0x00000000, 0x2ee00000, 0x05f },
130 { 0x00000000, 0x2ce00000, 0x05e },
131 { 0x00000000, 0x00400e2d, 0x062 },
132 { 0x00000001, 0x00400e2d, 0x062 },
133 { 0x0000000a, 0x00200e2d, 0x000 },
134 { 0x0000000b, 0x0040122d, 0x06a },
135 { 0x00000000, 0xc0200c00, 0x000 },
136 { 0x003ffffc, 0x00281223, 0x000 },
137 { 0x00000002, 0x00221224, 0x000 },
138 { 0x7fc00000, 0x00281623, 0x000 },
139 { 0x00000014, 0x00211625, 0x000 },
140 { 0x00000001, 0x00331625, 0x000 },
141 { 0x80000000, 0x00280e23, 0x000 },
142 { 0x00000000, 0x00290ca3, 0x000 },
143 { 0x3ffffc00, 0x00290e23, 0x000 },
144 { 0x0000001f, 0x00211e23, 0x000 },
145 { 0x00000000, 0x14e00000, 0x06d },
146 { 0x00000100, 0x00401c11, 0x070 },
147 { 0x0000000d, 0x00201e2d, 0x000 },
148 { 0x000000f0, 0x00281e27, 0x000 },
149 { 0x00000004, 0x00221e27, 0x000 },
150 { 0x81000000, 0x00204411, 0x000 },
151 { 0x0000000d, 0x00204811, 0x000 },
152 { 0xfffff0ff, 0x00281a30, 0x000 },
153 { 0x0000a028, 0x00204411, 0x000 },
154 { 0x00000000, 0x002948e6, 0x000 },
155 { 0x0000a018, 0x00204411, 0x000 },
156 { 0x3fffffff, 0x00284a23, 0x000 },
157 { 0x0000a010, 0x00204411, 0x000 },
158 { 0x00000000, 0x00204804, 0x000 },
159 { 0x0000002d, 0x0020162d, 0x000 },
160 { 0x00000000, 0x002f00a3, 0x000 },
161 { 0x00000000, 0x0cc00000, 0x080 },
162 { 0x0000002e, 0x0020162d, 0x000 },
163 { 0x00000000, 0x002f00a4, 0x000 },
164 { 0x00000000, 0x0cc00000, 0x081 },
165 { 0x00000000, 0x00400000, 0x087 },
166 { 0x0000002d, 0x00203623, 0x000 },
167 { 0x0000002e, 0x00203624, 0x000 },
168 { 0x0000001d, 0x00201e2d, 0x000 },
169 { 0x00000002, 0x00210227, 0x000 },
170 { 0x00000000, 0x14e00000, 0x087 },
171 { 0x00000000, 0x00600000, 0x5ed },
172 { 0x00000000, 0x00600000, 0x5e1 },
173 { 0x00000002, 0x00210e22, 0x000 },
174 { 0x00000000, 0x14c00000, 0x08a },
175 { 0x00000018, 0xc0403620, 0x090 },
176 { 0x00000000, 0x2ee00000, 0x08e },
177 { 0x00000000, 0x2ce00000, 0x08d },
178 { 0x00000002, 0x00400e2d, 0x08f },
179 { 0x00000003, 0x00400e2d, 0x08f },
180 { 0x0000000c, 0x00200e2d, 0x000 },
181 { 0x00000018, 0x00203623, 0x000 },
182 { 0x00000003, 0x00210e22, 0x000 },
183 { 0x00000000, 0x14c00000, 0x095 },
184 { 0x0000a00c, 0x00204411, 0x000 },
185 { 0x00000000, 0xc0204800, 0x000 },
186 { 0x00000000, 0xc0404800, 0x09d },
187 { 0x0000a00c, 0x00204411, 0x000 },
188 { 0x00000000, 0x00204811, 0x000 },
189 { 0x00000000, 0x2ee00000, 0x09b },
190 { 0x00000000, 0x2ce00000, 0x09a },
191 { 0x00000002, 0x00400e2d, 0x09c },
192 { 0x00000003, 0x00400e2d, 0x09c },
193 { 0x0000000c, 0x00200e2d, 0x000 },
194 { 0x00000000, 0x00204803, 0x000 },
195 { 0x00000000, 0x003a0c02, 0x000 },
196 { 0x003f0000, 0x00280e23, 0x000 },
197 { 0x00000010, 0x00210e23, 0x000 },
198 { 0x00000013, 0x00203623, 0x000 },
199 { 0x0000001e, 0x0021022b, 0x000 },
200 { 0x00000000, 0x14c00000, 0x0a4 },
201 { 0x0000001c, 0xc0203620, 0x000 },
202 { 0x0000001f, 0x0021022b, 0x000 },
203 { 0x00000000, 0x14c00000, 0x0a7 },
204 { 0x0000001b, 0xc0203620, 0x000 },
205 { 0x00000008, 0x00210e2b, 0x000 },
206 { 0x0000007f, 0x00280e23, 0x000 },
207 { 0x00000000, 0x002f0223, 0x000 },
208 { 0x00000000, 0x0ce00000, 0x0db },
209 { 0x00000000, 0x27000000, 0x000 },
210 { 0x00000000, 0x00600000, 0x28c },
211 { 0x81000000, 0x00204411, 0x000 },
212 { 0x00000006, 0x00204811, 0x000 },
213 { 0x0000000c, 0x00221e30, 0x000 },
214 { 0x99800000, 0x00204411, 0x000 },
215 { 0x00000004, 0x0020122d, 0x000 },
216 { 0x00000008, 0x00221224, 0x000 },
217 { 0x00000010, 0x00201811, 0x000 },
218 { 0x00000000, 0x00291ce4, 0x000 },
219 { 0x00000000, 0x00604807, 0x128 },
220 { 0x9b000000, 0x00204411, 0x000 },
221 { 0x00000000, 0x00204802, 0x000 },
222 { 0x9c000000, 0x00204411, 0x000 },
223 { 0x00000000, 0x0033146f, 0x000 },
224 { 0x00000001, 0x00333e23, 0x000 },
225 { 0x00000000, 0xd9004800, 0x000 },
226 { 0x00000000, 0x00203c05, 0x000 },
227 { 0x81000000, 0x00204411, 0x000 },
228 { 0x0000000e, 0x00204811, 0x000 },
229 { 0x00000000, 0x00201010, 0x000 },
230 { 0x0000e007, 0x00204411, 0x000 },
231 { 0x0000000f, 0x0021022b, 0x000 },
232 { 0x00000000, 0x14c00000, 0x0c5 },
233 { 0x00f8ff08, 0x00204811, 0x000 },
234 { 0x98000000, 0x00404811, 0x0d6 },
235 { 0x000000f0, 0x00280e22, 0x000 },
236 { 0x000000a0, 0x002f0223, 0x000 },
237 { 0x00000000, 0x0cc00000, 0x0d4 },
238 { 0x00000013, 0x00200e2d, 0x000 },
239 { 0x00000001, 0x002f0223, 0x000 },
240 { 0x00000000, 0x0ce00000, 0x0cf },
241 { 0x00000002, 0x002f0223, 0x000 },
242 { 0x00000000, 0x0ce00000, 0x0ce },
243 { 0x00003f00, 0x00400c11, 0x0d0 },
244 { 0x00001f00, 0x00400c11, 0x0d0 },
245 { 0x00000f00, 0x00200c11, 0x000 },
246 { 0x00380009, 0x00294a23, 0x000 },
247 { 0x3f000000, 0x00280e2b, 0x000 },
248 { 0x00000002, 0x00220e23, 0x000 },
249 { 0x00000007, 0x00494a23, 0x0d6 },
250 { 0x00380f09, 0x00204811, 0x000 },
251 { 0x68000007, 0x00204811, 0x000 },
252 { 0x00000008, 0x00214a27, 0x000 },
253 { 0x00000000, 0x00204811, 0x000 },
254 { 0x060a0200, 0x00294a24, 0x000 },
255 { 0x00000000, 0x00204811, 0x000 },
256 { 0x00000000, 0x00204811, 0x000 },
257 { 0x0000a202, 0x00204411, 0x000 },
258 { 0x00ff0000, 0x00284a22, 0x000 },
259 { 0x00000030, 0x00200e2d, 0x000 },
260 { 0x0000002e, 0x0020122d, 0x000 },
261 { 0x00000000, 0x002f0083, 0x000 },
262 { 0x00000000, 0x0ce00000, 0x0e3 },
263 { 0x00000000, 0x00600000, 0x5e7 },
264 { 0x00000000, 0x00400000, 0x0e4 },
265 { 0x00000000, 0x00600000, 0x5ea },
266 { 0x00000007, 0x0020222d, 0x000 },
267 { 0x00000005, 0x00220e22, 0x000 },
268 { 0x00100000, 0x00280e23, 0x000 },
269 { 0x00000000, 0x00292068, 0x000 },
270 { 0x00000000, 0x003a0c02, 0x000 },
271 { 0x000000ef, 0x00280e23, 0x000 },
272 { 0x00000000, 0x00292068, 0x000 },
273 { 0x0000001d, 0x00200e2d, 0x000 },
274 { 0x00000003, 0x00210223, 0x000 },
275 { 0x00000000, 0x14e00000, 0x0f1 },
276 { 0x0000000b, 0x00210228, 0x000 },
277 { 0x00000000, 0x14c00000, 0x0f1 },
278 { 0x00000400, 0x00292228, 0x000 },
279 { 0x0000001a, 0x00203628, 0x000 },
280 { 0x0000001c, 0x00210e22, 0x000 },
281 { 0x00000000, 0x14c00000, 0x0f6 },
282 { 0x0000a30c, 0x00204411, 0x000 },
283 { 0x00000000, 0x00204811, 0x000 },
284 { 0x0000001e, 0x00210e22, 0x000 },
285 { 0x00000000, 0x14c00000, 0x104 },
286 { 0x0000a30f, 0x00204411, 0x000 },
287 { 0x00000013, 0x00200e2d, 0x000 },
288 { 0x00000001, 0x002f0223, 0x000 },
289 { 0x00000000, 0x0cc00000, 0x0fd },
290 { 0xffffffff, 0x00404811, 0x104 },
291 { 0x00000002, 0x002f0223, 0x000 },
292 { 0x00000000, 0x0cc00000, 0x100 },
293 { 0x0000ffff, 0x00404811, 0x104 },
294 { 0x00000004, 0x002f0223, 0x000 },
295 { 0x00000000, 0x0cc00000, 0x103 },
296 { 0x000000ff, 0x00404811, 0x104 },
297 { 0x00000001, 0x00204811, 0x000 },
298 { 0x0002c400, 0x00204411, 0x000 },
299 { 0x0000001f, 0x00210e22, 0x000 },
300 { 0x00000000, 0x14c00000, 0x10b },
301 { 0x00000010, 0x40210e20, 0x000 },
302 { 0x00000019, 0x00203623, 0x000 },
303 { 0x00000018, 0x40224a20, 0x000 },
304 { 0x00000010, 0xc0424a20, 0x10d },
305 { 0x00000000, 0x00200c11, 0x000 },
306 { 0x00000019, 0x00203623, 0x000 },
307 { 0x00000000, 0x00204811, 0x000 },
308 { 0x00000000, 0x00204811, 0x000 },
309 { 0x0000000a, 0x00201011, 0x000 },
310 { 0x00000000, 0x002f0224, 0x000 },
311 { 0x00000000, 0x0ce00000, 0x114 },
312 { 0x00000000, 0x00204811, 0x000 },
313 { 0x00000001, 0x00531224, 0x110 },
314 { 0xffbfffff, 0x00283a2e, 0x000 },
315 { 0x0000001b, 0x00210222, 0x000 },
316 { 0x00000000, 0x14c00000, 0x127 },
317 { 0x81000000, 0x00204411, 0x000 },
318 { 0x0000000d, 0x00204811, 0x000 },
319 { 0x00000018, 0x00220e30, 0x000 },
320 { 0xfc000000, 0x00280e23, 0x000 },
321 { 0x81000000, 0x00204411, 0x000 },
322 { 0x0000000e, 0x00204811, 0x000 },
323 { 0x00000000, 0x00201010, 0x000 },
324 { 0x0000e00e, 0x00204411, 0x000 },
325 { 0x07f8ff08, 0x00204811, 0x000 },
326 { 0x00000000, 0x00294a23, 0x000 },
327 { 0x00000024, 0x00201e2d, 0x000 },
328 { 0x00000008, 0x00214a27, 0x000 },
329 { 0x00000000, 0x00204811, 0x000 },
330 { 0x060a0200, 0x00294a24, 0x000 },
331 { 0x00000000, 0x00204811, 0x000 },
332 { 0x00000000, 0x00204811, 0x000 },
333 { 0x00000000, 0x00800000, 0x000 },
334 { 0x81000000, 0x00204411, 0x000 },
335 { 0x00000001, 0x00204811, 0x000 },
336 { 0x0000217c, 0x00204411, 0x000 },
337 { 0x00800000, 0x00204811, 0x000 },
338 { 0x00000000, 0x00204806, 0x000 },
339 { 0x00000008, 0x00214a27, 0x000 },
340 { 0x00000000, 0x17000000, 0x000 },
341 { 0x0004217f, 0x00604411, 0x614 },
342 { 0x0000001f, 0x00210230, 0x000 },
343 { 0x00000000, 0x14c00000, 0x613 },
344 { 0x00000004, 0x00404c11, 0x12e },
345 { 0x00000000, 0x00600000, 0x00b },
346 { 0x00000000, 0x00600411, 0x2fe },
347 { 0x00000000, 0x00200411, 0x000 },
348 { 0x00000000, 0x00600811, 0x19f },
349 { 0x00000000, 0x00600000, 0x151 },
350 { 0x0000ffff, 0x40280e20, 0x000 },
351 { 0x00000010, 0xc0211220, 0x000 },
352 { 0x0000ffff, 0x40280620, 0x000 },
353 { 0x00000010, 0xc0210a20, 0x000 },
354 { 0x00000000, 0x00341461, 0x000 },
355 { 0x00000000, 0x00741882, 0x2a4 },
356 { 0x0001a1fd, 0x00604411, 0x2c9 },
357 { 0x00003fff, 0x002f022f, 0x000 },
358 { 0x00000000, 0x0cc00000, 0x138 },
359 { 0x00000000, 0xc0400400, 0x001 },
360 { 0x00000000, 0x00600000, 0x00b },
361 { 0x00000000, 0x00600411, 0x2fe },
362 { 0x00000000, 0x00200411, 0x000 },
363 { 0x00000000, 0x00600811, 0x19f },
364 { 0x00003fff, 0x002f022f, 0x000 },
365 { 0x00000000, 0x0ce00000, 0x000 },
366 { 0x00000000, 0x00600000, 0x151 },
367 { 0x00000010, 0x40210e20, 0x000 },
368 { 0x0000ffff, 0xc0281220, 0x000 },
369 { 0x00000010, 0x40211620, 0x000 },
370 { 0x0000ffff, 0xc0681a20, 0x2a4 },
371 { 0x0001a1fd, 0x00604411, 0x2c9 },
372 { 0x00003fff, 0x002f022f, 0x000 },
373 { 0x00000000, 0x0cc00000, 0x149 },
374 { 0x00000000, 0xc0400400, 0x001 },
375 { 0x0000225c, 0x00204411, 0x000 },
376 { 0x00000001, 0x00300a2f, 0x000 },
377 { 0x00000001, 0x00210a22, 0x000 },
378 { 0x00000003, 0x00384a22, 0x000 },
379 { 0x00002256, 0x00204411, 0x000 },
380 { 0x0000001a, 0x00204811, 0x000 },
381 { 0x0000a1fc, 0x00204411, 0x000 },
382 { 0x00000001, 0x00804811, 0x000 },
383 { 0x00000000, 0x00600000, 0x00b },
384 { 0x00000000, 0x00600000, 0x17c },
385 { 0x00000000, 0x00600000, 0x18d },
386 { 0x00003fff, 0x002f022f, 0x000 },
387 { 0x00000000, 0x0ce00000, 0x000 },
388 { 0x00000000, 0x00202c08, 0x000 },
389 { 0x00000000, 0x00202411, 0x000 },
390 { 0x00000000, 0x00202811, 0x000 },
391 { 0x00002256, 0x00204411, 0x000 },
392 { 0x00000016, 0x00204811, 0x000 },
393 { 0x0000225c, 0x00204411, 0x000 },
394 { 0x00000003, 0x00204811, 0x000 },
395 { 0x93800000, 0x00204411, 0x000 },
396 { 0x00000002, 0x00221e29, 0x000 },
397 { 0x00000000, 0x007048eb, 0x189 },
398 { 0x00000000, 0x00600000, 0x2a4 },
399 { 0x00000001, 0x40330620, 0x000 },
400 { 0x00000000, 0xc0302409, 0x000 },
401 { 0x00003fff, 0x002f022f, 0x000 },
402 { 0x00000000, 0x0ce00000, 0x000 },
403 { 0x00000000, 0x00600000, 0x28c },
404 { 0x95000000, 0x00204411, 0x000 },
405 { 0x00000000, 0x002f0221, 0x000 },
406 { 0x00000000, 0x0ce00000, 0x173 },
407 { 0x00000000, 0xc0204800, 0x000 },
408 { 0x00000001, 0x00530621, 0x16f },
409 { 0x92000000, 0x00204411, 0x000 },
410 { 0x00000000, 0xc0604800, 0x184 },
411 { 0x0001a1fd, 0x00204411, 0x000 },
412 { 0x00000013, 0x0020062d, 0x000 },
413 { 0x00000000, 0x0078042a, 0x2e4 },
414 { 0x00000000, 0x00202809, 0x000 },
415 { 0x00003fff, 0x002f022f, 0x000 },
416 { 0x00000000, 0x0cc00000, 0x165 },
417 { 0x00000000, 0xc0400400, 0x001 },
418 { 0x00000210, 0x00600411, 0x2fe },
419 { 0x00003fff, 0x002f022f, 0x000 },
420 { 0x00000000, 0x0ce00000, 0x181 },
421 { 0x0000001b, 0xc0203620, 0x000 },
422 { 0x0000001c, 0xc0203620, 0x000 },
423 { 0x3f800000, 0x00200411, 0x000 },
424 { 0x46000000, 0x00600811, 0x19f },
425 { 0x00000000, 0x00800000, 0x000 },
426 { 0x0000a1fc, 0x00204411, 0x000 },
427 { 0x00003fff, 0x002f022f, 0x000 },
428 { 0x00000000, 0x0cc00000, 0x188 },
429 { 0x00000001, 0x00804811, 0x000 },
430 { 0x00000021, 0x00804811, 0x000 },
431 { 0x0000ffff, 0x40280e20, 0x000 },
432 { 0x00000010, 0xc0211220, 0x000 },
433 { 0x0000ffff, 0x40281620, 0x000 },
434 { 0x00000010, 0xc0811a20, 0x000 },
435 { 0x81000000, 0x00204411, 0x000 },
436 { 0x00000006, 0x00204811, 0x000 },
437 { 0x00000008, 0x00221e30, 0x000 },
438 { 0x00000032, 0x00201a2d, 0x000 },
439 { 0x0000e000, 0x00204411, 0x000 },
440 { 0xfffbff09, 0x00204811, 0x000 },
441 { 0x00000011, 0x0020222d, 0x000 },
442 { 0x00001fff, 0x00294a28, 0x000 },
443 { 0x00000006, 0x0020222d, 0x000 },
444 { 0x00000000, 0x002920e8, 0x000 },
445 { 0x00000000, 0x00204808, 0x000 },
446 { 0x00000000, 0x00204811, 0x000 },
447 { 0x060a0200, 0x00294a26, 0x000 },
448 { 0x00000000, 0x00204811, 0x000 },
449 { 0x00000000, 0x00204811, 0x000 },
450 { 0x00000100, 0x00201811, 0x000 },
451 { 0x00000008, 0x00621e28, 0x128 },
452 { 0x00000008, 0x00822228, 0x000 },
453 { 0x0002c000, 0x00204411, 0x000 },
454 { 0x0000001b, 0x00600e2d, 0x1aa },
455 { 0x0000001c, 0x00600e2d, 0x1aa },
456 { 0x0000c008, 0x00204411, 0x000 },
457 { 0x0000001d, 0x00200e2d, 0x000 },
458 { 0x00000000, 0x14c00000, 0x1a6 },
459 { 0x00000000, 0x00200411, 0x000 },
460 { 0x00000000, 0x00204801, 0x000 },
461 { 0x39000000, 0x00204811, 0x000 },
462 { 0x00000000, 0x00204811, 0x000 },
463 { 0x00000000, 0x00804802, 0x000 },
464 { 0x00000020, 0x00202e2d, 0x000 },
465 { 0x00000000, 0x003b0d63, 0x000 },
466 { 0x00000008, 0x00224a23, 0x000 },
467 { 0x00000010, 0x00224a23, 0x000 },
468 { 0x00000018, 0x00224a23, 0x000 },
469 { 0x00000000, 0x00804803, 0x000 },
470 { 0x00000000, 0x00600000, 0x00b },
471 { 0x00001000, 0x00600411, 0x2fe },
472 { 0x00000000, 0x00200411, 0x000 },
473 { 0x00000000, 0x00600811, 0x19f },
474 { 0x00000007, 0x0021062f, 0x000 },
475 { 0x00000019, 0x00200a2d, 0x000 },
476 { 0x00000001, 0x00202c11, 0x000 },
477 { 0x0000ffff, 0x40282220, 0x000 },
478 { 0x0000000f, 0x00262228, 0x000 },
479 { 0x00000010, 0x40212620, 0x000 },
480 { 0x0000000f, 0x00262629, 0x000 },
481 { 0x00000000, 0x00202802, 0x000 },
482 { 0x00002256, 0x00204411, 0x000 },
483 { 0x0000001b, 0x00204811, 0x000 },
484 { 0x00000000, 0x002f0221, 0x000 },
485 { 0x00000000, 0x0ce00000, 0x1cd },
486 { 0x0000225c, 0x00204411, 0x000 },
487 { 0x00000081, 0x00204811, 0x000 },
488 { 0x0000a1fc, 0x00204411, 0x000 },
489 { 0x00000001, 0x00204811, 0x000 },
490 { 0x00000080, 0x00201c11, 0x000 },
491 { 0x00000000, 0x002f0227, 0x000 },
492 { 0x00000000, 0x0ce00000, 0x1c9 },
493 { 0x00000000, 0x00600000, 0x1d6 },
494 { 0x00000001, 0x00531e27, 0x1c5 },
495 { 0x00000001, 0x00202c11, 0x000 },
496 { 0x0000001f, 0x00280a22, 0x000 },
497 { 0x0000001f, 0x00282a2a, 0x000 },
498 { 0x00000001, 0x00530621, 0x1be },
499 { 0x0000225c, 0x00204411, 0x000 },
500 { 0x00000002, 0x00304a2f, 0x000 },
501 { 0x0000a1fc, 0x00204411, 0x000 },
502 { 0x00000001, 0x00204811, 0x000 },
503 { 0x00000001, 0x00301e2f, 0x000 },
504 { 0x00000000, 0x002f0227, 0x000 },
505 { 0x00000000, 0x0ce00000, 0x000 },
506 { 0x00000000, 0x00600000, 0x1d6 },
507 { 0x00000001, 0x00531e27, 0x1d2 },
508 { 0x0000ffff, 0x40280e20, 0x000 },
509 { 0x0000000f, 0x00260e23, 0x000 },
510 { 0x00000010, 0xc0211220, 0x000 },
511 { 0x0000000f, 0x00261224, 0x000 },
512 { 0x00000000, 0x00201411, 0x000 },
513 { 0x00000000, 0x00601811, 0x2a4 },
514 { 0x0001a1fd, 0x00204411, 0x000 },
515 { 0x00000000, 0x002f022b, 0x000 },
516 { 0x00000000, 0x0ce00000, 0x1e5 },
517 { 0x00000010, 0x00221628, 0x000 },
518 { 0xffff0000, 0x00281625, 0x000 },
519 { 0x0000ffff, 0x00281a29, 0x000 },
520 { 0x00000000, 0x002948c5, 0x000 },
521 { 0x00000000, 0x0020480a, 0x000 },
522 { 0x00000000, 0x00202c11, 0x000 },
523 { 0x00000010, 0x00221623, 0x000 },
524 { 0xffff0000, 0x00281625, 0x000 },
525 { 0x0000ffff, 0x00281a24, 0x000 },
526 { 0x00000000, 0x002948c5, 0x000 },
527 { 0x00000000, 0x00731503, 0x1f2 },
528 { 0x00000000, 0x00201805, 0x000 },
529 { 0x00000000, 0x00731524, 0x1f2 },
530 { 0x00000000, 0x002d14c5, 0x000 },
531 { 0x00000000, 0x003008a2, 0x000 },
532 { 0x00000000, 0x00204802, 0x000 },
533 { 0x00000000, 0x00202802, 0x000 },
534 { 0x00000000, 0x00202003, 0x000 },
535 { 0x00000000, 0x00802404, 0x000 },
536 { 0x0000000f, 0x00210225, 0x000 },
537 { 0x00000000, 0x14c00000, 0x613 },
538 { 0x00000000, 0x002b1405, 0x000 },
539 { 0x00000001, 0x00901625, 0x000 },
540 { 0x00000000, 0x00600000, 0x00b },
541 { 0x00000000, 0x00600411, 0x2fe },
542 { 0x00000000, 0x00200411, 0x000 },
543 { 0x00000000, 0x00600811, 0x19f },
544 { 0x00002256, 0x00204411, 0x000 },
545 { 0x0000001a, 0x00294a22, 0x000 },
546 { 0x00000000, 0xc0200000, 0x000 },
547 { 0x00003fff, 0x002f022f, 0x000 },
548 { 0x00000000, 0x0ce00000, 0x000 },
549 { 0x00000000, 0xc0200400, 0x000 },
550 { 0x0000225c, 0x00204411, 0x000 },
551 { 0x00000003, 0x00384a21, 0x000 },
552 { 0x0000a1fc, 0x00204411, 0x000 },
553 { 0x00000001, 0x00204811, 0x000 },
554 { 0x0000ffff, 0x40281220, 0x000 },
555 { 0x00000010, 0xc0211a20, 0x000 },
556 { 0x0000ffff, 0x40280e20, 0x000 },
557 { 0x00000010, 0xc0211620, 0x000 },
558 { 0x00000000, 0x00741465, 0x2a4 },
559 { 0x0001a1fd, 0x00604411, 0x2c9 },
560 { 0x00000001, 0x00330621, 0x000 },
561 { 0x00000000, 0x002f0221, 0x000 },
562 { 0x00000000, 0x0cc00000, 0x206 },
563 { 0x00003fff, 0x002f022f, 0x000 },
564 { 0x00000000, 0x0cc00000, 0x1ff },
565 { 0x00000000, 0xc0400400, 0x001 },
566 { 0x00000000, 0x00600000, 0x5c5 },
567 { 0x00000000, 0x0040040f, 0x200 },
568 { 0x00000000, 0x00600000, 0x5b2 },
569 { 0x00000000, 0x00600000, 0x5c5 },
570 { 0x00000210, 0x00600411, 0x2fe },
571 { 0x00000000, 0x00600000, 0x18d },
572 { 0x00000000, 0x00600000, 0x189 },
573 { 0x00000000, 0x00600000, 0x2a4 },
574 { 0x00000000, 0x00600000, 0x28c },
575 { 0x93800000, 0x00204411, 0x000 },
576 { 0x00000000, 0x00204808, 0x000 },
577 { 0x95000000, 0x00204411, 0x000 },
578 { 0x00000000, 0x002f022f, 0x000 },
579 { 0x00000000, 0x0ce00000, 0x21f },
580 { 0x00000000, 0xc0404800, 0x21c },
581 { 0x92000000, 0x00204411, 0x000 },
582 { 0x00000000, 0xc0204800, 0x000 },
583 { 0x00002256, 0x00204411, 0x000 },
584 { 0x00000016, 0x00204811, 0x000 },
585 { 0x0000225c, 0x00204411, 0x000 },
586 { 0x00000003, 0x00204811, 0x000 },
587 { 0x0000a1fc, 0x00204411, 0x000 },
588 { 0x00000001, 0x00204811, 0x000 },
589 { 0x0001a1fd, 0x00204411, 0x000 },
590 { 0x00000000, 0x00600411, 0x2e4 },
591 { 0x00000000, 0xc0400400, 0x001 },
592 { 0x00000000, 0x00600000, 0x5b2 },
593 { 0x0000a00c, 0x00204411, 0x000 },
594 { 0x00000000, 0xc0204800, 0x000 },
595 { 0x00000000, 0xc0404800, 0x000 },
596 { 0x00000000, 0x00600000, 0x00b },
597 { 0x00000018, 0x40210a20, 0x000 },
598 { 0x00000003, 0x002f0222, 0x000 },
599 { 0x00000000, 0x0ae00000, 0x235 },
600 { 0x0000001a, 0x0020222d, 0x000 },
601 { 0x00080101, 0x00292228, 0x000 },
602 { 0x0000001a, 0x00203628, 0x000 },
603 { 0x0000a30c, 0x00204411, 0x000 },
604 { 0x00000000, 0xc0204800, 0x000 },
605 { 0x00000000, 0xc0204800, 0x000 },
606 { 0x00000000, 0xc0404800, 0x23a },
607 { 0x00000000, 0x00600000, 0x00b },
608 { 0x00000010, 0x00600411, 0x2fe },
609 { 0x3f800000, 0x00200411, 0x000 },
610 { 0x00000000, 0x00600811, 0x19f },
611 { 0x0000225c, 0x00204411, 0x000 },
612 { 0x00000003, 0x00204811, 0x000 },
613 { 0x00000000, 0x00600000, 0x265 },
614 { 0x0000001d, 0x00201e2d, 0x000 },
615 { 0x00000001, 0x00211e27, 0x000 },
616 { 0x00000000, 0x14e00000, 0x253 },
617 { 0x00000018, 0x00201e2d, 0x000 },
618 { 0x0000ffff, 0x00281e27, 0x000 },
619 { 0x00000000, 0x00341c27, 0x000 },
620 { 0x00000000, 0x12c00000, 0x248 },
621 { 0x00000000, 0x00201c11, 0x000 },
622 { 0x00000000, 0x002f00e5, 0x000 },
623 { 0x00000000, 0x08c00000, 0x24b },
624 { 0x00000000, 0x00201407, 0x000 },
625 { 0x00000018, 0x00201e2d, 0x000 },
626 { 0x00000010, 0x00211e27, 0x000 },
627 { 0x00000000, 0x00341c47, 0x000 },
628 { 0x00000000, 0x12c00000, 0x250 },
629 { 0x00000000, 0x00201c11, 0x000 },
630 { 0x00000000, 0x002f00e6, 0x000 },
631 { 0x00000000, 0x08c00000, 0x253 },
632 { 0x00000000, 0x00201807, 0x000 },
633 { 0x00000000, 0x00600000, 0x2aa },
634 { 0x00002256, 0x00204411, 0x000 },
635 { 0x00000000, 0x00342023, 0x000 },
636 { 0x00000000, 0x12c00000, 0x25b },
637 { 0x00000000, 0x00342044, 0x000 },
638 { 0x00000000, 0x12c00000, 0x25a },
639 { 0x00000016, 0x00404811, 0x25f },
640 { 0x00000018, 0x00404811, 0x25f },
641 { 0x00000000, 0x00342044, 0x000 },
642 { 0x00000000, 0x12c00000, 0x25e },
643 { 0x00000017, 0x00404811, 0x25f },
644 { 0x00000019, 0x00204811, 0x000 },
645 { 0x0000a1fc, 0x00204411, 0x000 },
646 { 0x00000001, 0x00204811, 0x000 },
647 { 0x0001a1fd, 0x00604411, 0x2d2 },
648 { 0x00003fff, 0x002f022f, 0x000 },
649 { 0x00000000, 0x0cc00000, 0x23f },
650 { 0x00000000, 0xc0400400, 0x001 },
651 { 0x00000010, 0x40210620, 0x000 },
652 { 0x0000ffff, 0xc0280a20, 0x000 },
653 { 0x00000010, 0x40210e20, 0x000 },
654 { 0x0000ffff, 0xc0281220, 0x000 },
655 { 0x00000010, 0x40211620, 0x000 },
656 { 0x0000ffff, 0xc0881a20, 0x000 },
657 { 0x81000000, 0x00204411, 0x000 },
658 { 0x00000001, 0x00204811, 0x000 },
659 { 0x00042004, 0x00604411, 0x614 },
660 { 0x00000000, 0x00600000, 0x5b2 },
661 { 0x00000000, 0xc0600000, 0x28c },
662 { 0x00000005, 0x00200a2d, 0x000 },
663 { 0x00000008, 0x00220a22, 0x000 },
664 { 0x00000034, 0x00201a2d, 0x000 },
665 { 0x00000024, 0x00201e2d, 0x000 },
666 { 0x00007000, 0x00281e27, 0x000 },
667 { 0x00000000, 0x00311ce6, 0x000 },
668 { 0x00000033, 0x00201a2d, 0x000 },
669 { 0x0000000c, 0x00221a26, 0x000 },
670 { 0x00000000, 0x002f00e6, 0x000 },
671 { 0x00000000, 0x06e00000, 0x27b },
672 { 0x00000000, 0x00201c11, 0x000 },
673 { 0x00000000, 0x00200c11, 0x000 },
674 { 0x00000034, 0x00203623, 0x000 },
675 { 0x00000010, 0x00201811, 0x000 },
676 { 0x00000000, 0x00691ce2, 0x128 },
677 { 0x93800000, 0x00204411, 0x000 },
678 { 0x00000000, 0x00204807, 0x000 },
679 { 0x95000000, 0x00204411, 0x000 },
680 { 0x00000000, 0x002f022f, 0x000 },
681 { 0x00000000, 0x0ce00000, 0x286 },
682 { 0x00000001, 0x00333e2f, 0x000 },
683 { 0x00000000, 0xd9004800, 0x000 },
684 { 0x92000000, 0x00204411, 0x000 },
685 { 0x00000000, 0xc0204800, 0x000 },
686 { 0x00000024, 0x00403627, 0x000 },
687 { 0x0000000c, 0xc0220a20, 0x000 },
688 { 0x00000032, 0x00203622, 0x000 },
689 { 0x00000031, 0xc0403620, 0x000 },
690 { 0x0000a2a4, 0x00204411, 0x000 },
691 { 0x00000009, 0x00204811, 0x000 },
692 { 0xa1000000, 0x00204411, 0x000 },
693 { 0x00000001, 0x00804811, 0x000 },
694 { 0x00000029, 0x00201e2d, 0x000 },
695 { 0x00000000, 0x002c1ce3, 0x000 },
696 { 0x00000029, 0x00203627, 0x000 },
697 { 0x0000002a, 0x00201e2d, 0x000 },
698 { 0x00000000, 0x002c1ce4, 0x000 },
699 { 0x0000002a, 0x00203627, 0x000 },
700 { 0x0000002b, 0x00201e2d, 0x000 },
701 { 0x00000000, 0x003120a3, 0x000 },
702 { 0x00000000, 0x002d1d07, 0x000 },
703 { 0x0000002b, 0x00203627, 0x000 },
704 { 0x0000002c, 0x00201e2d, 0x000 },
705 { 0x00000000, 0x003120c4, 0x000 },
706 { 0x00000000, 0x002d1d07, 0x000 },
707 { 0x0000002c, 0x00803627, 0x000 },
708 { 0x00000029, 0x00203623, 0x000 },
709 { 0x0000002a, 0x00203624, 0x000 },
710 { 0x00000000, 0x00311ca3, 0x000 },
711 { 0x0000002b, 0x00203627, 0x000 },
712 { 0x00000000, 0x00311cc4, 0x000 },
713 { 0x0000002c, 0x00803627, 0x000 },
714 { 0x00000022, 0x00203627, 0x000 },
715 { 0x00000023, 0x00203628, 0x000 },
716 { 0x0000001d, 0x00201e2d, 0x000 },
717 { 0x00000002, 0x00210227, 0x000 },
718 { 0x00000000, 0x14c00000, 0x2c5 },
719 { 0x00000000, 0x00400000, 0x2c2 },
720 { 0x00000022, 0x00203627, 0x000 },
721 { 0x00000023, 0x00203628, 0x000 },
722 { 0x0000001d, 0x00201e2d, 0x000 },
723 { 0x00000002, 0x00210227, 0x000 },
724 { 0x00000000, 0x14e00000, 0x2c2 },
725 { 0x00000003, 0x00210227, 0x000 },
726 { 0x00000000, 0x14e00000, 0x2c5 },
727 { 0x0000002b, 0x00201e2d, 0x000 },
728 { 0x00000000, 0x002e00e1, 0x000 },
729 { 0x00000000, 0x02c00000, 0x2c5 },
730 { 0x00000029, 0x00201e2d, 0x000 },
731 { 0x00000000, 0x003120a1, 0x000 },
732 { 0x00000000, 0x002e00e8, 0x000 },
733 { 0x00000000, 0x06c00000, 0x2c5 },
734 { 0x0000002c, 0x00201e2d, 0x000 },
735 { 0x00000000, 0x002e00e2, 0x000 },
736 { 0x00000000, 0x02c00000, 0x2c5 },
737 { 0x0000002a, 0x00201e2d, 0x000 },
738 { 0x00000000, 0x003120c2, 0x000 },
739 { 0x00000000, 0x002e00e8, 0x000 },
740 { 0x00000000, 0x06c00000, 0x2c5 },
741 { 0x00000000, 0x00600000, 0x5ed },
742 { 0x00000000, 0x00600000, 0x29e },
743 { 0x00000000, 0x00400000, 0x2c7 },
744 { 0x00000000, 0x00600000, 0x29e },
745 { 0x00000000, 0x00600000, 0x5e4 },
746 { 0x00000000, 0x00400000, 0x2c7 },
747 { 0x00000000, 0x00600000, 0x290 },
748 { 0x00000000, 0x00400000, 0x2c7 },
749 { 0x00000022, 0x00201e2d, 0x000 },
750 { 0x00000023, 0x0080222d, 0x000 },
751 { 0x00000010, 0x00221e23, 0x000 },
752 { 0x00000000, 0x00294887, 0x000 },
753 { 0x00000000, 0x00311ca3, 0x000 },
754 { 0x00000010, 0x00221e27, 0x000 },
755 { 0x00000000, 0x00294887, 0x000 },
756 { 0x00000010, 0x00221e23, 0x000 },
757 { 0x00000000, 0x003120c4, 0x000 },
758 { 0x0000ffff, 0x00282228, 0x000 },
759 { 0x00000000, 0x00894907, 0x000 },
760 { 0x00000010, 0x00221e23, 0x000 },
761 { 0x00000000, 0x00294887, 0x000 },
762 { 0x00000010, 0x00221e21, 0x000 },
763 { 0x00000000, 0x00294847, 0x000 },
764 { 0x00000000, 0x00311ca3, 0x000 },
765 { 0x00000010, 0x00221e27, 0x000 },
766 { 0x00000000, 0x00294887, 0x000 },
767 { 0x00000000, 0x00311ca1, 0x000 },
768 { 0x00000010, 0x00221e27, 0x000 },
769 { 0x00000000, 0x00294847, 0x000 },
770 { 0x00000010, 0x00221e23, 0x000 },
771 { 0x00000000, 0x003120c4, 0x000 },
772 { 0x0000ffff, 0x00282228, 0x000 },
773 { 0x00000000, 0x00294907, 0x000 },
774 { 0x00000010, 0x00221e21, 0x000 },
775 { 0x00000000, 0x003120c2, 0x000 },
776 { 0x0000ffff, 0x00282228, 0x000 },
777 { 0x00000000, 0x00894907, 0x000 },
778 { 0x00000010, 0x00221e23, 0x000 },
779 { 0x00000000, 0x00294887, 0x000 },
780 { 0x00000001, 0x00220a21, 0x000 },
781 { 0x00000000, 0x003308a2, 0x000 },
782 { 0x00000010, 0x00221e22, 0x000 },
783 { 0x00000010, 0x00212222, 0x000 },
784 { 0x00000000, 0x00294907, 0x000 },
785 { 0x00000000, 0x00311ca3, 0x000 },
786 { 0x00000010, 0x00221e27, 0x000 },
787 { 0x00000000, 0x00294887, 0x000 },
788 { 0x00000001, 0x00220a21, 0x000 },
789 { 0x00000000, 0x003008a2, 0x000 },
790 { 0x00000010, 0x00221e22, 0x000 },
791 { 0x00000010, 0x00212222, 0x000 },
792 { 0x00000000, 0x00294907, 0x000 },
793 { 0x00000010, 0x00221e23, 0x000 },
794 { 0x00000000, 0x003120c4, 0x000 },
795 { 0x0000ffff, 0x00282228, 0x000 },
796 { 0x00000000, 0x00294907, 0x000 },
797 { 0x00000000, 0x003808c5, 0x000 },
798 { 0x00000000, 0x00300841, 0x000 },
799 { 0x00000001, 0x00220a22, 0x000 },
800 { 0x00000000, 0x003308a2, 0x000 },
801 { 0x00000010, 0x00221e22, 0x000 },
802 { 0x00000010, 0x00212222, 0x000 },
803 { 0x00000000, 0x00894907, 0x000 },
804 { 0x0000001d, 0x0020222d, 0x000 },
805 { 0x00000000, 0x14c00000, 0x301 },
806 { 0xffffffef, 0x00280621, 0x000 },
807 { 0x0000001a, 0x0020222d, 0x000 },
808 { 0x0000f8e0, 0x00204411, 0x000 },
809 { 0x00000000, 0x00294901, 0x000 },
810 { 0x00000000, 0x00894901, 0x000 },
811 { 0x00000000, 0x00204811, 0x000 },
812 { 0x00000000, 0x00204811, 0x000 },
813 { 0x060a0200, 0x00804811, 0x000 },
814 { 0x00000000, 0xc0200000, 0x000 },
815 { 0x97000000, 0xc0204411, 0x000 },
816 { 0x00000000, 0xc0204811, 0x000 },
817 { 0x8a000000, 0x00204411, 0x000 },
818 { 0x00000000, 0x00204811, 0x000 },
819 { 0x0000225c, 0x00204411, 0x000 },
820 { 0x00000000, 0xc0204800, 0x000 },
821 { 0x0000a1fc, 0x00204411, 0x000 },
822 { 0x00000000, 0xc0204800, 0x000 },
823 { 0x00000000, 0xc0200400, 0x000 },
824 { 0x00000000, 0x00a0000a, 0x000 },
825 { 0x97000000, 0x00204411, 0x000 },
826 { 0x00000000, 0x00204811, 0x000 },
827 { 0x8a000000, 0x00204411, 0x000 },
828 { 0x00000000, 0x00204811, 0x000 },
829 { 0x0000225c, 0x00204411, 0x000 },
830 { 0x00000000, 0xc0204800, 0x000 },
831 { 0x0000a1fc, 0x00204411, 0x000 },
832 { 0x00000000, 0xc0204800, 0x000 },
833 { 0x00000000, 0xc0200400, 0x000 },
834 { 0x00000000, 0x00a0000a, 0x000 },
835 { 0x97000000, 0x00204411, 0x000 },
836 { 0x00000000, 0x00204811, 0x000 },
837 { 0x8a000000, 0x00204411, 0x000 },
838 { 0x00000000, 0x00204811, 0x000 },
839 { 0x0000225c, 0x00204411, 0x000 },
840 { 0x00000000, 0xc0204800, 0x000 },
841 { 0x0000a1fc, 0x00204411, 0x000 },
842 { 0x00000000, 0xc0204800, 0x000 },
843 { 0x0001a1fd, 0x00204411, 0x000 },
844 { 0x00000000, 0xd9004800, 0x000 },
845 { 0x00000000, 0xc0200400, 0x000 },
846 { 0x00000000, 0x00a0000a, 0x000 },
847 { 0x00002257, 0x00204411, 0x000 },
848 { 0x00000003, 0xc0484a20, 0x000 },
849 { 0x0000225d, 0x00204411, 0x000 },
850 { 0x00000000, 0xc0404800, 0x000 },
851 { 0x00000000, 0x00600000, 0x5c5 },
852 { 0x00000000, 0xc0200800, 0x000 },
853 { 0x0000225c, 0x00204411, 0x000 },
854 { 0x00000003, 0x00384a22, 0x000 },
855 { 0x0000a1fc, 0x00204411, 0x000 },
856 { 0x00000000, 0xc0204800, 0x000 },
857 { 0x0001a1fd, 0x00204411, 0x000 },
858 { 0x00000000, 0x002f0222, 0x000 },
859 { 0x00000000, 0x0ce00000, 0x000 },
860 { 0x00000000, 0x40204800, 0x000 },
861 { 0x00000001, 0x40304a20, 0x000 },
862 { 0x00000002, 0xc0304a20, 0x000 },
863 { 0x00000001, 0x00530a22, 0x334 },
864 { 0x0000003f, 0xc0280a20, 0x000 },
865 { 0x81000000, 0x00204411, 0x000 },
866 { 0x00000001, 0x00204811, 0x000 },
867 { 0x000021f8, 0x00204411, 0x000 },
868 { 0x00000017, 0x00204811, 0x000 },
869 { 0x000421f9, 0x00604411, 0x614 },
870 { 0x00000011, 0x00210230, 0x000 },
871 { 0x00000000, 0x14e00000, 0x33d },
872 { 0x00000014, 0x002f0222, 0x000 },
873 { 0x00000000, 0x0cc00000, 0x351 },
874 { 0x00002010, 0x00204411, 0x000 },
875 { 0x00008000, 0x00204811, 0x000 },
876 { 0x0001a2a4, 0x00204411, 0x000 },
877 { 0x00000000, 0x00204811, 0x000 },
878 { 0x00000016, 0x00604811, 0x35e },
879 { 0x00002100, 0x00204411, 0x000 },
880 { 0x00000000, 0xc0204800, 0x000 },
881 { 0x00000000, 0xc0204800, 0x000 },
882 { 0x00000000, 0xc0204800, 0x000 },
883 { 0x00000000, 0xc0204800, 0x000 },
884 { 0x0001a2a4, 0x00204411, 0x000 },
885 { 0x00000000, 0x00204811, 0x000 },
886 { 0x00000000, 0x00404802, 0x000 },
887 { 0x00000004, 0x002f0222, 0x000 },
888 { 0x00000000, 0x0cc00000, 0x355 },
889 { 0x00002010, 0x00204411, 0x000 },
890 { 0x00008000, 0x00404811, 0x349 },
891 { 0x00000028, 0x002f0222, 0x000 },
892 { 0x00000000, 0x0ce00000, 0x349 },
893 { 0x00002104, 0x00204411, 0x000 },
894 { 0x00000000, 0xc0204800, 0x000 },
895 { 0x00000000, 0xc0204800, 0x000 },
896 { 0x00000000, 0xc0204800, 0x000 },
897 { 0x00000000, 0xc0204800, 0x000 },
898 { 0x0000a2a4, 0x00204411, 0x000 },
899 { 0x00000000, 0x00404802, 0x000 },
900 { 0x00000035, 0x00203626, 0x000 },
901 { 0x00000049, 0x00201811, 0x000 },
902 { 0x00000000, 0x00204811, 0x000 },
903 { 0x00000001, 0x00331a26, 0x000 },
904 { 0x00000000, 0x002f0226, 0x000 },
905 { 0x00000000, 0x0cc00000, 0x360 },
906 { 0x00000035, 0x00801a2d, 0x000 },
907 { 0x0000003f, 0xc0280a20, 0x000 },
908 { 0x00000015, 0x002f0222, 0x000 },
909 { 0x00000000, 0x0ce00000, 0x376 },
910 { 0x0000001e, 0x002f0222, 0x000 },
911 { 0x00000000, 0x0ce00000, 0x380 },
912 { 0x00000020, 0x002f0222, 0x000 },
913 { 0x00000000, 0x0ce00000, 0x38c },
914 { 0x0000000f, 0x002f0222, 0x000 },
915 { 0x00000000, 0x0ce00000, 0x398 },
916 { 0x00000010, 0x002f0222, 0x000 },
917 { 0x00000000, 0x0ce00000, 0x398 },
918 { 0x00000006, 0x002f0222, 0x000 },
919 { 0x00000000, 0x0ce00000, 0x39a },
920 { 0x00000016, 0x002f0222, 0x000 },
921 { 0x00000000, 0x0ce00000, 0x39f },
922 { 0x0000a2a4, 0x00204411, 0x000 },
923 { 0x00000000, 0x00404802, 0x000 },
924 { 0x08000000, 0x00290a22, 0x000 },
925 { 0x00000003, 0x40210e20, 0x000 },
926 { 0x0000000c, 0xc0211220, 0x000 },
927 { 0x00080000, 0x00281224, 0x000 },
928 { 0x00000014, 0xc0221620, 0x000 },
929 { 0x00000000, 0x002914a4, 0x000 },
930 { 0x0000a2a4, 0x00204411, 0x000 },
931 { 0x00000000, 0x002948a2, 0x000 },
932 { 0x0000a1fe, 0x00204411, 0x000 },
933 { 0x00000000, 0x00404803, 0x000 },
934 { 0x81000000, 0x00204411, 0x000 },
935 { 0x00000001, 0x00204811, 0x000 },
936 { 0x000021f8, 0x00204411, 0x000 },
937 { 0x00000015, 0x00204811, 0x000 },
938 { 0x000421f9, 0x00604411, 0x614 },
939 { 0x00000015, 0x00210230, 0x000 },
940 { 0x00000000, 0x14e00000, 0x382 },
941 { 0x0000210e, 0x00204411, 0x000 },
942 { 0x00000000, 0xc0204800, 0x000 },
943 { 0x00000000, 0xc0204800, 0x000 },
944 { 0x0000a2a4, 0x00204411, 0x000 },
945 { 0x00000000, 0x00404802, 0x000 },
946 { 0x81000000, 0x00204411, 0x000 },
947 { 0x00000001, 0x00204811, 0x000 },
948 { 0x000021f8, 0x00204411, 0x000 },
949 { 0x00000016, 0x00204811, 0x000 },
950 { 0x000421f9, 0x00604411, 0x614 },
951 { 0x00000003, 0x00210230, 0x000 },
952 { 0x00000000, 0x14e00000, 0x38e },
953 { 0x00002108, 0x00204411, 0x000 },
954 { 0x00000000, 0xc0204800, 0x000 },
955 { 0x00000000, 0xc0204800, 0x000 },
956 { 0x0000a2a4, 0x00204411, 0x000 },
957 { 0x00000000, 0x00404802, 0x000 },
958 { 0x00002010, 0x00204411, 0x000 },
959 { 0x00008000, 0x00404811, 0x000 },
960 { 0x00002010, 0x00204411, 0x000 },
961 { 0x00008000, 0x00204811, 0x000 },
962 { 0x0001a2a4, 0x00204411, 0x000 },
963 { 0x00000000, 0x00204811, 0x000 },
964 { 0x00000006, 0x00404811, 0x000 },
965 { 0x00002010, 0x00204411, 0x000 },
966 { 0x00008000, 0x00204811, 0x000 },
967 { 0x0001a2a4, 0x00204411, 0x000 },
968 { 0x00000000, 0x00204811, 0x000 },
969 { 0x00000016, 0x00604811, 0x35e },
970 { 0x00000016, 0x00404811, 0x000 },
971 { 0x00000000, 0xc0200800, 0x000 },
972 { 0x00000000, 0xc0200c00, 0x000 },
973 { 0x0000001d, 0x00210223, 0x000 },
974 { 0x00000000, 0x14e00000, 0x3b9 },
975 { 0x81000000, 0x00204411, 0x000 },
976 { 0x00000001, 0x00204811, 0x000 },
977 { 0x000021f8, 0x00204411, 0x000 },
978 { 0x00000017, 0x00204811, 0x000 },
979 { 0x000421f9, 0x00604411, 0x614 },
980 { 0x00000011, 0x00210230, 0x000 },
981 { 0x00000000, 0x14e00000, 0x3ab },
982 { 0x00002100, 0x00204411, 0x000 },
983 { 0x00000000, 0x00204802, 0x000 },
984 { 0x00000000, 0x00204803, 0x000 },
985 { 0xbabecafe, 0x00204811, 0x000 },
986 { 0xcafebabe, 0x00204811, 0x000 },
987 { 0x00002010, 0x00204411, 0x000 },
988 { 0x00008000, 0x00204811, 0x000 },
989 { 0x0000a2a4, 0x00204411, 0x000 },
990 { 0x00000004, 0x00404811, 0x000 },
991 { 0x00002170, 0x00204411, 0x000 },
992 { 0x00000000, 0x00204802, 0x000 },
993 { 0x00000000, 0x00204803, 0x000 },
994 { 0x81000000, 0x00204411, 0x000 },
995 { 0x0000000a, 0x00204811, 0x000 },
996 { 0x00000000, 0x00200010, 0x000 },
997 { 0x00000000, 0x14c00000, 0x3be },
998 { 0x8c000000, 0x00204411, 0x000 },
999 { 0xcafebabe, 0x00404811, 0x000 },
1000 { 0x81000000, 0x00204411, 0x000 },
1001 { 0x00000001, 0x00204811, 0x000 },
1002 { 0x00003fff, 0x40280a20, 0x000 },
1003 { 0x80000000, 0x40280e20, 0x000 },
1004 { 0x40000000, 0xc0281220, 0x000 },
1005 { 0x00040000, 0x00694622, 0x614 },
1006 { 0x00000000, 0x00201410, 0x000 },
1007 { 0x00000000, 0x002f0223, 0x000 },
1008 { 0x00000000, 0x0cc00000, 0x3cc },
1009 { 0x00000000, 0xc0401800, 0x3cf },
1010 { 0x00003fff, 0xc0281a20, 0x000 },
1011 { 0x00040000, 0x00694626, 0x614 },
1012 { 0x00000000, 0x00201810, 0x000 },
1013 { 0x00000000, 0x002f0224, 0x000 },
1014 { 0x00000000, 0x0cc00000, 0x3d2 },
1015 { 0x00000000, 0xc0401c00, 0x3d5 },
1016 { 0x00003fff, 0xc0281e20, 0x000 },
1017 { 0x00040000, 0x00694627, 0x614 },
1018 { 0x00000000, 0x00201c10, 0x000 },
1019 { 0x00000000, 0x00204402, 0x000 },
1020 { 0x00000000, 0x002820c5, 0x000 },
1021 { 0x00000000, 0x004948e8, 0x000 },
1022 { 0xa5800000, 0x00200811, 0x000 },
1023 { 0x00002000, 0x00200c11, 0x000 },
1024 { 0x83000000, 0x00604411, 0x3fd },
1025 { 0x00000000, 0x00204402, 0x000 },
1026 { 0x00000000, 0xc0204800, 0x000 },
1027 { 0x00000000, 0x40204800, 0x000 },
1028 { 0x0000001f, 0xc0210220, 0x000 },
1029 { 0x00000000, 0x14c00000, 0x3e2 },
1030 { 0x00002010, 0x00204411, 0x000 },
1031 { 0x00008000, 0x00204811, 0x000 },
1032 { 0x0000ffff, 0xc0481220, 0x3ea },
1033 { 0xa7800000, 0x00200811, 0x000 },
1034 { 0x0000a000, 0x00200c11, 0x000 },
1035 { 0x83000000, 0x00604411, 0x3fd },
1036 { 0x00000000, 0x00204402, 0x000 },
1037 { 0x00000000, 0xc0204800, 0x000 },
1038 { 0x00000000, 0xc0204800, 0x000 },
1039 { 0x0000ffff, 0xc0281220, 0x000 },
1040 { 0x83000000, 0x00204411, 0x000 },
1041 { 0x00000000, 0x00304883, 0x000 },
1042 { 0x84000000, 0x00204411, 0x000 },
1043 { 0x00000000, 0xc0204800, 0x000 },
1044 { 0x00000000, 0x1d000000, 0x000 },
1045 { 0x83000000, 0x00604411, 0x3fd },
1046 { 0x00000000, 0xc0400400, 0x001 },
1047 { 0xa9800000, 0x00200811, 0x000 },
1048 { 0x0000c000, 0x00400c11, 0x3e5 },
1049 { 0xab800000, 0x00200811, 0x000 },
1050 { 0x0000f8e0, 0x00400c11, 0x3e5 },
1051 { 0xad800000, 0x00200811, 0x000 },
1052 { 0x0000f880, 0x00400c11, 0x3e5 },
1053 { 0xb3800000, 0x00200811, 0x000 },
1054 { 0x0000f3fc, 0x00400c11, 0x3e5 },
1055 { 0xaf800000, 0x00200811, 0x000 },
1056 { 0x0000e000, 0x00400c11, 0x3e5 },
1057 { 0xb1800000, 0x00200811, 0x000 },
1058 { 0x0000f000, 0x00400c11, 0x3e5 },
1059 { 0x83000000, 0x00204411, 0x000 },
1060 { 0x00002148, 0x00204811, 0x000 },
1061 { 0x84000000, 0x00204411, 0x000 },
1062 { 0x00000000, 0xc0204800, 0x000 },
1063 { 0x00000000, 0x1d000000, 0x000 },
1064 { 0x00000000, 0x00800000, 0x000 },
1065 { 0x00182000, 0xc0304620, 0x000 },
1066 { 0x00000000, 0xd9004800, 0x000 },
1067 { 0x00000000, 0xc0200400, 0x000 },
1068 { 0x00000000, 0x00a0000a, 0x000 },
1069 { 0x0018a000, 0xc0304620, 0x000 },
1070 { 0x00000000, 0xd9004800, 0x000 },
1071 { 0x00000000, 0xc0200400, 0x000 },
1072 { 0x00000000, 0x00a0000a, 0x000 },
1073 { 0x0018c000, 0xc0304620, 0x000 },
1074 { 0x00000000, 0xd9004800, 0x000 },
1075 { 0x00000000, 0xc0200400, 0x000 },
1076 { 0x00000000, 0x00a0000a, 0x000 },
1077 { 0x0018f8e0, 0xc0304620, 0x000 },
1078 { 0x00000000, 0xd9004800, 0x000 },
1079 { 0x00000000, 0xc0200400, 0x000 },
1080 { 0x00000000, 0x00a0000a, 0x000 },
1081 { 0x0018f880, 0xc0304620, 0x000 },
1082 { 0x00000000, 0xd9004800, 0x000 },
1083 { 0x00000000, 0xc0200400, 0x000 },
1084 { 0x00000000, 0x00a0000a, 0x000 },
1085 { 0x0018e000, 0xc0304620, 0x000 },
1086 { 0x00000000, 0xd9004800, 0x000 },
1087 { 0x00000000, 0xc0200400, 0x000 },
1088 { 0x00000000, 0x00a0000a, 0x000 },
1089 { 0x0018f000, 0xc0304620, 0x000 },
1090 { 0x00000000, 0xd9004800, 0x000 },
1091 { 0x00000000, 0xc0200400, 0x000 },
1092 { 0x00000000, 0x00a0000a, 0x000 },
1093 { 0x0018f3fc, 0xc0304620, 0x000 },
1094 { 0x00000000, 0xd9004800, 0x000 },
1095 { 0x00000000, 0xc0200400, 0x000 },
1096 { 0x00000000, 0x00a0000a, 0x000 },
1097 { 0x86000000, 0x00204411, 0x000 },
1098 { 0x00000000, 0x00404801, 0x000 },
1099 { 0x85000000, 0x00204411, 0x000 },
1100 { 0x00000000, 0x00404801, 0x000 },
1101 { 0x0000217c, 0x00204411, 0x000 },
1102 { 0x00000000, 0xc0204800, 0x000 },
1103 { 0x00000000, 0xc0204800, 0x000 },
1104 { 0x00000000, 0xc0204800, 0x000 },
1105 { 0x81000000, 0x00204411, 0x000 },
1106 { 0x00000001, 0x00204811, 0x000 },
1107 { 0x00000000, 0xc0200800, 0x000 },
1108 { 0x00000000, 0x17000000, 0x000 },
1109 { 0x0004217f, 0x00604411, 0x614 },
1110 { 0x0000001f, 0x00210230, 0x000 },
1111 { 0x00000000, 0x14c00000, 0x000 },
1112 { 0x00000000, 0x00404c02, 0x42e },
1113 { 0x00000000, 0xc0200c00, 0x000 },
1114 { 0x00000000, 0xc0201000, 0x000 },
1115 { 0x00000000, 0xc0201400, 0x000 },
1116 { 0x00000000, 0xc0201800, 0x000 },
1117 { 0x00000000, 0xc0201c00, 0x000 },
1118 { 0x00007f00, 0x00280a21, 0x000 },
1119 { 0x00004500, 0x002f0222, 0x000 },
1120 { 0x00000000, 0x0ce00000, 0x43c },
1121 { 0x00000000, 0xc0202000, 0x000 },
1122 { 0x00000000, 0x17000000, 0x000 },
1123 { 0x00000010, 0x00280a23, 0x000 },
1124 { 0x00000010, 0x002f0222, 0x000 },
1125 { 0x00000000, 0x0ce00000, 0x444 },
1126 { 0x81000000, 0x00204411, 0x000 },
1127 { 0x00000001, 0x00204811, 0x000 },
1128 { 0x00040000, 0x00694624, 0x614 },
1129 { 0x00000000, 0x00400000, 0x44d },
1130 { 0x81000000, 0x00204411, 0x000 },
1131 { 0x00000000, 0x00204811, 0x000 },
1132 { 0x0000216d, 0x00204411, 0x000 },
1133 { 0x00000000, 0x00204804, 0x000 },
1134 { 0x00000000, 0x00204805, 0x000 },
1135 { 0x00000000, 0x1ac00000, 0x449 },
1136 { 0x9e000000, 0x00204411, 0x000 },
1137 { 0xcafebabe, 0x00204811, 0x000 },
1138 { 0x00000000, 0x1ae00000, 0x44c },
1139 { 0x00000000, 0x002824f0, 0x000 },
1140 { 0x00000007, 0x00280a23, 0x000 },
1141 { 0x00000001, 0x002f0222, 0x000 },
1142 { 0x00000000, 0x0ae00000, 0x454 },
1143 { 0x00000000, 0x002f00c9, 0x000 },
1144 { 0x00000000, 0x04e00000, 0x46d },
1145 { 0x00000000, 0x00400000, 0x47a },
1146 { 0x00000002, 0x002f0222, 0x000 },
1147 { 0x00000000, 0x0ae00000, 0x459 },
1148 { 0x00000000, 0x002f00c9, 0x000 },
1149 { 0x00000000, 0x02e00000, 0x46d },
1150 { 0x00000000, 0x00400000, 0x47a },
1151 { 0x00000003, 0x002f0222, 0x000 },
1152 { 0x00000000, 0x0ae00000, 0x45e },
1153 { 0x00000000, 0x002f00c9, 0x000 },
1154 { 0x00000000, 0x0ce00000, 0x46d },
1155 { 0x00000000, 0x00400000, 0x47a },
1156 { 0x00000004, 0x002f0222, 0x000 },
1157 { 0x00000000, 0x0ae00000, 0x463 },
1158 { 0x00000000, 0x002f00c9, 0x000 },
1159 { 0x00000000, 0x0ae00000, 0x46d },
1160 { 0x00000000, 0x00400000, 0x47a },
1161 { 0x00000005, 0x002f0222, 0x000 },
1162 { 0x00000000, 0x0ae00000, 0x468 },
1163 { 0x00000000, 0x002f00c9, 0x000 },
1164 { 0x00000000, 0x06e00000, 0x46d },
1165 { 0x00000000, 0x00400000, 0x47a },
1166 { 0x00000006, 0x002f0222, 0x000 },
1167 { 0x00000000, 0x0ae00000, 0x46d },
1168 { 0x00000000, 0x002f00c9, 0x000 },
1169 { 0x00000000, 0x08e00000, 0x46d },
1170 { 0x00000000, 0x00400000, 0x47a },
1171 { 0x00007f00, 0x00280a21, 0x000 },
1172 { 0x00004500, 0x002f0222, 0x000 },
1173 { 0x00000000, 0x0ae00000, 0x000 },
1174 { 0x00000008, 0x00210a23, 0x000 },
1175 { 0x00000000, 0x14c00000, 0x477 },
1176 { 0x00002169, 0x00204411, 0x000 },
1177 { 0x00000000, 0xc0204800, 0x000 },
1178 { 0x00000000, 0xc0204800, 0x000 },
1179 { 0x00000000, 0xc0204800, 0x000 },
1180 { 0xcafebabe, 0x00404811, 0x000 },
1181 { 0x00000000, 0xc0204400, 0x000 },
1182 { 0x00000000, 0xc0200000, 0x000 },
1183 { 0x00000000, 0xc0404800, 0x000 },
1184 { 0x00007f00, 0x00280a21, 0x000 },
1185 { 0x00004500, 0x002f0222, 0x000 },
1186 { 0x00000000, 0x0ae00000, 0x480 },
1187 { 0x00000000, 0xc0200000, 0x000 },
1188 { 0x00000000, 0xc0200000, 0x000 },
1189 { 0x00000000, 0xc0400000, 0x000 },
1190 { 0x00000000, 0x00404c08, 0x43c },
1191 { 0x00000000, 0xc0200800, 0x000 },
1192 { 0x00000010, 0x40210e20, 0x000 },
1193 { 0x00000011, 0x40211220, 0x000 },
1194 { 0x00000012, 0x40211620, 0x000 },
1195 { 0x00002169, 0x00204411, 0x000 },
1196 { 0x00000000, 0x00204802, 0x000 },
1197 { 0x00000000, 0x00210225, 0x000 },
1198 { 0x00000000, 0x14e00000, 0x48a },
1199 { 0x00040000, 0xc0494a20, 0x48b },
1200 { 0xfffbffff, 0xc0284a20, 0x000 },
1201 { 0x00000000, 0x00210223, 0x000 },
1202 { 0x00000000, 0x14e00000, 0x497 },
1203 { 0x00000000, 0xc0204800, 0x000 },
1204 { 0x00000000, 0xc0204800, 0x000 },
1205 { 0x00000000, 0x00210224, 0x000 },
1206 { 0x00000000, 0x14c00000, 0x000 },
1207 { 0x81000000, 0x00204411, 0x000 },
1208 { 0x0000000c, 0x00204811, 0x000 },
1209 { 0x00000000, 0x00200010, 0x000 },
1210 { 0x00000000, 0x14c00000, 0x493 },
1211 { 0xa0000000, 0x00204411, 0x000 },
1212 { 0xcafebabe, 0x00404811, 0x000 },
1213 { 0x81000000, 0x00204411, 0x000 },
1214 { 0x00000004, 0x00204811, 0x000 },
1215 { 0x0000216b, 0x00204411, 0x000 },
1216 { 0x00000000, 0xc0204810, 0x000 },
1217 { 0x81000000, 0x00204411, 0x000 },
1218 { 0x00000005, 0x00204811, 0x000 },
1219 { 0x0000216c, 0x00204411, 0x000 },
1220 { 0x00000000, 0xc0204810, 0x000 },
1221 { 0x00000000, 0x002f0224, 0x000 },
1222 { 0x00000000, 0x0ce00000, 0x000 },
1223 { 0x00000000, 0x00400000, 0x491 },
1224 { 0x00000000, 0xc0210a20, 0x000 },
1225 { 0x00000000, 0x14c00000, 0x4ae },
1226 { 0x81000000, 0x00204411, 0x000 },
1227 { 0x00000000, 0x00204811, 0x000 },
1228 { 0x0000216d, 0x00204411, 0x000 },
1229 { 0x00000000, 0xc0204800, 0x000 },
1230 { 0x00000000, 0xc0204800, 0x000 },
1231 { 0x00000000, 0x1ac00000, 0x4a9 },
1232 { 0x9e000000, 0x00204411, 0x000 },
1233 { 0xcafebabe, 0x00204811, 0x000 },
1234 { 0x00000000, 0x1ae00000, 0x4ac },
1235 { 0x00000000, 0x00400000, 0x4b2 },
1236 { 0x81000000, 0x00204411, 0x000 },
1237 { 0x00000001, 0x00204811, 0x000 },
1238 { 0x00040000, 0xc0294620, 0x000 },
1239 { 0x00000000, 0xc0600000, 0x614 },
1240 { 0x00000001, 0x00210222, 0x000 },
1241 { 0x00000000, 0x14c00000, 0x4b9 },
1242 { 0x00002169, 0x00204411, 0x000 },
1243 { 0x00000000, 0xc0204800, 0x000 },
1244 { 0x00000000, 0xc0204800, 0x000 },
1245 { 0x00000000, 0x00204810, 0x000 },
1246 { 0xcafebabe, 0x00404811, 0x000 },
1247 { 0x00000000, 0xc0204400, 0x000 },
1248 { 0x00000000, 0xc0404810, 0x000 },
1249 { 0x81000000, 0x00204411, 0x000 },
1250 { 0x00000001, 0x00204811, 0x000 },
1251 { 0x000021f8, 0x00204411, 0x000 },
1252 { 0x0000000d, 0x00204811, 0x000 },
1253 { 0x000421f9, 0x00604411, 0x614 },
1254 { 0x00000000, 0x00210230, 0x000 },
1255 { 0x00000000, 0x14c00000, 0x4bb },
1256 { 0x00002180, 0x00204411, 0x000 },
1257 { 0x00000000, 0xc0204800, 0x000 },
1258 { 0x00000000, 0xc0200000, 0x000 },
1259 { 0x00000000, 0xc0204800, 0x000 },
1260 { 0x00000000, 0xc0200000, 0x000 },
1261 { 0x00000000, 0xc0404800, 0x000 },
1262 { 0x00000003, 0x00333e2f, 0x000 },
1263 { 0x00000001, 0x00210221, 0x000 },
1264 { 0x00000000, 0x14e00000, 0x4eb },
1265 { 0x00000035, 0x00200a2d, 0x000 },
1266 { 0x00040000, 0x18e00c11, 0x4da },
1267 { 0x00000001, 0x00333e2f, 0x000 },
1268 { 0x00002169, 0x00204411, 0x000 },
1269 { 0x00000000, 0x00204802, 0x000 },
1270 { 0x00000000, 0x00204803, 0x000 },
1271 { 0x00000008, 0x00300a22, 0x000 },
1272 { 0x00000000, 0xc0204800, 0x000 },
1273 { 0x00000000, 0xc0204800, 0x000 },
1274 { 0x00002169, 0x00204411, 0x000 },
1275 { 0x00000000, 0x00204802, 0x000 },
1276 { 0x00000000, 0x00204803, 0x000 },
1277 { 0x00000008, 0x00300a22, 0x000 },
1278 { 0x00000000, 0xc0204800, 0x000 },
1279 { 0x00000000, 0xd8c04800, 0x4ce },
1280 { 0x00002169, 0x00204411, 0x000 },
1281 { 0x00000000, 0x00204802, 0x000 },
1282 { 0x00000000, 0x00204803, 0x000 },
1283 { 0x00000008, 0x00300a22, 0x000 },
1284 { 0x00000000, 0xc0204800, 0x000 },
1285 { 0x00000000, 0xc0204800, 0x000 },
1286 { 0x00000036, 0x0020122d, 0x000 },
1287 { 0x00000000, 0x00290c83, 0x000 },
1288 { 0x00002169, 0x00204411, 0x000 },
1289 { 0x00000000, 0x00204802, 0x000 },
1290 { 0x00000000, 0x00204803, 0x000 },
1291 { 0x00000008, 0x00300a22, 0x000 },
1292 { 0x00000000, 0xc0204800, 0x000 },
1293 { 0x00000000, 0xc0204800, 0x000 },
1294 { 0x00000011, 0x00210224, 0x000 },
1295 { 0x00000000, 0x14c00000, 0x000 },
1296 { 0x00000000, 0x00400000, 0x491 },
1297 { 0x00000035, 0xc0203620, 0x000 },
1298 { 0x00000036, 0xc0403620, 0x000 },
1299 { 0x0000304a, 0x00204411, 0x000 },
1300 { 0xe0000000, 0xc0484a20, 0x000 },
1301 { 0x0000000f, 0x00210221, 0x000 },
1302 { 0x00000000, 0x14c00000, 0x4f2 },
1303 { 0x00000000, 0x00600000, 0x00b },
1304 { 0x00000000, 0xd9000000, 0x000 },
1305 { 0x00000000, 0xc0400400, 0x001 },
1306 { 0x81000000, 0x00204411, 0x000 },
1307 { 0x00000002, 0x00204811, 0x000 },
1308 { 0x000000ff, 0x00280e30, 0x000 },
1309 { 0x00000000, 0x002f0223, 0x000 },
1310 { 0x00000000, 0x0cc00000, 0x4f6 },
1311 { 0x00000000, 0xc0200800, 0x000 },
1312 { 0x00000000, 0x14c00000, 0x50b },
1313 { 0x00000000, 0x00200c11, 0x000 },
1314 { 0x00000024, 0x00203623, 0x000 },
1315 { 0x00000034, 0x00203623, 0x000 },
1316 { 0x00000032, 0x00203623, 0x000 },
1317 { 0x00000031, 0x00203623, 0x000 },
1318 { 0x0000001d, 0x00203623, 0x000 },
1319 { 0x0000002d, 0x00203623, 0x000 },
1320 { 0x0000002e, 0x00203623, 0x000 },
1321 { 0x0000001b, 0x00203623, 0x000 },
1322 { 0x0000001c, 0x00203623, 0x000 },
1323 { 0xffffe000, 0x00200c11, 0x000 },
1324 { 0x00000029, 0x00203623, 0x000 },
1325 { 0x0000002a, 0x00203623, 0x000 },
1326 { 0x00001fff, 0x00200c11, 0x000 },
1327 { 0x0000002b, 0x00203623, 0x000 },
1328 { 0x0000002c, 0x00203623, 0x000 },
1329 { 0xf1ffffff, 0x00283a2e, 0x000 },
1330 { 0x0000001a, 0xc0220e20, 0x000 },
1331 { 0x00000000, 0x0029386e, 0x000 },
1332 { 0x81000000, 0x00204411, 0x000 },
1333 { 0x00000006, 0x00204811, 0x000 },
1334 { 0x00000033, 0x40203620, 0x000 },
1335 { 0x87000000, 0x00204411, 0x000 },
1336 { 0x00000000, 0xc0204800, 0x000 },
1337 { 0x0000a1f4, 0x00204411, 0x000 },
1338 { 0x00000000, 0x00204810, 0x000 },
1339 { 0x9d000000, 0x00204411, 0x000 },
1340 { 0x0000001f, 0x40214a20, 0x000 },
1341 { 0x96000000, 0x00204411, 0x000 },
1342 { 0x00000000, 0xc0204800, 0x000 },
1343 { 0x00000000, 0xc0200c00, 0x000 },
1344 { 0x00000000, 0xc0201000, 0x000 },
1345 { 0x0000001f, 0x00211624, 0x000 },
1346 { 0x00000000, 0x14c00000, 0x000 },
1347 { 0x00000025, 0x00203623, 0x000 },
1348 { 0x00000003, 0x00281e23, 0x000 },
1349 { 0x00000008, 0x00222223, 0x000 },
1350 { 0xfffff000, 0x00282228, 0x000 },
1351 { 0x00000000, 0x002920e8, 0x000 },
1352 { 0x00000027, 0x00203628, 0x000 },
1353 { 0x00000018, 0x00211e23, 0x000 },
1354 { 0x00000028, 0x00203627, 0x000 },
1355 { 0x00000002, 0x00221624, 0x000 },
1356 { 0x00000000, 0x003014a8, 0x000 },
1357 { 0x00000026, 0x00203625, 0x000 },
1358 { 0x00000003, 0x00211a24, 0x000 },
1359 { 0x10000000, 0x00281a26, 0x000 },
1360 { 0xefffffff, 0x00283a2e, 0x000 },
1361 { 0x00000000, 0x004938ce, 0x602 },
1362 { 0x00000001, 0x40280a20, 0x000 },
1363 { 0x00000006, 0x40280e20, 0x000 },
1364 { 0x00000300, 0xc0281220, 0x000 },
1365 { 0x00000008, 0x00211224, 0x000 },
1366 { 0x00000000, 0xc0201620, 0x000 },
1367 { 0x00000000, 0xc0201a20, 0x000 },
1368 { 0x00000000, 0x00210222, 0x000 },
1369 { 0x00000000, 0x14c00000, 0x541 },
1370 { 0x81000000, 0x00204411, 0x000 },
1371 { 0x00000001, 0x00204811, 0x000 },
1372 { 0x00002258, 0x00300a24, 0x000 },
1373 { 0x00040000, 0x00694622, 0x614 },
1374 { 0x00002169, 0x00204411, 0x000 },
1375 { 0x00000000, 0x00204805, 0x000 },
1376 { 0x00020000, 0x00294a26, 0x000 },
1377 { 0x00000000, 0x00204810, 0x000 },
1378 { 0xcafebabe, 0x00204811, 0x000 },
1379 { 0x00000002, 0x002f0223, 0x000 },
1380 { 0x00000000, 0x0cc00000, 0x549 },
1381 { 0x00000000, 0xc0201c10, 0x000 },
1382 { 0x00000000, 0xc0400000, 0x55b },
1383 { 0x00000002, 0x002f0223, 0x000 },
1384 { 0x00000000, 0x0cc00000, 0x549 },
1385 { 0x81000000, 0x00204411, 0x000 },
1386 { 0x00000001, 0x00204811, 0x000 },
1387 { 0x00002258, 0x00300a24, 0x000 },
1388 { 0x00040000, 0x00694622, 0x614 },
1389 { 0x00000000, 0xc0201c10, 0x000 },
1390 { 0x00000000, 0xc0400000, 0x55b },
1391 { 0x00000000, 0x002f0223, 0x000 },
1392 { 0x00000000, 0x0cc00000, 0x54d },
1393 { 0x00000000, 0xc0201c00, 0x000 },
1394 { 0x00000000, 0xc0400000, 0x55b },
1395 { 0x00000004, 0x002f0223, 0x000 },
1396 { 0x00000000, 0x0cc00000, 0x559 },
1397 { 0x81000000, 0x00204411, 0x000 },
1398 { 0x00000000, 0x00204811, 0x000 },
1399 { 0x0000216d, 0x00204411, 0x000 },
1400 { 0x00000000, 0xc0204800, 0x000 },
1401 { 0x00000000, 0xc0204800, 0x000 },
1402 { 0x00000000, 0x1ac00000, 0x554 },
1403 { 0x9e000000, 0x00204411, 0x000 },
1404 { 0xcafebabe, 0x00204811, 0x000 },
1405 { 0x00000000, 0x1ae00000, 0x557 },
1406 { 0x00000000, 0x00401c10, 0x55b },
1407 { 0x00000000, 0xc0200000, 0x000 },
1408 { 0x00000000, 0xc0400000, 0x000 },
1409 { 0x00000000, 0x0ee00000, 0x55d },
1410 { 0x00000000, 0x00600000, 0x5a4 },
1411 { 0x00000000, 0x002f0224, 0x000 },
1412 { 0x00000000, 0x0cc00000, 0x56d },
1413 { 0x0000a2b7, 0x00204411, 0x000 },
1414 { 0x00000000, 0x00204807, 0x000 },
1415 { 0x81000000, 0x00204411, 0x000 },
1416 { 0x00000001, 0x00204811, 0x000 },
1417 { 0x0004a2b6, 0x00604411, 0x614 },
1418 { 0x0000001a, 0x00212230, 0x000 },
1419 { 0x00000006, 0x00222630, 0x000 },
1420 { 0x0000a2c4, 0x00204411, 0x000 },
1421 { 0x00000000, 0x003048e9, 0x000 },
1422 { 0x00000000, 0x00e00000, 0x56b },
1423 { 0x0000a2d1, 0x00204411, 0x000 },
1424 { 0x00000000, 0x00404808, 0x000 },
1425 { 0x0000a2d1, 0x00204411, 0x000 },
1426 { 0x00000001, 0x00504a28, 0x000 },
1427 { 0x00000001, 0x002f0224, 0x000 },
1428 { 0x00000000, 0x0cc00000, 0x57d },
1429 { 0x0000a2bb, 0x00204411, 0x000 },
1430 { 0x00000000, 0x00204807, 0x000 },
1431 { 0x81000000, 0x00204411, 0x000 },
1432 { 0x00000001, 0x00204811, 0x000 },
1433 { 0x0004a2ba, 0x00604411, 0x614 },
1434 { 0x0000001a, 0x00212230, 0x000 },
1435 { 0x00000006, 0x00222630, 0x000 },
1436 { 0x0000a2c5, 0x00204411, 0x000 },
1437 { 0x00000000, 0x003048e9, 0x000 },
1438 { 0x00000000, 0x00e00000, 0x57b },
1439 { 0x0000a2d2, 0x00204411, 0x000 },
1440 { 0x00000000, 0x00404808, 0x000 },
1441 { 0x0000a2d2, 0x00204411, 0x000 },
1442 { 0x00000001, 0x00504a28, 0x000 },
1443 { 0x00000002, 0x002f0224, 0x000 },
1444 { 0x00000000, 0x0cc00000, 0x58d },
1445 { 0x0000a2bf, 0x00204411, 0x000 },
1446 { 0x00000000, 0x00204807, 0x000 },
1447 { 0x81000000, 0x00204411, 0x000 },
1448 { 0x00000001, 0x00204811, 0x000 },
1449 { 0x0004a2be, 0x00604411, 0x614 },
1450 { 0x0000001a, 0x00212230, 0x000 },
1451 { 0x00000006, 0x00222630, 0x000 },
1452 { 0x0000a2c6, 0x00204411, 0x000 },
1453 { 0x00000000, 0x003048e9, 0x000 },
1454 { 0x00000000, 0x00e00000, 0x58b },
1455 { 0x0000a2d3, 0x00204411, 0x000 },
1456 { 0x00000000, 0x00404808, 0x000 },
1457 { 0x0000a2d3, 0x00204411, 0x000 },
1458 { 0x00000001, 0x00504a28, 0x000 },
1459 { 0x0000a2c3, 0x00204411, 0x000 },
1460 { 0x00000000, 0x00204807, 0x000 },
1461 { 0x81000000, 0x00204411, 0x000 },
1462 { 0x00000001, 0x00204811, 0x000 },
1463 { 0x0004a2c2, 0x00604411, 0x614 },
1464 { 0x0000001a, 0x00212230, 0x000 },
1465 { 0x00000006, 0x00222630, 0x000 },
1466 { 0x0000a2c7, 0x00204411, 0x000 },
1467 { 0x00000000, 0x003048e9, 0x000 },
1468 { 0x00000000, 0x00e00000, 0x599 },
1469 { 0x0000a2d4, 0x00204411, 0x000 },
1470 { 0x00000000, 0x00404808, 0x000 },
1471 { 0x0000a2d4, 0x00204411, 0x000 },
1472 { 0x00000001, 0x00504a28, 0x000 },
1473 { 0x85000000, 0x00204411, 0x000 },
1474 { 0x00000000, 0x00204801, 0x000 },
1475 { 0x0000304a, 0x00204411, 0x000 },
1476 { 0x01000000, 0x00204811, 0x000 },
1477 { 0x00000000, 0x00400000, 0x59f },
1478 { 0xa4000000, 0xc0204411, 0x000 },
1479 { 0x00000000, 0xc0404800, 0x000 },
1480 { 0x00000000, 0xc0600000, 0x5a4 },
1481 { 0x00000000, 0xc0400400, 0x001 },
1482 { 0x0001a2a4, 0x00204411, 0x000 },
1483 { 0x00000000, 0x00204811, 0x000 },
1484 { 0x00000000, 0x00204811, 0x000 },
1485 { 0x00000000, 0x00204811, 0x000 },
1486 { 0x00000000, 0x00204811, 0x000 },
1487 { 0x00000005, 0x00204811, 0x000 },
1488 { 0x0000a1f4, 0x00204411, 0x000 },
1489 { 0x00000000, 0x00204811, 0x000 },
1490 { 0x88000000, 0x00204411, 0x000 },
1491 { 0x00000001, 0x00204811, 0x000 },
1492 { 0xff000000, 0x00204411, 0x000 },
1493 { 0x00000000, 0x00204811, 0x000 },
1494 { 0x00000001, 0x00204811, 0x000 },
1495 { 0x00000002, 0x00804811, 0x000 },
1496 { 0x00000000, 0x0ee00000, 0x5b7 },
1497 { 0x00001000, 0x00200811, 0x000 },
1498 { 0x00000034, 0x00203622, 0x000 },
1499 { 0x00000000, 0x00600000, 0x5bb },
1500 { 0x00000000, 0x00600000, 0x5a4 },
1501 { 0x98000000, 0x00204411, 0x000 },
1502 { 0x00000000, 0x00804811, 0x000 },
1503 { 0x00000000, 0xc0600000, 0x5bb },
1504 { 0x00000000, 0xc0400400, 0x001 },
1505 { 0x0000a2a4, 0x00204411, 0x000 },
1506 { 0x00000022, 0x00204811, 0x000 },
1507 { 0x89000000, 0x00204411, 0x000 },
1508 { 0x00000001, 0x00204811, 0x000 },
1509 { 0xff000000, 0x00204411, 0x000 },
1510 { 0x00000000, 0x00204811, 0x000 },
1511 { 0x00000001, 0x00204811, 0x000 },
1512 { 0x00000002, 0x00804811, 0x000 },
1513 { 0x0000217a, 0xc0204411, 0x000 },
1514 { 0x00000000, 0x00404811, 0x000 },
1515 { 0x97000000, 0x00204411, 0x000 },
1516 { 0x00000000, 0x00204811, 0x000 },
1517 { 0x8a000000, 0x00204411, 0x000 },
1518 { 0x00000000, 0x00204811, 0x000 },
1519 { 0xff000000, 0x00204411, 0x000 },
1520 { 0x00000000, 0x00204811, 0x000 },
1521 { 0x00000001, 0x00204811, 0x000 },
1522 { 0x00000002, 0x00804811, 0x000 },
1523 { 0x00000000, 0x00600000, 0x5e1 },
1524 { 0x00002010, 0x00204411, 0x000 },
1525 { 0x00008000, 0x00204811, 0x000 },
1526 { 0x0001a2a4, 0xc0204411, 0x000 },
1527 { 0x00000000, 0x00204811, 0x000 },
1528 { 0x00000016, 0x00604811, 0x35e },
1529 { 0x00000016, 0x00204811, 0x000 },
1530 { 0x00002010, 0x00204411, 0x000 },
1531 { 0x00010000, 0x00204811, 0x000 },
1532 { 0x81000000, 0x00204411, 0x000 },
1533 { 0x00000001, 0x00204811, 0x000 },
1534 { 0x0000217c, 0x00204411, 0x000 },
1535 { 0x09800000, 0x00204811, 0x000 },
1536 { 0xffffffff, 0x00204811, 0x000 },
1537 { 0x00000000, 0x00204811, 0x000 },
1538 { 0x00000000, 0x17000000, 0x000 },
1539 { 0x0004217f, 0x00604411, 0x614 },
1540 { 0x0000001f, 0x00210230, 0x000 },
1541 { 0x00000000, 0x14c00000, 0x000 },
1542 { 0x00000004, 0x00404c11, 0x5dc },
1543 { 0x0000001d, 0x00201e2d, 0x000 },
1544 { 0x00000004, 0x00291e27, 0x000 },
1545 { 0x0000001d, 0x00803627, 0x000 },
1546 { 0x0000001d, 0x00201e2d, 0x000 },
1547 { 0xfffffffb, 0x00281e27, 0x000 },
1548 { 0x0000001d, 0x00803627, 0x000 },
1549 { 0x0000001d, 0x00201e2d, 0x000 },
1550 { 0x00000008, 0x00291e27, 0x000 },
1551 { 0x0000001d, 0x00803627, 0x000 },
1552 { 0x0000001d, 0x00201e2d, 0x000 },
1553 { 0xfffffff7, 0x00281e27, 0x000 },
1554 { 0x0000001d, 0x00803627, 0x000 },
1555 { 0x00002010, 0x00204411, 0x000 },
1556 { 0x00008000, 0x00204811, 0x000 },
1557 { 0x0001a2a4, 0x00204411, 0x000 },
1558 { 0x00000000, 0x00204811, 0x000 },
1559 { 0x00000016, 0x00604811, 0x35e },
1560 { 0x00000016, 0x00204811, 0x000 },
1561 { 0x00002010, 0x00204411, 0x000 },
1562 { 0x00010000, 0x00204811, 0x000 },
1563 { 0x0000217c, 0x00204411, 0x000 },
1564 { 0x01800000, 0x00204811, 0x000 },
1565 { 0x00ffffff, 0x00204811, 0x000 },
1566 { 0x00000000, 0x00204811, 0x000 },
1567 { 0x00000000, 0x17000000, 0x000 },
1568 { 0x81000000, 0x00204411, 0x000 },
1569 { 0x00000001, 0x00204811, 0x000 },
1570 { 0x0004217f, 0x00604411, 0x614 },
1571 { 0x00000000, 0x00200010, 0x000 },
1572 { 0x00000000, 0x14c00000, 0x613 },
1573 { 0x00000010, 0x00404c11, 0x5f9 },
1574 { 0x00000000, 0xc0200400, 0x000 },
1575 { 0x00000000, 0x38c00000, 0x000 },
1576 { 0x00000025, 0x00200a2d, 0x000 },
1577 { 0x00000026, 0x00200e2d, 0x000 },
1578 { 0x00000027, 0x0020122d, 0x000 },
1579 { 0x00000028, 0x0020162d, 0x000 },
1580 { 0x00002169, 0x00204411, 0x000 },
1581 { 0x00000000, 0x00204804, 0x000 },
1582 { 0x00000000, 0x00204805, 0x000 },
1583 { 0x00000000, 0x00204801, 0x000 },
1584 { 0xcafebabe, 0x00204811, 0x000 },
1585 { 0x00000004, 0x00301224, 0x000 },
1586 { 0x00000000, 0x002f0064, 0x000 },
1587 { 0x00000000, 0x0cc00000, 0x612 },
1588 { 0x00000003, 0x00281a22, 0x000 },
1589 { 0x00000008, 0x00221222, 0x000 },
1590 { 0xfffff000, 0x00281224, 0x000 },
1591 { 0x00000000, 0x002910c4, 0x000 },
1592 { 0x00000027, 0x00403624, 0x000 },
1593 { 0x00000000, 0x00800000, 0x000 },
1594 { 0x00000000, 0x1ac00000, 0x614 },
1595 { 0x9f000000, 0x00204411, 0x000 },
1596 { 0xcafebabe, 0x00204811, 0x000 },
1597 { 0x00000000, 0x1ae00000, 0x617 },
1598 { 0x00000000, 0x00800000, 0x000 },
1599 { 0x00000000, 0x00600000, 0x00b },
1600 { 0x00001000, 0x00600411, 0x2fe },
1601 { 0x00000000, 0x00200411, 0x000 },
1602 { 0x00000000, 0x00600811, 0x19f },
1603 { 0x0000225c, 0x00204411, 0x000 },
1604 { 0x00000003, 0x00204811, 0x000 },
1605 { 0x00002256, 0x00204411, 0x000 },
1606 { 0x0000001b, 0x00204811, 0x000 },
1607 { 0x0000a1fc, 0x00204411, 0x000 },
1608 { 0x00000001, 0x00204811, 0x000 },
1609 { 0x0001a1fd, 0xc0204411, 0x000 },
1610 { 0x00000029, 0x00201e2d, 0x000 },
1611 { 0x00000010, 0x00221e27, 0x000 },
1612 { 0x0000002c, 0x0020222d, 0x000 },
1613 { 0x0000ffff, 0x00282228, 0x000 },
1614 { 0x00000000, 0x00294907, 0x000 },
1615 { 0x00000000, 0x00204811, 0x000 },
1616 { 0x0000002a, 0x0020222d, 0x000 },
1617 { 0x0000ffff, 0x00282228, 0x000 },
1618 { 0x00000000, 0x00294907, 0x000 },
1619 { 0x00000000, 0x00204811, 0x000 },
1620 { 0x0000002b, 0x00201e2d, 0x000 },
1621 { 0x00000010, 0x00221e27, 0x000 },
1622 { 0x00000000, 0x00294907, 0x000 },
1623 { 0x00000000, 0x00404811, 0x000 },
1624 { 0x00000000, 0x00000000, 0x000 },
1625 { 0x00000000, 0x00000000, 0x000 },
1626 { 0x00000000, 0x00000000, 0x000 },
1627 { 0x00000000, 0x00000000, 0x000 },
1628 { 0x00000000, 0x00000000, 0x000 },
1629 { 0x00000000, 0x00000000, 0x000 },
1630 { 0x00000000, 0x00000000, 0x000 },
1631 { 0x00000000, 0x00000000, 0x000 },
1632 { 0x00000000, 0x00000000, 0x000 },
1633 { 0x00000000, 0x00000000, 0x000 },
1634 { 0x00000000, 0x00000000, 0x000 },
1635 { 0x00000000, 0x00000000, 0x000 },
1636 { 0x00000000, 0x00000000, 0x000 },
1637 { 0x00000000, 0x00000000, 0x000 },
1638 { 0x00000000, 0x00000000, 0x000 },
1639 { 0x00000000, 0x00000000, 0x000 },
1640 { 0x00000000, 0x00000000, 0x000 },
1641 { 0x00000000, 0x00000000, 0x000 },
1642 { 0x00000000, 0x00000000, 0x000 },
1643 { 0x00000000, 0x00000000, 0x000 },
1644 { 0x00000000, 0x00000000, 0x000 },
1645 { 0x00000000, 0x00000000, 0x000 },
1646 { 0x00000000, 0x00000000, 0x000 },
1647 { 0x00000000, 0x00000000, 0x000 },
1648 { 0x00000000, 0x00000000, 0x000 },
1649 { 0x00000000, 0x00000000, 0x000 },
1650 { 0x00000000, 0x00000000, 0x000 },
1651 { 0x00000000, 0x00000000, 0x000 },
1652 { 0x00000000, 0x00000000, 0x000 },
1653 { 0x00000000, 0x00000000, 0x000 },
1654 { 0x00000000, 0x00000000, 0x000 },
1655 { 0x00000000, 0x00000000, 0x000 },
1656 { 0x00000000, 0x00000000, 0x000 },
1657 { 0x00000000, 0x00000000, 0x000 },
1658 { 0x00000000, 0x00000000, 0x000 },
1659 { 0x00000000, 0x00000000, 0x000 },
1660 { 0x00000000, 0x00000000, 0x000 },
1661 { 0x00000000, 0x00000000, 0x000 },
1662 { 0x00000000, 0x00000000, 0x000 },
1663 { 0x00000000, 0x00000000, 0x000 },
1664 { 0x00000000, 0x00000000, 0x000 },
1665 { 0x00000000, 0x00000000, 0x000 },
1666 { 0x00000000, 0x00000000, 0x000 },
1667 { 0x00000000, 0x00000000, 0x000 },
1668 { 0x00000000, 0x00000000, 0x000 },
1669 { 0x00000000, 0x00000000, 0x000 },
1670 { 0x00000000, 0x00000000, 0x000 },
1671 { 0x00000000, 0x00000000, 0x000 },
1672 { 0x00000000, 0x00000000, 0x000 },
1673 { 0x00000000, 0x00000000, 0x000 },
1674 { 0x00000000, 0x00000000, 0x000 },
1675 { 0x00000000, 0x00000000, 0x000 },
1676 { 0x00000000, 0x00000000, 0x000 },
1677 { 0x00000000, 0x00000000, 0x000 },
1678 { 0x00000000, 0x00000000, 0x000 },
1679 { 0x00000000, 0x00000000, 0x000 },
1680 { 0x00000000, 0x00000000, 0x000 },
1681 { 0x00000000, 0x00000000, 0x000 },
1682 { 0x00000000, 0x00000000, 0x000 },
1683 { 0x00000000, 0x00000000, 0x000 },
1684 { 0x00000000, 0x00000000, 0x000 },
1685 { 0x00000000, 0x00000000, 0x000 },
1686 { 0x00000000, 0x00000000, 0x000 },
1687 { 0x00000000, 0x00000000, 0x000 },
1688 { 0x00000000, 0x00000000, 0x000 },
1689 { 0x00000000, 0x00000000, 0x000 },
1690 { 0x00000000, 0x00000000, 0x000 },
1691 { 0x00000000, 0x00000000, 0x000 },
1692 { 0x00000000, 0x00000000, 0x000 },
1693 { 0x00000000, 0x00000000, 0x000 },
1694 { 0x00000000, 0x00000000, 0x000 },
1695 { 0x00000000, 0x00000000, 0x000 },
1696 { 0x00000000, 0x00000000, 0x000 },
1697 { 0x00000000, 0x00000000, 0x000 },
1698 { 0x00000000, 0x00000000, 0x000 },
1699 { 0x00000000, 0x00000000, 0x000 },
1700 { 0x00000000, 0x00000000, 0x000 },
1701 { 0x00000000, 0x00000000, 0x000 },
1702 { 0x00000000, 0x00000000, 0x000 },
1703 { 0x00000000, 0x00000000, 0x000 },
1704 { 0x00000000, 0x00000000, 0x000 },
1705 { 0x00000000, 0x00000000, 0x000 },
1706 { 0x00000000, 0x00000000, 0x000 },
1707 { 0x00000000, 0x00000000, 0x000 },
1708 { 0x00000000, 0x00000000, 0x000 },
1709 { 0x00000000, 0x00000000, 0x000 },
1710 { 0x00000000, 0x00000000, 0x000 },
1711 { 0x00000000, 0x00000000, 0x000 },
1712 { 0x00000000, 0x00000000, 0x000 },
1713 { 0x00000000, 0x00000000, 0x000 },
1714 { 0x00000000, 0x00000000, 0x000 },
1715 { 0x00000000, 0x00000000, 0x000 },
1716 { 0x00000000, 0x00000000, 0x000 },
1717 { 0x00000000, 0x00000000, 0x000 },
1718 { 0x00000000, 0x00000000, 0x000 },
1719 { 0x00000000, 0x00000000, 0x000 },
1720 { 0x00000000, 0x00000000, 0x000 },
1721 { 0x00000000, 0x00000000, 0x000 },
1722 { 0x00000000, 0x00000000, 0x000 },
1723 { 0x00000000, 0x00000000, 0x000 },
1724 { 0x00000000, 0x00000000, 0x000 },
1725 { 0x00000000, 0x00000000, 0x000 },
1726 { 0x00000000, 0x00000000, 0x000 },
1727 { 0x00000000, 0x00000000, 0x000 },
1728 { 0x00000000, 0x00000000, 0x000 },
1729 { 0x00000000, 0x00000000, 0x000 },
1730 { 0x00000000, 0x00000000, 0x000 },
1731 { 0x00000000, 0x00000000, 0x000 },
1732 { 0x00000000, 0x00000000, 0x000 },
1733 { 0x00000000, 0x00000000, 0x000 },
1734 { 0x00000000, 0x00000000, 0x000 },
1735 { 0x00000000, 0x00000000, 0x000 },
1736 { 0x00000000, 0x00000000, 0x000 },
1737 { 0x00000000, 0x00000000, 0x000 },
1738 { 0x00000000, 0x00000000, 0x000 },
1739 { 0x00000000, 0x00000000, 0x000 },
1740 { 0x00000000, 0x00000000, 0x000 },
1741 { 0x00000000, 0x00000000, 0x000 },
1742 { 0x00000000, 0x00000000, 0x000 },
1743 { 0x00000000, 0x00000000, 0x000 },
1744 { 0x00000000, 0x00000000, 0x000 },
1745 { 0x00000000, 0x00000000, 0x000 },
1746 { 0x00000000, 0x00000000, 0x000 },
1747 { 0x00000000, 0x00000000, 0x000 },
1748 { 0x00000000, 0x00000000, 0x000 },
1749 { 0x00000000, 0x00000000, 0x000 },
1750 { 0x00000000, 0x00000000, 0x000 },
1751 { 0x00000000, 0x00000000, 0x000 },
1752 { 0x00000000, 0x00000000, 0x000 },
1753 { 0x00000000, 0x00000000, 0x000 },
1754 { 0x00000000, 0x00000000, 0x000 },
1755 { 0x00000000, 0x00000000, 0x000 },
1756 { 0x00000000, 0x00000000, 0x000 },
1757 { 0x00000000, 0x00000000, 0x000 },
1758 { 0x00000000, 0x00000000, 0x000 },
1759 { 0x00000000, 0x00000000, 0x000 },
1760 { 0x00000000, 0x00000000, 0x000 },
1761 { 0x00000000, 0x00000000, 0x000 },
1762 { 0x00000000, 0x00000000, 0x000 },
1763 { 0x00000000, 0x00000000, 0x000 },
1764 { 0x00000000, 0x00000000, 0x000 },
1765 { 0x00000000, 0x00000000, 0x000 },
1766 { 0x00000000, 0x00000000, 0x000 },
1767 { 0x00000000, 0x00000000, 0x000 },
1768 { 0x00000000, 0x00000000, 0x000 },
1769 { 0x00000000, 0x00000000, 0x000 },
1770 { 0x00000000, 0x00000000, 0x000 },
1771 { 0x00000000, 0x00000000, 0x000 },
1772 { 0x00000000, 0x00000000, 0x000 },
1773 { 0x00000000, 0x00000000, 0x000 },
1774 { 0x00000000, 0x00000000, 0x000 },
1775 { 0x00000000, 0x00000000, 0x000 },
1776 { 0x00000000, 0x00000000, 0x000 },
1777 { 0x00000000, 0x00000000, 0x000 },
1778 { 0x00000000, 0x00000000, 0x000 },
1779 { 0x00000000, 0x00000000, 0x000 },
1780 { 0x00000000, 0x00000000, 0x000 },
1781 { 0x00000000, 0x00000000, 0x000 },
1782 { 0x00000000, 0x00000000, 0x000 },
1783 { 0x00000000, 0x00000000, 0x000 },
1784 { 0x00000000, 0x00000000, 0x000 },
1785 { 0x00000000, 0x00000000, 0x000 },
1786 { 0x00000000, 0x00000000, 0x000 },
1787 { 0x00000000, 0x00000000, 0x000 },
1788 { 0x00000000, 0x00000000, 0x000 },
1789 { 0x00000000, 0x00000000, 0x000 },
1790 { 0x00000000, 0x00000000, 0x000 },
1791 { 0x00000000, 0x00000000, 0x000 },
1792 { 0x00000000, 0x00000000, 0x000 },
1793 { 0x00000000, 0x00000000, 0x000 },
1794 { 0x00000000, 0x00000000, 0x000 },
1795 { 0x00000000, 0x00000000, 0x000 },
1796 { 0x00000000, 0x00000000, 0x000 },
1797 { 0x00000000, 0x00000000, 0x000 },
1798 { 0x00000000, 0x00000000, 0x000 },
1799 { 0x00000000, 0x00000000, 0x000 },
1800 { 0x00000000, 0x00000000, 0x000 },
1801 { 0x00000000, 0x00000000, 0x000 },
1802 { 0x013304ef, 0x059b0239, 0x000 },
1803 { 0x01b00159, 0x0425059b, 0x000 },
1804 { 0x021201f6, 0x02390142, 0x000 },
1805 { 0x0210022e, 0x0289022a, 0x000 },
1806 { 0x03c2059b, 0x059b059b, 0x000 },
1807 { 0x05cd05ce, 0x0308059b, 0x000 },
1808 { 0x059b05a0, 0x03090329, 0x000 },
1809 { 0x0313026b, 0x032b031d, 0x000 },
1810 { 0x059b059b, 0x059b059b, 0x000 },
1811 { 0x059b052c, 0x059b059b, 0x000 },
1812 { 0x03a5059b, 0x04a2032d, 0x000 },
1813 { 0x04810433, 0x0423059b, 0x000 },
1814 { 0x04bb04ed, 0x042704c8, 0x000 },
1815 { 0x043304f4, 0x033a0365, 0x000 },
1816 { 0x059b059b, 0x059b059b, 0x000 },
1817 { 0x059b059b, 0x059b059b, 0x000 },
1818 { 0x059b059b, 0x05b905a2, 0x000 },
1819 { 0x059b059b, 0x0007059b, 0x000 },
1820 { 0x059b059b, 0x059b059b, 0x000 },
1821 { 0x059b059b, 0x059b059b, 0x000 },
1822 { 0x03e303d8, 0x03f303f1, 0x000 },
1823 { 0x03f903f5, 0x03f703fb, 0x000 },
1824 { 0x04070403, 0x040f040b, 0x000 },
1825 { 0x04170413, 0x041f041b, 0x000 },
1826 { 0x059b059b, 0x059b059b, 0x000 },
1827 { 0x059b059b, 0x059b059b, 0x000 },
1828 { 0x059b059b, 0x059b059b, 0x000 },
1829 { 0x00020600, 0x06190006, 0x000 },
1830};
1831
1832static const u32 R600_pfp_microcode[] = {
18330xd40071,
18340xd40072,
18350xca0400,
18360xa00000,
18370x7e828b,
18380x800003,
18390xca0400,
18400xd4401e,
18410xee001e,
18420xca0400,
18430xa00000,
18440x7e828b,
18450xc41838,
18460xca2400,
18470xca2800,
18480x9581a8,
18490xc41c3a,
18500xc3c000,
18510xca0800,
18520xca0c00,
18530x7c744b,
18540xc20005,
18550x99c000,
18560xc41c3a,
18570x7c744c,
18580xc0fff0,
18590x042c04,
18600x309002,
18610x7d2500,
18620x351402,
18630x7d350b,
18640x255403,
18650x7cd580,
18660x259c03,
18670x95c004,
18680xd5001b,
18690x7eddc1,
18700x7d9d80,
18710xd6801b,
18720xd5801b,
18730xd4401e,
18740xd5401e,
18750xd6401e,
18760xd6801e,
18770xd4801e,
18780xd4c01e,
18790x9783d4,
18800xd5c01e,
18810xca0800,
18820x80001b,
18830xca0c00,
18840xe4011e,
18850xd4001e,
18860x80000d,
18870xc41838,
18880xe4013e,
18890xd4001e,
18900x80000d,
18910xc41838,
18920xd4401e,
18930xee001e,
18940xca0400,
18950xa00000,
18960x7e828b,
18970xe4011e,
18980xd4001e,
18990xd4401e,
19000xee001e,
19010xca0400,
19020xa00000,
19030x7e828b,
19040xe4013e,
19050xd4001e,
19060xd4401e,
19070xee001e,
19080xca0400,
19090xa00000,
19100x7e828b,
19110xca1800,
19120xd4401e,
19130xd5801e,
19140x800054,
19150xd40073,
19160xd4401e,
19170xca0800,
19180xca0c00,
19190xca1000,
19200xd48019,
19210xd4c018,
19220xd50017,
19230xd4801e,
19240xd4c01e,
19250xd5001e,
19260xe2001e,
19270xca0400,
19280xa00000,
19290x7e828b,
19300xca0800,
19310xd48060,
19320xd4401e,
19330x800002,
19340xd4801e,
19350xca0800,
19360xd48061,
19370xd4401e,
19380x800002,
19390xd4801e,
19400xca0800,
19410xca0c00,
19420xd4401e,
19430xd48016,
19440xd4c016,
19450xd4801e,
19460x8001b9,
19470xd4c01e,
19480xc6083e,
19490xca0c00,
19500xca1000,
19510x948004,
19520xca1400,
19530xe420f3,
19540xd42013,
19550xd56065,
19560xd4e01c,
19570xd5201c,
19580xd5601c,
19590x800002,
19600x062001,
19610xc6083e,
19620xca0c00,
19630xca1000,
19640x9483f7,
19650xca1400,
19660xe420f3,
19670x80007a,
19680xd42013,
19690xc6083e,
19700xca0c00,
19710xca1000,
19720x9883ef,
19730xca1400,
19740xd40064,
19750x80008e,
19760x000000,
19770xc41432,
19780xc6183e,
19790xc4082f,
19800x954005,
19810xc40c30,
19820xd4401e,
19830x800002,
19840xee001e,
19850x9583f5,
19860xc41031,
19870xd44033,
19880xd52065,
19890xd4a01c,
19900xd4e01c,
19910xd5201c,
19920xd40073,
19930xe4015e,
19940xd4001e,
19950x8001b9,
19960x062001,
19970x0a2001,
19980xd60074,
19990xc40836,
20000xc61040,
20010x988007,
20020xcc3835,
20030x95010f,
20040xd4001f,
20050xd46062,
20060x800002,
20070xd42062,
20080xcc1433,
20090x8401bc,
20100xd40070,
20110xd5401e,
20120x800002,
20130xee001e,
20140xca0c00,
20150xca1000,
20160xd4c01a,
20170x8401bc,
20180xd5001a,
20190xcc0443,
20200x35101f,
20210x2c9401,
20220x7d098b,
20230x984005,
20240x7d15cb,
20250xd4001a,
20260x8001b9,
20270xd4006d,
20280x344401,
20290xcc0c44,
20300x98403a,
20310xcc2c46,
20320x958004,
20330xcc0445,
20340x8001b9,
20350xd4001a,
20360xd4c01a,
20370x282801,
20380x8400f3,
20390xcc1003,
20400x98801b,
20410x04380c,
20420x8400f3,
20430xcc1003,
20440x988017,
20450x043808,
20460x8400f3,
20470xcc1003,
20480x988013,
20490x043804,
20500x8400f3,
20510xcc1003,
20520x988014,
20530xcc1047,
20540x9a8009,
20550xcc1448,
20560x9840da,
20570xd4006d,
20580xcc1844,
20590xd5001a,
20600xd5401a,
20610x8000cc,
20620xd5801a,
20630x96c0d3,
20640xd4006d,
20650x8001b9,
20660xd4006e,
20670x9ac003,
20680xd4006d,
20690xd4006e,
20700x800002,
20710xec007f,
20720x9ac0ca,
20730xd4006d,
20740x8001b9,
20750xd4006e,
20760xcc1403,
20770xcc1803,
20780xcc1c03,
20790x7d9103,
20800x7dd583,
20810x7d190c,
20820x35cc1f,
20830x35701f,
20840x7cf0cb,
20850x7cd08b,
20860x880000,
20870x7e8e8b,
20880x95c004,
20890xd4006e,
20900x8001b9,
20910xd4001a,
20920xd4c01a,
20930xcc0803,
20940xcc0c03,
20950xcc1003,
20960xcc1403,
20970xcc1803,
20980xcc1c03,
20990xcc2403,
21000xcc2803,
21010x35c41f,
21020x36b01f,
21030x7c704b,
21040x34f01f,
21050x7c704b,
21060x35701f,
21070x7c704b,
21080x7d8881,
21090x7dccc1,
21100x7e5101,
21110x7e9541,
21120x7c9082,
21130x7cd4c2,
21140x7c848b,
21150x9ac003,
21160x7c8c8b,
21170x2c8801,
21180x98809c,
21190xd4006d,
21200x98409a,
21210xd4006e,
21220xcc0847,
21230xcc0c48,
21240xcc1044,
21250xd4801a,
21260xd4c01a,
21270x800104,
21280xd5001a,
21290xcc0832,
21300xd40032,
21310x9482d8,
21320xca0c00,
21330xd4401e,
21340x800002,
21350xd4001e,
21360xe4011e,
21370xd4001e,
21380xca0800,
21390xca0c00,
21400xca1000,
21410xd4401e,
21420xca1400,
21430xd4801e,
21440xd4c01e,
21450xd5001e,
21460xd5401e,
21470xd54034,
21480x800002,
21490xee001e,
21500x280404,
21510xe2001a,
21520xe2001a,
21530xd4401a,
21540xca3800,
21550xcc0803,
21560xcc0c03,
21570xcc0c03,
21580xcc0c03,
21590x9882bc,
21600x000000,
21610x8401bc,
21620xd7806f,
21630x800002,
21640xee001f,
21650xca0400,
21660xc2ff00,
21670xcc0834,
21680xc13fff,
21690x7c74cb,
21700x7cc90b,
21710x7d010f,
21720x9902af,
21730x7c738b,
21740x8401bc,
21750xd7806f,
21760x800002,
21770xee001f,
21780xca0800,
21790x281900,
21800x7d898b,
21810x958014,
21820x281404,
21830xca0c00,
21840xca1000,
21850xca1c00,
21860xca2400,
21870xe2001f,
21880xd4c01a,
21890xd5001a,
21900xd5401a,
21910xcc1803,
21920xcc2c03,
21930xcc2c03,
21940xcc2c03,
21950x7da58b,
21960x7d9c47,
21970x984296,
21980x000000,
21990x800164,
22000xd4c01a,
22010xd4401e,
22020xd4801e,
22030x800002,
22040xee001e,
22050xe4011e,
22060xd4001e,
22070xd4401e,
22080xee001e,
22090xca0400,
22100xa00000,
22110x7e828b,
22120xe4013e,
22130xd4001e,
22140xd4401e,
22150xee001e,
22160xca0400,
22170xa00000,
22180x7e828b,
22190xca0800,
22200x248c06,
22210x0ccc06,
22220x98c006,
22230xcc1049,
22240x990004,
22250xd40071,
22260xe4011e,
22270xd4001e,
22280xd4401e,
22290xd4801e,
22300x800002,
22310xee001e,
22320xca0800,
22330xca0c00,
22340x34d018,
22350x251001,
22360x95001f,
22370xc17fff,
22380xca1000,
22390xca1400,
22400xca1800,
22410xd4801d,
22420xd4c01d,
22430x7db18b,
22440xc14202,
22450xc2c001,
22460xd5801d,
22470x34dc0e,
22480x7d5d4c,
22490x7f734c,
22500xd7401e,
22510xd5001e,
22520xd5401e,
22530xc14200,
22540xc2c000,
22550x099c01,
22560x31dc10,
22570x7f5f4c,
22580x7f734c,
22590x7d8380,
22600xd5806f,
22610xd58066,
22620xd7401e,
22630xec005e,
22640xc82402,
22650x8001b9,
22660xd60074,
22670xd4401e,
22680xd4801e,
22690xd4c01e,
22700x800002,
22710xee001e,
22720x800002,
22730xee001f,
22740xd4001f,
22750x800002,
22760xd4001f,
22770xd4001f,
22780x880000,
22790xd4001f,
22800x000000,
22810x000000,
22820x000000,
22830x000000,
22840x000000,
22850x000000,
22860x000000,
22870x000000,
22880x000000,
22890x000000,
22900x000000,
22910x000000,
22920x000000,
22930x000000,
22940x000000,
22950x000000,
22960x000000,
22970x000000,
22980x000000,
22990x000000,
23000x000000,
23010x000000,
23020x000000,
23030x000000,
23040x000000,
23050x000000,
23060x000000,
23070x000000,
23080x000000,
23090x000000,
23100x000000,
23110x000000,
23120x000000,
23130x000000,
23140x000000,
23150x000000,
23160x000000,
23170x000000,
23180x000000,
23190x000000,
23200x000000,
23210x000000,
23220x000000,
23230x000000,
23240x000000,
23250x000000,
23260x000000,
23270x000000,
23280x000000,
23290x000000,
23300x000000,
23310x000000,
23320x000000,
23330x000000,
23340x000000,
23350x000000,
23360x000000,
23370x000000,
23380x000000,
23390x000000,
23400x000000,
23410x000000,
23420x000000,
23430x000000,
23440x000000,
23450x010174,
23460x02017b,
23470x030090,
23480x040080,
23490x050005,
23500x060040,
23510x070033,
23520x08012f,
23530x090047,
23540x0a0037,
23550x1001b7,
23560x1700a4,
23570x22013d,
23580x23014c,
23590x2000b5,
23600x240128,
23610x27004e,
23620x28006b,
23630x2a0061,
23640x2b0053,
23650x2f0066,
23660x320088,
23670x340182,
23680x3c0159,
23690x3f0073,
23700x41018f,
23710x440131,
23720x550176,
23730x56017d,
23740x60000c,
23750x610035,
23760x620039,
23770x630039,
23780x640039,
23790x650039,
23800x660039,
23810x670039,
23820x68003b,
23830x690042,
23840x6a0049,
23850x6b0049,
23860x6c0049,
23870x6d0049,
23880x6e0049,
23890x6f0049,
23900x7301b7,
23910x000007,
23920x000007,
23930x000007,
23940x000007,
23950x000007,
23960x000007,
23970x000007,
23980x000007,
23990x000007,
24000x000007,
24010x000007,
24020x000007,
24030x000007,
24040x000007,
24050x000007,
24060x000007,
24070x000007,
24080x000007,
2409};
2410
2411static const u32 RV610_cp_microcode[][3] = {
2412 { 0x00000000, 0xc0200400, 0x000 },
2413 { 0x00000000, 0x00a0000a, 0x000 },
2414 { 0x0000ffff, 0x00284621, 0x000 },
2415 { 0x00000000, 0xd9004800, 0x000 },
2416 { 0x00000000, 0xc0200400, 0x000 },
2417 { 0x00000000, 0x00a0000a, 0x000 },
2418 { 0x00000000, 0x00e00000, 0x000 },
2419 { 0x00010000, 0xc0294620, 0x000 },
2420 { 0x00000000, 0xd9004800, 0x000 },
2421 { 0x00000000, 0xc0200400, 0x000 },
2422 { 0x00000000, 0x00a0000a, 0x000 },
2423 { 0x81000000, 0x00204411, 0x000 },
2424 { 0x00000001, 0x00204811, 0x000 },
2425 { 0x00042004, 0x00604411, 0x68d },
2426 { 0x00000000, 0x00600000, 0x631 },
2427 { 0x00000000, 0x00600000, 0x645 },
2428 { 0x00000000, 0xc0200800, 0x000 },
2429 { 0x00000f00, 0x00281622, 0x000 },
2430 { 0x00000008, 0x00211625, 0x000 },
2431 { 0x00000018, 0x00203625, 0x000 },
2432 { 0x8d000000, 0x00204411, 0x000 },
2433 { 0x00000004, 0x002f0225, 0x000 },
2434 { 0x00000000, 0x0ce00000, 0x018 },
2435 { 0x00412000, 0x00404811, 0x019 },
2436 { 0x00422000, 0x00204811, 0x000 },
2437 { 0x8e000000, 0x00204411, 0x000 },
2438 { 0x00000028, 0x00204a2d, 0x000 },
2439 { 0x90000000, 0x00204411, 0x000 },
2440 { 0x00000000, 0x00204805, 0x000 },
2441 { 0x0000000c, 0x00211622, 0x000 },
2442 { 0x00000003, 0x00281625, 0x000 },
2443 { 0x00000019, 0x00211a22, 0x000 },
2444 { 0x00000004, 0x00281a26, 0x000 },
2445 { 0x00000000, 0x002914c5, 0x000 },
2446 { 0x00000019, 0x00203625, 0x000 },
2447 { 0x00000000, 0x003a1402, 0x000 },
2448 { 0x00000016, 0x00211625, 0x000 },
2449 { 0x00000003, 0x00281625, 0x000 },
2450 { 0x00000017, 0x00200e2d, 0x000 },
2451 { 0xfffffffc, 0x00280e23, 0x000 },
2452 { 0x00000000, 0x002914a3, 0x000 },
2453 { 0x00000017, 0x00203625, 0x000 },
2454 { 0x00008000, 0x00280e22, 0x000 },
2455 { 0x00000007, 0x00220e23, 0x000 },
2456 { 0x00000000, 0x0029386e, 0x000 },
2457 { 0x20000000, 0x00280e22, 0x000 },
2458 { 0x00000006, 0x00210e23, 0x000 },
2459 { 0x00000000, 0x0029386e, 0x000 },
2460 { 0x00000000, 0x00220222, 0x000 },
2461 { 0x00000000, 0x14e00000, 0x038 },
2462 { 0x00000000, 0x2ee00000, 0x035 },
2463 { 0x00000000, 0x2ce00000, 0x037 },
2464 { 0x00000000, 0x00400e2d, 0x039 },
2465 { 0x00000008, 0x00200e2d, 0x000 },
2466 { 0x00000009, 0x0040122d, 0x046 },
2467 { 0x00000001, 0x00400e2d, 0x039 },
2468 { 0x00000000, 0xc0200c00, 0x000 },
2469 { 0x003ffffc, 0x00281223, 0x000 },
2470 { 0x00000002, 0x00221224, 0x000 },
2471 { 0x0000001f, 0x00211e23, 0x000 },
2472 { 0x00000000, 0x14e00000, 0x03e },
2473 { 0x00000008, 0x00401c11, 0x041 },
2474 { 0x0000000d, 0x00201e2d, 0x000 },
2475 { 0x0000000f, 0x00281e27, 0x000 },
2476 { 0x00000003, 0x00221e27, 0x000 },
2477 { 0x7fc00000, 0x00281a23, 0x000 },
2478 { 0x00000014, 0x00211a26, 0x000 },
2479 { 0x00000001, 0x00331a26, 0x000 },
2480 { 0x00000008, 0x00221a26, 0x000 },
2481 { 0x00000000, 0x00290cc7, 0x000 },
2482 { 0x00000027, 0x00203624, 0x000 },
2483 { 0x00007f00, 0x00281221, 0x000 },
2484 { 0x00001400, 0x002f0224, 0x000 },
2485 { 0x00000000, 0x0ce00000, 0x04b },
2486 { 0x00000001, 0x00290e23, 0x000 },
2487 { 0x0000000e, 0x00203623, 0x000 },
2488 { 0x0000e000, 0x00204411, 0x000 },
2489 { 0xfff80000, 0x00294a23, 0x000 },
2490 { 0x00000000, 0x003a2c02, 0x000 },
2491 { 0x00000002, 0x00220e2b, 0x000 },
2492 { 0xfc000000, 0x00280e23, 0x000 },
2493 { 0x0000000f, 0x00203623, 0x000 },
2494 { 0x00001fff, 0x00294a23, 0x000 },
2495 { 0x00000027, 0x00204a2d, 0x000 },
2496 { 0x00000000, 0x00204811, 0x000 },
2497 { 0x00000029, 0x00200e2d, 0x000 },
2498 { 0x060a0200, 0x00294a23, 0x000 },
2499 { 0x00000000, 0x00204811, 0x000 },
2500 { 0x00000000, 0x00204811, 0x000 },
2501 { 0x00000001, 0x00210222, 0x000 },
2502 { 0x00000000, 0x14e00000, 0x061 },
2503 { 0x00000000, 0x2ee00000, 0x05f },
2504 { 0x00000000, 0x2ce00000, 0x05e },
2505 { 0x00000000, 0x00400e2d, 0x062 },
2506 { 0x00000001, 0x00400e2d, 0x062 },
2507 { 0x0000000a, 0x00200e2d, 0x000 },
2508 { 0x0000000b, 0x0040122d, 0x06a },
2509 { 0x00000000, 0xc0200c00, 0x000 },
2510 { 0x003ffffc, 0x00281223, 0x000 },
2511 { 0x00000002, 0x00221224, 0x000 },
2512 { 0x7fc00000, 0x00281623, 0x000 },
2513 { 0x00000014, 0x00211625, 0x000 },
2514 { 0x00000001, 0x00331625, 0x000 },
2515 { 0x80000000, 0x00280e23, 0x000 },
2516 { 0x00000000, 0x00290ca3, 0x000 },
2517 { 0x3ffffc00, 0x00290e23, 0x000 },
2518 { 0x0000001f, 0x00211e23, 0x000 },
2519 { 0x00000000, 0x14e00000, 0x06d },
2520 { 0x00000100, 0x00401c11, 0x070 },
2521 { 0x0000000d, 0x00201e2d, 0x000 },
2522 { 0x000000f0, 0x00281e27, 0x000 },
2523 { 0x00000004, 0x00221e27, 0x000 },
2524 { 0x81000000, 0x00204411, 0x000 },
2525 { 0x0000000d, 0x00204811, 0x000 },
2526 { 0xfffff0ff, 0x00281a30, 0x000 },
2527 { 0x0000a028, 0x00204411, 0x000 },
2528 { 0x00000000, 0x002948e6, 0x000 },
2529 { 0x0000a018, 0x00204411, 0x000 },
2530 { 0x3fffffff, 0x00284a23, 0x000 },
2531 { 0x0000a010, 0x00204411, 0x000 },
2532 { 0x00000000, 0x00204804, 0x000 },
2533 { 0x00000030, 0x0020162d, 0x000 },
2534 { 0x00000002, 0x00291625, 0x000 },
2535 { 0x00000030, 0x00203625, 0x000 },
2536 { 0x00000025, 0x0020162d, 0x000 },
2537 { 0x00000000, 0x002f00a3, 0x000 },
2538 { 0x00000000, 0x0cc00000, 0x083 },
2539 { 0x00000026, 0x0020162d, 0x000 },
2540 { 0x00000000, 0x002f00a4, 0x000 },
2541 { 0x00000000, 0x0cc00000, 0x084 },
2542 { 0x00000000, 0x00400000, 0x08a },
2543 { 0x00000025, 0x00203623, 0x000 },
2544 { 0x00000026, 0x00203624, 0x000 },
2545 { 0x00000017, 0x00201e2d, 0x000 },
2546 { 0x00000002, 0x00210227, 0x000 },
2547 { 0x00000000, 0x14e00000, 0x08a },
2548 { 0x00000000, 0x00600000, 0x668 },
2549 { 0x00000000, 0x00600000, 0x65c },
2550 { 0x00000002, 0x00210e22, 0x000 },
2551 { 0x00000000, 0x14c00000, 0x08d },
2552 { 0x00000012, 0xc0403620, 0x093 },
2553 { 0x00000000, 0x2ee00000, 0x091 },
2554 { 0x00000000, 0x2ce00000, 0x090 },
2555 { 0x00000002, 0x00400e2d, 0x092 },
2556 { 0x00000003, 0x00400e2d, 0x092 },
2557 { 0x0000000c, 0x00200e2d, 0x000 },
2558 { 0x00000012, 0x00203623, 0x000 },
2559 { 0x00000003, 0x00210e22, 0x000 },
2560 { 0x00000000, 0x14c00000, 0x098 },
2561 { 0x0000a00c, 0x00204411, 0x000 },
2562 { 0x00000000, 0xc0204800, 0x000 },
2563 { 0x00000000, 0xc0404800, 0x0a0 },
2564 { 0x0000a00c, 0x00204411, 0x000 },
2565 { 0x00000000, 0x00204811, 0x000 },
2566 { 0x00000000, 0x2ee00000, 0x09e },
2567 { 0x00000000, 0x2ce00000, 0x09d },
2568 { 0x00000002, 0x00400e2d, 0x09f },
2569 { 0x00000003, 0x00400e2d, 0x09f },
2570 { 0x0000000c, 0x00200e2d, 0x000 },
2571 { 0x00000000, 0x00204803, 0x000 },
2572 { 0x00000000, 0x003a0c02, 0x000 },
2573 { 0x003f0000, 0x00280e23, 0x000 },
2574 { 0x00000010, 0x00210e23, 0x000 },
2575 { 0x00000011, 0x00203623, 0x000 },
2576 { 0x0000001e, 0x0021022b, 0x000 },
2577 { 0x00000000, 0x14c00000, 0x0a7 },
2578 { 0x00000016, 0xc0203620, 0x000 },
2579 { 0x0000001f, 0x0021022b, 0x000 },
2580 { 0x00000000, 0x14c00000, 0x0aa },
2581 { 0x00000015, 0xc0203620, 0x000 },
2582 { 0x00000008, 0x00210e2b, 0x000 },
2583 { 0x0000007f, 0x00280e23, 0x000 },
2584 { 0x00000000, 0x002f0223, 0x000 },
2585 { 0x00000000, 0x0ce00000, 0x0e1 },
2586 { 0x00000000, 0x27000000, 0x000 },
2587 { 0x00000000, 0x00600000, 0x2a3 },
2588 { 0x00000001, 0x002f0223, 0x000 },
2589 { 0x00000000, 0x0ae00000, 0x0b3 },
2590 { 0x00000000, 0x00600000, 0x13a },
2591 { 0x81000000, 0x00204411, 0x000 },
2592 { 0x00000006, 0x00204811, 0x000 },
2593 { 0x0000000c, 0x00221e30, 0x000 },
2594 { 0x99800000, 0x00204411, 0x000 },
2595 { 0x00000004, 0x0020122d, 0x000 },
2596 { 0x00000008, 0x00221224, 0x000 },
2597 { 0x00000010, 0x00201811, 0x000 },
2598 { 0x00000000, 0x00291ce4, 0x000 },
2599 { 0x00000000, 0x00604807, 0x12f },
2600 { 0x9b000000, 0x00204411, 0x000 },
2601 { 0x00000000, 0x00204802, 0x000 },
2602 { 0x9c000000, 0x00204411, 0x000 },
2603 { 0x00000000, 0x0033146f, 0x000 },
2604 { 0x00000001, 0x00333e23, 0x000 },
2605 { 0x00000000, 0xd9004800, 0x000 },
2606 { 0x00000000, 0x00203c05, 0x000 },
2607 { 0x81000000, 0x00204411, 0x000 },
2608 { 0x0000000e, 0x00204811, 0x000 },
2609 { 0x00000000, 0x00201010, 0x000 },
2610 { 0x0000e007, 0x00204411, 0x000 },
2611 { 0x0000000f, 0x0021022b, 0x000 },
2612 { 0x00000000, 0x14c00000, 0x0cb },
2613 { 0x00f8ff08, 0x00204811, 0x000 },
2614 { 0x98000000, 0x00404811, 0x0dc },
2615 { 0x000000f0, 0x00280e22, 0x000 },
2616 { 0x000000a0, 0x002f0223, 0x000 },
2617 { 0x00000000, 0x0cc00000, 0x0da },
2618 { 0x00000011, 0x00200e2d, 0x000 },
2619 { 0x00000001, 0x002f0223, 0x000 },
2620 { 0x00000000, 0x0ce00000, 0x0d5 },
2621 { 0x00000002, 0x002f0223, 0x000 },
2622 { 0x00000000, 0x0ce00000, 0x0d4 },
2623 { 0x00003f00, 0x00400c11, 0x0d6 },
2624 { 0x00001f00, 0x00400c11, 0x0d6 },
2625 { 0x00000f00, 0x00200c11, 0x000 },
2626 { 0x00380009, 0x00294a23, 0x000 },
2627 { 0x3f000000, 0x00280e2b, 0x000 },
2628 { 0x00000002, 0x00220e23, 0x000 },
2629 { 0x00000007, 0x00494a23, 0x0dc },
2630 { 0x00380f09, 0x00204811, 0x000 },
2631 { 0x68000007, 0x00204811, 0x000 },
2632 { 0x00000008, 0x00214a27, 0x000 },
2633 { 0x00000000, 0x00204811, 0x000 },
2634 { 0x060a0200, 0x00294a24, 0x000 },
2635 { 0x00000000, 0x00204811, 0x000 },
2636 { 0x00000000, 0x00204811, 0x000 },
2637 { 0x0000a202, 0x00204411, 0x000 },
2638 { 0x00ff0000, 0x00280e22, 0x000 },
2639 { 0x00000080, 0x00294a23, 0x000 },
2640 { 0x00000027, 0x00200e2d, 0x000 },
2641 { 0x00000026, 0x0020122d, 0x000 },
2642 { 0x00000000, 0x002f0083, 0x000 },
2643 { 0x00000000, 0x0ce00000, 0x0ea },
2644 { 0x00000000, 0x00600000, 0x662 },
2645 { 0x00000000, 0x00400000, 0x0eb },
2646 { 0x00000000, 0x00600000, 0x665 },
2647 { 0x00000007, 0x0020222d, 0x000 },
2648 { 0x00000005, 0x00220e22, 0x000 },
2649 { 0x00100000, 0x00280e23, 0x000 },
2650 { 0x00000000, 0x00292068, 0x000 },
2651 { 0x00000000, 0x003a0c02, 0x000 },
2652 { 0x000000ef, 0x00280e23, 0x000 },
2653 { 0x00000000, 0x00292068, 0x000 },
2654 { 0x00000017, 0x00200e2d, 0x000 },
2655 { 0x00000003, 0x00210223, 0x000 },
2656 { 0x00000000, 0x14e00000, 0x0f8 },
2657 { 0x0000000b, 0x00210228, 0x000 },
2658 { 0x00000000, 0x14c00000, 0x0f8 },
2659 { 0x00000400, 0x00292228, 0x000 },
2660 { 0x00000014, 0x00203628, 0x000 },
2661 { 0x0000001c, 0x00210e22, 0x000 },
2662 { 0x00000000, 0x14c00000, 0x0fd },
2663 { 0x0000a30c, 0x00204411, 0x000 },
2664 { 0x00000000, 0x00204811, 0x000 },
2665 { 0x0000001e, 0x00210e22, 0x000 },
2666 { 0x00000000, 0x14c00000, 0x10b },
2667 { 0x0000a30f, 0x00204411, 0x000 },
2668 { 0x00000011, 0x00200e2d, 0x000 },
2669 { 0x00000001, 0x002f0223, 0x000 },
2670 { 0x00000000, 0x0cc00000, 0x104 },
2671 { 0xffffffff, 0x00404811, 0x10b },
2672 { 0x00000002, 0x002f0223, 0x000 },
2673 { 0x00000000, 0x0cc00000, 0x107 },
2674 { 0x0000ffff, 0x00404811, 0x10b },
2675 { 0x00000004, 0x002f0223, 0x000 },
2676 { 0x00000000, 0x0cc00000, 0x10a },
2677 { 0x000000ff, 0x00404811, 0x10b },
2678 { 0x00000001, 0x00204811, 0x000 },
2679 { 0x0002c400, 0x00204411, 0x000 },
2680 { 0x0000001f, 0x00210e22, 0x000 },
2681 { 0x00000000, 0x14c00000, 0x112 },
2682 { 0x00000010, 0x40210e20, 0x000 },
2683 { 0x00000013, 0x00203623, 0x000 },
2684 { 0x00000018, 0x40224a20, 0x000 },
2685 { 0x00000010, 0xc0424a20, 0x114 },
2686 { 0x00000000, 0x00200c11, 0x000 },
2687 { 0x00000013, 0x00203623, 0x000 },
2688 { 0x00000000, 0x00204811, 0x000 },
2689 { 0x00000000, 0x00204811, 0x000 },
2690 { 0x0000000a, 0x00201011, 0x000 },
2691 { 0x00000000, 0x002f0224, 0x000 },
2692 { 0x00000000, 0x0ce00000, 0x11b },
2693 { 0x00000000, 0x00204811, 0x000 },
2694 { 0x00000001, 0x00531224, 0x117 },
2695 { 0xffbfffff, 0x00283a2e, 0x000 },
2696 { 0x0000001b, 0x00210222, 0x000 },
2697 { 0x00000000, 0x14c00000, 0x12e },
2698 { 0x81000000, 0x00204411, 0x000 },
2699 { 0x0000000d, 0x00204811, 0x000 },
2700 { 0x00000018, 0x00220e30, 0x000 },
2701 { 0xfc000000, 0x00280e23, 0x000 },
2702 { 0x81000000, 0x00204411, 0x000 },
2703 { 0x0000000e, 0x00204811, 0x000 },
2704 { 0x00000000, 0x00201010, 0x000 },
2705 { 0x0000e00e, 0x00204411, 0x000 },
2706 { 0x07f8ff08, 0x00204811, 0x000 },
2707 { 0x00000000, 0x00294a23, 0x000 },
2708 { 0x0000001c, 0x00201e2d, 0x000 },
2709 { 0x00000008, 0x00214a27, 0x000 },
2710 { 0x00000000, 0x00204811, 0x000 },
2711 { 0x060a0200, 0x00294a24, 0x000 },
2712 { 0x00000000, 0x00204811, 0x000 },
2713 { 0x00000000, 0x00204811, 0x000 },
2714 { 0x00000000, 0x00800000, 0x000 },
2715 { 0x81000000, 0x00204411, 0x000 },
2716 { 0x00000001, 0x00204811, 0x000 },
2717 { 0x0000217c, 0x00204411, 0x000 },
2718 { 0x00800000, 0x00204811, 0x000 },
2719 { 0x00000000, 0x00204806, 0x000 },
2720 { 0x00000008, 0x00214a27, 0x000 },
2721 { 0x00000000, 0x17000000, 0x000 },
2722 { 0x0004217f, 0x00604411, 0x68d },
2723 { 0x0000001f, 0x00210230, 0x000 },
2724 { 0x00000000, 0x14c00000, 0x68c },
2725 { 0x00000004, 0x00404c11, 0x135 },
2726 { 0x81000000, 0x00204411, 0x000 },
2727 { 0x00000001, 0x00204811, 0x000 },
2728 { 0x000021f8, 0x00204411, 0x000 },
2729 { 0x0000001c, 0x00204811, 0x000 },
2730 { 0x000421f9, 0x00604411, 0x68d },
2731 { 0x00000011, 0x00210230, 0x000 },
2732 { 0x00000000, 0x14e00000, 0x13c },
2733 { 0x00000000, 0x00800000, 0x000 },
2734 { 0x00000000, 0x00600000, 0x00b },
2735 { 0x00000000, 0x00600411, 0x315 },
2736 { 0x00000000, 0x00200411, 0x000 },
2737 { 0x00000000, 0x00600811, 0x1b2 },
2738 { 0x00000000, 0x00600000, 0x160 },
2739 { 0x0000ffff, 0x40280e20, 0x000 },
2740 { 0x00000010, 0xc0211220, 0x000 },
2741 { 0x0000ffff, 0x40280620, 0x000 },
2742 { 0x00000010, 0xc0210a20, 0x000 },
2743 { 0x00000000, 0x00341461, 0x000 },
2744 { 0x00000000, 0x00741882, 0x2bb },
2745 { 0x0001a1fd, 0x00604411, 0x2e0 },
2746 { 0x00003fff, 0x002f022f, 0x000 },
2747 { 0x00000000, 0x0cc00000, 0x147 },
2748 { 0x00000000, 0xc0400400, 0x001 },
2749 { 0x00000000, 0x00600000, 0x00b },
2750 { 0x00000000, 0x00600411, 0x315 },
2751 { 0x00000000, 0x00200411, 0x000 },
2752 { 0x00000000, 0x00600811, 0x1b2 },
2753 { 0x00003fff, 0x002f022f, 0x000 },
2754 { 0x00000000, 0x0ce00000, 0x000 },
2755 { 0x00000000, 0x00600000, 0x160 },
2756 { 0x00000010, 0x40210e20, 0x000 },
2757 { 0x0000ffff, 0xc0281220, 0x000 },
2758 { 0x00000010, 0x40211620, 0x000 },
2759 { 0x0000ffff, 0xc0681a20, 0x2bb },
2760 { 0x0001a1fd, 0x00604411, 0x2e0 },
2761 { 0x00003fff, 0x002f022f, 0x000 },
2762 { 0x00000000, 0x0cc00000, 0x158 },
2763 { 0x00000000, 0xc0400400, 0x001 },
2764 { 0x0000225c, 0x00204411, 0x000 },
2765 { 0x00000001, 0x00300a2f, 0x000 },
2766 { 0x00000001, 0x00210a22, 0x000 },
2767 { 0x00000003, 0x00384a22, 0x000 },
2768 { 0x00002256, 0x00204411, 0x000 },
2769 { 0x0000001a, 0x00204811, 0x000 },
2770 { 0x0000a1fc, 0x00204411, 0x000 },
2771 { 0x00000001, 0x00804811, 0x000 },
2772 { 0x00000000, 0x00600000, 0x00b },
2773 { 0x00000000, 0x00600000, 0x18f },
2774 { 0x00000000, 0x00600000, 0x1a0 },
2775 { 0x00003fff, 0x002f022f, 0x000 },
2776 { 0x00000000, 0x0ce00000, 0x000 },
2777 { 0x00000000, 0x00202c08, 0x000 },
2778 { 0x00000000, 0x00202411, 0x000 },
2779 { 0x00000000, 0x00202811, 0x000 },
2780 { 0x00002256, 0x00204411, 0x000 },
2781 { 0x00000016, 0x00204811, 0x000 },
2782 { 0x0000225c, 0x00204411, 0x000 },
2783 { 0x00000003, 0x00204811, 0x000 },
2784 { 0x93800000, 0x00204411, 0x000 },
2785 { 0x00000002, 0x00221e29, 0x000 },
2786 { 0x00000000, 0x007048eb, 0x19c },
2787 { 0x00000000, 0x00600000, 0x2bb },
2788 { 0x00000001, 0x40330620, 0x000 },
2789 { 0x00000000, 0xc0302409, 0x000 },
2790 { 0x00003fff, 0x002f022f, 0x000 },
2791 { 0x00000000, 0x0ce00000, 0x000 },
2792 { 0x00000000, 0x00600000, 0x2a3 },
2793 { 0x00000000, 0x002f0221, 0x000 },
2794 { 0x00000000, 0x0ae00000, 0x181 },
2795 { 0x00000000, 0x00600000, 0x13a },
2796 { 0x00000000, 0x00400000, 0x186 },
2797 { 0x95000000, 0x00204411, 0x000 },
2798 { 0x00000000, 0x002f0221, 0x000 },
2799 { 0x00000000, 0x0ce00000, 0x186 },
2800 { 0x00000000, 0xc0204800, 0x000 },
2801 { 0x00000001, 0x00530621, 0x182 },
2802 { 0x92000000, 0x00204411, 0x000 },
2803 { 0x00000000, 0xc0604800, 0x197 },
2804 { 0x0001a1fd, 0x00204411, 0x000 },
2805 { 0x00000011, 0x0020062d, 0x000 },
2806 { 0x00000000, 0x0078042a, 0x2fb },
2807 { 0x00000000, 0x00202809, 0x000 },
2808 { 0x00003fff, 0x002f022f, 0x000 },
2809 { 0x00000000, 0x0cc00000, 0x174 },
2810 { 0x00000000, 0xc0400400, 0x001 },
2811 { 0x00000210, 0x00600411, 0x315 },
2812 { 0x00003fff, 0x002f022f, 0x000 },
2813 { 0x00000000, 0x0ce00000, 0x194 },
2814 { 0x00000015, 0xc0203620, 0x000 },
2815 { 0x00000016, 0xc0203620, 0x000 },
2816 { 0x3f800000, 0x00200411, 0x000 },
2817 { 0x46000000, 0x00600811, 0x1b2 },
2818 { 0x00000000, 0x00800000, 0x000 },
2819 { 0x0000a1fc, 0x00204411, 0x000 },
2820 { 0x00003fff, 0x002f022f, 0x000 },
2821 { 0x00000000, 0x0cc00000, 0x19b },
2822 { 0x00000001, 0x00804811, 0x000 },
2823 { 0x00000021, 0x00804811, 0x000 },
2824 { 0x0000ffff, 0x40280e20, 0x000 },
2825 { 0x00000010, 0xc0211220, 0x000 },
2826 { 0x0000ffff, 0x40281620, 0x000 },
2827 { 0x00000010, 0xc0811a20, 0x000 },
2828 { 0x81000000, 0x00204411, 0x000 },
2829 { 0x00000006, 0x00204811, 0x000 },
2830 { 0x00000008, 0x00221e30, 0x000 },
2831 { 0x00000029, 0x00201a2d, 0x000 },
2832 { 0x0000e000, 0x00204411, 0x000 },
2833 { 0xfffbff09, 0x00204811, 0x000 },
2834 { 0x0000000f, 0x0020222d, 0x000 },
2835 { 0x00001fff, 0x00294a28, 0x000 },
2836 { 0x00000006, 0x0020222d, 0x000 },
2837 { 0x00000000, 0x002920e8, 0x000 },
2838 { 0x00000000, 0x00204808, 0x000 },
2839 { 0x00000000, 0x00204811, 0x000 },
2840 { 0x060a0200, 0x00294a26, 0x000 },
2841 { 0x00000000, 0x00204811, 0x000 },
2842 { 0x00000000, 0x00204811, 0x000 },
2843 { 0x00000100, 0x00201811, 0x000 },
2844 { 0x00000008, 0x00621e28, 0x12f },
2845 { 0x00000008, 0x00822228, 0x000 },
2846 { 0x0002c000, 0x00204411, 0x000 },
2847 { 0x00000015, 0x00600e2d, 0x1bd },
2848 { 0x00000016, 0x00600e2d, 0x1bd },
2849 { 0x0000c008, 0x00204411, 0x000 },
2850 { 0x00000017, 0x00200e2d, 0x000 },
2851 { 0x00000000, 0x14c00000, 0x1b9 },
2852 { 0x00000000, 0x00200411, 0x000 },
2853 { 0x00000000, 0x00204801, 0x000 },
2854 { 0x39000000, 0x00204811, 0x000 },
2855 { 0x00000000, 0x00204811, 0x000 },
2856 { 0x00000000, 0x00804802, 0x000 },
2857 { 0x00000018, 0x00202e2d, 0x000 },
2858 { 0x00000000, 0x003b0d63, 0x000 },
2859 { 0x00000008, 0x00224a23, 0x000 },
2860 { 0x00000010, 0x00224a23, 0x000 },
2861 { 0x00000018, 0x00224a23, 0x000 },
2862 { 0x00000000, 0x00804803, 0x000 },
2863 { 0x00000000, 0x00600000, 0x00b },
2864 { 0x00001000, 0x00600411, 0x315 },
2865 { 0x00000000, 0x00200411, 0x000 },
2866 { 0x00000000, 0x00600811, 0x1b2 },
2867 { 0x00000007, 0x0021062f, 0x000 },
2868 { 0x00000013, 0x00200a2d, 0x000 },
2869 { 0x00000001, 0x00202c11, 0x000 },
2870 { 0x0000ffff, 0x40282220, 0x000 },
2871 { 0x0000000f, 0x00262228, 0x000 },
2872 { 0x00000010, 0x40212620, 0x000 },
2873 { 0x0000000f, 0x00262629, 0x000 },
2874 { 0x00000000, 0x00202802, 0x000 },
2875 { 0x00002256, 0x00204411, 0x000 },
2876 { 0x0000001b, 0x00204811, 0x000 },
2877 { 0x00000000, 0x002f0221, 0x000 },
2878 { 0x00000000, 0x0ce00000, 0x1e0 },
2879 { 0x0000225c, 0x00204411, 0x000 },
2880 { 0x00000081, 0x00204811, 0x000 },
2881 { 0x0000a1fc, 0x00204411, 0x000 },
2882 { 0x00000001, 0x00204811, 0x000 },
2883 { 0x00000080, 0x00201c11, 0x000 },
2884 { 0x00000000, 0x002f0227, 0x000 },
2885 { 0x00000000, 0x0ce00000, 0x1dc },
2886 { 0x00000000, 0x00600000, 0x1e9 },
2887 { 0x00000001, 0x00531e27, 0x1d8 },
2888 { 0x00000001, 0x00202c11, 0x000 },
2889 { 0x0000001f, 0x00280a22, 0x000 },
2890 { 0x0000001f, 0x00282a2a, 0x000 },
2891 { 0x00000001, 0x00530621, 0x1d1 },
2892 { 0x0000225c, 0x00204411, 0x000 },
2893 { 0x00000002, 0x00304a2f, 0x000 },
2894 { 0x0000a1fc, 0x00204411, 0x000 },
2895 { 0x00000001, 0x00204811, 0x000 },
2896 { 0x00000001, 0x00301e2f, 0x000 },
2897 { 0x00000000, 0x002f0227, 0x000 },
2898 { 0x00000000, 0x0ce00000, 0x000 },
2899 { 0x00000000, 0x00600000, 0x1e9 },
2900 { 0x00000001, 0x00531e27, 0x1e5 },
2901 { 0x0000ffff, 0x40280e20, 0x000 },
2902 { 0x0000000f, 0x00260e23, 0x000 },
2903 { 0x00000010, 0xc0211220, 0x000 },
2904 { 0x0000000f, 0x00261224, 0x000 },
2905 { 0x00000000, 0x00201411, 0x000 },
2906 { 0x00000000, 0x00601811, 0x2bb },
2907 { 0x0001a1fd, 0x00204411, 0x000 },
2908 { 0x00000000, 0x002f022b, 0x000 },
2909 { 0x00000000, 0x0ce00000, 0x1f8 },
2910 { 0x00000010, 0x00221628, 0x000 },
2911 { 0xffff0000, 0x00281625, 0x000 },
2912 { 0x0000ffff, 0x00281a29, 0x000 },
2913 { 0x00000000, 0x002948c5, 0x000 },
2914 { 0x00000000, 0x0020480a, 0x000 },
2915 { 0x00000000, 0x00202c11, 0x000 },
2916 { 0x00000010, 0x00221623, 0x000 },
2917 { 0xffff0000, 0x00281625, 0x000 },
2918 { 0x0000ffff, 0x00281a24, 0x000 },
2919 { 0x00000000, 0x002948c5, 0x000 },
2920 { 0x00000000, 0x00731503, 0x205 },
2921 { 0x00000000, 0x00201805, 0x000 },
2922 { 0x00000000, 0x00731524, 0x205 },
2923 { 0x00000000, 0x002d14c5, 0x000 },
2924 { 0x00000000, 0x003008a2, 0x000 },
2925 { 0x00000000, 0x00204802, 0x000 },
2926 { 0x00000000, 0x00202802, 0x000 },
2927 { 0x00000000, 0x00202003, 0x000 },
2928 { 0x00000000, 0x00802404, 0x000 },
2929 { 0x0000000f, 0x00210225, 0x000 },
2930 { 0x00000000, 0x14c00000, 0x68c },
2931 { 0x00000000, 0x002b1405, 0x000 },
2932 { 0x00000001, 0x00901625, 0x000 },
2933 { 0x00000000, 0x00600000, 0x00b },
2934 { 0x00000000, 0x00600411, 0x315 },
2935 { 0x00000000, 0x00200411, 0x000 },
2936 { 0x00000000, 0x00600811, 0x1b2 },
2937 { 0x00002256, 0x00204411, 0x000 },
2938 { 0x0000001a, 0x00294a22, 0x000 },
2939 { 0x00000000, 0xc0200000, 0x000 },
2940 { 0x00003fff, 0x002f022f, 0x000 },
2941 { 0x00000000, 0x0ce00000, 0x000 },
2942 { 0x00000000, 0xc0200400, 0x000 },
2943 { 0x0000225c, 0x00204411, 0x000 },
2944 { 0x00000003, 0x00384a21, 0x000 },
2945 { 0x0000a1fc, 0x00204411, 0x000 },
2946 { 0x00000001, 0x00204811, 0x000 },
2947 { 0x0000ffff, 0x40281220, 0x000 },
2948 { 0x00000010, 0xc0211a20, 0x000 },
2949 { 0x0000ffff, 0x40280e20, 0x000 },
2950 { 0x00000010, 0xc0211620, 0x000 },
2951 { 0x00000000, 0x00741465, 0x2bb },
2952 { 0x0001a1fd, 0x00604411, 0x2e0 },
2953 { 0x00000001, 0x00330621, 0x000 },
2954 { 0x00000000, 0x002f0221, 0x000 },
2955 { 0x00000000, 0x0cc00000, 0x219 },
2956 { 0x00003fff, 0x002f022f, 0x000 },
2957 { 0x00000000, 0x0cc00000, 0x212 },
2958 { 0x00000000, 0xc0400400, 0x001 },
2959 { 0x00000000, 0x00600000, 0x645 },
2960 { 0x00000000, 0x0040040f, 0x213 },
2961 { 0x00000000, 0x00600000, 0x631 },
2962 { 0x00000000, 0x00600000, 0x645 },
2963 { 0x00000210, 0x00600411, 0x315 },
2964 { 0x00000000, 0x00600000, 0x1a0 },
2965 { 0x00000000, 0x00600000, 0x19c },
2966 { 0x00000000, 0x00600000, 0x2bb },
2967 { 0x00000000, 0x00600000, 0x2a3 },
2968 { 0x93800000, 0x00204411, 0x000 },
2969 { 0x00000000, 0x00204808, 0x000 },
2970 { 0x00000000, 0x002f022f, 0x000 },
2971 { 0x00000000, 0x0ae00000, 0x232 },
2972 { 0x00000000, 0x00600000, 0x13a },
2973 { 0x00000000, 0x00400000, 0x236 },
2974 { 0x95000000, 0x00204411, 0x000 },
2975 { 0x00000000, 0x002f022f, 0x000 },
2976 { 0x00000000, 0x0ce00000, 0x236 },
2977 { 0x00000000, 0xc0404800, 0x233 },
2978 { 0x92000000, 0x00204411, 0x000 },
2979 { 0x00000000, 0xc0204800, 0x000 },
2980 { 0x00002256, 0x00204411, 0x000 },
2981 { 0x00000016, 0x00204811, 0x000 },
2982 { 0x0000225c, 0x00204411, 0x000 },
2983 { 0x00000003, 0x00204811, 0x000 },
2984 { 0x0000a1fc, 0x00204411, 0x000 },
2985 { 0x00000001, 0x00204811, 0x000 },
2986 { 0x0001a1fd, 0x00204411, 0x000 },
2987 { 0x00000000, 0x00600411, 0x2fb },
2988 { 0x00000000, 0xc0400400, 0x001 },
2989 { 0x00000000, 0x00600000, 0x631 },
2990 { 0x0000a00c, 0x00204411, 0x000 },
2991 { 0x00000000, 0xc0204800, 0x000 },
2992 { 0x00000000, 0xc0404800, 0x000 },
2993 { 0x00000000, 0x00600000, 0x00b },
2994 { 0x00000018, 0x40210a20, 0x000 },
2995 { 0x00000003, 0x002f0222, 0x000 },
2996 { 0x00000000, 0x0ae00000, 0x24c },
2997 { 0x00000014, 0x0020222d, 0x000 },
2998 { 0x00080101, 0x00292228, 0x000 },
2999 { 0x00000014, 0x00203628, 0x000 },
3000 { 0x0000a30c, 0x00204411, 0x000 },
3001 { 0x00000000, 0xc0204800, 0x000 },
3002 { 0x00000000, 0xc0204800, 0x000 },
3003 { 0x00000000, 0xc0404800, 0x251 },
3004 { 0x00000000, 0x00600000, 0x00b },
3005 { 0x00000010, 0x00600411, 0x315 },
3006 { 0x3f800000, 0x00200411, 0x000 },
3007 { 0x00000000, 0x00600811, 0x1b2 },
3008 { 0x0000225c, 0x00204411, 0x000 },
3009 { 0x00000003, 0x00204811, 0x000 },
3010 { 0x00000000, 0x00600000, 0x27c },
3011 { 0x00000017, 0x00201e2d, 0x000 },
3012 { 0x00000001, 0x00211e27, 0x000 },
3013 { 0x00000000, 0x14e00000, 0x26a },
3014 { 0x00000012, 0x00201e2d, 0x000 },
3015 { 0x0000ffff, 0x00281e27, 0x000 },
3016 { 0x00000000, 0x00341c27, 0x000 },
3017 { 0x00000000, 0x12c00000, 0x25f },
3018 { 0x00000000, 0x00201c11, 0x000 },
3019 { 0x00000000, 0x002f00e5, 0x000 },
3020 { 0x00000000, 0x08c00000, 0x262 },
3021 { 0x00000000, 0x00201407, 0x000 },
3022 { 0x00000012, 0x00201e2d, 0x000 },
3023 { 0x00000010, 0x00211e27, 0x000 },
3024 { 0x00000000, 0x00341c47, 0x000 },
3025 { 0x00000000, 0x12c00000, 0x267 },
3026 { 0x00000000, 0x00201c11, 0x000 },
3027 { 0x00000000, 0x002f00e6, 0x000 },
3028 { 0x00000000, 0x08c00000, 0x26a },
3029 { 0x00000000, 0x00201807, 0x000 },
3030 { 0x00000000, 0x00600000, 0x2c1 },
3031 { 0x00002256, 0x00204411, 0x000 },
3032 { 0x00000000, 0x00342023, 0x000 },
3033 { 0x00000000, 0x12c00000, 0x272 },
3034 { 0x00000000, 0x00342044, 0x000 },
3035 { 0x00000000, 0x12c00000, 0x271 },
3036 { 0x00000016, 0x00404811, 0x276 },
3037 { 0x00000018, 0x00404811, 0x276 },
3038 { 0x00000000, 0x00342044, 0x000 },
3039 { 0x00000000, 0x12c00000, 0x275 },
3040 { 0x00000017, 0x00404811, 0x276 },
3041 { 0x00000019, 0x00204811, 0x000 },
3042 { 0x0000a1fc, 0x00204411, 0x000 },
3043 { 0x00000001, 0x00204811, 0x000 },
3044 { 0x0001a1fd, 0x00604411, 0x2e9 },
3045 { 0x00003fff, 0x002f022f, 0x000 },
3046 { 0x00000000, 0x0cc00000, 0x256 },
3047 { 0x00000000, 0xc0400400, 0x001 },
3048 { 0x00000010, 0x40210620, 0x000 },
3049 { 0x0000ffff, 0xc0280a20, 0x000 },
3050 { 0x00000010, 0x40210e20, 0x000 },
3051 { 0x0000ffff, 0xc0281220, 0x000 },
3052 { 0x00000010, 0x40211620, 0x000 },
3053 { 0x0000ffff, 0xc0881a20, 0x000 },
3054 { 0x81000000, 0x00204411, 0x000 },
3055 { 0x00000001, 0x00204811, 0x000 },
3056 { 0x00042004, 0x00604411, 0x68d },
3057 { 0x00000000, 0x00600000, 0x631 },
3058 { 0x00000000, 0xc0600000, 0x2a3 },
3059 { 0x00000005, 0x00200a2d, 0x000 },
3060 { 0x00000008, 0x00220a22, 0x000 },
3061 { 0x0000002b, 0x00201a2d, 0x000 },
3062 { 0x0000001c, 0x00201e2d, 0x000 },
3063 { 0x00007000, 0x00281e27, 0x000 },
3064 { 0x00000000, 0x00311ce6, 0x000 },
3065 { 0x0000002a, 0x00201a2d, 0x000 },
3066 { 0x0000000c, 0x00221a26, 0x000 },
3067 { 0x00000000, 0x002f00e6, 0x000 },
3068 { 0x00000000, 0x06e00000, 0x292 },
3069 { 0x00000000, 0x00201c11, 0x000 },
3070 { 0x00000000, 0x00200c11, 0x000 },
3071 { 0x0000002b, 0x00203623, 0x000 },
3072 { 0x00000010, 0x00201811, 0x000 },
3073 { 0x00000000, 0x00691ce2, 0x12f },
3074 { 0x93800000, 0x00204411, 0x000 },
3075 { 0x00000000, 0x00204807, 0x000 },
3076 { 0x95000000, 0x00204411, 0x000 },
3077 { 0x00000000, 0x002f022f, 0x000 },
3078 { 0x00000000, 0x0ce00000, 0x29d },
3079 { 0x00000001, 0x00333e2f, 0x000 },
3080 { 0x00000000, 0xd9004800, 0x000 },
3081 { 0x92000000, 0x00204411, 0x000 },
3082 { 0x00000000, 0xc0204800, 0x000 },
3083 { 0x0000001c, 0x00403627, 0x000 },
3084 { 0x0000000c, 0xc0220a20, 0x000 },
3085 { 0x00000029, 0x00203622, 0x000 },
3086 { 0x00000028, 0xc0403620, 0x000 },
3087 { 0x0000a2a4, 0x00204411, 0x000 },
3088 { 0x00000009, 0x00204811, 0x000 },
3089 { 0xa1000000, 0x00204411, 0x000 },
3090 { 0x00000001, 0x00804811, 0x000 },
3091 { 0x00000021, 0x00201e2d, 0x000 },
3092 { 0x00000000, 0x002c1ce3, 0x000 },
3093 { 0x00000021, 0x00203627, 0x000 },
3094 { 0x00000022, 0x00201e2d, 0x000 },
3095 { 0x00000000, 0x002c1ce4, 0x000 },
3096 { 0x00000022, 0x00203627, 0x000 },
3097 { 0x00000023, 0x00201e2d, 0x000 },
3098 { 0x00000000, 0x003120a3, 0x000 },
3099 { 0x00000000, 0x002d1d07, 0x000 },
3100 { 0x00000023, 0x00203627, 0x000 },
3101 { 0x00000024, 0x00201e2d, 0x000 },
3102 { 0x00000000, 0x003120c4, 0x000 },
3103 { 0x00000000, 0x002d1d07, 0x000 },
3104 { 0x00000024, 0x00803627, 0x000 },
3105 { 0x00000021, 0x00203623, 0x000 },
3106 { 0x00000022, 0x00203624, 0x000 },
3107 { 0x00000000, 0x00311ca3, 0x000 },
3108 { 0x00000023, 0x00203627, 0x000 },
3109 { 0x00000000, 0x00311cc4, 0x000 },
3110 { 0x00000024, 0x00803627, 0x000 },
3111 { 0x0000001a, 0x00203627, 0x000 },
3112 { 0x0000001b, 0x00203628, 0x000 },
3113 { 0x00000017, 0x00201e2d, 0x000 },
3114 { 0x00000002, 0x00210227, 0x000 },
3115 { 0x00000000, 0x14c00000, 0x2dc },
3116 { 0x00000000, 0x00400000, 0x2d9 },
3117 { 0x0000001a, 0x00203627, 0x000 },
3118 { 0x0000001b, 0x00203628, 0x000 },
3119 { 0x00000017, 0x00201e2d, 0x000 },
3120 { 0x00000002, 0x00210227, 0x000 },
3121 { 0x00000000, 0x14e00000, 0x2d9 },
3122 { 0x00000003, 0x00210227, 0x000 },
3123 { 0x00000000, 0x14e00000, 0x2dc },
3124 { 0x00000023, 0x00201e2d, 0x000 },
3125 { 0x00000000, 0x002e00e1, 0x000 },
3126 { 0x00000000, 0x02c00000, 0x2dc },
3127 { 0x00000021, 0x00201e2d, 0x000 },
3128 { 0x00000000, 0x003120a1, 0x000 },
3129 { 0x00000000, 0x002e00e8, 0x000 },
3130 { 0x00000000, 0x06c00000, 0x2dc },
3131 { 0x00000024, 0x00201e2d, 0x000 },
3132 { 0x00000000, 0x002e00e2, 0x000 },
3133 { 0x00000000, 0x02c00000, 0x2dc },
3134 { 0x00000022, 0x00201e2d, 0x000 },
3135 { 0x00000000, 0x003120c2, 0x000 },
3136 { 0x00000000, 0x002e00e8, 0x000 },
3137 { 0x00000000, 0x06c00000, 0x2dc },
3138 { 0x00000000, 0x00600000, 0x668 },
3139 { 0x00000000, 0x00600000, 0x2b5 },
3140 { 0x00000000, 0x00400000, 0x2de },
3141 { 0x00000000, 0x00600000, 0x2b5 },
3142 { 0x00000000, 0x00600000, 0x65f },
3143 { 0x00000000, 0x00400000, 0x2de },
3144 { 0x00000000, 0x00600000, 0x2a7 },
3145 { 0x00000000, 0x00400000, 0x2de },
3146 { 0x0000001a, 0x00201e2d, 0x000 },
3147 { 0x0000001b, 0x0080222d, 0x000 },
3148 { 0x00000010, 0x00221e23, 0x000 },
3149 { 0x00000000, 0x00294887, 0x000 },
3150 { 0x00000000, 0x00311ca3, 0x000 },
3151 { 0x00000010, 0x00221e27, 0x000 },
3152 { 0x00000000, 0x00294887, 0x000 },
3153 { 0x00000010, 0x00221e23, 0x000 },
3154 { 0x00000000, 0x003120c4, 0x000 },
3155 { 0x0000ffff, 0x00282228, 0x000 },
3156 { 0x00000000, 0x00894907, 0x000 },
3157 { 0x00000010, 0x00221e23, 0x000 },
3158 { 0x00000000, 0x00294887, 0x000 },
3159 { 0x00000010, 0x00221e21, 0x000 },
3160 { 0x00000000, 0x00294847, 0x000 },
3161 { 0x00000000, 0x00311ca3, 0x000 },
3162 { 0x00000010, 0x00221e27, 0x000 },
3163 { 0x00000000, 0x00294887, 0x000 },
3164 { 0x00000000, 0x00311ca1, 0x000 },
3165 { 0x00000010, 0x00221e27, 0x000 },
3166 { 0x00000000, 0x00294847, 0x000 },
3167 { 0x00000010, 0x00221e23, 0x000 },
3168 { 0x00000000, 0x003120c4, 0x000 },
3169 { 0x0000ffff, 0x00282228, 0x000 },
3170 { 0x00000000, 0x00294907, 0x000 },
3171 { 0x00000010, 0x00221e21, 0x000 },
3172 { 0x00000000, 0x003120c2, 0x000 },
3173 { 0x0000ffff, 0x00282228, 0x000 },
3174 { 0x00000000, 0x00894907, 0x000 },
3175 { 0x00000010, 0x00221e23, 0x000 },
3176 { 0x00000000, 0x00294887, 0x000 },
3177 { 0x00000001, 0x00220a21, 0x000 },
3178 { 0x00000000, 0x003308a2, 0x000 },
3179 { 0x00000010, 0x00221e22, 0x000 },
3180 { 0x00000010, 0x00212222, 0x000 },
3181 { 0x00000000, 0x00294907, 0x000 },
3182 { 0x00000000, 0x00311ca3, 0x000 },
3183 { 0x00000010, 0x00221e27, 0x000 },
3184 { 0x00000000, 0x00294887, 0x000 },
3185 { 0x00000001, 0x00220a21, 0x000 },
3186 { 0x00000000, 0x003008a2, 0x000 },
3187 { 0x00000010, 0x00221e22, 0x000 },
3188 { 0x00000010, 0x00212222, 0x000 },
3189 { 0x00000000, 0x00294907, 0x000 },
3190 { 0x00000010, 0x00221e23, 0x000 },
3191 { 0x00000000, 0x003120c4, 0x000 },
3192 { 0x0000ffff, 0x00282228, 0x000 },
3193 { 0x00000000, 0x00294907, 0x000 },
3194 { 0x00000000, 0x003808c5, 0x000 },
3195 { 0x00000000, 0x00300841, 0x000 },
3196 { 0x00000001, 0x00220a22, 0x000 },
3197 { 0x00000000, 0x003308a2, 0x000 },
3198 { 0x00000010, 0x00221e22, 0x000 },
3199 { 0x00000010, 0x00212222, 0x000 },
3200 { 0x00000000, 0x00894907, 0x000 },
3201 { 0x00000017, 0x0020222d, 0x000 },
3202 { 0x00000000, 0x14c00000, 0x318 },
3203 { 0xffffffef, 0x00280621, 0x000 },
3204 { 0x00000014, 0x0020222d, 0x000 },
3205 { 0x0000f8e0, 0x00204411, 0x000 },
3206 { 0x00000000, 0x00294901, 0x000 },
3207 { 0x00000000, 0x00894901, 0x000 },
3208 { 0x00000000, 0x00204811, 0x000 },
3209 { 0x00000000, 0x00204811, 0x000 },
3210 { 0x060a0200, 0x00804811, 0x000 },
3211 { 0x00000000, 0xc0200000, 0x000 },
3212 { 0x97000000, 0xc0204411, 0x000 },
3213 { 0x00000000, 0xc0204811, 0x000 },
3214 { 0x8a000000, 0x00204411, 0x000 },
3215 { 0x00000000, 0x00204811, 0x000 },
3216 { 0x0000225c, 0x00204411, 0x000 },
3217 { 0x00000000, 0xc0204800, 0x000 },
3218 { 0x0000a1fc, 0x00204411, 0x000 },
3219 { 0x00000000, 0xc0204800, 0x000 },
3220 { 0x00000000, 0xc0200400, 0x000 },
3221 { 0x00000000, 0x00a0000a, 0x000 },
3222 { 0x97000000, 0x00204411, 0x000 },
3223 { 0x00000000, 0x00204811, 0x000 },
3224 { 0x8a000000, 0x00204411, 0x000 },
3225 { 0x00000000, 0x00204811, 0x000 },
3226 { 0x0000225c, 0x00204411, 0x000 },
3227 { 0x00000000, 0xc0204800, 0x000 },
3228 { 0x0000a1fc, 0x00204411, 0x000 },
3229 { 0x00000000, 0xc0204800, 0x000 },
3230 { 0x00000000, 0xc0200400, 0x000 },
3231 { 0x00000000, 0x00a0000a, 0x000 },
3232 { 0x97000000, 0x00204411, 0x000 },
3233 { 0x00000000, 0x00204811, 0x000 },
3234 { 0x8a000000, 0x00204411, 0x000 },
3235 { 0x00000000, 0x00204811, 0x000 },
3236 { 0x0000225c, 0x00204411, 0x000 },
3237 { 0x00000000, 0xc0204800, 0x000 },
3238 { 0x0000a1fc, 0x00204411, 0x000 },
3239 { 0x00000000, 0xc0204800, 0x000 },
3240 { 0x0001a1fd, 0x00204411, 0x000 },
3241 { 0x00000000, 0xd9004800, 0x000 },
3242 { 0x00000000, 0xc0200400, 0x000 },
3243 { 0x00000000, 0x00a0000a, 0x000 },
3244 { 0x00002257, 0x00204411, 0x000 },
3245 { 0x00000003, 0xc0484a20, 0x000 },
3246 { 0x0000225d, 0x00204411, 0x000 },
3247 { 0x00000000, 0xc0404800, 0x000 },
3248 { 0x00000000, 0x00600000, 0x645 },
3249 { 0x00000000, 0xc0200800, 0x000 },
3250 { 0x0000225c, 0x00204411, 0x000 },
3251 { 0x00000003, 0x00384a22, 0x000 },
3252 { 0x0000a1fc, 0x00204411, 0x000 },
3253 { 0x00000000, 0xc0204800, 0x000 },
3254 { 0x0001a1fd, 0x00204411, 0x000 },
3255 { 0x00000000, 0x002f0222, 0x000 },
3256 { 0x00000000, 0x0ce00000, 0x000 },
3257 { 0x00000000, 0x40204800, 0x000 },
3258 { 0x00000001, 0x40304a20, 0x000 },
3259 { 0x00000002, 0xc0304a20, 0x000 },
3260 { 0x00000001, 0x00530a22, 0x34b },
3261 { 0x0000003f, 0xc0280a20, 0x000 },
3262 { 0x81000000, 0x00204411, 0x000 },
3263 { 0x00000001, 0x00204811, 0x000 },
3264 { 0x000021f8, 0x00204411, 0x000 },
3265 { 0x00000018, 0x00204811, 0x000 },
3266 { 0x000421f9, 0x00604411, 0x68d },
3267 { 0x00000011, 0x00210230, 0x000 },
3268 { 0x00000000, 0x14e00000, 0x354 },
3269 { 0x00000014, 0x002f0222, 0x000 },
3270 { 0x00000000, 0x0cc00000, 0x364 },
3271 { 0x00002010, 0x00204411, 0x000 },
3272 { 0x00008000, 0x00204811, 0x000 },
3273 { 0x0001a2a4, 0x00204411, 0x000 },
3274 { 0x00000000, 0x00604802, 0x36e },
3275 { 0x00002100, 0x00204411, 0x000 },
3276 { 0x00000000, 0xc0204800, 0x000 },
3277 { 0x00000000, 0xc0204800, 0x000 },
3278 { 0x00000000, 0xc0204800, 0x000 },
3279 { 0x00000000, 0xc0404800, 0x000 },
3280 { 0x00000004, 0x002f0222, 0x000 },
3281 { 0x00000000, 0x0cc00000, 0x36a },
3282 { 0x00002010, 0x00204411, 0x000 },
3283 { 0x00008000, 0x00204811, 0x000 },
3284 { 0x0001a2a4, 0x00204411, 0x000 },
3285 { 0x00000000, 0x00404802, 0x35f },
3286 { 0x00000028, 0x002f0222, 0x000 },
3287 { 0x00000000, 0x0cc00000, 0x5c0 },
3288 { 0x0001a2a4, 0x00204411, 0x000 },
3289 { 0x00000000, 0x00404802, 0x35f },
3290 { 0x0000002c, 0x00203626, 0x000 },
3291 { 0x00000049, 0x00201811, 0x000 },
3292 { 0x0000003f, 0x00204811, 0x000 },
3293 { 0x00000001, 0x00331a26, 0x000 },
3294 { 0x00000000, 0x002f0226, 0x000 },
3295 { 0x00000000, 0x0cc00000, 0x370 },
3296 { 0x0000002c, 0x00801a2d, 0x000 },
3297 { 0x0000003f, 0xc0280a20, 0x000 },
3298 { 0x00000015, 0x002f0222, 0x000 },
3299 { 0x00000000, 0x0ce00000, 0x386 },
3300 { 0x00000006, 0x002f0222, 0x000 },
3301 { 0x00000000, 0x0ce00000, 0x3b1 },
3302 { 0x00000016, 0x002f0222, 0x000 },
3303 { 0x00000000, 0x0ce00000, 0x3b5 },
3304 { 0x00000020, 0x002f0222, 0x000 },
3305 { 0x00000000, 0x0ce00000, 0x39c },
3306 { 0x0000000f, 0x002f0222, 0x000 },
3307 { 0x00000000, 0x0ce00000, 0x3a8 },
3308 { 0x00000010, 0x002f0222, 0x000 },
3309 { 0x00000000, 0x0ce00000, 0x3a8 },
3310 { 0x0000001e, 0x002f0222, 0x000 },
3311 { 0x00000000, 0x0ce00000, 0x390 },
3312 { 0x0000a2a4, 0x00204411, 0x000 },
3313 { 0x00000000, 0x00404802, 0x000 },
3314 { 0x08000000, 0x00290a22, 0x000 },
3315 { 0x00000003, 0x40210e20, 0x000 },
3316 { 0x0000000c, 0xc0211220, 0x000 },
3317 { 0x00080000, 0x00281224, 0x000 },
3318 { 0x00000014, 0xc0221620, 0x000 },
3319 { 0x00000000, 0x002914a4, 0x000 },
3320 { 0x0000a2a4, 0x00204411, 0x000 },
3321 { 0x00000000, 0x002948a2, 0x000 },
3322 { 0x0000a1fe, 0x00204411, 0x000 },
3323 { 0x00000000, 0x00404803, 0x000 },
3324 { 0x81000000, 0x00204411, 0x000 },
3325 { 0x00000001, 0x00204811, 0x000 },
3326 { 0x000021f8, 0x00204411, 0x000 },
3327 { 0x00000016, 0x00204811, 0x000 },
3328 { 0x000421f9, 0x00604411, 0x68d },
3329 { 0x00000015, 0x00210230, 0x000 },
3330 { 0x00000000, 0x14e00000, 0x392 },
3331 { 0x0000210e, 0x00204411, 0x000 },
3332 { 0x00000000, 0xc0204800, 0x000 },
3333 { 0x00000000, 0xc0204800, 0x000 },
3334 { 0x0000a2a4, 0x00204411, 0x000 },
3335 { 0x00000000, 0x00404802, 0x000 },
3336 { 0x81000000, 0x00204411, 0x000 },
3337 { 0x00000001, 0x00204811, 0x000 },
3338 { 0x000021f8, 0x00204411, 0x000 },
3339 { 0x00000017, 0x00204811, 0x000 },
3340 { 0x000421f9, 0x00604411, 0x68d },
3341 { 0x00000003, 0x00210230, 0x000 },
3342 { 0x00000000, 0x14e00000, 0x39e },
3343 { 0x00002108, 0x00204411, 0x000 },
3344 { 0x00000000, 0xc0204800, 0x000 },
3345 { 0x00000000, 0xc0204800, 0x000 },
3346 { 0x0000a2a4, 0x00204411, 0x000 },
3347 { 0x00000000, 0x00404802, 0x000 },
3348 { 0x0000a2a4, 0x00204411, 0x000 },
3349 { 0x00000000, 0x00204802, 0x000 },
3350 { 0x80000000, 0x00204411, 0x000 },
3351 { 0x00000000, 0x00204811, 0x000 },
3352 { 0x81000000, 0x00204411, 0x000 },
3353 { 0x00000010, 0x00204811, 0x000 },
3354 { 0x00000000, 0x00200010, 0x000 },
3355 { 0x00000000, 0x14c00000, 0x3ae },
3356 { 0x00000000, 0x00400000, 0x000 },
3357 { 0x00002010, 0x00204411, 0x000 },
3358 { 0x00008000, 0x00204811, 0x000 },
3359 { 0x0001a2a4, 0x00204411, 0x000 },
3360 { 0x00000006, 0x00404811, 0x000 },
3361 { 0x00002010, 0x00204411, 0x000 },
3362 { 0x00008000, 0x00204811, 0x000 },
3363 { 0x0001a2a4, 0x00204411, 0x000 },
3364 { 0x00000016, 0x00604811, 0x36e },
3365 { 0x00000000, 0x00400000, 0x000 },
3366 { 0x00000000, 0xc0200800, 0x000 },
3367 { 0x00000000, 0xc0200c00, 0x000 },
3368 { 0x0000001d, 0x00210223, 0x000 },
3369 { 0x00000000, 0x14e00000, 0x3ce },
3370 { 0x81000000, 0x00204411, 0x000 },
3371 { 0x00000001, 0x00204811, 0x000 },
3372 { 0x000021f8, 0x00204411, 0x000 },
3373 { 0x00000018, 0x00204811, 0x000 },
3374 { 0x000421f9, 0x00604411, 0x68d },
3375 { 0x00000011, 0x00210230, 0x000 },
3376 { 0x00000000, 0x14e00000, 0x3c0 },
3377 { 0x00002100, 0x00204411, 0x000 },
3378 { 0x00000000, 0x00204802, 0x000 },
3379 { 0x00000000, 0x00204803, 0x000 },
3380 { 0xbabecafe, 0x00204811, 0x000 },
3381 { 0xcafebabe, 0x00204811, 0x000 },
3382 { 0x00002010, 0x00204411, 0x000 },
3383 { 0x00008000, 0x00204811, 0x000 },
3384 { 0x0000a2a4, 0x00204411, 0x000 },
3385 { 0x00000004, 0x00404811, 0x000 },
3386 { 0x00002170, 0x00204411, 0x000 },
3387 { 0x00000000, 0x00204802, 0x000 },
3388 { 0x00000000, 0x00204803, 0x000 },
3389 { 0x81000000, 0x00204411, 0x000 },
3390 { 0x0000000a, 0x00204811, 0x000 },
3391 { 0x00000000, 0x00200010, 0x000 },
3392 { 0x00000000, 0x14c00000, 0x3d3 },
3393 { 0x8c000000, 0x00204411, 0x000 },
3394 { 0xcafebabe, 0x00404811, 0x000 },
3395 { 0x81000000, 0x00204411, 0x000 },
3396 { 0x00000001, 0x00204811, 0x000 },
3397 { 0x00003fff, 0x40280a20, 0x000 },
3398 { 0x80000000, 0x40280e20, 0x000 },
3399 { 0x40000000, 0xc0281220, 0x000 },
3400 { 0x00040000, 0x00694622, 0x68d },
3401 { 0x00000000, 0x00201410, 0x000 },
3402 { 0x00000000, 0x002f0223, 0x000 },
3403 { 0x00000000, 0x0cc00000, 0x3e1 },
3404 { 0x00000000, 0xc0401800, 0x3e4 },
3405 { 0x00003fff, 0xc0281a20, 0x000 },
3406 { 0x00040000, 0x00694626, 0x68d },
3407 { 0x00000000, 0x00201810, 0x000 },
3408 { 0x00000000, 0x002f0224, 0x000 },
3409 { 0x00000000, 0x0cc00000, 0x3e7 },
3410 { 0x00000000, 0xc0401c00, 0x3ea },
3411 { 0x00003fff, 0xc0281e20, 0x000 },
3412 { 0x00040000, 0x00694627, 0x68d },
3413 { 0x00000000, 0x00201c10, 0x000 },
3414 { 0x00000000, 0x00204402, 0x000 },
3415 { 0x00000000, 0x002820c5, 0x000 },
3416 { 0x00000000, 0x004948e8, 0x000 },
3417 { 0xa5800000, 0x00200811, 0x000 },
3418 { 0x00002000, 0x00200c11, 0x000 },
3419 { 0x83000000, 0x00604411, 0x412 },
3420 { 0x00000000, 0x00204402, 0x000 },
3421 { 0x00000000, 0xc0204800, 0x000 },
3422 { 0x00000000, 0x40204800, 0x000 },
3423 { 0x0000001f, 0xc0210220, 0x000 },
3424 { 0x00000000, 0x14c00000, 0x3f7 },
3425 { 0x00002010, 0x00204411, 0x000 },
3426 { 0x00008000, 0x00204811, 0x000 },
3427 { 0x0000ffff, 0xc0481220, 0x3ff },
3428 { 0xa7800000, 0x00200811, 0x000 },
3429 { 0x0000a000, 0x00200c11, 0x000 },
3430 { 0x83000000, 0x00604411, 0x412 },
3431 { 0x00000000, 0x00204402, 0x000 },
3432 { 0x00000000, 0xc0204800, 0x000 },
3433 { 0x00000000, 0xc0204800, 0x000 },
3434 { 0x0000ffff, 0xc0281220, 0x000 },
3435 { 0x83000000, 0x00204411, 0x000 },
3436 { 0x00000000, 0x00304883, 0x000 },
3437 { 0x84000000, 0x00204411, 0x000 },
3438 { 0x00000000, 0xc0204800, 0x000 },
3439 { 0x00000000, 0x1d000000, 0x000 },
3440 { 0x83000000, 0x00604411, 0x412 },
3441 { 0x00000000, 0xc0400400, 0x001 },
3442 { 0xa9800000, 0x00200811, 0x000 },
3443 { 0x0000c000, 0x00400c11, 0x3fa },
3444 { 0xab800000, 0x00200811, 0x000 },
3445 { 0x0000f8e0, 0x00400c11, 0x3fa },
3446 { 0xad800000, 0x00200811, 0x000 },
3447 { 0x0000f880, 0x00400c11, 0x3fa },
3448 { 0xb3800000, 0x00200811, 0x000 },
3449 { 0x0000f3fc, 0x00400c11, 0x3fa },
3450 { 0xaf800000, 0x00200811, 0x000 },
3451 { 0x0000e000, 0x00400c11, 0x3fa },
3452 { 0xb1800000, 0x00200811, 0x000 },
3453 { 0x0000f000, 0x00400c11, 0x3fa },
3454 { 0x83000000, 0x00204411, 0x000 },
3455 { 0x00002148, 0x00204811, 0x000 },
3456 { 0x84000000, 0x00204411, 0x000 },
3457 { 0x00000000, 0xc0204800, 0x000 },
3458 { 0x00000000, 0x1d000000, 0x000 },
3459 { 0x00000000, 0x00800000, 0x000 },
3460 { 0x01182000, 0xc0304620, 0x000 },
3461 { 0x00000000, 0xd9004800, 0x000 },
3462 { 0x00000000, 0xc0200400, 0x000 },
3463 { 0x00000000, 0x00a0000a, 0x000 },
3464 { 0x0218a000, 0xc0304620, 0x000 },
3465 { 0x00000000, 0xd9004800, 0x000 },
3466 { 0x00000000, 0xc0200400, 0x000 },
3467 { 0x00000000, 0x00a0000a, 0x000 },
3468 { 0x0318c000, 0xc0304620, 0x000 },
3469 { 0x00000000, 0xd9004800, 0x000 },
3470 { 0x00000000, 0xc0200400, 0x000 },
3471 { 0x00000000, 0x00a0000a, 0x000 },
3472 { 0x0418f8e0, 0xc0304620, 0x000 },
3473 { 0x00000000, 0xd9004800, 0x000 },
3474 { 0x00000000, 0xc0200400, 0x000 },
3475 { 0x00000000, 0x00a0000a, 0x000 },
3476 { 0x0518f880, 0xc0304620, 0x000 },
3477 { 0x00000000, 0xd9004800, 0x000 },
3478 { 0x00000000, 0xc0200400, 0x000 },
3479 { 0x00000000, 0x00a0000a, 0x000 },
3480 { 0x0618e000, 0xc0304620, 0x000 },
3481 { 0x00000000, 0xd9004800, 0x000 },
3482 { 0x00000000, 0xc0200400, 0x000 },
3483 { 0x00000000, 0x00a0000a, 0x000 },
3484 { 0x0718f000, 0xc0304620, 0x000 },
3485 { 0x00000000, 0xd9004800, 0x000 },
3486 { 0x00000000, 0xc0200400, 0x000 },
3487 { 0x00000000, 0x00a0000a, 0x000 },
3488 { 0x0818f3fc, 0xc0304620, 0x000 },
3489 { 0x00000000, 0xd9004800, 0x000 },
3490 { 0x00000000, 0xc0200400, 0x000 },
3491 { 0x00000000, 0x00a0000a, 0x000 },
3492 { 0x00000030, 0x00200a2d, 0x000 },
3493 { 0x00000000, 0xc0290c40, 0x000 },
3494 { 0x00000030, 0x00203623, 0x000 },
3495 { 0x00000000, 0xc0200400, 0x000 },
3496 { 0x00000000, 0x00a0000a, 0x000 },
3497 { 0x86000000, 0x00204411, 0x000 },
3498 { 0x00000000, 0x00404801, 0x000 },
3499 { 0x85000000, 0xc0204411, 0x000 },
3500 { 0x00000000, 0x00404801, 0x000 },
3501 { 0x0000217c, 0x00204411, 0x000 },
3502 { 0x00000018, 0x40210220, 0x000 },
3503 { 0x00000000, 0x14c00000, 0x445 },
3504 { 0x00800000, 0xc0494a20, 0x446 },
3505 { 0x00000000, 0xc0204800, 0x000 },
3506 { 0x00000000, 0xc0204800, 0x000 },
3507 { 0x00000000, 0xc0204800, 0x000 },
3508 { 0x81000000, 0x00204411, 0x000 },
3509 { 0x00000001, 0x00204811, 0x000 },
3510 { 0x00000000, 0xc0200800, 0x000 },
3511 { 0x00000000, 0x17000000, 0x000 },
3512 { 0x0004217f, 0x00604411, 0x68d },
3513 { 0x0000001f, 0x00210230, 0x000 },
3514 { 0x00000000, 0x14c00000, 0x000 },
3515 { 0x00000000, 0x00404c02, 0x44b },
3516 { 0x00000000, 0xc0200c00, 0x000 },
3517 { 0x00000000, 0xc0201000, 0x000 },
3518 { 0x00000000, 0xc0201400, 0x000 },
3519 { 0x00000000, 0xc0201800, 0x000 },
3520 { 0x00000000, 0xc0201c00, 0x000 },
3521 { 0x00007f00, 0x00280a21, 0x000 },
3522 { 0x00004500, 0x002f0222, 0x000 },
3523 { 0x00000000, 0x0ce00000, 0x459 },
3524 { 0x00000000, 0xc0202000, 0x000 },
3525 { 0x00000000, 0x17000000, 0x000 },
3526 { 0x00000010, 0x00280a23, 0x000 },
3527 { 0x00000010, 0x002f0222, 0x000 },
3528 { 0x00000000, 0x0ce00000, 0x461 },
3529 { 0x81000000, 0x00204411, 0x000 },
3530 { 0x00000001, 0x00204811, 0x000 },
3531 { 0x00040000, 0x00694624, 0x68d },
3532 { 0x00000000, 0x00400000, 0x466 },
3533 { 0x81000000, 0x00204411, 0x000 },
3534 { 0x00000000, 0x00204811, 0x000 },
3535 { 0x0000216d, 0x00204411, 0x000 },
3536 { 0x00000000, 0x00204804, 0x000 },
3537 { 0x00000000, 0x00604805, 0x692 },
3538 { 0x00000000, 0x002824f0, 0x000 },
3539 { 0x00000007, 0x00280a23, 0x000 },
3540 { 0x00000001, 0x002f0222, 0x000 },
3541 { 0x00000000, 0x0ae00000, 0x46d },
3542 { 0x00000000, 0x002f00c9, 0x000 },
3543 { 0x00000000, 0x04e00000, 0x486 },
3544 { 0x00000000, 0x00400000, 0x493 },
3545 { 0x00000002, 0x002f0222, 0x000 },
3546 { 0x00000000, 0x0ae00000, 0x472 },
3547 { 0x00000000, 0x002f00c9, 0x000 },
3548 { 0x00000000, 0x02e00000, 0x486 },
3549 { 0x00000000, 0x00400000, 0x493 },
3550 { 0x00000003, 0x002f0222, 0x000 },
3551 { 0x00000000, 0x0ae00000, 0x477 },
3552 { 0x00000000, 0x002f00c9, 0x000 },
3553 { 0x00000000, 0x0ce00000, 0x486 },
3554 { 0x00000000, 0x00400000, 0x493 },
3555 { 0x00000004, 0x002f0222, 0x000 },
3556 { 0x00000000, 0x0ae00000, 0x47c },
3557 { 0x00000000, 0x002f00c9, 0x000 },
3558 { 0x00000000, 0x0ae00000, 0x486 },
3559 { 0x00000000, 0x00400000, 0x493 },
3560 { 0x00000005, 0x002f0222, 0x000 },
3561 { 0x00000000, 0x0ae00000, 0x481 },
3562 { 0x00000000, 0x002f00c9, 0x000 },
3563 { 0x00000000, 0x06e00000, 0x486 },
3564 { 0x00000000, 0x00400000, 0x493 },
3565 { 0x00000006, 0x002f0222, 0x000 },
3566 { 0x00000000, 0x0ae00000, 0x486 },
3567 { 0x00000000, 0x002f00c9, 0x000 },
3568 { 0x00000000, 0x08e00000, 0x486 },
3569 { 0x00000000, 0x00400000, 0x493 },
3570 { 0x00007f00, 0x00280a21, 0x000 },
3571 { 0x00004500, 0x002f0222, 0x000 },
3572 { 0x00000000, 0x0ae00000, 0x000 },
3573 { 0x00000008, 0x00210a23, 0x000 },
3574 { 0x00000000, 0x14c00000, 0x490 },
3575 { 0x00002169, 0x00204411, 0x000 },
3576 { 0x00000000, 0xc0204800, 0x000 },
3577 { 0x00000000, 0xc0204800, 0x000 },
3578 { 0x00000000, 0xc0204800, 0x000 },
3579 { 0xcafebabe, 0x00404811, 0x000 },
3580 { 0x00000000, 0xc0204400, 0x000 },
3581 { 0x00000000, 0xc0200000, 0x000 },
3582 { 0x00000000, 0xc0404800, 0x000 },
3583 { 0x00007f00, 0x00280a21, 0x000 },
3584 { 0x00004500, 0x002f0222, 0x000 },
3585 { 0x00000000, 0x0ae00000, 0x499 },
3586 { 0x00000000, 0xc0200000, 0x000 },
3587 { 0x00000000, 0xc0200000, 0x000 },
3588 { 0x00000000, 0xc0400000, 0x000 },
3589 { 0x00000000, 0x00404c08, 0x459 },
3590 { 0x00000000, 0xc0200800, 0x000 },
3591 { 0x00000010, 0x40210e20, 0x000 },
3592 { 0x00000011, 0x40211220, 0x000 },
3593 { 0x00000012, 0x40211620, 0x000 },
3594 { 0x00002169, 0x00204411, 0x000 },
3595 { 0x00000000, 0x00204802, 0x000 },
3596 { 0x00000000, 0x00210225, 0x000 },
3597 { 0x00000000, 0x14e00000, 0x4a3 },
3598 { 0x00040000, 0xc0494a20, 0x4a4 },
3599 { 0xfffbffff, 0xc0284a20, 0x000 },
3600 { 0x00000000, 0x00210223, 0x000 },
3601 { 0x00000000, 0x14e00000, 0x4b0 },
3602 { 0x00000000, 0xc0204800, 0x000 },
3603 { 0x00000000, 0xc0204800, 0x000 },
3604 { 0x00000000, 0x00210224, 0x000 },
3605 { 0x00000000, 0x14c00000, 0x000 },
3606 { 0x81000000, 0x00204411, 0x000 },
3607 { 0x0000000c, 0x00204811, 0x000 },
3608 { 0x00000000, 0x00200010, 0x000 },
3609 { 0x00000000, 0x14c00000, 0x4ac },
3610 { 0xa0000000, 0x00204411, 0x000 },
3611 { 0xcafebabe, 0x00404811, 0x000 },
3612 { 0x81000000, 0x00204411, 0x000 },
3613 { 0x00000004, 0x00204811, 0x000 },
3614 { 0x0000216b, 0x00204411, 0x000 },
3615 { 0x00000000, 0xc0204810, 0x000 },
3616 { 0x81000000, 0x00204411, 0x000 },
3617 { 0x00000005, 0x00204811, 0x000 },
3618 { 0x0000216c, 0x00204411, 0x000 },
3619 { 0x00000000, 0xc0204810, 0x000 },
3620 { 0x00000000, 0x002f0224, 0x000 },
3621 { 0x00000000, 0x0ce00000, 0x000 },
3622 { 0x00000000, 0x00400000, 0x4aa },
3623 { 0x00000000, 0xc0210a20, 0x000 },
3624 { 0x00000000, 0x14c00000, 0x4c3 },
3625 { 0x81000000, 0x00204411, 0x000 },
3626 { 0x00000000, 0x00204811, 0x000 },
3627 { 0x0000216d, 0x00204411, 0x000 },
3628 { 0x00000000, 0xc0204800, 0x000 },
3629 { 0x00000000, 0xc0604800, 0x692 },
3630 { 0x00000000, 0x00400000, 0x4c7 },
3631 { 0x81000000, 0x00204411, 0x000 },
3632 { 0x00000001, 0x00204811, 0x000 },
3633 { 0x00040000, 0xc0294620, 0x000 },
3634 { 0x00000000, 0xc0600000, 0x68d },
3635 { 0x00000001, 0x00210222, 0x000 },
3636 { 0x00000000, 0x14c00000, 0x4ce },
3637 { 0x00002169, 0x00204411, 0x000 },
3638 { 0x00000000, 0xc0204800, 0x000 },
3639 { 0x00000000, 0xc0204800, 0x000 },
3640 { 0x00000000, 0x00204810, 0x000 },
3641 { 0xcafebabe, 0x00404811, 0x000 },
3642 { 0x00000000, 0xc0204400, 0x000 },
3643 { 0x00000000, 0xc0404810, 0x000 },
3644 { 0x81000000, 0x00204411, 0x000 },
3645 { 0x00000001, 0x00204811, 0x000 },
3646 { 0x000021f8, 0x00204411, 0x000 },
3647 { 0x0000000e, 0x00204811, 0x000 },
3648 { 0x000421f9, 0x00604411, 0x68d },
3649 { 0x00000000, 0x00210230, 0x000 },
3650 { 0x00000000, 0x14c00000, 0x4d0 },
3651 { 0x00002180, 0x00204411, 0x000 },
3652 { 0x00000000, 0xc0204800, 0x000 },
3653 { 0x00000000, 0xc0200000, 0x000 },
3654 { 0x00000000, 0xc0204800, 0x000 },
3655 { 0x00000000, 0xc0200000, 0x000 },
3656 { 0x00000000, 0xc0404800, 0x000 },
3657 { 0x00000003, 0x00333e2f, 0x000 },
3658 { 0x00000001, 0x00210221, 0x000 },
3659 { 0x00000000, 0x14e00000, 0x500 },
3660 { 0x0000002c, 0x00200a2d, 0x000 },
3661 { 0x00040000, 0x18e00c11, 0x4ef },
3662 { 0x00000001, 0x00333e2f, 0x000 },
3663 { 0x00002169, 0x00204411, 0x000 },
3664 { 0x00000000, 0x00204802, 0x000 },
3665 { 0x00000000, 0x00204803, 0x000 },
3666 { 0x00000008, 0x00300a22, 0x000 },
3667 { 0x00000000, 0xc0204800, 0x000 },
3668 { 0x00000000, 0xc0204800, 0x000 },
3669 { 0x00002169, 0x00204411, 0x000 },
3670 { 0x00000000, 0x00204802, 0x000 },
3671 { 0x00000000, 0x00204803, 0x000 },
3672 { 0x00000008, 0x00300a22, 0x000 },
3673 { 0x00000000, 0xc0204800, 0x000 },
3674 { 0x00000000, 0xd8c04800, 0x4e3 },
3675 { 0x00002169, 0x00204411, 0x000 },
3676 { 0x00000000, 0x00204802, 0x000 },
3677 { 0x00000000, 0x00204803, 0x000 },
3678 { 0x00000008, 0x00300a22, 0x000 },
3679 { 0x00000000, 0xc0204800, 0x000 },
3680 { 0x00000000, 0xc0204800, 0x000 },
3681 { 0x0000002d, 0x0020122d, 0x000 },
3682 { 0x00000000, 0x00290c83, 0x000 },
3683 { 0x00002169, 0x00204411, 0x000 },
3684 { 0x00000000, 0x00204802, 0x000 },
3685 { 0x00000000, 0x00204803, 0x000 },
3686 { 0x00000008, 0x00300a22, 0x000 },
3687 { 0x00000000, 0xc0204800, 0x000 },
3688 { 0x00000000, 0xc0204800, 0x000 },
3689 { 0x00000011, 0x00210224, 0x000 },
3690 { 0x00000000, 0x14c00000, 0x000 },
3691 { 0x00000000, 0x00400000, 0x4aa },
3692 { 0x0000002c, 0xc0203620, 0x000 },
3693 { 0x0000002d, 0xc0403620, 0x000 },
3694 { 0x0000000f, 0x00210221, 0x000 },
3695 { 0x00000000, 0x14c00000, 0x505 },
3696 { 0x00000000, 0x00600000, 0x00b },
3697 { 0x00000000, 0xd9000000, 0x000 },
3698 { 0x00000000, 0xc0400400, 0x001 },
3699 { 0xb5000000, 0x00204411, 0x000 },
3700 { 0x00002000, 0x00204811, 0x000 },
3701 { 0xb6000000, 0x00204411, 0x000 },
3702 { 0x0000a000, 0x00204811, 0x000 },
3703 { 0xb7000000, 0x00204411, 0x000 },
3704 { 0x0000c000, 0x00204811, 0x000 },
3705 { 0xb8000000, 0x00204411, 0x000 },
3706 { 0x0000f8e0, 0x00204811, 0x000 },
3707 { 0xb9000000, 0x00204411, 0x000 },
3708 { 0x0000f880, 0x00204811, 0x000 },
3709 { 0xba000000, 0x00204411, 0x000 },
3710 { 0x0000e000, 0x00204811, 0x000 },
3711 { 0xbb000000, 0x00204411, 0x000 },
3712 { 0x0000f000, 0x00204811, 0x000 },
3713 { 0xbc000000, 0x00204411, 0x000 },
3714 { 0x0000f3fc, 0x00204811, 0x000 },
3715 { 0x81000000, 0x00204411, 0x000 },
3716 { 0x00000002, 0x00204811, 0x000 },
3717 { 0x000000ff, 0x00280e30, 0x000 },
3718 { 0x00000000, 0x002f0223, 0x000 },
3719 { 0x00000000, 0x0cc00000, 0x519 },
3720 { 0x00000000, 0xc0200800, 0x000 },
3721 { 0x00000000, 0x14c00000, 0x52e },
3722 { 0x00000000, 0x00200c11, 0x000 },
3723 { 0x0000001c, 0x00203623, 0x000 },
3724 { 0x0000002b, 0x00203623, 0x000 },
3725 { 0x00000029, 0x00203623, 0x000 },
3726 { 0x00000028, 0x00203623, 0x000 },
3727 { 0x00000017, 0x00203623, 0x000 },
3728 { 0x00000025, 0x00203623, 0x000 },
3729 { 0x00000026, 0x00203623, 0x000 },
3730 { 0x00000015, 0x00203623, 0x000 },
3731 { 0x00000016, 0x00203623, 0x000 },
3732 { 0xffffe000, 0x00200c11, 0x000 },
3733 { 0x00000021, 0x00203623, 0x000 },
3734 { 0x00000022, 0x00203623, 0x000 },
3735 { 0x00001fff, 0x00200c11, 0x000 },
3736 { 0x00000023, 0x00203623, 0x000 },
3737 { 0x00000024, 0x00203623, 0x000 },
3738 { 0xf1ffffff, 0x00283a2e, 0x000 },
3739 { 0x0000001a, 0xc0220e20, 0x000 },
3740 { 0x00000000, 0x0029386e, 0x000 },
3741 { 0x81000000, 0x00204411, 0x000 },
3742 { 0x00000006, 0x00204811, 0x000 },
3743 { 0x0000002a, 0x40203620, 0x000 },
3744 { 0x87000000, 0x00204411, 0x000 },
3745 { 0x00000000, 0xc0204800, 0x000 },
3746 { 0x0000a1f4, 0x00204411, 0x000 },
3747 { 0x00000000, 0x00204810, 0x000 },
3748 { 0x00000000, 0x00200c11, 0x000 },
3749 { 0x00000030, 0x00203623, 0x000 },
3750 { 0x9d000000, 0x00204411, 0x000 },
3751 { 0x0000001f, 0x40214a20, 0x000 },
3752 { 0x96000000, 0x00204411, 0x000 },
3753 { 0x00000000, 0xc0204800, 0x000 },
3754 { 0x00000000, 0xc0200c00, 0x000 },
3755 { 0x00000000, 0xc0201000, 0x000 },
3756 { 0x0000001f, 0x00211624, 0x000 },
3757 { 0x00000000, 0x14c00000, 0x000 },
3758 { 0x0000001d, 0x00203623, 0x000 },
3759 { 0x00000003, 0x00281e23, 0x000 },
3760 { 0x00000008, 0x00222223, 0x000 },
3761 { 0xfffff000, 0x00282228, 0x000 },
3762 { 0x00000000, 0x002920e8, 0x000 },
3763 { 0x0000001f, 0x00203628, 0x000 },
3764 { 0x00000018, 0x00211e23, 0x000 },
3765 { 0x00000020, 0x00203627, 0x000 },
3766 { 0x00000002, 0x00221624, 0x000 },
3767 { 0x00000000, 0x003014a8, 0x000 },
3768 { 0x0000001e, 0x00203625, 0x000 },
3769 { 0x00000003, 0x00211a24, 0x000 },
3770 { 0x10000000, 0x00281a26, 0x000 },
3771 { 0xefffffff, 0x00283a2e, 0x000 },
3772 { 0x00000000, 0x004938ce, 0x67b },
3773 { 0x00000001, 0x40280a20, 0x000 },
3774 { 0x00000006, 0x40280e20, 0x000 },
3775 { 0x00000300, 0xc0281220, 0x000 },
3776 { 0x00000008, 0x00211224, 0x000 },
3777 { 0x00000000, 0xc0201620, 0x000 },
3778 { 0x00000000, 0xc0201a20, 0x000 },
3779 { 0x00000000, 0x00210222, 0x000 },
3780 { 0x00000000, 0x14c00000, 0x566 },
3781 { 0x81000000, 0x00204411, 0x000 },
3782 { 0x00000001, 0x00204811, 0x000 },
3783 { 0x00002258, 0x00300a24, 0x000 },
3784 { 0x00040000, 0x00694622, 0x68d },
3785 { 0x00002169, 0x00204411, 0x000 },
3786 { 0x00000000, 0x00204805, 0x000 },
3787 { 0x00020000, 0x00294a26, 0x000 },
3788 { 0x00000000, 0x00204810, 0x000 },
3789 { 0xcafebabe, 0x00204811, 0x000 },
3790 { 0x00000002, 0x002f0223, 0x000 },
3791 { 0x00000000, 0x0cc00000, 0x56e },
3792 { 0x00000000, 0xc0201c10, 0x000 },
3793 { 0x00000000, 0xc0400000, 0x57c },
3794 { 0x00000002, 0x002f0223, 0x000 },
3795 { 0x00000000, 0x0cc00000, 0x56e },
3796 { 0x81000000, 0x00204411, 0x000 },
3797 { 0x00000001, 0x00204811, 0x000 },
3798 { 0x00002258, 0x00300a24, 0x000 },
3799 { 0x00040000, 0x00694622, 0x68d },
3800 { 0x00000000, 0xc0201c10, 0x000 },
3801 { 0x00000000, 0xc0400000, 0x57c },
3802 { 0x00000000, 0x002f0223, 0x000 },
3803 { 0x00000000, 0x0cc00000, 0x572 },
3804 { 0x00000000, 0xc0201c00, 0x000 },
3805 { 0x00000000, 0xc0400000, 0x57c },
3806 { 0x00000004, 0x002f0223, 0x000 },
3807 { 0x00000000, 0x0cc00000, 0x57a },
3808 { 0x81000000, 0x00204411, 0x000 },
3809 { 0x00000000, 0x00204811, 0x000 },
3810 { 0x0000216d, 0x00204411, 0x000 },
3811 { 0x00000000, 0xc0204800, 0x000 },
3812 { 0x00000000, 0xc0604800, 0x692 },
3813 { 0x00000000, 0x00401c10, 0x57c },
3814 { 0x00000000, 0xc0200000, 0x000 },
3815 { 0x00000000, 0xc0400000, 0x000 },
3816 { 0x00000000, 0x0ee00000, 0x57e },
3817 { 0x00000000, 0x00600000, 0x5c9 },
3818 { 0x00000000, 0x002f0224, 0x000 },
3819 { 0x00000000, 0x0cc00000, 0x58f },
3820 { 0x0000a2b7, 0x00204411, 0x000 },
3821 { 0x00000000, 0x00204807, 0x000 },
3822 { 0x81000000, 0x00204411, 0x000 },
3823 { 0x00000001, 0x00204811, 0x000 },
3824 { 0x0004a2b6, 0x00604411, 0x68d },
3825 { 0x0000001a, 0x00212230, 0x000 },
3826 { 0x00000006, 0x00222630, 0x000 },
3827 { 0x00042004, 0x00604411, 0x68d },
3828 { 0x0000a2c4, 0x00204411, 0x000 },
3829 { 0x00000000, 0x003048e9, 0x000 },
3830 { 0x00000000, 0x00e00000, 0x58d },
3831 { 0x0000a2d1, 0x00204411, 0x000 },
3832 { 0x00000000, 0x00404808, 0x000 },
3833 { 0x0000a2d1, 0x00204411, 0x000 },
3834 { 0x00000001, 0x00504a28, 0x000 },
3835 { 0x00000001, 0x002f0224, 0x000 },
3836 { 0x00000000, 0x0cc00000, 0x5a0 },
3837 { 0x0000a2bb, 0x00204411, 0x000 },
3838 { 0x00000000, 0x00204807, 0x000 },
3839 { 0x81000000, 0x00204411, 0x000 },
3840 { 0x00000001, 0x00204811, 0x000 },
3841 { 0x0004a2ba, 0x00604411, 0x68d },
3842 { 0x0000001a, 0x00212230, 0x000 },
3843 { 0x00000006, 0x00222630, 0x000 },
3844 { 0x00042004, 0x00604411, 0x68d },
3845 { 0x0000a2c5, 0x00204411, 0x000 },
3846 { 0x00000000, 0x003048e9, 0x000 },
3847 { 0x00000000, 0x00e00000, 0x59e },
3848 { 0x0000a2d2, 0x00204411, 0x000 },
3849 { 0x00000000, 0x00404808, 0x000 },
3850 { 0x0000a2d2, 0x00204411, 0x000 },
3851 { 0x00000001, 0x00504a28, 0x000 },
3852 { 0x00000002, 0x002f0224, 0x000 },
3853 { 0x00000000, 0x0cc00000, 0x5b1 },
3854 { 0x0000a2bf, 0x00204411, 0x000 },
3855 { 0x00000000, 0x00204807, 0x000 },
3856 { 0x81000000, 0x00204411, 0x000 },
3857 { 0x00000001, 0x00204811, 0x000 },
3858 { 0x0004a2be, 0x00604411, 0x68d },
3859 { 0x0000001a, 0x00212230, 0x000 },
3860 { 0x00000006, 0x00222630, 0x000 },
3861 { 0x00042004, 0x00604411, 0x68d },
3862 { 0x0000a2c6, 0x00204411, 0x000 },
3863 { 0x00000000, 0x003048e9, 0x000 },
3864 { 0x00000000, 0x00e00000, 0x5af },
3865 { 0x0000a2d3, 0x00204411, 0x000 },
3866 { 0x00000000, 0x00404808, 0x000 },
3867 { 0x0000a2d3, 0x00204411, 0x000 },
3868 { 0x00000001, 0x00504a28, 0x000 },
3869 { 0x0000a2c3, 0x00204411, 0x000 },
3870 { 0x00000000, 0x00204807, 0x000 },
3871 { 0x81000000, 0x00204411, 0x000 },
3872 { 0x00000001, 0x00204811, 0x000 },
3873 { 0x0004a2c2, 0x00604411, 0x68d },
3874 { 0x0000001a, 0x00212230, 0x000 },
3875 { 0x00000006, 0x00222630, 0x000 },
3876 { 0x00042004, 0x00604411, 0x68d },
3877 { 0x0000a2c7, 0x00204411, 0x000 },
3878 { 0x00000000, 0x003048e9, 0x000 },
3879 { 0x00000000, 0x00e00000, 0x5be },
3880 { 0x0000a2d4, 0x00204411, 0x000 },
3881 { 0x00000000, 0x00404808, 0x000 },
3882 { 0x0000a2d4, 0x00204411, 0x000 },
3883 { 0x00000001, 0x00504a28, 0x000 },
3884 { 0x85000000, 0x00204411, 0x000 },
3885 { 0x00000000, 0x00204801, 0x000 },
3886 { 0x0000304a, 0x00204411, 0x000 },
3887 { 0x01000000, 0x00204811, 0x000 },
3888 { 0x00000000, 0x00400000, 0x5c4 },
3889 { 0xa4000000, 0xc0204411, 0x000 },
3890 { 0x00000000, 0xc0404800, 0x000 },
3891 { 0x00000000, 0xc0600000, 0x5c9 },
3892 { 0x00000000, 0xc0400400, 0x001 },
3893 { 0x0000002c, 0x00203621, 0x000 },
3894 { 0x81000000, 0x00204411, 0x000 },
3895 { 0x00000006, 0x00204811, 0x000 },
3896 { 0x00000000, 0x002f0230, 0x000 },
3897 { 0x00000000, 0x0cc00000, 0x5d0 },
3898 { 0x00000000, 0x00200411, 0x000 },
3899 { 0x00000030, 0x00403621, 0x5e3 },
3900 { 0x00000030, 0x0020062d, 0x000 },
3901 { 0x00007e00, 0x00280621, 0x000 },
3902 { 0x00000000, 0x002f0221, 0x000 },
3903 { 0x00000000, 0x0ce00000, 0x5e3 },
3904 { 0x81000000, 0x00204411, 0x000 },
3905 { 0x00000001, 0x00204811, 0x000 },
3906 { 0x0004a092, 0x00604411, 0x68d },
3907 { 0x00000031, 0x00203630, 0x000 },
3908 { 0x0004a093, 0x00604411, 0x68d },
3909 { 0x00000032, 0x00203630, 0x000 },
3910 { 0x0004a2b6, 0x00604411, 0x68d },
3911 { 0x00000033, 0x00203630, 0x000 },
3912 { 0x0004a2ba, 0x00604411, 0x68d },
3913 { 0x00000034, 0x00203630, 0x000 },
3914 { 0x0004a2be, 0x00604411, 0x68d },
3915 { 0x00000035, 0x00203630, 0x000 },
3916 { 0x0004a2c2, 0x00604411, 0x68d },
3917 { 0x00000036, 0x00203630, 0x000 },
3918 { 0x00042004, 0x00604411, 0x68d },
3919 { 0x0001a2a4, 0x00204411, 0x000 },
3920 { 0x0000003f, 0x00204811, 0x000 },
3921 { 0x0000003f, 0x00204811, 0x000 },
3922 { 0x0000003f, 0x00204811, 0x000 },
3923 { 0x0000003f, 0x00204811, 0x000 },
3924 { 0x00000005, 0x00204811, 0x000 },
3925 { 0x0000a1f4, 0x00204411, 0x000 },
3926 { 0x00000000, 0x00204811, 0x000 },
3927 { 0x88000000, 0x00204411, 0x000 },
3928 { 0x00000001, 0x00204811, 0x000 },
3929 { 0x81000000, 0x00204411, 0x000 },
3930 { 0x00000006, 0x00204811, 0x000 },
3931 { 0x00000001, 0x002f0230, 0x000 },
3932 { 0x00000000, 0x0ce00000, 0x62c },
3933 { 0x00000030, 0x0020062d, 0x000 },
3934 { 0x00000000, 0x002f0221, 0x000 },
3935 { 0x00000000, 0x0ce00000, 0x62c },
3936 { 0x81000000, 0x00204411, 0x000 },
3937 { 0x00000001, 0x00204811, 0x000 },
3938 { 0x00007e00, 0x00280621, 0x000 },
3939 { 0x00000000, 0x002f0221, 0x000 },
3940 { 0x00000000, 0x0ce00000, 0x605 },
3941 { 0x0000a092, 0x00204411, 0x000 },
3942 { 0x00000031, 0x00204a2d, 0x000 },
3943 { 0x0000a093, 0x00204411, 0x000 },
3944 { 0x00000032, 0x00204a2d, 0x000 },
3945 { 0x0000a2b6, 0x00204411, 0x000 },
3946 { 0x00000033, 0x00204a2d, 0x000 },
3947 { 0x0000a2ba, 0x00204411, 0x000 },
3948 { 0x00000034, 0x00204a2d, 0x000 },
3949 { 0x0000a2be, 0x00204411, 0x000 },
3950 { 0x00000035, 0x00204a2d, 0x000 },
3951 { 0x0000a2c2, 0x00204411, 0x000 },
3952 { 0x00000036, 0x00204a2d, 0x000 },
3953 { 0x00000030, 0x0020062d, 0x000 },
3954 { 0x000001ff, 0x00280621, 0x000 },
3955 { 0x00000000, 0x002f0221, 0x000 },
3956 { 0x00000000, 0x0ce00000, 0x62b },
3957 { 0x00000000, 0x00210221, 0x000 },
3958 { 0x00000000, 0x14c00000, 0x60e },
3959 { 0x0004a003, 0x00604411, 0x68d },
3960 { 0x0000a003, 0x00204411, 0x000 },
3961 { 0x00000000, 0x00204810, 0x000 },
3962 { 0x00000001, 0x00210621, 0x000 },
3963 { 0x00000000, 0x14c00000, 0x613 },
3964 { 0x0004a010, 0x00604411, 0x68d },
3965 { 0x0000a010, 0x00204411, 0x000 },
3966 { 0x00000000, 0x00204810, 0x000 },
3967 { 0x00000001, 0x00210621, 0x000 },
3968 { 0x00000000, 0x002f0221, 0x000 },
3969 { 0x00000000, 0x0ce00000, 0x62b },
3970 { 0x0004a011, 0x00604411, 0x68d },
3971 { 0x0000a011, 0x00204411, 0x000 },
3972 { 0x00000000, 0x00204810, 0x000 },
3973 { 0x0004a012, 0x00604411, 0x68d },
3974 { 0x0000a012, 0x00204411, 0x000 },
3975 { 0x00000000, 0x00204810, 0x000 },
3976 { 0x0004a013, 0x00604411, 0x68d },
3977 { 0x0000a013, 0x00204411, 0x000 },
3978 { 0x00000000, 0x00204810, 0x000 },
3979 { 0x0004a014, 0x00604411, 0x68d },
3980 { 0x0000a014, 0x00204411, 0x000 },
3981 { 0x00000000, 0x00204810, 0x000 },
3982 { 0x0004a015, 0x00604411, 0x68d },
3983 { 0x0000a015, 0x00204411, 0x000 },
3984 { 0x00000000, 0x00204810, 0x000 },
3985 { 0x0004a016, 0x00604411, 0x68d },
3986 { 0x0000a016, 0x00204411, 0x000 },
3987 { 0x00000000, 0x00204810, 0x000 },
3988 { 0x0004a017, 0x00604411, 0x68d },
3989 { 0x0000a017, 0x00204411, 0x000 },
3990 { 0x00000000, 0x00204810, 0x000 },
3991 { 0x00042004, 0x00604411, 0x68d },
3992 { 0x0000002c, 0x0080062d, 0x000 },
3993 { 0xff000000, 0x00204411, 0x000 },
3994 { 0x00000000, 0x00204811, 0x000 },
3995 { 0x00000001, 0x00204811, 0x000 },
3996 { 0x00000002, 0x00804811, 0x000 },
3997 { 0x00000000, 0x0ee00000, 0x63d },
3998 { 0x00000030, 0x0020062d, 0x000 },
3999 { 0x00000002, 0x00280621, 0x000 },
4000 { 0x00000000, 0x002f0221, 0x000 },
4001 { 0x00000000, 0x0ce00000, 0x63b },
4002 { 0x81000000, 0x00204411, 0x000 },
4003 { 0x00000001, 0x00204811, 0x000 },
4004 { 0x00042004, 0x00604411, 0x68d },
4005 { 0x00001000, 0x00200811, 0x000 },
4006 { 0x0000002b, 0x00203622, 0x000 },
4007 { 0x00000000, 0x00600000, 0x641 },
4008 { 0x00000000, 0x00600000, 0x5c9 },
4009 { 0x98000000, 0x00204411, 0x000 },
4010 { 0x00000000, 0x00804811, 0x000 },
4011 { 0x00000000, 0xc0600000, 0x641 },
4012 { 0x00000000, 0xc0400400, 0x001 },
4013 { 0x0000a2a4, 0x00204411, 0x000 },
4014 { 0x00000022, 0x00204811, 0x000 },
4015 { 0x89000000, 0x00204411, 0x000 },
4016 { 0x00000001, 0x00404811, 0x62d },
4017 { 0x97000000, 0x00204411, 0x000 },
4018 { 0x00000000, 0x00204811, 0x000 },
4019 { 0x8a000000, 0x00204411, 0x000 },
4020 { 0x00000000, 0x00404811, 0x62d },
4021 { 0x00000000, 0x00600000, 0x65c },
4022 { 0x00002010, 0x00204411, 0x000 },
4023 { 0x00008000, 0x00204811, 0x000 },
4024 { 0x0001a2a4, 0xc0204411, 0x000 },
4025 { 0x00000016, 0x00604811, 0x36e },
4026 { 0x00002010, 0x00204411, 0x000 },
4027 { 0x00010000, 0x00204811, 0x000 },
4028 { 0x81000000, 0x00204411, 0x000 },
4029 { 0x00000001, 0x00204811, 0x000 },
4030 { 0x0000217c, 0x00204411, 0x000 },
4031 { 0x09800000, 0x00204811, 0x000 },
4032 { 0xffffffff, 0x00204811, 0x000 },
4033 { 0x00000000, 0x00204811, 0x000 },
4034 { 0x00000000, 0x17000000, 0x000 },
4035 { 0x0004217f, 0x00604411, 0x68d },
4036 { 0x0000001f, 0x00210230, 0x000 },
4037 { 0x00000000, 0x14c00000, 0x000 },
4038 { 0x00000004, 0x00404c11, 0x656 },
4039 { 0x00000000, 0x00400000, 0x000 },
4040 { 0x00000017, 0x00201e2d, 0x000 },
4041 { 0x00000004, 0x00291e27, 0x000 },
4042 { 0x00000017, 0x00803627, 0x000 },
4043 { 0x00000017, 0x00201e2d, 0x000 },
4044 { 0xfffffffb, 0x00281e27, 0x000 },
4045 { 0x00000017, 0x00803627, 0x000 },
4046 { 0x00000017, 0x00201e2d, 0x000 },
4047 { 0x00000008, 0x00291e27, 0x000 },
4048 { 0x00000017, 0x00803627, 0x000 },
4049 { 0x00000017, 0x00201e2d, 0x000 },
4050 { 0xfffffff7, 0x00281e27, 0x000 },
4051 { 0x00000017, 0x00803627, 0x000 },
4052 { 0x00002010, 0x00204411, 0x000 },
4053 { 0x00008000, 0x00204811, 0x000 },
4054 { 0x0001a2a4, 0x00204411, 0x000 },
4055 { 0x00000016, 0x00604811, 0x36e },
4056 { 0x00002010, 0x00204411, 0x000 },
4057 { 0x00010000, 0x00204811, 0x000 },
4058 { 0x0000217c, 0x00204411, 0x000 },
4059 { 0x01800000, 0x00204811, 0x000 },
4060 { 0xffffffff, 0x00204811, 0x000 },
4061 { 0x00000000, 0x00204811, 0x000 },
4062 { 0x00000000, 0x17000000, 0x000 },
4063 { 0x81000000, 0x00204411, 0x000 },
4064 { 0x00000001, 0x00204811, 0x000 },
4065 { 0x0004217f, 0x00604411, 0x68d },
4066 { 0x0000001f, 0x00210230, 0x000 },
4067 { 0x00000000, 0x14c00000, 0x68c },
4068 { 0x00000010, 0x00404c11, 0x672 },
4069 { 0x00000000, 0xc0200400, 0x000 },
4070 { 0x00000000, 0x38c00000, 0x000 },
4071 { 0x0000001d, 0x00200a2d, 0x000 },
4072 { 0x0000001e, 0x00200e2d, 0x000 },
4073 { 0x0000001f, 0x0020122d, 0x000 },
4074 { 0x00000020, 0x0020162d, 0x000 },
4075 { 0x00002169, 0x00204411, 0x000 },
4076 { 0x00000000, 0x00204804, 0x000 },
4077 { 0x00000000, 0x00204805, 0x000 },
4078 { 0x00000000, 0x00204801, 0x000 },
4079 { 0xcafebabe, 0x00204811, 0x000 },
4080 { 0x00000004, 0x00301224, 0x000 },
4081 { 0x00000000, 0x002f0064, 0x000 },
4082 { 0x00000000, 0x0cc00000, 0x68b },
4083 { 0x00000003, 0x00281a22, 0x000 },
4084 { 0x00000008, 0x00221222, 0x000 },
4085 { 0xfffff000, 0x00281224, 0x000 },
4086 { 0x00000000, 0x002910c4, 0x000 },
4087 { 0x0000001f, 0x00403624, 0x000 },
4088 { 0x00000000, 0x00800000, 0x000 },
4089 { 0x00000000, 0x1ac00000, 0x68d },
4090 { 0x9f000000, 0x00204411, 0x000 },
4091 { 0xcafebabe, 0x00204811, 0x000 },
4092 { 0x00000000, 0x1ae00000, 0x690 },
4093 { 0x00000000, 0x00800000, 0x000 },
4094 { 0x00000000, 0x1ac00000, 0x692 },
4095 { 0x9e000000, 0x00204411, 0x000 },
4096 { 0xcafebabe, 0x00204811, 0x000 },
4097 { 0x00000000, 0x1ae00000, 0x695 },
4098 { 0x00000000, 0x00800000, 0x000 },
4099 { 0x00000000, 0x00600000, 0x00b },
4100 { 0x00001000, 0x00600411, 0x315 },
4101 { 0x00000000, 0x00200411, 0x000 },
4102 { 0x00000000, 0x00600811, 0x1b2 },
4103 { 0x0000225c, 0x00204411, 0x000 },
4104 { 0x00000003, 0x00204811, 0x000 },
4105 { 0x00002256, 0x00204411, 0x000 },
4106 { 0x0000001b, 0x00204811, 0x000 },
4107 { 0x0000a1fc, 0x00204411, 0x000 },
4108 { 0x00000001, 0x00204811, 0x000 },
4109 { 0x0001a1fd, 0xc0204411, 0x000 },
4110 { 0x00000021, 0x00201e2d, 0x000 },
4111 { 0x00000010, 0x00221e27, 0x000 },
4112 { 0x00000024, 0x0020222d, 0x000 },
4113 { 0x0000ffff, 0x00282228, 0x000 },
4114 { 0x00000000, 0x00294907, 0x000 },
4115 { 0x00000000, 0x00204811, 0x000 },
4116 { 0x00000022, 0x0020222d, 0x000 },
4117 { 0x0000ffff, 0x00282228, 0x000 },
4118 { 0x00000000, 0x00294907, 0x000 },
4119 { 0x00000000, 0x00204811, 0x000 },
4120 { 0x00000023, 0x00201e2d, 0x000 },
4121 { 0x00000010, 0x00221e27, 0x000 },
4122 { 0x00000000, 0x00294907, 0x000 },
4123 { 0x00000000, 0x00404811, 0x000 },
4124 { 0x00000000, 0x00000000, 0x000 },
4125 { 0x00000000, 0x00000000, 0x000 },
4126 { 0x00000000, 0x00000000, 0x000 },
4127 { 0x00000000, 0x00000000, 0x000 },
4128 { 0x00000000, 0x00000000, 0x000 },
4129 { 0x00000000, 0x00000000, 0x000 },
4130 { 0x00000000, 0x00000000, 0x000 },
4131 { 0x00000000, 0x00000000, 0x000 },
4132 { 0x00000000, 0x00000000, 0x000 },
4133 { 0x00000000, 0x00000000, 0x000 },
4134 { 0x00000000, 0x00000000, 0x000 },
4135 { 0x00000000, 0x00000000, 0x000 },
4136 { 0x00000000, 0x00000000, 0x000 },
4137 { 0x00000000, 0x00000000, 0x000 },
4138 { 0x00000000, 0x00000000, 0x000 },
4139 { 0x00000000, 0x00000000, 0x000 },
4140 { 0x00000000, 0x00000000, 0x000 },
4141 { 0x00000000, 0x00000000, 0x000 },
4142 { 0x00000000, 0x00000000, 0x000 },
4143 { 0x00000000, 0x00000000, 0x000 },
4144 { 0x00000000, 0x00000000, 0x000 },
4145 { 0x00000000, 0x00000000, 0x000 },
4146 { 0x00000000, 0x00000000, 0x000 },
4147 { 0x00000000, 0x00000000, 0x000 },
4148 { 0x00000000, 0x00000000, 0x000 },
4149 { 0x00000000, 0x00000000, 0x000 },
4150 { 0x00000000, 0x00000000, 0x000 },
4151 { 0x00000000, 0x00000000, 0x000 },
4152 { 0x00000000, 0x00000000, 0x000 },
4153 { 0x00000000, 0x00000000, 0x000 },
4154 { 0x00000000, 0x00000000, 0x000 },
4155 { 0x00000000, 0x00000000, 0x000 },
4156 { 0x00000000, 0x00000000, 0x000 },
4157 { 0x00000000, 0x00000000, 0x000 },
4158 { 0x00000000, 0x00000000, 0x000 },
4159 { 0x00000000, 0x00000000, 0x000 },
4160 { 0x00000000, 0x00000000, 0x000 },
4161 { 0x00000000, 0x00000000, 0x000 },
4162 { 0x00000000, 0x00000000, 0x000 },
4163 { 0x00000000, 0x00000000, 0x000 },
4164 { 0x00000000, 0x00000000, 0x000 },
4165 { 0x00000000, 0x00000000, 0x000 },
4166 { 0x00000000, 0x00000000, 0x000 },
4167 { 0x00000000, 0x00000000, 0x000 },
4168 { 0x00000000, 0x00000000, 0x000 },
4169 { 0x00000000, 0x00000000, 0x000 },
4170 { 0x00000000, 0x00000000, 0x000 },
4171 { 0x00000000, 0x00000000, 0x000 },
4172 { 0x00000000, 0x00000000, 0x000 },
4173 { 0x00000000, 0x00000000, 0x000 },
4174 { 0x00000000, 0x00000000, 0x000 },
4175 { 0x00000000, 0x00000000, 0x000 },
4176 { 0x01420502, 0x05c00250, 0x000 },
4177 { 0x01c30168, 0x043f05c0, 0x000 },
4178 { 0x02250209, 0x02500151, 0x000 },
4179 { 0x02230245, 0x02a00241, 0x000 },
4180 { 0x03d705c0, 0x05c005c0, 0x000 },
4181 { 0x0649064a, 0x031f05c0, 0x000 },
4182 { 0x05c005c5, 0x03200340, 0x000 },
4183 { 0x032a0282, 0x03420334, 0x000 },
4184 { 0x05c005c0, 0x05c005c0, 0x000 },
4185 { 0x05c00551, 0x05c005c0, 0x000 },
4186 { 0x03ba05c0, 0x04bb0344, 0x000 },
4187 { 0x049a0450, 0x043d05c0, 0x000 },
4188 { 0x04d005c0, 0x044104dd, 0x000 },
4189 { 0x04500507, 0x03510375, 0x000 },
4190 { 0x05c005c0, 0x05c005c0, 0x000 },
4191 { 0x05c005c0, 0x05c005c0, 0x000 },
4192 { 0x05c005c0, 0x063f05c7, 0x000 },
4193 { 0x05c005c0, 0x000705c0, 0x000 },
4194 { 0x05c005c0, 0x05c005c0, 0x000 },
4195 { 0x05c005c0, 0x05c005c0, 0x000 },
4196 { 0x03f803ed, 0x04080406, 0x000 },
4197 { 0x040e040a, 0x040c0410, 0x000 },
4198 { 0x041c0418, 0x04240420, 0x000 },
4199 { 0x042c0428, 0x04340430, 0x000 },
4200 { 0x05c005c0, 0x043805c0, 0x000 },
4201 { 0x05c005c0, 0x05c005c0, 0x000 },
4202 { 0x05c005c0, 0x05c005c0, 0x000 },
4203 { 0x00020679, 0x06970006, 0x000 },
4204};
4205
4206static const u32 RV610_pfp_microcode[] = {
42070xca0400,
42080xa00000,
42090x7e828b,
42100x7c038b,
42110x8001b8,
42120x7c038b,
42130xd4401e,
42140xee001e,
42150xca0400,
42160xa00000,
42170x7e828b,
42180xc41838,
42190xca2400,
42200xca2800,
42210x9581a8,
42220xc41c3a,
42230xc3c000,
42240xca0800,
42250xca0c00,
42260x7c744b,
42270xc20005,
42280x99c000,
42290xc41c3a,
42300x7c744c,
42310xc0fff0,
42320x042c04,
42330x309002,
42340x7d2500,
42350x351402,
42360x7d350b,
42370x255403,
42380x7cd580,
42390x259c03,
42400x95c004,
42410xd5001b,
42420x7eddc1,
42430x7d9d80,
42440xd6801b,
42450xd5801b,
42460xd4401e,
42470xd5401e,
42480xd6401e,
42490xd6801e,
42500xd4801e,
42510xd4c01e,
42520x9783d3,
42530xd5c01e,
42540xca0800,
42550x80001a,
42560xca0c00,
42570xe4011e,
42580xd4001e,
42590x80000c,
42600xc41838,
42610xe4013e,
42620xd4001e,
42630x80000c,
42640xc41838,
42650xd4401e,
42660xee001e,
42670xca0400,
42680xa00000,
42690x7e828b,
42700xe4011e,
42710xd4001e,
42720xd4401e,
42730xee001e,
42740xca0400,
42750xa00000,
42760x7e828b,
42770xe4013e,
42780xd4001e,
42790xd4401e,
42800xee001e,
42810xca0400,
42820xa00000,
42830x7e828b,
42840xca1800,
42850xd4401e,
42860xd5801e,
42870x800053,
42880xd40075,
42890xd4401e,
42900xca0800,
42910xca0c00,
42920xca1000,
42930xd48019,
42940xd4c018,
42950xd50017,
42960xd4801e,
42970xd4c01e,
42980xd5001e,
42990xe2001e,
43000xca0400,
43010xa00000,
43020x7e828b,
43030xca0800,
43040xd48060,
43050xd4401e,
43060x800000,
43070xd4801e,
43080xca0800,
43090xd48061,
43100xd4401e,
43110x800000,
43120xd4801e,
43130xca0800,
43140xca0c00,
43150xd4401e,
43160xd48016,
43170xd4c016,
43180xd4801e,
43190x8001b8,
43200xd4c01e,
43210xc60843,
43220xca0c00,
43230xca1000,
43240x948004,
43250xca1400,
43260xe420f3,
43270xd42013,
43280xd56065,
43290xd4e01c,
43300xd5201c,
43310xd5601c,
43320x800000,
43330x062001,
43340xc60843,
43350xca0c00,
43360xca1000,
43370x9483f7,
43380xca1400,
43390xe420f3,
43400x800079,
43410xd42013,
43420xc60843,
43430xca0c00,
43440xca1000,
43450x9883ef,
43460xca1400,
43470xd40064,
43480x80008d,
43490x000000,
43500xc41432,
43510xc61843,
43520xc4082f,
43530x954005,
43540xc40c30,
43550xd4401e,
43560x800000,
43570xee001e,
43580x9583f5,
43590xc41031,
43600xd44033,
43610xd52065,
43620xd4a01c,
43630xd4e01c,
43640xd5201c,
43650xe4015e,
43660xd4001e,
43670x800000,
43680x062001,
43690xca1800,
43700x0a2001,
43710xd60076,
43720xc40836,
43730x988007,
43740xc61045,
43750x950110,
43760xd4001f,
43770xd46062,
43780x800000,
43790xd42062,
43800xcc3835,
43810xcc1433,
43820x8401bb,
43830xd40072,
43840xd5401e,
43850x800000,
43860xee001e,
43870xe2001a,
43880x8401bb,
43890xe2001a,
43900xcc104b,
43910xcc0447,
43920x2c9401,
43930x7d098b,
43940x984005,
43950x7d15cb,
43960xd4001a,
43970x8001b8,
43980xd4006d,
43990x344401,
44000xcc0c48,
44010x98403a,
44020xcc2c4a,
44030x958004,
44040xcc0449,
44050x8001b8,
44060xd4001a,
44070xd4c01a,
44080x282801,
44090x8400f0,
44100xcc1003,
44110x98801b,
44120x04380c,
44130x8400f0,
44140xcc1003,
44150x988017,
44160x043808,
44170x8400f0,
44180xcc1003,
44190x988013,
44200x043804,
44210x8400f0,
44220xcc1003,
44230x988014,
44240xcc104c,
44250x9a8009,
44260xcc144d,
44270x9840dc,
44280xd4006d,
44290xcc1848,
44300xd5001a,
44310xd5401a,
44320x8000c9,
44330xd5801a,
44340x96c0d5,
44350xd4006d,
44360x8001b8,
44370xd4006e,
44380x9ac003,
44390xd4006d,
44400xd4006e,
44410x800000,
44420xec007f,
44430x9ac0cc,
44440xd4006d,
44450x8001b8,
44460xd4006e,
44470xcc1403,
44480xcc1803,
44490xcc1c03,
44500x7d9103,
44510x7dd583,
44520x7d190c,
44530x35cc1f,
44540x35701f,
44550x7cf0cb,
44560x7cd08b,
44570x880000,
44580x7e8e8b,
44590x95c004,
44600xd4006e,
44610x8001b8,
44620xd4001a,
44630xd4c01a,
44640xcc0803,
44650xcc0c03,
44660xcc1003,
44670xcc1403,
44680xcc1803,
44690xcc1c03,
44700xcc2403,
44710xcc2803,
44720x35c41f,
44730x36b01f,
44740x7c704b,
44750x34f01f,
44760x7c704b,
44770x35701f,
44780x7c704b,
44790x7d8881,
44800x7dccc1,
44810x7e5101,
44820x7e9541,
44830x7c9082,
44840x7cd4c2,
44850x7c848b,
44860x9ac003,
44870x7c8c8b,
44880x2c8801,
44890x98809e,
44900xd4006d,
44910x98409c,
44920xd4006e,
44930xcc084c,
44940xcc0c4d,
44950xcc1048,
44960xd4801a,
44970xd4c01a,
44980x800101,
44990xd5001a,
45000xcc0832,
45010xd40032,
45020x9482d9,
45030xca0c00,
45040xd4401e,
45050x800000,
45060xd4001e,
45070xe4011e,
45080xd4001e,
45090xca0800,
45100xca0c00,
45110xca1000,
45120xd4401e,
45130xca1400,
45140xd4801e,
45150xd4c01e,
45160xd5001e,
45170xd5401e,
45180xd54034,
45190x800000,
45200xee001e,
45210x280404,
45220xe2001a,
45230xe2001a,
45240xd4401a,
45250xca3800,
45260xcc0803,
45270xcc0c03,
45280xcc0c03,
45290xcc0c03,
45300x9882bd,
45310x000000,
45320x8401bb,
45330xd7a06f,
45340x800000,
45350xee001f,
45360xca0400,
45370xc2ff00,
45380xcc0834,
45390xc13fff,
45400x7c74cb,
45410x7cc90b,
45420x7d010f,
45430x9902b0,
45440x7c738b,
45450x8401bb,
45460xd7a06f,
45470x800000,
45480xee001f,
45490xca0800,
45500x281900,
45510x7d898b,
45520x958014,
45530x281404,
45540xca0c00,
45550xca1000,
45560xca1c00,
45570xca2400,
45580xe2001f,
45590xd4c01a,
45600xd5001a,
45610xd5401a,
45620xcc1803,
45630xcc2c03,
45640xcc2c03,
45650xcc2c03,
45660x7da58b,
45670x7d9c47,
45680x984297,
45690x000000,
45700x800161,
45710xd4c01a,
45720xd4401e,
45730xd4801e,
45740x800000,
45750xee001e,
45760xe4011e,
45770xd4001e,
45780xd4401e,
45790xee001e,
45800xca0400,
45810xa00000,
45820x7e828b,
45830xe4013e,
45840xd4001e,
45850xd4401e,
45860xee001e,
45870xca0400,
45880xa00000,
45890x7e828b,
45900xca0800,
45910x248c06,
45920x0ccc06,
45930x98c006,
45940xcc104e,
45950x990004,
45960xd40073,
45970xe4011e,
45980xd4001e,
45990xd4401e,
46000xd4801e,
46010x800000,
46020xee001e,
46030xca0800,
46040xca0c00,
46050x34d018,
46060x251001,
46070x950021,
46080xc17fff,
46090xca1000,
46100xca1400,
46110xca1800,
46120xd4801d,
46130xd4c01d,
46140x7db18b,
46150xc14202,
46160xc2c001,
46170xd5801d,
46180x34dc0e,
46190x7d5d4c,
46200x7f734c,
46210xd7401e,
46220xd5001e,
46230xd5401e,
46240xc14200,
46250xc2c000,
46260x099c01,
46270x31dc10,
46280x7f5f4c,
46290x7f734c,
46300x042802,
46310x7d8380,
46320xd5a86f,
46330xd58066,
46340xd7401e,
46350xec005e,
46360xc82402,
46370xc82402,
46380x8001b8,
46390xd60076,
46400xd4401e,
46410xd4801e,
46420xd4c01e,
46430x800000,
46440xee001e,
46450x800000,
46460xee001f,
46470xd4001f,
46480x800000,
46490xd4001f,
46500xd4001f,
46510x880000,
46520xd4001f,
46530x000000,
46540x000000,
46550x000000,
46560x000000,
46570x000000,
46580x000000,
46590x000000,
46600x000000,
46610x000000,
46620x000000,
46630x000000,
46640x000000,
46650x000000,
46660x000000,
46670x000000,
46680x000000,
46690x000000,
46700x000000,
46710x000000,
46720x000000,
46730x000000,
46740x000000,
46750x000000,
46760x000000,
46770x000000,
46780x000000,
46790x000000,
46800x000000,
46810x000000,
46820x000000,
46830x000000,
46840x000000,
46850x000000,
46860x000000,
46870x000000,
46880x000000,
46890x000000,
46900x000000,
46910x000000,
46920x000000,
46930x000000,
46940x000000,
46950x000000,
46960x000000,
46970x000000,
46980x000000,
46990x000000,
47000x000000,
47010x000000,
47020x000000,
47030x000000,
47040x000000,
47050x000000,
47060x000000,
47070x000000,
47080x000000,
47090x000000,
47100x000000,
47110x000000,
47120x000000,
47130x000000,
47140x000000,
47150x000000,
47160x000000,
47170x000000,
47180x000000,
47190x010171,
47200x020178,
47210x03008f,
47220x04007f,
47230x050003,
47240x06003f,
47250x070032,
47260x08012c,
47270x090046,
47280x0a0036,
47290x1001b6,
47300x1700a2,
47310x22013a,
47320x230149,
47330x2000b4,
47340x240125,
47350x27004d,
47360x28006a,
47370x2a0060,
47380x2b0052,
47390x2f0065,
47400x320087,
47410x34017f,
47420x3c0156,
47430x3f0072,
47440x41018c,
47450x44012e,
47460x550173,
47470x56017a,
47480x60000b,
47490x610034,
47500x620038,
47510x630038,
47520x640038,
47530x650038,
47540x660038,
47550x670038,
47560x68003a,
47570x690041,
47580x6a0048,
47590x6b0048,
47600x6c0048,
47610x6d0048,
47620x6e0048,
47630x6f0048,
47640x000006,
47650x000006,
47660x000006,
47670x000006,
47680x000006,
47690x000006,
47700x000006,
47710x000006,
47720x000006,
47730x000006,
47740x000006,
47750x000006,
47760x000006,
47770x000006,
47780x000006,
47790x000006,
47800x000006,
47810x000006,
47820x000006,
4783};
4784
4785static const u32 RV620_cp_microcode[][3] = {
4786 { 0x00000000, 0xc0200400, 0x000 },
4787 { 0x00000000, 0x00a0000a, 0x000 },
4788 { 0x0000ffff, 0x00284621, 0x000 },
4789 { 0x00000000, 0xd9004800, 0x000 },
4790 { 0x00000000, 0xc0200400, 0x000 },
4791 { 0x00000000, 0x00a0000a, 0x000 },
4792 { 0x00000000, 0x00e00000, 0x000 },
4793 { 0x00010000, 0xc0294620, 0x000 },
4794 { 0x00000000, 0xd9004800, 0x000 },
4795 { 0x00000000, 0xc0200400, 0x000 },
4796 { 0x00000000, 0x00a0000a, 0x000 },
4797 { 0x81000000, 0x00204411, 0x000 },
4798 { 0x00000001, 0x00204811, 0x000 },
4799 { 0x00042004, 0x00604411, 0x68d },
4800 { 0x00000000, 0x00600000, 0x631 },
4801 { 0x00000000, 0x00600000, 0x645 },
4802 { 0x00000000, 0xc0200800, 0x000 },
4803 { 0x00000f00, 0x00281622, 0x000 },
4804 { 0x00000008, 0x00211625, 0x000 },
4805 { 0x00000018, 0x00203625, 0x000 },
4806 { 0x8d000000, 0x00204411, 0x000 },
4807 { 0x00000004, 0x002f0225, 0x000 },
4808 { 0x00000000, 0x0ce00000, 0x018 },
4809 { 0x00412000, 0x00404811, 0x019 },
4810 { 0x00422000, 0x00204811, 0x000 },
4811 { 0x8e000000, 0x00204411, 0x000 },
4812 { 0x00000028, 0x00204a2d, 0x000 },
4813 { 0x90000000, 0x00204411, 0x000 },
4814 { 0x00000000, 0x00204805, 0x000 },
4815 { 0x0000000c, 0x00211622, 0x000 },
4816 { 0x00000003, 0x00281625, 0x000 },
4817 { 0x00000019, 0x00211a22, 0x000 },
4818 { 0x00000004, 0x00281a26, 0x000 },
4819 { 0x00000000, 0x002914c5, 0x000 },
4820 { 0x00000019, 0x00203625, 0x000 },
4821 { 0x00000000, 0x003a1402, 0x000 },
4822 { 0x00000016, 0x00211625, 0x000 },
4823 { 0x00000003, 0x00281625, 0x000 },
4824 { 0x00000017, 0x00200e2d, 0x000 },
4825 { 0xfffffffc, 0x00280e23, 0x000 },
4826 { 0x00000000, 0x002914a3, 0x000 },
4827 { 0x00000017, 0x00203625, 0x000 },
4828 { 0x00008000, 0x00280e22, 0x000 },
4829 { 0x00000007, 0x00220e23, 0x000 },
4830 { 0x00000000, 0x0029386e, 0x000 },
4831 { 0x20000000, 0x00280e22, 0x000 },
4832 { 0x00000006, 0x00210e23, 0x000 },
4833 { 0x00000000, 0x0029386e, 0x000 },
4834 { 0x00000000, 0x00220222, 0x000 },
4835 { 0x00000000, 0x14e00000, 0x038 },
4836 { 0x00000000, 0x2ee00000, 0x035 },
4837 { 0x00000000, 0x2ce00000, 0x037 },
4838 { 0x00000000, 0x00400e2d, 0x039 },
4839 { 0x00000008, 0x00200e2d, 0x000 },
4840 { 0x00000009, 0x0040122d, 0x046 },
4841 { 0x00000001, 0x00400e2d, 0x039 },
4842 { 0x00000000, 0xc0200c00, 0x000 },
4843 { 0x003ffffc, 0x00281223, 0x000 },
4844 { 0x00000002, 0x00221224, 0x000 },
4845 { 0x0000001f, 0x00211e23, 0x000 },
4846 { 0x00000000, 0x14e00000, 0x03e },
4847 { 0x00000008, 0x00401c11, 0x041 },
4848 { 0x0000000d, 0x00201e2d, 0x000 },
4849 { 0x0000000f, 0x00281e27, 0x000 },
4850 { 0x00000003, 0x00221e27, 0x000 },
4851 { 0x7fc00000, 0x00281a23, 0x000 },
4852 { 0x00000014, 0x00211a26, 0x000 },
4853 { 0x00000001, 0x00331a26, 0x000 },
4854 { 0x00000008, 0x00221a26, 0x000 },
4855 { 0x00000000, 0x00290cc7, 0x000 },
4856 { 0x00000027, 0x00203624, 0x000 },
4857 { 0x00007f00, 0x00281221, 0x000 },
4858 { 0x00001400, 0x002f0224, 0x000 },
4859 { 0x00000000, 0x0ce00000, 0x04b },
4860 { 0x00000001, 0x00290e23, 0x000 },
4861 { 0x0000000e, 0x00203623, 0x000 },
4862 { 0x0000e000, 0x00204411, 0x000 },
4863 { 0xfff80000, 0x00294a23, 0x000 },
4864 { 0x00000000, 0x003a2c02, 0x000 },
4865 { 0x00000002, 0x00220e2b, 0x000 },
4866 { 0xfc000000, 0x00280e23, 0x000 },
4867 { 0x0000000f, 0x00203623, 0x000 },
4868 { 0x00001fff, 0x00294a23, 0x000 },
4869 { 0x00000027, 0x00204a2d, 0x000 },
4870 { 0x00000000, 0x00204811, 0x000 },
4871 { 0x00000029, 0x00200e2d, 0x000 },
4872 { 0x060a0200, 0x00294a23, 0x000 },
4873 { 0x00000000, 0x00204811, 0x000 },
4874 { 0x00000000, 0x00204811, 0x000 },
4875 { 0x00000001, 0x00210222, 0x000 },
4876 { 0x00000000, 0x14e00000, 0x061 },
4877 { 0x00000000, 0x2ee00000, 0x05f },
4878 { 0x00000000, 0x2ce00000, 0x05e },
4879 { 0x00000000, 0x00400e2d, 0x062 },
4880 { 0x00000001, 0x00400e2d, 0x062 },
4881 { 0x0000000a, 0x00200e2d, 0x000 },
4882 { 0x0000000b, 0x0040122d, 0x06a },
4883 { 0x00000000, 0xc0200c00, 0x000 },
4884 { 0x003ffffc, 0x00281223, 0x000 },
4885 { 0x00000002, 0x00221224, 0x000 },
4886 { 0x7fc00000, 0x00281623, 0x000 },
4887 { 0x00000014, 0x00211625, 0x000 },
4888 { 0x00000001, 0x00331625, 0x000 },
4889 { 0x80000000, 0x00280e23, 0x000 },
4890 { 0x00000000, 0x00290ca3, 0x000 },
4891 { 0x3ffffc00, 0x00290e23, 0x000 },
4892 { 0x0000001f, 0x00211e23, 0x000 },
4893 { 0x00000000, 0x14e00000, 0x06d },
4894 { 0x00000100, 0x00401c11, 0x070 },
4895 { 0x0000000d, 0x00201e2d, 0x000 },
4896 { 0x000000f0, 0x00281e27, 0x000 },
4897 { 0x00000004, 0x00221e27, 0x000 },
4898 { 0x81000000, 0x00204411, 0x000 },
4899 { 0x0000000d, 0x00204811, 0x000 },
4900 { 0xfffff0ff, 0x00281a30, 0x000 },
4901 { 0x0000a028, 0x00204411, 0x000 },
4902 { 0x00000000, 0x002948e6, 0x000 },
4903 { 0x0000a018, 0x00204411, 0x000 },
4904 { 0x3fffffff, 0x00284a23, 0x000 },
4905 { 0x0000a010, 0x00204411, 0x000 },
4906 { 0x00000000, 0x00204804, 0x000 },
4907 { 0x00000030, 0x0020162d, 0x000 },
4908 { 0x00000002, 0x00291625, 0x000 },
4909 { 0x00000030, 0x00203625, 0x000 },
4910 { 0x00000025, 0x0020162d, 0x000 },
4911 { 0x00000000, 0x002f00a3, 0x000 },
4912 { 0x00000000, 0x0cc00000, 0x083 },
4913 { 0x00000026, 0x0020162d, 0x000 },
4914 { 0x00000000, 0x002f00a4, 0x000 },
4915 { 0x00000000, 0x0cc00000, 0x084 },
4916 { 0x00000000, 0x00400000, 0x08a },
4917 { 0x00000025, 0x00203623, 0x000 },
4918 { 0x00000026, 0x00203624, 0x000 },
4919 { 0x00000017, 0x00201e2d, 0x000 },
4920 { 0x00000002, 0x00210227, 0x000 },
4921 { 0x00000000, 0x14e00000, 0x08a },
4922 { 0x00000000, 0x00600000, 0x668 },
4923 { 0x00000000, 0x00600000, 0x65c },
4924 { 0x00000002, 0x00210e22, 0x000 },
4925 { 0x00000000, 0x14c00000, 0x08d },
4926 { 0x00000012, 0xc0403620, 0x093 },
4927 { 0x00000000, 0x2ee00000, 0x091 },
4928 { 0x00000000, 0x2ce00000, 0x090 },
4929 { 0x00000002, 0x00400e2d, 0x092 },
4930 { 0x00000003, 0x00400e2d, 0x092 },
4931 { 0x0000000c, 0x00200e2d, 0x000 },
4932 { 0x00000012, 0x00203623, 0x000 },
4933 { 0x00000003, 0x00210e22, 0x000 },
4934 { 0x00000000, 0x14c00000, 0x098 },
4935 { 0x0000a00c, 0x00204411, 0x000 },
4936 { 0x00000000, 0xc0204800, 0x000 },
4937 { 0x00000000, 0xc0404800, 0x0a0 },
4938 { 0x0000a00c, 0x00204411, 0x000 },
4939 { 0x00000000, 0x00204811, 0x000 },
4940 { 0x00000000, 0x2ee00000, 0x09e },
4941 { 0x00000000, 0x2ce00000, 0x09d },
4942 { 0x00000002, 0x00400e2d, 0x09f },
4943 { 0x00000003, 0x00400e2d, 0x09f },
4944 { 0x0000000c, 0x00200e2d, 0x000 },
4945 { 0x00000000, 0x00204803, 0x000 },
4946 { 0x00000000, 0x003a0c02, 0x000 },
4947 { 0x003f0000, 0x00280e23, 0x000 },
4948 { 0x00000010, 0x00210e23, 0x000 },
4949 { 0x00000011, 0x00203623, 0x000 },
4950 { 0x0000001e, 0x0021022b, 0x000 },
4951 { 0x00000000, 0x14c00000, 0x0a7 },
4952 { 0x00000016, 0xc0203620, 0x000 },
4953 { 0x0000001f, 0x0021022b, 0x000 },
4954 { 0x00000000, 0x14c00000, 0x0aa },
4955 { 0x00000015, 0xc0203620, 0x000 },
4956 { 0x00000008, 0x00210e2b, 0x000 },
4957 { 0x0000007f, 0x00280e23, 0x000 },
4958 { 0x00000000, 0x002f0223, 0x000 },
4959 { 0x00000000, 0x0ce00000, 0x0e1 },
4960 { 0x00000000, 0x27000000, 0x000 },
4961 { 0x00000000, 0x00600000, 0x2a3 },
4962 { 0x00000001, 0x002f0223, 0x000 },
4963 { 0x00000000, 0x0ae00000, 0x0b3 },
4964 { 0x00000000, 0x00600000, 0x13a },
4965 { 0x81000000, 0x00204411, 0x000 },
4966 { 0x00000006, 0x00204811, 0x000 },
4967 { 0x0000000c, 0x00221e30, 0x000 },
4968 { 0x99800000, 0x00204411, 0x000 },
4969 { 0x00000004, 0x0020122d, 0x000 },
4970 { 0x00000008, 0x00221224, 0x000 },
4971 { 0x00000010, 0x00201811, 0x000 },
4972 { 0x00000000, 0x00291ce4, 0x000 },
4973 { 0x00000000, 0x00604807, 0x12f },
4974 { 0x9b000000, 0x00204411, 0x000 },
4975 { 0x00000000, 0x00204802, 0x000 },
4976 { 0x9c000000, 0x00204411, 0x000 },
4977 { 0x00000000, 0x0033146f, 0x000 },
4978 { 0x00000001, 0x00333e23, 0x000 },
4979 { 0x00000000, 0xd9004800, 0x000 },
4980 { 0x00000000, 0x00203c05, 0x000 },
4981 { 0x81000000, 0x00204411, 0x000 },
4982 { 0x0000000e, 0x00204811, 0x000 },
4983 { 0x00000000, 0x00201010, 0x000 },
4984 { 0x0000e007, 0x00204411, 0x000 },
4985 { 0x0000000f, 0x0021022b, 0x000 },
4986 { 0x00000000, 0x14c00000, 0x0cb },
4987 { 0x00f8ff08, 0x00204811, 0x000 },
4988 { 0x98000000, 0x00404811, 0x0dc },
4989 { 0x000000f0, 0x00280e22, 0x000 },
4990 { 0x000000a0, 0x002f0223, 0x000 },
4991 { 0x00000000, 0x0cc00000, 0x0da },
4992 { 0x00000011, 0x00200e2d, 0x000 },
4993 { 0x00000001, 0x002f0223, 0x000 },
4994 { 0x00000000, 0x0ce00000, 0x0d5 },
4995 { 0x00000002, 0x002f0223, 0x000 },
4996 { 0x00000000, 0x0ce00000, 0x0d4 },
4997 { 0x00003f00, 0x00400c11, 0x0d6 },
4998 { 0x00001f00, 0x00400c11, 0x0d6 },
4999 { 0x00000f00, 0x00200c11, 0x000 },
5000 { 0x00380009, 0x00294a23, 0x000 },
5001 { 0x3f000000, 0x00280e2b, 0x000 },
5002 { 0x00000002, 0x00220e23, 0x000 },
5003 { 0x00000007, 0x00494a23, 0x0dc },
5004 { 0x00380f09, 0x00204811, 0x000 },
5005 { 0x68000007, 0x00204811, 0x000 },
5006 { 0x00000008, 0x00214a27, 0x000 },
5007 { 0x00000000, 0x00204811, 0x000 },
5008 { 0x060a0200, 0x00294a24, 0x000 },
5009 { 0x00000000, 0x00204811, 0x000 },
5010 { 0x00000000, 0x00204811, 0x000 },
5011 { 0x0000a202, 0x00204411, 0x000 },
5012 { 0x00ff0000, 0x00280e22, 0x000 },
5013 { 0x00000080, 0x00294a23, 0x000 },
5014 { 0x00000027, 0x00200e2d, 0x000 },
5015 { 0x00000026, 0x0020122d, 0x000 },
5016 { 0x00000000, 0x002f0083, 0x000 },
5017 { 0x00000000, 0x0ce00000, 0x0ea },
5018 { 0x00000000, 0x00600000, 0x662 },
5019 { 0x00000000, 0x00400000, 0x0eb },
5020 { 0x00000000, 0x00600000, 0x665 },
5021 { 0x00000007, 0x0020222d, 0x000 },
5022 { 0x00000005, 0x00220e22, 0x000 },
5023 { 0x00100000, 0x00280e23, 0x000 },
5024 { 0x00000000, 0x00292068, 0x000 },
5025 { 0x00000000, 0x003a0c02, 0x000 },
5026 { 0x000000ef, 0x00280e23, 0x000 },
5027 { 0x00000000, 0x00292068, 0x000 },
5028 { 0x00000017, 0x00200e2d, 0x000 },
5029 { 0x00000003, 0x00210223, 0x000 },
5030 { 0x00000000, 0x14e00000, 0x0f8 },
5031 { 0x0000000b, 0x00210228, 0x000 },
5032 { 0x00000000, 0x14c00000, 0x0f8 },
5033 { 0x00000400, 0x00292228, 0x000 },
5034 { 0x00000014, 0x00203628, 0x000 },
5035 { 0x0000001c, 0x00210e22, 0x000 },
5036 { 0x00000000, 0x14c00000, 0x0fd },
5037 { 0x0000a30c, 0x00204411, 0x000 },
5038 { 0x00000000, 0x00204811, 0x000 },
5039 { 0x0000001e, 0x00210e22, 0x000 },
5040 { 0x00000000, 0x14c00000, 0x10b },
5041 { 0x0000a30f, 0x00204411, 0x000 },
5042 { 0x00000011, 0x00200e2d, 0x000 },
5043 { 0x00000001, 0x002f0223, 0x000 },
5044 { 0x00000000, 0x0cc00000, 0x104 },
5045 { 0xffffffff, 0x00404811, 0x10b },
5046 { 0x00000002, 0x002f0223, 0x000 },
5047 { 0x00000000, 0x0cc00000, 0x107 },
5048 { 0x0000ffff, 0x00404811, 0x10b },
5049 { 0x00000004, 0x002f0223, 0x000 },
5050 { 0x00000000, 0x0cc00000, 0x10a },
5051 { 0x000000ff, 0x00404811, 0x10b },
5052 { 0x00000001, 0x00204811, 0x000 },
5053 { 0x0002c400, 0x00204411, 0x000 },
5054 { 0x0000001f, 0x00210e22, 0x000 },
5055 { 0x00000000, 0x14c00000, 0x112 },
5056 { 0x00000010, 0x40210e20, 0x000 },
5057 { 0x00000013, 0x00203623, 0x000 },
5058 { 0x00000018, 0x40224a20, 0x000 },
5059 { 0x00000010, 0xc0424a20, 0x114 },
5060 { 0x00000000, 0x00200c11, 0x000 },
5061 { 0x00000013, 0x00203623, 0x000 },
5062 { 0x00000000, 0x00204811, 0x000 },
5063 { 0x00000000, 0x00204811, 0x000 },
5064 { 0x0000000a, 0x00201011, 0x000 },
5065 { 0x00000000, 0x002f0224, 0x000 },
5066 { 0x00000000, 0x0ce00000, 0x11b },
5067 { 0x00000000, 0x00204811, 0x000 },
5068 { 0x00000001, 0x00531224, 0x117 },
5069 { 0xffbfffff, 0x00283a2e, 0x000 },
5070 { 0x0000001b, 0x00210222, 0x000 },
5071 { 0x00000000, 0x14c00000, 0x12e },
5072 { 0x81000000, 0x00204411, 0x000 },
5073 { 0x0000000d, 0x00204811, 0x000 },
5074 { 0x00000018, 0x00220e30, 0x000 },
5075 { 0xfc000000, 0x00280e23, 0x000 },
5076 { 0x81000000, 0x00204411, 0x000 },
5077 { 0x0000000e, 0x00204811, 0x000 },
5078 { 0x00000000, 0x00201010, 0x000 },
5079 { 0x0000e00e, 0x00204411, 0x000 },
5080 { 0x07f8ff08, 0x00204811, 0x000 },
5081 { 0x00000000, 0x00294a23, 0x000 },
5082 { 0x0000001c, 0x00201e2d, 0x000 },
5083 { 0x00000008, 0x00214a27, 0x000 },
5084 { 0x00000000, 0x00204811, 0x000 },
5085 { 0x060a0200, 0x00294a24, 0x000 },
5086 { 0x00000000, 0x00204811, 0x000 },
5087 { 0x00000000, 0x00204811, 0x000 },
5088 { 0x00000000, 0x00800000, 0x000 },
5089 { 0x81000000, 0x00204411, 0x000 },
5090 { 0x00000001, 0x00204811, 0x000 },
5091 { 0x0000217c, 0x00204411, 0x000 },
5092 { 0x00800000, 0x00204811, 0x000 },
5093 { 0x00000000, 0x00204806, 0x000 },
5094 { 0x00000008, 0x00214a27, 0x000 },
5095 { 0x00000000, 0x17000000, 0x000 },
5096 { 0x0004217f, 0x00604411, 0x68d },
5097 { 0x0000001f, 0x00210230, 0x000 },
5098 { 0x00000000, 0x14c00000, 0x68c },
5099 { 0x00000004, 0x00404c11, 0x135 },
5100 { 0x81000000, 0x00204411, 0x000 },
5101 { 0x00000001, 0x00204811, 0x000 },
5102 { 0x000021f8, 0x00204411, 0x000 },
5103 { 0x0000001c, 0x00204811, 0x000 },
5104 { 0x000421f9, 0x00604411, 0x68d },
5105 { 0x00000011, 0x00210230, 0x000 },
5106 { 0x00000000, 0x14e00000, 0x13c },
5107 { 0x00000000, 0x00800000, 0x000 },
5108 { 0x00000000, 0x00600000, 0x00b },
5109 { 0x00000000, 0x00600411, 0x315 },
5110 { 0x00000000, 0x00200411, 0x000 },
5111 { 0x00000000, 0x00600811, 0x1b2 },
5112 { 0x00000000, 0x00600000, 0x160 },
5113 { 0x0000ffff, 0x40280e20, 0x000 },
5114 { 0x00000010, 0xc0211220, 0x000 },
5115 { 0x0000ffff, 0x40280620, 0x000 },
5116 { 0x00000010, 0xc0210a20, 0x000 },
5117 { 0x00000000, 0x00341461, 0x000 },
5118 { 0x00000000, 0x00741882, 0x2bb },
5119 { 0x0001a1fd, 0x00604411, 0x2e0 },
5120 { 0x00003fff, 0x002f022f, 0x000 },
5121 { 0x00000000, 0x0cc00000, 0x147 },
5122 { 0x00000000, 0xc0400400, 0x001 },
5123 { 0x00000000, 0x00600000, 0x00b },
5124 { 0x00000000, 0x00600411, 0x315 },
5125 { 0x00000000, 0x00200411, 0x000 },
5126 { 0x00000000, 0x00600811, 0x1b2 },
5127 { 0x00003fff, 0x002f022f, 0x000 },
5128 { 0x00000000, 0x0ce00000, 0x000 },
5129 { 0x00000000, 0x00600000, 0x160 },
5130 { 0x00000010, 0x40210e20, 0x000 },
5131 { 0x0000ffff, 0xc0281220, 0x000 },
5132 { 0x00000010, 0x40211620, 0x000 },
5133 { 0x0000ffff, 0xc0681a20, 0x2bb },
5134 { 0x0001a1fd, 0x00604411, 0x2e0 },
5135 { 0x00003fff, 0x002f022f, 0x000 },
5136 { 0x00000000, 0x0cc00000, 0x158 },
5137 { 0x00000000, 0xc0400400, 0x001 },
5138 { 0x0000225c, 0x00204411, 0x000 },
5139 { 0x00000001, 0x00300a2f, 0x000 },
5140 { 0x00000001, 0x00210a22, 0x000 },
5141 { 0x00000003, 0x00384a22, 0x000 },
5142 { 0x00002256, 0x00204411, 0x000 },
5143 { 0x0000001a, 0x00204811, 0x000 },
5144 { 0x0000a1fc, 0x00204411, 0x000 },
5145 { 0x00000001, 0x00804811, 0x000 },
5146 { 0x00000000, 0x00600000, 0x00b },
5147 { 0x00000000, 0x00600000, 0x18f },
5148 { 0x00000000, 0x00600000, 0x1a0 },
5149 { 0x00003fff, 0x002f022f, 0x000 },
5150 { 0x00000000, 0x0ce00000, 0x000 },
5151 { 0x00000000, 0x00202c08, 0x000 },
5152 { 0x00000000, 0x00202411, 0x000 },
5153 { 0x00000000, 0x00202811, 0x000 },
5154 { 0x00002256, 0x00204411, 0x000 },
5155 { 0x00000016, 0x00204811, 0x000 },
5156 { 0x0000225c, 0x00204411, 0x000 },
5157 { 0x00000003, 0x00204811, 0x000 },
5158 { 0x93800000, 0x00204411, 0x000 },
5159 { 0x00000002, 0x00221e29, 0x000 },
5160 { 0x00000000, 0x007048eb, 0x19c },
5161 { 0x00000000, 0x00600000, 0x2bb },
5162 { 0x00000001, 0x40330620, 0x000 },
5163 { 0x00000000, 0xc0302409, 0x000 },
5164 { 0x00003fff, 0x002f022f, 0x000 },
5165 { 0x00000000, 0x0ce00000, 0x000 },
5166 { 0x00000000, 0x00600000, 0x2a3 },
5167 { 0x00000000, 0x002f0221, 0x000 },
5168 { 0x00000000, 0x0ae00000, 0x181 },
5169 { 0x00000000, 0x00600000, 0x13a },
5170 { 0x00000000, 0x00400000, 0x186 },
5171 { 0x95000000, 0x00204411, 0x000 },
5172 { 0x00000000, 0x002f0221, 0x000 },
5173 { 0x00000000, 0x0ce00000, 0x186 },
5174 { 0x00000000, 0xc0204800, 0x000 },
5175 { 0x00000001, 0x00530621, 0x182 },
5176 { 0x92000000, 0x00204411, 0x000 },
5177 { 0x00000000, 0xc0604800, 0x197 },
5178 { 0x0001a1fd, 0x00204411, 0x000 },
5179 { 0x00000011, 0x0020062d, 0x000 },
5180 { 0x00000000, 0x0078042a, 0x2fb },
5181 { 0x00000000, 0x00202809, 0x000 },
5182 { 0x00003fff, 0x002f022f, 0x000 },
5183 { 0x00000000, 0x0cc00000, 0x174 },
5184 { 0x00000000, 0xc0400400, 0x001 },
5185 { 0x00000210, 0x00600411, 0x315 },
5186 { 0x00003fff, 0x002f022f, 0x000 },
5187 { 0x00000000, 0x0ce00000, 0x194 },
5188 { 0x00000015, 0xc0203620, 0x000 },
5189 { 0x00000016, 0xc0203620, 0x000 },
5190 { 0x3f800000, 0x00200411, 0x000 },
5191 { 0x46000000, 0x00600811, 0x1b2 },
5192 { 0x00000000, 0x00800000, 0x000 },
5193 { 0x0000a1fc, 0x00204411, 0x000 },
5194 { 0x00003fff, 0x002f022f, 0x000 },
5195 { 0x00000000, 0x0cc00000, 0x19b },
5196 { 0x00000001, 0x00804811, 0x000 },
5197 { 0x00000021, 0x00804811, 0x000 },
5198 { 0x0000ffff, 0x40280e20, 0x000 },
5199 { 0x00000010, 0xc0211220, 0x000 },
5200 { 0x0000ffff, 0x40281620, 0x000 },
5201 { 0x00000010, 0xc0811a20, 0x000 },
5202 { 0x81000000, 0x00204411, 0x000 },
5203 { 0x00000006, 0x00204811, 0x000 },
5204 { 0x00000008, 0x00221e30, 0x000 },
5205 { 0x00000029, 0x00201a2d, 0x000 },
5206 { 0x0000e000, 0x00204411, 0x000 },
5207 { 0xfffbff09, 0x00204811, 0x000 },
5208 { 0x0000000f, 0x0020222d, 0x000 },
5209 { 0x00001fff, 0x00294a28, 0x000 },
5210 { 0x00000006, 0x0020222d, 0x000 },
5211 { 0x00000000, 0x002920e8, 0x000 },
5212 { 0x00000000, 0x00204808, 0x000 },
5213 { 0x00000000, 0x00204811, 0x000 },
5214 { 0x060a0200, 0x00294a26, 0x000 },
5215 { 0x00000000, 0x00204811, 0x000 },
5216 { 0x00000000, 0x00204811, 0x000 },
5217 { 0x00000100, 0x00201811, 0x000 },
5218 { 0x00000008, 0x00621e28, 0x12f },
5219 { 0x00000008, 0x00822228, 0x000 },
5220 { 0x0002c000, 0x00204411, 0x000 },
5221 { 0x00000015, 0x00600e2d, 0x1bd },
5222 { 0x00000016, 0x00600e2d, 0x1bd },
5223 { 0x0000c008, 0x00204411, 0x000 },
5224 { 0x00000017, 0x00200e2d, 0x000 },
5225 { 0x00000000, 0x14c00000, 0x1b9 },
5226 { 0x00000000, 0x00200411, 0x000 },
5227 { 0x00000000, 0x00204801, 0x000 },
5228 { 0x39000000, 0x00204811, 0x000 },
5229 { 0x00000000, 0x00204811, 0x000 },
5230 { 0x00000000, 0x00804802, 0x000 },
5231 { 0x00000018, 0x00202e2d, 0x000 },
5232 { 0x00000000, 0x003b0d63, 0x000 },
5233 { 0x00000008, 0x00224a23, 0x000 },
5234 { 0x00000010, 0x00224a23, 0x000 },
5235 { 0x00000018, 0x00224a23, 0x000 },
5236 { 0x00000000, 0x00804803, 0x000 },
5237 { 0x00000000, 0x00600000, 0x00b },
5238 { 0x00001000, 0x00600411, 0x315 },
5239 { 0x00000000, 0x00200411, 0x000 },
5240 { 0x00000000, 0x00600811, 0x1b2 },
5241 { 0x00000007, 0x0021062f, 0x000 },
5242 { 0x00000013, 0x00200a2d, 0x000 },
5243 { 0x00000001, 0x00202c11, 0x000 },
5244 { 0x0000ffff, 0x40282220, 0x000 },
5245 { 0x0000000f, 0x00262228, 0x000 },
5246 { 0x00000010, 0x40212620, 0x000 },
5247 { 0x0000000f, 0x00262629, 0x000 },
5248 { 0x00000000, 0x00202802, 0x000 },
5249 { 0x00002256, 0x00204411, 0x000 },
5250 { 0x0000001b, 0x00204811, 0x000 },
5251 { 0x00000000, 0x002f0221, 0x000 },
5252 { 0x00000000, 0x0ce00000, 0x1e0 },
5253 { 0x0000225c, 0x00204411, 0x000 },
5254 { 0x00000081, 0x00204811, 0x000 },
5255 { 0x0000a1fc, 0x00204411, 0x000 },
5256 { 0x00000001, 0x00204811, 0x000 },
5257 { 0x00000080, 0x00201c11, 0x000 },
5258 { 0x00000000, 0x002f0227, 0x000 },
5259 { 0x00000000, 0x0ce00000, 0x1dc },
5260 { 0x00000000, 0x00600000, 0x1e9 },
5261 { 0x00000001, 0x00531e27, 0x1d8 },
5262 { 0x00000001, 0x00202c11, 0x000 },
5263 { 0x0000001f, 0x00280a22, 0x000 },
5264 { 0x0000001f, 0x00282a2a, 0x000 },
5265 { 0x00000001, 0x00530621, 0x1d1 },
5266 { 0x0000225c, 0x00204411, 0x000 },
5267 { 0x00000002, 0x00304a2f, 0x000 },
5268 { 0x0000a1fc, 0x00204411, 0x000 },
5269 { 0x00000001, 0x00204811, 0x000 },
5270 { 0x00000001, 0x00301e2f, 0x000 },
5271 { 0x00000000, 0x002f0227, 0x000 },
5272 { 0x00000000, 0x0ce00000, 0x000 },
5273 { 0x00000000, 0x00600000, 0x1e9 },
5274 { 0x00000001, 0x00531e27, 0x1e5 },
5275 { 0x0000ffff, 0x40280e20, 0x000 },
5276 { 0x0000000f, 0x00260e23, 0x000 },
5277 { 0x00000010, 0xc0211220, 0x000 },
5278 { 0x0000000f, 0x00261224, 0x000 },
5279 { 0x00000000, 0x00201411, 0x000 },
5280 { 0x00000000, 0x00601811, 0x2bb },
5281 { 0x0001a1fd, 0x00204411, 0x000 },
5282 { 0x00000000, 0x002f022b, 0x000 },
5283 { 0x00000000, 0x0ce00000, 0x1f8 },
5284 { 0x00000010, 0x00221628, 0x000 },
5285 { 0xffff0000, 0x00281625, 0x000 },
5286 { 0x0000ffff, 0x00281a29, 0x000 },
5287 { 0x00000000, 0x002948c5, 0x000 },
5288 { 0x00000000, 0x0020480a, 0x000 },
5289 { 0x00000000, 0x00202c11, 0x000 },
5290 { 0x00000010, 0x00221623, 0x000 },
5291 { 0xffff0000, 0x00281625, 0x000 },
5292 { 0x0000ffff, 0x00281a24, 0x000 },
5293 { 0x00000000, 0x002948c5, 0x000 },
5294 { 0x00000000, 0x00731503, 0x205 },
5295 { 0x00000000, 0x00201805, 0x000 },
5296 { 0x00000000, 0x00731524, 0x205 },
5297 { 0x00000000, 0x002d14c5, 0x000 },
5298 { 0x00000000, 0x003008a2, 0x000 },
5299 { 0x00000000, 0x00204802, 0x000 },
5300 { 0x00000000, 0x00202802, 0x000 },
5301 { 0x00000000, 0x00202003, 0x000 },
5302 { 0x00000000, 0x00802404, 0x000 },
5303 { 0x0000000f, 0x00210225, 0x000 },
5304 { 0x00000000, 0x14c00000, 0x68c },
5305 { 0x00000000, 0x002b1405, 0x000 },
5306 { 0x00000001, 0x00901625, 0x000 },
5307 { 0x00000000, 0x00600000, 0x00b },
5308 { 0x00000000, 0x00600411, 0x315 },
5309 { 0x00000000, 0x00200411, 0x000 },
5310 { 0x00000000, 0x00600811, 0x1b2 },
5311 { 0x00002256, 0x00204411, 0x000 },
5312 { 0x0000001a, 0x00294a22, 0x000 },
5313 { 0x00000000, 0xc0200000, 0x000 },
5314 { 0x00003fff, 0x002f022f, 0x000 },
5315 { 0x00000000, 0x0ce00000, 0x000 },
5316 { 0x00000000, 0xc0200400, 0x000 },
5317 { 0x0000225c, 0x00204411, 0x000 },
5318 { 0x00000003, 0x00384a21, 0x000 },
5319 { 0x0000a1fc, 0x00204411, 0x000 },
5320 { 0x00000001, 0x00204811, 0x000 },
5321 { 0x0000ffff, 0x40281220, 0x000 },
5322 { 0x00000010, 0xc0211a20, 0x000 },
5323 { 0x0000ffff, 0x40280e20, 0x000 },
5324 { 0x00000010, 0xc0211620, 0x000 },
5325 { 0x00000000, 0x00741465, 0x2bb },
5326 { 0x0001a1fd, 0x00604411, 0x2e0 },
5327 { 0x00000001, 0x00330621, 0x000 },
5328 { 0x00000000, 0x002f0221, 0x000 },
5329 { 0x00000000, 0x0cc00000, 0x219 },
5330 { 0x00003fff, 0x002f022f, 0x000 },
5331 { 0x00000000, 0x0cc00000, 0x212 },
5332 { 0x00000000, 0xc0400400, 0x001 },
5333 { 0x00000000, 0x00600000, 0x645 },
5334 { 0x00000000, 0x0040040f, 0x213 },
5335 { 0x00000000, 0x00600000, 0x631 },
5336 { 0x00000000, 0x00600000, 0x645 },
5337 { 0x00000210, 0x00600411, 0x315 },
5338 { 0x00000000, 0x00600000, 0x1a0 },
5339 { 0x00000000, 0x00600000, 0x19c },
5340 { 0x00000000, 0x00600000, 0x2bb },
5341 { 0x00000000, 0x00600000, 0x2a3 },
5342 { 0x93800000, 0x00204411, 0x000 },
5343 { 0x00000000, 0x00204808, 0x000 },
5344 { 0x00000000, 0x002f022f, 0x000 },
5345 { 0x00000000, 0x0ae00000, 0x232 },
5346 { 0x00000000, 0x00600000, 0x13a },
5347 { 0x00000000, 0x00400000, 0x236 },
5348 { 0x95000000, 0x00204411, 0x000 },
5349 { 0x00000000, 0x002f022f, 0x000 },
5350 { 0x00000000, 0x0ce00000, 0x236 },
5351 { 0x00000000, 0xc0404800, 0x233 },
5352 { 0x92000000, 0x00204411, 0x000 },
5353 { 0x00000000, 0xc0204800, 0x000 },
5354 { 0x00002256, 0x00204411, 0x000 },
5355 { 0x00000016, 0x00204811, 0x000 },
5356 { 0x0000225c, 0x00204411, 0x000 },
5357 { 0x00000003, 0x00204811, 0x000 },
5358 { 0x0000a1fc, 0x00204411, 0x000 },
5359 { 0x00000001, 0x00204811, 0x000 },
5360 { 0x0001a1fd, 0x00204411, 0x000 },
5361 { 0x00000000, 0x00600411, 0x2fb },
5362 { 0x00000000, 0xc0400400, 0x001 },
5363 { 0x00000000, 0x00600000, 0x631 },
5364 { 0x0000a00c, 0x00204411, 0x000 },
5365 { 0x00000000, 0xc0204800, 0x000 },
5366 { 0x00000000, 0xc0404800, 0x000 },
5367 { 0x00000000, 0x00600000, 0x00b },
5368 { 0x00000018, 0x40210a20, 0x000 },
5369 { 0x00000003, 0x002f0222, 0x000 },
5370 { 0x00000000, 0x0ae00000, 0x24c },
5371 { 0x00000014, 0x0020222d, 0x000 },
5372 { 0x00080101, 0x00292228, 0x000 },
5373 { 0x00000014, 0x00203628, 0x000 },
5374 { 0x0000a30c, 0x00204411, 0x000 },
5375 { 0x00000000, 0xc0204800, 0x000 },
5376 { 0x00000000, 0xc0204800, 0x000 },
5377 { 0x00000000, 0xc0404800, 0x251 },
5378 { 0x00000000, 0x00600000, 0x00b },
5379 { 0x00000010, 0x00600411, 0x315 },
5380 { 0x3f800000, 0x00200411, 0x000 },
5381 { 0x00000000, 0x00600811, 0x1b2 },
5382 { 0x0000225c, 0x00204411, 0x000 },
5383 { 0x00000003, 0x00204811, 0x000 },
5384 { 0x00000000, 0x00600000, 0x27c },
5385 { 0x00000017, 0x00201e2d, 0x000 },
5386 { 0x00000001, 0x00211e27, 0x000 },
5387 { 0x00000000, 0x14e00000, 0x26a },
5388 { 0x00000012, 0x00201e2d, 0x000 },
5389 { 0x0000ffff, 0x00281e27, 0x000 },
5390 { 0x00000000, 0x00341c27, 0x000 },
5391 { 0x00000000, 0x12c00000, 0x25f },
5392 { 0x00000000, 0x00201c11, 0x000 },
5393 { 0x00000000, 0x002f00e5, 0x000 },
5394 { 0x00000000, 0x08c00000, 0x262 },
5395 { 0x00000000, 0x00201407, 0x000 },
5396 { 0x00000012, 0x00201e2d, 0x000 },
5397 { 0x00000010, 0x00211e27, 0x000 },
5398 { 0x00000000, 0x00341c47, 0x000 },
5399 { 0x00000000, 0x12c00000, 0x267 },
5400 { 0x00000000, 0x00201c11, 0x000 },
5401 { 0x00000000, 0x002f00e6, 0x000 },
5402 { 0x00000000, 0x08c00000, 0x26a },
5403 { 0x00000000, 0x00201807, 0x000 },
5404 { 0x00000000, 0x00600000, 0x2c1 },
5405 { 0x00002256, 0x00204411, 0x000 },
5406 { 0x00000000, 0x00342023, 0x000 },
5407 { 0x00000000, 0x12c00000, 0x272 },
5408 { 0x00000000, 0x00342044, 0x000 },
5409 { 0x00000000, 0x12c00000, 0x271 },
5410 { 0x00000016, 0x00404811, 0x276 },
5411 { 0x00000018, 0x00404811, 0x276 },
5412 { 0x00000000, 0x00342044, 0x000 },
5413 { 0x00000000, 0x12c00000, 0x275 },
5414 { 0x00000017, 0x00404811, 0x276 },
5415 { 0x00000019, 0x00204811, 0x000 },
5416 { 0x0000a1fc, 0x00204411, 0x000 },
5417 { 0x00000001, 0x00204811, 0x000 },
5418 { 0x0001a1fd, 0x00604411, 0x2e9 },
5419 { 0x00003fff, 0x002f022f, 0x000 },
5420 { 0x00000000, 0x0cc00000, 0x256 },
5421 { 0x00000000, 0xc0400400, 0x001 },
5422 { 0x00000010, 0x40210620, 0x000 },
5423 { 0x0000ffff, 0xc0280a20, 0x000 },
5424 { 0x00000010, 0x40210e20, 0x000 },
5425 { 0x0000ffff, 0xc0281220, 0x000 },
5426 { 0x00000010, 0x40211620, 0x000 },
5427 { 0x0000ffff, 0xc0881a20, 0x000 },
5428 { 0x81000000, 0x00204411, 0x000 },
5429 { 0x00000001, 0x00204811, 0x000 },
5430 { 0x00042004, 0x00604411, 0x68d },
5431 { 0x00000000, 0x00600000, 0x631 },
5432 { 0x00000000, 0xc0600000, 0x2a3 },
5433 { 0x00000005, 0x00200a2d, 0x000 },
5434 { 0x00000008, 0x00220a22, 0x000 },
5435 { 0x0000002b, 0x00201a2d, 0x000 },
5436 { 0x0000001c, 0x00201e2d, 0x000 },
5437 { 0x00007000, 0x00281e27, 0x000 },
5438 { 0x00000000, 0x00311ce6, 0x000 },
5439 { 0x0000002a, 0x00201a2d, 0x000 },
5440 { 0x0000000c, 0x00221a26, 0x000 },
5441 { 0x00000000, 0x002f00e6, 0x000 },
5442 { 0x00000000, 0x06e00000, 0x292 },
5443 { 0x00000000, 0x00201c11, 0x000 },
5444 { 0x00000000, 0x00200c11, 0x000 },
5445 { 0x0000002b, 0x00203623, 0x000 },
5446 { 0x00000010, 0x00201811, 0x000 },
5447 { 0x00000000, 0x00691ce2, 0x12f },
5448 { 0x93800000, 0x00204411, 0x000 },
5449 { 0x00000000, 0x00204807, 0x000 },
5450 { 0x95000000, 0x00204411, 0x000 },
5451 { 0x00000000, 0x002f022f, 0x000 },
5452 { 0x00000000, 0x0ce00000, 0x29d },
5453 { 0x00000001, 0x00333e2f, 0x000 },
5454 { 0x00000000, 0xd9004800, 0x000 },
5455 { 0x92000000, 0x00204411, 0x000 },
5456 { 0x00000000, 0xc0204800, 0x000 },
5457 { 0x0000001c, 0x00403627, 0x000 },
5458 { 0x0000000c, 0xc0220a20, 0x000 },
5459 { 0x00000029, 0x00203622, 0x000 },
5460 { 0x00000028, 0xc0403620, 0x000 },
5461 { 0x0000a2a4, 0x00204411, 0x000 },
5462 { 0x00000009, 0x00204811, 0x000 },
5463 { 0xa1000000, 0x00204411, 0x000 },
5464 { 0x00000001, 0x00804811, 0x000 },
5465 { 0x00000021, 0x00201e2d, 0x000 },
5466 { 0x00000000, 0x002c1ce3, 0x000 },
5467 { 0x00000021, 0x00203627, 0x000 },
5468 { 0x00000022, 0x00201e2d, 0x000 },
5469 { 0x00000000, 0x002c1ce4, 0x000 },
5470 { 0x00000022, 0x00203627, 0x000 },
5471 { 0x00000023, 0x00201e2d, 0x000 },
5472 { 0x00000000, 0x003120a3, 0x000 },
5473 { 0x00000000, 0x002d1d07, 0x000 },
5474 { 0x00000023, 0x00203627, 0x000 },
5475 { 0x00000024, 0x00201e2d, 0x000 },
5476 { 0x00000000, 0x003120c4, 0x000 },
5477 { 0x00000000, 0x002d1d07, 0x000 },
5478 { 0x00000024, 0x00803627, 0x000 },
5479 { 0x00000021, 0x00203623, 0x000 },
5480 { 0x00000022, 0x00203624, 0x000 },
5481 { 0x00000000, 0x00311ca3, 0x000 },
5482 { 0x00000023, 0x00203627, 0x000 },
5483 { 0x00000000, 0x00311cc4, 0x000 },
5484 { 0x00000024, 0x00803627, 0x000 },
5485 { 0x0000001a, 0x00203627, 0x000 },
5486 { 0x0000001b, 0x00203628, 0x000 },
5487 { 0x00000017, 0x00201e2d, 0x000 },
5488 { 0x00000002, 0x00210227, 0x000 },
5489 { 0x00000000, 0x14c00000, 0x2dc },
5490 { 0x00000000, 0x00400000, 0x2d9 },
5491 { 0x0000001a, 0x00203627, 0x000 },
5492 { 0x0000001b, 0x00203628, 0x000 },
5493 { 0x00000017, 0x00201e2d, 0x000 },
5494 { 0x00000002, 0x00210227, 0x000 },
5495 { 0x00000000, 0x14e00000, 0x2d9 },
5496 { 0x00000003, 0x00210227, 0x000 },
5497 { 0x00000000, 0x14e00000, 0x2dc },
5498 { 0x00000023, 0x00201e2d, 0x000 },
5499 { 0x00000000, 0x002e00e1, 0x000 },
5500 { 0x00000000, 0x02c00000, 0x2dc },
5501 { 0x00000021, 0x00201e2d, 0x000 },
5502 { 0x00000000, 0x003120a1, 0x000 },
5503 { 0x00000000, 0x002e00e8, 0x000 },
5504 { 0x00000000, 0x06c00000, 0x2dc },
5505 { 0x00000024, 0x00201e2d, 0x000 },
5506 { 0x00000000, 0x002e00e2, 0x000 },
5507 { 0x00000000, 0x02c00000, 0x2dc },
5508 { 0x00000022, 0x00201e2d, 0x000 },
5509 { 0x00000000, 0x003120c2, 0x000 },
5510 { 0x00000000, 0x002e00e8, 0x000 },
5511 { 0x00000000, 0x06c00000, 0x2dc },
5512 { 0x00000000, 0x00600000, 0x668 },
5513 { 0x00000000, 0x00600000, 0x2b5 },
5514 { 0x00000000, 0x00400000, 0x2de },
5515 { 0x00000000, 0x00600000, 0x2b5 },
5516 { 0x00000000, 0x00600000, 0x65f },
5517 { 0x00000000, 0x00400000, 0x2de },
5518 { 0x00000000, 0x00600000, 0x2a7 },
5519 { 0x00000000, 0x00400000, 0x2de },
5520 { 0x0000001a, 0x00201e2d, 0x000 },
5521 { 0x0000001b, 0x0080222d, 0x000 },
5522 { 0x00000010, 0x00221e23, 0x000 },
5523 { 0x00000000, 0x00294887, 0x000 },
5524 { 0x00000000, 0x00311ca3, 0x000 },
5525 { 0x00000010, 0x00221e27, 0x000 },
5526 { 0x00000000, 0x00294887, 0x000 },
5527 { 0x00000010, 0x00221e23, 0x000 },
5528 { 0x00000000, 0x003120c4, 0x000 },
5529 { 0x0000ffff, 0x00282228, 0x000 },
5530 { 0x00000000, 0x00894907, 0x000 },
5531 { 0x00000010, 0x00221e23, 0x000 },
5532 { 0x00000000, 0x00294887, 0x000 },
5533 { 0x00000010, 0x00221e21, 0x000 },
5534 { 0x00000000, 0x00294847, 0x000 },
5535 { 0x00000000, 0x00311ca3, 0x000 },
5536 { 0x00000010, 0x00221e27, 0x000 },
5537 { 0x00000000, 0x00294887, 0x000 },
5538 { 0x00000000, 0x00311ca1, 0x000 },
5539 { 0x00000010, 0x00221e27, 0x000 },
5540 { 0x00000000, 0x00294847, 0x000 },
5541 { 0x00000010, 0x00221e23, 0x000 },
5542 { 0x00000000, 0x003120c4, 0x000 },
5543 { 0x0000ffff, 0x00282228, 0x000 },
5544 { 0x00000000, 0x00294907, 0x000 },
5545 { 0x00000010, 0x00221e21, 0x000 },
5546 { 0x00000000, 0x003120c2, 0x000 },
5547 { 0x0000ffff, 0x00282228, 0x000 },
5548 { 0x00000000, 0x00894907, 0x000 },
5549 { 0x00000010, 0x00221e23, 0x000 },
5550 { 0x00000000, 0x00294887, 0x000 },
5551 { 0x00000001, 0x00220a21, 0x000 },
5552 { 0x00000000, 0x003308a2, 0x000 },
5553 { 0x00000010, 0x00221e22, 0x000 },
5554 { 0x00000010, 0x00212222, 0x000 },
5555 { 0x00000000, 0x00294907, 0x000 },
5556 { 0x00000000, 0x00311ca3, 0x000 },
5557 { 0x00000010, 0x00221e27, 0x000 },
5558 { 0x00000000, 0x00294887, 0x000 },
5559 { 0x00000001, 0x00220a21, 0x000 },
5560 { 0x00000000, 0x003008a2, 0x000 },
5561 { 0x00000010, 0x00221e22, 0x000 },
5562 { 0x00000010, 0x00212222, 0x000 },
5563 { 0x00000000, 0x00294907, 0x000 },
5564 { 0x00000010, 0x00221e23, 0x000 },
5565 { 0x00000000, 0x003120c4, 0x000 },
5566 { 0x0000ffff, 0x00282228, 0x000 },
5567 { 0x00000000, 0x00294907, 0x000 },
5568 { 0x00000000, 0x003808c5, 0x000 },
5569 { 0x00000000, 0x00300841, 0x000 },
5570 { 0x00000001, 0x00220a22, 0x000 },
5571 { 0x00000000, 0x003308a2, 0x000 },
5572 { 0x00000010, 0x00221e22, 0x000 },
5573 { 0x00000010, 0x00212222, 0x000 },
5574 { 0x00000000, 0x00894907, 0x000 },
5575 { 0x00000017, 0x0020222d, 0x000 },
5576 { 0x00000000, 0x14c00000, 0x318 },
5577 { 0xffffffef, 0x00280621, 0x000 },
5578 { 0x00000014, 0x0020222d, 0x000 },
5579 { 0x0000f8e0, 0x00204411, 0x000 },
5580 { 0x00000000, 0x00294901, 0x000 },
5581 { 0x00000000, 0x00894901, 0x000 },
5582 { 0x00000000, 0x00204811, 0x000 },
5583 { 0x00000000, 0x00204811, 0x000 },
5584 { 0x060a0200, 0x00804811, 0x000 },
5585 { 0x00000000, 0xc0200000, 0x000 },
5586 { 0x97000000, 0xc0204411, 0x000 },
5587 { 0x00000000, 0xc0204811, 0x000 },
5588 { 0x8a000000, 0x00204411, 0x000 },
5589 { 0x00000000, 0x00204811, 0x000 },
5590 { 0x0000225c, 0x00204411, 0x000 },
5591 { 0x00000000, 0xc0204800, 0x000 },
5592 { 0x0000a1fc, 0x00204411, 0x000 },
5593 { 0x00000000, 0xc0204800, 0x000 },
5594 { 0x00000000, 0xc0200400, 0x000 },
5595 { 0x00000000, 0x00a0000a, 0x000 },
5596 { 0x97000000, 0x00204411, 0x000 },
5597 { 0x00000000, 0x00204811, 0x000 },
5598 { 0x8a000000, 0x00204411, 0x000 },
5599 { 0x00000000, 0x00204811, 0x000 },
5600 { 0x0000225c, 0x00204411, 0x000 },
5601 { 0x00000000, 0xc0204800, 0x000 },
5602 { 0x0000a1fc, 0x00204411, 0x000 },
5603 { 0x00000000, 0xc0204800, 0x000 },
5604 { 0x00000000, 0xc0200400, 0x000 },
5605 { 0x00000000, 0x00a0000a, 0x000 },
5606 { 0x97000000, 0x00204411, 0x000 },
5607 { 0x00000000, 0x00204811, 0x000 },
5608 { 0x8a000000, 0x00204411, 0x000 },
5609 { 0x00000000, 0x00204811, 0x000 },
5610 { 0x0000225c, 0x00204411, 0x000 },
5611 { 0x00000000, 0xc0204800, 0x000 },
5612 { 0x0000a1fc, 0x00204411, 0x000 },
5613 { 0x00000000, 0xc0204800, 0x000 },
5614 { 0x0001a1fd, 0x00204411, 0x000 },
5615 { 0x00000000, 0xd9004800, 0x000 },
5616 { 0x00000000, 0xc0200400, 0x000 },
5617 { 0x00000000, 0x00a0000a, 0x000 },
5618 { 0x00002257, 0x00204411, 0x000 },
5619 { 0x00000003, 0xc0484a20, 0x000 },
5620 { 0x0000225d, 0x00204411, 0x000 },
5621 { 0x00000000, 0xc0404800, 0x000 },
5622 { 0x00000000, 0x00600000, 0x645 },
5623 { 0x00000000, 0xc0200800, 0x000 },
5624 { 0x0000225c, 0x00204411, 0x000 },
5625 { 0x00000003, 0x00384a22, 0x000 },
5626 { 0x0000a1fc, 0x00204411, 0x000 },
5627 { 0x00000000, 0xc0204800, 0x000 },
5628 { 0x0001a1fd, 0x00204411, 0x000 },
5629 { 0x00000000, 0x002f0222, 0x000 },
5630 { 0x00000000, 0x0ce00000, 0x000 },
5631 { 0x00000000, 0x40204800, 0x000 },
5632 { 0x00000001, 0x40304a20, 0x000 },
5633 { 0x00000002, 0xc0304a20, 0x000 },
5634 { 0x00000001, 0x00530a22, 0x34b },
5635 { 0x0000003f, 0xc0280a20, 0x000 },
5636 { 0x81000000, 0x00204411, 0x000 },
5637 { 0x00000001, 0x00204811, 0x000 },
5638 { 0x000021f8, 0x00204411, 0x000 },
5639 { 0x00000018, 0x00204811, 0x000 },
5640 { 0x000421f9, 0x00604411, 0x68d },
5641 { 0x00000011, 0x00210230, 0x000 },
5642 { 0x00000000, 0x14e00000, 0x354 },
5643 { 0x00000014, 0x002f0222, 0x000 },
5644 { 0x00000000, 0x0cc00000, 0x364 },
5645 { 0x00002010, 0x00204411, 0x000 },
5646 { 0x00008000, 0x00204811, 0x000 },
5647 { 0x0001a2a4, 0x00204411, 0x000 },
5648 { 0x00000000, 0x00604802, 0x36e },
5649 { 0x00002100, 0x00204411, 0x000 },
5650 { 0x00000000, 0xc0204800, 0x000 },
5651 { 0x00000000, 0xc0204800, 0x000 },
5652 { 0x00000000, 0xc0204800, 0x000 },
5653 { 0x00000000, 0xc0404800, 0x000 },
5654 { 0x00000004, 0x002f0222, 0x000 },
5655 { 0x00000000, 0x0cc00000, 0x36a },
5656 { 0x00002010, 0x00204411, 0x000 },
5657 { 0x00008000, 0x00204811, 0x000 },
5658 { 0x0001a2a4, 0x00204411, 0x000 },
5659 { 0x00000000, 0x00404802, 0x35f },
5660 { 0x00000028, 0x002f0222, 0x000 },
5661 { 0x00000000, 0x0cc00000, 0x5c0 },
5662 { 0x0001a2a4, 0x00204411, 0x000 },
5663 { 0x00000000, 0x00404802, 0x35f },
5664 { 0x0000002c, 0x00203626, 0x000 },
5665 { 0x00000049, 0x00201811, 0x000 },
5666 { 0x0000003f, 0x00204811, 0x000 },
5667 { 0x00000001, 0x00331a26, 0x000 },
5668 { 0x00000000, 0x002f0226, 0x000 },
5669 { 0x00000000, 0x0cc00000, 0x370 },
5670 { 0x0000002c, 0x00801a2d, 0x000 },
5671 { 0x0000003f, 0xc0280a20, 0x000 },
5672 { 0x00000015, 0x002f0222, 0x000 },
5673 { 0x00000000, 0x0ce00000, 0x386 },
5674 { 0x00000006, 0x002f0222, 0x000 },
5675 { 0x00000000, 0x0ce00000, 0x3b1 },
5676 { 0x00000016, 0x002f0222, 0x000 },
5677 { 0x00000000, 0x0ce00000, 0x3b5 },
5678 { 0x00000020, 0x002f0222, 0x000 },
5679 { 0x00000000, 0x0ce00000, 0x39c },
5680 { 0x0000000f, 0x002f0222, 0x000 },
5681 { 0x00000000, 0x0ce00000, 0x3a8 },
5682 { 0x00000010, 0x002f0222, 0x000 },
5683 { 0x00000000, 0x0ce00000, 0x3a8 },
5684 { 0x0000001e, 0x002f0222, 0x000 },
5685 { 0x00000000, 0x0ce00000, 0x390 },
5686 { 0x0000a2a4, 0x00204411, 0x000 },
5687 { 0x00000000, 0x00404802, 0x000 },
5688 { 0x08000000, 0x00290a22, 0x000 },
5689 { 0x00000003, 0x40210e20, 0x000 },
5690 { 0x0000000c, 0xc0211220, 0x000 },
5691 { 0x00080000, 0x00281224, 0x000 },
5692 { 0x00000014, 0xc0221620, 0x000 },
5693 { 0x00000000, 0x002914a4, 0x000 },
5694 { 0x0000a2a4, 0x00204411, 0x000 },
5695 { 0x00000000, 0x002948a2, 0x000 },
5696 { 0x0000a1fe, 0x00204411, 0x000 },
5697 { 0x00000000, 0x00404803, 0x000 },
5698 { 0x81000000, 0x00204411, 0x000 },
5699 { 0x00000001, 0x00204811, 0x000 },
5700 { 0x000021f8, 0x00204411, 0x000 },
5701 { 0x00000016, 0x00204811, 0x000 },
5702 { 0x000421f9, 0x00604411, 0x68d },
5703 { 0x00000015, 0x00210230, 0x000 },
5704 { 0x00000000, 0x14e00000, 0x392 },
5705 { 0x0000210e, 0x00204411, 0x000 },
5706 { 0x00000000, 0xc0204800, 0x000 },
5707 { 0x00000000, 0xc0204800, 0x000 },
5708 { 0x0000a2a4, 0x00204411, 0x000 },
5709 { 0x00000000, 0x00404802, 0x000 },
5710 { 0x81000000, 0x00204411, 0x000 },
5711 { 0x00000001, 0x00204811, 0x000 },
5712 { 0x000021f8, 0x00204411, 0x000 },
5713 { 0x00000017, 0x00204811, 0x000 },
5714 { 0x000421f9, 0x00604411, 0x68d },
5715 { 0x00000003, 0x00210230, 0x000 },
5716 { 0x00000000, 0x14e00000, 0x39e },
5717 { 0x00002108, 0x00204411, 0x000 },
5718 { 0x00000000, 0xc0204800, 0x000 },
5719 { 0x00000000, 0xc0204800, 0x000 },
5720 { 0x0000a2a4, 0x00204411, 0x000 },
5721 { 0x00000000, 0x00404802, 0x000 },
5722 { 0x0000a2a4, 0x00204411, 0x000 },
5723 { 0x00000000, 0x00204802, 0x000 },
5724 { 0x80000000, 0x00204411, 0x000 },
5725 { 0x00000000, 0x00204811, 0x000 },
5726 { 0x81000000, 0x00204411, 0x000 },
5727 { 0x00000010, 0x00204811, 0x000 },
5728 { 0x00000000, 0x00200010, 0x000 },
5729 { 0x00000000, 0x14c00000, 0x3ae },
5730 { 0x00000000, 0x00400000, 0x000 },
5731 { 0x00002010, 0x00204411, 0x000 },
5732 { 0x00008000, 0x00204811, 0x000 },
5733 { 0x0001a2a4, 0x00204411, 0x000 },
5734 { 0x00000006, 0x00404811, 0x000 },
5735 { 0x00002010, 0x00204411, 0x000 },
5736 { 0x00008000, 0x00204811, 0x000 },
5737 { 0x0001a2a4, 0x00204411, 0x000 },
5738 { 0x00000016, 0x00604811, 0x36e },
5739 { 0x00000000, 0x00400000, 0x000 },
5740 { 0x00000000, 0xc0200800, 0x000 },
5741 { 0x00000000, 0xc0200c00, 0x000 },
5742 { 0x0000001d, 0x00210223, 0x000 },
5743 { 0x00000000, 0x14e00000, 0x3ce },
5744 { 0x81000000, 0x00204411, 0x000 },
5745 { 0x00000001, 0x00204811, 0x000 },
5746 { 0x000021f8, 0x00204411, 0x000 },
5747 { 0x00000018, 0x00204811, 0x000 },
5748 { 0x000421f9, 0x00604411, 0x68d },
5749 { 0x00000011, 0x00210230, 0x000 },
5750 { 0x00000000, 0x14e00000, 0x3c0 },
5751 { 0x00002100, 0x00204411, 0x000 },
5752 { 0x00000000, 0x00204802, 0x000 },
5753 { 0x00000000, 0x00204803, 0x000 },
5754 { 0xbabecafe, 0x00204811, 0x000 },
5755 { 0xcafebabe, 0x00204811, 0x000 },
5756 { 0x00002010, 0x00204411, 0x000 },
5757 { 0x00008000, 0x00204811, 0x000 },
5758 { 0x0000a2a4, 0x00204411, 0x000 },
5759 { 0x00000004, 0x00404811, 0x000 },
5760 { 0x00002170, 0x00204411, 0x000 },
5761 { 0x00000000, 0x00204802, 0x000 },
5762 { 0x00000000, 0x00204803, 0x000 },
5763 { 0x81000000, 0x00204411, 0x000 },
5764 { 0x0000000a, 0x00204811, 0x000 },
5765 { 0x00000000, 0x00200010, 0x000 },
5766 { 0x00000000, 0x14c00000, 0x3d3 },
5767 { 0x8c000000, 0x00204411, 0x000 },
5768 { 0xcafebabe, 0x00404811, 0x000 },
5769 { 0x81000000, 0x00204411, 0x000 },
5770 { 0x00000001, 0x00204811, 0x000 },
5771 { 0x00003fff, 0x40280a20, 0x000 },
5772 { 0x80000000, 0x40280e20, 0x000 },
5773 { 0x40000000, 0xc0281220, 0x000 },
5774 { 0x00040000, 0x00694622, 0x68d },
5775 { 0x00000000, 0x00201410, 0x000 },
5776 { 0x00000000, 0x002f0223, 0x000 },
5777 { 0x00000000, 0x0cc00000, 0x3e1 },
5778 { 0x00000000, 0xc0401800, 0x3e4 },
5779 { 0x00003fff, 0xc0281a20, 0x000 },
5780 { 0x00040000, 0x00694626, 0x68d },
5781 { 0x00000000, 0x00201810, 0x000 },
5782 { 0x00000000, 0x002f0224, 0x000 },
5783 { 0x00000000, 0x0cc00000, 0x3e7 },
5784 { 0x00000000, 0xc0401c00, 0x3ea },
5785 { 0x00003fff, 0xc0281e20, 0x000 },
5786 { 0x00040000, 0x00694627, 0x68d },
5787 { 0x00000000, 0x00201c10, 0x000 },
5788 { 0x00000000, 0x00204402, 0x000 },
5789 { 0x00000000, 0x002820c5, 0x000 },
5790 { 0x00000000, 0x004948e8, 0x000 },
5791 { 0xa5800000, 0x00200811, 0x000 },
5792 { 0x00002000, 0x00200c11, 0x000 },
5793 { 0x83000000, 0x00604411, 0x412 },
5794 { 0x00000000, 0x00204402, 0x000 },
5795 { 0x00000000, 0xc0204800, 0x000 },
5796 { 0x00000000, 0x40204800, 0x000 },
5797 { 0x0000001f, 0xc0210220, 0x000 },
5798 { 0x00000000, 0x14c00000, 0x3f7 },
5799 { 0x00002010, 0x00204411, 0x000 },
5800 { 0x00008000, 0x00204811, 0x000 },
5801 { 0x0000ffff, 0xc0481220, 0x3ff },
5802 { 0xa7800000, 0x00200811, 0x000 },
5803 { 0x0000a000, 0x00200c11, 0x000 },
5804 { 0x83000000, 0x00604411, 0x412 },
5805 { 0x00000000, 0x00204402, 0x000 },
5806 { 0x00000000, 0xc0204800, 0x000 },
5807 { 0x00000000, 0xc0204800, 0x000 },
5808 { 0x0000ffff, 0xc0281220, 0x000 },
5809 { 0x83000000, 0x00204411, 0x000 },
5810 { 0x00000000, 0x00304883, 0x000 },
5811 { 0x84000000, 0x00204411, 0x000 },
5812 { 0x00000000, 0xc0204800, 0x000 },
5813 { 0x00000000, 0x1d000000, 0x000 },
5814 { 0x83000000, 0x00604411, 0x412 },
5815 { 0x00000000, 0xc0400400, 0x001 },
5816 { 0xa9800000, 0x00200811, 0x000 },
5817 { 0x0000c000, 0x00400c11, 0x3fa },
5818 { 0xab800000, 0x00200811, 0x000 },
5819 { 0x0000f8e0, 0x00400c11, 0x3fa },
5820 { 0xad800000, 0x00200811, 0x000 },
5821 { 0x0000f880, 0x00400c11, 0x3fa },
5822 { 0xb3800000, 0x00200811, 0x000 },
5823 { 0x0000f3fc, 0x00400c11, 0x3fa },
5824 { 0xaf800000, 0x00200811, 0x000 },
5825 { 0x0000e000, 0x00400c11, 0x3fa },
5826 { 0xb1800000, 0x00200811, 0x000 },
5827 { 0x0000f000, 0x00400c11, 0x3fa },
5828 { 0x83000000, 0x00204411, 0x000 },
5829 { 0x00002148, 0x00204811, 0x000 },
5830 { 0x84000000, 0x00204411, 0x000 },
5831 { 0x00000000, 0xc0204800, 0x000 },
5832 { 0x00000000, 0x1d000000, 0x000 },
5833 { 0x00000000, 0x00800000, 0x000 },
5834 { 0x01182000, 0xc0304620, 0x000 },
5835 { 0x00000000, 0xd9004800, 0x000 },
5836 { 0x00000000, 0xc0200400, 0x000 },
5837 { 0x00000000, 0x00a0000a, 0x000 },
5838 { 0x0218a000, 0xc0304620, 0x000 },
5839 { 0x00000000, 0xd9004800, 0x000 },
5840 { 0x00000000, 0xc0200400, 0x000 },
5841 { 0x00000000, 0x00a0000a, 0x000 },
5842 { 0x0318c000, 0xc0304620, 0x000 },
5843 { 0x00000000, 0xd9004800, 0x000 },
5844 { 0x00000000, 0xc0200400, 0x000 },
5845 { 0x00000000, 0x00a0000a, 0x000 },
5846 { 0x0418f8e0, 0xc0304620, 0x000 },
5847 { 0x00000000, 0xd9004800, 0x000 },
5848 { 0x00000000, 0xc0200400, 0x000 },
5849 { 0x00000000, 0x00a0000a, 0x000 },
5850 { 0x0518f880, 0xc0304620, 0x000 },
5851 { 0x00000000, 0xd9004800, 0x000 },
5852 { 0x00000000, 0xc0200400, 0x000 },
5853 { 0x00000000, 0x00a0000a, 0x000 },
5854 { 0x0618e000, 0xc0304620, 0x000 },
5855 { 0x00000000, 0xd9004800, 0x000 },
5856 { 0x00000000, 0xc0200400, 0x000 },
5857 { 0x00000000, 0x00a0000a, 0x000 },
5858 { 0x0718f000, 0xc0304620, 0x000 },
5859 { 0x00000000, 0xd9004800, 0x000 },
5860 { 0x00000000, 0xc0200400, 0x000 },
5861 { 0x00000000, 0x00a0000a, 0x000 },
5862 { 0x0818f3fc, 0xc0304620, 0x000 },
5863 { 0x00000000, 0xd9004800, 0x000 },
5864 { 0x00000000, 0xc0200400, 0x000 },
5865 { 0x00000000, 0x00a0000a, 0x000 },
5866 { 0x00000030, 0x00200a2d, 0x000 },
5867 { 0x00000000, 0xc0290c40, 0x000 },
5868 { 0x00000030, 0x00203623, 0x000 },
5869 { 0x00000000, 0xc0200400, 0x000 },
5870 { 0x00000000, 0x00a0000a, 0x000 },
5871 { 0x86000000, 0x00204411, 0x000 },
5872 { 0x00000000, 0x00404801, 0x000 },
5873 { 0x85000000, 0xc0204411, 0x000 },
5874 { 0x00000000, 0x00404801, 0x000 },
5875 { 0x0000217c, 0x00204411, 0x000 },
5876 { 0x00000018, 0x40210220, 0x000 },
5877 { 0x00000000, 0x14c00000, 0x445 },
5878 { 0x00800000, 0xc0494a20, 0x446 },
5879 { 0x00000000, 0xc0204800, 0x000 },
5880 { 0x00000000, 0xc0204800, 0x000 },
5881 { 0x00000000, 0xc0204800, 0x000 },
5882 { 0x81000000, 0x00204411, 0x000 },
5883 { 0x00000001, 0x00204811, 0x000 },
5884 { 0x00000000, 0xc0200800, 0x000 },
5885 { 0x00000000, 0x17000000, 0x000 },
5886 { 0x0004217f, 0x00604411, 0x68d },
5887 { 0x0000001f, 0x00210230, 0x000 },
5888 { 0x00000000, 0x14c00000, 0x000 },
5889 { 0x00000000, 0x00404c02, 0x44b },
5890 { 0x00000000, 0xc0200c00, 0x000 },
5891 { 0x00000000, 0xc0201000, 0x000 },
5892 { 0x00000000, 0xc0201400, 0x000 },
5893 { 0x00000000, 0xc0201800, 0x000 },
5894 { 0x00000000, 0xc0201c00, 0x000 },
5895 { 0x00007f00, 0x00280a21, 0x000 },
5896 { 0x00004500, 0x002f0222, 0x000 },
5897 { 0x00000000, 0x0ce00000, 0x459 },
5898 { 0x00000000, 0xc0202000, 0x000 },
5899 { 0x00000000, 0x17000000, 0x000 },
5900 { 0x00000010, 0x00280a23, 0x000 },
5901 { 0x00000010, 0x002f0222, 0x000 },
5902 { 0x00000000, 0x0ce00000, 0x461 },
5903 { 0x81000000, 0x00204411, 0x000 },
5904 { 0x00000001, 0x00204811, 0x000 },
5905 { 0x00040000, 0x00694624, 0x68d },
5906 { 0x00000000, 0x00400000, 0x466 },
5907 { 0x81000000, 0x00204411, 0x000 },
5908 { 0x00000000, 0x00204811, 0x000 },
5909 { 0x0000216d, 0x00204411, 0x000 },
5910 { 0x00000000, 0x00204804, 0x000 },
5911 { 0x00000000, 0x00604805, 0x692 },
5912 { 0x00000000, 0x002824f0, 0x000 },
5913 { 0x00000007, 0x00280a23, 0x000 },
5914 { 0x00000001, 0x002f0222, 0x000 },
5915 { 0x00000000, 0x0ae00000, 0x46d },
5916 { 0x00000000, 0x002f00c9, 0x000 },
5917 { 0x00000000, 0x04e00000, 0x486 },
5918 { 0x00000000, 0x00400000, 0x493 },
5919 { 0x00000002, 0x002f0222, 0x000 },
5920 { 0x00000000, 0x0ae00000, 0x472 },
5921 { 0x00000000, 0x002f00c9, 0x000 },
5922 { 0x00000000, 0x02e00000, 0x486 },
5923 { 0x00000000, 0x00400000, 0x493 },
5924 { 0x00000003, 0x002f0222, 0x000 },
5925 { 0x00000000, 0x0ae00000, 0x477 },
5926 { 0x00000000, 0x002f00c9, 0x000 },
5927 { 0x00000000, 0x0ce00000, 0x486 },
5928 { 0x00000000, 0x00400000, 0x493 },
5929 { 0x00000004, 0x002f0222, 0x000 },
5930 { 0x00000000, 0x0ae00000, 0x47c },
5931 { 0x00000000, 0x002f00c9, 0x000 },
5932 { 0x00000000, 0x0ae00000, 0x486 },
5933 { 0x00000000, 0x00400000, 0x493 },
5934 { 0x00000005, 0x002f0222, 0x000 },
5935 { 0x00000000, 0x0ae00000, 0x481 },
5936 { 0x00000000, 0x002f00c9, 0x000 },
5937 { 0x00000000, 0x06e00000, 0x486 },
5938 { 0x00000000, 0x00400000, 0x493 },
5939 { 0x00000006, 0x002f0222, 0x000 },
5940 { 0x00000000, 0x0ae00000, 0x486 },
5941 { 0x00000000, 0x002f00c9, 0x000 },
5942 { 0x00000000, 0x08e00000, 0x486 },
5943 { 0x00000000, 0x00400000, 0x493 },
5944 { 0x00007f00, 0x00280a21, 0x000 },
5945 { 0x00004500, 0x002f0222, 0x000 },
5946 { 0x00000000, 0x0ae00000, 0x000 },
5947 { 0x00000008, 0x00210a23, 0x000 },
5948 { 0x00000000, 0x14c00000, 0x490 },
5949 { 0x00002169, 0x00204411, 0x000 },
5950 { 0x00000000, 0xc0204800, 0x000 },
5951 { 0x00000000, 0xc0204800, 0x000 },
5952 { 0x00000000, 0xc0204800, 0x000 },
5953 { 0xcafebabe, 0x00404811, 0x000 },
5954 { 0x00000000, 0xc0204400, 0x000 },
5955 { 0x00000000, 0xc0200000, 0x000 },
5956 { 0x00000000, 0xc0404800, 0x000 },
5957 { 0x00007f00, 0x00280a21, 0x000 },
5958 { 0x00004500, 0x002f0222, 0x000 },
5959 { 0x00000000, 0x0ae00000, 0x499 },
5960 { 0x00000000, 0xc0200000, 0x000 },
5961 { 0x00000000, 0xc0200000, 0x000 },
5962 { 0x00000000, 0xc0400000, 0x000 },
5963 { 0x00000000, 0x00404c08, 0x459 },
5964 { 0x00000000, 0xc0200800, 0x000 },
5965 { 0x00000010, 0x40210e20, 0x000 },
5966 { 0x00000011, 0x40211220, 0x000 },
5967 { 0x00000012, 0x40211620, 0x000 },
5968 { 0x00002169, 0x00204411, 0x000 },
5969 { 0x00000000, 0x00204802, 0x000 },
5970 { 0x00000000, 0x00210225, 0x000 },
5971 { 0x00000000, 0x14e00000, 0x4a3 },
5972 { 0x00040000, 0xc0494a20, 0x4a4 },
5973 { 0xfffbffff, 0xc0284a20, 0x000 },
5974 { 0x00000000, 0x00210223, 0x000 },
5975 { 0x00000000, 0x14e00000, 0x4b0 },
5976 { 0x00000000, 0xc0204800, 0x000 },
5977 { 0x00000000, 0xc0204800, 0x000 },
5978 { 0x00000000, 0x00210224, 0x000 },
5979 { 0x00000000, 0x14c00000, 0x000 },
5980 { 0x81000000, 0x00204411, 0x000 },
5981 { 0x0000000c, 0x00204811, 0x000 },
5982 { 0x00000000, 0x00200010, 0x000 },
5983 { 0x00000000, 0x14c00000, 0x4ac },
5984 { 0xa0000000, 0x00204411, 0x000 },
5985 { 0xcafebabe, 0x00404811, 0x000 },
5986 { 0x81000000, 0x00204411, 0x000 },
5987 { 0x00000004, 0x00204811, 0x000 },
5988 { 0x0000216b, 0x00204411, 0x000 },
5989 { 0x00000000, 0xc0204810, 0x000 },
5990 { 0x81000000, 0x00204411, 0x000 },
5991 { 0x00000005, 0x00204811, 0x000 },
5992 { 0x0000216c, 0x00204411, 0x000 },
5993 { 0x00000000, 0xc0204810, 0x000 },
5994 { 0x00000000, 0x002f0224, 0x000 },
5995 { 0x00000000, 0x0ce00000, 0x000 },
5996 { 0x00000000, 0x00400000, 0x4aa },
5997 { 0x00000000, 0xc0210a20, 0x000 },
5998 { 0x00000000, 0x14c00000, 0x4c3 },
5999 { 0x81000000, 0x00204411, 0x000 },
6000 { 0x00000000, 0x00204811, 0x000 },
6001 { 0x0000216d, 0x00204411, 0x000 },
6002 { 0x00000000, 0xc0204800, 0x000 },
6003 { 0x00000000, 0xc0604800, 0x692 },
6004 { 0x00000000, 0x00400000, 0x4c7 },
6005 { 0x81000000, 0x00204411, 0x000 },
6006 { 0x00000001, 0x00204811, 0x000 },
6007 { 0x00040000, 0xc0294620, 0x000 },
6008 { 0x00000000, 0xc0600000, 0x68d },
6009 { 0x00000001, 0x00210222, 0x000 },
6010 { 0x00000000, 0x14c00000, 0x4ce },
6011 { 0x00002169, 0x00204411, 0x000 },
6012 { 0x00000000, 0xc0204800, 0x000 },
6013 { 0x00000000, 0xc0204800, 0x000 },
6014 { 0x00000000, 0x00204810, 0x000 },
6015 { 0xcafebabe, 0x00404811, 0x000 },
6016 { 0x00000000, 0xc0204400, 0x000 },
6017 { 0x00000000, 0xc0404810, 0x000 },
6018 { 0x81000000, 0x00204411, 0x000 },
6019 { 0x00000001, 0x00204811, 0x000 },
6020 { 0x000021f8, 0x00204411, 0x000 },
6021 { 0x0000000e, 0x00204811, 0x000 },
6022 { 0x000421f9, 0x00604411, 0x68d },
6023 { 0x00000000, 0x00210230, 0x000 },
6024 { 0x00000000, 0x14c00000, 0x4d0 },
6025 { 0x00002180, 0x00204411, 0x000 },
6026 { 0x00000000, 0xc0204800, 0x000 },
6027 { 0x00000000, 0xc0200000, 0x000 },
6028 { 0x00000000, 0xc0204800, 0x000 },
6029 { 0x00000000, 0xc0200000, 0x000 },
6030 { 0x00000000, 0xc0404800, 0x000 },
6031 { 0x00000003, 0x00333e2f, 0x000 },
6032 { 0x00000001, 0x00210221, 0x000 },
6033 { 0x00000000, 0x14e00000, 0x500 },
6034 { 0x0000002c, 0x00200a2d, 0x000 },
6035 { 0x00040000, 0x18e00c11, 0x4ef },
6036 { 0x00000001, 0x00333e2f, 0x000 },
6037 { 0x00002169, 0x00204411, 0x000 },
6038 { 0x00000000, 0x00204802, 0x000 },
6039 { 0x00000000, 0x00204803, 0x000 },
6040 { 0x00000008, 0x00300a22, 0x000 },
6041 { 0x00000000, 0xc0204800, 0x000 },
6042 { 0x00000000, 0xc0204800, 0x000 },
6043 { 0x00002169, 0x00204411, 0x000 },
6044 { 0x00000000, 0x00204802, 0x000 },
6045 { 0x00000000, 0x00204803, 0x000 },
6046 { 0x00000008, 0x00300a22, 0x000 },
6047 { 0x00000000, 0xc0204800, 0x000 },
6048 { 0x00000000, 0xd8c04800, 0x4e3 },
6049 { 0x00002169, 0x00204411, 0x000 },
6050 { 0x00000000, 0x00204802, 0x000 },
6051 { 0x00000000, 0x00204803, 0x000 },
6052 { 0x00000008, 0x00300a22, 0x000 },
6053 { 0x00000000, 0xc0204800, 0x000 },
6054 { 0x00000000, 0xc0204800, 0x000 },
6055 { 0x0000002d, 0x0020122d, 0x000 },
6056 { 0x00000000, 0x00290c83, 0x000 },
6057 { 0x00002169, 0x00204411, 0x000 },
6058 { 0x00000000, 0x00204802, 0x000 },
6059 { 0x00000000, 0x00204803, 0x000 },
6060 { 0x00000008, 0x00300a22, 0x000 },
6061 { 0x00000000, 0xc0204800, 0x000 },
6062 { 0x00000000, 0xc0204800, 0x000 },
6063 { 0x00000011, 0x00210224, 0x000 },
6064 { 0x00000000, 0x14c00000, 0x000 },
6065 { 0x00000000, 0x00400000, 0x4aa },
6066 { 0x0000002c, 0xc0203620, 0x000 },
6067 { 0x0000002d, 0xc0403620, 0x000 },
6068 { 0x0000000f, 0x00210221, 0x000 },
6069 { 0x00000000, 0x14c00000, 0x505 },
6070 { 0x00000000, 0x00600000, 0x00b },
6071 { 0x00000000, 0xd9000000, 0x000 },
6072 { 0x00000000, 0xc0400400, 0x001 },
6073 { 0xb5000000, 0x00204411, 0x000 },
6074 { 0x00002000, 0x00204811, 0x000 },
6075 { 0xb6000000, 0x00204411, 0x000 },
6076 { 0x0000a000, 0x00204811, 0x000 },
6077 { 0xb7000000, 0x00204411, 0x000 },
6078 { 0x0000c000, 0x00204811, 0x000 },
6079 { 0xb8000000, 0x00204411, 0x000 },
6080 { 0x0000f8e0, 0x00204811, 0x000 },
6081 { 0xb9000000, 0x00204411, 0x000 },
6082 { 0x0000f880, 0x00204811, 0x000 },
6083 { 0xba000000, 0x00204411, 0x000 },
6084 { 0x0000e000, 0x00204811, 0x000 },
6085 { 0xbb000000, 0x00204411, 0x000 },
6086 { 0x0000f000, 0x00204811, 0x000 },
6087 { 0xbc000000, 0x00204411, 0x000 },
6088 { 0x0000f3fc, 0x00204811, 0x000 },
6089 { 0x81000000, 0x00204411, 0x000 },
6090 { 0x00000002, 0x00204811, 0x000 },
6091 { 0x000000ff, 0x00280e30, 0x000 },
6092 { 0x00000000, 0x002f0223, 0x000 },
6093 { 0x00000000, 0x0cc00000, 0x519 },
6094 { 0x00000000, 0xc0200800, 0x000 },
6095 { 0x00000000, 0x14c00000, 0x52e },
6096 { 0x00000000, 0x00200c11, 0x000 },
6097 { 0x0000001c, 0x00203623, 0x000 },
6098 { 0x0000002b, 0x00203623, 0x000 },
6099 { 0x00000029, 0x00203623, 0x000 },
6100 { 0x00000028, 0x00203623, 0x000 },
6101 { 0x00000017, 0x00203623, 0x000 },
6102 { 0x00000025, 0x00203623, 0x000 },
6103 { 0x00000026, 0x00203623, 0x000 },
6104 { 0x00000015, 0x00203623, 0x000 },
6105 { 0x00000016, 0x00203623, 0x000 },
6106 { 0xffffe000, 0x00200c11, 0x000 },
6107 { 0x00000021, 0x00203623, 0x000 },
6108 { 0x00000022, 0x00203623, 0x000 },
6109 { 0x00001fff, 0x00200c11, 0x000 },
6110 { 0x00000023, 0x00203623, 0x000 },
6111 { 0x00000024, 0x00203623, 0x000 },
6112 { 0xf1ffffff, 0x00283a2e, 0x000 },
6113 { 0x0000001a, 0xc0220e20, 0x000 },
6114 { 0x00000000, 0x0029386e, 0x000 },
6115 { 0x81000000, 0x00204411, 0x000 },
6116 { 0x00000006, 0x00204811, 0x000 },
6117 { 0x0000002a, 0x40203620, 0x000 },
6118 { 0x87000000, 0x00204411, 0x000 },
6119 { 0x00000000, 0xc0204800, 0x000 },
6120 { 0x0000a1f4, 0x00204411, 0x000 },
6121 { 0x00000000, 0x00204810, 0x000 },
6122 { 0x00000000, 0x00200c11, 0x000 },
6123 { 0x00000030, 0x00203623, 0x000 },
6124 { 0x9d000000, 0x00204411, 0x000 },
6125 { 0x0000001f, 0x40214a20, 0x000 },
6126 { 0x96000000, 0x00204411, 0x000 },
6127 { 0x00000000, 0xc0204800, 0x000 },
6128 { 0x00000000, 0xc0200c00, 0x000 },
6129 { 0x00000000, 0xc0201000, 0x000 },
6130 { 0x0000001f, 0x00211624, 0x000 },
6131 { 0x00000000, 0x14c00000, 0x000 },
6132 { 0x0000001d, 0x00203623, 0x000 },
6133 { 0x00000003, 0x00281e23, 0x000 },
6134 { 0x00000008, 0x00222223, 0x000 },
6135 { 0xfffff000, 0x00282228, 0x000 },
6136 { 0x00000000, 0x002920e8, 0x000 },
6137 { 0x0000001f, 0x00203628, 0x000 },
6138 { 0x00000018, 0x00211e23, 0x000 },
6139 { 0x00000020, 0x00203627, 0x000 },
6140 { 0x00000002, 0x00221624, 0x000 },
6141 { 0x00000000, 0x003014a8, 0x000 },
6142 { 0x0000001e, 0x00203625, 0x000 },
6143 { 0x00000003, 0x00211a24, 0x000 },
6144 { 0x10000000, 0x00281a26, 0x000 },
6145 { 0xefffffff, 0x00283a2e, 0x000 },
6146 { 0x00000000, 0x004938ce, 0x67b },
6147 { 0x00000001, 0x40280a20, 0x000 },
6148 { 0x00000006, 0x40280e20, 0x000 },
6149 { 0x00000300, 0xc0281220, 0x000 },
6150 { 0x00000008, 0x00211224, 0x000 },
6151 { 0x00000000, 0xc0201620, 0x000 },
6152 { 0x00000000, 0xc0201a20, 0x000 },
6153 { 0x00000000, 0x00210222, 0x000 },
6154 { 0x00000000, 0x14c00000, 0x566 },
6155 { 0x81000000, 0x00204411, 0x000 },
6156 { 0x00000001, 0x00204811, 0x000 },
6157 { 0x00002258, 0x00300a24, 0x000 },
6158 { 0x00040000, 0x00694622, 0x68d },
6159 { 0x00002169, 0x00204411, 0x000 },
6160 { 0x00000000, 0x00204805, 0x000 },
6161 { 0x00020000, 0x00294a26, 0x000 },
6162 { 0x00000000, 0x00204810, 0x000 },
6163 { 0xcafebabe, 0x00204811, 0x000 },
6164 { 0x00000002, 0x002f0223, 0x000 },
6165 { 0x00000000, 0x0cc00000, 0x56e },
6166 { 0x00000000, 0xc0201c10, 0x000 },
6167 { 0x00000000, 0xc0400000, 0x57c },
6168 { 0x00000002, 0x002f0223, 0x000 },
6169 { 0x00000000, 0x0cc00000, 0x56e },
6170 { 0x81000000, 0x00204411, 0x000 },
6171 { 0x00000001, 0x00204811, 0x000 },
6172 { 0x00002258, 0x00300a24, 0x000 },
6173 { 0x00040000, 0x00694622, 0x68d },
6174 { 0x00000000, 0xc0201c10, 0x000 },
6175 { 0x00000000, 0xc0400000, 0x57c },
6176 { 0x00000000, 0x002f0223, 0x000 },
6177 { 0x00000000, 0x0cc00000, 0x572 },
6178 { 0x00000000, 0xc0201c00, 0x000 },
6179 { 0x00000000, 0xc0400000, 0x57c },
6180 { 0x00000004, 0x002f0223, 0x000 },
6181 { 0x00000000, 0x0cc00000, 0x57a },
6182 { 0x81000000, 0x00204411, 0x000 },
6183 { 0x00000000, 0x00204811, 0x000 },
6184 { 0x0000216d, 0x00204411, 0x000 },
6185 { 0x00000000, 0xc0204800, 0x000 },
6186 { 0x00000000, 0xc0604800, 0x692 },
6187 { 0x00000000, 0x00401c10, 0x57c },
6188 { 0x00000000, 0xc0200000, 0x000 },
6189 { 0x00000000, 0xc0400000, 0x000 },
6190 { 0x00000000, 0x0ee00000, 0x57e },
6191 { 0x00000000, 0x00600000, 0x5c9 },
6192 { 0x00000000, 0x002f0224, 0x000 },
6193 { 0x00000000, 0x0cc00000, 0x58f },
6194 { 0x0000a2b7, 0x00204411, 0x000 },
6195 { 0x00000000, 0x00204807, 0x000 },
6196 { 0x81000000, 0x00204411, 0x000 },
6197 { 0x00000001, 0x00204811, 0x000 },
6198 { 0x0004a2b6, 0x00604411, 0x68d },
6199 { 0x0000001a, 0x00212230, 0x000 },
6200 { 0x00000006, 0x00222630, 0x000 },
6201 { 0x00042004, 0x00604411, 0x68d },
6202 { 0x0000a2c4, 0x00204411, 0x000 },
6203 { 0x00000000, 0x003048e9, 0x000 },
6204 { 0x00000000, 0x00e00000, 0x58d },
6205 { 0x0000a2d1, 0x00204411, 0x000 },
6206 { 0x00000000, 0x00404808, 0x000 },
6207 { 0x0000a2d1, 0x00204411, 0x000 },
6208 { 0x00000001, 0x00504a28, 0x000 },
6209 { 0x00000001, 0x002f0224, 0x000 },
6210 { 0x00000000, 0x0cc00000, 0x5a0 },
6211 { 0x0000a2bb, 0x00204411, 0x000 },
6212 { 0x00000000, 0x00204807, 0x000 },
6213 { 0x81000000, 0x00204411, 0x000 },
6214 { 0x00000001, 0x00204811, 0x000 },
6215 { 0x0004a2ba, 0x00604411, 0x68d },
6216 { 0x0000001a, 0x00212230, 0x000 },
6217 { 0x00000006, 0x00222630, 0x000 },
6218 { 0x00042004, 0x00604411, 0x68d },
6219 { 0x0000a2c5, 0x00204411, 0x000 },
6220 { 0x00000000, 0x003048e9, 0x000 },
6221 { 0x00000000, 0x00e00000, 0x59e },
6222 { 0x0000a2d2, 0x00204411, 0x000 },
6223 { 0x00000000, 0x00404808, 0x000 },
6224 { 0x0000a2d2, 0x00204411, 0x000 },
6225 { 0x00000001, 0x00504a28, 0x000 },
6226 { 0x00000002, 0x002f0224, 0x000 },
6227 { 0x00000000, 0x0cc00000, 0x5b1 },
6228 { 0x0000a2bf, 0x00204411, 0x000 },
6229 { 0x00000000, 0x00204807, 0x000 },
6230 { 0x81000000, 0x00204411, 0x000 },
6231 { 0x00000001, 0x00204811, 0x000 },
6232 { 0x0004a2be, 0x00604411, 0x68d },
6233 { 0x0000001a, 0x00212230, 0x000 },
6234 { 0x00000006, 0x00222630, 0x000 },
6235 { 0x00042004, 0x00604411, 0x68d },
6236 { 0x0000a2c6, 0x00204411, 0x000 },
6237 { 0x00000000, 0x003048e9, 0x000 },
6238 { 0x00000000, 0x00e00000, 0x5af },
6239 { 0x0000a2d3, 0x00204411, 0x000 },
6240 { 0x00000000, 0x00404808, 0x000 },
6241 { 0x0000a2d3, 0x00204411, 0x000 },
6242 { 0x00000001, 0x00504a28, 0x000 },
6243 { 0x0000a2c3, 0x00204411, 0x000 },
6244 { 0x00000000, 0x00204807, 0x000 },
6245 { 0x81000000, 0x00204411, 0x000 },
6246 { 0x00000001, 0x00204811, 0x000 },
6247 { 0x0004a2c2, 0x00604411, 0x68d },
6248 { 0x0000001a, 0x00212230, 0x000 },
6249 { 0x00000006, 0x00222630, 0x000 },
6250 { 0x00042004, 0x00604411, 0x68d },
6251 { 0x0000a2c7, 0x00204411, 0x000 },
6252 { 0x00000000, 0x003048e9, 0x000 },
6253 { 0x00000000, 0x00e00000, 0x5be },
6254 { 0x0000a2d4, 0x00204411, 0x000 },
6255 { 0x00000000, 0x00404808, 0x000 },
6256 { 0x0000a2d4, 0x00204411, 0x000 },
6257 { 0x00000001, 0x00504a28, 0x000 },
6258 { 0x85000000, 0x00204411, 0x000 },
6259 { 0x00000000, 0x00204801, 0x000 },
6260 { 0x0000304a, 0x00204411, 0x000 },
6261 { 0x01000000, 0x00204811, 0x000 },
6262 { 0x00000000, 0x00400000, 0x5c4 },
6263 { 0xa4000000, 0xc0204411, 0x000 },
6264 { 0x00000000, 0xc0404800, 0x000 },
6265 { 0x00000000, 0xc0600000, 0x5c9 },
6266 { 0x00000000, 0xc0400400, 0x001 },
6267 { 0x0000002c, 0x00203621, 0x000 },
6268 { 0x81000000, 0x00204411, 0x000 },
6269 { 0x00000006, 0x00204811, 0x000 },
6270 { 0x00000000, 0x002f0230, 0x000 },
6271 { 0x00000000, 0x0cc00000, 0x5d0 },
6272 { 0x00000000, 0x00200411, 0x000 },
6273 { 0x00000030, 0x00403621, 0x5e3 },
6274 { 0x00000030, 0x0020062d, 0x000 },
6275 { 0x00007e00, 0x00280621, 0x000 },
6276 { 0x00000000, 0x002f0221, 0x000 },
6277 { 0x00000000, 0x0ce00000, 0x5e3 },
6278 { 0x81000000, 0x00204411, 0x000 },
6279 { 0x00000001, 0x00204811, 0x000 },
6280 { 0x0004a092, 0x00604411, 0x68d },
6281 { 0x00000031, 0x00203630, 0x000 },
6282 { 0x0004a093, 0x00604411, 0x68d },
6283 { 0x00000032, 0x00203630, 0x000 },
6284 { 0x0004a2b6, 0x00604411, 0x68d },
6285 { 0x00000033, 0x00203630, 0x000 },
6286 { 0x0004a2ba, 0x00604411, 0x68d },
6287 { 0x00000034, 0x00203630, 0x000 },
6288 { 0x0004a2be, 0x00604411, 0x68d },
6289 { 0x00000035, 0x00203630, 0x000 },
6290 { 0x0004a2c2, 0x00604411, 0x68d },
6291 { 0x00000036, 0x00203630, 0x000 },
6292 { 0x00042004, 0x00604411, 0x68d },
6293 { 0x0001a2a4, 0x00204411, 0x000 },
6294 { 0x0000003f, 0x00204811, 0x000 },
6295 { 0x0000003f, 0x00204811, 0x000 },
6296 { 0x0000003f, 0x00204811, 0x000 },
6297 { 0x0000003f, 0x00204811, 0x000 },
6298 { 0x00000005, 0x00204811, 0x000 },
6299 { 0x0000a1f4, 0x00204411, 0x000 },
6300 { 0x00000000, 0x00204811, 0x000 },
6301 { 0x88000000, 0x00204411, 0x000 },
6302 { 0x00000001, 0x00204811, 0x000 },
6303 { 0x81000000, 0x00204411, 0x000 },
6304 { 0x00000006, 0x00204811, 0x000 },
6305 { 0x00000001, 0x002f0230, 0x000 },
6306 { 0x00000000, 0x0ce00000, 0x62c },
6307 { 0x00000030, 0x0020062d, 0x000 },
6308 { 0x00000000, 0x002f0221, 0x000 },
6309 { 0x00000000, 0x0ce00000, 0x62c },
6310 { 0x81000000, 0x00204411, 0x000 },
6311 { 0x00000001, 0x00204811, 0x000 },
6312 { 0x00007e00, 0x00280621, 0x000 },
6313 { 0x00000000, 0x002f0221, 0x000 },
6314 { 0x00000000, 0x0ce00000, 0x605 },
6315 { 0x0000a092, 0x00204411, 0x000 },
6316 { 0x00000031, 0x00204a2d, 0x000 },
6317 { 0x0000a093, 0x00204411, 0x000 },
6318 { 0x00000032, 0x00204a2d, 0x000 },
6319 { 0x0000a2b6, 0x00204411, 0x000 },
6320 { 0x00000033, 0x00204a2d, 0x000 },
6321 { 0x0000a2ba, 0x00204411, 0x000 },
6322 { 0x00000034, 0x00204a2d, 0x000 },
6323 { 0x0000a2be, 0x00204411, 0x000 },
6324 { 0x00000035, 0x00204a2d, 0x000 },
6325 { 0x0000a2c2, 0x00204411, 0x000 },
6326 { 0x00000036, 0x00204a2d, 0x000 },
6327 { 0x00000030, 0x0020062d, 0x000 },
6328 { 0x000001ff, 0x00280621, 0x000 },
6329 { 0x00000000, 0x002f0221, 0x000 },
6330 { 0x00000000, 0x0ce00000, 0x62b },
6331 { 0x00000000, 0x00210221, 0x000 },
6332 { 0x00000000, 0x14c00000, 0x60e },
6333 { 0x0004a003, 0x00604411, 0x68d },
6334 { 0x0000a003, 0x00204411, 0x000 },
6335 { 0x00000000, 0x00204810, 0x000 },
6336 { 0x00000001, 0x00210621, 0x000 },
6337 { 0x00000000, 0x14c00000, 0x613 },
6338 { 0x0004a010, 0x00604411, 0x68d },
6339 { 0x0000a010, 0x00204411, 0x000 },
6340 { 0x00000000, 0x00204810, 0x000 },
6341 { 0x00000001, 0x00210621, 0x000 },
6342 { 0x00000000, 0x002f0221, 0x000 },
6343 { 0x00000000, 0x0ce00000, 0x62b },
6344 { 0x0004a011, 0x00604411, 0x68d },
6345 { 0x0000a011, 0x00204411, 0x000 },
6346 { 0x00000000, 0x00204810, 0x000 },
6347 { 0x0004a012, 0x00604411, 0x68d },
6348 { 0x0000a012, 0x00204411, 0x000 },
6349 { 0x00000000, 0x00204810, 0x000 },
6350 { 0x0004a013, 0x00604411, 0x68d },
6351 { 0x0000a013, 0x00204411, 0x000 },
6352 { 0x00000000, 0x00204810, 0x000 },
6353 { 0x0004a014, 0x00604411, 0x68d },
6354 { 0x0000a014, 0x00204411, 0x000 },
6355 { 0x00000000, 0x00204810, 0x000 },
6356 { 0x0004a015, 0x00604411, 0x68d },
6357 { 0x0000a015, 0x00204411, 0x000 },
6358 { 0x00000000, 0x00204810, 0x000 },
6359 { 0x0004a016, 0x00604411, 0x68d },
6360 { 0x0000a016, 0x00204411, 0x000 },
6361 { 0x00000000, 0x00204810, 0x000 },
6362 { 0x0004a017, 0x00604411, 0x68d },
6363 { 0x0000a017, 0x00204411, 0x000 },
6364 { 0x00000000, 0x00204810, 0x000 },
6365 { 0x00042004, 0x00604411, 0x68d },
6366 { 0x0000002c, 0x0080062d, 0x000 },
6367 { 0xff000000, 0x00204411, 0x000 },
6368 { 0x00000000, 0x00204811, 0x000 },
6369 { 0x00000001, 0x00204811, 0x000 },
6370 { 0x00000002, 0x00804811, 0x000 },
6371 { 0x00000000, 0x0ee00000, 0x63d },
6372 { 0x00000030, 0x0020062d, 0x000 },
6373 { 0x00000002, 0x00280621, 0x000 },
6374 { 0x00000000, 0x002f0221, 0x000 },
6375 { 0x00000000, 0x0ce00000, 0x63b },
6376 { 0x81000000, 0x00204411, 0x000 },
6377 { 0x00000001, 0x00204811, 0x000 },
6378 { 0x00042004, 0x00604411, 0x68d },
6379 { 0x00001000, 0x00200811, 0x000 },
6380 { 0x0000002b, 0x00203622, 0x000 },
6381 { 0x00000000, 0x00600000, 0x641 },
6382 { 0x00000000, 0x00600000, 0x5c9 },
6383 { 0x98000000, 0x00204411, 0x000 },
6384 { 0x00000000, 0x00804811, 0x000 },
6385 { 0x00000000, 0xc0600000, 0x641 },
6386 { 0x00000000, 0xc0400400, 0x001 },
6387 { 0x0000a2a4, 0x00204411, 0x000 },
6388 { 0x00000022, 0x00204811, 0x000 },
6389 { 0x89000000, 0x00204411, 0x000 },
6390 { 0x00000001, 0x00404811, 0x62d },
6391 { 0x97000000, 0x00204411, 0x000 },
6392 { 0x00000000, 0x00204811, 0x000 },
6393 { 0x8a000000, 0x00204411, 0x000 },
6394 { 0x00000000, 0x00404811, 0x62d },
6395 { 0x00000000, 0x00600000, 0x65c },
6396 { 0x00002010, 0x00204411, 0x000 },
6397 { 0x00008000, 0x00204811, 0x000 },
6398 { 0x0001a2a4, 0xc0204411, 0x000 },
6399 { 0x00000016, 0x00604811, 0x36e },
6400 { 0x00002010, 0x00204411, 0x000 },
6401 { 0x00010000, 0x00204811, 0x000 },
6402 { 0x81000000, 0x00204411, 0x000 },
6403 { 0x00000001, 0x00204811, 0x000 },
6404 { 0x0000217c, 0x00204411, 0x000 },
6405 { 0x09800000, 0x00204811, 0x000 },
6406 { 0xffffffff, 0x00204811, 0x000 },
6407 { 0x00000000, 0x00204811, 0x000 },
6408 { 0x00000000, 0x17000000, 0x000 },
6409 { 0x0004217f, 0x00604411, 0x68d },
6410 { 0x0000001f, 0x00210230, 0x000 },
6411 { 0x00000000, 0x14c00000, 0x000 },
6412 { 0x00000004, 0x00404c11, 0x656 },
6413 { 0x00000000, 0x00400000, 0x000 },
6414 { 0x00000017, 0x00201e2d, 0x000 },
6415 { 0x00000004, 0x00291e27, 0x000 },
6416 { 0x00000017, 0x00803627, 0x000 },
6417 { 0x00000017, 0x00201e2d, 0x000 },
6418 { 0xfffffffb, 0x00281e27, 0x000 },
6419 { 0x00000017, 0x00803627, 0x000 },
6420 { 0x00000017, 0x00201e2d, 0x000 },
6421 { 0x00000008, 0x00291e27, 0x000 },
6422 { 0x00000017, 0x00803627, 0x000 },
6423 { 0x00000017, 0x00201e2d, 0x000 },
6424 { 0xfffffff7, 0x00281e27, 0x000 },
6425 { 0x00000017, 0x00803627, 0x000 },
6426 { 0x00002010, 0x00204411, 0x000 },
6427 { 0x00008000, 0x00204811, 0x000 },
6428 { 0x0001a2a4, 0x00204411, 0x000 },
6429 { 0x00000016, 0x00604811, 0x36e },
6430 { 0x00002010, 0x00204411, 0x000 },
6431 { 0x00010000, 0x00204811, 0x000 },
6432 { 0x0000217c, 0x00204411, 0x000 },
6433 { 0x01800000, 0x00204811, 0x000 },
6434 { 0xffffffff, 0x00204811, 0x000 },
6435 { 0x00000000, 0x00204811, 0x000 },
6436 { 0x00000000, 0x17000000, 0x000 },
6437 { 0x81000000, 0x00204411, 0x000 },
6438 { 0x00000001, 0x00204811, 0x000 },
6439 { 0x0004217f, 0x00604411, 0x68d },
6440 { 0x0000001f, 0x00210230, 0x000 },
6441 { 0x00000000, 0x14c00000, 0x68c },
6442 { 0x00000010, 0x00404c11, 0x672 },
6443 { 0x00000000, 0xc0200400, 0x000 },
6444 { 0x00000000, 0x38c00000, 0x000 },
6445 { 0x0000001d, 0x00200a2d, 0x000 },
6446 { 0x0000001e, 0x00200e2d, 0x000 },
6447 { 0x0000001f, 0x0020122d, 0x000 },
6448 { 0x00000020, 0x0020162d, 0x000 },
6449 { 0x00002169, 0x00204411, 0x000 },
6450 { 0x00000000, 0x00204804, 0x000 },
6451 { 0x00000000, 0x00204805, 0x000 },
6452 { 0x00000000, 0x00204801, 0x000 },
6453 { 0xcafebabe, 0x00204811, 0x000 },
6454 { 0x00000004, 0x00301224, 0x000 },
6455 { 0x00000000, 0x002f0064, 0x000 },
6456 { 0x00000000, 0x0cc00000, 0x68b },
6457 { 0x00000003, 0x00281a22, 0x000 },
6458 { 0x00000008, 0x00221222, 0x000 },
6459 { 0xfffff000, 0x00281224, 0x000 },
6460 { 0x00000000, 0x002910c4, 0x000 },
6461 { 0x0000001f, 0x00403624, 0x000 },
6462 { 0x00000000, 0x00800000, 0x000 },
6463 { 0x00000000, 0x1ac00000, 0x68d },
6464 { 0x9f000000, 0x00204411, 0x000 },
6465 { 0xcafebabe, 0x00204811, 0x000 },
6466 { 0x00000000, 0x1ae00000, 0x690 },
6467 { 0x00000000, 0x00800000, 0x000 },
6468 { 0x00000000, 0x1ac00000, 0x692 },
6469 { 0x9e000000, 0x00204411, 0x000 },
6470 { 0xcafebabe, 0x00204811, 0x000 },
6471 { 0x00000000, 0x1ae00000, 0x695 },
6472 { 0x00000000, 0x00800000, 0x000 },
6473 { 0x00000000, 0x00600000, 0x00b },
6474 { 0x00001000, 0x00600411, 0x315 },
6475 { 0x00000000, 0x00200411, 0x000 },
6476 { 0x00000000, 0x00600811, 0x1b2 },
6477 { 0x0000225c, 0x00204411, 0x000 },
6478 { 0x00000003, 0x00204811, 0x000 },
6479 { 0x00002256, 0x00204411, 0x000 },
6480 { 0x0000001b, 0x00204811, 0x000 },
6481 { 0x0000a1fc, 0x00204411, 0x000 },
6482 { 0x00000001, 0x00204811, 0x000 },
6483 { 0x0001a1fd, 0xc0204411, 0x000 },
6484 { 0x00000021, 0x00201e2d, 0x000 },
6485 { 0x00000010, 0x00221e27, 0x000 },
6486 { 0x00000024, 0x0020222d, 0x000 },
6487 { 0x0000ffff, 0x00282228, 0x000 },
6488 { 0x00000000, 0x00294907, 0x000 },
6489 { 0x00000000, 0x00204811, 0x000 },
6490 { 0x00000022, 0x0020222d, 0x000 },
6491 { 0x0000ffff, 0x00282228, 0x000 },
6492 { 0x00000000, 0x00294907, 0x000 },
6493 { 0x00000000, 0x00204811, 0x000 },
6494 { 0x00000023, 0x00201e2d, 0x000 },
6495 { 0x00000010, 0x00221e27, 0x000 },
6496 { 0x00000000, 0x00294907, 0x000 },
6497 { 0x00000000, 0x00404811, 0x000 },
6498 { 0x00000000, 0x00000000, 0x000 },
6499 { 0x00000000, 0x00000000, 0x000 },
6500 { 0x00000000, 0x00000000, 0x000 },
6501 { 0x00000000, 0x00000000, 0x000 },
6502 { 0x00000000, 0x00000000, 0x000 },
6503 { 0x00000000, 0x00000000, 0x000 },
6504 { 0x00000000, 0x00000000, 0x000 },
6505 { 0x00000000, 0x00000000, 0x000 },
6506 { 0x00000000, 0x00000000, 0x000 },
6507 { 0x00000000, 0x00000000, 0x000 },
6508 { 0x00000000, 0x00000000, 0x000 },
6509 { 0x00000000, 0x00000000, 0x000 },
6510 { 0x00000000, 0x00000000, 0x000 },
6511 { 0x00000000, 0x00000000, 0x000 },
6512 { 0x00000000, 0x00000000, 0x000 },
6513 { 0x00000000, 0x00000000, 0x000 },
6514 { 0x00000000, 0x00000000, 0x000 },
6515 { 0x00000000, 0x00000000, 0x000 },
6516 { 0x00000000, 0x00000000, 0x000 },
6517 { 0x00000000, 0x00000000, 0x000 },
6518 { 0x00000000, 0x00000000, 0x000 },
6519 { 0x00000000, 0x00000000, 0x000 },
6520 { 0x00000000, 0x00000000, 0x000 },
6521 { 0x00000000, 0x00000000, 0x000 },
6522 { 0x00000000, 0x00000000, 0x000 },
6523 { 0x00000000, 0x00000000, 0x000 },
6524 { 0x00000000, 0x00000000, 0x000 },
6525 { 0x00000000, 0x00000000, 0x000 },
6526 { 0x00000000, 0x00000000, 0x000 },
6527 { 0x00000000, 0x00000000, 0x000 },
6528 { 0x00000000, 0x00000000, 0x000 },
6529 { 0x00000000, 0x00000000, 0x000 },
6530 { 0x00000000, 0x00000000, 0x000 },
6531 { 0x00000000, 0x00000000, 0x000 },
6532 { 0x00000000, 0x00000000, 0x000 },
6533 { 0x00000000, 0x00000000, 0x000 },
6534 { 0x00000000, 0x00000000, 0x000 },
6535 { 0x00000000, 0x00000000, 0x000 },
6536 { 0x00000000, 0x00000000, 0x000 },
6537 { 0x00000000, 0x00000000, 0x000 },
6538 { 0x00000000, 0x00000000, 0x000 },
6539 { 0x00000000, 0x00000000, 0x000 },
6540 { 0x00000000, 0x00000000, 0x000 },
6541 { 0x00000000, 0x00000000, 0x000 },
6542 { 0x00000000, 0x00000000, 0x000 },
6543 { 0x00000000, 0x00000000, 0x000 },
6544 { 0x00000000, 0x00000000, 0x000 },
6545 { 0x00000000, 0x00000000, 0x000 },
6546 { 0x00000000, 0x00000000, 0x000 },
6547 { 0x00000000, 0x00000000, 0x000 },
6548 { 0x00000000, 0x00000000, 0x000 },
6549 { 0x00000000, 0x00000000, 0x000 },
6550 { 0x01420502, 0x05c00250, 0x000 },
6551 { 0x01c30168, 0x043f05c0, 0x000 },
6552 { 0x02250209, 0x02500151, 0x000 },
6553 { 0x02230245, 0x02a00241, 0x000 },
6554 { 0x03d705c0, 0x05c005c0, 0x000 },
6555 { 0x0649064a, 0x031f05c0, 0x000 },
6556 { 0x05c005c5, 0x03200340, 0x000 },
6557 { 0x032a0282, 0x03420334, 0x000 },
6558 { 0x05c005c0, 0x05c005c0, 0x000 },
6559 { 0x05c00551, 0x05c005c0, 0x000 },
6560 { 0x03ba05c0, 0x04bb0344, 0x000 },
6561 { 0x049a0450, 0x043d05c0, 0x000 },
6562 { 0x04d005c0, 0x044104dd, 0x000 },
6563 { 0x04500507, 0x03510375, 0x000 },
6564 { 0x05c005c0, 0x05c005c0, 0x000 },
6565 { 0x05c005c0, 0x05c005c0, 0x000 },
6566 { 0x05c005c0, 0x063f05c7, 0x000 },
6567 { 0x05c005c0, 0x000705c0, 0x000 },
6568 { 0x05c005c0, 0x05c005c0, 0x000 },
6569 { 0x05c005c0, 0x05c005c0, 0x000 },
6570 { 0x03f803ed, 0x04080406, 0x000 },
6571 { 0x040e040a, 0x040c0410, 0x000 },
6572 { 0x041c0418, 0x04240420, 0x000 },
6573 { 0x042c0428, 0x04340430, 0x000 },
6574 { 0x05c005c0, 0x043805c0, 0x000 },
6575 { 0x05c005c0, 0x05c005c0, 0x000 },
6576 { 0x05c005c0, 0x05c005c0, 0x000 },
6577 { 0x00020679, 0x06970006, 0x000 },
6578};
6579
6580static const u32 RV620_pfp_microcode[] = {
65810xca0400,
65820xa00000,
65830x7e828b,
65840x7c038b,
65850x8001b8,
65860x7c038b,
65870xd4401e,
65880xee001e,
65890xca0400,
65900xa00000,
65910x7e828b,
65920xc41838,
65930xca2400,
65940xca2800,
65950x9581a8,
65960xc41c3a,
65970xc3c000,
65980xca0800,
65990xca0c00,
66000x7c744b,
66010xc20005,
66020x99c000,
66030xc41c3a,
66040x7c744c,
66050xc0fff0,
66060x042c04,
66070x309002,
66080x7d2500,
66090x351402,
66100x7d350b,
66110x255403,
66120x7cd580,
66130x259c03,
66140x95c004,
66150xd5001b,
66160x7eddc1,
66170x7d9d80,
66180xd6801b,
66190xd5801b,
66200xd4401e,
66210xd5401e,
66220xd6401e,
66230xd6801e,
66240xd4801e,
66250xd4c01e,
66260x9783d3,
66270xd5c01e,
66280xca0800,
66290x80001a,
66300xca0c00,
66310xe4011e,
66320xd4001e,
66330x80000c,
66340xc41838,
66350xe4013e,
66360xd4001e,
66370x80000c,
66380xc41838,
66390xd4401e,
66400xee001e,
66410xca0400,
66420xa00000,
66430x7e828b,
66440xe4011e,
66450xd4001e,
66460xd4401e,
66470xee001e,
66480xca0400,
66490xa00000,
66500x7e828b,
66510xe4013e,
66520xd4001e,
66530xd4401e,
66540xee001e,
66550xca0400,
66560xa00000,
66570x7e828b,
66580xca1800,
66590xd4401e,
66600xd5801e,
66610x800053,
66620xd40075,
66630xd4401e,
66640xca0800,
66650xca0c00,
66660xca1000,
66670xd48019,
66680xd4c018,
66690xd50017,
66700xd4801e,
66710xd4c01e,
66720xd5001e,
66730xe2001e,
66740xca0400,
66750xa00000,
66760x7e828b,
66770xca0800,
66780xd48060,
66790xd4401e,
66800x800000,
66810xd4801e,
66820xca0800,
66830xd48061,
66840xd4401e,
66850x800000,
66860xd4801e,
66870xca0800,
66880xca0c00,
66890xd4401e,
66900xd48016,
66910xd4c016,
66920xd4801e,
66930x8001b8,
66940xd4c01e,
66950xc60843,
66960xca0c00,
66970xca1000,
66980x948004,
66990xca1400,
67000xe420f3,
67010xd42013,
67020xd56065,
67030xd4e01c,
67040xd5201c,
67050xd5601c,
67060x800000,
67070x062001,
67080xc60843,
67090xca0c00,
67100xca1000,
67110x9483f7,
67120xca1400,
67130xe420f3,
67140x800079,
67150xd42013,
67160xc60843,
67170xca0c00,
67180xca1000,
67190x9883ef,
67200xca1400,
67210xd40064,
67220x80008d,
67230x000000,
67240xc41432,
67250xc61843,
67260xc4082f,
67270x954005,
67280xc40c30,
67290xd4401e,
67300x800000,
67310xee001e,
67320x9583f5,
67330xc41031,
67340xd44033,
67350xd52065,
67360xd4a01c,
67370xd4e01c,
67380xd5201c,
67390xe4015e,
67400xd4001e,
67410x800000,
67420x062001,
67430xca1800,
67440x0a2001,
67450xd60076,
67460xc40836,
67470x988007,
67480xc61045,
67490x950110,
67500xd4001f,
67510xd46062,
67520x800000,
67530xd42062,
67540xcc3835,
67550xcc1433,
67560x8401bb,
67570xd40072,
67580xd5401e,
67590x800000,
67600xee001e,
67610xe2001a,
67620x8401bb,
67630xe2001a,
67640xcc104b,
67650xcc0447,
67660x2c9401,
67670x7d098b,
67680x984005,
67690x7d15cb,
67700xd4001a,
67710x8001b8,
67720xd4006d,
67730x344401,
67740xcc0c48,
67750x98403a,
67760xcc2c4a,
67770x958004,
67780xcc0449,
67790x8001b8,
67800xd4001a,
67810xd4c01a,
67820x282801,
67830x8400f0,
67840xcc1003,
67850x98801b,
67860x04380c,
67870x8400f0,
67880xcc1003,
67890x988017,
67900x043808,
67910x8400f0,
67920xcc1003,
67930x988013,
67940x043804,
67950x8400f0,
67960xcc1003,
67970x988014,
67980xcc104c,
67990x9a8009,
68000xcc144d,
68010x9840dc,
68020xd4006d,
68030xcc1848,
68040xd5001a,
68050xd5401a,
68060x8000c9,
68070xd5801a,
68080x96c0d5,
68090xd4006d,
68100x8001b8,
68110xd4006e,
68120x9ac003,
68130xd4006d,
68140xd4006e,
68150x800000,
68160xec007f,
68170x9ac0cc,
68180xd4006d,
68190x8001b8,
68200xd4006e,
68210xcc1403,
68220xcc1803,
68230xcc1c03,
68240x7d9103,
68250x7dd583,
68260x7d190c,
68270x35cc1f,
68280x35701f,
68290x7cf0cb,
68300x7cd08b,
68310x880000,
68320x7e8e8b,
68330x95c004,
68340xd4006e,
68350x8001b8,
68360xd4001a,
68370xd4c01a,
68380xcc0803,
68390xcc0c03,
68400xcc1003,
68410xcc1403,
68420xcc1803,
68430xcc1c03,
68440xcc2403,
68450xcc2803,
68460x35c41f,
68470x36b01f,
68480x7c704b,
68490x34f01f,
68500x7c704b,
68510x35701f,
68520x7c704b,
68530x7d8881,
68540x7dccc1,
68550x7e5101,
68560x7e9541,
68570x7c9082,
68580x7cd4c2,
68590x7c848b,
68600x9ac003,
68610x7c8c8b,
68620x2c8801,
68630x98809e,
68640xd4006d,
68650x98409c,
68660xd4006e,
68670xcc084c,
68680xcc0c4d,
68690xcc1048,
68700xd4801a,
68710xd4c01a,
68720x800101,
68730xd5001a,
68740xcc0832,
68750xd40032,
68760x9482d9,
68770xca0c00,
68780xd4401e,
68790x800000,
68800xd4001e,
68810xe4011e,
68820xd4001e,
68830xca0800,
68840xca0c00,
68850xca1000,
68860xd4401e,
68870xca1400,
68880xd4801e,
68890xd4c01e,
68900xd5001e,
68910xd5401e,
68920xd54034,
68930x800000,
68940xee001e,
68950x280404,
68960xe2001a,
68970xe2001a,
68980xd4401a,
68990xca3800,
69000xcc0803,
69010xcc0c03,
69020xcc0c03,
69030xcc0c03,
69040x9882bd,
69050x000000,
69060x8401bb,
69070xd7a06f,
69080x800000,
69090xee001f,
69100xca0400,
69110xc2ff00,
69120xcc0834,
69130xc13fff,
69140x7c74cb,
69150x7cc90b,
69160x7d010f,
69170x9902b0,
69180x7c738b,
69190x8401bb,
69200xd7a06f,
69210x800000,
69220xee001f,
69230xca0800,
69240x281900,
69250x7d898b,
69260x958014,
69270x281404,
69280xca0c00,
69290xca1000,
69300xca1c00,
69310xca2400,
69320xe2001f,
69330xd4c01a,
69340xd5001a,
69350xd5401a,
69360xcc1803,
69370xcc2c03,
69380xcc2c03,
69390xcc2c03,
69400x7da58b,
69410x7d9c47,
69420x984297,
69430x000000,
69440x800161,
69450xd4c01a,
69460xd4401e,
69470xd4801e,
69480x800000,
69490xee001e,
69500xe4011e,
69510xd4001e,
69520xd4401e,
69530xee001e,
69540xca0400,
69550xa00000,
69560x7e828b,
69570xe4013e,
69580xd4001e,
69590xd4401e,
69600xee001e,
69610xca0400,
69620xa00000,
69630x7e828b,
69640xca0800,
69650x248c06,
69660x0ccc06,
69670x98c006,
69680xcc104e,
69690x990004,
69700xd40073,
69710xe4011e,
69720xd4001e,
69730xd4401e,
69740xd4801e,
69750x800000,
69760xee001e,
69770xca0800,
69780xca0c00,
69790x34d018,
69800x251001,
69810x950021,
69820xc17fff,
69830xca1000,
69840xca1400,
69850xca1800,
69860xd4801d,
69870xd4c01d,
69880x7db18b,
69890xc14202,
69900xc2c001,
69910xd5801d,
69920x34dc0e,
69930x7d5d4c,
69940x7f734c,
69950xd7401e,
69960xd5001e,
69970xd5401e,
69980xc14200,
69990xc2c000,
70000x099c01,
70010x31dc10,
70020x7f5f4c,
70030x7f734c,
70040x042802,
70050x7d8380,
70060xd5a86f,
70070xd58066,
70080xd7401e,
70090xec005e,
70100xc82402,
70110xc82402,
70120x8001b8,
70130xd60076,
70140xd4401e,
70150xd4801e,
70160xd4c01e,
70170x800000,
70180xee001e,
70190x800000,
70200xee001f,
70210xd4001f,
70220x800000,
70230xd4001f,
70240xd4001f,
70250x880000,
70260xd4001f,
70270x000000,
70280x000000,
70290x000000,
70300x000000,
70310x000000,
70320x000000,
70330x000000,
70340x000000,
70350x000000,
70360x000000,
70370x000000,
70380x000000,
70390x000000,
70400x000000,
70410x000000,
70420x000000,
70430x000000,
70440x000000,
70450x000000,
70460x000000,
70470x000000,
70480x000000,
70490x000000,
70500x000000,
70510x000000,
70520x000000,
70530x000000,
70540x000000,
70550x000000,
70560x000000,
70570x000000,
70580x000000,
70590x000000,
70600x000000,
70610x000000,
70620x000000,
70630x000000,
70640x000000,
70650x000000,
70660x000000,
70670x000000,
70680x000000,
70690x000000,
70700x000000,
70710x000000,
70720x000000,
70730x000000,
70740x000000,
70750x000000,
70760x000000,
70770x000000,
70780x000000,
70790x000000,
70800x000000,
70810x000000,
70820x000000,
70830x000000,
70840x000000,
70850x000000,
70860x000000,
70870x000000,
70880x000000,
70890x000000,
70900x000000,
70910x000000,
70920x000000,
70930x010171,
70940x020178,
70950x03008f,
70960x04007f,
70970x050003,
70980x06003f,
70990x070032,
71000x08012c,
71010x090046,
71020x0a0036,
71030x1001b6,
71040x1700a2,
71050x22013a,
71060x230149,
71070x2000b4,
71080x240125,
71090x27004d,
71100x28006a,
71110x2a0060,
71120x2b0052,
71130x2f0065,
71140x320087,
71150x34017f,
71160x3c0156,
71170x3f0072,
71180x41018c,
71190x44012e,
71200x550173,
71210x56017a,
71220x60000b,
71230x610034,
71240x620038,
71250x630038,
71260x640038,
71270x650038,
71280x660038,
71290x670038,
71300x68003a,
71310x690041,
71320x6a0048,
71330x6b0048,
71340x6c0048,
71350x6d0048,
71360x6e0048,
71370x6f0048,
71380x000006,
71390x000006,
71400x000006,
71410x000006,
71420x000006,
71430x000006,
71440x000006,
71450x000006,
71460x000006,
71470x000006,
71480x000006,
71490x000006,
71500x000006,
71510x000006,
71520x000006,
71530x000006,
71540x000006,
71550x000006,
71560x000006,
7157};
7158
7159static const u32 RV630_cp_microcode[][3] = {
7160 { 0x00000000, 0xc0200400, 0x000 },
7161 { 0x00000000, 0x00a0000a, 0x000 },
7162 { 0x0000ffff, 0x00284621, 0x000 },
7163 { 0x00000000, 0xd9004800, 0x000 },
7164 { 0x00000000, 0xc0200400, 0x000 },
7165 { 0x00000000, 0x00a0000a, 0x000 },
7166 { 0x00000000, 0x00e00000, 0x000 },
7167 { 0x00010000, 0xc0294620, 0x000 },
7168 { 0x00000000, 0xd9004800, 0x000 },
7169 { 0x00000000, 0xc0200400, 0x000 },
7170 { 0x00000000, 0x00a0000a, 0x000 },
7171 { 0x81000000, 0x00204411, 0x000 },
7172 { 0x00000001, 0x00204811, 0x000 },
7173 { 0x00042004, 0x00604411, 0x68a },
7174 { 0x00000000, 0x00600000, 0x62e },
7175 { 0x00000000, 0x00600000, 0x642 },
7176 { 0x00000000, 0xc0200800, 0x000 },
7177 { 0x00000f00, 0x00281622, 0x000 },
7178 { 0x00000008, 0x00211625, 0x000 },
7179 { 0x00000018, 0x00203625, 0x000 },
7180 { 0x8d000000, 0x00204411, 0x000 },
7181 { 0x00000004, 0x002f0225, 0x000 },
7182 { 0x00000000, 0x0ce00000, 0x018 },
7183 { 0x00412000, 0x00404811, 0x019 },
7184 { 0x00422000, 0x00204811, 0x000 },
7185 { 0x8e000000, 0x00204411, 0x000 },
7186 { 0x00000028, 0x00204a2d, 0x000 },
7187 { 0x90000000, 0x00204411, 0x000 },
7188 { 0x00000000, 0x00204805, 0x000 },
7189 { 0x0000000c, 0x00211622, 0x000 },
7190 { 0x00000003, 0x00281625, 0x000 },
7191 { 0x00000019, 0x00211a22, 0x000 },
7192 { 0x00000004, 0x00281a26, 0x000 },
7193 { 0x00000000, 0x002914c5, 0x000 },
7194 { 0x00000019, 0x00203625, 0x000 },
7195 { 0x00000000, 0x003a1402, 0x000 },
7196 { 0x00000016, 0x00211625, 0x000 },
7197 { 0x00000003, 0x00281625, 0x000 },
7198 { 0x00000017, 0x00200e2d, 0x000 },
7199 { 0xfffffffc, 0x00280e23, 0x000 },
7200 { 0x00000000, 0x002914a3, 0x000 },
7201 { 0x00000017, 0x00203625, 0x000 },
7202 { 0x00008000, 0x00280e22, 0x000 },
7203 { 0x00000007, 0x00220e23, 0x000 },
7204 { 0x00000000, 0x0029386e, 0x000 },
7205 { 0x20000000, 0x00280e22, 0x000 },
7206 { 0x00000006, 0x00210e23, 0x000 },
7207 { 0x00000000, 0x0029386e, 0x000 },
7208 { 0x00000000, 0x00220222, 0x000 },
7209 { 0x00000000, 0x14e00000, 0x038 },
7210 { 0x00000000, 0x2ee00000, 0x035 },
7211 { 0x00000000, 0x2ce00000, 0x037 },
7212 { 0x00000000, 0x00400e2d, 0x039 },
7213 { 0x00000008, 0x00200e2d, 0x000 },
7214 { 0x00000009, 0x0040122d, 0x046 },
7215 { 0x00000001, 0x00400e2d, 0x039 },
7216 { 0x00000000, 0xc0200c00, 0x000 },
7217 { 0x003ffffc, 0x00281223, 0x000 },
7218 { 0x00000002, 0x00221224, 0x000 },
7219 { 0x0000001f, 0x00211e23, 0x000 },
7220 { 0x00000000, 0x14e00000, 0x03e },
7221 { 0x00000008, 0x00401c11, 0x041 },
7222 { 0x0000000d, 0x00201e2d, 0x000 },
7223 { 0x0000000f, 0x00281e27, 0x000 },
7224 { 0x00000003, 0x00221e27, 0x000 },
7225 { 0x7fc00000, 0x00281a23, 0x000 },
7226 { 0x00000014, 0x00211a26, 0x000 },
7227 { 0x00000001, 0x00331a26, 0x000 },
7228 { 0x00000008, 0x00221a26, 0x000 },
7229 { 0x00000000, 0x00290cc7, 0x000 },
7230 { 0x00000027, 0x00203624, 0x000 },
7231 { 0x00007f00, 0x00281221, 0x000 },
7232 { 0x00001400, 0x002f0224, 0x000 },
7233 { 0x00000000, 0x0ce00000, 0x04b },
7234 { 0x00000001, 0x00290e23, 0x000 },
7235 { 0x0000000e, 0x00203623, 0x000 },
7236 { 0x0000e000, 0x00204411, 0x000 },
7237 { 0xfff80000, 0x00294a23, 0x000 },
7238 { 0x00000000, 0x003a2c02, 0x000 },
7239 { 0x00000002, 0x00220e2b, 0x000 },
7240 { 0xfc000000, 0x00280e23, 0x000 },
7241 { 0x0000000f, 0x00203623, 0x000 },
7242 { 0x00001fff, 0x00294a23, 0x000 },
7243 { 0x00000027, 0x00204a2d, 0x000 },
7244 { 0x00000000, 0x00204811, 0x000 },
7245 { 0x00000029, 0x00200e2d, 0x000 },
7246 { 0x060a0200, 0x00294a23, 0x000 },
7247 { 0x00000000, 0x00204811, 0x000 },
7248 { 0x00000000, 0x00204811, 0x000 },
7249 { 0x00000001, 0x00210222, 0x000 },
7250 { 0x00000000, 0x14e00000, 0x061 },
7251 { 0x00000000, 0x2ee00000, 0x05f },
7252 { 0x00000000, 0x2ce00000, 0x05e },
7253 { 0x00000000, 0x00400e2d, 0x062 },
7254 { 0x00000001, 0x00400e2d, 0x062 },
7255 { 0x0000000a, 0x00200e2d, 0x000 },
7256 { 0x0000000b, 0x0040122d, 0x06a },
7257 { 0x00000000, 0xc0200c00, 0x000 },
7258 { 0x003ffffc, 0x00281223, 0x000 },
7259 { 0x00000002, 0x00221224, 0x000 },
7260 { 0x7fc00000, 0x00281623, 0x000 },
7261 { 0x00000014, 0x00211625, 0x000 },
7262 { 0x00000001, 0x00331625, 0x000 },
7263 { 0x80000000, 0x00280e23, 0x000 },
7264 { 0x00000000, 0x00290ca3, 0x000 },
7265 { 0x3ffffc00, 0x00290e23, 0x000 },
7266 { 0x0000001f, 0x00211e23, 0x000 },
7267 { 0x00000000, 0x14e00000, 0x06d },
7268 { 0x00000100, 0x00401c11, 0x070 },
7269 { 0x0000000d, 0x00201e2d, 0x000 },
7270 { 0x000000f0, 0x00281e27, 0x000 },
7271 { 0x00000004, 0x00221e27, 0x000 },
7272 { 0x81000000, 0x00204411, 0x000 },
7273 { 0x0000000d, 0x00204811, 0x000 },
7274 { 0xfffff0ff, 0x00281a30, 0x000 },
7275 { 0x0000a028, 0x00204411, 0x000 },
7276 { 0x00000000, 0x002948e6, 0x000 },
7277 { 0x0000a018, 0x00204411, 0x000 },
7278 { 0x3fffffff, 0x00284a23, 0x000 },
7279 { 0x0000a010, 0x00204411, 0x000 },
7280 { 0x00000000, 0x00204804, 0x000 },
7281 { 0x00000030, 0x0020162d, 0x000 },
7282 { 0x00000002, 0x00291625, 0x000 },
7283 { 0x00000030, 0x00203625, 0x000 },
7284 { 0x00000025, 0x0020162d, 0x000 },
7285 { 0x00000000, 0x002f00a3, 0x000 },
7286 { 0x00000000, 0x0cc00000, 0x083 },
7287 { 0x00000026, 0x0020162d, 0x000 },
7288 { 0x00000000, 0x002f00a4, 0x000 },
7289 { 0x00000000, 0x0cc00000, 0x084 },
7290 { 0x00000000, 0x00400000, 0x08a },
7291 { 0x00000025, 0x00203623, 0x000 },
7292 { 0x00000026, 0x00203624, 0x000 },
7293 { 0x00000017, 0x00201e2d, 0x000 },
7294 { 0x00000002, 0x00210227, 0x000 },
7295 { 0x00000000, 0x14e00000, 0x08a },
7296 { 0x00000000, 0x00600000, 0x665 },
7297 { 0x00000000, 0x00600000, 0x659 },
7298 { 0x00000002, 0x00210e22, 0x000 },
7299 { 0x00000000, 0x14c00000, 0x08d },
7300 { 0x00000012, 0xc0403620, 0x093 },
7301 { 0x00000000, 0x2ee00000, 0x091 },
7302 { 0x00000000, 0x2ce00000, 0x090 },
7303 { 0x00000002, 0x00400e2d, 0x092 },
7304 { 0x00000003, 0x00400e2d, 0x092 },
7305 { 0x0000000c, 0x00200e2d, 0x000 },
7306 { 0x00000012, 0x00203623, 0x000 },
7307 { 0x00000003, 0x00210e22, 0x000 },
7308 { 0x00000000, 0x14c00000, 0x098 },
7309 { 0x0000a00c, 0x00204411, 0x000 },
7310 { 0x00000000, 0xc0204800, 0x000 },
7311 { 0x00000000, 0xc0404800, 0x0a0 },
7312 { 0x0000a00c, 0x00204411, 0x000 },
7313 { 0x00000000, 0x00204811, 0x000 },
7314 { 0x00000000, 0x2ee00000, 0x09e },
7315 { 0x00000000, 0x2ce00000, 0x09d },
7316 { 0x00000002, 0x00400e2d, 0x09f },
7317 { 0x00000003, 0x00400e2d, 0x09f },
7318 { 0x0000000c, 0x00200e2d, 0x000 },
7319 { 0x00000000, 0x00204803, 0x000 },
7320 { 0x00000000, 0x003a0c02, 0x000 },
7321 { 0x003f0000, 0x00280e23, 0x000 },
7322 { 0x00000010, 0x00210e23, 0x000 },
7323 { 0x00000011, 0x00203623, 0x000 },
7324 { 0x0000001e, 0x0021022b, 0x000 },
7325 { 0x00000000, 0x14c00000, 0x0a7 },
7326 { 0x00000016, 0xc0203620, 0x000 },
7327 { 0x0000001f, 0x0021022b, 0x000 },
7328 { 0x00000000, 0x14c00000, 0x0aa },
7329 { 0x00000015, 0xc0203620, 0x000 },
7330 { 0x00000008, 0x00210e2b, 0x000 },
7331 { 0x0000007f, 0x00280e23, 0x000 },
7332 { 0x00000000, 0x002f0223, 0x000 },
7333 { 0x00000000, 0x0ce00000, 0x0e1 },
7334 { 0x00000000, 0x27000000, 0x000 },
7335 { 0x00000000, 0x00600000, 0x2a3 },
7336 { 0x00000001, 0x002f0223, 0x000 },
7337 { 0x00000000, 0x0ae00000, 0x0b3 },
7338 { 0x00000000, 0x00600000, 0x13a },
7339 { 0x81000000, 0x00204411, 0x000 },
7340 { 0x00000006, 0x00204811, 0x000 },
7341 { 0x0000000c, 0x00221e30, 0x000 },
7342 { 0x99800000, 0x00204411, 0x000 },
7343 { 0x00000004, 0x0020122d, 0x000 },
7344 { 0x00000008, 0x00221224, 0x000 },
7345 { 0x00000010, 0x00201811, 0x000 },
7346 { 0x00000000, 0x00291ce4, 0x000 },
7347 { 0x00000000, 0x00604807, 0x12f },
7348 { 0x9b000000, 0x00204411, 0x000 },
7349 { 0x00000000, 0x00204802, 0x000 },
7350 { 0x9c000000, 0x00204411, 0x000 },
7351 { 0x00000000, 0x0033146f, 0x000 },
7352 { 0x00000001, 0x00333e23, 0x000 },
7353 { 0x00000000, 0xd9004800, 0x000 },
7354 { 0x00000000, 0x00203c05, 0x000 },
7355 { 0x81000000, 0x00204411, 0x000 },
7356 { 0x0000000e, 0x00204811, 0x000 },
7357 { 0x00000000, 0x00201010, 0x000 },
7358 { 0x0000e007, 0x00204411, 0x000 },
7359 { 0x0000000f, 0x0021022b, 0x000 },
7360 { 0x00000000, 0x14c00000, 0x0cb },
7361 { 0x00f8ff08, 0x00204811, 0x000 },
7362 { 0x98000000, 0x00404811, 0x0dc },
7363 { 0x000000f0, 0x00280e22, 0x000 },
7364 { 0x000000a0, 0x002f0223, 0x000 },
7365 { 0x00000000, 0x0cc00000, 0x0da },
7366 { 0x00000011, 0x00200e2d, 0x000 },
7367 { 0x00000001, 0x002f0223, 0x000 },
7368 { 0x00000000, 0x0ce00000, 0x0d5 },
7369 { 0x00000002, 0x002f0223, 0x000 },
7370 { 0x00000000, 0x0ce00000, 0x0d4 },
7371 { 0x00003f00, 0x00400c11, 0x0d6 },
7372 { 0x00001f00, 0x00400c11, 0x0d6 },
7373 { 0x00000f00, 0x00200c11, 0x000 },
7374 { 0x00380009, 0x00294a23, 0x000 },
7375 { 0x3f000000, 0x00280e2b, 0x000 },
7376 { 0x00000002, 0x00220e23, 0x000 },
7377 { 0x00000007, 0x00494a23, 0x0dc },
7378 { 0x00380f09, 0x00204811, 0x000 },
7379 { 0x68000007, 0x00204811, 0x000 },
7380 { 0x00000008, 0x00214a27, 0x000 },
7381 { 0x00000000, 0x00204811, 0x000 },
7382 { 0x060a0200, 0x00294a24, 0x000 },
7383 { 0x00000000, 0x00204811, 0x000 },
7384 { 0x00000000, 0x00204811, 0x000 },
7385 { 0x0000a202, 0x00204411, 0x000 },
7386 { 0x00ff0000, 0x00280e22, 0x000 },
7387 { 0x00000080, 0x00294a23, 0x000 },
7388 { 0x00000027, 0x00200e2d, 0x000 },
7389 { 0x00000026, 0x0020122d, 0x000 },
7390 { 0x00000000, 0x002f0083, 0x000 },
7391 { 0x00000000, 0x0ce00000, 0x0ea },
7392 { 0x00000000, 0x00600000, 0x65f },
7393 { 0x00000000, 0x00400000, 0x0eb },
7394 { 0x00000000, 0x00600000, 0x662 },
7395 { 0x00000007, 0x0020222d, 0x000 },
7396 { 0x00000005, 0x00220e22, 0x000 },
7397 { 0x00100000, 0x00280e23, 0x000 },
7398 { 0x00000000, 0x00292068, 0x000 },
7399 { 0x00000000, 0x003a0c02, 0x000 },
7400 { 0x000000ef, 0x00280e23, 0x000 },
7401 { 0x00000000, 0x00292068, 0x000 },
7402 { 0x00000017, 0x00200e2d, 0x000 },
7403 { 0x00000003, 0x00210223, 0x000 },
7404 { 0x00000000, 0x14e00000, 0x0f8 },
7405 { 0x0000000b, 0x00210228, 0x000 },
7406 { 0x00000000, 0x14c00000, 0x0f8 },
7407 { 0x00000400, 0x00292228, 0x000 },
7408 { 0x00000014, 0x00203628, 0x000 },
7409 { 0x0000001c, 0x00210e22, 0x000 },
7410 { 0x00000000, 0x14c00000, 0x0fd },
7411 { 0x0000a30c, 0x00204411, 0x000 },
7412 { 0x00000000, 0x00204811, 0x000 },
7413 { 0x0000001e, 0x00210e22, 0x000 },
7414 { 0x00000000, 0x14c00000, 0x10b },
7415 { 0x0000a30f, 0x00204411, 0x000 },
7416 { 0x00000011, 0x00200e2d, 0x000 },
7417 { 0x00000001, 0x002f0223, 0x000 },
7418 { 0x00000000, 0x0cc00000, 0x104 },
7419 { 0xffffffff, 0x00404811, 0x10b },
7420 { 0x00000002, 0x002f0223, 0x000 },
7421 { 0x00000000, 0x0cc00000, 0x107 },
7422 { 0x0000ffff, 0x00404811, 0x10b },
7423 { 0x00000004, 0x002f0223, 0x000 },
7424 { 0x00000000, 0x0cc00000, 0x10a },
7425 { 0x000000ff, 0x00404811, 0x10b },
7426 { 0x00000001, 0x00204811, 0x000 },
7427 { 0x0002c400, 0x00204411, 0x000 },
7428 { 0x0000001f, 0x00210e22, 0x000 },
7429 { 0x00000000, 0x14c00000, 0x112 },
7430 { 0x00000010, 0x40210e20, 0x000 },
7431 { 0x00000013, 0x00203623, 0x000 },
7432 { 0x00000018, 0x40224a20, 0x000 },
7433 { 0x00000010, 0xc0424a20, 0x114 },
7434 { 0x00000000, 0x00200c11, 0x000 },
7435 { 0x00000013, 0x00203623, 0x000 },
7436 { 0x00000000, 0x00204811, 0x000 },
7437 { 0x00000000, 0x00204811, 0x000 },
7438 { 0x0000000a, 0x00201011, 0x000 },
7439 { 0x00000000, 0x002f0224, 0x000 },
7440 { 0x00000000, 0x0ce00000, 0x11b },
7441 { 0x00000000, 0x00204811, 0x000 },
7442 { 0x00000001, 0x00531224, 0x117 },
7443 { 0xffbfffff, 0x00283a2e, 0x000 },
7444 { 0x0000001b, 0x00210222, 0x000 },
7445 { 0x00000000, 0x14c00000, 0x12e },
7446 { 0x81000000, 0x00204411, 0x000 },
7447 { 0x0000000d, 0x00204811, 0x000 },
7448 { 0x00000018, 0x00220e30, 0x000 },
7449 { 0xfc000000, 0x00280e23, 0x000 },
7450 { 0x81000000, 0x00204411, 0x000 },
7451 { 0x0000000e, 0x00204811, 0x000 },
7452 { 0x00000000, 0x00201010, 0x000 },
7453 { 0x0000e00e, 0x00204411, 0x000 },
7454 { 0x07f8ff08, 0x00204811, 0x000 },
7455 { 0x00000000, 0x00294a23, 0x000 },
7456 { 0x0000001c, 0x00201e2d, 0x000 },
7457 { 0x00000008, 0x00214a27, 0x000 },
7458 { 0x00000000, 0x00204811, 0x000 },
7459 { 0x060a0200, 0x00294a24, 0x000 },
7460 { 0x00000000, 0x00204811, 0x000 },
7461 { 0x00000000, 0x00204811, 0x000 },
7462 { 0x00000000, 0x00800000, 0x000 },
7463 { 0x81000000, 0x00204411, 0x000 },
7464 { 0x00000001, 0x00204811, 0x000 },
7465 { 0x0000217c, 0x00204411, 0x000 },
7466 { 0x00800000, 0x00204811, 0x000 },
7467 { 0x00000000, 0x00204806, 0x000 },
7468 { 0x00000008, 0x00214a27, 0x000 },
7469 { 0x00000000, 0x17000000, 0x000 },
7470 { 0x0004217f, 0x00604411, 0x68a },
7471 { 0x0000001f, 0x00210230, 0x000 },
7472 { 0x00000000, 0x14c00000, 0x689 },
7473 { 0x00000004, 0x00404c11, 0x135 },
7474 { 0x81000000, 0x00204411, 0x000 },
7475 { 0x00000001, 0x00204811, 0x000 },
7476 { 0x000021f8, 0x00204411, 0x000 },
7477 { 0x0000001c, 0x00204811, 0x000 },
7478 { 0x000421f9, 0x00604411, 0x68a },
7479 { 0x00000011, 0x00210230, 0x000 },
7480 { 0x00000000, 0x14e00000, 0x13c },
7481 { 0x00000000, 0x00800000, 0x000 },
7482 { 0x00000000, 0x00600000, 0x00b },
7483 { 0x00000000, 0x00600411, 0x315 },
7484 { 0x00000000, 0x00200411, 0x000 },
7485 { 0x00000000, 0x00600811, 0x1b2 },
7486 { 0x00000000, 0x00600000, 0x160 },
7487 { 0x0000ffff, 0x40280e20, 0x000 },
7488 { 0x00000010, 0xc0211220, 0x000 },
7489 { 0x0000ffff, 0x40280620, 0x000 },
7490 { 0x00000010, 0xc0210a20, 0x000 },
7491 { 0x00000000, 0x00341461, 0x000 },
7492 { 0x00000000, 0x00741882, 0x2bb },
7493 { 0x0001a1fd, 0x00604411, 0x2e0 },
7494 { 0x00003fff, 0x002f022f, 0x000 },
7495 { 0x00000000, 0x0cc00000, 0x147 },
7496 { 0x00000000, 0xc0400400, 0x001 },
7497 { 0x00000000, 0x00600000, 0x00b },
7498 { 0x00000000, 0x00600411, 0x315 },
7499 { 0x00000000, 0x00200411, 0x000 },
7500 { 0x00000000, 0x00600811, 0x1b2 },
7501 { 0x00003fff, 0x002f022f, 0x000 },
7502 { 0x00000000, 0x0ce00000, 0x000 },
7503 { 0x00000000, 0x00600000, 0x160 },
7504 { 0x00000010, 0x40210e20, 0x000 },
7505 { 0x0000ffff, 0xc0281220, 0x000 },
7506 { 0x00000010, 0x40211620, 0x000 },
7507 { 0x0000ffff, 0xc0681a20, 0x2bb },
7508 { 0x0001a1fd, 0x00604411, 0x2e0 },
7509 { 0x00003fff, 0x002f022f, 0x000 },
7510 { 0x00000000, 0x0cc00000, 0x158 },
7511 { 0x00000000, 0xc0400400, 0x001 },
7512 { 0x0000225c, 0x00204411, 0x000 },
7513 { 0x00000001, 0x00300a2f, 0x000 },
7514 { 0x00000001, 0x00210a22, 0x000 },
7515 { 0x00000003, 0x00384a22, 0x000 },
7516 { 0x00002256, 0x00204411, 0x000 },
7517 { 0x0000001a, 0x00204811, 0x000 },
7518 { 0x0000a1fc, 0x00204411, 0x000 },
7519 { 0x00000001, 0x00804811, 0x000 },
7520 { 0x00000000, 0x00600000, 0x00b },
7521 { 0x00000000, 0x00600000, 0x18f },
7522 { 0x00000000, 0x00600000, 0x1a0 },
7523 { 0x00003fff, 0x002f022f, 0x000 },
7524 { 0x00000000, 0x0ce00000, 0x000 },
7525 { 0x00000000, 0x00202c08, 0x000 },
7526 { 0x00000000, 0x00202411, 0x000 },
7527 { 0x00000000, 0x00202811, 0x000 },
7528 { 0x00002256, 0x00204411, 0x000 },
7529 { 0x00000016, 0x00204811, 0x000 },
7530 { 0x0000225c, 0x00204411, 0x000 },
7531 { 0x00000003, 0x00204811, 0x000 },
7532 { 0x93800000, 0x00204411, 0x000 },
7533 { 0x00000002, 0x00221e29, 0x000 },
7534 { 0x00000000, 0x007048eb, 0x19c },
7535 { 0x00000000, 0x00600000, 0x2bb },
7536 { 0x00000001, 0x40330620, 0x000 },
7537 { 0x00000000, 0xc0302409, 0x000 },
7538 { 0x00003fff, 0x002f022f, 0x000 },
7539 { 0x00000000, 0x0ce00000, 0x000 },
7540 { 0x00000000, 0x00600000, 0x2a3 },
7541 { 0x00000000, 0x002f0221, 0x000 },
7542 { 0x00000000, 0x0ae00000, 0x181 },
7543 { 0x00000000, 0x00600000, 0x13a },
7544 { 0x00000000, 0x00400000, 0x186 },
7545 { 0x95000000, 0x00204411, 0x000 },
7546 { 0x00000000, 0x002f0221, 0x000 },
7547 { 0x00000000, 0x0ce00000, 0x186 },
7548 { 0x00000000, 0xc0204800, 0x000 },
7549 { 0x00000001, 0x00530621, 0x182 },
7550 { 0x92000000, 0x00204411, 0x000 },
7551 { 0x00000000, 0xc0604800, 0x197 },
7552 { 0x0001a1fd, 0x00204411, 0x000 },
7553 { 0x00000011, 0x0020062d, 0x000 },
7554 { 0x00000000, 0x0078042a, 0x2fb },
7555 { 0x00000000, 0x00202809, 0x000 },
7556 { 0x00003fff, 0x002f022f, 0x000 },
7557 { 0x00000000, 0x0cc00000, 0x174 },
7558 { 0x00000000, 0xc0400400, 0x001 },
7559 { 0x00000210, 0x00600411, 0x315 },
7560 { 0x00003fff, 0x002f022f, 0x000 },
7561 { 0x00000000, 0x0ce00000, 0x194 },
7562 { 0x00000015, 0xc0203620, 0x000 },
7563 { 0x00000016, 0xc0203620, 0x000 },
7564 { 0x3f800000, 0x00200411, 0x000 },
7565 { 0x46000000, 0x00600811, 0x1b2 },
7566 { 0x00000000, 0x00800000, 0x000 },
7567 { 0x0000a1fc, 0x00204411, 0x000 },
7568 { 0x00003fff, 0x002f022f, 0x000 },
7569 { 0x00000000, 0x0cc00000, 0x19b },
7570 { 0x00000001, 0x00804811, 0x000 },
7571 { 0x00000021, 0x00804811, 0x000 },
7572 { 0x0000ffff, 0x40280e20, 0x000 },
7573 { 0x00000010, 0xc0211220, 0x000 },
7574 { 0x0000ffff, 0x40281620, 0x000 },
7575 { 0x00000010, 0xc0811a20, 0x000 },
7576 { 0x81000000, 0x00204411, 0x000 },
7577 { 0x00000006, 0x00204811, 0x000 },
7578 { 0x00000008, 0x00221e30, 0x000 },
7579 { 0x00000029, 0x00201a2d, 0x000 },
7580 { 0x0000e000, 0x00204411, 0x000 },
7581 { 0xfffbff09, 0x00204811, 0x000 },
7582 { 0x0000000f, 0x0020222d, 0x000 },
7583 { 0x00001fff, 0x00294a28, 0x000 },
7584 { 0x00000006, 0x0020222d, 0x000 },
7585 { 0x00000000, 0x002920e8, 0x000 },
7586 { 0x00000000, 0x00204808, 0x000 },
7587 { 0x00000000, 0x00204811, 0x000 },
7588 { 0x060a0200, 0x00294a26, 0x000 },
7589 { 0x00000000, 0x00204811, 0x000 },
7590 { 0x00000000, 0x00204811, 0x000 },
7591 { 0x00000100, 0x00201811, 0x000 },
7592 { 0x00000008, 0x00621e28, 0x12f },
7593 { 0x00000008, 0x00822228, 0x000 },
7594 { 0x0002c000, 0x00204411, 0x000 },
7595 { 0x00000015, 0x00600e2d, 0x1bd },
7596 { 0x00000016, 0x00600e2d, 0x1bd },
7597 { 0x0000c008, 0x00204411, 0x000 },
7598 { 0x00000017, 0x00200e2d, 0x000 },
7599 { 0x00000000, 0x14c00000, 0x1b9 },
7600 { 0x00000000, 0x00200411, 0x000 },
7601 { 0x00000000, 0x00204801, 0x000 },
7602 { 0x39000000, 0x00204811, 0x000 },
7603 { 0x00000000, 0x00204811, 0x000 },
7604 { 0x00000000, 0x00804802, 0x000 },
7605 { 0x00000018, 0x00202e2d, 0x000 },
7606 { 0x00000000, 0x003b0d63, 0x000 },
7607 { 0x00000008, 0x00224a23, 0x000 },
7608 { 0x00000010, 0x00224a23, 0x000 },
7609 { 0x00000018, 0x00224a23, 0x000 },
7610 { 0x00000000, 0x00804803, 0x000 },
7611 { 0x00000000, 0x00600000, 0x00b },
7612 { 0x00001000, 0x00600411, 0x315 },
7613 { 0x00000000, 0x00200411, 0x000 },
7614 { 0x00000000, 0x00600811, 0x1b2 },
7615 { 0x00000007, 0x0021062f, 0x000 },
7616 { 0x00000013, 0x00200a2d, 0x000 },
7617 { 0x00000001, 0x00202c11, 0x000 },
7618 { 0x0000ffff, 0x40282220, 0x000 },
7619 { 0x0000000f, 0x00262228, 0x000 },
7620 { 0x00000010, 0x40212620, 0x000 },
7621 { 0x0000000f, 0x00262629, 0x000 },
7622 { 0x00000000, 0x00202802, 0x000 },
7623 { 0x00002256, 0x00204411, 0x000 },
7624 { 0x0000001b, 0x00204811, 0x000 },
7625 { 0x00000000, 0x002f0221, 0x000 },
7626 { 0x00000000, 0x0ce00000, 0x1e0 },
7627 { 0x0000225c, 0x00204411, 0x000 },
7628 { 0x00000081, 0x00204811, 0x000 },
7629 { 0x0000a1fc, 0x00204411, 0x000 },
7630 { 0x00000001, 0x00204811, 0x000 },
7631 { 0x00000080, 0x00201c11, 0x000 },
7632 { 0x00000000, 0x002f0227, 0x000 },
7633 { 0x00000000, 0x0ce00000, 0x1dc },
7634 { 0x00000000, 0x00600000, 0x1e9 },
7635 { 0x00000001, 0x00531e27, 0x1d8 },
7636 { 0x00000001, 0x00202c11, 0x000 },
7637 { 0x0000001f, 0x00280a22, 0x000 },
7638 { 0x0000001f, 0x00282a2a, 0x000 },
7639 { 0x00000001, 0x00530621, 0x1d1 },
7640 { 0x0000225c, 0x00204411, 0x000 },
7641 { 0x00000002, 0x00304a2f, 0x000 },
7642 { 0x0000a1fc, 0x00204411, 0x000 },
7643 { 0x00000001, 0x00204811, 0x000 },
7644 { 0x00000001, 0x00301e2f, 0x000 },
7645 { 0x00000000, 0x002f0227, 0x000 },
7646 { 0x00000000, 0x0ce00000, 0x000 },
7647 { 0x00000000, 0x00600000, 0x1e9 },
7648 { 0x00000001, 0x00531e27, 0x1e5 },
7649 { 0x0000ffff, 0x40280e20, 0x000 },
7650 { 0x0000000f, 0x00260e23, 0x000 },
7651 { 0x00000010, 0xc0211220, 0x000 },
7652 { 0x0000000f, 0x00261224, 0x000 },
7653 { 0x00000000, 0x00201411, 0x000 },
7654 { 0x00000000, 0x00601811, 0x2bb },
7655 { 0x0001a1fd, 0x00204411, 0x000 },
7656 { 0x00000000, 0x002f022b, 0x000 },
7657 { 0x00000000, 0x0ce00000, 0x1f8 },
7658 { 0x00000010, 0x00221628, 0x000 },
7659 { 0xffff0000, 0x00281625, 0x000 },
7660 { 0x0000ffff, 0x00281a29, 0x000 },
7661 { 0x00000000, 0x002948c5, 0x000 },
7662 { 0x00000000, 0x0020480a, 0x000 },
7663 { 0x00000000, 0x00202c11, 0x000 },
7664 { 0x00000010, 0x00221623, 0x000 },
7665 { 0xffff0000, 0x00281625, 0x000 },
7666 { 0x0000ffff, 0x00281a24, 0x000 },
7667 { 0x00000000, 0x002948c5, 0x000 },
7668 { 0x00000000, 0x00731503, 0x205 },
7669 { 0x00000000, 0x00201805, 0x000 },
7670 { 0x00000000, 0x00731524, 0x205 },
7671 { 0x00000000, 0x002d14c5, 0x000 },
7672 { 0x00000000, 0x003008a2, 0x000 },
7673 { 0x00000000, 0x00204802, 0x000 },
7674 { 0x00000000, 0x00202802, 0x000 },
7675 { 0x00000000, 0x00202003, 0x000 },
7676 { 0x00000000, 0x00802404, 0x000 },
7677 { 0x0000000f, 0x00210225, 0x000 },
7678 { 0x00000000, 0x14c00000, 0x689 },
7679 { 0x00000000, 0x002b1405, 0x000 },
7680 { 0x00000001, 0x00901625, 0x000 },
7681 { 0x00000000, 0x00600000, 0x00b },
7682 { 0x00000000, 0x00600411, 0x315 },
7683 { 0x00000000, 0x00200411, 0x000 },
7684 { 0x00000000, 0x00600811, 0x1b2 },
7685 { 0x00002256, 0x00204411, 0x000 },
7686 { 0x0000001a, 0x00294a22, 0x000 },
7687 { 0x00000000, 0xc0200000, 0x000 },
7688 { 0x00003fff, 0x002f022f, 0x000 },
7689 { 0x00000000, 0x0ce00000, 0x000 },
7690 { 0x00000000, 0xc0200400, 0x000 },
7691 { 0x0000225c, 0x00204411, 0x000 },
7692 { 0x00000003, 0x00384a21, 0x000 },
7693 { 0x0000a1fc, 0x00204411, 0x000 },
7694 { 0x00000001, 0x00204811, 0x000 },
7695 { 0x0000ffff, 0x40281220, 0x000 },
7696 { 0x00000010, 0xc0211a20, 0x000 },
7697 { 0x0000ffff, 0x40280e20, 0x000 },
7698 { 0x00000010, 0xc0211620, 0x000 },
7699 { 0x00000000, 0x00741465, 0x2bb },
7700 { 0x0001a1fd, 0x00604411, 0x2e0 },
7701 { 0x00000001, 0x00330621, 0x000 },
7702 { 0x00000000, 0x002f0221, 0x000 },
7703 { 0x00000000, 0x0cc00000, 0x219 },
7704 { 0x00003fff, 0x002f022f, 0x000 },
7705 { 0x00000000, 0x0cc00000, 0x212 },
7706 { 0x00000000, 0xc0400400, 0x001 },
7707 { 0x00000000, 0x00600000, 0x642 },
7708 { 0x00000000, 0x0040040f, 0x213 },
7709 { 0x00000000, 0x00600000, 0x62e },
7710 { 0x00000000, 0x00600000, 0x642 },
7711 { 0x00000210, 0x00600411, 0x315 },
7712 { 0x00000000, 0x00600000, 0x1a0 },
7713 { 0x00000000, 0x00600000, 0x19c },
7714 { 0x00000000, 0x00600000, 0x2bb },
7715 { 0x00000000, 0x00600000, 0x2a3 },
7716 { 0x93800000, 0x00204411, 0x000 },
7717 { 0x00000000, 0x00204808, 0x000 },
7718 { 0x00000000, 0x002f022f, 0x000 },
7719 { 0x00000000, 0x0ae00000, 0x232 },
7720 { 0x00000000, 0x00600000, 0x13a },
7721 { 0x00000000, 0x00400000, 0x236 },
7722 { 0x95000000, 0x00204411, 0x000 },
7723 { 0x00000000, 0x002f022f, 0x000 },
7724 { 0x00000000, 0x0ce00000, 0x236 },
7725 { 0x00000000, 0xc0404800, 0x233 },
7726 { 0x92000000, 0x00204411, 0x000 },
7727 { 0x00000000, 0xc0204800, 0x000 },
7728 { 0x00002256, 0x00204411, 0x000 },
7729 { 0x00000016, 0x00204811, 0x000 },
7730 { 0x0000225c, 0x00204411, 0x000 },
7731 { 0x00000003, 0x00204811, 0x000 },
7732 { 0x0000a1fc, 0x00204411, 0x000 },
7733 { 0x00000001, 0x00204811, 0x000 },
7734 { 0x0001a1fd, 0x00204411, 0x000 },
7735 { 0x00000000, 0x00600411, 0x2fb },
7736 { 0x00000000, 0xc0400400, 0x001 },
7737 { 0x00000000, 0x00600000, 0x62e },
7738 { 0x0000a00c, 0x00204411, 0x000 },
7739 { 0x00000000, 0xc0204800, 0x000 },
7740 { 0x00000000, 0xc0404800, 0x000 },
7741 { 0x00000000, 0x00600000, 0x00b },
7742 { 0x00000018, 0x40210a20, 0x000 },
7743 { 0x00000003, 0x002f0222, 0x000 },
7744 { 0x00000000, 0x0ae00000, 0x24c },
7745 { 0x00000014, 0x0020222d, 0x000 },
7746 { 0x00080101, 0x00292228, 0x000 },
7747 { 0x00000014, 0x00203628, 0x000 },
7748 { 0x0000a30c, 0x00204411, 0x000 },
7749 { 0x00000000, 0xc0204800, 0x000 },
7750 { 0x00000000, 0xc0204800, 0x000 },
7751 { 0x00000000, 0xc0404800, 0x251 },
7752 { 0x00000000, 0x00600000, 0x00b },
7753 { 0x00000010, 0x00600411, 0x315 },
7754 { 0x3f800000, 0x00200411, 0x000 },
7755 { 0x00000000, 0x00600811, 0x1b2 },
7756 { 0x0000225c, 0x00204411, 0x000 },
7757 { 0x00000003, 0x00204811, 0x000 },
7758 { 0x00000000, 0x00600000, 0x27c },
7759 { 0x00000017, 0x00201e2d, 0x000 },
7760 { 0x00000001, 0x00211e27, 0x000 },
7761 { 0x00000000, 0x14e00000, 0x26a },
7762 { 0x00000012, 0x00201e2d, 0x000 },
7763 { 0x0000ffff, 0x00281e27, 0x000 },
7764 { 0x00000000, 0x00341c27, 0x000 },
7765 { 0x00000000, 0x12c00000, 0x25f },
7766 { 0x00000000, 0x00201c11, 0x000 },
7767 { 0x00000000, 0x002f00e5, 0x000 },
7768 { 0x00000000, 0x08c00000, 0x262 },
7769 { 0x00000000, 0x00201407, 0x000 },
7770 { 0x00000012, 0x00201e2d, 0x000 },
7771 { 0x00000010, 0x00211e27, 0x000 },
7772 { 0x00000000, 0x00341c47, 0x000 },
7773 { 0x00000000, 0x12c00000, 0x267 },
7774 { 0x00000000, 0x00201c11, 0x000 },
7775 { 0x00000000, 0x002f00e6, 0x000 },
7776 { 0x00000000, 0x08c00000, 0x26a },
7777 { 0x00000000, 0x00201807, 0x000 },
7778 { 0x00000000, 0x00600000, 0x2c1 },
7779 { 0x00002256, 0x00204411, 0x000 },
7780 { 0x00000000, 0x00342023, 0x000 },
7781 { 0x00000000, 0x12c00000, 0x272 },
7782 { 0x00000000, 0x00342044, 0x000 },
7783 { 0x00000000, 0x12c00000, 0x271 },
7784 { 0x00000016, 0x00404811, 0x276 },
7785 { 0x00000018, 0x00404811, 0x276 },
7786 { 0x00000000, 0x00342044, 0x000 },
7787 { 0x00000000, 0x12c00000, 0x275 },
7788 { 0x00000017, 0x00404811, 0x276 },
7789 { 0x00000019, 0x00204811, 0x000 },
7790 { 0x0000a1fc, 0x00204411, 0x000 },
7791 { 0x00000001, 0x00204811, 0x000 },
7792 { 0x0001a1fd, 0x00604411, 0x2e9 },
7793 { 0x00003fff, 0x002f022f, 0x000 },
7794 { 0x00000000, 0x0cc00000, 0x256 },
7795 { 0x00000000, 0xc0400400, 0x001 },
7796 { 0x00000010, 0x40210620, 0x000 },
7797 { 0x0000ffff, 0xc0280a20, 0x000 },
7798 { 0x00000010, 0x40210e20, 0x000 },
7799 { 0x0000ffff, 0xc0281220, 0x000 },
7800 { 0x00000010, 0x40211620, 0x000 },
7801 { 0x0000ffff, 0xc0881a20, 0x000 },
7802 { 0x81000000, 0x00204411, 0x000 },
7803 { 0x00000001, 0x00204811, 0x000 },
7804 { 0x00042004, 0x00604411, 0x68a },
7805 { 0x00000000, 0x00600000, 0x62e },
7806 { 0x00000000, 0xc0600000, 0x2a3 },
7807 { 0x00000005, 0x00200a2d, 0x000 },
7808 { 0x00000008, 0x00220a22, 0x000 },
7809 { 0x0000002b, 0x00201a2d, 0x000 },
7810 { 0x0000001c, 0x00201e2d, 0x000 },
7811 { 0x00007000, 0x00281e27, 0x000 },
7812 { 0x00000000, 0x00311ce6, 0x000 },
7813 { 0x0000002a, 0x00201a2d, 0x000 },
7814 { 0x0000000c, 0x00221a26, 0x000 },
7815 { 0x00000000, 0x002f00e6, 0x000 },
7816 { 0x00000000, 0x06e00000, 0x292 },
7817 { 0x00000000, 0x00201c11, 0x000 },
7818 { 0x00000000, 0x00200c11, 0x000 },
7819 { 0x0000002b, 0x00203623, 0x000 },
7820 { 0x00000010, 0x00201811, 0x000 },
7821 { 0x00000000, 0x00691ce2, 0x12f },
7822 { 0x93800000, 0x00204411, 0x000 },
7823 { 0x00000000, 0x00204807, 0x000 },
7824 { 0x95000000, 0x00204411, 0x000 },
7825 { 0x00000000, 0x002f022f, 0x000 },
7826 { 0x00000000, 0x0ce00000, 0x29d },
7827 { 0x00000001, 0x00333e2f, 0x000 },
7828 { 0x00000000, 0xd9004800, 0x000 },
7829 { 0x92000000, 0x00204411, 0x000 },
7830 { 0x00000000, 0xc0204800, 0x000 },
7831 { 0x0000001c, 0x00403627, 0x000 },
7832 { 0x0000000c, 0xc0220a20, 0x000 },
7833 { 0x00000029, 0x00203622, 0x000 },
7834 { 0x00000028, 0xc0403620, 0x000 },
7835 { 0x0000a2a4, 0x00204411, 0x000 },
7836 { 0x00000009, 0x00204811, 0x000 },
7837 { 0xa1000000, 0x00204411, 0x000 },
7838 { 0x00000001, 0x00804811, 0x000 },
7839 { 0x00000021, 0x00201e2d, 0x000 },
7840 { 0x00000000, 0x002c1ce3, 0x000 },
7841 { 0x00000021, 0x00203627, 0x000 },
7842 { 0x00000022, 0x00201e2d, 0x000 },
7843 { 0x00000000, 0x002c1ce4, 0x000 },
7844 { 0x00000022, 0x00203627, 0x000 },
7845 { 0x00000023, 0x00201e2d, 0x000 },
7846 { 0x00000000, 0x003120a3, 0x000 },
7847 { 0x00000000, 0x002d1d07, 0x000 },
7848 { 0x00000023, 0x00203627, 0x000 },
7849 { 0x00000024, 0x00201e2d, 0x000 },
7850 { 0x00000000, 0x003120c4, 0x000 },
7851 { 0x00000000, 0x002d1d07, 0x000 },
7852 { 0x00000024, 0x00803627, 0x000 },
7853 { 0x00000021, 0x00203623, 0x000 },
7854 { 0x00000022, 0x00203624, 0x000 },
7855 { 0x00000000, 0x00311ca3, 0x000 },
7856 { 0x00000023, 0x00203627, 0x000 },
7857 { 0x00000000, 0x00311cc4, 0x000 },
7858 { 0x00000024, 0x00803627, 0x000 },
7859 { 0x0000001a, 0x00203627, 0x000 },
7860 { 0x0000001b, 0x00203628, 0x000 },
7861 { 0x00000017, 0x00201e2d, 0x000 },
7862 { 0x00000002, 0x00210227, 0x000 },
7863 { 0x00000000, 0x14c00000, 0x2dc },
7864 { 0x00000000, 0x00400000, 0x2d9 },
7865 { 0x0000001a, 0x00203627, 0x000 },
7866 { 0x0000001b, 0x00203628, 0x000 },
7867 { 0x00000017, 0x00201e2d, 0x000 },
7868 { 0x00000002, 0x00210227, 0x000 },
7869 { 0x00000000, 0x14e00000, 0x2d9 },
7870 { 0x00000003, 0x00210227, 0x000 },
7871 { 0x00000000, 0x14e00000, 0x2dc },
7872 { 0x00000023, 0x00201e2d, 0x000 },
7873 { 0x00000000, 0x002e00e1, 0x000 },
7874 { 0x00000000, 0x02c00000, 0x2dc },
7875 { 0x00000021, 0x00201e2d, 0x000 },
7876 { 0x00000000, 0x003120a1, 0x000 },
7877 { 0x00000000, 0x002e00e8, 0x000 },
7878 { 0x00000000, 0x06c00000, 0x2dc },
7879 { 0x00000024, 0x00201e2d, 0x000 },
7880 { 0x00000000, 0x002e00e2, 0x000 },
7881 { 0x00000000, 0x02c00000, 0x2dc },
7882 { 0x00000022, 0x00201e2d, 0x000 },
7883 { 0x00000000, 0x003120c2, 0x000 },
7884 { 0x00000000, 0x002e00e8, 0x000 },
7885 { 0x00000000, 0x06c00000, 0x2dc },
7886 { 0x00000000, 0x00600000, 0x665 },
7887 { 0x00000000, 0x00600000, 0x2b5 },
7888 { 0x00000000, 0x00400000, 0x2de },
7889 { 0x00000000, 0x00600000, 0x2b5 },
7890 { 0x00000000, 0x00600000, 0x65c },
7891 { 0x00000000, 0x00400000, 0x2de },
7892 { 0x00000000, 0x00600000, 0x2a7 },
7893 { 0x00000000, 0x00400000, 0x2de },
7894 { 0x0000001a, 0x00201e2d, 0x000 },
7895 { 0x0000001b, 0x0080222d, 0x000 },
7896 { 0x00000010, 0x00221e23, 0x000 },
7897 { 0x00000000, 0x00294887, 0x000 },
7898 { 0x00000000, 0x00311ca3, 0x000 },
7899 { 0x00000010, 0x00221e27, 0x000 },
7900 { 0x00000000, 0x00294887, 0x000 },
7901 { 0x00000010, 0x00221e23, 0x000 },
7902 { 0x00000000, 0x003120c4, 0x000 },
7903 { 0x0000ffff, 0x00282228, 0x000 },
7904 { 0x00000000, 0x00894907, 0x000 },
7905 { 0x00000010, 0x00221e23, 0x000 },
7906 { 0x00000000, 0x00294887, 0x000 },
7907 { 0x00000010, 0x00221e21, 0x000 },
7908 { 0x00000000, 0x00294847, 0x000 },
7909 { 0x00000000, 0x00311ca3, 0x000 },
7910 { 0x00000010, 0x00221e27, 0x000 },
7911 { 0x00000000, 0x00294887, 0x000 },
7912 { 0x00000000, 0x00311ca1, 0x000 },
7913 { 0x00000010, 0x00221e27, 0x000 },
7914 { 0x00000000, 0x00294847, 0x000 },
7915 { 0x00000010, 0x00221e23, 0x000 },
7916 { 0x00000000, 0x003120c4, 0x000 },
7917 { 0x0000ffff, 0x00282228, 0x000 },
7918 { 0x00000000, 0x00294907, 0x000 },
7919 { 0x00000010, 0x00221e21, 0x000 },
7920 { 0x00000000, 0x003120c2, 0x000 },
7921 { 0x0000ffff, 0x00282228, 0x000 },
7922 { 0x00000000, 0x00894907, 0x000 },
7923 { 0x00000010, 0x00221e23, 0x000 },
7924 { 0x00000000, 0x00294887, 0x000 },
7925 { 0x00000001, 0x00220a21, 0x000 },
7926 { 0x00000000, 0x003308a2, 0x000 },
7927 { 0x00000010, 0x00221e22, 0x000 },
7928 { 0x00000010, 0x00212222, 0x000 },
7929 { 0x00000000, 0x00294907, 0x000 },
7930 { 0x00000000, 0x00311ca3, 0x000 },
7931 { 0x00000010, 0x00221e27, 0x000 },
7932 { 0x00000000, 0x00294887, 0x000 },
7933 { 0x00000001, 0x00220a21, 0x000 },
7934 { 0x00000000, 0x003008a2, 0x000 },
7935 { 0x00000010, 0x00221e22, 0x000 },
7936 { 0x00000010, 0x00212222, 0x000 },
7937 { 0x00000000, 0x00294907, 0x000 },
7938 { 0x00000010, 0x00221e23, 0x000 },
7939 { 0x00000000, 0x003120c4, 0x000 },
7940 { 0x0000ffff, 0x00282228, 0x000 },
7941 { 0x00000000, 0x00294907, 0x000 },
7942 { 0x00000000, 0x003808c5, 0x000 },
7943 { 0x00000000, 0x00300841, 0x000 },
7944 { 0x00000001, 0x00220a22, 0x000 },
7945 { 0x00000000, 0x003308a2, 0x000 },
7946 { 0x00000010, 0x00221e22, 0x000 },
7947 { 0x00000010, 0x00212222, 0x000 },
7948 { 0x00000000, 0x00894907, 0x000 },
7949 { 0x00000017, 0x0020222d, 0x000 },
7950 { 0x00000000, 0x14c00000, 0x318 },
7951 { 0xffffffef, 0x00280621, 0x000 },
7952 { 0x00000014, 0x0020222d, 0x000 },
7953 { 0x0000f8e0, 0x00204411, 0x000 },
7954 { 0x00000000, 0x00294901, 0x000 },
7955 { 0x00000000, 0x00894901, 0x000 },
7956 { 0x00000000, 0x00204811, 0x000 },
7957 { 0x00000000, 0x00204811, 0x000 },
7958 { 0x060a0200, 0x00804811, 0x000 },
7959 { 0x00000000, 0xc0200000, 0x000 },
7960 { 0x97000000, 0xc0204411, 0x000 },
7961 { 0x00000000, 0xc0204811, 0x000 },
7962 { 0x8a000000, 0x00204411, 0x000 },
7963 { 0x00000000, 0x00204811, 0x000 },
7964 { 0x0000225c, 0x00204411, 0x000 },
7965 { 0x00000000, 0xc0204800, 0x000 },
7966 { 0x0000a1fc, 0x00204411, 0x000 },
7967 { 0x00000000, 0xc0204800, 0x000 },
7968 { 0x00000000, 0xc0200400, 0x000 },
7969 { 0x00000000, 0x00a0000a, 0x000 },
7970 { 0x97000000, 0x00204411, 0x000 },
7971 { 0x00000000, 0x00204811, 0x000 },
7972 { 0x8a000000, 0x00204411, 0x000 },
7973 { 0x00000000, 0x00204811, 0x000 },
7974 { 0x0000225c, 0x00204411, 0x000 },
7975 { 0x00000000, 0xc0204800, 0x000 },
7976 { 0x0000a1fc, 0x00204411, 0x000 },
7977 { 0x00000000, 0xc0204800, 0x000 },
7978 { 0x00000000, 0xc0200400, 0x000 },
7979 { 0x00000000, 0x00a0000a, 0x000 },
7980 { 0x97000000, 0x00204411, 0x000 },
7981 { 0x00000000, 0x00204811, 0x000 },
7982 { 0x8a000000, 0x00204411, 0x000 },
7983 { 0x00000000, 0x00204811, 0x000 },
7984 { 0x0000225c, 0x00204411, 0x000 },
7985 { 0x00000000, 0xc0204800, 0x000 },
7986 { 0x0000a1fc, 0x00204411, 0x000 },
7987 { 0x00000000, 0xc0204800, 0x000 },
7988 { 0x0001a1fd, 0x00204411, 0x000 },
7989 { 0x00000000, 0xd9004800, 0x000 },
7990 { 0x00000000, 0xc0200400, 0x000 },
7991 { 0x00000000, 0x00a0000a, 0x000 },
7992 { 0x00002257, 0x00204411, 0x000 },
7993 { 0x00000003, 0xc0484a20, 0x000 },
7994 { 0x0000225d, 0x00204411, 0x000 },
7995 { 0x00000000, 0xc0404800, 0x000 },
7996 { 0x00000000, 0x00600000, 0x642 },
7997 { 0x00000000, 0xc0200800, 0x000 },
7998 { 0x0000225c, 0x00204411, 0x000 },
7999 { 0x00000003, 0x00384a22, 0x000 },
8000 { 0x0000a1fc, 0x00204411, 0x000 },
8001 { 0x00000000, 0xc0204800, 0x000 },
8002 { 0x0001a1fd, 0x00204411, 0x000 },
8003 { 0x00000000, 0x002f0222, 0x000 },
8004 { 0x00000000, 0x0ce00000, 0x000 },
8005 { 0x00000000, 0x40204800, 0x000 },
8006 { 0x00000001, 0x40304a20, 0x000 },
8007 { 0x00000002, 0xc0304a20, 0x000 },
8008 { 0x00000001, 0x00530a22, 0x34b },
8009 { 0x0000003f, 0xc0280a20, 0x000 },
8010 { 0x81000000, 0x00204411, 0x000 },
8011 { 0x00000001, 0x00204811, 0x000 },
8012 { 0x000021f8, 0x00204411, 0x000 },
8013 { 0x00000018, 0x00204811, 0x000 },
8014 { 0x000421f9, 0x00604411, 0x68a },
8015 { 0x00000011, 0x00210230, 0x000 },
8016 { 0x00000000, 0x14e00000, 0x354 },
8017 { 0x00000014, 0x002f0222, 0x000 },
8018 { 0x00000000, 0x0cc00000, 0x364 },
8019 { 0x00002010, 0x00204411, 0x000 },
8020 { 0x00008000, 0x00204811, 0x000 },
8021 { 0x0001a2a4, 0x00204411, 0x000 },
8022 { 0x00000000, 0x00604802, 0x36e },
8023 { 0x00002100, 0x00204411, 0x000 },
8024 { 0x00000000, 0xc0204800, 0x000 },
8025 { 0x00000000, 0xc0204800, 0x000 },
8026 { 0x00000000, 0xc0204800, 0x000 },
8027 { 0x00000000, 0xc0404800, 0x000 },
8028 { 0x00000004, 0x002f0222, 0x000 },
8029 { 0x00000000, 0x0cc00000, 0x36a },
8030 { 0x00002010, 0x00204411, 0x000 },
8031 { 0x00008000, 0x00204811, 0x000 },
8032 { 0x0001a2a4, 0x00204411, 0x000 },
8033 { 0x00000000, 0x00404802, 0x35f },
8034 { 0x00000028, 0x002f0222, 0x000 },
8035 { 0x00000000, 0x0cc00000, 0x5bd },
8036 { 0x0001a2a4, 0x00204411, 0x000 },
8037 { 0x00000000, 0x00404802, 0x35f },
8038 { 0x0000002c, 0x00203626, 0x000 },
8039 { 0x00000049, 0x00201811, 0x000 },
8040 { 0x0000003f, 0x00204811, 0x000 },
8041 { 0x00000001, 0x00331a26, 0x000 },
8042 { 0x00000000, 0x002f0226, 0x000 },
8043 { 0x00000000, 0x0cc00000, 0x370 },
8044 { 0x0000002c, 0x00801a2d, 0x000 },
8045 { 0x0000003f, 0xc0280a20, 0x000 },
8046 { 0x00000015, 0x002f0222, 0x000 },
8047 { 0x00000000, 0x0ce00000, 0x386 },
8048 { 0x00000006, 0x002f0222, 0x000 },
8049 { 0x00000000, 0x0ce00000, 0x3b1 },
8050 { 0x00000016, 0x002f0222, 0x000 },
8051 { 0x00000000, 0x0ce00000, 0x3b5 },
8052 { 0x00000020, 0x002f0222, 0x000 },
8053 { 0x00000000, 0x0ce00000, 0x39c },
8054 { 0x0000000f, 0x002f0222, 0x000 },
8055 { 0x00000000, 0x0ce00000, 0x3a8 },
8056 { 0x00000010, 0x002f0222, 0x000 },
8057 { 0x00000000, 0x0ce00000, 0x3a8 },
8058 { 0x0000001e, 0x002f0222, 0x000 },
8059 { 0x00000000, 0x0ce00000, 0x390 },
8060 { 0x0000a2a4, 0x00204411, 0x000 },
8061 { 0x00000000, 0x00404802, 0x000 },
8062 { 0x08000000, 0x00290a22, 0x000 },
8063 { 0x00000003, 0x40210e20, 0x000 },
8064 { 0x0000000c, 0xc0211220, 0x000 },
8065 { 0x00080000, 0x00281224, 0x000 },
8066 { 0x00000014, 0xc0221620, 0x000 },
8067 { 0x00000000, 0x002914a4, 0x000 },
8068 { 0x0000a2a4, 0x00204411, 0x000 },
8069 { 0x00000000, 0x002948a2, 0x000 },
8070 { 0x0000a1fe, 0x00204411, 0x000 },
8071 { 0x00000000, 0x00404803, 0x000 },
8072 { 0x81000000, 0x00204411, 0x000 },
8073 { 0x00000001, 0x00204811, 0x000 },
8074 { 0x000021f8, 0x00204411, 0x000 },
8075 { 0x00000016, 0x00204811, 0x000 },
8076 { 0x000421f9, 0x00604411, 0x68a },
8077 { 0x00000015, 0x00210230, 0x000 },
8078 { 0x00000000, 0x14e00000, 0x392 },
8079 { 0x0000210e, 0x00204411, 0x000 },
8080 { 0x00000000, 0xc0204800, 0x000 },
8081 { 0x00000000, 0xc0204800, 0x000 },
8082 { 0x0000a2a4, 0x00204411, 0x000 },
8083 { 0x00000000, 0x00404802, 0x000 },
8084 { 0x81000000, 0x00204411, 0x000 },
8085 { 0x00000001, 0x00204811, 0x000 },
8086 { 0x000021f8, 0x00204411, 0x000 },
8087 { 0x00000017, 0x00204811, 0x000 },
8088 { 0x000421f9, 0x00604411, 0x68a },
8089 { 0x00000003, 0x00210230, 0x000 },
8090 { 0x00000000, 0x14e00000, 0x39e },
8091 { 0x00002108, 0x00204411, 0x000 },
8092 { 0x00000000, 0xc0204800, 0x000 },
8093 { 0x00000000, 0xc0204800, 0x000 },
8094 { 0x0000a2a4, 0x00204411, 0x000 },
8095 { 0x00000000, 0x00404802, 0x000 },
8096 { 0x0000a2a4, 0x00204411, 0x000 },
8097 { 0x00000000, 0x00204802, 0x000 },
8098 { 0x80000000, 0x00204411, 0x000 },
8099 { 0x00000000, 0x00204811, 0x000 },
8100 { 0x81000000, 0x00204411, 0x000 },
8101 { 0x00000010, 0x00204811, 0x000 },
8102 { 0x00000000, 0x00200010, 0x000 },
8103 { 0x00000000, 0x14c00000, 0x3ae },
8104 { 0x00000000, 0x00400000, 0x000 },
8105 { 0x00002010, 0x00204411, 0x000 },
8106 { 0x00008000, 0x00204811, 0x000 },
8107 { 0x0001a2a4, 0x00204411, 0x000 },
8108 { 0x00000006, 0x00404811, 0x000 },
8109 { 0x00002010, 0x00204411, 0x000 },
8110 { 0x00008000, 0x00204811, 0x000 },
8111 { 0x0001a2a4, 0x00204411, 0x000 },
8112 { 0x00000016, 0x00604811, 0x36e },
8113 { 0x00000000, 0x00400000, 0x000 },
8114 { 0x00000000, 0xc0200800, 0x000 },
8115 { 0x00000000, 0xc0200c00, 0x000 },
8116 { 0x0000001d, 0x00210223, 0x000 },
8117 { 0x00000000, 0x14e00000, 0x3ce },
8118 { 0x81000000, 0x00204411, 0x000 },
8119 { 0x00000001, 0x00204811, 0x000 },
8120 { 0x000021f8, 0x00204411, 0x000 },
8121 { 0x00000018, 0x00204811, 0x000 },
8122 { 0x000421f9, 0x00604411, 0x68a },
8123 { 0x00000011, 0x00210230, 0x000 },
8124 { 0x00000000, 0x14e00000, 0x3c0 },
8125 { 0x00002100, 0x00204411, 0x000 },
8126 { 0x00000000, 0x00204802, 0x000 },
8127 { 0x00000000, 0x00204803, 0x000 },
8128 { 0xbabecafe, 0x00204811, 0x000 },
8129 { 0xcafebabe, 0x00204811, 0x000 },
8130 { 0x00002010, 0x00204411, 0x000 },
8131 { 0x00008000, 0x00204811, 0x000 },
8132 { 0x0000a2a4, 0x00204411, 0x000 },
8133 { 0x00000004, 0x00404811, 0x000 },
8134 { 0x00002170, 0x00204411, 0x000 },
8135 { 0x00000000, 0x00204802, 0x000 },
8136 { 0x00000000, 0x00204803, 0x000 },
8137 { 0x81000000, 0x00204411, 0x000 },
8138 { 0x0000000a, 0x00204811, 0x000 },
8139 { 0x00000000, 0x00200010, 0x000 },
8140 { 0x00000000, 0x14c00000, 0x3d3 },
8141 { 0x8c000000, 0x00204411, 0x000 },
8142 { 0xcafebabe, 0x00404811, 0x000 },
8143 { 0x81000000, 0x00204411, 0x000 },
8144 { 0x00000001, 0x00204811, 0x000 },
8145 { 0x00003fff, 0x40280a20, 0x000 },
8146 { 0x80000000, 0x40280e20, 0x000 },
8147 { 0x40000000, 0xc0281220, 0x000 },
8148 { 0x00040000, 0x00694622, 0x68a },
8149 { 0x00000000, 0x00201410, 0x000 },
8150 { 0x00000000, 0x002f0223, 0x000 },
8151 { 0x00000000, 0x0cc00000, 0x3e1 },
8152 { 0x00000000, 0xc0401800, 0x3e4 },
8153 { 0x00003fff, 0xc0281a20, 0x000 },
8154 { 0x00040000, 0x00694626, 0x68a },
8155 { 0x00000000, 0x00201810, 0x000 },
8156 { 0x00000000, 0x002f0224, 0x000 },
8157 { 0x00000000, 0x0cc00000, 0x3e7 },
8158 { 0x00000000, 0xc0401c00, 0x3ea },
8159 { 0x00003fff, 0xc0281e20, 0x000 },
8160 { 0x00040000, 0x00694627, 0x68a },
8161 { 0x00000000, 0x00201c10, 0x000 },
8162 { 0x00000000, 0x00204402, 0x000 },
8163 { 0x00000000, 0x002820c5, 0x000 },
8164 { 0x00000000, 0x004948e8, 0x000 },
8165 { 0xa5800000, 0x00200811, 0x000 },
8166 { 0x00002000, 0x00200c11, 0x000 },
8167 { 0x83000000, 0x00604411, 0x412 },
8168 { 0x00000000, 0x00204402, 0x000 },
8169 { 0x00000000, 0xc0204800, 0x000 },
8170 { 0x00000000, 0x40204800, 0x000 },
8171 { 0x0000001f, 0xc0210220, 0x000 },
8172 { 0x00000000, 0x14c00000, 0x3f7 },
8173 { 0x00002010, 0x00204411, 0x000 },
8174 { 0x00008000, 0x00204811, 0x000 },
8175 { 0x0000ffff, 0xc0481220, 0x3ff },
8176 { 0xa7800000, 0x00200811, 0x000 },
8177 { 0x0000a000, 0x00200c11, 0x000 },
8178 { 0x83000000, 0x00604411, 0x412 },
8179 { 0x00000000, 0x00204402, 0x000 },
8180 { 0x00000000, 0xc0204800, 0x000 },
8181 { 0x00000000, 0xc0204800, 0x000 },
8182 { 0x0000ffff, 0xc0281220, 0x000 },
8183 { 0x83000000, 0x00204411, 0x000 },
8184 { 0x00000000, 0x00304883, 0x000 },
8185 { 0x84000000, 0x00204411, 0x000 },
8186 { 0x00000000, 0xc0204800, 0x000 },
8187 { 0x00000000, 0x1d000000, 0x000 },
8188 { 0x83000000, 0x00604411, 0x412 },
8189 { 0x00000000, 0xc0400400, 0x001 },
8190 { 0xa9800000, 0x00200811, 0x000 },
8191 { 0x0000c000, 0x00400c11, 0x3fa },
8192 { 0xab800000, 0x00200811, 0x000 },
8193 { 0x0000f8e0, 0x00400c11, 0x3fa },
8194 { 0xad800000, 0x00200811, 0x000 },
8195 { 0x0000f880, 0x00400c11, 0x3fa },
8196 { 0xb3800000, 0x00200811, 0x000 },
8197 { 0x0000f3fc, 0x00400c11, 0x3fa },
8198 { 0xaf800000, 0x00200811, 0x000 },
8199 { 0x0000e000, 0x00400c11, 0x3fa },
8200 { 0xb1800000, 0x00200811, 0x000 },
8201 { 0x0000f000, 0x00400c11, 0x3fa },
8202 { 0x83000000, 0x00204411, 0x000 },
8203 { 0x00002148, 0x00204811, 0x000 },
8204 { 0x84000000, 0x00204411, 0x000 },
8205 { 0x00000000, 0xc0204800, 0x000 },
8206 { 0x00000000, 0x1d000000, 0x000 },
8207 { 0x00000000, 0x00800000, 0x000 },
8208 { 0x01182000, 0xc0304620, 0x000 },
8209 { 0x00000000, 0xd9004800, 0x000 },
8210 { 0x00000000, 0xc0200400, 0x000 },
8211 { 0x00000000, 0x00a0000a, 0x000 },
8212 { 0x0218a000, 0xc0304620, 0x000 },
8213 { 0x00000000, 0xd9004800, 0x000 },
8214 { 0x00000000, 0xc0200400, 0x000 },
8215 { 0x00000000, 0x00a0000a, 0x000 },
8216 { 0x0318c000, 0xc0304620, 0x000 },
8217 { 0x00000000, 0xd9004800, 0x000 },
8218 { 0x00000000, 0xc0200400, 0x000 },
8219 { 0x00000000, 0x00a0000a, 0x000 },
8220 { 0x0418f8e0, 0xc0304620, 0x000 },
8221 { 0x00000000, 0xd9004800, 0x000 },
8222 { 0x00000000, 0xc0200400, 0x000 },
8223 { 0x00000000, 0x00a0000a, 0x000 },
8224 { 0x0518f880, 0xc0304620, 0x000 },
8225 { 0x00000000, 0xd9004800, 0x000 },
8226 { 0x00000000, 0xc0200400, 0x000 },
8227 { 0x00000000, 0x00a0000a, 0x000 },
8228 { 0x0618e000, 0xc0304620, 0x000 },
8229 { 0x00000000, 0xd9004800, 0x000 },
8230 { 0x00000000, 0xc0200400, 0x000 },
8231 { 0x00000000, 0x00a0000a, 0x000 },
8232 { 0x0718f000, 0xc0304620, 0x000 },
8233 { 0x00000000, 0xd9004800, 0x000 },
8234 { 0x00000000, 0xc0200400, 0x000 },
8235 { 0x00000000, 0x00a0000a, 0x000 },
8236 { 0x0818f3fc, 0xc0304620, 0x000 },
8237 { 0x00000000, 0xd9004800, 0x000 },
8238 { 0x00000000, 0xc0200400, 0x000 },
8239 { 0x00000000, 0x00a0000a, 0x000 },
8240 { 0x00000030, 0x00200a2d, 0x000 },
8241 { 0x00000000, 0xc0290c40, 0x000 },
8242 { 0x00000030, 0x00203623, 0x000 },
8243 { 0x00000000, 0xc0200400, 0x000 },
8244 { 0x00000000, 0x00a0000a, 0x000 },
8245 { 0x86000000, 0x00204411, 0x000 },
8246 { 0x00000000, 0x00404801, 0x000 },
8247 { 0x85000000, 0xc0204411, 0x000 },
8248 { 0x00000000, 0x00404801, 0x000 },
8249 { 0x0000217c, 0x00204411, 0x000 },
8250 { 0x00000000, 0xc0204800, 0x000 },
8251 { 0x00000000, 0xc0204800, 0x000 },
8252 { 0x00000000, 0xc0204800, 0x000 },
8253 { 0x81000000, 0x00204411, 0x000 },
8254 { 0x00000001, 0x00204811, 0x000 },
8255 { 0x00000000, 0xc0200800, 0x000 },
8256 { 0x00000000, 0x17000000, 0x000 },
8257 { 0x0004217f, 0x00604411, 0x68a },
8258 { 0x0000001f, 0x00210230, 0x000 },
8259 { 0x00000000, 0x14c00000, 0x000 },
8260 { 0x00000000, 0x00404c02, 0x448 },
8261 { 0x00000000, 0xc0200c00, 0x000 },
8262 { 0x00000000, 0xc0201000, 0x000 },
8263 { 0x00000000, 0xc0201400, 0x000 },
8264 { 0x00000000, 0xc0201800, 0x000 },
8265 { 0x00000000, 0xc0201c00, 0x000 },
8266 { 0x00007f00, 0x00280a21, 0x000 },
8267 { 0x00004500, 0x002f0222, 0x000 },
8268 { 0x00000000, 0x0ce00000, 0x456 },
8269 { 0x00000000, 0xc0202000, 0x000 },
8270 { 0x00000000, 0x17000000, 0x000 },
8271 { 0x00000010, 0x00280a23, 0x000 },
8272 { 0x00000010, 0x002f0222, 0x000 },
8273 { 0x00000000, 0x0ce00000, 0x45e },
8274 { 0x81000000, 0x00204411, 0x000 },
8275 { 0x00000001, 0x00204811, 0x000 },
8276 { 0x00040000, 0x00694624, 0x68a },
8277 { 0x00000000, 0x00400000, 0x463 },
8278 { 0x81000000, 0x00204411, 0x000 },
8279 { 0x00000000, 0x00204811, 0x000 },
8280 { 0x0000216d, 0x00204411, 0x000 },
8281 { 0x00000000, 0x00204804, 0x000 },
8282 { 0x00000000, 0x00604805, 0x68f },
8283 { 0x00000000, 0x002824f0, 0x000 },
8284 { 0x00000007, 0x00280a23, 0x000 },
8285 { 0x00000001, 0x002f0222, 0x000 },
8286 { 0x00000000, 0x0ae00000, 0x46a },
8287 { 0x00000000, 0x002f00c9, 0x000 },
8288 { 0x00000000, 0x04e00000, 0x483 },
8289 { 0x00000000, 0x00400000, 0x490 },
8290 { 0x00000002, 0x002f0222, 0x000 },
8291 { 0x00000000, 0x0ae00000, 0x46f },
8292 { 0x00000000, 0x002f00c9, 0x000 },
8293 { 0x00000000, 0x02e00000, 0x483 },
8294 { 0x00000000, 0x00400000, 0x490 },
8295 { 0x00000003, 0x002f0222, 0x000 },
8296 { 0x00000000, 0x0ae00000, 0x474 },
8297 { 0x00000000, 0x002f00c9, 0x000 },
8298 { 0x00000000, 0x0ce00000, 0x483 },
8299 { 0x00000000, 0x00400000, 0x490 },
8300 { 0x00000004, 0x002f0222, 0x000 },
8301 { 0x00000000, 0x0ae00000, 0x479 },
8302 { 0x00000000, 0x002f00c9, 0x000 },
8303 { 0x00000000, 0x0ae00000, 0x483 },
8304 { 0x00000000, 0x00400000, 0x490 },
8305 { 0x00000005, 0x002f0222, 0x000 },
8306 { 0x00000000, 0x0ae00000, 0x47e },
8307 { 0x00000000, 0x002f00c9, 0x000 },
8308 { 0x00000000, 0x06e00000, 0x483 },
8309 { 0x00000000, 0x00400000, 0x490 },
8310 { 0x00000006, 0x002f0222, 0x000 },
8311 { 0x00000000, 0x0ae00000, 0x483 },
8312 { 0x00000000, 0x002f00c9, 0x000 },
8313 { 0x00000000, 0x08e00000, 0x483 },
8314 { 0x00000000, 0x00400000, 0x490 },
8315 { 0x00007f00, 0x00280a21, 0x000 },
8316 { 0x00004500, 0x002f0222, 0x000 },
8317 { 0x00000000, 0x0ae00000, 0x000 },
8318 { 0x00000008, 0x00210a23, 0x000 },
8319 { 0x00000000, 0x14c00000, 0x48d },
8320 { 0x00002169, 0x00204411, 0x000 },
8321 { 0x00000000, 0xc0204800, 0x000 },
8322 { 0x00000000, 0xc0204800, 0x000 },
8323 { 0x00000000, 0xc0204800, 0x000 },
8324 { 0xcafebabe, 0x00404811, 0x000 },
8325 { 0x00000000, 0xc0204400, 0x000 },
8326 { 0x00000000, 0xc0200000, 0x000 },
8327 { 0x00000000, 0xc0404800, 0x000 },
8328 { 0x00007f00, 0x00280a21, 0x000 },
8329 { 0x00004500, 0x002f0222, 0x000 },
8330 { 0x00000000, 0x0ae00000, 0x496 },
8331 { 0x00000000, 0xc0200000, 0x000 },
8332 { 0x00000000, 0xc0200000, 0x000 },
8333 { 0x00000000, 0xc0400000, 0x000 },
8334 { 0x00000000, 0x00404c08, 0x456 },
8335 { 0x00000000, 0xc0200800, 0x000 },
8336 { 0x00000010, 0x40210e20, 0x000 },
8337 { 0x00000011, 0x40211220, 0x000 },
8338 { 0x00000012, 0x40211620, 0x000 },
8339 { 0x00002169, 0x00204411, 0x000 },
8340 { 0x00000000, 0x00204802, 0x000 },
8341 { 0x00000000, 0x00210225, 0x000 },
8342 { 0x00000000, 0x14e00000, 0x4a0 },
8343 { 0x00040000, 0xc0494a20, 0x4a1 },
8344 { 0xfffbffff, 0xc0284a20, 0x000 },
8345 { 0x00000000, 0x00210223, 0x000 },
8346 { 0x00000000, 0x14e00000, 0x4ad },
8347 { 0x00000000, 0xc0204800, 0x000 },
8348 { 0x00000000, 0xc0204800, 0x000 },
8349 { 0x00000000, 0x00210224, 0x000 },
8350 { 0x00000000, 0x14c00000, 0x000 },
8351 { 0x81000000, 0x00204411, 0x000 },
8352 { 0x0000000c, 0x00204811, 0x000 },
8353 { 0x00000000, 0x00200010, 0x000 },
8354 { 0x00000000, 0x14c00000, 0x4a9 },
8355 { 0xa0000000, 0x00204411, 0x000 },
8356 { 0xcafebabe, 0x00404811, 0x000 },
8357 { 0x81000000, 0x00204411, 0x000 },
8358 { 0x00000004, 0x00204811, 0x000 },
8359 { 0x0000216b, 0x00204411, 0x000 },
8360 { 0x00000000, 0xc0204810, 0x000 },
8361 { 0x81000000, 0x00204411, 0x000 },
8362 { 0x00000005, 0x00204811, 0x000 },
8363 { 0x0000216c, 0x00204411, 0x000 },
8364 { 0x00000000, 0xc0204810, 0x000 },
8365 { 0x00000000, 0x002f0224, 0x000 },
8366 { 0x00000000, 0x0ce00000, 0x000 },
8367 { 0x00000000, 0x00400000, 0x4a7 },
8368 { 0x00000000, 0xc0210a20, 0x000 },
8369 { 0x00000000, 0x14c00000, 0x4c0 },
8370 { 0x81000000, 0x00204411, 0x000 },
8371 { 0x00000000, 0x00204811, 0x000 },
8372 { 0x0000216d, 0x00204411, 0x000 },
8373 { 0x00000000, 0xc0204800, 0x000 },
8374 { 0x00000000, 0xc0604800, 0x68f },
8375 { 0x00000000, 0x00400000, 0x4c4 },
8376 { 0x81000000, 0x00204411, 0x000 },
8377 { 0x00000001, 0x00204811, 0x000 },
8378 { 0x00040000, 0xc0294620, 0x000 },
8379 { 0x00000000, 0xc0600000, 0x68a },
8380 { 0x00000001, 0x00210222, 0x000 },
8381 { 0x00000000, 0x14c00000, 0x4cb },
8382 { 0x00002169, 0x00204411, 0x000 },
8383 { 0x00000000, 0xc0204800, 0x000 },
8384 { 0x00000000, 0xc0204800, 0x000 },
8385 { 0x00000000, 0x00204810, 0x000 },
8386 { 0xcafebabe, 0x00404811, 0x000 },
8387 { 0x00000000, 0xc0204400, 0x000 },
8388 { 0x00000000, 0xc0404810, 0x000 },
8389 { 0x81000000, 0x00204411, 0x000 },
8390 { 0x00000001, 0x00204811, 0x000 },
8391 { 0x000021f8, 0x00204411, 0x000 },
8392 { 0x0000000e, 0x00204811, 0x000 },
8393 { 0x000421f9, 0x00604411, 0x68a },
8394 { 0x00000000, 0x00210230, 0x000 },
8395 { 0x00000000, 0x14c00000, 0x4cd },
8396 { 0x00002180, 0x00204411, 0x000 },
8397 { 0x00000000, 0xc0204800, 0x000 },
8398 { 0x00000000, 0xc0200000, 0x000 },
8399 { 0x00000000, 0xc0204800, 0x000 },
8400 { 0x00000000, 0xc0200000, 0x000 },
8401 { 0x00000000, 0xc0404800, 0x000 },
8402 { 0x00000003, 0x00333e2f, 0x000 },
8403 { 0x00000001, 0x00210221, 0x000 },
8404 { 0x00000000, 0x14e00000, 0x4fd },
8405 { 0x0000002c, 0x00200a2d, 0x000 },
8406 { 0x00040000, 0x18e00c11, 0x4ec },
8407 { 0x00000001, 0x00333e2f, 0x000 },
8408 { 0x00002169, 0x00204411, 0x000 },
8409 { 0x00000000, 0x00204802, 0x000 },
8410 { 0x00000000, 0x00204803, 0x000 },
8411 { 0x00000008, 0x00300a22, 0x000 },
8412 { 0x00000000, 0xc0204800, 0x000 },
8413 { 0x00000000, 0xc0204800, 0x000 },
8414 { 0x00002169, 0x00204411, 0x000 },
8415 { 0x00000000, 0x00204802, 0x000 },
8416 { 0x00000000, 0x00204803, 0x000 },
8417 { 0x00000008, 0x00300a22, 0x000 },
8418 { 0x00000000, 0xc0204800, 0x000 },
8419 { 0x00000000, 0xd8c04800, 0x4e0 },
8420 { 0x00002169, 0x00204411, 0x000 },
8421 { 0x00000000, 0x00204802, 0x000 },
8422 { 0x00000000, 0x00204803, 0x000 },
8423 { 0x00000008, 0x00300a22, 0x000 },
8424 { 0x00000000, 0xc0204800, 0x000 },
8425 { 0x00000000, 0xc0204800, 0x000 },
8426 { 0x0000002d, 0x0020122d, 0x000 },
8427 { 0x00000000, 0x00290c83, 0x000 },
8428 { 0x00002169, 0x00204411, 0x000 },
8429 { 0x00000000, 0x00204802, 0x000 },
8430 { 0x00000000, 0x00204803, 0x000 },
8431 { 0x00000008, 0x00300a22, 0x000 },
8432 { 0x00000000, 0xc0204800, 0x000 },
8433 { 0x00000000, 0xc0204800, 0x000 },
8434 { 0x00000011, 0x00210224, 0x000 },
8435 { 0x00000000, 0x14c00000, 0x000 },
8436 { 0x00000000, 0x00400000, 0x4a7 },
8437 { 0x0000002c, 0xc0203620, 0x000 },
8438 { 0x0000002d, 0xc0403620, 0x000 },
8439 { 0x0000000f, 0x00210221, 0x000 },
8440 { 0x00000000, 0x14c00000, 0x502 },
8441 { 0x00000000, 0x00600000, 0x00b },
8442 { 0x00000000, 0xd9000000, 0x000 },
8443 { 0x00000000, 0xc0400400, 0x001 },
8444 { 0xb5000000, 0x00204411, 0x000 },
8445 { 0x00002000, 0x00204811, 0x000 },
8446 { 0xb6000000, 0x00204411, 0x000 },
8447 { 0x0000a000, 0x00204811, 0x000 },
8448 { 0xb7000000, 0x00204411, 0x000 },
8449 { 0x0000c000, 0x00204811, 0x000 },
8450 { 0xb8000000, 0x00204411, 0x000 },
8451 { 0x0000f8e0, 0x00204811, 0x000 },
8452 { 0xb9000000, 0x00204411, 0x000 },
8453 { 0x0000f880, 0x00204811, 0x000 },
8454 { 0xba000000, 0x00204411, 0x000 },
8455 { 0x0000e000, 0x00204811, 0x000 },
8456 { 0xbb000000, 0x00204411, 0x000 },
8457 { 0x0000f000, 0x00204811, 0x000 },
8458 { 0xbc000000, 0x00204411, 0x000 },
8459 { 0x0000f3fc, 0x00204811, 0x000 },
8460 { 0x81000000, 0x00204411, 0x000 },
8461 { 0x00000002, 0x00204811, 0x000 },
8462 { 0x000000ff, 0x00280e30, 0x000 },
8463 { 0x00000000, 0x002f0223, 0x000 },
8464 { 0x00000000, 0x0cc00000, 0x516 },
8465 { 0x00000000, 0xc0200800, 0x000 },
8466 { 0x00000000, 0x14c00000, 0x52b },
8467 { 0x00000000, 0x00200c11, 0x000 },
8468 { 0x0000001c, 0x00203623, 0x000 },
8469 { 0x0000002b, 0x00203623, 0x000 },
8470 { 0x00000029, 0x00203623, 0x000 },
8471 { 0x00000028, 0x00203623, 0x000 },
8472 { 0x00000017, 0x00203623, 0x000 },
8473 { 0x00000025, 0x00203623, 0x000 },
8474 { 0x00000026, 0x00203623, 0x000 },
8475 { 0x00000015, 0x00203623, 0x000 },
8476 { 0x00000016, 0x00203623, 0x000 },
8477 { 0xffffe000, 0x00200c11, 0x000 },
8478 { 0x00000021, 0x00203623, 0x000 },
8479 { 0x00000022, 0x00203623, 0x000 },
8480 { 0x00001fff, 0x00200c11, 0x000 },
8481 { 0x00000023, 0x00203623, 0x000 },
8482 { 0x00000024, 0x00203623, 0x000 },
8483 { 0xf1ffffff, 0x00283a2e, 0x000 },
8484 { 0x0000001a, 0xc0220e20, 0x000 },
8485 { 0x00000000, 0x0029386e, 0x000 },
8486 { 0x81000000, 0x00204411, 0x000 },
8487 { 0x00000006, 0x00204811, 0x000 },
8488 { 0x0000002a, 0x40203620, 0x000 },
8489 { 0x87000000, 0x00204411, 0x000 },
8490 { 0x00000000, 0xc0204800, 0x000 },
8491 { 0x0000a1f4, 0x00204411, 0x000 },
8492 { 0x00000000, 0x00204810, 0x000 },
8493 { 0x00000000, 0x00200c11, 0x000 },
8494 { 0x00000030, 0x00203623, 0x000 },
8495 { 0x9d000000, 0x00204411, 0x000 },
8496 { 0x0000001f, 0x40214a20, 0x000 },
8497 { 0x96000000, 0x00204411, 0x000 },
8498 { 0x00000000, 0xc0204800, 0x000 },
8499 { 0x00000000, 0xc0200c00, 0x000 },
8500 { 0x00000000, 0xc0201000, 0x000 },
8501 { 0x0000001f, 0x00211624, 0x000 },
8502 { 0x00000000, 0x14c00000, 0x000 },
8503 { 0x0000001d, 0x00203623, 0x000 },
8504 { 0x00000003, 0x00281e23, 0x000 },
8505 { 0x00000008, 0x00222223, 0x000 },
8506 { 0xfffff000, 0x00282228, 0x000 },
8507 { 0x00000000, 0x002920e8, 0x000 },
8508 { 0x0000001f, 0x00203628, 0x000 },
8509 { 0x00000018, 0x00211e23, 0x000 },
8510 { 0x00000020, 0x00203627, 0x000 },
8511 { 0x00000002, 0x00221624, 0x000 },
8512 { 0x00000000, 0x003014a8, 0x000 },
8513 { 0x0000001e, 0x00203625, 0x000 },
8514 { 0x00000003, 0x00211a24, 0x000 },
8515 { 0x10000000, 0x00281a26, 0x000 },
8516 { 0xefffffff, 0x00283a2e, 0x000 },
8517 { 0x00000000, 0x004938ce, 0x678 },
8518 { 0x00000001, 0x40280a20, 0x000 },
8519 { 0x00000006, 0x40280e20, 0x000 },
8520 { 0x00000300, 0xc0281220, 0x000 },
8521 { 0x00000008, 0x00211224, 0x000 },
8522 { 0x00000000, 0xc0201620, 0x000 },
8523 { 0x00000000, 0xc0201a20, 0x000 },
8524 { 0x00000000, 0x00210222, 0x000 },
8525 { 0x00000000, 0x14c00000, 0x563 },
8526 { 0x81000000, 0x00204411, 0x000 },
8527 { 0x00000001, 0x00204811, 0x000 },
8528 { 0x00002258, 0x00300a24, 0x000 },
8529 { 0x00040000, 0x00694622, 0x68a },
8530 { 0x00002169, 0x00204411, 0x000 },
8531 { 0x00000000, 0x00204805, 0x000 },
8532 { 0x00020000, 0x00294a26, 0x000 },
8533 { 0x00000000, 0x00204810, 0x000 },
8534 { 0xcafebabe, 0x00204811, 0x000 },
8535 { 0x00000002, 0x002f0223, 0x000 },
8536 { 0x00000000, 0x0cc00000, 0x56b },
8537 { 0x00000000, 0xc0201c10, 0x000 },
8538 { 0x00000000, 0xc0400000, 0x579 },
8539 { 0x00000002, 0x002f0223, 0x000 },
8540 { 0x00000000, 0x0cc00000, 0x56b },
8541 { 0x81000000, 0x00204411, 0x000 },
8542 { 0x00000001, 0x00204811, 0x000 },
8543 { 0x00002258, 0x00300a24, 0x000 },
8544 { 0x00040000, 0x00694622, 0x68a },
8545 { 0x00000000, 0xc0201c10, 0x000 },
8546 { 0x00000000, 0xc0400000, 0x579 },
8547 { 0x00000000, 0x002f0223, 0x000 },
8548 { 0x00000000, 0x0cc00000, 0x56f },
8549 { 0x00000000, 0xc0201c00, 0x000 },
8550 { 0x00000000, 0xc0400000, 0x579 },
8551 { 0x00000004, 0x002f0223, 0x000 },
8552 { 0x00000000, 0x0cc00000, 0x577 },
8553 { 0x81000000, 0x00204411, 0x000 },
8554 { 0x00000000, 0x00204811, 0x000 },
8555 { 0x0000216d, 0x00204411, 0x000 },
8556 { 0x00000000, 0xc0204800, 0x000 },
8557 { 0x00000000, 0xc0604800, 0x68f },
8558 { 0x00000000, 0x00401c10, 0x579 },
8559 { 0x00000000, 0xc0200000, 0x000 },
8560 { 0x00000000, 0xc0400000, 0x000 },
8561 { 0x00000000, 0x0ee00000, 0x57b },
8562 { 0x00000000, 0x00600000, 0x5c6 },
8563 { 0x00000000, 0x002f0224, 0x000 },
8564 { 0x00000000, 0x0cc00000, 0x58c },
8565 { 0x0000a2b7, 0x00204411, 0x000 },
8566 { 0x00000000, 0x00204807, 0x000 },
8567 { 0x81000000, 0x00204411, 0x000 },
8568 { 0x00000001, 0x00204811, 0x000 },
8569 { 0x0004a2b6, 0x00604411, 0x68a },
8570 { 0x0000001a, 0x00212230, 0x000 },
8571 { 0x00000006, 0x00222630, 0x000 },
8572 { 0x00042004, 0x00604411, 0x68a },
8573 { 0x0000a2c4, 0x00204411, 0x000 },
8574 { 0x00000000, 0x003048e9, 0x000 },
8575 { 0x00000000, 0x00e00000, 0x58a },
8576 { 0x0000a2d1, 0x00204411, 0x000 },
8577 { 0x00000000, 0x00404808, 0x000 },
8578 { 0x0000a2d1, 0x00204411, 0x000 },
8579 { 0x00000001, 0x00504a28, 0x000 },
8580 { 0x00000001, 0x002f0224, 0x000 },
8581 { 0x00000000, 0x0cc00000, 0x59d },
8582 { 0x0000a2bb, 0x00204411, 0x000 },
8583 { 0x00000000, 0x00204807, 0x000 },
8584 { 0x81000000, 0x00204411, 0x000 },
8585 { 0x00000001, 0x00204811, 0x000 },
8586 { 0x0004a2ba, 0x00604411, 0x68a },
8587 { 0x0000001a, 0x00212230, 0x000 },
8588 { 0x00000006, 0x00222630, 0x000 },
8589 { 0x00042004, 0x00604411, 0x68a },
8590 { 0x0000a2c5, 0x00204411, 0x000 },
8591 { 0x00000000, 0x003048e9, 0x000 },
8592 { 0x00000000, 0x00e00000, 0x59b },
8593 { 0x0000a2d2, 0x00204411, 0x000 },
8594 { 0x00000000, 0x00404808, 0x000 },
8595 { 0x0000a2d2, 0x00204411, 0x000 },
8596 { 0x00000001, 0x00504a28, 0x000 },
8597 { 0x00000002, 0x002f0224, 0x000 },
8598 { 0x00000000, 0x0cc00000, 0x5ae },
8599 { 0x0000a2bf, 0x00204411, 0x000 },
8600 { 0x00000000, 0x00204807, 0x000 },
8601 { 0x81000000, 0x00204411, 0x000 },
8602 { 0x00000001, 0x00204811, 0x000 },
8603 { 0x0004a2be, 0x00604411, 0x68a },
8604 { 0x0000001a, 0x00212230, 0x000 },
8605 { 0x00000006, 0x00222630, 0x000 },
8606 { 0x00042004, 0x00604411, 0x68a },
8607 { 0x0000a2c6, 0x00204411, 0x000 },
8608 { 0x00000000, 0x003048e9, 0x000 },
8609 { 0x00000000, 0x00e00000, 0x5ac },
8610 { 0x0000a2d3, 0x00204411, 0x000 },
8611 { 0x00000000, 0x00404808, 0x000 },
8612 { 0x0000a2d3, 0x00204411, 0x000 },
8613 { 0x00000001, 0x00504a28, 0x000 },
8614 { 0x0000a2c3, 0x00204411, 0x000 },
8615 { 0x00000000, 0x00204807, 0x000 },
8616 { 0x81000000, 0x00204411, 0x000 },
8617 { 0x00000001, 0x00204811, 0x000 },
8618 { 0x0004a2c2, 0x00604411, 0x68a },
8619 { 0x0000001a, 0x00212230, 0x000 },
8620 { 0x00000006, 0x00222630, 0x000 },
8621 { 0x00042004, 0x00604411, 0x68a },
8622 { 0x0000a2c7, 0x00204411, 0x000 },
8623 { 0x00000000, 0x003048e9, 0x000 },
8624 { 0x00000000, 0x00e00000, 0x5bb },
8625 { 0x0000a2d4, 0x00204411, 0x000 },
8626 { 0x00000000, 0x00404808, 0x000 },
8627 { 0x0000a2d4, 0x00204411, 0x000 },
8628 { 0x00000001, 0x00504a28, 0x000 },
8629 { 0x85000000, 0x00204411, 0x000 },
8630 { 0x00000000, 0x00204801, 0x000 },
8631 { 0x0000304a, 0x00204411, 0x000 },
8632 { 0x01000000, 0x00204811, 0x000 },
8633 { 0x00000000, 0x00400000, 0x5c1 },
8634 { 0xa4000000, 0xc0204411, 0x000 },
8635 { 0x00000000, 0xc0404800, 0x000 },
8636 { 0x00000000, 0xc0600000, 0x5c6 },
8637 { 0x00000000, 0xc0400400, 0x001 },
8638 { 0x0000002c, 0x00203621, 0x000 },
8639 { 0x81000000, 0x00204411, 0x000 },
8640 { 0x00000006, 0x00204811, 0x000 },
8641 { 0x00000000, 0x002f0230, 0x000 },
8642 { 0x00000000, 0x0cc00000, 0x5cd },
8643 { 0x00000000, 0x00200411, 0x000 },
8644 { 0x00000030, 0x00403621, 0x5e0 },
8645 { 0x00000030, 0x0020062d, 0x000 },
8646 { 0x00007e00, 0x00280621, 0x000 },
8647 { 0x00000000, 0x002f0221, 0x000 },
8648 { 0x00000000, 0x0ce00000, 0x5e0 },
8649 { 0x81000000, 0x00204411, 0x000 },
8650 { 0x00000001, 0x00204811, 0x000 },
8651 { 0x0004a092, 0x00604411, 0x68a },
8652 { 0x00000031, 0x00203630, 0x000 },
8653 { 0x0004a093, 0x00604411, 0x68a },
8654 { 0x00000032, 0x00203630, 0x000 },
8655 { 0x0004a2b6, 0x00604411, 0x68a },
8656 { 0x00000033, 0x00203630, 0x000 },
8657 { 0x0004a2ba, 0x00604411, 0x68a },
8658 { 0x00000034, 0x00203630, 0x000 },
8659 { 0x0004a2be, 0x00604411, 0x68a },
8660 { 0x00000035, 0x00203630, 0x000 },
8661 { 0x0004a2c2, 0x00604411, 0x68a },
8662 { 0x00000036, 0x00203630, 0x000 },
8663 { 0x00042004, 0x00604411, 0x68a },
8664 { 0x0001a2a4, 0x00204411, 0x000 },
8665 { 0x0000003f, 0x00204811, 0x000 },
8666 { 0x0000003f, 0x00204811, 0x000 },
8667 { 0x0000003f, 0x00204811, 0x000 },
8668 { 0x0000003f, 0x00204811, 0x000 },
8669 { 0x00000005, 0x00204811, 0x000 },
8670 { 0x0000a1f4, 0x00204411, 0x000 },
8671 { 0x00000000, 0x00204811, 0x000 },
8672 { 0x88000000, 0x00204411, 0x000 },
8673 { 0x00000001, 0x00204811, 0x000 },
8674 { 0x81000000, 0x00204411, 0x000 },
8675 { 0x00000006, 0x00204811, 0x000 },
8676 { 0x00000001, 0x002f0230, 0x000 },
8677 { 0x00000000, 0x0ce00000, 0x629 },
8678 { 0x00000030, 0x0020062d, 0x000 },
8679 { 0x00000000, 0x002f0221, 0x000 },
8680 { 0x00000000, 0x0ce00000, 0x629 },
8681 { 0x81000000, 0x00204411, 0x000 },
8682 { 0x00000001, 0x00204811, 0x000 },
8683 { 0x00007e00, 0x00280621, 0x000 },
8684 { 0x00000000, 0x002f0221, 0x000 },
8685 { 0x00000000, 0x0ce00000, 0x602 },
8686 { 0x0000a092, 0x00204411, 0x000 },
8687 { 0x00000031, 0x00204a2d, 0x000 },
8688 { 0x0000a093, 0x00204411, 0x000 },
8689 { 0x00000032, 0x00204a2d, 0x000 },
8690 { 0x0000a2b6, 0x00204411, 0x000 },
8691 { 0x00000033, 0x00204a2d, 0x000 },
8692 { 0x0000a2ba, 0x00204411, 0x000 },
8693 { 0x00000034, 0x00204a2d, 0x000 },
8694 { 0x0000a2be, 0x00204411, 0x000 },
8695 { 0x00000035, 0x00204a2d, 0x000 },
8696 { 0x0000a2c2, 0x00204411, 0x000 },
8697 { 0x00000036, 0x00204a2d, 0x000 },
8698 { 0x00000030, 0x0020062d, 0x000 },
8699 { 0x000001ff, 0x00280621, 0x000 },
8700 { 0x00000000, 0x002f0221, 0x000 },
8701 { 0x00000000, 0x0ce00000, 0x628 },
8702 { 0x00000000, 0x00210221, 0x000 },
8703 { 0x00000000, 0x14c00000, 0x60b },
8704 { 0x0004a003, 0x00604411, 0x68a },
8705 { 0x0000a003, 0x00204411, 0x000 },
8706 { 0x00000000, 0x00204810, 0x000 },
8707 { 0x00000001, 0x00210621, 0x000 },
8708 { 0x00000000, 0x14c00000, 0x610 },
8709 { 0x0004a010, 0x00604411, 0x68a },
8710 { 0x0000a010, 0x00204411, 0x000 },
8711 { 0x00000000, 0x00204810, 0x000 },
8712 { 0x00000001, 0x00210621, 0x000 },
8713 { 0x00000000, 0x002f0221, 0x000 },
8714 { 0x00000000, 0x0ce00000, 0x628 },
8715 { 0x0004a011, 0x00604411, 0x68a },
8716 { 0x0000a011, 0x00204411, 0x000 },
8717 { 0x00000000, 0x00204810, 0x000 },
8718 { 0x0004a012, 0x00604411, 0x68a },
8719 { 0x0000a012, 0x00204411, 0x000 },
8720 { 0x00000000, 0x00204810, 0x000 },
8721 { 0x0004a013, 0x00604411, 0x68a },
8722 { 0x0000a013, 0x00204411, 0x000 },
8723 { 0x00000000, 0x00204810, 0x000 },
8724 { 0x0004a014, 0x00604411, 0x68a },
8725 { 0x0000a014, 0x00204411, 0x000 },
8726 { 0x00000000, 0x00204810, 0x000 },
8727 { 0x0004a015, 0x00604411, 0x68a },
8728 { 0x0000a015, 0x00204411, 0x000 },
8729 { 0x00000000, 0x00204810, 0x000 },
8730 { 0x0004a016, 0x00604411, 0x68a },
8731 { 0x0000a016, 0x00204411, 0x000 },
8732 { 0x00000000, 0x00204810, 0x000 },
8733 { 0x0004a017, 0x00604411, 0x68a },
8734 { 0x0000a017, 0x00204411, 0x000 },
8735 { 0x00000000, 0x00204810, 0x000 },
8736 { 0x00042004, 0x00604411, 0x68a },
8737 { 0x0000002c, 0x0080062d, 0x000 },
8738 { 0xff000000, 0x00204411, 0x000 },
8739 { 0x00000000, 0x00204811, 0x000 },
8740 { 0x00000001, 0x00204811, 0x000 },
8741 { 0x00000002, 0x00804811, 0x000 },
8742 { 0x00000000, 0x0ee00000, 0x63a },
8743 { 0x00000030, 0x0020062d, 0x000 },
8744 { 0x00000002, 0x00280621, 0x000 },
8745 { 0x00000000, 0x002f0221, 0x000 },
8746 { 0x00000000, 0x0ce00000, 0x638 },
8747 { 0x81000000, 0x00204411, 0x000 },
8748 { 0x00000001, 0x00204811, 0x000 },
8749 { 0x00042004, 0x00604411, 0x68a },
8750 { 0x00001000, 0x00200811, 0x000 },
8751 { 0x0000002b, 0x00203622, 0x000 },
8752 { 0x00000000, 0x00600000, 0x63e },
8753 { 0x00000000, 0x00600000, 0x5c6 },
8754 { 0x98000000, 0x00204411, 0x000 },
8755 { 0x00000000, 0x00804811, 0x000 },
8756 { 0x00000000, 0xc0600000, 0x63e },
8757 { 0x00000000, 0xc0400400, 0x001 },
8758 { 0x0000a2a4, 0x00204411, 0x000 },
8759 { 0x00000022, 0x00204811, 0x000 },
8760 { 0x89000000, 0x00204411, 0x000 },
8761 { 0x00000001, 0x00404811, 0x62a },
8762 { 0x97000000, 0x00204411, 0x000 },
8763 { 0x00000000, 0x00204811, 0x000 },
8764 { 0x8a000000, 0x00204411, 0x000 },
8765 { 0x00000000, 0x00404811, 0x62a },
8766 { 0x00000000, 0x00600000, 0x659 },
8767 { 0x00002010, 0x00204411, 0x000 },
8768 { 0x00008000, 0x00204811, 0x000 },
8769 { 0x0001a2a4, 0xc0204411, 0x000 },
8770 { 0x00000016, 0x00604811, 0x36e },
8771 { 0x00002010, 0x00204411, 0x000 },
8772 { 0x00010000, 0x00204811, 0x000 },
8773 { 0x81000000, 0x00204411, 0x000 },
8774 { 0x00000001, 0x00204811, 0x000 },
8775 { 0x0000217c, 0x00204411, 0x000 },
8776 { 0x09800000, 0x00204811, 0x000 },
8777 { 0xffffffff, 0x00204811, 0x000 },
8778 { 0x00000000, 0x00204811, 0x000 },
8779 { 0x00000000, 0x17000000, 0x000 },
8780 { 0x0004217f, 0x00604411, 0x68a },
8781 { 0x0000001f, 0x00210230, 0x000 },
8782 { 0x00000000, 0x14c00000, 0x000 },
8783 { 0x00000004, 0x00404c11, 0x653 },
8784 { 0x00000000, 0x00400000, 0x000 },
8785 { 0x00000017, 0x00201e2d, 0x000 },
8786 { 0x00000004, 0x00291e27, 0x000 },
8787 { 0x00000017, 0x00803627, 0x000 },
8788 { 0x00000017, 0x00201e2d, 0x000 },
8789 { 0xfffffffb, 0x00281e27, 0x000 },
8790 { 0x00000017, 0x00803627, 0x000 },
8791 { 0x00000017, 0x00201e2d, 0x000 },
8792 { 0x00000008, 0x00291e27, 0x000 },
8793 { 0x00000017, 0x00803627, 0x000 },
8794 { 0x00000017, 0x00201e2d, 0x000 },
8795 { 0xfffffff7, 0x00281e27, 0x000 },
8796 { 0x00000017, 0x00803627, 0x000 },
8797 { 0x00002010, 0x00204411, 0x000 },
8798 { 0x00008000, 0x00204811, 0x000 },
8799 { 0x0001a2a4, 0x00204411, 0x000 },
8800 { 0x00000016, 0x00604811, 0x36e },
8801 { 0x00002010, 0x00204411, 0x000 },
8802 { 0x00010000, 0x00204811, 0x000 },
8803 { 0x0000217c, 0x00204411, 0x000 },
8804 { 0x01800000, 0x00204811, 0x000 },
8805 { 0xffffffff, 0x00204811, 0x000 },
8806 { 0x00000000, 0x00204811, 0x000 },
8807 { 0x00000000, 0x17000000, 0x000 },
8808 { 0x81000000, 0x00204411, 0x000 },
8809 { 0x00000001, 0x00204811, 0x000 },
8810 { 0x0004217f, 0x00604411, 0x68a },
8811 { 0x0000001f, 0x00210230, 0x000 },
8812 { 0x00000000, 0x14c00000, 0x689 },
8813 { 0x00000010, 0x00404c11, 0x66f },
8814 { 0x00000000, 0xc0200400, 0x000 },
8815 { 0x00000000, 0x38c00000, 0x000 },
8816 { 0x0000001d, 0x00200a2d, 0x000 },
8817 { 0x0000001e, 0x00200e2d, 0x000 },
8818 { 0x0000001f, 0x0020122d, 0x000 },
8819 { 0x00000020, 0x0020162d, 0x000 },
8820 { 0x00002169, 0x00204411, 0x000 },
8821 { 0x00000000, 0x00204804, 0x000 },
8822 { 0x00000000, 0x00204805, 0x000 },
8823 { 0x00000000, 0x00204801, 0x000 },
8824 { 0xcafebabe, 0x00204811, 0x000 },
8825 { 0x00000004, 0x00301224, 0x000 },
8826 { 0x00000000, 0x002f0064, 0x000 },
8827 { 0x00000000, 0x0cc00000, 0x688 },
8828 { 0x00000003, 0x00281a22, 0x000 },
8829 { 0x00000008, 0x00221222, 0x000 },
8830 { 0xfffff000, 0x00281224, 0x000 },
8831 { 0x00000000, 0x002910c4, 0x000 },
8832 { 0x0000001f, 0x00403624, 0x000 },
8833 { 0x00000000, 0x00800000, 0x000 },
8834 { 0x00000000, 0x1ac00000, 0x68a },
8835 { 0x9f000000, 0x00204411, 0x000 },
8836 { 0xcafebabe, 0x00204811, 0x000 },
8837 { 0x00000000, 0x1ae00000, 0x68d },
8838 { 0x00000000, 0x00800000, 0x000 },
8839 { 0x00000000, 0x1ac00000, 0x68f },
8840 { 0x9e000000, 0x00204411, 0x000 },
8841 { 0xcafebabe, 0x00204811, 0x000 },
8842 { 0x00000000, 0x1ae00000, 0x692 },
8843 { 0x00000000, 0x00800000, 0x000 },
8844 { 0x00000000, 0x00600000, 0x00b },
8845 { 0x00001000, 0x00600411, 0x315 },
8846 { 0x00000000, 0x00200411, 0x000 },
8847 { 0x00000000, 0x00600811, 0x1b2 },
8848 { 0x0000225c, 0x00204411, 0x000 },
8849 { 0x00000003, 0x00204811, 0x000 },
8850 { 0x00002256, 0x00204411, 0x000 },
8851 { 0x0000001b, 0x00204811, 0x000 },
8852 { 0x0000a1fc, 0x00204411, 0x000 },
8853 { 0x00000001, 0x00204811, 0x000 },
8854 { 0x0001a1fd, 0xc0204411, 0x000 },
8855 { 0x00000021, 0x00201e2d, 0x000 },
8856 { 0x00000010, 0x00221e27, 0x000 },
8857 { 0x00000024, 0x0020222d, 0x000 },
8858 { 0x0000ffff, 0x00282228, 0x000 },
8859 { 0x00000000, 0x00294907, 0x000 },
8860 { 0x00000000, 0x00204811, 0x000 },
8861 { 0x00000022, 0x0020222d, 0x000 },
8862 { 0x0000ffff, 0x00282228, 0x000 },
8863 { 0x00000000, 0x00294907, 0x000 },
8864 { 0x00000000, 0x00204811, 0x000 },
8865 { 0x00000023, 0x00201e2d, 0x000 },
8866 { 0x00000010, 0x00221e27, 0x000 },
8867 { 0x00000000, 0x00294907, 0x000 },
8868 { 0x00000000, 0x00404811, 0x000 },
8869 { 0x00000000, 0x00000000, 0x000 },
8870 { 0x00000000, 0x00000000, 0x000 },
8871 { 0x00000000, 0x00000000, 0x000 },
8872 { 0x00000000, 0x00000000, 0x000 },
8873 { 0x00000000, 0x00000000, 0x000 },
8874 { 0x00000000, 0x00000000, 0x000 },
8875 { 0x00000000, 0x00000000, 0x000 },
8876 { 0x00000000, 0x00000000, 0x000 },
8877 { 0x00000000, 0x00000000, 0x000 },
8878 { 0x00000000, 0x00000000, 0x000 },
8879 { 0x00000000, 0x00000000, 0x000 },
8880 { 0x00000000, 0x00000000, 0x000 },
8881 { 0x00000000, 0x00000000, 0x000 },
8882 { 0x00000000, 0x00000000, 0x000 },
8883 { 0x00000000, 0x00000000, 0x000 },
8884 { 0x00000000, 0x00000000, 0x000 },
8885 { 0x00000000, 0x00000000, 0x000 },
8886 { 0x00000000, 0x00000000, 0x000 },
8887 { 0x00000000, 0x00000000, 0x000 },
8888 { 0x00000000, 0x00000000, 0x000 },
8889 { 0x00000000, 0x00000000, 0x000 },
8890 { 0x00000000, 0x00000000, 0x000 },
8891 { 0x00000000, 0x00000000, 0x000 },
8892 { 0x00000000, 0x00000000, 0x000 },
8893 { 0x00000000, 0x00000000, 0x000 },
8894 { 0x00000000, 0x00000000, 0x000 },
8895 { 0x00000000, 0x00000000, 0x000 },
8896 { 0x00000000, 0x00000000, 0x000 },
8897 { 0x00000000, 0x00000000, 0x000 },
8898 { 0x00000000, 0x00000000, 0x000 },
8899 { 0x00000000, 0x00000000, 0x000 },
8900 { 0x00000000, 0x00000000, 0x000 },
8901 { 0x00000000, 0x00000000, 0x000 },
8902 { 0x00000000, 0x00000000, 0x000 },
8903 { 0x00000000, 0x00000000, 0x000 },
8904 { 0x00000000, 0x00000000, 0x000 },
8905 { 0x00000000, 0x00000000, 0x000 },
8906 { 0x00000000, 0x00000000, 0x000 },
8907 { 0x00000000, 0x00000000, 0x000 },
8908 { 0x00000000, 0x00000000, 0x000 },
8909 { 0x00000000, 0x00000000, 0x000 },
8910 { 0x00000000, 0x00000000, 0x000 },
8911 { 0x00000000, 0x00000000, 0x000 },
8912 { 0x00000000, 0x00000000, 0x000 },
8913 { 0x00000000, 0x00000000, 0x000 },
8914 { 0x00000000, 0x00000000, 0x000 },
8915 { 0x00000000, 0x00000000, 0x000 },
8916 { 0x00000000, 0x00000000, 0x000 },
8917 { 0x00000000, 0x00000000, 0x000 },
8918 { 0x00000000, 0x00000000, 0x000 },
8919 { 0x00000000, 0x00000000, 0x000 },
8920 { 0x00000000, 0x00000000, 0x000 },
8921 { 0x00000000, 0x00000000, 0x000 },
8922 { 0x00000000, 0x00000000, 0x000 },
8923 { 0x00000000, 0x00000000, 0x000 },
8924 { 0x014204ff, 0x05bd0250, 0x000 },
8925 { 0x01c30168, 0x043f05bd, 0x000 },
8926 { 0x02250209, 0x02500151, 0x000 },
8927 { 0x02230245, 0x02a00241, 0x000 },
8928 { 0x03d705bd, 0x05bd05bd, 0x000 },
8929 { 0x06460647, 0x031f05bd, 0x000 },
8930 { 0x05bd05c2, 0x03200340, 0x000 },
8931 { 0x032a0282, 0x03420334, 0x000 },
8932 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8933 { 0x05bd054e, 0x05bd05bd, 0x000 },
8934 { 0x03ba05bd, 0x04b80344, 0x000 },
8935 { 0x0497044d, 0x043d05bd, 0x000 },
8936 { 0x04cd05bd, 0x044104da, 0x000 },
8937 { 0x044d0504, 0x03510375, 0x000 },
8938 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8939 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8940 { 0x05bd05bd, 0x063c05c4, 0x000 },
8941 { 0x05bd05bd, 0x000705bd, 0x000 },
8942 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8943 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8944 { 0x03f803ed, 0x04080406, 0x000 },
8945 { 0x040e040a, 0x040c0410, 0x000 },
8946 { 0x041c0418, 0x04240420, 0x000 },
8947 { 0x042c0428, 0x04340430, 0x000 },
8948 { 0x05bd05bd, 0x043805bd, 0x000 },
8949 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8950 { 0x05bd05bd, 0x05bd05bd, 0x000 },
8951 { 0x00020676, 0x06940006, 0x000 },
8952};
8953
8954static const u32 RV630_pfp_microcode[] = {
89550xca0400,
89560xa00000,
89570x7e828b,
89580x7c038b,
89590x8001b8,
89600x7c038b,
89610xd4401e,
89620xee001e,
89630xca0400,
89640xa00000,
89650x7e828b,
89660xc41838,
89670xca2400,
89680xca2800,
89690x9581a8,
89700xc41c3a,
89710xc3c000,
89720xca0800,
89730xca0c00,
89740x7c744b,
89750xc20005,
89760x99c000,
89770xc41c3a,
89780x7c744c,
89790xc0fff0,
89800x042c04,
89810x309002,
89820x7d2500,
89830x351402,
89840x7d350b,
89850x255403,
89860x7cd580,
89870x259c03,
89880x95c004,
89890xd5001b,
89900x7eddc1,
89910x7d9d80,
89920xd6801b,
89930xd5801b,
89940xd4401e,
89950xd5401e,
89960xd6401e,
89970xd6801e,
89980xd4801e,
89990xd4c01e,
90000x9783d3,
90010xd5c01e,
90020xca0800,
90030x80001a,
90040xca0c00,
90050xe4011e,
90060xd4001e,
90070x80000c,
90080xc41838,
90090xe4013e,
90100xd4001e,
90110x80000c,
90120xc41838,
90130xd4401e,
90140xee001e,
90150xca0400,
90160xa00000,
90170x7e828b,
90180xe4011e,
90190xd4001e,
90200xd4401e,
90210xee001e,
90220xca0400,
90230xa00000,
90240x7e828b,
90250xe4013e,
90260xd4001e,
90270xd4401e,
90280xee001e,
90290xca0400,
90300xa00000,
90310x7e828b,
90320xca1800,
90330xd4401e,
90340xd5801e,
90350x800053,
90360xd40075,
90370xd4401e,
90380xca0800,
90390xca0c00,
90400xca1000,
90410xd48019,
90420xd4c018,
90430xd50017,
90440xd4801e,
90450xd4c01e,
90460xd5001e,
90470xe2001e,
90480xca0400,
90490xa00000,
90500x7e828b,
90510xca0800,
90520xd48060,
90530xd4401e,
90540x800000,
90550xd4801e,
90560xca0800,
90570xd48061,
90580xd4401e,
90590x800000,
90600xd4801e,
90610xca0800,
90620xca0c00,
90630xd4401e,
90640xd48016,
90650xd4c016,
90660xd4801e,
90670x8001b8,
90680xd4c01e,
90690xc60843,
90700xca0c00,
90710xca1000,
90720x948004,
90730xca1400,
90740xe420f3,
90750xd42013,
90760xd56065,
90770xd4e01c,
90780xd5201c,
90790xd5601c,
90800x800000,
90810x062001,
90820xc60843,
90830xca0c00,
90840xca1000,
90850x9483f7,
90860xca1400,
90870xe420f3,
90880x800079,
90890xd42013,
90900xc60843,
90910xca0c00,
90920xca1000,
90930x9883ef,
90940xca1400,
90950xd40064,
90960x80008d,
90970x000000,
90980xc41432,
90990xc61843,
91000xc4082f,
91010x954005,
91020xc40c30,
91030xd4401e,
91040x800000,
91050xee001e,
91060x9583f5,
91070xc41031,
91080xd44033,
91090xd52065,
91100xd4a01c,
91110xd4e01c,
91120xd5201c,
91130xe4015e,
91140xd4001e,
91150x800000,
91160x062001,
91170xca1800,
91180x0a2001,
91190xd60076,
91200xc40836,
91210x988007,
91220xc61045,
91230x950110,
91240xd4001f,
91250xd46062,
91260x800000,
91270xd42062,
91280xcc3835,
91290xcc1433,
91300x8401bb,
91310xd40072,
91320xd5401e,
91330x800000,
91340xee001e,
91350xe2001a,
91360x8401bb,
91370xe2001a,
91380xcc104b,
91390xcc0447,
91400x2c9401,
91410x7d098b,
91420x984005,
91430x7d15cb,
91440xd4001a,
91450x8001b8,
91460xd4006d,
91470x344401,
91480xcc0c48,
91490x98403a,
91500xcc2c4a,
91510x958004,
91520xcc0449,
91530x8001b8,
91540xd4001a,
91550xd4c01a,
91560x282801,
91570x8400f0,
91580xcc1003,
91590x98801b,
91600x04380c,
91610x8400f0,
91620xcc1003,
91630x988017,
91640x043808,
91650x8400f0,
91660xcc1003,
91670x988013,
91680x043804,
91690x8400f0,
91700xcc1003,
91710x988014,
91720xcc104c,
91730x9a8009,
91740xcc144d,
91750x9840dc,
91760xd4006d,
91770xcc1848,
91780xd5001a,
91790xd5401a,
91800x8000c9,
91810xd5801a,
91820x96c0d5,
91830xd4006d,
91840x8001b8,
91850xd4006e,
91860x9ac003,
91870xd4006d,
91880xd4006e,
91890x800000,
91900xec007f,
91910x9ac0cc,
91920xd4006d,
91930x8001b8,
91940xd4006e,
91950xcc1403,
91960xcc1803,
91970xcc1c03,
91980x7d9103,
91990x7dd583,
92000x7d190c,
92010x35cc1f,
92020x35701f,
92030x7cf0cb,
92040x7cd08b,
92050x880000,
92060x7e8e8b,
92070x95c004,
92080xd4006e,
92090x8001b8,
92100xd4001a,
92110xd4c01a,
92120xcc0803,
92130xcc0c03,
92140xcc1003,
92150xcc1403,
92160xcc1803,
92170xcc1c03,
92180xcc2403,
92190xcc2803,
92200x35c41f,
92210x36b01f,
92220x7c704b,
92230x34f01f,
92240x7c704b,
92250x35701f,
92260x7c704b,
92270x7d8881,
92280x7dccc1,
92290x7e5101,
92300x7e9541,
92310x7c9082,
92320x7cd4c2,
92330x7c848b,
92340x9ac003,
92350x7c8c8b,
92360x2c8801,
92370x98809e,
92380xd4006d,
92390x98409c,
92400xd4006e,
92410xcc084c,
92420xcc0c4d,
92430xcc1048,
92440xd4801a,
92450xd4c01a,
92460x800101,
92470xd5001a,
92480xcc0832,
92490xd40032,
92500x9482d9,
92510xca0c00,
92520xd4401e,
92530x800000,
92540xd4001e,
92550xe4011e,
92560xd4001e,
92570xca0800,
92580xca0c00,
92590xca1000,
92600xd4401e,
92610xca1400,
92620xd4801e,
92630xd4c01e,
92640xd5001e,
92650xd5401e,
92660xd54034,
92670x800000,
92680xee001e,
92690x280404,
92700xe2001a,
92710xe2001a,
92720xd4401a,
92730xca3800,
92740xcc0803,
92750xcc0c03,
92760xcc0c03,
92770xcc0c03,
92780x9882bd,
92790x000000,
92800x8401bb,
92810xd7a06f,
92820x800000,
92830xee001f,
92840xca0400,
92850xc2ff00,
92860xcc0834,
92870xc13fff,
92880x7c74cb,
92890x7cc90b,
92900x7d010f,
92910x9902b0,
92920x7c738b,
92930x8401bb,
92940xd7a06f,
92950x800000,
92960xee001f,
92970xca0800,
92980x281900,
92990x7d898b,
93000x958014,
93010x281404,
93020xca0c00,
93030xca1000,
93040xca1c00,
93050xca2400,
93060xe2001f,
93070xd4c01a,
93080xd5001a,
93090xd5401a,
93100xcc1803,
93110xcc2c03,
93120xcc2c03,
93130xcc2c03,
93140x7da58b,
93150x7d9c47,
93160x984297,
93170x000000,
93180x800161,
93190xd4c01a,
93200xd4401e,
93210xd4801e,
93220x800000,
93230xee001e,
93240xe4011e,
93250xd4001e,
93260xd4401e,
93270xee001e,
93280xca0400,
93290xa00000,
93300x7e828b,
93310xe4013e,
93320xd4001e,
93330xd4401e,
93340xee001e,
93350xca0400,
93360xa00000,
93370x7e828b,
93380xca0800,
93390x248c06,
93400x0ccc06,
93410x98c006,
93420xcc104e,
93430x990004,
93440xd40073,
93450xe4011e,
93460xd4001e,
93470xd4401e,
93480xd4801e,
93490x800000,
93500xee001e,
93510xca0800,
93520xca0c00,
93530x34d018,
93540x251001,
93550x950021,
93560xc17fff,
93570xca1000,
93580xca1400,
93590xca1800,
93600xd4801d,
93610xd4c01d,
93620x7db18b,
93630xc14202,
93640xc2c001,
93650xd5801d,
93660x34dc0e,
93670x7d5d4c,
93680x7f734c,
93690xd7401e,
93700xd5001e,
93710xd5401e,
93720xc14200,
93730xc2c000,
93740x099c01,
93750x31dc10,
93760x7f5f4c,
93770x7f734c,
93780x042802,
93790x7d8380,
93800xd5a86f,
93810xd58066,
93820xd7401e,
93830xec005e,
93840xc82402,
93850xc82402,
93860x8001b8,
93870xd60076,
93880xd4401e,
93890xd4801e,
93900xd4c01e,
93910x800000,
93920xee001e,
93930x800000,
93940xee001f,
93950xd4001f,
93960x800000,
93970xd4001f,
93980xd4001f,
93990x880000,
94000xd4001f,
94010x000000,
94020x000000,
94030x000000,
94040x000000,
94050x000000,
94060x000000,
94070x000000,
94080x000000,
94090x000000,
94100x000000,
94110x000000,
94120x000000,
94130x000000,
94140x000000,
94150x000000,
94160x000000,
94170x000000,
94180x000000,
94190x000000,
94200x000000,
94210x000000,
94220x000000,
94230x000000,
94240x000000,
94250x000000,
94260x000000,
94270x000000,
94280x000000,
94290x000000,
94300x000000,
94310x000000,
94320x000000,
94330x000000,
94340x000000,
94350x000000,
94360x000000,
94370x000000,
94380x000000,
94390x000000,
94400x000000,
94410x000000,
94420x000000,
94430x000000,
94440x000000,
94450x000000,
94460x000000,
94470x000000,
94480x000000,
94490x000000,
94500x000000,
94510x000000,
94520x000000,
94530x000000,
94540x000000,
94550x000000,
94560x000000,
94570x000000,
94580x000000,
94590x000000,
94600x000000,
94610x000000,
94620x000000,
94630x000000,
94640x000000,
94650x000000,
94660x000000,
94670x010171,
94680x020178,
94690x03008f,
94700x04007f,
94710x050003,
94720x06003f,
94730x070032,
94740x08012c,
94750x090046,
94760x0a0036,
94770x1001b6,
94780x1700a2,
94790x22013a,
94800x230149,
94810x2000b4,
94820x240125,
94830x27004d,
94840x28006a,
94850x2a0060,
94860x2b0052,
94870x2f0065,
94880x320087,
94890x34017f,
94900x3c0156,
94910x3f0072,
94920x41018c,
94930x44012e,
94940x550173,
94950x56017a,
94960x60000b,
94970x610034,
94980x620038,
94990x630038,
95000x640038,
95010x650038,
95020x660038,
95030x670038,
95040x68003a,
95050x690041,
95060x6a0048,
95070x6b0048,
95080x6c0048,
95090x6d0048,
95100x6e0048,
95110x6f0048,
95120x000006,
95130x000006,
95140x000006,
95150x000006,
95160x000006,
95170x000006,
95180x000006,
95190x000006,
95200x000006,
95210x000006,
95220x000006,
95230x000006,
95240x000006,
95250x000006,
95260x000006,
95270x000006,
95280x000006,
95290x000006,
95300x000006,
9531};
9532
9533static const u32 RV635_cp_microcode[][3] = {
9534 { 0x00000000, 0xc0200400, 0x000 },
9535 { 0x00000000, 0x00a0000a, 0x000 },
9536 { 0x0000ffff, 0x00284621, 0x000 },
9537 { 0x00000000, 0xd9004800, 0x000 },
9538 { 0x00000000, 0xc0200400, 0x000 },
9539 { 0x00000000, 0x00a0000a, 0x000 },
9540 { 0x00000000, 0x00e00000, 0x000 },
9541 { 0x00010000, 0xc0294620, 0x000 },
9542 { 0x00000000, 0xd9004800, 0x000 },
9543 { 0x00000000, 0xc0200400, 0x000 },
9544 { 0x00000000, 0x00a0000a, 0x000 },
9545 { 0x81000000, 0x00204411, 0x000 },
9546 { 0x00000001, 0x00204811, 0x000 },
9547 { 0x00042004, 0x00604411, 0x68a },
9548 { 0x00000000, 0x00600000, 0x62e },
9549 { 0x00000000, 0x00600000, 0x642 },
9550 { 0x00000000, 0xc0200800, 0x000 },
9551 { 0x00000f00, 0x00281622, 0x000 },
9552 { 0x00000008, 0x00211625, 0x000 },
9553 { 0x00000018, 0x00203625, 0x000 },
9554 { 0x8d000000, 0x00204411, 0x000 },
9555 { 0x00000004, 0x002f0225, 0x000 },
9556 { 0x00000000, 0x0ce00000, 0x018 },
9557 { 0x00412000, 0x00404811, 0x019 },
9558 { 0x00422000, 0x00204811, 0x000 },
9559 { 0x8e000000, 0x00204411, 0x000 },
9560 { 0x00000028, 0x00204a2d, 0x000 },
9561 { 0x90000000, 0x00204411, 0x000 },
9562 { 0x00000000, 0x00204805, 0x000 },
9563 { 0x0000000c, 0x00211622, 0x000 },
9564 { 0x00000003, 0x00281625, 0x000 },
9565 { 0x00000019, 0x00211a22, 0x000 },
9566 { 0x00000004, 0x00281a26, 0x000 },
9567 { 0x00000000, 0x002914c5, 0x000 },
9568 { 0x00000019, 0x00203625, 0x000 },
9569 { 0x00000000, 0x003a1402, 0x000 },
9570 { 0x00000016, 0x00211625, 0x000 },
9571 { 0x00000003, 0x00281625, 0x000 },
9572 { 0x00000017, 0x00200e2d, 0x000 },
9573 { 0xfffffffc, 0x00280e23, 0x000 },
9574 { 0x00000000, 0x002914a3, 0x000 },
9575 { 0x00000017, 0x00203625, 0x000 },
9576 { 0x00008000, 0x00280e22, 0x000 },
9577 { 0x00000007, 0x00220e23, 0x000 },
9578 { 0x00000000, 0x0029386e, 0x000 },
9579 { 0x20000000, 0x00280e22, 0x000 },
9580 { 0x00000006, 0x00210e23, 0x000 },
9581 { 0x00000000, 0x0029386e, 0x000 },
9582 { 0x00000000, 0x00220222, 0x000 },
9583 { 0x00000000, 0x14e00000, 0x038 },
9584 { 0x00000000, 0x2ee00000, 0x035 },
9585 { 0x00000000, 0x2ce00000, 0x037 },
9586 { 0x00000000, 0x00400e2d, 0x039 },
9587 { 0x00000008, 0x00200e2d, 0x000 },
9588 { 0x00000009, 0x0040122d, 0x046 },
9589 { 0x00000001, 0x00400e2d, 0x039 },
9590 { 0x00000000, 0xc0200c00, 0x000 },
9591 { 0x003ffffc, 0x00281223, 0x000 },
9592 { 0x00000002, 0x00221224, 0x000 },
9593 { 0x0000001f, 0x00211e23, 0x000 },
9594 { 0x00000000, 0x14e00000, 0x03e },
9595 { 0x00000008, 0x00401c11, 0x041 },
9596 { 0x0000000d, 0x00201e2d, 0x000 },
9597 { 0x0000000f, 0x00281e27, 0x000 },
9598 { 0x00000003, 0x00221e27, 0x000 },
9599 { 0x7fc00000, 0x00281a23, 0x000 },
9600 { 0x00000014, 0x00211a26, 0x000 },
9601 { 0x00000001, 0x00331a26, 0x000 },
9602 { 0x00000008, 0x00221a26, 0x000 },
9603 { 0x00000000, 0x00290cc7, 0x000 },
9604 { 0x00000027, 0x00203624, 0x000 },
9605 { 0x00007f00, 0x00281221, 0x000 },
9606 { 0x00001400, 0x002f0224, 0x000 },
9607 { 0x00000000, 0x0ce00000, 0x04b },
9608 { 0x00000001, 0x00290e23, 0x000 },
9609 { 0x0000000e, 0x00203623, 0x000 },
9610 { 0x0000e000, 0x00204411, 0x000 },
9611 { 0xfff80000, 0x00294a23, 0x000 },
9612 { 0x00000000, 0x003a2c02, 0x000 },
9613 { 0x00000002, 0x00220e2b, 0x000 },
9614 { 0xfc000000, 0x00280e23, 0x000 },
9615 { 0x0000000f, 0x00203623, 0x000 },
9616 { 0x00001fff, 0x00294a23, 0x000 },
9617 { 0x00000027, 0x00204a2d, 0x000 },
9618 { 0x00000000, 0x00204811, 0x000 },
9619 { 0x00000029, 0x00200e2d, 0x000 },
9620 { 0x060a0200, 0x00294a23, 0x000 },
9621 { 0x00000000, 0x00204811, 0x000 },
9622 { 0x00000000, 0x00204811, 0x000 },
9623 { 0x00000001, 0x00210222, 0x000 },
9624 { 0x00000000, 0x14e00000, 0x061 },
9625 { 0x00000000, 0x2ee00000, 0x05f },
9626 { 0x00000000, 0x2ce00000, 0x05e },
9627 { 0x00000000, 0x00400e2d, 0x062 },
9628 { 0x00000001, 0x00400e2d, 0x062 },
9629 { 0x0000000a, 0x00200e2d, 0x000 },
9630 { 0x0000000b, 0x0040122d, 0x06a },
9631 { 0x00000000, 0xc0200c00, 0x000 },
9632 { 0x003ffffc, 0x00281223, 0x000 },
9633 { 0x00000002, 0x00221224, 0x000 },
9634 { 0x7fc00000, 0x00281623, 0x000 },
9635 { 0x00000014, 0x00211625, 0x000 },
9636 { 0x00000001, 0x00331625, 0x000 },
9637 { 0x80000000, 0x00280e23, 0x000 },
9638 { 0x00000000, 0x00290ca3, 0x000 },
9639 { 0x3ffffc00, 0x00290e23, 0x000 },
9640 { 0x0000001f, 0x00211e23, 0x000 },
9641 { 0x00000000, 0x14e00000, 0x06d },
9642 { 0x00000100, 0x00401c11, 0x070 },
9643 { 0x0000000d, 0x00201e2d, 0x000 },
9644 { 0x000000f0, 0x00281e27, 0x000 },
9645 { 0x00000004, 0x00221e27, 0x000 },
9646 { 0x81000000, 0x00204411, 0x000 },
9647 { 0x0000000d, 0x00204811, 0x000 },
9648 { 0xfffff0ff, 0x00281a30, 0x000 },
9649 { 0x0000a028, 0x00204411, 0x000 },
9650 { 0x00000000, 0x002948e6, 0x000 },
9651 { 0x0000a018, 0x00204411, 0x000 },
9652 { 0x3fffffff, 0x00284a23, 0x000 },
9653 { 0x0000a010, 0x00204411, 0x000 },
9654 { 0x00000000, 0x00204804, 0x000 },
9655 { 0x00000030, 0x0020162d, 0x000 },
9656 { 0x00000002, 0x00291625, 0x000 },
9657 { 0x00000030, 0x00203625, 0x000 },
9658 { 0x00000025, 0x0020162d, 0x000 },
9659 { 0x00000000, 0x002f00a3, 0x000 },
9660 { 0x00000000, 0x0cc00000, 0x083 },
9661 { 0x00000026, 0x0020162d, 0x000 },
9662 { 0x00000000, 0x002f00a4, 0x000 },
9663 { 0x00000000, 0x0cc00000, 0x084 },
9664 { 0x00000000, 0x00400000, 0x08a },
9665 { 0x00000025, 0x00203623, 0x000 },
9666 { 0x00000026, 0x00203624, 0x000 },
9667 { 0x00000017, 0x00201e2d, 0x000 },
9668 { 0x00000002, 0x00210227, 0x000 },
9669 { 0x00000000, 0x14e00000, 0x08a },
9670 { 0x00000000, 0x00600000, 0x665 },
9671 { 0x00000000, 0x00600000, 0x659 },
9672 { 0x00000002, 0x00210e22, 0x000 },
9673 { 0x00000000, 0x14c00000, 0x08d },
9674 { 0x00000012, 0xc0403620, 0x093 },
9675 { 0x00000000, 0x2ee00000, 0x091 },
9676 { 0x00000000, 0x2ce00000, 0x090 },
9677 { 0x00000002, 0x00400e2d, 0x092 },
9678 { 0x00000003, 0x00400e2d, 0x092 },
9679 { 0x0000000c, 0x00200e2d, 0x000 },
9680 { 0x00000012, 0x00203623, 0x000 },
9681 { 0x00000003, 0x00210e22, 0x000 },
9682 { 0x00000000, 0x14c00000, 0x098 },
9683 { 0x0000a00c, 0x00204411, 0x000 },
9684 { 0x00000000, 0xc0204800, 0x000 },
9685 { 0x00000000, 0xc0404800, 0x0a0 },
9686 { 0x0000a00c, 0x00204411, 0x000 },
9687 { 0x00000000, 0x00204811, 0x000 },
9688 { 0x00000000, 0x2ee00000, 0x09e },
9689 { 0x00000000, 0x2ce00000, 0x09d },
9690 { 0x00000002, 0x00400e2d, 0x09f },
9691 { 0x00000003, 0x00400e2d, 0x09f },
9692 { 0x0000000c, 0x00200e2d, 0x000 },
9693 { 0x00000000, 0x00204803, 0x000 },
9694 { 0x00000000, 0x003a0c02, 0x000 },
9695 { 0x003f0000, 0x00280e23, 0x000 },
9696 { 0x00000010, 0x00210e23, 0x000 },
9697 { 0x00000011, 0x00203623, 0x000 },
9698 { 0x0000001e, 0x0021022b, 0x000 },
9699 { 0x00000000, 0x14c00000, 0x0a7 },
9700 { 0x00000016, 0xc0203620, 0x000 },
9701 { 0x0000001f, 0x0021022b, 0x000 },
9702 { 0x00000000, 0x14c00000, 0x0aa },
9703 { 0x00000015, 0xc0203620, 0x000 },
9704 { 0x00000008, 0x00210e2b, 0x000 },
9705 { 0x0000007f, 0x00280e23, 0x000 },
9706 { 0x00000000, 0x002f0223, 0x000 },
9707 { 0x00000000, 0x0ce00000, 0x0e1 },
9708 { 0x00000000, 0x27000000, 0x000 },
9709 { 0x00000000, 0x00600000, 0x2a3 },
9710 { 0x00000001, 0x002f0223, 0x000 },
9711 { 0x00000000, 0x0ae00000, 0x0b3 },
9712 { 0x00000000, 0x00600000, 0x13a },
9713 { 0x81000000, 0x00204411, 0x000 },
9714 { 0x00000006, 0x00204811, 0x000 },
9715 { 0x0000000c, 0x00221e30, 0x000 },
9716 { 0x99800000, 0x00204411, 0x000 },
9717 { 0x00000004, 0x0020122d, 0x000 },
9718 { 0x00000008, 0x00221224, 0x000 },
9719 { 0x00000010, 0x00201811, 0x000 },
9720 { 0x00000000, 0x00291ce4, 0x000 },
9721 { 0x00000000, 0x00604807, 0x12f },
9722 { 0x9b000000, 0x00204411, 0x000 },
9723 { 0x00000000, 0x00204802, 0x000 },
9724 { 0x9c000000, 0x00204411, 0x000 },
9725 { 0x00000000, 0x0033146f, 0x000 },
9726 { 0x00000001, 0x00333e23, 0x000 },
9727 { 0x00000000, 0xd9004800, 0x000 },
9728 { 0x00000000, 0x00203c05, 0x000 },
9729 { 0x81000000, 0x00204411, 0x000 },
9730 { 0x0000000e, 0x00204811, 0x000 },
9731 { 0x00000000, 0x00201010, 0x000 },
9732 { 0x0000e007, 0x00204411, 0x000 },
9733 { 0x0000000f, 0x0021022b, 0x000 },
9734 { 0x00000000, 0x14c00000, 0x0cb },
9735 { 0x00f8ff08, 0x00204811, 0x000 },
9736 { 0x98000000, 0x00404811, 0x0dc },
9737 { 0x000000f0, 0x00280e22, 0x000 },
9738 { 0x000000a0, 0x002f0223, 0x000 },
9739 { 0x00000000, 0x0cc00000, 0x0da },
9740 { 0x00000011, 0x00200e2d, 0x000 },
9741 { 0x00000001, 0x002f0223, 0x000 },
9742 { 0x00000000, 0x0ce00000, 0x0d5 },
9743 { 0x00000002, 0x002f0223, 0x000 },
9744 { 0x00000000, 0x0ce00000, 0x0d4 },
9745 { 0x00003f00, 0x00400c11, 0x0d6 },
9746 { 0x00001f00, 0x00400c11, 0x0d6 },
9747 { 0x00000f00, 0x00200c11, 0x000 },
9748 { 0x00380009, 0x00294a23, 0x000 },
9749 { 0x3f000000, 0x00280e2b, 0x000 },
9750 { 0x00000002, 0x00220e23, 0x000 },
9751 { 0x00000007, 0x00494a23, 0x0dc },
9752 { 0x00380f09, 0x00204811, 0x000 },
9753 { 0x68000007, 0x00204811, 0x000 },
9754 { 0x00000008, 0x00214a27, 0x000 },
9755 { 0x00000000, 0x00204811, 0x000 },
9756 { 0x060a0200, 0x00294a24, 0x000 },
9757 { 0x00000000, 0x00204811, 0x000 },
9758 { 0x00000000, 0x00204811, 0x000 },
9759 { 0x0000a202, 0x00204411, 0x000 },
9760 { 0x00ff0000, 0x00280e22, 0x000 },
9761 { 0x00000080, 0x00294a23, 0x000 },
9762 { 0x00000027, 0x00200e2d, 0x000 },
9763 { 0x00000026, 0x0020122d, 0x000 },
9764 { 0x00000000, 0x002f0083, 0x000 },
9765 { 0x00000000, 0x0ce00000, 0x0ea },
9766 { 0x00000000, 0x00600000, 0x65f },
9767 { 0x00000000, 0x00400000, 0x0eb },
9768 { 0x00000000, 0x00600000, 0x662 },
9769 { 0x00000007, 0x0020222d, 0x000 },
9770 { 0x00000005, 0x00220e22, 0x000 },
9771 { 0x00100000, 0x00280e23, 0x000 },
9772 { 0x00000000, 0x00292068, 0x000 },
9773 { 0x00000000, 0x003a0c02, 0x000 },
9774 { 0x000000ef, 0x00280e23, 0x000 },
9775 { 0x00000000, 0x00292068, 0x000 },
9776 { 0x00000017, 0x00200e2d, 0x000 },
9777 { 0x00000003, 0x00210223, 0x000 },
9778 { 0x00000000, 0x14e00000, 0x0f8 },
9779 { 0x0000000b, 0x00210228, 0x000 },
9780 { 0x00000000, 0x14c00000, 0x0f8 },
9781 { 0x00000400, 0x00292228, 0x000 },
9782 { 0x00000014, 0x00203628, 0x000 },
9783 { 0x0000001c, 0x00210e22, 0x000 },
9784 { 0x00000000, 0x14c00000, 0x0fd },
9785 { 0x0000a30c, 0x00204411, 0x000 },
9786 { 0x00000000, 0x00204811, 0x000 },
9787 { 0x0000001e, 0x00210e22, 0x000 },
9788 { 0x00000000, 0x14c00000, 0x10b },
9789 { 0x0000a30f, 0x00204411, 0x000 },
9790 { 0x00000011, 0x00200e2d, 0x000 },
9791 { 0x00000001, 0x002f0223, 0x000 },
9792 { 0x00000000, 0x0cc00000, 0x104 },
9793 { 0xffffffff, 0x00404811, 0x10b },
9794 { 0x00000002, 0x002f0223, 0x000 },
9795 { 0x00000000, 0x0cc00000, 0x107 },
9796 { 0x0000ffff, 0x00404811, 0x10b },
9797 { 0x00000004, 0x002f0223, 0x000 },
9798 { 0x00000000, 0x0cc00000, 0x10a },
9799 { 0x000000ff, 0x00404811, 0x10b },
9800 { 0x00000001, 0x00204811, 0x000 },
9801 { 0x0002c400, 0x00204411, 0x000 },
9802 { 0x0000001f, 0x00210e22, 0x000 },
9803 { 0x00000000, 0x14c00000, 0x112 },
9804 { 0x00000010, 0x40210e20, 0x000 },
9805 { 0x00000013, 0x00203623, 0x000 },
9806 { 0x00000018, 0x40224a20, 0x000 },
9807 { 0x00000010, 0xc0424a20, 0x114 },
9808 { 0x00000000, 0x00200c11, 0x000 },
9809 { 0x00000013, 0x00203623, 0x000 },
9810 { 0x00000000, 0x00204811, 0x000 },
9811 { 0x00000000, 0x00204811, 0x000 },
9812 { 0x0000000a, 0x00201011, 0x000 },
9813 { 0x00000000, 0x002f0224, 0x000 },
9814 { 0x00000000, 0x0ce00000, 0x11b },
9815 { 0x00000000, 0x00204811, 0x000 },
9816 { 0x00000001, 0x00531224, 0x117 },
9817 { 0xffbfffff, 0x00283a2e, 0x000 },
9818 { 0x0000001b, 0x00210222, 0x000 },
9819 { 0x00000000, 0x14c00000, 0x12e },
9820 { 0x81000000, 0x00204411, 0x000 },
9821 { 0x0000000d, 0x00204811, 0x000 },
9822 { 0x00000018, 0x00220e30, 0x000 },
9823 { 0xfc000000, 0x00280e23, 0x000 },
9824 { 0x81000000, 0x00204411, 0x000 },
9825 { 0x0000000e, 0x00204811, 0x000 },
9826 { 0x00000000, 0x00201010, 0x000 },
9827 { 0x0000e00e, 0x00204411, 0x000 },
9828 { 0x07f8ff08, 0x00204811, 0x000 },
9829 { 0x00000000, 0x00294a23, 0x000 },
9830 { 0x0000001c, 0x00201e2d, 0x000 },
9831 { 0x00000008, 0x00214a27, 0x000 },
9832 { 0x00000000, 0x00204811, 0x000 },
9833 { 0x060a0200, 0x00294a24, 0x000 },
9834 { 0x00000000, 0x00204811, 0x000 },
9835 { 0x00000000, 0x00204811, 0x000 },
9836 { 0x00000000, 0x00800000, 0x000 },
9837 { 0x81000000, 0x00204411, 0x000 },
9838 { 0x00000001, 0x00204811, 0x000 },
9839 { 0x0000217c, 0x00204411, 0x000 },
9840 { 0x00800000, 0x00204811, 0x000 },
9841 { 0x00000000, 0x00204806, 0x000 },
9842 { 0x00000008, 0x00214a27, 0x000 },
9843 { 0x00000000, 0x17000000, 0x000 },
9844 { 0x0004217f, 0x00604411, 0x68a },
9845 { 0x0000001f, 0x00210230, 0x000 },
9846 { 0x00000000, 0x14c00000, 0x689 },
9847 { 0x00000004, 0x00404c11, 0x135 },
9848 { 0x81000000, 0x00204411, 0x000 },
9849 { 0x00000001, 0x00204811, 0x000 },
9850 { 0x000021f8, 0x00204411, 0x000 },
9851 { 0x0000001c, 0x00204811, 0x000 },
9852 { 0x000421f9, 0x00604411, 0x68a },
9853 { 0x00000011, 0x00210230, 0x000 },
9854 { 0x00000000, 0x14e00000, 0x13c },
9855 { 0x00000000, 0x00800000, 0x000 },
9856 { 0x00000000, 0x00600000, 0x00b },
9857 { 0x00000000, 0x00600411, 0x315 },
9858 { 0x00000000, 0x00200411, 0x000 },
9859 { 0x00000000, 0x00600811, 0x1b2 },
9860 { 0x00000000, 0x00600000, 0x160 },
9861 { 0x0000ffff, 0x40280e20, 0x000 },
9862 { 0x00000010, 0xc0211220, 0x000 },
9863 { 0x0000ffff, 0x40280620, 0x000 },
9864 { 0x00000010, 0xc0210a20, 0x000 },
9865 { 0x00000000, 0x00341461, 0x000 },
9866 { 0x00000000, 0x00741882, 0x2bb },
9867 { 0x0001a1fd, 0x00604411, 0x2e0 },
9868 { 0x00003fff, 0x002f022f, 0x000 },
9869 { 0x00000000, 0x0cc00000, 0x147 },
9870 { 0x00000000, 0xc0400400, 0x001 },
9871 { 0x00000000, 0x00600000, 0x00b },
9872 { 0x00000000, 0x00600411, 0x315 },
9873 { 0x00000000, 0x00200411, 0x000 },
9874 { 0x00000000, 0x00600811, 0x1b2 },
9875 { 0x00003fff, 0x002f022f, 0x000 },
9876 { 0x00000000, 0x0ce00000, 0x000 },
9877 { 0x00000000, 0x00600000, 0x160 },
9878 { 0x00000010, 0x40210e20, 0x000 },
9879 { 0x0000ffff, 0xc0281220, 0x000 },
9880 { 0x00000010, 0x40211620, 0x000 },
9881 { 0x0000ffff, 0xc0681a20, 0x2bb },
9882 { 0x0001a1fd, 0x00604411, 0x2e0 },
9883 { 0x00003fff, 0x002f022f, 0x000 },
9884 { 0x00000000, 0x0cc00000, 0x158 },
9885 { 0x00000000, 0xc0400400, 0x001 },
9886 { 0x0000225c, 0x00204411, 0x000 },
9887 { 0x00000001, 0x00300a2f, 0x000 },
9888 { 0x00000001, 0x00210a22, 0x000 },
9889 { 0x00000003, 0x00384a22, 0x000 },
9890 { 0x00002256, 0x00204411, 0x000 },
9891 { 0x0000001a, 0x00204811, 0x000 },
9892 { 0x0000a1fc, 0x00204411, 0x000 },
9893 { 0x00000001, 0x00804811, 0x000 },
9894 { 0x00000000, 0x00600000, 0x00b },
9895 { 0x00000000, 0x00600000, 0x18f },
9896 { 0x00000000, 0x00600000, 0x1a0 },
9897 { 0x00003fff, 0x002f022f, 0x000 },
9898 { 0x00000000, 0x0ce00000, 0x000 },
9899 { 0x00000000, 0x00202c08, 0x000 },
9900 { 0x00000000, 0x00202411, 0x000 },
9901 { 0x00000000, 0x00202811, 0x000 },
9902 { 0x00002256, 0x00204411, 0x000 },
9903 { 0x00000016, 0x00204811, 0x000 },
9904 { 0x0000225c, 0x00204411, 0x000 },
9905 { 0x00000003, 0x00204811, 0x000 },
9906 { 0x93800000, 0x00204411, 0x000 },
9907 { 0x00000002, 0x00221e29, 0x000 },
9908 { 0x00000000, 0x007048eb, 0x19c },
9909 { 0x00000000, 0x00600000, 0x2bb },
9910 { 0x00000001, 0x40330620, 0x000 },
9911 { 0x00000000, 0xc0302409, 0x000 },
9912 { 0x00003fff, 0x002f022f, 0x000 },
9913 { 0x00000000, 0x0ce00000, 0x000 },
9914 { 0x00000000, 0x00600000, 0x2a3 },
9915 { 0x00000000, 0x002f0221, 0x000 },
9916 { 0x00000000, 0x0ae00000, 0x181 },
9917 { 0x00000000, 0x00600000, 0x13a },
9918 { 0x00000000, 0x00400000, 0x186 },
9919 { 0x95000000, 0x00204411, 0x000 },
9920 { 0x00000000, 0x002f0221, 0x000 },
9921 { 0x00000000, 0x0ce00000, 0x186 },
9922 { 0x00000000, 0xc0204800, 0x000 },
9923 { 0x00000001, 0x00530621, 0x182 },
9924 { 0x92000000, 0x00204411, 0x000 },
9925 { 0x00000000, 0xc0604800, 0x197 },
9926 { 0x0001a1fd, 0x00204411, 0x000 },
9927 { 0x00000011, 0x0020062d, 0x000 },
9928 { 0x00000000, 0x0078042a, 0x2fb },
9929 { 0x00000000, 0x00202809, 0x000 },
9930 { 0x00003fff, 0x002f022f, 0x000 },
9931 { 0x00000000, 0x0cc00000, 0x174 },
9932 { 0x00000000, 0xc0400400, 0x001 },
9933 { 0x00000210, 0x00600411, 0x315 },
9934 { 0x00003fff, 0x002f022f, 0x000 },
9935 { 0x00000000, 0x0ce00000, 0x194 },
9936 { 0x00000015, 0xc0203620, 0x000 },
9937 { 0x00000016, 0xc0203620, 0x000 },
9938 { 0x3f800000, 0x00200411, 0x000 },
9939 { 0x46000000, 0x00600811, 0x1b2 },
9940 { 0x00000000, 0x00800000, 0x000 },
9941 { 0x0000a1fc, 0x00204411, 0x000 },
9942 { 0x00003fff, 0x002f022f, 0x000 },
9943 { 0x00000000, 0x0cc00000, 0x19b },
9944 { 0x00000001, 0x00804811, 0x000 },
9945 { 0x00000021, 0x00804811, 0x000 },
9946 { 0x0000ffff, 0x40280e20, 0x000 },
9947 { 0x00000010, 0xc0211220, 0x000 },
9948 { 0x0000ffff, 0x40281620, 0x000 },
9949 { 0x00000010, 0xc0811a20, 0x000 },
9950 { 0x81000000, 0x00204411, 0x000 },
9951 { 0x00000006, 0x00204811, 0x000 },
9952 { 0x00000008, 0x00221e30, 0x000 },
9953 { 0x00000029, 0x00201a2d, 0x000 },
9954 { 0x0000e000, 0x00204411, 0x000 },
9955 { 0xfffbff09, 0x00204811, 0x000 },
9956 { 0x0000000f, 0x0020222d, 0x000 },
9957 { 0x00001fff, 0x00294a28, 0x000 },
9958 { 0x00000006, 0x0020222d, 0x000 },
9959 { 0x00000000, 0x002920e8, 0x000 },
9960 { 0x00000000, 0x00204808, 0x000 },
9961 { 0x00000000, 0x00204811, 0x000 },
9962 { 0x060a0200, 0x00294a26, 0x000 },
9963 { 0x00000000, 0x00204811, 0x000 },
9964 { 0x00000000, 0x00204811, 0x000 },
9965 { 0x00000100, 0x00201811, 0x000 },
9966 { 0x00000008, 0x00621e28, 0x12f },
9967 { 0x00000008, 0x00822228, 0x000 },
9968 { 0x0002c000, 0x00204411, 0x000 },
9969 { 0x00000015, 0x00600e2d, 0x1bd },
9970 { 0x00000016, 0x00600e2d, 0x1bd },
9971 { 0x0000c008, 0x00204411, 0x000 },
9972 { 0x00000017, 0x00200e2d, 0x000 },
9973 { 0x00000000, 0x14c00000, 0x1b9 },
9974 { 0x00000000, 0x00200411, 0x000 },
9975 { 0x00000000, 0x00204801, 0x000 },
9976 { 0x39000000, 0x00204811, 0x000 },
9977 { 0x00000000, 0x00204811, 0x000 },
9978 { 0x00000000, 0x00804802, 0x000 },
9979 { 0x00000018, 0x00202e2d, 0x000 },
9980 { 0x00000000, 0x003b0d63, 0x000 },
9981 { 0x00000008, 0x00224a23, 0x000 },
9982 { 0x00000010, 0x00224a23, 0x000 },
9983 { 0x00000018, 0x00224a23, 0x000 },
9984 { 0x00000000, 0x00804803, 0x000 },
9985 { 0x00000000, 0x00600000, 0x00b },
9986 { 0x00001000, 0x00600411, 0x315 },
9987 { 0x00000000, 0x00200411, 0x000 },
9988 { 0x00000000, 0x00600811, 0x1b2 },
9989 { 0x00000007, 0x0021062f, 0x000 },
9990 { 0x00000013, 0x00200a2d, 0x000 },
9991 { 0x00000001, 0x00202c11, 0x000 },
9992 { 0x0000ffff, 0x40282220, 0x000 },
9993 { 0x0000000f, 0x00262228, 0x000 },
9994 { 0x00000010, 0x40212620, 0x000 },
9995 { 0x0000000f, 0x00262629, 0x000 },
9996 { 0x00000000, 0x00202802, 0x000 },
9997 { 0x00002256, 0x00204411, 0x000 },
9998 { 0x0000001b, 0x00204811, 0x000 },
9999 { 0x00000000, 0x002f0221, 0x000 },
10000 { 0x00000000, 0x0ce00000, 0x1e0 },
10001 { 0x0000225c, 0x00204411, 0x000 },
10002 { 0x00000081, 0x00204811, 0x000 },
10003 { 0x0000a1fc, 0x00204411, 0x000 },
10004 { 0x00000001, 0x00204811, 0x000 },
10005 { 0x00000080, 0x00201c11, 0x000 },
10006 { 0x00000000, 0x002f0227, 0x000 },
10007 { 0x00000000, 0x0ce00000, 0x1dc },
10008 { 0x00000000, 0x00600000, 0x1e9 },
10009 { 0x00000001, 0x00531e27, 0x1d8 },
10010 { 0x00000001, 0x00202c11, 0x000 },
10011 { 0x0000001f, 0x00280a22, 0x000 },
10012 { 0x0000001f, 0x00282a2a, 0x000 },
10013 { 0x00000001, 0x00530621, 0x1d1 },
10014 { 0x0000225c, 0x00204411, 0x000 },
10015 { 0x00000002, 0x00304a2f, 0x000 },
10016 { 0x0000a1fc, 0x00204411, 0x000 },
10017 { 0x00000001, 0x00204811, 0x000 },
10018 { 0x00000001, 0x00301e2f, 0x000 },
10019 { 0x00000000, 0x002f0227, 0x000 },
10020 { 0x00000000, 0x0ce00000, 0x000 },
10021 { 0x00000000, 0x00600000, 0x1e9 },
10022 { 0x00000001, 0x00531e27, 0x1e5 },
10023 { 0x0000ffff, 0x40280e20, 0x000 },
10024 { 0x0000000f, 0x00260e23, 0x000 },
10025 { 0x00000010, 0xc0211220, 0x000 },
10026 { 0x0000000f, 0x00261224, 0x000 },
10027 { 0x00000000, 0x00201411, 0x000 },
10028 { 0x00000000, 0x00601811, 0x2bb },
10029 { 0x0001a1fd, 0x00204411, 0x000 },
10030 { 0x00000000, 0x002f022b, 0x000 },
10031 { 0x00000000, 0x0ce00000, 0x1f8 },
10032 { 0x00000010, 0x00221628, 0x000 },
10033 { 0xffff0000, 0x00281625, 0x000 },
10034 { 0x0000ffff, 0x00281a29, 0x000 },
10035 { 0x00000000, 0x002948c5, 0x000 },
10036 { 0x00000000, 0x0020480a, 0x000 },
10037 { 0x00000000, 0x00202c11, 0x000 },
10038 { 0x00000010, 0x00221623, 0x000 },
10039 { 0xffff0000, 0x00281625, 0x000 },
10040 { 0x0000ffff, 0x00281a24, 0x000 },
10041 { 0x00000000, 0x002948c5, 0x000 },
10042 { 0x00000000, 0x00731503, 0x205 },
10043 { 0x00000000, 0x00201805, 0x000 },
10044 { 0x00000000, 0x00731524, 0x205 },
10045 { 0x00000000, 0x002d14c5, 0x000 },
10046 { 0x00000000, 0x003008a2, 0x000 },
10047 { 0x00000000, 0x00204802, 0x000 },
10048 { 0x00000000, 0x00202802, 0x000 },
10049 { 0x00000000, 0x00202003, 0x000 },
10050 { 0x00000000, 0x00802404, 0x000 },
10051 { 0x0000000f, 0x00210225, 0x000 },
10052 { 0x00000000, 0x14c00000, 0x689 },
10053 { 0x00000000, 0x002b1405, 0x000 },
10054 { 0x00000001, 0x00901625, 0x000 },
10055 { 0x00000000, 0x00600000, 0x00b },
10056 { 0x00000000, 0x00600411, 0x315 },
10057 { 0x00000000, 0x00200411, 0x000 },
10058 { 0x00000000, 0x00600811, 0x1b2 },
10059 { 0x00002256, 0x00204411, 0x000 },
10060 { 0x0000001a, 0x00294a22, 0x000 },
10061 { 0x00000000, 0xc0200000, 0x000 },
10062 { 0x00003fff, 0x002f022f, 0x000 },
10063 { 0x00000000, 0x0ce00000, 0x000 },
10064 { 0x00000000, 0xc0200400, 0x000 },
10065 { 0x0000225c, 0x00204411, 0x000 },
10066 { 0x00000003, 0x00384a21, 0x000 },
10067 { 0x0000a1fc, 0x00204411, 0x000 },
10068 { 0x00000001, 0x00204811, 0x000 },
10069 { 0x0000ffff, 0x40281220, 0x000 },
10070 { 0x00000010, 0xc0211a20, 0x000 },
10071 { 0x0000ffff, 0x40280e20, 0x000 },
10072 { 0x00000010, 0xc0211620, 0x000 },
10073 { 0x00000000, 0x00741465, 0x2bb },
10074 { 0x0001a1fd, 0x00604411, 0x2e0 },
10075 { 0x00000001, 0x00330621, 0x000 },
10076 { 0x00000000, 0x002f0221, 0x000 },
10077 { 0x00000000, 0x0cc00000, 0x219 },
10078 { 0x00003fff, 0x002f022f, 0x000 },
10079 { 0x00000000, 0x0cc00000, 0x212 },
10080 { 0x00000000, 0xc0400400, 0x001 },
10081 { 0x00000000, 0x00600000, 0x642 },
10082 { 0x00000000, 0x0040040f, 0x213 },
10083 { 0x00000000, 0x00600000, 0x62e },
10084 { 0x00000000, 0x00600000, 0x642 },
10085 { 0x00000210, 0x00600411, 0x315 },
10086 { 0x00000000, 0x00600000, 0x1a0 },
10087 { 0x00000000, 0x00600000, 0x19c },
10088 { 0x00000000, 0x00600000, 0x2bb },
10089 { 0x00000000, 0x00600000, 0x2a3 },
10090 { 0x93800000, 0x00204411, 0x000 },
10091 { 0x00000000, 0x00204808, 0x000 },
10092 { 0x00000000, 0x002f022f, 0x000 },
10093 { 0x00000000, 0x0ae00000, 0x232 },
10094 { 0x00000000, 0x00600000, 0x13a },
10095 { 0x00000000, 0x00400000, 0x236 },
10096 { 0x95000000, 0x00204411, 0x000 },
10097 { 0x00000000, 0x002f022f, 0x000 },
10098 { 0x00000000, 0x0ce00000, 0x236 },
10099 { 0x00000000, 0xc0404800, 0x233 },
10100 { 0x92000000, 0x00204411, 0x000 },
10101 { 0x00000000, 0xc0204800, 0x000 },
10102 { 0x00002256, 0x00204411, 0x000 },
10103 { 0x00000016, 0x00204811, 0x000 },
10104 { 0x0000225c, 0x00204411, 0x000 },
10105 { 0x00000003, 0x00204811, 0x000 },
10106 { 0x0000a1fc, 0x00204411, 0x000 },
10107 { 0x00000001, 0x00204811, 0x000 },
10108 { 0x0001a1fd, 0x00204411, 0x000 },
10109 { 0x00000000, 0x00600411, 0x2fb },
10110 { 0x00000000, 0xc0400400, 0x001 },
10111 { 0x00000000, 0x00600000, 0x62e },
10112 { 0x0000a00c, 0x00204411, 0x000 },
10113 { 0x00000000, 0xc0204800, 0x000 },
10114 { 0x00000000, 0xc0404800, 0x000 },
10115 { 0x00000000, 0x00600000, 0x00b },
10116 { 0x00000018, 0x40210a20, 0x000 },
10117 { 0x00000003, 0x002f0222, 0x000 },
10118 { 0x00000000, 0x0ae00000, 0x24c },
10119 { 0x00000014, 0x0020222d, 0x000 },
10120 { 0x00080101, 0x00292228, 0x000 },
10121 { 0x00000014, 0x00203628, 0x000 },
10122 { 0x0000a30c, 0x00204411, 0x000 },
10123 { 0x00000000, 0xc0204800, 0x000 },
10124 { 0x00000000, 0xc0204800, 0x000 },
10125 { 0x00000000, 0xc0404800, 0x251 },
10126 { 0x00000000, 0x00600000, 0x00b },
10127 { 0x00000010, 0x00600411, 0x315 },
10128 { 0x3f800000, 0x00200411, 0x000 },
10129 { 0x00000000, 0x00600811, 0x1b2 },
10130 { 0x0000225c, 0x00204411, 0x000 },
10131 { 0x00000003, 0x00204811, 0x000 },
10132 { 0x00000000, 0x00600000, 0x27c },
10133 { 0x00000017, 0x00201e2d, 0x000 },
10134 { 0x00000001, 0x00211e27, 0x000 },
10135 { 0x00000000, 0x14e00000, 0x26a },
10136 { 0x00000012, 0x00201e2d, 0x000 },
10137 { 0x0000ffff, 0x00281e27, 0x000 },
10138 { 0x00000000, 0x00341c27, 0x000 },
10139 { 0x00000000, 0x12c00000, 0x25f },
10140 { 0x00000000, 0x00201c11, 0x000 },
10141 { 0x00000000, 0x002f00e5, 0x000 },
10142 { 0x00000000, 0x08c00000, 0x262 },
10143 { 0x00000000, 0x00201407, 0x000 },
10144 { 0x00000012, 0x00201e2d, 0x000 },
10145 { 0x00000010, 0x00211e27, 0x000 },
10146 { 0x00000000, 0x00341c47, 0x000 },
10147 { 0x00000000, 0x12c00000, 0x267 },
10148 { 0x00000000, 0x00201c11, 0x000 },
10149 { 0x00000000, 0x002f00e6, 0x000 },
10150 { 0x00000000, 0x08c00000, 0x26a },
10151 { 0x00000000, 0x00201807, 0x000 },
10152 { 0x00000000, 0x00600000, 0x2c1 },
10153 { 0x00002256, 0x00204411, 0x000 },
10154 { 0x00000000, 0x00342023, 0x000 },
10155 { 0x00000000, 0x12c00000, 0x272 },
10156 { 0x00000000, 0x00342044, 0x000 },
10157 { 0x00000000, 0x12c00000, 0x271 },
10158 { 0x00000016, 0x00404811, 0x276 },
10159 { 0x00000018, 0x00404811, 0x276 },
10160 { 0x00000000, 0x00342044, 0x000 },
10161 { 0x00000000, 0x12c00000, 0x275 },
10162 { 0x00000017, 0x00404811, 0x276 },
10163 { 0x00000019, 0x00204811, 0x000 },
10164 { 0x0000a1fc, 0x00204411, 0x000 },
10165 { 0x00000001, 0x00204811, 0x000 },
10166 { 0x0001a1fd, 0x00604411, 0x2e9 },
10167 { 0x00003fff, 0x002f022f, 0x000 },
10168 { 0x00000000, 0x0cc00000, 0x256 },
10169 { 0x00000000, 0xc0400400, 0x001 },
10170 { 0x00000010, 0x40210620, 0x000 },
10171 { 0x0000ffff, 0xc0280a20, 0x000 },
10172 { 0x00000010, 0x40210e20, 0x000 },
10173 { 0x0000ffff, 0xc0281220, 0x000 },
10174 { 0x00000010, 0x40211620, 0x000 },
10175 { 0x0000ffff, 0xc0881a20, 0x000 },
10176 { 0x81000000, 0x00204411, 0x000 },
10177 { 0x00000001, 0x00204811, 0x000 },
10178 { 0x00042004, 0x00604411, 0x68a },
10179 { 0x00000000, 0x00600000, 0x62e },
10180 { 0x00000000, 0xc0600000, 0x2a3 },
10181 { 0x00000005, 0x00200a2d, 0x000 },
10182 { 0x00000008, 0x00220a22, 0x000 },
10183 { 0x0000002b, 0x00201a2d, 0x000 },
10184 { 0x0000001c, 0x00201e2d, 0x000 },
10185 { 0x00007000, 0x00281e27, 0x000 },
10186 { 0x00000000, 0x00311ce6, 0x000 },
10187 { 0x0000002a, 0x00201a2d, 0x000 },
10188 { 0x0000000c, 0x00221a26, 0x000 },
10189 { 0x00000000, 0x002f00e6, 0x000 },
10190 { 0x00000000, 0x06e00000, 0x292 },
10191 { 0x00000000, 0x00201c11, 0x000 },
10192 { 0x00000000, 0x00200c11, 0x000 },
10193 { 0x0000002b, 0x00203623, 0x000 },
10194 { 0x00000010, 0x00201811, 0x000 },
10195 { 0x00000000, 0x00691ce2, 0x12f },
10196 { 0x93800000, 0x00204411, 0x000 },
10197 { 0x00000000, 0x00204807, 0x000 },
10198 { 0x95000000, 0x00204411, 0x000 },
10199 { 0x00000000, 0x002f022f, 0x000 },
10200 { 0x00000000, 0x0ce00000, 0x29d },
10201 { 0x00000001, 0x00333e2f, 0x000 },
10202 { 0x00000000, 0xd9004800, 0x000 },
10203 { 0x92000000, 0x00204411, 0x000 },
10204 { 0x00000000, 0xc0204800, 0x000 },
10205 { 0x0000001c, 0x00403627, 0x000 },
10206 { 0x0000000c, 0xc0220a20, 0x000 },
10207 { 0x00000029, 0x00203622, 0x000 },
10208 { 0x00000028, 0xc0403620, 0x000 },
10209 { 0x0000a2a4, 0x00204411, 0x000 },
10210 { 0x00000009, 0x00204811, 0x000 },
10211 { 0xa1000000, 0x00204411, 0x000 },
10212 { 0x00000001, 0x00804811, 0x000 },
10213 { 0x00000021, 0x00201e2d, 0x000 },
10214 { 0x00000000, 0x002c1ce3, 0x000 },
10215 { 0x00000021, 0x00203627, 0x000 },
10216 { 0x00000022, 0x00201e2d, 0x000 },
10217 { 0x00000000, 0x002c1ce4, 0x000 },
10218 { 0x00000022, 0x00203627, 0x000 },
10219 { 0x00000023, 0x00201e2d, 0x000 },
10220 { 0x00000000, 0x003120a3, 0x000 },
10221 { 0x00000000, 0x002d1d07, 0x000 },
10222 { 0x00000023, 0x00203627, 0x000 },
10223 { 0x00000024, 0x00201e2d, 0x000 },
10224 { 0x00000000, 0x003120c4, 0x000 },
10225 { 0x00000000, 0x002d1d07, 0x000 },
10226 { 0x00000024, 0x00803627, 0x000 },
10227 { 0x00000021, 0x00203623, 0x000 },
10228 { 0x00000022, 0x00203624, 0x000 },
10229 { 0x00000000, 0x00311ca3, 0x000 },
10230 { 0x00000023, 0x00203627, 0x000 },
10231 { 0x00000000, 0x00311cc4, 0x000 },
10232 { 0x00000024, 0x00803627, 0x000 },
10233 { 0x0000001a, 0x00203627, 0x000 },
10234 { 0x0000001b, 0x00203628, 0x000 },
10235 { 0x00000017, 0x00201e2d, 0x000 },
10236 { 0x00000002, 0x00210227, 0x000 },
10237 { 0x00000000, 0x14c00000, 0x2dc },
10238 { 0x00000000, 0x00400000, 0x2d9 },
10239 { 0x0000001a, 0x00203627, 0x000 },
10240 { 0x0000001b, 0x00203628, 0x000 },
10241 { 0x00000017, 0x00201e2d, 0x000 },
10242 { 0x00000002, 0x00210227, 0x000 },
10243 { 0x00000000, 0x14e00000, 0x2d9 },
10244 { 0x00000003, 0x00210227, 0x000 },
10245 { 0x00000000, 0x14e00000, 0x2dc },
10246 { 0x00000023, 0x00201e2d, 0x000 },
10247 { 0x00000000, 0x002e00e1, 0x000 },
10248 { 0x00000000, 0x02c00000, 0x2dc },
10249 { 0x00000021, 0x00201e2d, 0x000 },
10250 { 0x00000000, 0x003120a1, 0x000 },
10251 { 0x00000000, 0x002e00e8, 0x000 },
10252 { 0x00000000, 0x06c00000, 0x2dc },
10253 { 0x00000024, 0x00201e2d, 0x000 },
10254 { 0x00000000, 0x002e00e2, 0x000 },
10255 { 0x00000000, 0x02c00000, 0x2dc },
10256 { 0x00000022, 0x00201e2d, 0x000 },
10257 { 0x00000000, 0x003120c2, 0x000 },
10258 { 0x00000000, 0x002e00e8, 0x000 },
10259 { 0x00000000, 0x06c00000, 0x2dc },
10260 { 0x00000000, 0x00600000, 0x665 },
10261 { 0x00000000, 0x00600000, 0x2b5 },
10262 { 0x00000000, 0x00400000, 0x2de },
10263 { 0x00000000, 0x00600000, 0x2b5 },
10264 { 0x00000000, 0x00600000, 0x65c },
10265 { 0x00000000, 0x00400000, 0x2de },
10266 { 0x00000000, 0x00600000, 0x2a7 },
10267 { 0x00000000, 0x00400000, 0x2de },
10268 { 0x0000001a, 0x00201e2d, 0x000 },
10269 { 0x0000001b, 0x0080222d, 0x000 },
10270 { 0x00000010, 0x00221e23, 0x000 },
10271 { 0x00000000, 0x00294887, 0x000 },
10272 { 0x00000000, 0x00311ca3, 0x000 },
10273 { 0x00000010, 0x00221e27, 0x000 },
10274 { 0x00000000, 0x00294887, 0x000 },
10275 { 0x00000010, 0x00221e23, 0x000 },
10276 { 0x00000000, 0x003120c4, 0x000 },
10277 { 0x0000ffff, 0x00282228, 0x000 },
10278 { 0x00000000, 0x00894907, 0x000 },
10279 { 0x00000010, 0x00221e23, 0x000 },
10280 { 0x00000000, 0x00294887, 0x000 },
10281 { 0x00000010, 0x00221e21, 0x000 },
10282 { 0x00000000, 0x00294847, 0x000 },
10283 { 0x00000000, 0x00311ca3, 0x000 },
10284 { 0x00000010, 0x00221e27, 0x000 },
10285 { 0x00000000, 0x00294887, 0x000 },
10286 { 0x00000000, 0x00311ca1, 0x000 },
10287 { 0x00000010, 0x00221e27, 0x000 },
10288 { 0x00000000, 0x00294847, 0x000 },
10289 { 0x00000010, 0x00221e23, 0x000 },
10290 { 0x00000000, 0x003120c4, 0x000 },
10291 { 0x0000ffff, 0x00282228, 0x000 },
10292 { 0x00000000, 0x00294907, 0x000 },
10293 { 0x00000010, 0x00221e21, 0x000 },
10294 { 0x00000000, 0x003120c2, 0x000 },
10295 { 0x0000ffff, 0x00282228, 0x000 },
10296 { 0x00000000, 0x00894907, 0x000 },
10297 { 0x00000010, 0x00221e23, 0x000 },
10298 { 0x00000000, 0x00294887, 0x000 },
10299 { 0x00000001, 0x00220a21, 0x000 },
10300 { 0x00000000, 0x003308a2, 0x000 },
10301 { 0x00000010, 0x00221e22, 0x000 },
10302 { 0x00000010, 0x00212222, 0x000 },
10303 { 0x00000000, 0x00294907, 0x000 },
10304 { 0x00000000, 0x00311ca3, 0x000 },
10305 { 0x00000010, 0x00221e27, 0x000 },
10306 { 0x00000000, 0x00294887, 0x000 },
10307 { 0x00000001, 0x00220a21, 0x000 },
10308 { 0x00000000, 0x003008a2, 0x000 },
10309 { 0x00000010, 0x00221e22, 0x000 },
10310 { 0x00000010, 0x00212222, 0x000 },
10311 { 0x00000000, 0x00294907, 0x000 },
10312 { 0x00000010, 0x00221e23, 0x000 },
10313 { 0x00000000, 0x003120c4, 0x000 },
10314 { 0x0000ffff, 0x00282228, 0x000 },
10315 { 0x00000000, 0x00294907, 0x000 },
10316 { 0x00000000, 0x003808c5, 0x000 },
10317 { 0x00000000, 0x00300841, 0x000 },
10318 { 0x00000001, 0x00220a22, 0x000 },
10319 { 0x00000000, 0x003308a2, 0x000 },
10320 { 0x00000010, 0x00221e22, 0x000 },
10321 { 0x00000010, 0x00212222, 0x000 },
10322 { 0x00000000, 0x00894907, 0x000 },
10323 { 0x00000017, 0x0020222d, 0x000 },
10324 { 0x00000000, 0x14c00000, 0x318 },
10325 { 0xffffffef, 0x00280621, 0x000 },
10326 { 0x00000014, 0x0020222d, 0x000 },
10327 { 0x0000f8e0, 0x00204411, 0x000 },
10328 { 0x00000000, 0x00294901, 0x000 },
10329 { 0x00000000, 0x00894901, 0x000 },
10330 { 0x00000000, 0x00204811, 0x000 },
10331 { 0x00000000, 0x00204811, 0x000 },
10332 { 0x060a0200, 0x00804811, 0x000 },
10333 { 0x00000000, 0xc0200000, 0x000 },
10334 { 0x97000000, 0xc0204411, 0x000 },
10335 { 0x00000000, 0xc0204811, 0x000 },
10336 { 0x8a000000, 0x00204411, 0x000 },
10337 { 0x00000000, 0x00204811, 0x000 },
10338 { 0x0000225c, 0x00204411, 0x000 },
10339 { 0x00000000, 0xc0204800, 0x000 },
10340 { 0x0000a1fc, 0x00204411, 0x000 },
10341 { 0x00000000, 0xc0204800, 0x000 },
10342 { 0x00000000, 0xc0200400, 0x000 },
10343 { 0x00000000, 0x00a0000a, 0x000 },
10344 { 0x97000000, 0x00204411, 0x000 },
10345 { 0x00000000, 0x00204811, 0x000 },
10346 { 0x8a000000, 0x00204411, 0x000 },
10347 { 0x00000000, 0x00204811, 0x000 },
10348 { 0x0000225c, 0x00204411, 0x000 },
10349 { 0x00000000, 0xc0204800, 0x000 },
10350 { 0x0000a1fc, 0x00204411, 0x000 },
10351 { 0x00000000, 0xc0204800, 0x000 },
10352 { 0x00000000, 0xc0200400, 0x000 },
10353 { 0x00000000, 0x00a0000a, 0x000 },
10354 { 0x97000000, 0x00204411, 0x000 },
10355 { 0x00000000, 0x00204811, 0x000 },
10356 { 0x8a000000, 0x00204411, 0x000 },
10357 { 0x00000000, 0x00204811, 0x000 },
10358 { 0x0000225c, 0x00204411, 0x000 },
10359 { 0x00000000, 0xc0204800, 0x000 },
10360 { 0x0000a1fc, 0x00204411, 0x000 },
10361 { 0x00000000, 0xc0204800, 0x000 },
10362 { 0x0001a1fd, 0x00204411, 0x000 },
10363 { 0x00000000, 0xd9004800, 0x000 },
10364 { 0x00000000, 0xc0200400, 0x000 },
10365 { 0x00000000, 0x00a0000a, 0x000 },
10366 { 0x00002257, 0x00204411, 0x000 },
10367 { 0x00000003, 0xc0484a20, 0x000 },
10368 { 0x0000225d, 0x00204411, 0x000 },
10369 { 0x00000000, 0xc0404800, 0x000 },
10370 { 0x00000000, 0x00600000, 0x642 },
10371 { 0x00000000, 0xc0200800, 0x000 },
10372 { 0x0000225c, 0x00204411, 0x000 },
10373 { 0x00000003, 0x00384a22, 0x000 },
10374 { 0x0000a1fc, 0x00204411, 0x000 },
10375 { 0x00000000, 0xc0204800, 0x000 },
10376 { 0x0001a1fd, 0x00204411, 0x000 },
10377 { 0x00000000, 0x002f0222, 0x000 },
10378 { 0x00000000, 0x0ce00000, 0x000 },
10379 { 0x00000000, 0x40204800, 0x000 },
10380 { 0x00000001, 0x40304a20, 0x000 },
10381 { 0x00000002, 0xc0304a20, 0x000 },
10382 { 0x00000001, 0x00530a22, 0x34b },
10383 { 0x0000003f, 0xc0280a20, 0x000 },
10384 { 0x81000000, 0x00204411, 0x000 },
10385 { 0x00000001, 0x00204811, 0x000 },
10386 { 0x000021f8, 0x00204411, 0x000 },
10387 { 0x00000018, 0x00204811, 0x000 },
10388 { 0x000421f9, 0x00604411, 0x68a },
10389 { 0x00000011, 0x00210230, 0x000 },
10390 { 0x00000000, 0x14e00000, 0x354 },
10391 { 0x00000014, 0x002f0222, 0x000 },
10392 { 0x00000000, 0x0cc00000, 0x364 },
10393 { 0x00002010, 0x00204411, 0x000 },
10394 { 0x00008000, 0x00204811, 0x000 },
10395 { 0x0001a2a4, 0x00204411, 0x000 },
10396 { 0x00000000, 0x00604802, 0x36e },
10397 { 0x00002100, 0x00204411, 0x000 },
10398 { 0x00000000, 0xc0204800, 0x000 },
10399 { 0x00000000, 0xc0204800, 0x000 },
10400 { 0x00000000, 0xc0204800, 0x000 },
10401 { 0x00000000, 0xc0404800, 0x000 },
10402 { 0x00000004, 0x002f0222, 0x000 },
10403 { 0x00000000, 0x0cc00000, 0x36a },
10404 { 0x00002010, 0x00204411, 0x000 },
10405 { 0x00008000, 0x00204811, 0x000 },
10406 { 0x0001a2a4, 0x00204411, 0x000 },
10407 { 0x00000000, 0x00404802, 0x35f },
10408 { 0x00000028, 0x002f0222, 0x000 },
10409 { 0x00000000, 0x0cc00000, 0x5bd },
10410 { 0x0001a2a4, 0x00204411, 0x000 },
10411 { 0x00000000, 0x00404802, 0x35f },
10412 { 0x0000002c, 0x00203626, 0x000 },
10413 { 0x00000049, 0x00201811, 0x000 },
10414 { 0x0000003f, 0x00204811, 0x000 },
10415 { 0x00000001, 0x00331a26, 0x000 },
10416 { 0x00000000, 0x002f0226, 0x000 },
10417 { 0x00000000, 0x0cc00000, 0x370 },
10418 { 0x0000002c, 0x00801a2d, 0x000 },
10419 { 0x0000003f, 0xc0280a20, 0x000 },
10420 { 0x00000015, 0x002f0222, 0x000 },
10421 { 0x00000000, 0x0ce00000, 0x386 },
10422 { 0x00000006, 0x002f0222, 0x000 },
10423 { 0x00000000, 0x0ce00000, 0x3b1 },
10424 { 0x00000016, 0x002f0222, 0x000 },
10425 { 0x00000000, 0x0ce00000, 0x3b5 },
10426 { 0x00000020, 0x002f0222, 0x000 },
10427 { 0x00000000, 0x0ce00000, 0x39c },
10428 { 0x0000000f, 0x002f0222, 0x000 },
10429 { 0x00000000, 0x0ce00000, 0x3a8 },
10430 { 0x00000010, 0x002f0222, 0x000 },
10431 { 0x00000000, 0x0ce00000, 0x3a8 },
10432 { 0x0000001e, 0x002f0222, 0x000 },
10433 { 0x00000000, 0x0ce00000, 0x390 },
10434 { 0x0000a2a4, 0x00204411, 0x000 },
10435 { 0x00000000, 0x00404802, 0x000 },
10436 { 0x08000000, 0x00290a22, 0x000 },
10437 { 0x00000003, 0x40210e20, 0x000 },
10438 { 0x0000000c, 0xc0211220, 0x000 },
10439 { 0x00080000, 0x00281224, 0x000 },
10440 { 0x00000014, 0xc0221620, 0x000 },
10441 { 0x00000000, 0x002914a4, 0x000 },
10442 { 0x0000a2a4, 0x00204411, 0x000 },
10443 { 0x00000000, 0x002948a2, 0x000 },
10444 { 0x0000a1fe, 0x00204411, 0x000 },
10445 { 0x00000000, 0x00404803, 0x000 },
10446 { 0x81000000, 0x00204411, 0x000 },
10447 { 0x00000001, 0x00204811, 0x000 },
10448 { 0x000021f8, 0x00204411, 0x000 },
10449 { 0x00000016, 0x00204811, 0x000 },
10450 { 0x000421f9, 0x00604411, 0x68a },
10451 { 0x00000015, 0x00210230, 0x000 },
10452 { 0x00000000, 0x14e00000, 0x392 },
10453 { 0x0000210e, 0x00204411, 0x000 },
10454 { 0x00000000, 0xc0204800, 0x000 },
10455 { 0x00000000, 0xc0204800, 0x000 },
10456 { 0x0000a2a4, 0x00204411, 0x000 },
10457 { 0x00000000, 0x00404802, 0x000 },
10458 { 0x81000000, 0x00204411, 0x000 },
10459 { 0x00000001, 0x00204811, 0x000 },
10460 { 0x000021f8, 0x00204411, 0x000 },
10461 { 0x00000017, 0x00204811, 0x000 },
10462 { 0x000421f9, 0x00604411, 0x68a },
10463 { 0x00000003, 0x00210230, 0x000 },
10464 { 0x00000000, 0x14e00000, 0x39e },
10465 { 0x00002108, 0x00204411, 0x000 },
10466 { 0x00000000, 0xc0204800, 0x000 },
10467 { 0x00000000, 0xc0204800, 0x000 },
10468 { 0x0000a2a4, 0x00204411, 0x000 },
10469 { 0x00000000, 0x00404802, 0x000 },
10470 { 0x0000a2a4, 0x00204411, 0x000 },
10471 { 0x00000000, 0x00204802, 0x000 },
10472 { 0x80000000, 0x00204411, 0x000 },
10473 { 0x00000000, 0x00204811, 0x000 },
10474 { 0x81000000, 0x00204411, 0x000 },
10475 { 0x00000010, 0x00204811, 0x000 },
10476 { 0x00000000, 0x00200010, 0x000 },
10477 { 0x00000000, 0x14c00000, 0x3ae },
10478 { 0x00000000, 0x00400000, 0x000 },
10479 { 0x00002010, 0x00204411, 0x000 },
10480 { 0x00008000, 0x00204811, 0x000 },
10481 { 0x0001a2a4, 0x00204411, 0x000 },
10482 { 0x00000006, 0x00404811, 0x000 },
10483 { 0x00002010, 0x00204411, 0x000 },
10484 { 0x00008000, 0x00204811, 0x000 },
10485 { 0x0001a2a4, 0x00204411, 0x000 },
10486 { 0x00000016, 0x00604811, 0x36e },
10487 { 0x00000000, 0x00400000, 0x000 },
10488 { 0x00000000, 0xc0200800, 0x000 },
10489 { 0x00000000, 0xc0200c00, 0x000 },
10490 { 0x0000001d, 0x00210223, 0x000 },
10491 { 0x00000000, 0x14e00000, 0x3ce },
10492 { 0x81000000, 0x00204411, 0x000 },
10493 { 0x00000001, 0x00204811, 0x000 },
10494 { 0x000021f8, 0x00204411, 0x000 },
10495 { 0x00000018, 0x00204811, 0x000 },
10496 { 0x000421f9, 0x00604411, 0x68a },
10497 { 0x00000011, 0x00210230, 0x000 },
10498 { 0x00000000, 0x14e00000, 0x3c0 },
10499 { 0x00002100, 0x00204411, 0x000 },
10500 { 0x00000000, 0x00204802, 0x000 },
10501 { 0x00000000, 0x00204803, 0x000 },
10502 { 0xbabecafe, 0x00204811, 0x000 },
10503 { 0xcafebabe, 0x00204811, 0x000 },
10504 { 0x00002010, 0x00204411, 0x000 },
10505 { 0x00008000, 0x00204811, 0x000 },
10506 { 0x0000a2a4, 0x00204411, 0x000 },
10507 { 0x00000004, 0x00404811, 0x000 },
10508 { 0x00002170, 0x00204411, 0x000 },
10509 { 0x00000000, 0x00204802, 0x000 },
10510 { 0x00000000, 0x00204803, 0x000 },
10511 { 0x81000000, 0x00204411, 0x000 },
10512 { 0x0000000a, 0x00204811, 0x000 },
10513 { 0x00000000, 0x00200010, 0x000 },
10514 { 0x00000000, 0x14c00000, 0x3d3 },
10515 { 0x8c000000, 0x00204411, 0x000 },
10516 { 0xcafebabe, 0x00404811, 0x000 },
10517 { 0x81000000, 0x00204411, 0x000 },
10518 { 0x00000001, 0x00204811, 0x000 },
10519 { 0x00003fff, 0x40280a20, 0x000 },
10520 { 0x80000000, 0x40280e20, 0x000 },
10521 { 0x40000000, 0xc0281220, 0x000 },
10522 { 0x00040000, 0x00694622, 0x68a },
10523 { 0x00000000, 0x00201410, 0x000 },
10524 { 0x00000000, 0x002f0223, 0x000 },
10525 { 0x00000000, 0x0cc00000, 0x3e1 },
10526 { 0x00000000, 0xc0401800, 0x3e4 },
10527 { 0x00003fff, 0xc0281a20, 0x000 },
10528 { 0x00040000, 0x00694626, 0x68a },
10529 { 0x00000000, 0x00201810, 0x000 },
10530 { 0x00000000, 0x002f0224, 0x000 },
10531 { 0x00000000, 0x0cc00000, 0x3e7 },
10532 { 0x00000000, 0xc0401c00, 0x3ea },
10533 { 0x00003fff, 0xc0281e20, 0x000 },
10534 { 0x00040000, 0x00694627, 0x68a },
10535 { 0x00000000, 0x00201c10, 0x000 },
10536 { 0x00000000, 0x00204402, 0x000 },
10537 { 0x00000000, 0x002820c5, 0x000 },
10538 { 0x00000000, 0x004948e8, 0x000 },
10539 { 0xa5800000, 0x00200811, 0x000 },
10540 { 0x00002000, 0x00200c11, 0x000 },
10541 { 0x83000000, 0x00604411, 0x412 },
10542 { 0x00000000, 0x00204402, 0x000 },
10543 { 0x00000000, 0xc0204800, 0x000 },
10544 { 0x00000000, 0x40204800, 0x000 },
10545 { 0x0000001f, 0xc0210220, 0x000 },
10546 { 0x00000000, 0x14c00000, 0x3f7 },
10547 { 0x00002010, 0x00204411, 0x000 },
10548 { 0x00008000, 0x00204811, 0x000 },
10549 { 0x0000ffff, 0xc0481220, 0x3ff },
10550 { 0xa7800000, 0x00200811, 0x000 },
10551 { 0x0000a000, 0x00200c11, 0x000 },
10552 { 0x83000000, 0x00604411, 0x412 },
10553 { 0x00000000, 0x00204402, 0x000 },
10554 { 0x00000000, 0xc0204800, 0x000 },
10555 { 0x00000000, 0xc0204800, 0x000 },
10556 { 0x0000ffff, 0xc0281220, 0x000 },
10557 { 0x83000000, 0x00204411, 0x000 },
10558 { 0x00000000, 0x00304883, 0x000 },
10559 { 0x84000000, 0x00204411, 0x000 },
10560 { 0x00000000, 0xc0204800, 0x000 },
10561 { 0x00000000, 0x1d000000, 0x000 },
10562 { 0x83000000, 0x00604411, 0x412 },
10563 { 0x00000000, 0xc0400400, 0x001 },
10564 { 0xa9800000, 0x00200811, 0x000 },
10565 { 0x0000c000, 0x00400c11, 0x3fa },
10566 { 0xab800000, 0x00200811, 0x000 },
10567 { 0x0000f8e0, 0x00400c11, 0x3fa },
10568 { 0xad800000, 0x00200811, 0x000 },
10569 { 0x0000f880, 0x00400c11, 0x3fa },
10570 { 0xb3800000, 0x00200811, 0x000 },
10571 { 0x0000f3fc, 0x00400c11, 0x3fa },
10572 { 0xaf800000, 0x00200811, 0x000 },
10573 { 0x0000e000, 0x00400c11, 0x3fa },
10574 { 0xb1800000, 0x00200811, 0x000 },
10575 { 0x0000f000, 0x00400c11, 0x3fa },
10576 { 0x83000000, 0x00204411, 0x000 },
10577 { 0x00002148, 0x00204811, 0x000 },
10578 { 0x84000000, 0x00204411, 0x000 },
10579 { 0x00000000, 0xc0204800, 0x000 },
10580 { 0x00000000, 0x1d000000, 0x000 },
10581 { 0x00000000, 0x00800000, 0x000 },
10582 { 0x01182000, 0xc0304620, 0x000 },
10583 { 0x00000000, 0xd9004800, 0x000 },
10584 { 0x00000000, 0xc0200400, 0x000 },
10585 { 0x00000000, 0x00a0000a, 0x000 },
10586 { 0x0218a000, 0xc0304620, 0x000 },
10587 { 0x00000000, 0xd9004800, 0x000 },
10588 { 0x00000000, 0xc0200400, 0x000 },
10589 { 0x00000000, 0x00a0000a, 0x000 },
10590 { 0x0318c000, 0xc0304620, 0x000 },
10591 { 0x00000000, 0xd9004800, 0x000 },
10592 { 0x00000000, 0xc0200400, 0x000 },
10593 { 0x00000000, 0x00a0000a, 0x000 },
10594 { 0x0418f8e0, 0xc0304620, 0x000 },
10595 { 0x00000000, 0xd9004800, 0x000 },
10596 { 0x00000000, 0xc0200400, 0x000 },
10597 { 0x00000000, 0x00a0000a, 0x000 },
10598 { 0x0518f880, 0xc0304620, 0x000 },
10599 { 0x00000000, 0xd9004800, 0x000 },
10600 { 0x00000000, 0xc0200400, 0x000 },
10601 { 0x00000000, 0x00a0000a, 0x000 },
10602 { 0x0618e000, 0xc0304620, 0x000 },
10603 { 0x00000000, 0xd9004800, 0x000 },
10604 { 0x00000000, 0xc0200400, 0x000 },
10605 { 0x00000000, 0x00a0000a, 0x000 },
10606 { 0x0718f000, 0xc0304620, 0x000 },
10607 { 0x00000000, 0xd9004800, 0x000 },
10608 { 0x00000000, 0xc0200400, 0x000 },
10609 { 0x00000000, 0x00a0000a, 0x000 },
10610 { 0x0818f3fc, 0xc0304620, 0x000 },
10611 { 0x00000000, 0xd9004800, 0x000 },
10612 { 0x00000000, 0xc0200400, 0x000 },
10613 { 0x00000000, 0x00a0000a, 0x000 },
10614 { 0x00000030, 0x00200a2d, 0x000 },
10615 { 0x00000000, 0xc0290c40, 0x000 },
10616 { 0x00000030, 0x00203623, 0x000 },
10617 { 0x00000000, 0xc0200400, 0x000 },
10618 { 0x00000000, 0x00a0000a, 0x000 },
10619 { 0x86000000, 0x00204411, 0x000 },
10620 { 0x00000000, 0x00404801, 0x000 },
10621 { 0x85000000, 0xc0204411, 0x000 },
10622 { 0x00000000, 0x00404801, 0x000 },
10623 { 0x0000217c, 0x00204411, 0x000 },
10624 { 0x00000000, 0xc0204800, 0x000 },
10625 { 0x00000000, 0xc0204800, 0x000 },
10626 { 0x00000000, 0xc0204800, 0x000 },
10627 { 0x81000000, 0x00204411, 0x000 },
10628 { 0x00000001, 0x00204811, 0x000 },
10629 { 0x00000000, 0xc0200800, 0x000 },
10630 { 0x00000000, 0x17000000, 0x000 },
10631 { 0x0004217f, 0x00604411, 0x68a },
10632 { 0x0000001f, 0x00210230, 0x000 },
10633 { 0x00000000, 0x14c00000, 0x000 },
10634 { 0x00000000, 0x00404c02, 0x448 },
10635 { 0x00000000, 0xc0200c00, 0x000 },
10636 { 0x00000000, 0xc0201000, 0x000 },
10637 { 0x00000000, 0xc0201400, 0x000 },
10638 { 0x00000000, 0xc0201800, 0x000 },
10639 { 0x00000000, 0xc0201c00, 0x000 },
10640 { 0x00007f00, 0x00280a21, 0x000 },
10641 { 0x00004500, 0x002f0222, 0x000 },
10642 { 0x00000000, 0x0ce00000, 0x456 },
10643 { 0x00000000, 0xc0202000, 0x000 },
10644 { 0x00000000, 0x17000000, 0x000 },
10645 { 0x00000010, 0x00280a23, 0x000 },
10646 { 0x00000010, 0x002f0222, 0x000 },
10647 { 0x00000000, 0x0ce00000, 0x45e },
10648 { 0x81000000, 0x00204411, 0x000 },
10649 { 0x00000001, 0x00204811, 0x000 },
10650 { 0x00040000, 0x00694624, 0x68a },
10651 { 0x00000000, 0x00400000, 0x463 },
10652 { 0x81000000, 0x00204411, 0x000 },
10653 { 0x00000000, 0x00204811, 0x000 },
10654 { 0x0000216d, 0x00204411, 0x000 },
10655 { 0x00000000, 0x00204804, 0x000 },
10656 { 0x00000000, 0x00604805, 0x68f },
10657 { 0x00000000, 0x002824f0, 0x000 },
10658 { 0x00000007, 0x00280a23, 0x000 },
10659 { 0x00000001, 0x002f0222, 0x000 },
10660 { 0x00000000, 0x0ae00000, 0x46a },
10661 { 0x00000000, 0x002f00c9, 0x000 },
10662 { 0x00000000, 0x04e00000, 0x483 },
10663 { 0x00000000, 0x00400000, 0x490 },
10664 { 0x00000002, 0x002f0222, 0x000 },
10665 { 0x00000000, 0x0ae00000, 0x46f },
10666 { 0x00000000, 0x002f00c9, 0x000 },
10667 { 0x00000000, 0x02e00000, 0x483 },
10668 { 0x00000000, 0x00400000, 0x490 },
10669 { 0x00000003, 0x002f0222, 0x000 },
10670 { 0x00000000, 0x0ae00000, 0x474 },
10671 { 0x00000000, 0x002f00c9, 0x000 },
10672 { 0x00000000, 0x0ce00000, 0x483 },
10673 { 0x00000000, 0x00400000, 0x490 },
10674 { 0x00000004, 0x002f0222, 0x000 },
10675 { 0x00000000, 0x0ae00000, 0x479 },
10676 { 0x00000000, 0x002f00c9, 0x000 },
10677 { 0x00000000, 0x0ae00000, 0x483 },
10678 { 0x00000000, 0x00400000, 0x490 },
10679 { 0x00000005, 0x002f0222, 0x000 },
10680 { 0x00000000, 0x0ae00000, 0x47e },
10681 { 0x00000000, 0x002f00c9, 0x000 },
10682 { 0x00000000, 0x06e00000, 0x483 },
10683 { 0x00000000, 0x00400000, 0x490 },
10684 { 0x00000006, 0x002f0222, 0x000 },
10685 { 0x00000000, 0x0ae00000, 0x483 },
10686 { 0x00000000, 0x002f00c9, 0x000 },
10687 { 0x00000000, 0x08e00000, 0x483 },
10688 { 0x00000000, 0x00400000, 0x490 },
10689 { 0x00007f00, 0x00280a21, 0x000 },
10690 { 0x00004500, 0x002f0222, 0x000 },
10691 { 0x00000000, 0x0ae00000, 0x000 },
10692 { 0x00000008, 0x00210a23, 0x000 },
10693 { 0x00000000, 0x14c00000, 0x48d },
10694 { 0x00002169, 0x00204411, 0x000 },
10695 { 0x00000000, 0xc0204800, 0x000 },
10696 { 0x00000000, 0xc0204800, 0x000 },
10697 { 0x00000000, 0xc0204800, 0x000 },
10698 { 0xcafebabe, 0x00404811, 0x000 },
10699 { 0x00000000, 0xc0204400, 0x000 },
10700 { 0x00000000, 0xc0200000, 0x000 },
10701 { 0x00000000, 0xc0404800, 0x000 },
10702 { 0x00007f00, 0x00280a21, 0x000 },
10703 { 0x00004500, 0x002f0222, 0x000 },
10704 { 0x00000000, 0x0ae00000, 0x496 },
10705 { 0x00000000, 0xc0200000, 0x000 },
10706 { 0x00000000, 0xc0200000, 0x000 },
10707 { 0x00000000, 0xc0400000, 0x000 },
10708 { 0x00000000, 0x00404c08, 0x456 },
10709 { 0x00000000, 0xc0200800, 0x000 },
10710 { 0x00000010, 0x40210e20, 0x000 },
10711 { 0x00000011, 0x40211220, 0x000 },
10712 { 0x00000012, 0x40211620, 0x000 },
10713 { 0x00002169, 0x00204411, 0x000 },
10714 { 0x00000000, 0x00204802, 0x000 },
10715 { 0x00000000, 0x00210225, 0x000 },
10716 { 0x00000000, 0x14e00000, 0x4a0 },
10717 { 0x00040000, 0xc0494a20, 0x4a1 },
10718 { 0xfffbffff, 0xc0284a20, 0x000 },
10719 { 0x00000000, 0x00210223, 0x000 },
10720 { 0x00000000, 0x14e00000, 0x4ad },
10721 { 0x00000000, 0xc0204800, 0x000 },
10722 { 0x00000000, 0xc0204800, 0x000 },
10723 { 0x00000000, 0x00210224, 0x000 },
10724 { 0x00000000, 0x14c00000, 0x000 },
10725 { 0x81000000, 0x00204411, 0x000 },
10726 { 0x0000000c, 0x00204811, 0x000 },
10727 { 0x00000000, 0x00200010, 0x000 },
10728 { 0x00000000, 0x14c00000, 0x4a9 },
10729 { 0xa0000000, 0x00204411, 0x000 },
10730 { 0xcafebabe, 0x00404811, 0x000 },
10731 { 0x81000000, 0x00204411, 0x000 },
10732 { 0x00000004, 0x00204811, 0x000 },
10733 { 0x0000216b, 0x00204411, 0x000 },
10734 { 0x00000000, 0xc0204810, 0x000 },
10735 { 0x81000000, 0x00204411, 0x000 },
10736 { 0x00000005, 0x00204811, 0x000 },
10737 { 0x0000216c, 0x00204411, 0x000 },
10738 { 0x00000000, 0xc0204810, 0x000 },
10739 { 0x00000000, 0x002f0224, 0x000 },
10740 { 0x00000000, 0x0ce00000, 0x000 },
10741 { 0x00000000, 0x00400000, 0x4a7 },
10742 { 0x00000000, 0xc0210a20, 0x000 },
10743 { 0x00000000, 0x14c00000, 0x4c0 },
10744 { 0x81000000, 0x00204411, 0x000 },
10745 { 0x00000000, 0x00204811, 0x000 },
10746 { 0x0000216d, 0x00204411, 0x000 },
10747 { 0x00000000, 0xc0204800, 0x000 },
10748 { 0x00000000, 0xc0604800, 0x68f },
10749 { 0x00000000, 0x00400000, 0x4c4 },
10750 { 0x81000000, 0x00204411, 0x000 },
10751 { 0x00000001, 0x00204811, 0x000 },
10752 { 0x00040000, 0xc0294620, 0x000 },
10753 { 0x00000000, 0xc0600000, 0x68a },
10754 { 0x00000001, 0x00210222, 0x000 },
10755 { 0x00000000, 0x14c00000, 0x4cb },
10756 { 0x00002169, 0x00204411, 0x000 },
10757 { 0x00000000, 0xc0204800, 0x000 },
10758 { 0x00000000, 0xc0204800, 0x000 },
10759 { 0x00000000, 0x00204810, 0x000 },
10760 { 0xcafebabe, 0x00404811, 0x000 },
10761 { 0x00000000, 0xc0204400, 0x000 },
10762 { 0x00000000, 0xc0404810, 0x000 },
10763 { 0x81000000, 0x00204411, 0x000 },
10764 { 0x00000001, 0x00204811, 0x000 },
10765 { 0x000021f8, 0x00204411, 0x000 },
10766 { 0x0000000e, 0x00204811, 0x000 },
10767 { 0x000421f9, 0x00604411, 0x68a },
10768 { 0x00000000, 0x00210230, 0x000 },
10769 { 0x00000000, 0x14c00000, 0x4cd },
10770 { 0x00002180, 0x00204411, 0x000 },
10771 { 0x00000000, 0xc0204800, 0x000 },
10772 { 0x00000000, 0xc0200000, 0x000 },
10773 { 0x00000000, 0xc0204800, 0x000 },
10774 { 0x00000000, 0xc0200000, 0x000 },
10775 { 0x00000000, 0xc0404800, 0x000 },
10776 { 0x00000003, 0x00333e2f, 0x000 },
10777 { 0x00000001, 0x00210221, 0x000 },
10778 { 0x00000000, 0x14e00000, 0x4fd },
10779 { 0x0000002c, 0x00200a2d, 0x000 },
10780 { 0x00040000, 0x18e00c11, 0x4ec },
10781 { 0x00000001, 0x00333e2f, 0x000 },
10782 { 0x00002169, 0x00204411, 0x000 },
10783 { 0x00000000, 0x00204802, 0x000 },
10784 { 0x00000000, 0x00204803, 0x000 },
10785 { 0x00000008, 0x00300a22, 0x000 },
10786 { 0x00000000, 0xc0204800, 0x000 },
10787 { 0x00000000, 0xc0204800, 0x000 },
10788 { 0x00002169, 0x00204411, 0x000 },
10789 { 0x00000000, 0x00204802, 0x000 },
10790 { 0x00000000, 0x00204803, 0x000 },
10791 { 0x00000008, 0x00300a22, 0x000 },
10792 { 0x00000000, 0xc0204800, 0x000 },
10793 { 0x00000000, 0xd8c04800, 0x4e0 },
10794 { 0x00002169, 0x00204411, 0x000 },
10795 { 0x00000000, 0x00204802, 0x000 },
10796 { 0x00000000, 0x00204803, 0x000 },
10797 { 0x00000008, 0x00300a22, 0x000 },
10798 { 0x00000000, 0xc0204800, 0x000 },
10799 { 0x00000000, 0xc0204800, 0x000 },
10800 { 0x0000002d, 0x0020122d, 0x000 },
10801 { 0x00000000, 0x00290c83, 0x000 },
10802 { 0x00002169, 0x00204411, 0x000 },
10803 { 0x00000000, 0x00204802, 0x000 },
10804 { 0x00000000, 0x00204803, 0x000 },
10805 { 0x00000008, 0x00300a22, 0x000 },
10806 { 0x00000000, 0xc0204800, 0x000 },
10807 { 0x00000000, 0xc0204800, 0x000 },
10808 { 0x00000011, 0x00210224, 0x000 },
10809 { 0x00000000, 0x14c00000, 0x000 },
10810 { 0x00000000, 0x00400000, 0x4a7 },
10811 { 0x0000002c, 0xc0203620, 0x000 },
10812 { 0x0000002d, 0xc0403620, 0x000 },
10813 { 0x0000000f, 0x00210221, 0x000 },
10814 { 0x00000000, 0x14c00000, 0x502 },
10815 { 0x00000000, 0x00600000, 0x00b },
10816 { 0x00000000, 0xd9000000, 0x000 },
10817 { 0x00000000, 0xc0400400, 0x001 },
10818 { 0xb5000000, 0x00204411, 0x000 },
10819 { 0x00002000, 0x00204811, 0x000 },
10820 { 0xb6000000, 0x00204411, 0x000 },
10821 { 0x0000a000, 0x00204811, 0x000 },
10822 { 0xb7000000, 0x00204411, 0x000 },
10823 { 0x0000c000, 0x00204811, 0x000 },
10824 { 0xb8000000, 0x00204411, 0x000 },
10825 { 0x0000f8e0, 0x00204811, 0x000 },
10826 { 0xb9000000, 0x00204411, 0x000 },
10827 { 0x0000f880, 0x00204811, 0x000 },
10828 { 0xba000000, 0x00204411, 0x000 },
10829 { 0x0000e000, 0x00204811, 0x000 },
10830 { 0xbb000000, 0x00204411, 0x000 },
10831 { 0x0000f000, 0x00204811, 0x000 },
10832 { 0xbc000000, 0x00204411, 0x000 },
10833 { 0x0000f3fc, 0x00204811, 0x000 },
10834 { 0x81000000, 0x00204411, 0x000 },
10835 { 0x00000002, 0x00204811, 0x000 },
10836 { 0x000000ff, 0x00280e30, 0x000 },
10837 { 0x00000000, 0x002f0223, 0x000 },
10838 { 0x00000000, 0x0cc00000, 0x516 },
10839 { 0x00000000, 0xc0200800, 0x000 },
10840 { 0x00000000, 0x14c00000, 0x52b },
10841 { 0x00000000, 0x00200c11, 0x000 },
10842 { 0x0000001c, 0x00203623, 0x000 },
10843 { 0x0000002b, 0x00203623, 0x000 },
10844 { 0x00000029, 0x00203623, 0x000 },
10845 { 0x00000028, 0x00203623, 0x000 },
10846 { 0x00000017, 0x00203623, 0x000 },
10847 { 0x00000025, 0x00203623, 0x000 },
10848 { 0x00000026, 0x00203623, 0x000 },
10849 { 0x00000015, 0x00203623, 0x000 },
10850 { 0x00000016, 0x00203623, 0x000 },
10851 { 0xffffe000, 0x00200c11, 0x000 },
10852 { 0x00000021, 0x00203623, 0x000 },
10853 { 0x00000022, 0x00203623, 0x000 },
10854 { 0x00001fff, 0x00200c11, 0x000 },
10855 { 0x00000023, 0x00203623, 0x000 },
10856 { 0x00000024, 0x00203623, 0x000 },
10857 { 0xf1ffffff, 0x00283a2e, 0x000 },
10858 { 0x0000001a, 0xc0220e20, 0x000 },
10859 { 0x00000000, 0x0029386e, 0x000 },
10860 { 0x81000000, 0x00204411, 0x000 },
10861 { 0x00000006, 0x00204811, 0x000 },
10862 { 0x0000002a, 0x40203620, 0x000 },
10863 { 0x87000000, 0x00204411, 0x000 },
10864 { 0x00000000, 0xc0204800, 0x000 },
10865 { 0x0000a1f4, 0x00204411, 0x000 },
10866 { 0x00000000, 0x00204810, 0x000 },
10867 { 0x00000000, 0x00200c11, 0x000 },
10868 { 0x00000030, 0x00203623, 0x000 },
10869 { 0x9d000000, 0x00204411, 0x000 },
10870 { 0x0000001f, 0x40214a20, 0x000 },
10871 { 0x96000000, 0x00204411, 0x000 },
10872 { 0x00000000, 0xc0204800, 0x000 },
10873 { 0x00000000, 0xc0200c00, 0x000 },
10874 { 0x00000000, 0xc0201000, 0x000 },
10875 { 0x0000001f, 0x00211624, 0x000 },
10876 { 0x00000000, 0x14c00000, 0x000 },
10877 { 0x0000001d, 0x00203623, 0x000 },
10878 { 0x00000003, 0x00281e23, 0x000 },
10879 { 0x00000008, 0x00222223, 0x000 },
10880 { 0xfffff000, 0x00282228, 0x000 },
10881 { 0x00000000, 0x002920e8, 0x000 },
10882 { 0x0000001f, 0x00203628, 0x000 },
10883 { 0x00000018, 0x00211e23, 0x000 },
10884 { 0x00000020, 0x00203627, 0x000 },
10885 { 0x00000002, 0x00221624, 0x000 },
10886 { 0x00000000, 0x003014a8, 0x000 },
10887 { 0x0000001e, 0x00203625, 0x000 },
10888 { 0x00000003, 0x00211a24, 0x000 },
10889 { 0x10000000, 0x00281a26, 0x000 },
10890 { 0xefffffff, 0x00283a2e, 0x000 },
10891 { 0x00000000, 0x004938ce, 0x678 },
10892 { 0x00000001, 0x40280a20, 0x000 },
10893 { 0x00000006, 0x40280e20, 0x000 },
10894 { 0x00000300, 0xc0281220, 0x000 },
10895 { 0x00000008, 0x00211224, 0x000 },
10896 { 0x00000000, 0xc0201620, 0x000 },
10897 { 0x00000000, 0xc0201a20, 0x000 },
10898 { 0x00000000, 0x00210222, 0x000 },
10899 { 0x00000000, 0x14c00000, 0x563 },
10900 { 0x81000000, 0x00204411, 0x000 },
10901 { 0x00000001, 0x00204811, 0x000 },
10902 { 0x00002258, 0x00300a24, 0x000 },
10903 { 0x00040000, 0x00694622, 0x68a },
10904 { 0x00002169, 0x00204411, 0x000 },
10905 { 0x00000000, 0x00204805, 0x000 },
10906 { 0x00020000, 0x00294a26, 0x000 },
10907 { 0x00000000, 0x00204810, 0x000 },
10908 { 0xcafebabe, 0x00204811, 0x000 },
10909 { 0x00000002, 0x002f0223, 0x000 },
10910 { 0x00000000, 0x0cc00000, 0x56b },
10911 { 0x00000000, 0xc0201c10, 0x000 },
10912 { 0x00000000, 0xc0400000, 0x579 },
10913 { 0x00000002, 0x002f0223, 0x000 },
10914 { 0x00000000, 0x0cc00000, 0x56b },
10915 { 0x81000000, 0x00204411, 0x000 },
10916 { 0x00000001, 0x00204811, 0x000 },
10917 { 0x00002258, 0x00300a24, 0x000 },
10918 { 0x00040000, 0x00694622, 0x68a },
10919 { 0x00000000, 0xc0201c10, 0x000 },
10920 { 0x00000000, 0xc0400000, 0x579 },
10921 { 0x00000000, 0x002f0223, 0x000 },
10922 { 0x00000000, 0x0cc00000, 0x56f },
10923 { 0x00000000, 0xc0201c00, 0x000 },
10924 { 0x00000000, 0xc0400000, 0x579 },
10925 { 0x00000004, 0x002f0223, 0x000 },
10926 { 0x00000000, 0x0cc00000, 0x577 },
10927 { 0x81000000, 0x00204411, 0x000 },
10928 { 0x00000000, 0x00204811, 0x000 },
10929 { 0x0000216d, 0x00204411, 0x000 },
10930 { 0x00000000, 0xc0204800, 0x000 },
10931 { 0x00000000, 0xc0604800, 0x68f },
10932 { 0x00000000, 0x00401c10, 0x579 },
10933 { 0x00000000, 0xc0200000, 0x000 },
10934 { 0x00000000, 0xc0400000, 0x000 },
10935 { 0x00000000, 0x0ee00000, 0x57b },
10936 { 0x00000000, 0x00600000, 0x5c6 },
10937 { 0x00000000, 0x002f0224, 0x000 },
10938 { 0x00000000, 0x0cc00000, 0x58c },
10939 { 0x0000a2b7, 0x00204411, 0x000 },
10940 { 0x00000000, 0x00204807, 0x000 },
10941 { 0x81000000, 0x00204411, 0x000 },
10942 { 0x00000001, 0x00204811, 0x000 },
10943 { 0x0004a2b6, 0x00604411, 0x68a },
10944 { 0x0000001a, 0x00212230, 0x000 },
10945 { 0x00000006, 0x00222630, 0x000 },
10946 { 0x00042004, 0x00604411, 0x68a },
10947 { 0x0000a2c4, 0x00204411, 0x000 },
10948 { 0x00000000, 0x003048e9, 0x000 },
10949 { 0x00000000, 0x00e00000, 0x58a },
10950 { 0x0000a2d1, 0x00204411, 0x000 },
10951 { 0x00000000, 0x00404808, 0x000 },
10952 { 0x0000a2d1, 0x00204411, 0x000 },
10953 { 0x00000001, 0x00504a28, 0x000 },
10954 { 0x00000001, 0x002f0224, 0x000 },
10955 { 0x00000000, 0x0cc00000, 0x59d },
10956 { 0x0000a2bb, 0x00204411, 0x000 },
10957 { 0x00000000, 0x00204807, 0x000 },
10958 { 0x81000000, 0x00204411, 0x000 },
10959 { 0x00000001, 0x00204811, 0x000 },
10960 { 0x0004a2ba, 0x00604411, 0x68a },
10961 { 0x0000001a, 0x00212230, 0x000 },
10962 { 0x00000006, 0x00222630, 0x000 },
10963 { 0x00042004, 0x00604411, 0x68a },
10964 { 0x0000a2c5, 0x00204411, 0x000 },
10965 { 0x00000000, 0x003048e9, 0x000 },
10966 { 0x00000000, 0x00e00000, 0x59b },
10967 { 0x0000a2d2, 0x00204411, 0x000 },
10968 { 0x00000000, 0x00404808, 0x000 },
10969 { 0x0000a2d2, 0x00204411, 0x000 },
10970 { 0x00000001, 0x00504a28, 0x000 },
10971 { 0x00000002, 0x002f0224, 0x000 },
10972 { 0x00000000, 0x0cc00000, 0x5ae },
10973 { 0x0000a2bf, 0x00204411, 0x000 },
10974 { 0x00000000, 0x00204807, 0x000 },
10975 { 0x81000000, 0x00204411, 0x000 },
10976 { 0x00000001, 0x00204811, 0x000 },
10977 { 0x0004a2be, 0x00604411, 0x68a },
10978 { 0x0000001a, 0x00212230, 0x000 },
10979 { 0x00000006, 0x00222630, 0x000 },
10980 { 0x00042004, 0x00604411, 0x68a },
10981 { 0x0000a2c6, 0x00204411, 0x000 },
10982 { 0x00000000, 0x003048e9, 0x000 },
10983 { 0x00000000, 0x00e00000, 0x5ac },
10984 { 0x0000a2d3, 0x00204411, 0x000 },
10985 { 0x00000000, 0x00404808, 0x000 },
10986 { 0x0000a2d3, 0x00204411, 0x000 },
10987 { 0x00000001, 0x00504a28, 0x000 },
10988 { 0x0000a2c3, 0x00204411, 0x000 },
10989 { 0x00000000, 0x00204807, 0x000 },
10990 { 0x81000000, 0x00204411, 0x000 },
10991 { 0x00000001, 0x00204811, 0x000 },
10992 { 0x0004a2c2, 0x00604411, 0x68a },
10993 { 0x0000001a, 0x00212230, 0x000 },
10994 { 0x00000006, 0x00222630, 0x000 },
10995 { 0x00042004, 0x00604411, 0x68a },
10996 { 0x0000a2c7, 0x00204411, 0x000 },
10997 { 0x00000000, 0x003048e9, 0x000 },
10998 { 0x00000000, 0x00e00000, 0x5bb },
10999 { 0x0000a2d4, 0x00204411, 0x000 },
11000 { 0x00000000, 0x00404808, 0x000 },
11001 { 0x0000a2d4, 0x00204411, 0x000 },
11002 { 0x00000001, 0x00504a28, 0x000 },
11003 { 0x85000000, 0x00204411, 0x000 },
11004 { 0x00000000, 0x00204801, 0x000 },
11005 { 0x0000304a, 0x00204411, 0x000 },
11006 { 0x01000000, 0x00204811, 0x000 },
11007 { 0x00000000, 0x00400000, 0x5c1 },
11008 { 0xa4000000, 0xc0204411, 0x000 },
11009 { 0x00000000, 0xc0404800, 0x000 },
11010 { 0x00000000, 0xc0600000, 0x5c6 },
11011 { 0x00000000, 0xc0400400, 0x001 },
11012 { 0x0000002c, 0x00203621, 0x000 },
11013 { 0x81000000, 0x00204411, 0x000 },
11014 { 0x00000006, 0x00204811, 0x000 },
11015 { 0x00000000, 0x002f0230, 0x000 },
11016 { 0x00000000, 0x0cc00000, 0x5cd },
11017 { 0x00000000, 0x00200411, 0x000 },
11018 { 0x00000030, 0x00403621, 0x5e0 },
11019 { 0x00000030, 0x0020062d, 0x000 },
11020 { 0x00007e00, 0x00280621, 0x000 },
11021 { 0x00000000, 0x002f0221, 0x000 },
11022 { 0x00000000, 0x0ce00000, 0x5e0 },
11023 { 0x81000000, 0x00204411, 0x000 },
11024 { 0x00000001, 0x00204811, 0x000 },
11025 { 0x0004a092, 0x00604411, 0x68a },
11026 { 0x00000031, 0x00203630, 0x000 },
11027 { 0x0004a093, 0x00604411, 0x68a },
11028 { 0x00000032, 0x00203630, 0x000 },
11029 { 0x0004a2b6, 0x00604411, 0x68a },
11030 { 0x00000033, 0x00203630, 0x000 },
11031 { 0x0004a2ba, 0x00604411, 0x68a },
11032 { 0x00000034, 0x00203630, 0x000 },
11033 { 0x0004a2be, 0x00604411, 0x68a },
11034 { 0x00000035, 0x00203630, 0x000 },
11035 { 0x0004a2c2, 0x00604411, 0x68a },
11036 { 0x00000036, 0x00203630, 0x000 },
11037 { 0x00042004, 0x00604411, 0x68a },
11038 { 0x0001a2a4, 0x00204411, 0x000 },
11039 { 0x0000003f, 0x00204811, 0x000 },
11040 { 0x0000003f, 0x00204811, 0x000 },
11041 { 0x0000003f, 0x00204811, 0x000 },
11042 { 0x0000003f, 0x00204811, 0x000 },
11043 { 0x00000005, 0x00204811, 0x000 },
11044 { 0x0000a1f4, 0x00204411, 0x000 },
11045 { 0x00000000, 0x00204811, 0x000 },
11046 { 0x88000000, 0x00204411, 0x000 },
11047 { 0x00000001, 0x00204811, 0x000 },
11048 { 0x81000000, 0x00204411, 0x000 },
11049 { 0x00000006, 0x00204811, 0x000 },
11050 { 0x00000001, 0x002f0230, 0x000 },
11051 { 0x00000000, 0x0ce00000, 0x629 },
11052 { 0x00000030, 0x0020062d, 0x000 },
11053 { 0x00000000, 0x002f0221, 0x000 },
11054 { 0x00000000, 0x0ce00000, 0x629 },
11055 { 0x81000000, 0x00204411, 0x000 },
11056 { 0x00000001, 0x00204811, 0x000 },
11057 { 0x00007e00, 0x00280621, 0x000 },
11058 { 0x00000000, 0x002f0221, 0x000 },
11059 { 0x00000000, 0x0ce00000, 0x602 },
11060 { 0x0000a092, 0x00204411, 0x000 },
11061 { 0x00000031, 0x00204a2d, 0x000 },
11062 { 0x0000a093, 0x00204411, 0x000 },
11063 { 0x00000032, 0x00204a2d, 0x000 },
11064 { 0x0000a2b6, 0x00204411, 0x000 },
11065 { 0x00000033, 0x00204a2d, 0x000 },
11066 { 0x0000a2ba, 0x00204411, 0x000 },
11067 { 0x00000034, 0x00204a2d, 0x000 },
11068 { 0x0000a2be, 0x00204411, 0x000 },
11069 { 0x00000035, 0x00204a2d, 0x000 },
11070 { 0x0000a2c2, 0x00204411, 0x000 },
11071 { 0x00000036, 0x00204a2d, 0x000 },
11072 { 0x00000030, 0x0020062d, 0x000 },
11073 { 0x000001ff, 0x00280621, 0x000 },
11074 { 0x00000000, 0x002f0221, 0x000 },
11075 { 0x00000000, 0x0ce00000, 0x628 },
11076 { 0x00000000, 0x00210221, 0x000 },
11077 { 0x00000000, 0x14c00000, 0x60b },
11078 { 0x0004a003, 0x00604411, 0x68a },
11079 { 0x0000a003, 0x00204411, 0x000 },
11080 { 0x00000000, 0x00204810, 0x000 },
11081 { 0x00000001, 0x00210621, 0x000 },
11082 { 0x00000000, 0x14c00000, 0x610 },
11083 { 0x0004a010, 0x00604411, 0x68a },
11084 { 0x0000a010, 0x00204411, 0x000 },
11085 { 0x00000000, 0x00204810, 0x000 },
11086 { 0x00000001, 0x00210621, 0x000 },
11087 { 0x00000000, 0x002f0221, 0x000 },
11088 { 0x00000000, 0x0ce00000, 0x628 },
11089 { 0x0004a011, 0x00604411, 0x68a },
11090 { 0x0000a011, 0x00204411, 0x000 },
11091 { 0x00000000, 0x00204810, 0x000 },
11092 { 0x0004a012, 0x00604411, 0x68a },
11093 { 0x0000a012, 0x00204411, 0x000 },
11094 { 0x00000000, 0x00204810, 0x000 },
11095 { 0x0004a013, 0x00604411, 0x68a },
11096 { 0x0000a013, 0x00204411, 0x000 },
11097 { 0x00000000, 0x00204810, 0x000 },
11098 { 0x0004a014, 0x00604411, 0x68a },
11099 { 0x0000a014, 0x00204411, 0x000 },
11100 { 0x00000000, 0x00204810, 0x000 },
11101 { 0x0004a015, 0x00604411, 0x68a },
11102 { 0x0000a015, 0x00204411, 0x000 },
11103 { 0x00000000, 0x00204810, 0x000 },
11104 { 0x0004a016, 0x00604411, 0x68a },
11105 { 0x0000a016, 0x00204411, 0x000 },
11106 { 0x00000000, 0x00204810, 0x000 },
11107 { 0x0004a017, 0x00604411, 0x68a },
11108 { 0x0000a017, 0x00204411, 0x000 },
11109 { 0x00000000, 0x00204810, 0x000 },
11110 { 0x00042004, 0x00604411, 0x68a },
11111 { 0x0000002c, 0x0080062d, 0x000 },
11112 { 0xff000000, 0x00204411, 0x000 },
11113 { 0x00000000, 0x00204811, 0x000 },
11114 { 0x00000001, 0x00204811, 0x000 },
11115 { 0x00000002, 0x00804811, 0x000 },
11116 { 0x00000000, 0x0ee00000, 0x63a },
11117 { 0x00000030, 0x0020062d, 0x000 },
11118 { 0x00000002, 0x00280621, 0x000 },
11119 { 0x00000000, 0x002f0221, 0x000 },
11120 { 0x00000000, 0x0ce00000, 0x638 },
11121 { 0x81000000, 0x00204411, 0x000 },
11122 { 0x00000001, 0x00204811, 0x000 },
11123 { 0x00042004, 0x00604411, 0x68a },
11124 { 0x00001000, 0x00200811, 0x000 },
11125 { 0x0000002b, 0x00203622, 0x000 },
11126 { 0x00000000, 0x00600000, 0x63e },
11127 { 0x00000000, 0x00600000, 0x5c6 },
11128 { 0x98000000, 0x00204411, 0x000 },
11129 { 0x00000000, 0x00804811, 0x000 },
11130 { 0x00000000, 0xc0600000, 0x63e },
11131 { 0x00000000, 0xc0400400, 0x001 },
11132 { 0x0000a2a4, 0x00204411, 0x000 },
11133 { 0x00000022, 0x00204811, 0x000 },
11134 { 0x89000000, 0x00204411, 0x000 },
11135 { 0x00000001, 0x00404811, 0x62a },
11136 { 0x97000000, 0x00204411, 0x000 },
11137 { 0x00000000, 0x00204811, 0x000 },
11138 { 0x8a000000, 0x00204411, 0x000 },
11139 { 0x00000000, 0x00404811, 0x62a },
11140 { 0x00000000, 0x00600000, 0x659 },
11141 { 0x00002010, 0x00204411, 0x000 },
11142 { 0x00008000, 0x00204811, 0x000 },
11143 { 0x0001a2a4, 0xc0204411, 0x000 },
11144 { 0x00000016, 0x00604811, 0x36e },
11145 { 0x00002010, 0x00204411, 0x000 },
11146 { 0x00010000, 0x00204811, 0x000 },
11147 { 0x81000000, 0x00204411, 0x000 },
11148 { 0x00000001, 0x00204811, 0x000 },
11149 { 0x0000217c, 0x00204411, 0x000 },
11150 { 0x09800000, 0x00204811, 0x000 },
11151 { 0xffffffff, 0x00204811, 0x000 },
11152 { 0x00000000, 0x00204811, 0x000 },
11153 { 0x00000000, 0x17000000, 0x000 },
11154 { 0x0004217f, 0x00604411, 0x68a },
11155 { 0x0000001f, 0x00210230, 0x000 },
11156 { 0x00000000, 0x14c00000, 0x000 },
11157 { 0x00000004, 0x00404c11, 0x653 },
11158 { 0x00000000, 0x00400000, 0x000 },
11159 { 0x00000017, 0x00201e2d, 0x000 },
11160 { 0x00000004, 0x00291e27, 0x000 },
11161 { 0x00000017, 0x00803627, 0x000 },
11162 { 0x00000017, 0x00201e2d, 0x000 },
11163 { 0xfffffffb, 0x00281e27, 0x000 },
11164 { 0x00000017, 0x00803627, 0x000 },
11165 { 0x00000017, 0x00201e2d, 0x000 },
11166 { 0x00000008, 0x00291e27, 0x000 },
11167 { 0x00000017, 0x00803627, 0x000 },
11168 { 0x00000017, 0x00201e2d, 0x000 },
11169 { 0xfffffff7, 0x00281e27, 0x000 },
11170 { 0x00000017, 0x00803627, 0x000 },
11171 { 0x00002010, 0x00204411, 0x000 },
11172 { 0x00008000, 0x00204811, 0x000 },
11173 { 0x0001a2a4, 0x00204411, 0x000 },
11174 { 0x00000016, 0x00604811, 0x36e },
11175 { 0x00002010, 0x00204411, 0x000 },
11176 { 0x00010000, 0x00204811, 0x000 },
11177 { 0x0000217c, 0x00204411, 0x000 },
11178 { 0x01800000, 0x00204811, 0x000 },
11179 { 0xffffffff, 0x00204811, 0x000 },
11180 { 0x00000000, 0x00204811, 0x000 },
11181 { 0x00000000, 0x17000000, 0x000 },
11182 { 0x81000000, 0x00204411, 0x000 },
11183 { 0x00000001, 0x00204811, 0x000 },
11184 { 0x0004217f, 0x00604411, 0x68a },
11185 { 0x0000001f, 0x00210230, 0x000 },
11186 { 0x00000000, 0x14c00000, 0x689 },
11187 { 0x00000010, 0x00404c11, 0x66f },
11188 { 0x00000000, 0xc0200400, 0x000 },
11189 { 0x00000000, 0x38c00000, 0x000 },
11190 { 0x0000001d, 0x00200a2d, 0x000 },
11191 { 0x0000001e, 0x00200e2d, 0x000 },
11192 { 0x0000001f, 0x0020122d, 0x000 },
11193 { 0x00000020, 0x0020162d, 0x000 },
11194 { 0x00002169, 0x00204411, 0x000 },
11195 { 0x00000000, 0x00204804, 0x000 },
11196 { 0x00000000, 0x00204805, 0x000 },
11197 { 0x00000000, 0x00204801, 0x000 },
11198 { 0xcafebabe, 0x00204811, 0x000 },
11199 { 0x00000004, 0x00301224, 0x000 },
11200 { 0x00000000, 0x002f0064, 0x000 },
11201 { 0x00000000, 0x0cc00000, 0x688 },
11202 { 0x00000003, 0x00281a22, 0x000 },
11203 { 0x00000008, 0x00221222, 0x000 },
11204 { 0xfffff000, 0x00281224, 0x000 },
11205 { 0x00000000, 0x002910c4, 0x000 },
11206 { 0x0000001f, 0x00403624, 0x000 },
11207 { 0x00000000, 0x00800000, 0x000 },
11208 { 0x00000000, 0x1ac00000, 0x68a },
11209 { 0x9f000000, 0x00204411, 0x000 },
11210 { 0xcafebabe, 0x00204811, 0x000 },
11211 { 0x00000000, 0x1ae00000, 0x68d },
11212 { 0x00000000, 0x00800000, 0x000 },
11213 { 0x00000000, 0x1ac00000, 0x68f },
11214 { 0x9e000000, 0x00204411, 0x000 },
11215 { 0xcafebabe, 0x00204811, 0x000 },
11216 { 0x00000000, 0x1ae00000, 0x692 },
11217 { 0x00000000, 0x00800000, 0x000 },
11218 { 0x00000000, 0x00600000, 0x00b },
11219 { 0x00001000, 0x00600411, 0x315 },
11220 { 0x00000000, 0x00200411, 0x000 },
11221 { 0x00000000, 0x00600811, 0x1b2 },
11222 { 0x0000225c, 0x00204411, 0x000 },
11223 { 0x00000003, 0x00204811, 0x000 },
11224 { 0x00002256, 0x00204411, 0x000 },
11225 { 0x0000001b, 0x00204811, 0x000 },
11226 { 0x0000a1fc, 0x00204411, 0x000 },
11227 { 0x00000001, 0x00204811, 0x000 },
11228 { 0x0001a1fd, 0xc0204411, 0x000 },
11229 { 0x00000021, 0x00201e2d, 0x000 },
11230 { 0x00000010, 0x00221e27, 0x000 },
11231 { 0x00000024, 0x0020222d, 0x000 },
11232 { 0x0000ffff, 0x00282228, 0x000 },
11233 { 0x00000000, 0x00294907, 0x000 },
11234 { 0x00000000, 0x00204811, 0x000 },
11235 { 0x00000022, 0x0020222d, 0x000 },
11236 { 0x0000ffff, 0x00282228, 0x000 },
11237 { 0x00000000, 0x00294907, 0x000 },
11238 { 0x00000000, 0x00204811, 0x000 },
11239 { 0x00000023, 0x00201e2d, 0x000 },
11240 { 0x00000010, 0x00221e27, 0x000 },
11241 { 0x00000000, 0x00294907, 0x000 },
11242 { 0x00000000, 0x00404811, 0x000 },
11243 { 0x00000000, 0x00000000, 0x000 },
11244 { 0x00000000, 0x00000000, 0x000 },
11245 { 0x00000000, 0x00000000, 0x000 },
11246 { 0x00000000, 0x00000000, 0x000 },
11247 { 0x00000000, 0x00000000, 0x000 },
11248 { 0x00000000, 0x00000000, 0x000 },
11249 { 0x00000000, 0x00000000, 0x000 },
11250 { 0x00000000, 0x00000000, 0x000 },
11251 { 0x00000000, 0x00000000, 0x000 },
11252 { 0x00000000, 0x00000000, 0x000 },
11253 { 0x00000000, 0x00000000, 0x000 },
11254 { 0x00000000, 0x00000000, 0x000 },
11255 { 0x00000000, 0x00000000, 0x000 },
11256 { 0x00000000, 0x00000000, 0x000 },
11257 { 0x00000000, 0x00000000, 0x000 },
11258 { 0x00000000, 0x00000000, 0x000 },
11259 { 0x00000000, 0x00000000, 0x000 },
11260 { 0x00000000, 0x00000000, 0x000 },
11261 { 0x00000000, 0x00000000, 0x000 },
11262 { 0x00000000, 0x00000000, 0x000 },
11263 { 0x00000000, 0x00000000, 0x000 },
11264 { 0x00000000, 0x00000000, 0x000 },
11265 { 0x00000000, 0x00000000, 0x000 },
11266 { 0x00000000, 0x00000000, 0x000 },
11267 { 0x00000000, 0x00000000, 0x000 },
11268 { 0x00000000, 0x00000000, 0x000 },
11269 { 0x00000000, 0x00000000, 0x000 },
11270 { 0x00000000, 0x00000000, 0x000 },
11271 { 0x00000000, 0x00000000, 0x000 },
11272 { 0x00000000, 0x00000000, 0x000 },
11273 { 0x00000000, 0x00000000, 0x000 },
11274 { 0x00000000, 0x00000000, 0x000 },
11275 { 0x00000000, 0x00000000, 0x000 },
11276 { 0x00000000, 0x00000000, 0x000 },
11277 { 0x00000000, 0x00000000, 0x000 },
11278 { 0x00000000, 0x00000000, 0x000 },
11279 { 0x00000000, 0x00000000, 0x000 },
11280 { 0x00000000, 0x00000000, 0x000 },
11281 { 0x00000000, 0x00000000, 0x000 },
11282 { 0x00000000, 0x00000000, 0x000 },
11283 { 0x00000000, 0x00000000, 0x000 },
11284 { 0x00000000, 0x00000000, 0x000 },
11285 { 0x00000000, 0x00000000, 0x000 },
11286 { 0x00000000, 0x00000000, 0x000 },
11287 { 0x00000000, 0x00000000, 0x000 },
11288 { 0x00000000, 0x00000000, 0x000 },
11289 { 0x00000000, 0x00000000, 0x000 },
11290 { 0x00000000, 0x00000000, 0x000 },
11291 { 0x00000000, 0x00000000, 0x000 },
11292 { 0x00000000, 0x00000000, 0x000 },
11293 { 0x00000000, 0x00000000, 0x000 },
11294 { 0x00000000, 0x00000000, 0x000 },
11295 { 0x00000000, 0x00000000, 0x000 },
11296 { 0x00000000, 0x00000000, 0x000 },
11297 { 0x00000000, 0x00000000, 0x000 },
11298 { 0x014204ff, 0x05bd0250, 0x000 },
11299 { 0x01c30168, 0x043f05bd, 0x000 },
11300 { 0x02250209, 0x02500151, 0x000 },
11301 { 0x02230245, 0x02a00241, 0x000 },
11302 { 0x03d705bd, 0x05bd05bd, 0x000 },
11303 { 0x06460647, 0x031f05bd, 0x000 },
11304 { 0x05bd05c2, 0x03200340, 0x000 },
11305 { 0x032a0282, 0x03420334, 0x000 },
11306 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11307 { 0x05bd054e, 0x05bd05bd, 0x000 },
11308 { 0x03ba05bd, 0x04b80344, 0x000 },
11309 { 0x0497044d, 0x043d05bd, 0x000 },
11310 { 0x04cd05bd, 0x044104da, 0x000 },
11311 { 0x044d0504, 0x03510375, 0x000 },
11312 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11313 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11314 { 0x05bd05bd, 0x063c05c4, 0x000 },
11315 { 0x05bd05bd, 0x000705bd, 0x000 },
11316 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11317 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11318 { 0x03f803ed, 0x04080406, 0x000 },
11319 { 0x040e040a, 0x040c0410, 0x000 },
11320 { 0x041c0418, 0x04240420, 0x000 },
11321 { 0x042c0428, 0x04340430, 0x000 },
11322 { 0x05bd05bd, 0x043805bd, 0x000 },
11323 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11324 { 0x05bd05bd, 0x05bd05bd, 0x000 },
11325 { 0x00020676, 0x06940006, 0x000 },
11326};
11327
11328static const u32 RV635_pfp_microcode[] = {
113290xca0400,
113300xa00000,
113310x7e828b,
113320x7c038b,
113330x8001b8,
113340x7c038b,
113350xd4401e,
113360xee001e,
113370xca0400,
113380xa00000,
113390x7e828b,
113400xc41838,
113410xca2400,
113420xca2800,
113430x9581a8,
113440xc41c3a,
113450xc3c000,
113460xca0800,
113470xca0c00,
113480x7c744b,
113490xc20005,
113500x99c000,
113510xc41c3a,
113520x7c744c,
113530xc0fff0,
113540x042c04,
113550x309002,
113560x7d2500,
113570x351402,
113580x7d350b,
113590x255403,
113600x7cd580,
113610x259c03,
113620x95c004,
113630xd5001b,
113640x7eddc1,
113650x7d9d80,
113660xd6801b,
113670xd5801b,
113680xd4401e,
113690xd5401e,
113700xd6401e,
113710xd6801e,
113720xd4801e,
113730xd4c01e,
113740x9783d3,
113750xd5c01e,
113760xca0800,
113770x80001a,
113780xca0c00,
113790xe4011e,
113800xd4001e,
113810x80000c,
113820xc41838,
113830xe4013e,
113840xd4001e,
113850x80000c,
113860xc41838,
113870xd4401e,
113880xee001e,
113890xca0400,
113900xa00000,
113910x7e828b,
113920xe4011e,
113930xd4001e,
113940xd4401e,
113950xee001e,
113960xca0400,
113970xa00000,
113980x7e828b,
113990xe4013e,
114000xd4001e,
114010xd4401e,
114020xee001e,
114030xca0400,
114040xa00000,
114050x7e828b,
114060xca1800,
114070xd4401e,
114080xd5801e,
114090x800053,
114100xd40075,
114110xd4401e,
114120xca0800,
114130xca0c00,
114140xca1000,
114150xd48019,
114160xd4c018,
114170xd50017,
114180xd4801e,
114190xd4c01e,
114200xd5001e,
114210xe2001e,
114220xca0400,
114230xa00000,
114240x7e828b,
114250xca0800,
114260xd48060,
114270xd4401e,
114280x800000,
114290xd4801e,
114300xca0800,
114310xd48061,
114320xd4401e,
114330x800000,
114340xd4801e,
114350xca0800,
114360xca0c00,
114370xd4401e,
114380xd48016,
114390xd4c016,
114400xd4801e,
114410x8001b8,
114420xd4c01e,
114430xc60843,
114440xca0c00,
114450xca1000,
114460x948004,
114470xca1400,
114480xe420f3,
114490xd42013,
114500xd56065,
114510xd4e01c,
114520xd5201c,
114530xd5601c,
114540x800000,
114550x062001,
114560xc60843,
114570xca0c00,
114580xca1000,
114590x9483f7,
114600xca1400,
114610xe420f3,
114620x800079,
114630xd42013,
114640xc60843,
114650xca0c00,
114660xca1000,
114670x9883ef,
114680xca1400,
114690xd40064,
114700x80008d,
114710x000000,
114720xc41432,
114730xc61843,
114740xc4082f,
114750x954005,
114760xc40c30,
114770xd4401e,
114780x800000,
114790xee001e,
114800x9583f5,
114810xc41031,
114820xd44033,
114830xd52065,
114840xd4a01c,
114850xd4e01c,
114860xd5201c,
114870xe4015e,
114880xd4001e,
114890x800000,
114900x062001,
114910xca1800,
114920x0a2001,
114930xd60076,
114940xc40836,
114950x988007,
114960xc61045,
114970x950110,
114980xd4001f,
114990xd46062,
115000x800000,
115010xd42062,
115020xcc3835,
115030xcc1433,
115040x8401bb,
115050xd40072,
115060xd5401e,
115070x800000,
115080xee001e,
115090xe2001a,
115100x8401bb,
115110xe2001a,
115120xcc104b,
115130xcc0447,
115140x2c9401,
115150x7d098b,
115160x984005,
115170x7d15cb,
115180xd4001a,
115190x8001b8,
115200xd4006d,
115210x344401,
115220xcc0c48,
115230x98403a,
115240xcc2c4a,
115250x958004,
115260xcc0449,
115270x8001b8,
115280xd4001a,
115290xd4c01a,
115300x282801,
115310x8400f0,
115320xcc1003,
115330x98801b,
115340x04380c,
115350x8400f0,
115360xcc1003,
115370x988017,
115380x043808,
115390x8400f0,
115400xcc1003,
115410x988013,
115420x043804,
115430x8400f0,
115440xcc1003,
115450x988014,
115460xcc104c,
115470x9a8009,
115480xcc144d,
115490x9840dc,
115500xd4006d,
115510xcc1848,
115520xd5001a,
115530xd5401a,
115540x8000c9,
115550xd5801a,
115560x96c0d5,
115570xd4006d,
115580x8001b8,
115590xd4006e,
115600x9ac003,
115610xd4006d,
115620xd4006e,
115630x800000,
115640xec007f,
115650x9ac0cc,
115660xd4006d,
115670x8001b8,
115680xd4006e,
115690xcc1403,
115700xcc1803,
115710xcc1c03,
115720x7d9103,
115730x7dd583,
115740x7d190c,
115750x35cc1f,
115760x35701f,
115770x7cf0cb,
115780x7cd08b,
115790x880000,
115800x7e8e8b,
115810x95c004,
115820xd4006e,
115830x8001b8,
115840xd4001a,
115850xd4c01a,
115860xcc0803,
115870xcc0c03,
115880xcc1003,
115890xcc1403,
115900xcc1803,
115910xcc1c03,
115920xcc2403,
115930xcc2803,
115940x35c41f,
115950x36b01f,
115960x7c704b,
115970x34f01f,
115980x7c704b,
115990x35701f,
116000x7c704b,
116010x7d8881,
116020x7dccc1,
116030x7e5101,
116040x7e9541,
116050x7c9082,
116060x7cd4c2,
116070x7c848b,
116080x9ac003,
116090x7c8c8b,
116100x2c8801,
116110x98809e,
116120xd4006d,
116130x98409c,
116140xd4006e,
116150xcc084c,
116160xcc0c4d,
116170xcc1048,
116180xd4801a,
116190xd4c01a,
116200x800101,
116210xd5001a,
116220xcc0832,
116230xd40032,
116240x9482d9,
116250xca0c00,
116260xd4401e,
116270x800000,
116280xd4001e,
116290xe4011e,
116300xd4001e,
116310xca0800,
116320xca0c00,
116330xca1000,
116340xd4401e,
116350xca1400,
116360xd4801e,
116370xd4c01e,
116380xd5001e,
116390xd5401e,
116400xd54034,
116410x800000,
116420xee001e,
116430x280404,
116440xe2001a,
116450xe2001a,
116460xd4401a,
116470xca3800,
116480xcc0803,
116490xcc0c03,
116500xcc0c03,
116510xcc0c03,
116520x9882bd,
116530x000000,
116540x8401bb,
116550xd7a06f,
116560x800000,
116570xee001f,
116580xca0400,
116590xc2ff00,
116600xcc0834,
116610xc13fff,
116620x7c74cb,
116630x7cc90b,
116640x7d010f,
116650x9902b0,
116660x7c738b,
116670x8401bb,
116680xd7a06f,
116690x800000,
116700xee001f,
116710xca0800,
116720x281900,
116730x7d898b,
116740x958014,
116750x281404,
116760xca0c00,
116770xca1000,
116780xca1c00,
116790xca2400,
116800xe2001f,
116810xd4c01a,
116820xd5001a,
116830xd5401a,
116840xcc1803,
116850xcc2c03,
116860xcc2c03,
116870xcc2c03,
116880x7da58b,
116890x7d9c47,
116900x984297,
116910x000000,
116920x800161,
116930xd4c01a,
116940xd4401e,
116950xd4801e,
116960x800000,
116970xee001e,
116980xe4011e,
116990xd4001e,
117000xd4401e,
117010xee001e,
117020xca0400,
117030xa00000,
117040x7e828b,
117050xe4013e,
117060xd4001e,
117070xd4401e,
117080xee001e,
117090xca0400,
117100xa00000,
117110x7e828b,
117120xca0800,
117130x248c06,
117140x0ccc06,
117150x98c006,
117160xcc104e,
117170x990004,
117180xd40073,
117190xe4011e,
117200xd4001e,
117210xd4401e,
117220xd4801e,
117230x800000,
117240xee001e,
117250xca0800,
117260xca0c00,
117270x34d018,
117280x251001,
117290x950021,
117300xc17fff,
117310xca1000,
117320xca1400,
117330xca1800,
117340xd4801d,
117350xd4c01d,
117360x7db18b,
117370xc14202,
117380xc2c001,
117390xd5801d,
117400x34dc0e,
117410x7d5d4c,
117420x7f734c,
117430xd7401e,
117440xd5001e,
117450xd5401e,
117460xc14200,
117470xc2c000,
117480x099c01,
117490x31dc10,
117500x7f5f4c,
117510x7f734c,
117520x042802,
117530x7d8380,
117540xd5a86f,
117550xd58066,
117560xd7401e,
117570xec005e,
117580xc82402,
117590xc82402,
117600x8001b8,
117610xd60076,
117620xd4401e,
117630xd4801e,
117640xd4c01e,
117650x800000,
117660xee001e,
117670x800000,
117680xee001f,
117690xd4001f,
117700x800000,
117710xd4001f,
117720xd4001f,
117730x880000,
117740xd4001f,
117750x000000,
117760x000000,
117770x000000,
117780x000000,
117790x000000,
117800x000000,
117810x000000,
117820x000000,
117830x000000,
117840x000000,
117850x000000,
117860x000000,
117870x000000,
117880x000000,
117890x000000,
117900x000000,
117910x000000,
117920x000000,
117930x000000,
117940x000000,
117950x000000,
117960x000000,
117970x000000,
117980x000000,
117990x000000,
118000x000000,
118010x000000,
118020x000000,
118030x000000,
118040x000000,
118050x000000,
118060x000000,
118070x000000,
118080x000000,
118090x000000,
118100x000000,
118110x000000,
118120x000000,
118130x000000,
118140x000000,
118150x000000,
118160x000000,
118170x000000,
118180x000000,
118190x000000,
118200x000000,
118210x000000,
118220x000000,
118230x000000,
118240x000000,
118250x000000,
118260x000000,
118270x000000,
118280x000000,
118290x000000,
118300x000000,
118310x000000,
118320x000000,
118330x000000,
118340x000000,
118350x000000,
118360x000000,
118370x000000,
118380x000000,
118390x000000,
118400x000000,
118410x010171,
118420x020178,
118430x03008f,
118440x04007f,
118450x050003,
118460x06003f,
118470x070032,
118480x08012c,
118490x090046,
118500x0a0036,
118510x1001b6,
118520x1700a2,
118530x22013a,
118540x230149,
118550x2000b4,
118560x240125,
118570x27004d,
118580x28006a,
118590x2a0060,
118600x2b0052,
118610x2f0065,
118620x320087,
118630x34017f,
118640x3c0156,
118650x3f0072,
118660x41018c,
118670x44012e,
118680x550173,
118690x56017a,
118700x60000b,
118710x610034,
118720x620038,
118730x630038,
118740x640038,
118750x650038,
118760x660038,
118770x670038,
118780x68003a,
118790x690041,
118800x6a0048,
118810x6b0048,
118820x6c0048,
118830x6d0048,
118840x6e0048,
118850x6f0048,
118860x000006,
118870x000006,
118880x000006,
118890x000006,
118900x000006,
118910x000006,
118920x000006,
118930x000006,
118940x000006,
118950x000006,
118960x000006,
118970x000006,
118980x000006,
118990x000006,
119000x000006,
119010x000006,
119020x000006,
119030x000006,
119040x000006,
11905};
11906
11907static const u32 RV670_cp_microcode[][3] = {
11908 { 0x00000000, 0xc0200400, 0x000 },
11909 { 0x00000000, 0x00a0000a, 0x000 },
11910 { 0x0000ffff, 0x00284621, 0x000 },
11911 { 0x00000000, 0xd9004800, 0x000 },
11912 { 0x00000000, 0xc0200400, 0x000 },
11913 { 0x00000000, 0x00a0000a, 0x000 },
11914 { 0x00000000, 0x00e00000, 0x000 },
11915 { 0x00010000, 0xc0294620, 0x000 },
11916 { 0x00000000, 0xd9004800, 0x000 },
11917 { 0x00000000, 0xc0200400, 0x000 },
11918 { 0x00000000, 0x00a0000a, 0x000 },
11919 { 0x81000000, 0x00204411, 0x000 },
11920 { 0x00000001, 0x00204811, 0x000 },
11921 { 0x00042004, 0x00604411, 0x67c },
11922 { 0x00000000, 0x00600000, 0x624 },
11923 { 0x00000000, 0x00600000, 0x638 },
11924 { 0x00000000, 0xc0200800, 0x000 },
11925 { 0x00000f00, 0x00281622, 0x000 },
11926 { 0x00000008, 0x00211625, 0x000 },
11927 { 0x00000018, 0x00203625, 0x000 },
11928 { 0x8d000000, 0x00204411, 0x000 },
11929 { 0x00000004, 0x002f0225, 0x000 },
11930 { 0x00000000, 0x0ce00000, 0x018 },
11931 { 0x00412000, 0x00404811, 0x019 },
11932 { 0x00422000, 0x00204811, 0x000 },
11933 { 0x8e000000, 0x00204411, 0x000 },
11934 { 0x00000028, 0x00204a2d, 0x000 },
11935 { 0x90000000, 0x00204411, 0x000 },
11936 { 0x00000000, 0x00204805, 0x000 },
11937 { 0x0000000c, 0x00211622, 0x000 },
11938 { 0x00000003, 0x00281625, 0x000 },
11939 { 0x00000019, 0x00211a22, 0x000 },
11940 { 0x00000004, 0x00281a26, 0x000 },
11941 { 0x00000000, 0x002914c5, 0x000 },
11942 { 0x00000019, 0x00203625, 0x000 },
11943 { 0x00000000, 0x003a1402, 0x000 },
11944 { 0x00000016, 0x00211625, 0x000 },
11945 { 0x00000003, 0x00281625, 0x000 },
11946 { 0x00000017, 0x00200e2d, 0x000 },
11947 { 0xfffffffc, 0x00280e23, 0x000 },
11948 { 0x00000000, 0x002914a3, 0x000 },
11949 { 0x00000017, 0x00203625, 0x000 },
11950 { 0x00008000, 0x00280e22, 0x000 },
11951 { 0x00000007, 0x00220e23, 0x000 },
11952 { 0x00000000, 0x0029386e, 0x000 },
11953 { 0x20000000, 0x00280e22, 0x000 },
11954 { 0x00000006, 0x00210e23, 0x000 },
11955 { 0x00000000, 0x0029386e, 0x000 },
11956 { 0x00000000, 0x00220222, 0x000 },
11957 { 0x00000000, 0x14e00000, 0x038 },
11958 { 0x00000000, 0x2ee00000, 0x035 },
11959 { 0x00000000, 0x2ce00000, 0x037 },
11960 { 0x00000000, 0x00400e2d, 0x039 },
11961 { 0x00000008, 0x00200e2d, 0x000 },
11962 { 0x00000009, 0x0040122d, 0x046 },
11963 { 0x00000001, 0x00400e2d, 0x039 },
11964 { 0x00000000, 0xc0200c00, 0x000 },
11965 { 0x003ffffc, 0x00281223, 0x000 },
11966 { 0x00000002, 0x00221224, 0x000 },
11967 { 0x0000001f, 0x00211e23, 0x000 },
11968 { 0x00000000, 0x14e00000, 0x03e },
11969 { 0x00000008, 0x00401c11, 0x041 },
11970 { 0x0000000d, 0x00201e2d, 0x000 },
11971 { 0x0000000f, 0x00281e27, 0x000 },
11972 { 0x00000003, 0x00221e27, 0x000 },
11973 { 0x7fc00000, 0x00281a23, 0x000 },
11974 { 0x00000014, 0x00211a26, 0x000 },
11975 { 0x00000001, 0x00331a26, 0x000 },
11976 { 0x00000008, 0x00221a26, 0x000 },
11977 { 0x00000000, 0x00290cc7, 0x000 },
11978 { 0x00000027, 0x00203624, 0x000 },
11979 { 0x00007f00, 0x00281221, 0x000 },
11980 { 0x00001400, 0x002f0224, 0x000 },
11981 { 0x00000000, 0x0ce00000, 0x04b },
11982 { 0x00000001, 0x00290e23, 0x000 },
11983 { 0x0000000e, 0x00203623, 0x000 },
11984 { 0x0000e000, 0x00204411, 0x000 },
11985 { 0xfff80000, 0x00294a23, 0x000 },
11986 { 0x00000000, 0x003a2c02, 0x000 },
11987 { 0x00000002, 0x00220e2b, 0x000 },
11988 { 0xfc000000, 0x00280e23, 0x000 },
11989 { 0x0000000f, 0x00203623, 0x000 },
11990 { 0x00001fff, 0x00294a23, 0x000 },
11991 { 0x00000027, 0x00204a2d, 0x000 },
11992 { 0x00000000, 0x00204811, 0x000 },
11993 { 0x00000029, 0x00200e2d, 0x000 },
11994 { 0x060a0200, 0x00294a23, 0x000 },
11995 { 0x00000000, 0x00204811, 0x000 },
11996 { 0x00000000, 0x00204811, 0x000 },
11997 { 0x00000001, 0x00210222, 0x000 },
11998 { 0x00000000, 0x14e00000, 0x061 },
11999 { 0x00000000, 0x2ee00000, 0x05f },
12000 { 0x00000000, 0x2ce00000, 0x05e },
12001 { 0x00000000, 0x00400e2d, 0x062 },
12002 { 0x00000001, 0x00400e2d, 0x062 },
12003 { 0x0000000a, 0x00200e2d, 0x000 },
12004 { 0x0000000b, 0x0040122d, 0x06a },
12005 { 0x00000000, 0xc0200c00, 0x000 },
12006 { 0x003ffffc, 0x00281223, 0x000 },
12007 { 0x00000002, 0x00221224, 0x000 },
12008 { 0x7fc00000, 0x00281623, 0x000 },
12009 { 0x00000014, 0x00211625, 0x000 },
12010 { 0x00000001, 0x00331625, 0x000 },
12011 { 0x80000000, 0x00280e23, 0x000 },
12012 { 0x00000000, 0x00290ca3, 0x000 },
12013 { 0x3ffffc00, 0x00290e23, 0x000 },
12014 { 0x0000001f, 0x00211e23, 0x000 },
12015 { 0x00000000, 0x14e00000, 0x06d },
12016 { 0x00000100, 0x00401c11, 0x070 },
12017 { 0x0000000d, 0x00201e2d, 0x000 },
12018 { 0x000000f0, 0x00281e27, 0x000 },
12019 { 0x00000004, 0x00221e27, 0x000 },
12020 { 0x81000000, 0x00204411, 0x000 },
12021 { 0x0000000d, 0x00204811, 0x000 },
12022 { 0xfffff0ff, 0x00281a30, 0x000 },
12023 { 0x0000a028, 0x00204411, 0x000 },
12024 { 0x00000000, 0x002948e6, 0x000 },
12025 { 0x0000a018, 0x00204411, 0x000 },
12026 { 0x3fffffff, 0x00284a23, 0x000 },
12027 { 0x0000a010, 0x00204411, 0x000 },
12028 { 0x00000000, 0x00204804, 0x000 },
12029 { 0x00000030, 0x0020162d, 0x000 },
12030 { 0x00000002, 0x00291625, 0x000 },
12031 { 0x00000030, 0x00203625, 0x000 },
12032 { 0x00000025, 0x0020162d, 0x000 },
12033 { 0x00000000, 0x002f00a3, 0x000 },
12034 { 0x00000000, 0x0cc00000, 0x083 },
12035 { 0x00000026, 0x0020162d, 0x000 },
12036 { 0x00000000, 0x002f00a4, 0x000 },
12037 { 0x00000000, 0x0cc00000, 0x084 },
12038 { 0x00000000, 0x00400000, 0x08a },
12039 { 0x00000025, 0x00203623, 0x000 },
12040 { 0x00000026, 0x00203624, 0x000 },
12041 { 0x00000017, 0x00201e2d, 0x000 },
12042 { 0x00000002, 0x00210227, 0x000 },
12043 { 0x00000000, 0x14e00000, 0x08a },
12044 { 0x00000000, 0x00600000, 0x659 },
12045 { 0x00000000, 0x00600000, 0x64d },
12046 { 0x00000002, 0x00210e22, 0x000 },
12047 { 0x00000000, 0x14c00000, 0x08d },
12048 { 0x00000012, 0xc0403620, 0x093 },
12049 { 0x00000000, 0x2ee00000, 0x091 },
12050 { 0x00000000, 0x2ce00000, 0x090 },
12051 { 0x00000002, 0x00400e2d, 0x092 },
12052 { 0x00000003, 0x00400e2d, 0x092 },
12053 { 0x0000000c, 0x00200e2d, 0x000 },
12054 { 0x00000012, 0x00203623, 0x000 },
12055 { 0x00000003, 0x00210e22, 0x000 },
12056 { 0x00000000, 0x14c00000, 0x098 },
12057 { 0x0000a00c, 0x00204411, 0x000 },
12058 { 0x00000000, 0xc0204800, 0x000 },
12059 { 0x00000000, 0xc0404800, 0x0a0 },
12060 { 0x0000a00c, 0x00204411, 0x000 },
12061 { 0x00000000, 0x00204811, 0x000 },
12062 { 0x00000000, 0x2ee00000, 0x09e },
12063 { 0x00000000, 0x2ce00000, 0x09d },
12064 { 0x00000002, 0x00400e2d, 0x09f },
12065 { 0x00000003, 0x00400e2d, 0x09f },
12066 { 0x0000000c, 0x00200e2d, 0x000 },
12067 { 0x00000000, 0x00204803, 0x000 },
12068 { 0x00000000, 0x003a0c02, 0x000 },
12069 { 0x003f0000, 0x00280e23, 0x000 },
12070 { 0x00000010, 0x00210e23, 0x000 },
12071 { 0x00000011, 0x00203623, 0x000 },
12072 { 0x0000001e, 0x0021022b, 0x000 },
12073 { 0x00000000, 0x14c00000, 0x0a7 },
12074 { 0x00000016, 0xc0203620, 0x000 },
12075 { 0x0000001f, 0x0021022b, 0x000 },
12076 { 0x00000000, 0x14c00000, 0x0aa },
12077 { 0x00000015, 0xc0203620, 0x000 },
12078 { 0x00000008, 0x00210e2b, 0x000 },
12079 { 0x0000007f, 0x00280e23, 0x000 },
12080 { 0x00000000, 0x002f0223, 0x000 },
12081 { 0x00000000, 0x0ce00000, 0x0e1 },
12082 { 0x00000000, 0x27000000, 0x000 },
12083 { 0x00000000, 0x00600000, 0x2a3 },
12084 { 0x00000001, 0x002f0223, 0x000 },
12085 { 0x00000000, 0x0ae00000, 0x0b3 },
12086 { 0x00000000, 0x00600000, 0x13a },
12087 { 0x81000000, 0x00204411, 0x000 },
12088 { 0x00000006, 0x00204811, 0x000 },
12089 { 0x0000000c, 0x00221e30, 0x000 },
12090 { 0x99800000, 0x00204411, 0x000 },
12091 { 0x00000004, 0x0020122d, 0x000 },
12092 { 0x00000008, 0x00221224, 0x000 },
12093 { 0x00000010, 0x00201811, 0x000 },
12094 { 0x00000000, 0x00291ce4, 0x000 },
12095 { 0x00000000, 0x00604807, 0x12f },
12096 { 0x9b000000, 0x00204411, 0x000 },
12097 { 0x00000000, 0x00204802, 0x000 },
12098 { 0x9c000000, 0x00204411, 0x000 },
12099 { 0x00000000, 0x0033146f, 0x000 },
12100 { 0x00000001, 0x00333e23, 0x000 },
12101 { 0x00000000, 0xd9004800, 0x000 },
12102 { 0x00000000, 0x00203c05, 0x000 },
12103 { 0x81000000, 0x00204411, 0x000 },
12104 { 0x0000000e, 0x00204811, 0x000 },
12105 { 0x00000000, 0x00201010, 0x000 },
12106 { 0x0000e007, 0x00204411, 0x000 },
12107 { 0x0000000f, 0x0021022b, 0x000 },
12108 { 0x00000000, 0x14c00000, 0x0cb },
12109 { 0x00f8ff08, 0x00204811, 0x000 },
12110 { 0x98000000, 0x00404811, 0x0dc },
12111 { 0x000000f0, 0x00280e22, 0x000 },
12112 { 0x000000a0, 0x002f0223, 0x000 },
12113 { 0x00000000, 0x0cc00000, 0x0da },
12114 { 0x00000011, 0x00200e2d, 0x000 },
12115 { 0x00000001, 0x002f0223, 0x000 },
12116 { 0x00000000, 0x0ce00000, 0x0d5 },
12117 { 0x00000002, 0x002f0223, 0x000 },
12118 { 0x00000000, 0x0ce00000, 0x0d4 },
12119 { 0x00003f00, 0x00400c11, 0x0d6 },
12120 { 0x00001f00, 0x00400c11, 0x0d6 },
12121 { 0x00000f00, 0x00200c11, 0x000 },
12122 { 0x00380009, 0x00294a23, 0x000 },
12123 { 0x3f000000, 0x00280e2b, 0x000 },
12124 { 0x00000002, 0x00220e23, 0x000 },
12125 { 0x00000007, 0x00494a23, 0x0dc },
12126 { 0x00380f09, 0x00204811, 0x000 },
12127 { 0x68000007, 0x00204811, 0x000 },
12128 { 0x00000008, 0x00214a27, 0x000 },
12129 { 0x00000000, 0x00204811, 0x000 },
12130 { 0x060a0200, 0x00294a24, 0x000 },
12131 { 0x00000000, 0x00204811, 0x000 },
12132 { 0x00000000, 0x00204811, 0x000 },
12133 { 0x0000a202, 0x00204411, 0x000 },
12134 { 0x00ff0000, 0x00280e22, 0x000 },
12135 { 0x00000080, 0x00294a23, 0x000 },
12136 { 0x00000027, 0x00200e2d, 0x000 },
12137 { 0x00000026, 0x0020122d, 0x000 },
12138 { 0x00000000, 0x002f0083, 0x000 },
12139 { 0x00000000, 0x0ce00000, 0x0ea },
12140 { 0x00000000, 0x00600000, 0x653 },
12141 { 0x00000000, 0x00400000, 0x0eb },
12142 { 0x00000000, 0x00600000, 0x656 },
12143 { 0x00000007, 0x0020222d, 0x000 },
12144 { 0x00000005, 0x00220e22, 0x000 },
12145 { 0x00100000, 0x00280e23, 0x000 },
12146 { 0x00000000, 0x00292068, 0x000 },
12147 { 0x00000000, 0x003a0c02, 0x000 },
12148 { 0x000000ef, 0x00280e23, 0x000 },
12149 { 0x00000000, 0x00292068, 0x000 },
12150 { 0x00000017, 0x00200e2d, 0x000 },
12151 { 0x00000003, 0x00210223, 0x000 },
12152 { 0x00000000, 0x14e00000, 0x0f8 },
12153 { 0x0000000b, 0x00210228, 0x000 },
12154 { 0x00000000, 0x14c00000, 0x0f8 },
12155 { 0x00000400, 0x00292228, 0x000 },
12156 { 0x00000014, 0x00203628, 0x000 },
12157 { 0x0000001c, 0x00210e22, 0x000 },
12158 { 0x00000000, 0x14c00000, 0x0fd },
12159 { 0x0000a30c, 0x00204411, 0x000 },
12160 { 0x00000000, 0x00204811, 0x000 },
12161 { 0x0000001e, 0x00210e22, 0x000 },
12162 { 0x00000000, 0x14c00000, 0x10b },
12163 { 0x0000a30f, 0x00204411, 0x000 },
12164 { 0x00000011, 0x00200e2d, 0x000 },
12165 { 0x00000001, 0x002f0223, 0x000 },
12166 { 0x00000000, 0x0cc00000, 0x104 },
12167 { 0xffffffff, 0x00404811, 0x10b },
12168 { 0x00000002, 0x002f0223, 0x000 },
12169 { 0x00000000, 0x0cc00000, 0x107 },
12170 { 0x0000ffff, 0x00404811, 0x10b },
12171 { 0x00000004, 0x002f0223, 0x000 },
12172 { 0x00000000, 0x0cc00000, 0x10a },
12173 { 0x000000ff, 0x00404811, 0x10b },
12174 { 0x00000001, 0x00204811, 0x000 },
12175 { 0x0002c400, 0x00204411, 0x000 },
12176 { 0x0000001f, 0x00210e22, 0x000 },
12177 { 0x00000000, 0x14c00000, 0x112 },
12178 { 0x00000010, 0x40210e20, 0x000 },
12179 { 0x00000013, 0x00203623, 0x000 },
12180 { 0x00000018, 0x40224a20, 0x000 },
12181 { 0x00000010, 0xc0424a20, 0x114 },
12182 { 0x00000000, 0x00200c11, 0x000 },
12183 { 0x00000013, 0x00203623, 0x000 },
12184 { 0x00000000, 0x00204811, 0x000 },
12185 { 0x00000000, 0x00204811, 0x000 },
12186 { 0x0000000a, 0x00201011, 0x000 },
12187 { 0x00000000, 0x002f0224, 0x000 },
12188 { 0x00000000, 0x0ce00000, 0x11b },
12189 { 0x00000000, 0x00204811, 0x000 },
12190 { 0x00000001, 0x00531224, 0x117 },
12191 { 0xffbfffff, 0x00283a2e, 0x000 },
12192 { 0x0000001b, 0x00210222, 0x000 },
12193 { 0x00000000, 0x14c00000, 0x12e },
12194 { 0x81000000, 0x00204411, 0x000 },
12195 { 0x0000000d, 0x00204811, 0x000 },
12196 { 0x00000018, 0x00220e30, 0x000 },
12197 { 0xfc000000, 0x00280e23, 0x000 },
12198 { 0x81000000, 0x00204411, 0x000 },
12199 { 0x0000000e, 0x00204811, 0x000 },
12200 { 0x00000000, 0x00201010, 0x000 },
12201 { 0x0000e00e, 0x00204411, 0x000 },
12202 { 0x07f8ff08, 0x00204811, 0x000 },
12203 { 0x00000000, 0x00294a23, 0x000 },
12204 { 0x0000001c, 0x00201e2d, 0x000 },
12205 { 0x00000008, 0x00214a27, 0x000 },
12206 { 0x00000000, 0x00204811, 0x000 },
12207 { 0x060a0200, 0x00294a24, 0x000 },
12208 { 0x00000000, 0x00204811, 0x000 },
12209 { 0x00000000, 0x00204811, 0x000 },
12210 { 0x00000000, 0x00800000, 0x000 },
12211 { 0x81000000, 0x00204411, 0x000 },
12212 { 0x00000001, 0x00204811, 0x000 },
12213 { 0x0000217c, 0x00204411, 0x000 },
12214 { 0x00800000, 0x00204811, 0x000 },
12215 { 0x00000000, 0x00204806, 0x000 },
12216 { 0x00000008, 0x00214a27, 0x000 },
12217 { 0x00000000, 0x17000000, 0x000 },
12218 { 0x0004217f, 0x00604411, 0x67c },
12219 { 0x0000001f, 0x00210230, 0x000 },
12220 { 0x00000000, 0x14c00000, 0x67b },
12221 { 0x00000004, 0x00404c11, 0x135 },
12222 { 0x81000000, 0x00204411, 0x000 },
12223 { 0x00000001, 0x00204811, 0x000 },
12224 { 0x000021f8, 0x00204411, 0x000 },
12225 { 0x0000001c, 0x00204811, 0x000 },
12226 { 0x000421f9, 0x00604411, 0x67c },
12227 { 0x00000011, 0x00210230, 0x000 },
12228 { 0x00000000, 0x14e00000, 0x13c },
12229 { 0x00000000, 0x00800000, 0x000 },
12230 { 0x00000000, 0x00600000, 0x00b },
12231 { 0x00000000, 0x00600411, 0x315 },
12232 { 0x00000000, 0x00200411, 0x000 },
12233 { 0x00000000, 0x00600811, 0x1b2 },
12234 { 0x00000000, 0x00600000, 0x160 },
12235 { 0x0000ffff, 0x40280e20, 0x000 },
12236 { 0x00000010, 0xc0211220, 0x000 },
12237 { 0x0000ffff, 0x40280620, 0x000 },
12238 { 0x00000010, 0xc0210a20, 0x000 },
12239 { 0x00000000, 0x00341461, 0x000 },
12240 { 0x00000000, 0x00741882, 0x2bb },
12241 { 0x0001a1fd, 0x00604411, 0x2e0 },
12242 { 0x00003fff, 0x002f022f, 0x000 },
12243 { 0x00000000, 0x0cc00000, 0x147 },
12244 { 0x00000000, 0xc0400400, 0x001 },
12245 { 0x00000000, 0x00600000, 0x00b },
12246 { 0x00000000, 0x00600411, 0x315 },
12247 { 0x00000000, 0x00200411, 0x000 },
12248 { 0x00000000, 0x00600811, 0x1b2 },
12249 { 0x00003fff, 0x002f022f, 0x000 },
12250 { 0x00000000, 0x0ce00000, 0x000 },
12251 { 0x00000000, 0x00600000, 0x160 },
12252 { 0x00000010, 0x40210e20, 0x000 },
12253 { 0x0000ffff, 0xc0281220, 0x000 },
12254 { 0x00000010, 0x40211620, 0x000 },
12255 { 0x0000ffff, 0xc0681a20, 0x2bb },
12256 { 0x0001a1fd, 0x00604411, 0x2e0 },
12257 { 0x00003fff, 0x002f022f, 0x000 },
12258 { 0x00000000, 0x0cc00000, 0x158 },
12259 { 0x00000000, 0xc0400400, 0x001 },
12260 { 0x0000225c, 0x00204411, 0x000 },
12261 { 0x00000001, 0x00300a2f, 0x000 },
12262 { 0x00000001, 0x00210a22, 0x000 },
12263 { 0x00000003, 0x00384a22, 0x000 },
12264 { 0x00002256, 0x00204411, 0x000 },
12265 { 0x0000001a, 0x00204811, 0x000 },
12266 { 0x0000a1fc, 0x00204411, 0x000 },
12267 { 0x00000001, 0x00804811, 0x000 },
12268 { 0x00000000, 0x00600000, 0x00b },
12269 { 0x00000000, 0x00600000, 0x18f },
12270 { 0x00000000, 0x00600000, 0x1a0 },
12271 { 0x00003fff, 0x002f022f, 0x000 },
12272 { 0x00000000, 0x0ce00000, 0x000 },
12273 { 0x00000000, 0x00202c08, 0x000 },
12274 { 0x00000000, 0x00202411, 0x000 },
12275 { 0x00000000, 0x00202811, 0x000 },
12276 { 0x00002256, 0x00204411, 0x000 },
12277 { 0x00000016, 0x00204811, 0x000 },
12278 { 0x0000225c, 0x00204411, 0x000 },
12279 { 0x00000003, 0x00204811, 0x000 },
12280 { 0x93800000, 0x00204411, 0x000 },
12281 { 0x00000002, 0x00221e29, 0x000 },
12282 { 0x00000000, 0x007048eb, 0x19c },
12283 { 0x00000000, 0x00600000, 0x2bb },
12284 { 0x00000001, 0x40330620, 0x000 },
12285 { 0x00000000, 0xc0302409, 0x000 },
12286 { 0x00003fff, 0x002f022f, 0x000 },
12287 { 0x00000000, 0x0ce00000, 0x000 },
12288 { 0x00000000, 0x00600000, 0x2a3 },
12289 { 0x00000000, 0x002f0221, 0x000 },
12290 { 0x00000000, 0x0ae00000, 0x181 },
12291 { 0x00000000, 0x00600000, 0x13a },
12292 { 0x00000000, 0x00400000, 0x186 },
12293 { 0x95000000, 0x00204411, 0x000 },
12294 { 0x00000000, 0x002f0221, 0x000 },
12295 { 0x00000000, 0x0ce00000, 0x186 },
12296 { 0x00000000, 0xc0204800, 0x000 },
12297 { 0x00000001, 0x00530621, 0x182 },
12298 { 0x92000000, 0x00204411, 0x000 },
12299 { 0x00000000, 0xc0604800, 0x197 },
12300 { 0x0001a1fd, 0x00204411, 0x000 },
12301 { 0x00000011, 0x0020062d, 0x000 },
12302 { 0x00000000, 0x0078042a, 0x2fb },
12303 { 0x00000000, 0x00202809, 0x000 },
12304 { 0x00003fff, 0x002f022f, 0x000 },
12305 { 0x00000000, 0x0cc00000, 0x174 },
12306 { 0x00000000, 0xc0400400, 0x001 },
12307 { 0x00000210, 0x00600411, 0x315 },
12308 { 0x00003fff, 0x002f022f, 0x000 },
12309 { 0x00000000, 0x0ce00000, 0x194 },
12310 { 0x00000015, 0xc0203620, 0x000 },
12311 { 0x00000016, 0xc0203620, 0x000 },
12312 { 0x3f800000, 0x00200411, 0x000 },
12313 { 0x46000000, 0x00600811, 0x1b2 },
12314 { 0x00000000, 0x00800000, 0x000 },
12315 { 0x0000a1fc, 0x00204411, 0x000 },
12316 { 0x00003fff, 0x002f022f, 0x000 },
12317 { 0x00000000, 0x0cc00000, 0x19b },
12318 { 0x00000001, 0x00804811, 0x000 },
12319 { 0x00000021, 0x00804811, 0x000 },
12320 { 0x0000ffff, 0x40280e20, 0x000 },
12321 { 0x00000010, 0xc0211220, 0x000 },
12322 { 0x0000ffff, 0x40281620, 0x000 },
12323 { 0x00000010, 0xc0811a20, 0x000 },
12324 { 0x81000000, 0x00204411, 0x000 },
12325 { 0x00000006, 0x00204811, 0x000 },
12326 { 0x00000008, 0x00221e30, 0x000 },
12327 { 0x00000029, 0x00201a2d, 0x000 },
12328 { 0x0000e000, 0x00204411, 0x000 },
12329 { 0xfffbff09, 0x00204811, 0x000 },
12330 { 0x0000000f, 0x0020222d, 0x000 },
12331 { 0x00001fff, 0x00294a28, 0x000 },
12332 { 0x00000006, 0x0020222d, 0x000 },
12333 { 0x00000000, 0x002920e8, 0x000 },
12334 { 0x00000000, 0x00204808, 0x000 },
12335 { 0x00000000, 0x00204811, 0x000 },
12336 { 0x060a0200, 0x00294a26, 0x000 },
12337 { 0x00000000, 0x00204811, 0x000 },
12338 { 0x00000000, 0x00204811, 0x000 },
12339 { 0x00000100, 0x00201811, 0x000 },
12340 { 0x00000008, 0x00621e28, 0x12f },
12341 { 0x00000008, 0x00822228, 0x000 },
12342 { 0x0002c000, 0x00204411, 0x000 },
12343 { 0x00000015, 0x00600e2d, 0x1bd },
12344 { 0x00000016, 0x00600e2d, 0x1bd },
12345 { 0x0000c008, 0x00204411, 0x000 },
12346 { 0x00000017, 0x00200e2d, 0x000 },
12347 { 0x00000000, 0x14c00000, 0x1b9 },
12348 { 0x00000000, 0x00200411, 0x000 },
12349 { 0x00000000, 0x00204801, 0x000 },
12350 { 0x39000000, 0x00204811, 0x000 },
12351 { 0x00000000, 0x00204811, 0x000 },
12352 { 0x00000000, 0x00804802, 0x000 },
12353 { 0x00000018, 0x00202e2d, 0x000 },
12354 { 0x00000000, 0x003b0d63, 0x000 },
12355 { 0x00000008, 0x00224a23, 0x000 },
12356 { 0x00000010, 0x00224a23, 0x000 },
12357 { 0x00000018, 0x00224a23, 0x000 },
12358 { 0x00000000, 0x00804803, 0x000 },
12359 { 0x00000000, 0x00600000, 0x00b },
12360 { 0x00001000, 0x00600411, 0x315 },
12361 { 0x00000000, 0x00200411, 0x000 },
12362 { 0x00000000, 0x00600811, 0x1b2 },
12363 { 0x00000007, 0x0021062f, 0x000 },
12364 { 0x00000013, 0x00200a2d, 0x000 },
12365 { 0x00000001, 0x00202c11, 0x000 },
12366 { 0x0000ffff, 0x40282220, 0x000 },
12367 { 0x0000000f, 0x00262228, 0x000 },
12368 { 0x00000010, 0x40212620, 0x000 },
12369 { 0x0000000f, 0x00262629, 0x000 },
12370 { 0x00000000, 0x00202802, 0x000 },
12371 { 0x00002256, 0x00204411, 0x000 },
12372 { 0x0000001b, 0x00204811, 0x000 },
12373 { 0x00000000, 0x002f0221, 0x000 },
12374 { 0x00000000, 0x0ce00000, 0x1e0 },
12375 { 0x0000225c, 0x00204411, 0x000 },
12376 { 0x00000081, 0x00204811, 0x000 },
12377 { 0x0000a1fc, 0x00204411, 0x000 },
12378 { 0x00000001, 0x00204811, 0x000 },
12379 { 0x00000080, 0x00201c11, 0x000 },
12380 { 0x00000000, 0x002f0227, 0x000 },
12381 { 0x00000000, 0x0ce00000, 0x1dc },
12382 { 0x00000000, 0x00600000, 0x1e9 },
12383 { 0x00000001, 0x00531e27, 0x1d8 },
12384 { 0x00000001, 0x00202c11, 0x000 },
12385 { 0x0000001f, 0x00280a22, 0x000 },
12386 { 0x0000001f, 0x00282a2a, 0x000 },
12387 { 0x00000001, 0x00530621, 0x1d1 },
12388 { 0x0000225c, 0x00204411, 0x000 },
12389 { 0x00000002, 0x00304a2f, 0x000 },
12390 { 0x0000a1fc, 0x00204411, 0x000 },
12391 { 0x00000001, 0x00204811, 0x000 },
12392 { 0x00000001, 0x00301e2f, 0x000 },
12393 { 0x00000000, 0x002f0227, 0x000 },
12394 { 0x00000000, 0x0ce00000, 0x000 },
12395 { 0x00000000, 0x00600000, 0x1e9 },
12396 { 0x00000001, 0x00531e27, 0x1e5 },
12397 { 0x0000ffff, 0x40280e20, 0x000 },
12398 { 0x0000000f, 0x00260e23, 0x000 },
12399 { 0x00000010, 0xc0211220, 0x000 },
12400 { 0x0000000f, 0x00261224, 0x000 },
12401 { 0x00000000, 0x00201411, 0x000 },
12402 { 0x00000000, 0x00601811, 0x2bb },
12403 { 0x0001a1fd, 0x00204411, 0x000 },
12404 { 0x00000000, 0x002f022b, 0x000 },
12405 { 0x00000000, 0x0ce00000, 0x1f8 },
12406 { 0x00000010, 0x00221628, 0x000 },
12407 { 0xffff0000, 0x00281625, 0x000 },
12408 { 0x0000ffff, 0x00281a29, 0x000 },
12409 { 0x00000000, 0x002948c5, 0x000 },
12410 { 0x00000000, 0x0020480a, 0x000 },
12411 { 0x00000000, 0x00202c11, 0x000 },
12412 { 0x00000010, 0x00221623, 0x000 },
12413 { 0xffff0000, 0x00281625, 0x000 },
12414 { 0x0000ffff, 0x00281a24, 0x000 },
12415 { 0x00000000, 0x002948c5, 0x000 },
12416 { 0x00000000, 0x00731503, 0x205 },
12417 { 0x00000000, 0x00201805, 0x000 },
12418 { 0x00000000, 0x00731524, 0x205 },
12419 { 0x00000000, 0x002d14c5, 0x000 },
12420 { 0x00000000, 0x003008a2, 0x000 },
12421 { 0x00000000, 0x00204802, 0x000 },
12422 { 0x00000000, 0x00202802, 0x000 },
12423 { 0x00000000, 0x00202003, 0x000 },
12424 { 0x00000000, 0x00802404, 0x000 },
12425 { 0x0000000f, 0x00210225, 0x000 },
12426 { 0x00000000, 0x14c00000, 0x67b },
12427 { 0x00000000, 0x002b1405, 0x000 },
12428 { 0x00000001, 0x00901625, 0x000 },
12429 { 0x00000000, 0x00600000, 0x00b },
12430 { 0x00000000, 0x00600411, 0x315 },
12431 { 0x00000000, 0x00200411, 0x000 },
12432 { 0x00000000, 0x00600811, 0x1b2 },
12433 { 0x00002256, 0x00204411, 0x000 },
12434 { 0x0000001a, 0x00294a22, 0x000 },
12435 { 0x00000000, 0xc0200000, 0x000 },
12436 { 0x00003fff, 0x002f022f, 0x000 },
12437 { 0x00000000, 0x0ce00000, 0x000 },
12438 { 0x00000000, 0xc0200400, 0x000 },
12439 { 0x0000225c, 0x00204411, 0x000 },
12440 { 0x00000003, 0x00384a21, 0x000 },
12441 { 0x0000a1fc, 0x00204411, 0x000 },
12442 { 0x00000001, 0x00204811, 0x000 },
12443 { 0x0000ffff, 0x40281220, 0x000 },
12444 { 0x00000010, 0xc0211a20, 0x000 },
12445 { 0x0000ffff, 0x40280e20, 0x000 },
12446 { 0x00000010, 0xc0211620, 0x000 },
12447 { 0x00000000, 0x00741465, 0x2bb },
12448 { 0x0001a1fd, 0x00604411, 0x2e0 },
12449 { 0x00000001, 0x00330621, 0x000 },
12450 { 0x00000000, 0x002f0221, 0x000 },
12451 { 0x00000000, 0x0cc00000, 0x219 },
12452 { 0x00003fff, 0x002f022f, 0x000 },
12453 { 0x00000000, 0x0cc00000, 0x212 },
12454 { 0x00000000, 0xc0400400, 0x001 },
12455 { 0x00000000, 0x00600000, 0x638 },
12456 { 0x00000000, 0x0040040f, 0x213 },
12457 { 0x00000000, 0x00600000, 0x624 },
12458 { 0x00000000, 0x00600000, 0x638 },
12459 { 0x00000210, 0x00600411, 0x315 },
12460 { 0x00000000, 0x00600000, 0x1a0 },
12461 { 0x00000000, 0x00600000, 0x19c },
12462 { 0x00000000, 0x00600000, 0x2bb },
12463 { 0x00000000, 0x00600000, 0x2a3 },
12464 { 0x93800000, 0x00204411, 0x000 },
12465 { 0x00000000, 0x00204808, 0x000 },
12466 { 0x00000000, 0x002f022f, 0x000 },
12467 { 0x00000000, 0x0ae00000, 0x232 },
12468 { 0x00000000, 0x00600000, 0x13a },
12469 { 0x00000000, 0x00400000, 0x236 },
12470 { 0x95000000, 0x00204411, 0x000 },
12471 { 0x00000000, 0x002f022f, 0x000 },
12472 { 0x00000000, 0x0ce00000, 0x236 },
12473 { 0x00000000, 0xc0404800, 0x233 },
12474 { 0x92000000, 0x00204411, 0x000 },
12475 { 0x00000000, 0xc0204800, 0x000 },
12476 { 0x00002256, 0x00204411, 0x000 },
12477 { 0x00000016, 0x00204811, 0x000 },
12478 { 0x0000225c, 0x00204411, 0x000 },
12479 { 0x00000003, 0x00204811, 0x000 },
12480 { 0x0000a1fc, 0x00204411, 0x000 },
12481 { 0x00000001, 0x00204811, 0x000 },
12482 { 0x0001a1fd, 0x00204411, 0x000 },
12483 { 0x00000000, 0x00600411, 0x2fb },
12484 { 0x00000000, 0xc0400400, 0x001 },
12485 { 0x00000000, 0x00600000, 0x624 },
12486 { 0x0000a00c, 0x00204411, 0x000 },
12487 { 0x00000000, 0xc0204800, 0x000 },
12488 { 0x00000000, 0xc0404800, 0x000 },
12489 { 0x00000000, 0x00600000, 0x00b },
12490 { 0x00000018, 0x40210a20, 0x000 },
12491 { 0x00000003, 0x002f0222, 0x000 },
12492 { 0x00000000, 0x0ae00000, 0x24c },
12493 { 0x00000014, 0x0020222d, 0x000 },
12494 { 0x00080101, 0x00292228, 0x000 },
12495 { 0x00000014, 0x00203628, 0x000 },
12496 { 0x0000a30c, 0x00204411, 0x000 },
12497 { 0x00000000, 0xc0204800, 0x000 },
12498 { 0x00000000, 0xc0204800, 0x000 },
12499 { 0x00000000, 0xc0404800, 0x251 },
12500 { 0x00000000, 0x00600000, 0x00b },
12501 { 0x00000010, 0x00600411, 0x315 },
12502 { 0x3f800000, 0x00200411, 0x000 },
12503 { 0x00000000, 0x00600811, 0x1b2 },
12504 { 0x0000225c, 0x00204411, 0x000 },
12505 { 0x00000003, 0x00204811, 0x000 },
12506 { 0x00000000, 0x00600000, 0x27c },
12507 { 0x00000017, 0x00201e2d, 0x000 },
12508 { 0x00000001, 0x00211e27, 0x000 },
12509 { 0x00000000, 0x14e00000, 0x26a },
12510 { 0x00000012, 0x00201e2d, 0x000 },
12511 { 0x0000ffff, 0x00281e27, 0x000 },
12512 { 0x00000000, 0x00341c27, 0x000 },
12513 { 0x00000000, 0x12c00000, 0x25f },
12514 { 0x00000000, 0x00201c11, 0x000 },
12515 { 0x00000000, 0x002f00e5, 0x000 },
12516 { 0x00000000, 0x08c00000, 0x262 },
12517 { 0x00000000, 0x00201407, 0x000 },
12518 { 0x00000012, 0x00201e2d, 0x000 },
12519 { 0x00000010, 0x00211e27, 0x000 },
12520 { 0x00000000, 0x00341c47, 0x000 },
12521 { 0x00000000, 0x12c00000, 0x267 },
12522 { 0x00000000, 0x00201c11, 0x000 },
12523 { 0x00000000, 0x002f00e6, 0x000 },
12524 { 0x00000000, 0x08c00000, 0x26a },
12525 { 0x00000000, 0x00201807, 0x000 },
12526 { 0x00000000, 0x00600000, 0x2c1 },
12527 { 0x00002256, 0x00204411, 0x000 },
12528 { 0x00000000, 0x00342023, 0x000 },
12529 { 0x00000000, 0x12c00000, 0x272 },
12530 { 0x00000000, 0x00342044, 0x000 },
12531 { 0x00000000, 0x12c00000, 0x271 },
12532 { 0x00000016, 0x00404811, 0x276 },
12533 { 0x00000018, 0x00404811, 0x276 },
12534 { 0x00000000, 0x00342044, 0x000 },
12535 { 0x00000000, 0x12c00000, 0x275 },
12536 { 0x00000017, 0x00404811, 0x276 },
12537 { 0x00000019, 0x00204811, 0x000 },
12538 { 0x0000a1fc, 0x00204411, 0x000 },
12539 { 0x00000001, 0x00204811, 0x000 },
12540 { 0x0001a1fd, 0x00604411, 0x2e9 },
12541 { 0x00003fff, 0x002f022f, 0x000 },
12542 { 0x00000000, 0x0cc00000, 0x256 },
12543 { 0x00000000, 0xc0400400, 0x001 },
12544 { 0x00000010, 0x40210620, 0x000 },
12545 { 0x0000ffff, 0xc0280a20, 0x000 },
12546 { 0x00000010, 0x40210e20, 0x000 },
12547 { 0x0000ffff, 0xc0281220, 0x000 },
12548 { 0x00000010, 0x40211620, 0x000 },
12549 { 0x0000ffff, 0xc0881a20, 0x000 },
12550 { 0x81000000, 0x00204411, 0x000 },
12551 { 0x00000001, 0x00204811, 0x000 },
12552 { 0x00042004, 0x00604411, 0x67c },
12553 { 0x00000000, 0x00600000, 0x624 },
12554 { 0x00000000, 0xc0600000, 0x2a3 },
12555 { 0x00000005, 0x00200a2d, 0x000 },
12556 { 0x00000008, 0x00220a22, 0x000 },
12557 { 0x0000002b, 0x00201a2d, 0x000 },
12558 { 0x0000001c, 0x00201e2d, 0x000 },
12559 { 0x00007000, 0x00281e27, 0x000 },
12560 { 0x00000000, 0x00311ce6, 0x000 },
12561 { 0x0000002a, 0x00201a2d, 0x000 },
12562 { 0x0000000c, 0x00221a26, 0x000 },
12563 { 0x00000000, 0x002f00e6, 0x000 },
12564 { 0x00000000, 0x06e00000, 0x292 },
12565 { 0x00000000, 0x00201c11, 0x000 },
12566 { 0x00000000, 0x00200c11, 0x000 },
12567 { 0x0000002b, 0x00203623, 0x000 },
12568 { 0x00000010, 0x00201811, 0x000 },
12569 { 0x00000000, 0x00691ce2, 0x12f },
12570 { 0x93800000, 0x00204411, 0x000 },
12571 { 0x00000000, 0x00204807, 0x000 },
12572 { 0x95000000, 0x00204411, 0x000 },
12573 { 0x00000000, 0x002f022f, 0x000 },
12574 { 0x00000000, 0x0ce00000, 0x29d },
12575 { 0x00000001, 0x00333e2f, 0x000 },
12576 { 0x00000000, 0xd9004800, 0x000 },
12577 { 0x92000000, 0x00204411, 0x000 },
12578 { 0x00000000, 0xc0204800, 0x000 },
12579 { 0x0000001c, 0x00403627, 0x000 },
12580 { 0x0000000c, 0xc0220a20, 0x000 },
12581 { 0x00000029, 0x00203622, 0x000 },
12582 { 0x00000028, 0xc0403620, 0x000 },
12583 { 0x0000a2a4, 0x00204411, 0x000 },
12584 { 0x00000009, 0x00204811, 0x000 },
12585 { 0xa1000000, 0x00204411, 0x000 },
12586 { 0x00000001, 0x00804811, 0x000 },
12587 { 0x00000021, 0x00201e2d, 0x000 },
12588 { 0x00000000, 0x002c1ce3, 0x000 },
12589 { 0x00000021, 0x00203627, 0x000 },
12590 { 0x00000022, 0x00201e2d, 0x000 },
12591 { 0x00000000, 0x002c1ce4, 0x000 },
12592 { 0x00000022, 0x00203627, 0x000 },
12593 { 0x00000023, 0x00201e2d, 0x000 },
12594 { 0x00000000, 0x003120a3, 0x000 },
12595 { 0x00000000, 0x002d1d07, 0x000 },
12596 { 0x00000023, 0x00203627, 0x000 },
12597 { 0x00000024, 0x00201e2d, 0x000 },
12598 { 0x00000000, 0x003120c4, 0x000 },
12599 { 0x00000000, 0x002d1d07, 0x000 },
12600 { 0x00000024, 0x00803627, 0x000 },
12601 { 0x00000021, 0x00203623, 0x000 },
12602 { 0x00000022, 0x00203624, 0x000 },
12603 { 0x00000000, 0x00311ca3, 0x000 },
12604 { 0x00000023, 0x00203627, 0x000 },
12605 { 0x00000000, 0x00311cc4, 0x000 },
12606 { 0x00000024, 0x00803627, 0x000 },
12607 { 0x0000001a, 0x00203627, 0x000 },
12608 { 0x0000001b, 0x00203628, 0x000 },
12609 { 0x00000017, 0x00201e2d, 0x000 },
12610 { 0x00000002, 0x00210227, 0x000 },
12611 { 0x00000000, 0x14c00000, 0x2dc },
12612 { 0x00000000, 0x00400000, 0x2d9 },
12613 { 0x0000001a, 0x00203627, 0x000 },
12614 { 0x0000001b, 0x00203628, 0x000 },
12615 { 0x00000017, 0x00201e2d, 0x000 },
12616 { 0x00000002, 0x00210227, 0x000 },
12617 { 0x00000000, 0x14e00000, 0x2d9 },
12618 { 0x00000003, 0x00210227, 0x000 },
12619 { 0x00000000, 0x14e00000, 0x2dc },
12620 { 0x00000023, 0x00201e2d, 0x000 },
12621 { 0x00000000, 0x002e00e1, 0x000 },
12622 { 0x00000000, 0x02c00000, 0x2dc },
12623 { 0x00000021, 0x00201e2d, 0x000 },
12624 { 0x00000000, 0x003120a1, 0x000 },
12625 { 0x00000000, 0x002e00e8, 0x000 },
12626 { 0x00000000, 0x06c00000, 0x2dc },
12627 { 0x00000024, 0x00201e2d, 0x000 },
12628 { 0x00000000, 0x002e00e2, 0x000 },
12629 { 0x00000000, 0x02c00000, 0x2dc },
12630 { 0x00000022, 0x00201e2d, 0x000 },
12631 { 0x00000000, 0x003120c2, 0x000 },
12632 { 0x00000000, 0x002e00e8, 0x000 },
12633 { 0x00000000, 0x06c00000, 0x2dc },
12634 { 0x00000000, 0x00600000, 0x659 },
12635 { 0x00000000, 0x00600000, 0x2b5 },
12636 { 0x00000000, 0x00400000, 0x2de },
12637 { 0x00000000, 0x00600000, 0x2b5 },
12638 { 0x00000000, 0x00600000, 0x650 },
12639 { 0x00000000, 0x00400000, 0x2de },
12640 { 0x00000000, 0x00600000, 0x2a7 },
12641 { 0x00000000, 0x00400000, 0x2de },
12642 { 0x0000001a, 0x00201e2d, 0x000 },
12643 { 0x0000001b, 0x0080222d, 0x000 },
12644 { 0x00000010, 0x00221e23, 0x000 },
12645 { 0x00000000, 0x00294887, 0x000 },
12646 { 0x00000000, 0x00311ca3, 0x000 },
12647 { 0x00000010, 0x00221e27, 0x000 },
12648 { 0x00000000, 0x00294887, 0x000 },
12649 { 0x00000010, 0x00221e23, 0x000 },
12650 { 0x00000000, 0x003120c4, 0x000 },
12651 { 0x0000ffff, 0x00282228, 0x000 },
12652 { 0x00000000, 0x00894907, 0x000 },
12653 { 0x00000010, 0x00221e23, 0x000 },
12654 { 0x00000000, 0x00294887, 0x000 },
12655 { 0x00000010, 0x00221e21, 0x000 },
12656 { 0x00000000, 0x00294847, 0x000 },
12657 { 0x00000000, 0x00311ca3, 0x000 },
12658 { 0x00000010, 0x00221e27, 0x000 },
12659 { 0x00000000, 0x00294887, 0x000 },
12660 { 0x00000000, 0x00311ca1, 0x000 },
12661 { 0x00000010, 0x00221e27, 0x000 },
12662 { 0x00000000, 0x00294847, 0x000 },
12663 { 0x00000010, 0x00221e23, 0x000 },
12664 { 0x00000000, 0x003120c4, 0x000 },
12665 { 0x0000ffff, 0x00282228, 0x000 },
12666 { 0x00000000, 0x00294907, 0x000 },
12667 { 0x00000010, 0x00221e21, 0x000 },
12668 { 0x00000000, 0x003120c2, 0x000 },
12669 { 0x0000ffff, 0x00282228, 0x000 },
12670 { 0x00000000, 0x00894907, 0x000 },
12671 { 0x00000010, 0x00221e23, 0x000 },
12672 { 0x00000000, 0x00294887, 0x000 },
12673 { 0x00000001, 0x00220a21, 0x000 },
12674 { 0x00000000, 0x003308a2, 0x000 },
12675 { 0x00000010, 0x00221e22, 0x000 },
12676 { 0x00000010, 0x00212222, 0x000 },
12677 { 0x00000000, 0x00294907, 0x000 },
12678 { 0x00000000, 0x00311ca3, 0x000 },
12679 { 0x00000010, 0x00221e27, 0x000 },
12680 { 0x00000000, 0x00294887, 0x000 },
12681 { 0x00000001, 0x00220a21, 0x000 },
12682 { 0x00000000, 0x003008a2, 0x000 },
12683 { 0x00000010, 0x00221e22, 0x000 },
12684 { 0x00000010, 0x00212222, 0x000 },
12685 { 0x00000000, 0x00294907, 0x000 },
12686 { 0x00000010, 0x00221e23, 0x000 },
12687 { 0x00000000, 0x003120c4, 0x000 },
12688 { 0x0000ffff, 0x00282228, 0x000 },
12689 { 0x00000000, 0x00294907, 0x000 },
12690 { 0x00000000, 0x003808c5, 0x000 },
12691 { 0x00000000, 0x00300841, 0x000 },
12692 { 0x00000001, 0x00220a22, 0x000 },
12693 { 0x00000000, 0x003308a2, 0x000 },
12694 { 0x00000010, 0x00221e22, 0x000 },
12695 { 0x00000010, 0x00212222, 0x000 },
12696 { 0x00000000, 0x00894907, 0x000 },
12697 { 0x00000017, 0x0020222d, 0x000 },
12698 { 0x00000000, 0x14c00000, 0x318 },
12699 { 0xffffffef, 0x00280621, 0x000 },
12700 { 0x00000014, 0x0020222d, 0x000 },
12701 { 0x0000f8e0, 0x00204411, 0x000 },
12702 { 0x00000000, 0x00294901, 0x000 },
12703 { 0x00000000, 0x00894901, 0x000 },
12704 { 0x00000000, 0x00204811, 0x000 },
12705 { 0x00000000, 0x00204811, 0x000 },
12706 { 0x060a0200, 0x00804811, 0x000 },
12707 { 0x00000000, 0xc0200000, 0x000 },
12708 { 0x97000000, 0xc0204411, 0x000 },
12709 { 0x00000000, 0xc0204811, 0x000 },
12710 { 0x8a000000, 0x00204411, 0x000 },
12711 { 0x00000000, 0x00204811, 0x000 },
12712 { 0x0000225c, 0x00204411, 0x000 },
12713 { 0x00000000, 0xc0204800, 0x000 },
12714 { 0x0000a1fc, 0x00204411, 0x000 },
12715 { 0x00000000, 0xc0204800, 0x000 },
12716 { 0x00000000, 0xc0200400, 0x000 },
12717 { 0x00000000, 0x00a0000a, 0x000 },
12718 { 0x97000000, 0x00204411, 0x000 },
12719 { 0x00000000, 0x00204811, 0x000 },
12720 { 0x8a000000, 0x00204411, 0x000 },
12721 { 0x00000000, 0x00204811, 0x000 },
12722 { 0x0000225c, 0x00204411, 0x000 },
12723 { 0x00000000, 0xc0204800, 0x000 },
12724 { 0x0000a1fc, 0x00204411, 0x000 },
12725 { 0x00000000, 0xc0204800, 0x000 },
12726 { 0x00000000, 0xc0200400, 0x000 },
12727 { 0x00000000, 0x00a0000a, 0x000 },
12728 { 0x97000000, 0x00204411, 0x000 },
12729 { 0x00000000, 0x00204811, 0x000 },
12730 { 0x8a000000, 0x00204411, 0x000 },
12731 { 0x00000000, 0x00204811, 0x000 },
12732 { 0x0000225c, 0x00204411, 0x000 },
12733 { 0x00000000, 0xc0204800, 0x000 },
12734 { 0x0000a1fc, 0x00204411, 0x000 },
12735 { 0x00000000, 0xc0204800, 0x000 },
12736 { 0x0001a1fd, 0x00204411, 0x000 },
12737 { 0x00000000, 0xd9004800, 0x000 },
12738 { 0x00000000, 0xc0200400, 0x000 },
12739 { 0x00000000, 0x00a0000a, 0x000 },
12740 { 0x00002257, 0x00204411, 0x000 },
12741 { 0x00000003, 0xc0484a20, 0x000 },
12742 { 0x0000225d, 0x00204411, 0x000 },
12743 { 0x00000000, 0xc0404800, 0x000 },
12744 { 0x00000000, 0x00600000, 0x638 },
12745 { 0x00000000, 0xc0200800, 0x000 },
12746 { 0x0000225c, 0x00204411, 0x000 },
12747 { 0x00000003, 0x00384a22, 0x000 },
12748 { 0x0000a1fc, 0x00204411, 0x000 },
12749 { 0x00000000, 0xc0204800, 0x000 },
12750 { 0x0001a1fd, 0x00204411, 0x000 },
12751 { 0x00000000, 0x002f0222, 0x000 },
12752 { 0x00000000, 0x0ce00000, 0x000 },
12753 { 0x00000000, 0x40204800, 0x000 },
12754 { 0x00000001, 0x40304a20, 0x000 },
12755 { 0x00000002, 0xc0304a20, 0x000 },
12756 { 0x00000001, 0x00530a22, 0x34b },
12757 { 0x0000003f, 0xc0280a20, 0x000 },
12758 { 0x81000000, 0x00204411, 0x000 },
12759 { 0x00000001, 0x00204811, 0x000 },
12760 { 0x000021f8, 0x00204411, 0x000 },
12761 { 0x00000018, 0x00204811, 0x000 },
12762 { 0x000421f9, 0x00604411, 0x67c },
12763 { 0x00000011, 0x00210230, 0x000 },
12764 { 0x00000000, 0x14e00000, 0x354 },
12765 { 0x00000014, 0x002f0222, 0x000 },
12766 { 0x00000000, 0x0cc00000, 0x362 },
12767 { 0x0001a2a4, 0x00204411, 0x000 },
12768 { 0x00000000, 0x00604802, 0x36a },
12769 { 0x00002100, 0x00204411, 0x000 },
12770 { 0x00000000, 0xc0204800, 0x000 },
12771 { 0x00000000, 0xc0204800, 0x000 },
12772 { 0x00000000, 0xc0204800, 0x000 },
12773 { 0x00000000, 0xc0404800, 0x000 },
12774 { 0x00000004, 0x002f0222, 0x000 },
12775 { 0x00000000, 0x0cc00000, 0x366 },
12776 { 0x0001a2a4, 0x00204411, 0x000 },
12777 { 0x00000000, 0x00404802, 0x35d },
12778 { 0x00000028, 0x002f0222, 0x000 },
12779 { 0x00000000, 0x0cc00000, 0x5b3 },
12780 { 0x0001a2a4, 0x00204411, 0x000 },
12781 { 0x00000000, 0x00404802, 0x35d },
12782 { 0x0000002c, 0x00203626, 0x000 },
12783 { 0x00000049, 0x00201811, 0x000 },
12784 { 0x0000003f, 0x00204811, 0x000 },
12785 { 0x00000001, 0x00331a26, 0x000 },
12786 { 0x00000000, 0x002f0226, 0x000 },
12787 { 0x00000000, 0x0cc00000, 0x36c },
12788 { 0x0000002c, 0x00801a2d, 0x000 },
12789 { 0x0000003f, 0xc0280a20, 0x000 },
12790 { 0x00000015, 0x002f0222, 0x000 },
12791 { 0x00000000, 0x0ce00000, 0x382 },
12792 { 0x00000006, 0x002f0222, 0x000 },
12793 { 0x00000000, 0x0ce00000, 0x3ad },
12794 { 0x00000016, 0x002f0222, 0x000 },
12795 { 0x00000000, 0x0ce00000, 0x3af },
12796 { 0x00000020, 0x002f0222, 0x000 },
12797 { 0x00000000, 0x0ce00000, 0x398 },
12798 { 0x0000000f, 0x002f0222, 0x000 },
12799 { 0x00000000, 0x0ce00000, 0x3a4 },
12800 { 0x00000010, 0x002f0222, 0x000 },
12801 { 0x00000000, 0x0ce00000, 0x3a4 },
12802 { 0x0000001e, 0x002f0222, 0x000 },
12803 { 0x00000000, 0x0ce00000, 0x38c },
12804 { 0x0000a2a4, 0x00204411, 0x000 },
12805 { 0x00000000, 0x00404802, 0x000 },
12806 { 0x08000000, 0x00290a22, 0x000 },
12807 { 0x00000003, 0x40210e20, 0x000 },
12808 { 0x0000000c, 0xc0211220, 0x000 },
12809 { 0x00080000, 0x00281224, 0x000 },
12810 { 0x00000014, 0xc0221620, 0x000 },
12811 { 0x00000000, 0x002914a4, 0x000 },
12812 { 0x0000a2a4, 0x00204411, 0x000 },
12813 { 0x00000000, 0x002948a2, 0x000 },
12814 { 0x0000a1fe, 0x00204411, 0x000 },
12815 { 0x00000000, 0x00404803, 0x000 },
12816 { 0x81000000, 0x00204411, 0x000 },
12817 { 0x00000001, 0x00204811, 0x000 },
12818 { 0x000021f8, 0x00204411, 0x000 },
12819 { 0x00000016, 0x00204811, 0x000 },
12820 { 0x000421f9, 0x00604411, 0x67c },
12821 { 0x00000015, 0x00210230, 0x000 },
12822 { 0x00000000, 0x14e00000, 0x38e },
12823 { 0x0000210e, 0x00204411, 0x000 },
12824 { 0x00000000, 0xc0204800, 0x000 },
12825 { 0x00000000, 0xc0204800, 0x000 },
12826 { 0x0000a2a4, 0x00204411, 0x000 },
12827 { 0x00000000, 0x00404802, 0x000 },
12828 { 0x81000000, 0x00204411, 0x000 },
12829 { 0x00000001, 0x00204811, 0x000 },
12830 { 0x000021f8, 0x00204411, 0x000 },
12831 { 0x00000017, 0x00204811, 0x000 },
12832 { 0x000421f9, 0x00604411, 0x67c },
12833 { 0x00000003, 0x00210230, 0x000 },
12834 { 0x00000000, 0x14e00000, 0x39a },
12835 { 0x00002108, 0x00204411, 0x000 },
12836 { 0x00000000, 0xc0204800, 0x000 },
12837 { 0x00000000, 0xc0204800, 0x000 },
12838 { 0x0000a2a4, 0x00204411, 0x000 },
12839 { 0x00000000, 0x00404802, 0x000 },
12840 { 0x0000a2a4, 0x00204411, 0x000 },
12841 { 0x00000000, 0x00204802, 0x000 },
12842 { 0x80000000, 0x00204411, 0x000 },
12843 { 0x00000000, 0x00204811, 0x000 },
12844 { 0x81000000, 0x00204411, 0x000 },
12845 { 0x00000010, 0x00204811, 0x000 },
12846 { 0x00000000, 0x00200010, 0x000 },
12847 { 0x00000000, 0x14c00000, 0x3aa },
12848 { 0x00000000, 0x00400000, 0x000 },
12849 { 0x0001a2a4, 0x00204411, 0x000 },
12850 { 0x00000006, 0x00404811, 0x000 },
12851 { 0x0001a2a4, 0x00204411, 0x000 },
12852 { 0x00000016, 0x00604811, 0x36a },
12853 { 0x00000000, 0x00400000, 0x000 },
12854 { 0x00000000, 0xc0200800, 0x000 },
12855 { 0x00000000, 0xc0200c00, 0x000 },
12856 { 0x0000001d, 0x00210223, 0x000 },
12857 { 0x00000000, 0x14e00000, 0x3c4 },
12858 { 0x81000000, 0x00204411, 0x000 },
12859 { 0x00000001, 0x00204811, 0x000 },
12860 { 0x000021f8, 0x00204411, 0x000 },
12861 { 0x00000018, 0x00204811, 0x000 },
12862 { 0x000421f9, 0x00604411, 0x67c },
12863 { 0x00000011, 0x00210230, 0x000 },
12864 { 0x00000000, 0x14e00000, 0x3b8 },
12865 { 0x00002100, 0x00204411, 0x000 },
12866 { 0x00000000, 0x00204802, 0x000 },
12867 { 0x00000000, 0x00204803, 0x000 },
12868 { 0xbabecafe, 0x00204811, 0x000 },
12869 { 0xcafebabe, 0x00204811, 0x000 },
12870 { 0x0000a2a4, 0x00204411, 0x000 },
12871 { 0x00000004, 0x00404811, 0x000 },
12872 { 0x00002170, 0x00204411, 0x000 },
12873 { 0x00000000, 0x00204802, 0x000 },
12874 { 0x00000000, 0x00204803, 0x000 },
12875 { 0x81000000, 0x00204411, 0x000 },
12876 { 0x0000000a, 0x00204811, 0x000 },
12877 { 0x00000000, 0x00200010, 0x000 },
12878 { 0x00000000, 0x14c00000, 0x3c9 },
12879 { 0x8c000000, 0x00204411, 0x000 },
12880 { 0xcafebabe, 0x00404811, 0x000 },
12881 { 0x81000000, 0x00204411, 0x000 },
12882 { 0x00000001, 0x00204811, 0x000 },
12883 { 0x00003fff, 0x40280a20, 0x000 },
12884 { 0x80000000, 0x40280e20, 0x000 },
12885 { 0x40000000, 0xc0281220, 0x000 },
12886 { 0x00040000, 0x00694622, 0x67c },
12887 { 0x00000000, 0x00201410, 0x000 },
12888 { 0x00000000, 0x002f0223, 0x000 },
12889 { 0x00000000, 0x0cc00000, 0x3d7 },
12890 { 0x00000000, 0xc0401800, 0x3da },
12891 { 0x00003fff, 0xc0281a20, 0x000 },
12892 { 0x00040000, 0x00694626, 0x67c },
12893 { 0x00000000, 0x00201810, 0x000 },
12894 { 0x00000000, 0x002f0224, 0x000 },
12895 { 0x00000000, 0x0cc00000, 0x3dd },
12896 { 0x00000000, 0xc0401c00, 0x3e0 },
12897 { 0x00003fff, 0xc0281e20, 0x000 },
12898 { 0x00040000, 0x00694627, 0x67c },
12899 { 0x00000000, 0x00201c10, 0x000 },
12900 { 0x00000000, 0x00204402, 0x000 },
12901 { 0x00000000, 0x002820c5, 0x000 },
12902 { 0x00000000, 0x004948e8, 0x000 },
12903 { 0xa5800000, 0x00200811, 0x000 },
12904 { 0x00002000, 0x00200c11, 0x000 },
12905 { 0x83000000, 0x00604411, 0x408 },
12906 { 0x00000000, 0x00204402, 0x000 },
12907 { 0x00000000, 0xc0204800, 0x000 },
12908 { 0x00000000, 0x40204800, 0x000 },
12909 { 0x0000001f, 0xc0210220, 0x000 },
12910 { 0x00000000, 0x14c00000, 0x3ed },
12911 { 0x00002010, 0x00204411, 0x000 },
12912 { 0x00008000, 0x00204811, 0x000 },
12913 { 0x0000ffff, 0xc0481220, 0x3f5 },
12914 { 0xa7800000, 0x00200811, 0x000 },
12915 { 0x0000a000, 0x00200c11, 0x000 },
12916 { 0x83000000, 0x00604411, 0x408 },
12917 { 0x00000000, 0x00204402, 0x000 },
12918 { 0x00000000, 0xc0204800, 0x000 },
12919 { 0x00000000, 0xc0204800, 0x000 },
12920 { 0x0000ffff, 0xc0281220, 0x000 },
12921 { 0x83000000, 0x00204411, 0x000 },
12922 { 0x00000000, 0x00304883, 0x000 },
12923 { 0x84000000, 0x00204411, 0x000 },
12924 { 0x00000000, 0xc0204800, 0x000 },
12925 { 0x00000000, 0x1d000000, 0x000 },
12926 { 0x83000000, 0x00604411, 0x408 },
12927 { 0x00000000, 0xc0400400, 0x001 },
12928 { 0xa9800000, 0x00200811, 0x000 },
12929 { 0x0000c000, 0x00400c11, 0x3f0 },
12930 { 0xab800000, 0x00200811, 0x000 },
12931 { 0x0000f8e0, 0x00400c11, 0x3f0 },
12932 { 0xad800000, 0x00200811, 0x000 },
12933 { 0x0000f880, 0x00400c11, 0x3f0 },
12934 { 0xb3800000, 0x00200811, 0x000 },
12935 { 0x0000f3fc, 0x00400c11, 0x3f0 },
12936 { 0xaf800000, 0x00200811, 0x000 },
12937 { 0x0000e000, 0x00400c11, 0x3f0 },
12938 { 0xb1800000, 0x00200811, 0x000 },
12939 { 0x0000f000, 0x00400c11, 0x3f0 },
12940 { 0x83000000, 0x00204411, 0x000 },
12941 { 0x00002148, 0x00204811, 0x000 },
12942 { 0x84000000, 0x00204411, 0x000 },
12943 { 0x00000000, 0xc0204800, 0x000 },
12944 { 0x00000000, 0x1d000000, 0x000 },
12945 { 0x00000000, 0x00800000, 0x000 },
12946 { 0x01182000, 0xc0304620, 0x000 },
12947 { 0x00000000, 0xd9004800, 0x000 },
12948 { 0x00000000, 0xc0200400, 0x000 },
12949 { 0x00000000, 0x00a0000a, 0x000 },
12950 { 0x0218a000, 0xc0304620, 0x000 },
12951 { 0x00000000, 0xd9004800, 0x000 },
12952 { 0x00000000, 0xc0200400, 0x000 },
12953 { 0x00000000, 0x00a0000a, 0x000 },
12954 { 0x0318c000, 0xc0304620, 0x000 },
12955 { 0x00000000, 0xd9004800, 0x000 },
12956 { 0x00000000, 0xc0200400, 0x000 },
12957 { 0x00000000, 0x00a0000a, 0x000 },
12958 { 0x0418f8e0, 0xc0304620, 0x000 },
12959 { 0x00000000, 0xd9004800, 0x000 },
12960 { 0x00000000, 0xc0200400, 0x000 },
12961 { 0x00000000, 0x00a0000a, 0x000 },
12962 { 0x0518f880, 0xc0304620, 0x000 },
12963 { 0x00000000, 0xd9004800, 0x000 },
12964 { 0x00000000, 0xc0200400, 0x000 },
12965 { 0x00000000, 0x00a0000a, 0x000 },
12966 { 0x0618e000, 0xc0304620, 0x000 },
12967 { 0x00000000, 0xd9004800, 0x000 },
12968 { 0x00000000, 0xc0200400, 0x000 },
12969 { 0x00000000, 0x00a0000a, 0x000 },
12970 { 0x0718f000, 0xc0304620, 0x000 },
12971 { 0x00000000, 0xd9004800, 0x000 },
12972 { 0x00000000, 0xc0200400, 0x000 },
12973 { 0x00000000, 0x00a0000a, 0x000 },
12974 { 0x0818f3fc, 0xc0304620, 0x000 },
12975 { 0x00000000, 0xd9004800, 0x000 },
12976 { 0x00000000, 0xc0200400, 0x000 },
12977 { 0x00000000, 0x00a0000a, 0x000 },
12978 { 0x00000030, 0x00200a2d, 0x000 },
12979 { 0x00000000, 0xc0290c40, 0x000 },
12980 { 0x00000030, 0x00203623, 0x000 },
12981 { 0x00000000, 0xc0200400, 0x000 },
12982 { 0x00000000, 0x00a0000a, 0x000 },
12983 { 0x86000000, 0x00204411, 0x000 },
12984 { 0x00000000, 0x00404801, 0x000 },
12985 { 0x85000000, 0xc0204411, 0x000 },
12986 { 0x00000000, 0x00404801, 0x000 },
12987 { 0x0000217c, 0x00204411, 0x000 },
12988 { 0x00000000, 0xc0204800, 0x000 },
12989 { 0x00000000, 0xc0204800, 0x000 },
12990 { 0x00000000, 0xc0204800, 0x000 },
12991 { 0x81000000, 0x00204411, 0x000 },
12992 { 0x00000001, 0x00204811, 0x000 },
12993 { 0x00000000, 0xc0200800, 0x000 },
12994 { 0x00000000, 0x17000000, 0x000 },
12995 { 0x0004217f, 0x00604411, 0x67c },
12996 { 0x0000001f, 0x00210230, 0x000 },
12997 { 0x00000000, 0x14c00000, 0x000 },
12998 { 0x00000000, 0x00404c02, 0x43e },
12999 { 0x00000000, 0xc0200c00, 0x000 },
13000 { 0x00000000, 0xc0201000, 0x000 },
13001 { 0x00000000, 0xc0201400, 0x000 },
13002 { 0x00000000, 0xc0201800, 0x000 },
13003 { 0x00000000, 0xc0201c00, 0x000 },
13004 { 0x00007f00, 0x00280a21, 0x000 },
13005 { 0x00004500, 0x002f0222, 0x000 },
13006 { 0x00000000, 0x0ce00000, 0x44c },
13007 { 0x00000000, 0xc0202000, 0x000 },
13008 { 0x00000000, 0x17000000, 0x000 },
13009 { 0x00000010, 0x00280a23, 0x000 },
13010 { 0x00000010, 0x002f0222, 0x000 },
13011 { 0x00000000, 0x0ce00000, 0x454 },
13012 { 0x81000000, 0x00204411, 0x000 },
13013 { 0x00000001, 0x00204811, 0x000 },
13014 { 0x00040000, 0x00694624, 0x67c },
13015 { 0x00000000, 0x00400000, 0x459 },
13016 { 0x81000000, 0x00204411, 0x000 },
13017 { 0x00000000, 0x00204811, 0x000 },
13018 { 0x0000216d, 0x00204411, 0x000 },
13019 { 0x00000000, 0x00204804, 0x000 },
13020 { 0x00000000, 0x00604805, 0x681 },
13021 { 0x00000000, 0x002824f0, 0x000 },
13022 { 0x00000007, 0x00280a23, 0x000 },
13023 { 0x00000001, 0x002f0222, 0x000 },
13024 { 0x00000000, 0x0ae00000, 0x460 },
13025 { 0x00000000, 0x002f00c9, 0x000 },
13026 { 0x00000000, 0x04e00000, 0x479 },
13027 { 0x00000000, 0x00400000, 0x486 },
13028 { 0x00000002, 0x002f0222, 0x000 },
13029 { 0x00000000, 0x0ae00000, 0x465 },
13030 { 0x00000000, 0x002f00c9, 0x000 },
13031 { 0x00000000, 0x02e00000, 0x479 },
13032 { 0x00000000, 0x00400000, 0x486 },
13033 { 0x00000003, 0x002f0222, 0x000 },
13034 { 0x00000000, 0x0ae00000, 0x46a },
13035 { 0x00000000, 0x002f00c9, 0x000 },
13036 { 0x00000000, 0x0ce00000, 0x479 },
13037 { 0x00000000, 0x00400000, 0x486 },
13038 { 0x00000004, 0x002f0222, 0x000 },
13039 { 0x00000000, 0x0ae00000, 0x46f },
13040 { 0x00000000, 0x002f00c9, 0x000 },
13041 { 0x00000000, 0x0ae00000, 0x479 },
13042 { 0x00000000, 0x00400000, 0x486 },
13043 { 0x00000005, 0x002f0222, 0x000 },
13044 { 0x00000000, 0x0ae00000, 0x474 },
13045 { 0x00000000, 0x002f00c9, 0x000 },
13046 { 0x00000000, 0x06e00000, 0x479 },
13047 { 0x00000000, 0x00400000, 0x486 },
13048 { 0x00000006, 0x002f0222, 0x000 },
13049 { 0x00000000, 0x0ae00000, 0x479 },
13050 { 0x00000000, 0x002f00c9, 0x000 },
13051 { 0x00000000, 0x08e00000, 0x479 },
13052 { 0x00000000, 0x00400000, 0x486 },
13053 { 0x00007f00, 0x00280a21, 0x000 },
13054 { 0x00004500, 0x002f0222, 0x000 },
13055 { 0x00000000, 0x0ae00000, 0x000 },
13056 { 0x00000008, 0x00210a23, 0x000 },
13057 { 0x00000000, 0x14c00000, 0x483 },
13058 { 0x00002169, 0x00204411, 0x000 },
13059 { 0x00000000, 0xc0204800, 0x000 },
13060 { 0x00000000, 0xc0204800, 0x000 },
13061 { 0x00000000, 0xc0204800, 0x000 },
13062 { 0xcafebabe, 0x00404811, 0x000 },
13063 { 0x00000000, 0xc0204400, 0x000 },
13064 { 0x00000000, 0xc0200000, 0x000 },
13065 { 0x00000000, 0xc0404800, 0x000 },
13066 { 0x00007f00, 0x00280a21, 0x000 },
13067 { 0x00004500, 0x002f0222, 0x000 },
13068 { 0x00000000, 0x0ae00000, 0x48c },
13069 { 0x00000000, 0xc0200000, 0x000 },
13070 { 0x00000000, 0xc0200000, 0x000 },
13071 { 0x00000000, 0xc0400000, 0x000 },
13072 { 0x00000000, 0x00404c08, 0x44c },
13073 { 0x00000000, 0xc0200800, 0x000 },
13074 { 0x00000010, 0x40210e20, 0x000 },
13075 { 0x00000011, 0x40211220, 0x000 },
13076 { 0x00000012, 0x40211620, 0x000 },
13077 { 0x00002169, 0x00204411, 0x000 },
13078 { 0x00000000, 0x00204802, 0x000 },
13079 { 0x00000000, 0x00210225, 0x000 },
13080 { 0x00000000, 0x14e00000, 0x496 },
13081 { 0x00040000, 0xc0494a20, 0x497 },
13082 { 0xfffbffff, 0xc0284a20, 0x000 },
13083 { 0x00000000, 0x00210223, 0x000 },
13084 { 0x00000000, 0x14e00000, 0x4a3 },
13085 { 0x00000000, 0xc0204800, 0x000 },
13086 { 0x00000000, 0xc0204800, 0x000 },
13087 { 0x00000000, 0x00210224, 0x000 },
13088 { 0x00000000, 0x14c00000, 0x000 },
13089 { 0x81000000, 0x00204411, 0x000 },
13090 { 0x0000000c, 0x00204811, 0x000 },
13091 { 0x00000000, 0x00200010, 0x000 },
13092 { 0x00000000, 0x14c00000, 0x49f },
13093 { 0xa0000000, 0x00204411, 0x000 },
13094 { 0xcafebabe, 0x00404811, 0x000 },
13095 { 0x81000000, 0x00204411, 0x000 },
13096 { 0x00000004, 0x00204811, 0x000 },
13097 { 0x0000216b, 0x00204411, 0x000 },
13098 { 0x00000000, 0xc0204810, 0x000 },
13099 { 0x81000000, 0x00204411, 0x000 },
13100 { 0x00000005, 0x00204811, 0x000 },
13101 { 0x0000216c, 0x00204411, 0x000 },
13102 { 0x00000000, 0xc0204810, 0x000 },
13103 { 0x00000000, 0x002f0224, 0x000 },
13104 { 0x00000000, 0x0ce00000, 0x000 },
13105 { 0x00000000, 0x00400000, 0x49d },
13106 { 0x00000000, 0xc0210a20, 0x000 },
13107 { 0x00000000, 0x14c00000, 0x4b6 },
13108 { 0x81000000, 0x00204411, 0x000 },
13109 { 0x00000000, 0x00204811, 0x000 },
13110 { 0x0000216d, 0x00204411, 0x000 },
13111 { 0x00000000, 0xc0204800, 0x000 },
13112 { 0x00000000, 0xc0604800, 0x681 },
13113 { 0x00000000, 0x00400000, 0x4ba },
13114 { 0x81000000, 0x00204411, 0x000 },
13115 { 0x00000001, 0x00204811, 0x000 },
13116 { 0x00040000, 0xc0294620, 0x000 },
13117 { 0x00000000, 0xc0600000, 0x67c },
13118 { 0x00000001, 0x00210222, 0x000 },
13119 { 0x00000000, 0x14c00000, 0x4c1 },
13120 { 0x00002169, 0x00204411, 0x000 },
13121 { 0x00000000, 0xc0204800, 0x000 },
13122 { 0x00000000, 0xc0204800, 0x000 },
13123 { 0x00000000, 0x00204810, 0x000 },
13124 { 0xcafebabe, 0x00404811, 0x000 },
13125 { 0x00000000, 0xc0204400, 0x000 },
13126 { 0x00000000, 0xc0404810, 0x000 },
13127 { 0x81000000, 0x00204411, 0x000 },
13128 { 0x00000001, 0x00204811, 0x000 },
13129 { 0x000021f8, 0x00204411, 0x000 },
13130 { 0x0000000e, 0x00204811, 0x000 },
13131 { 0x000421f9, 0x00604411, 0x67c },
13132 { 0x00000000, 0x00210230, 0x000 },
13133 { 0x00000000, 0x14c00000, 0x4c3 },
13134 { 0x00002180, 0x00204411, 0x000 },
13135 { 0x00000000, 0xc0204800, 0x000 },
13136 { 0x00000000, 0xc0200000, 0x000 },
13137 { 0x00000000, 0xc0204800, 0x000 },
13138 { 0x00000000, 0xc0200000, 0x000 },
13139 { 0x00000000, 0xc0404800, 0x000 },
13140 { 0x00000003, 0x00333e2f, 0x000 },
13141 { 0x00000001, 0x00210221, 0x000 },
13142 { 0x00000000, 0x14e00000, 0x4f3 },
13143 { 0x0000002c, 0x00200a2d, 0x000 },
13144 { 0x00040000, 0x18e00c11, 0x4e2 },
13145 { 0x00000001, 0x00333e2f, 0x000 },
13146 { 0x00002169, 0x00204411, 0x000 },
13147 { 0x00000000, 0x00204802, 0x000 },
13148 { 0x00000000, 0x00204803, 0x000 },
13149 { 0x00000008, 0x00300a22, 0x000 },
13150 { 0x00000000, 0xc0204800, 0x000 },
13151 { 0x00000000, 0xc0204800, 0x000 },
13152 { 0x00002169, 0x00204411, 0x000 },
13153 { 0x00000000, 0x00204802, 0x000 },
13154 { 0x00000000, 0x00204803, 0x000 },
13155 { 0x00000008, 0x00300a22, 0x000 },
13156 { 0x00000000, 0xc0204800, 0x000 },
13157 { 0x00000000, 0xd8c04800, 0x4d6 },
13158 { 0x00002169, 0x00204411, 0x000 },
13159 { 0x00000000, 0x00204802, 0x000 },
13160 { 0x00000000, 0x00204803, 0x000 },
13161 { 0x00000008, 0x00300a22, 0x000 },
13162 { 0x00000000, 0xc0204800, 0x000 },
13163 { 0x00000000, 0xc0204800, 0x000 },
13164 { 0x0000002d, 0x0020122d, 0x000 },
13165 { 0x00000000, 0x00290c83, 0x000 },
13166 { 0x00002169, 0x00204411, 0x000 },
13167 { 0x00000000, 0x00204802, 0x000 },
13168 { 0x00000000, 0x00204803, 0x000 },
13169 { 0x00000008, 0x00300a22, 0x000 },
13170 { 0x00000000, 0xc0204800, 0x000 },
13171 { 0x00000000, 0xc0204800, 0x000 },
13172 { 0x00000011, 0x00210224, 0x000 },
13173 { 0x00000000, 0x14c00000, 0x000 },
13174 { 0x00000000, 0x00400000, 0x49d },
13175 { 0x0000002c, 0xc0203620, 0x000 },
13176 { 0x0000002d, 0xc0403620, 0x000 },
13177 { 0x0000000f, 0x00210221, 0x000 },
13178 { 0x00000000, 0x14c00000, 0x4f8 },
13179 { 0x00000000, 0x00600000, 0x00b },
13180 { 0x00000000, 0xd9000000, 0x000 },
13181 { 0x00000000, 0xc0400400, 0x001 },
13182 { 0xb5000000, 0x00204411, 0x000 },
13183 { 0x00002000, 0x00204811, 0x000 },
13184 { 0xb6000000, 0x00204411, 0x000 },
13185 { 0x0000a000, 0x00204811, 0x000 },
13186 { 0xb7000000, 0x00204411, 0x000 },
13187 { 0x0000c000, 0x00204811, 0x000 },
13188 { 0xb8000000, 0x00204411, 0x000 },
13189 { 0x0000f8e0, 0x00204811, 0x000 },
13190 { 0xb9000000, 0x00204411, 0x000 },
13191 { 0x0000f880, 0x00204811, 0x000 },
13192 { 0xba000000, 0x00204411, 0x000 },
13193 { 0x0000e000, 0x00204811, 0x000 },
13194 { 0xbb000000, 0x00204411, 0x000 },
13195 { 0x0000f000, 0x00204811, 0x000 },
13196 { 0xbc000000, 0x00204411, 0x000 },
13197 { 0x0000f3fc, 0x00204811, 0x000 },
13198 { 0x81000000, 0x00204411, 0x000 },
13199 { 0x00000002, 0x00204811, 0x000 },
13200 { 0x000000ff, 0x00280e30, 0x000 },
13201 { 0x00000000, 0x002f0223, 0x000 },
13202 { 0x00000000, 0x0cc00000, 0x50c },
13203 { 0x00000000, 0xc0200800, 0x000 },
13204 { 0x00000000, 0x14c00000, 0x521 },
13205 { 0x00000000, 0x00200c11, 0x000 },
13206 { 0x0000001c, 0x00203623, 0x000 },
13207 { 0x0000002b, 0x00203623, 0x000 },
13208 { 0x00000029, 0x00203623, 0x000 },
13209 { 0x00000028, 0x00203623, 0x000 },
13210 { 0x00000017, 0x00203623, 0x000 },
13211 { 0x00000025, 0x00203623, 0x000 },
13212 { 0x00000026, 0x00203623, 0x000 },
13213 { 0x00000015, 0x00203623, 0x000 },
13214 { 0x00000016, 0x00203623, 0x000 },
13215 { 0xffffe000, 0x00200c11, 0x000 },
13216 { 0x00000021, 0x00203623, 0x000 },
13217 { 0x00000022, 0x00203623, 0x000 },
13218 { 0x00001fff, 0x00200c11, 0x000 },
13219 { 0x00000023, 0x00203623, 0x000 },
13220 { 0x00000024, 0x00203623, 0x000 },
13221 { 0xf1ffffff, 0x00283a2e, 0x000 },
13222 { 0x0000001a, 0xc0220e20, 0x000 },
13223 { 0x00000000, 0x0029386e, 0x000 },
13224 { 0x81000000, 0x00204411, 0x000 },
13225 { 0x00000006, 0x00204811, 0x000 },
13226 { 0x0000002a, 0x40203620, 0x000 },
13227 { 0x87000000, 0x00204411, 0x000 },
13228 { 0x00000000, 0xc0204800, 0x000 },
13229 { 0x0000a1f4, 0x00204411, 0x000 },
13230 { 0x00000000, 0x00204810, 0x000 },
13231 { 0x00000000, 0x00200c11, 0x000 },
13232 { 0x00000030, 0x00203623, 0x000 },
13233 { 0x9d000000, 0x00204411, 0x000 },
13234 { 0x0000001f, 0x40214a20, 0x000 },
13235 { 0x96000000, 0x00204411, 0x000 },
13236 { 0x00000000, 0xc0204800, 0x000 },
13237 { 0x00000000, 0xc0200c00, 0x000 },
13238 { 0x00000000, 0xc0201000, 0x000 },
13239 { 0x0000001f, 0x00211624, 0x000 },
13240 { 0x00000000, 0x14c00000, 0x000 },
13241 { 0x0000001d, 0x00203623, 0x000 },
13242 { 0x00000003, 0x00281e23, 0x000 },
13243 { 0x00000008, 0x00222223, 0x000 },
13244 { 0xfffff000, 0x00282228, 0x000 },
13245 { 0x00000000, 0x002920e8, 0x000 },
13246 { 0x0000001f, 0x00203628, 0x000 },
13247 { 0x00000018, 0x00211e23, 0x000 },
13248 { 0x00000020, 0x00203627, 0x000 },
13249 { 0x00000002, 0x00221624, 0x000 },
13250 { 0x00000000, 0x003014a8, 0x000 },
13251 { 0x0000001e, 0x00203625, 0x000 },
13252 { 0x00000003, 0x00211a24, 0x000 },
13253 { 0x10000000, 0x00281a26, 0x000 },
13254 { 0xefffffff, 0x00283a2e, 0x000 },
13255 { 0x00000000, 0x004938ce, 0x66a },
13256 { 0x00000001, 0x40280a20, 0x000 },
13257 { 0x00000006, 0x40280e20, 0x000 },
13258 { 0x00000300, 0xc0281220, 0x000 },
13259 { 0x00000008, 0x00211224, 0x000 },
13260 { 0x00000000, 0xc0201620, 0x000 },
13261 { 0x00000000, 0xc0201a20, 0x000 },
13262 { 0x00000000, 0x00210222, 0x000 },
13263 { 0x00000000, 0x14c00000, 0x559 },
13264 { 0x81000000, 0x00204411, 0x000 },
13265 { 0x00000001, 0x00204811, 0x000 },
13266 { 0x00002258, 0x00300a24, 0x000 },
13267 { 0x00040000, 0x00694622, 0x67c },
13268 { 0x00002169, 0x00204411, 0x000 },
13269 { 0x00000000, 0x00204805, 0x000 },
13270 { 0x00020000, 0x00294a26, 0x000 },
13271 { 0x00000000, 0x00204810, 0x000 },
13272 { 0xcafebabe, 0x00204811, 0x000 },
13273 { 0x00000002, 0x002f0223, 0x000 },
13274 { 0x00000000, 0x0cc00000, 0x561 },
13275 { 0x00000000, 0xc0201c10, 0x000 },
13276 { 0x00000000, 0xc0400000, 0x56f },
13277 { 0x00000002, 0x002f0223, 0x000 },
13278 { 0x00000000, 0x0cc00000, 0x561 },
13279 { 0x81000000, 0x00204411, 0x000 },
13280 { 0x00000001, 0x00204811, 0x000 },
13281 { 0x00002258, 0x00300a24, 0x000 },
13282 { 0x00040000, 0x00694622, 0x67c },
13283 { 0x00000000, 0xc0201c10, 0x000 },
13284 { 0x00000000, 0xc0400000, 0x56f },
13285 { 0x00000000, 0x002f0223, 0x000 },
13286 { 0x00000000, 0x0cc00000, 0x565 },
13287 { 0x00000000, 0xc0201c00, 0x000 },
13288 { 0x00000000, 0xc0400000, 0x56f },
13289 { 0x00000004, 0x002f0223, 0x000 },
13290 { 0x00000000, 0x0cc00000, 0x56d },
13291 { 0x81000000, 0x00204411, 0x000 },
13292 { 0x00000000, 0x00204811, 0x000 },
13293 { 0x0000216d, 0x00204411, 0x000 },
13294 { 0x00000000, 0xc0204800, 0x000 },
13295 { 0x00000000, 0xc0604800, 0x681 },
13296 { 0x00000000, 0x00401c10, 0x56f },
13297 { 0x00000000, 0xc0200000, 0x000 },
13298 { 0x00000000, 0xc0400000, 0x000 },
13299 { 0x00000000, 0x0ee00000, 0x571 },
13300 { 0x00000000, 0x00600000, 0x5bc },
13301 { 0x00000000, 0x002f0224, 0x000 },
13302 { 0x00000000, 0x0cc00000, 0x582 },
13303 { 0x0000a2b7, 0x00204411, 0x000 },
13304 { 0x00000000, 0x00204807, 0x000 },
13305 { 0x81000000, 0x00204411, 0x000 },
13306 { 0x00000001, 0x00204811, 0x000 },
13307 { 0x0004a2b6, 0x00604411, 0x67c },
13308 { 0x0000001a, 0x00212230, 0x000 },
13309 { 0x00000006, 0x00222630, 0x000 },
13310 { 0x00042004, 0x00604411, 0x67c },
13311 { 0x0000a2c4, 0x00204411, 0x000 },
13312 { 0x00000000, 0x003048e9, 0x000 },
13313 { 0x00000000, 0x00e00000, 0x580 },
13314 { 0x0000a2d1, 0x00204411, 0x000 },
13315 { 0x00000000, 0x00404808, 0x000 },
13316 { 0x0000a2d1, 0x00204411, 0x000 },
13317 { 0x00000001, 0x00504a28, 0x000 },
13318 { 0x00000001, 0x002f0224, 0x000 },
13319 { 0x00000000, 0x0cc00000, 0x593 },
13320 { 0x0000a2bb, 0x00204411, 0x000 },
13321 { 0x00000000, 0x00204807, 0x000 },
13322 { 0x81000000, 0x00204411, 0x000 },
13323 { 0x00000001, 0x00204811, 0x000 },
13324 { 0x0004a2ba, 0x00604411, 0x67c },
13325 { 0x0000001a, 0x00212230, 0x000 },
13326 { 0x00000006, 0x00222630, 0x000 },
13327 { 0x00042004, 0x00604411, 0x67c },
13328 { 0x0000a2c5, 0x00204411, 0x000 },
13329 { 0x00000000, 0x003048e9, 0x000 },
13330 { 0x00000000, 0x00e00000, 0x591 },
13331 { 0x0000a2d2, 0x00204411, 0x000 },
13332 { 0x00000000, 0x00404808, 0x000 },
13333 { 0x0000a2d2, 0x00204411, 0x000 },
13334 { 0x00000001, 0x00504a28, 0x000 },
13335 { 0x00000002, 0x002f0224, 0x000 },
13336 { 0x00000000, 0x0cc00000, 0x5a4 },
13337 { 0x0000a2bf, 0x00204411, 0x000 },
13338 { 0x00000000, 0x00204807, 0x000 },
13339 { 0x81000000, 0x00204411, 0x000 },
13340 { 0x00000001, 0x00204811, 0x000 },
13341 { 0x0004a2be, 0x00604411, 0x67c },
13342 { 0x0000001a, 0x00212230, 0x000 },
13343 { 0x00000006, 0x00222630, 0x000 },
13344 { 0x00042004, 0x00604411, 0x67c },
13345 { 0x0000a2c6, 0x00204411, 0x000 },
13346 { 0x00000000, 0x003048e9, 0x000 },
13347 { 0x00000000, 0x00e00000, 0x5a2 },
13348 { 0x0000a2d3, 0x00204411, 0x000 },
13349 { 0x00000000, 0x00404808, 0x000 },
13350 { 0x0000a2d3, 0x00204411, 0x000 },
13351 { 0x00000001, 0x00504a28, 0x000 },
13352 { 0x0000a2c3, 0x00204411, 0x000 },
13353 { 0x00000000, 0x00204807, 0x000 },
13354 { 0x81000000, 0x00204411, 0x000 },
13355 { 0x00000001, 0x00204811, 0x000 },
13356 { 0x0004a2c2, 0x00604411, 0x67c },
13357 { 0x0000001a, 0x00212230, 0x000 },
13358 { 0x00000006, 0x00222630, 0x000 },
13359 { 0x00042004, 0x00604411, 0x67c },
13360 { 0x0000a2c7, 0x00204411, 0x000 },
13361 { 0x00000000, 0x003048e9, 0x000 },
13362 { 0x00000000, 0x00e00000, 0x5b1 },
13363 { 0x0000a2d4, 0x00204411, 0x000 },
13364 { 0x00000000, 0x00404808, 0x000 },
13365 { 0x0000a2d4, 0x00204411, 0x000 },
13366 { 0x00000001, 0x00504a28, 0x000 },
13367 { 0x85000000, 0x00204411, 0x000 },
13368 { 0x00000000, 0x00204801, 0x000 },
13369 { 0x0000304a, 0x00204411, 0x000 },
13370 { 0x01000000, 0x00204811, 0x000 },
13371 { 0x00000000, 0x00400000, 0x5b7 },
13372 { 0xa4000000, 0xc0204411, 0x000 },
13373 { 0x00000000, 0xc0404800, 0x000 },
13374 { 0x00000000, 0xc0600000, 0x5bc },
13375 { 0x00000000, 0xc0400400, 0x001 },
13376 { 0x0000002c, 0x00203621, 0x000 },
13377 { 0x81000000, 0x00204411, 0x000 },
13378 { 0x00000006, 0x00204811, 0x000 },
13379 { 0x00000000, 0x002f0230, 0x000 },
13380 { 0x00000000, 0x0cc00000, 0x5c3 },
13381 { 0x00000000, 0x00200411, 0x000 },
13382 { 0x00000030, 0x00403621, 0x5d6 },
13383 { 0x00000030, 0x0020062d, 0x000 },
13384 { 0x00007e00, 0x00280621, 0x000 },
13385 { 0x00000000, 0x002f0221, 0x000 },
13386 { 0x00000000, 0x0ce00000, 0x5d6 },
13387 { 0x81000000, 0x00204411, 0x000 },
13388 { 0x00000001, 0x00204811, 0x000 },
13389 { 0x0004a092, 0x00604411, 0x67c },
13390 { 0x00000031, 0x00203630, 0x000 },
13391 { 0x0004a093, 0x00604411, 0x67c },
13392 { 0x00000032, 0x00203630, 0x000 },
13393 { 0x0004a2b6, 0x00604411, 0x67c },
13394 { 0x00000033, 0x00203630, 0x000 },
13395 { 0x0004a2ba, 0x00604411, 0x67c },
13396 { 0x00000034, 0x00203630, 0x000 },
13397 { 0x0004a2be, 0x00604411, 0x67c },
13398 { 0x00000035, 0x00203630, 0x000 },
13399 { 0x0004a2c2, 0x00604411, 0x67c },
13400 { 0x00000036, 0x00203630, 0x000 },
13401 { 0x00042004, 0x00604411, 0x67c },
13402 { 0x0001a2a4, 0x00204411, 0x000 },
13403 { 0x0000003f, 0x00204811, 0x000 },
13404 { 0x0000003f, 0x00204811, 0x000 },
13405 { 0x0000003f, 0x00204811, 0x000 },
13406 { 0x0000003f, 0x00204811, 0x000 },
13407 { 0x00000005, 0x00204811, 0x000 },
13408 { 0x0000a1f4, 0x00204411, 0x000 },
13409 { 0x00000000, 0x00204811, 0x000 },
13410 { 0x88000000, 0x00204411, 0x000 },
13411 { 0x00000001, 0x00204811, 0x000 },
13412 { 0x81000000, 0x00204411, 0x000 },
13413 { 0x00000006, 0x00204811, 0x000 },
13414 { 0x00000001, 0x002f0230, 0x000 },
13415 { 0x00000000, 0x0ce00000, 0x61f },
13416 { 0x00000030, 0x0020062d, 0x000 },
13417 { 0x00000000, 0x002f0221, 0x000 },
13418 { 0x00000000, 0x0ce00000, 0x61f },
13419 { 0x81000000, 0x00204411, 0x000 },
13420 { 0x00000001, 0x00204811, 0x000 },
13421 { 0x00007e00, 0x00280621, 0x000 },
13422 { 0x00000000, 0x002f0221, 0x000 },
13423 { 0x00000000, 0x0ce00000, 0x5f8 },
13424 { 0x0000a092, 0x00204411, 0x000 },
13425 { 0x00000031, 0x00204a2d, 0x000 },
13426 { 0x0000a093, 0x00204411, 0x000 },
13427 { 0x00000032, 0x00204a2d, 0x000 },
13428 { 0x0000a2b6, 0x00204411, 0x000 },
13429 { 0x00000033, 0x00204a2d, 0x000 },
13430 { 0x0000a2ba, 0x00204411, 0x000 },
13431 { 0x00000034, 0x00204a2d, 0x000 },
13432 { 0x0000a2be, 0x00204411, 0x000 },
13433 { 0x00000035, 0x00204a2d, 0x000 },
13434 { 0x0000a2c2, 0x00204411, 0x000 },
13435 { 0x00000036, 0x00204a2d, 0x000 },
13436 { 0x00000030, 0x0020062d, 0x000 },
13437 { 0x000001ff, 0x00280621, 0x000 },
13438 { 0x00000000, 0x002f0221, 0x000 },
13439 { 0x00000000, 0x0ce00000, 0x61e },
13440 { 0x00000000, 0x00210221, 0x000 },
13441 { 0x00000000, 0x14c00000, 0x601 },
13442 { 0x0004a003, 0x00604411, 0x67c },
13443 { 0x0000a003, 0x00204411, 0x000 },
13444 { 0x00000000, 0x00204810, 0x000 },
13445 { 0x00000001, 0x00210621, 0x000 },
13446 { 0x00000000, 0x14c00000, 0x606 },
13447 { 0x0004a010, 0x00604411, 0x67c },
13448 { 0x0000a010, 0x00204411, 0x000 },
13449 { 0x00000000, 0x00204810, 0x000 },
13450 { 0x00000001, 0x00210621, 0x000 },
13451 { 0x00000000, 0x002f0221, 0x000 },
13452 { 0x00000000, 0x0ce00000, 0x61e },
13453 { 0x0004a011, 0x00604411, 0x67c },
13454 { 0x0000a011, 0x00204411, 0x000 },
13455 { 0x00000000, 0x00204810, 0x000 },
13456 { 0x0004a012, 0x00604411, 0x67c },
13457 { 0x0000a012, 0x00204411, 0x000 },
13458 { 0x00000000, 0x00204810, 0x000 },
13459 { 0x0004a013, 0x00604411, 0x67c },
13460 { 0x0000a013, 0x00204411, 0x000 },
13461 { 0x00000000, 0x00204810, 0x000 },
13462 { 0x0004a014, 0x00604411, 0x67c },
13463 { 0x0000a014, 0x00204411, 0x000 },
13464 { 0x00000000, 0x00204810, 0x000 },
13465 { 0x0004a015, 0x00604411, 0x67c },
13466 { 0x0000a015, 0x00204411, 0x000 },
13467 { 0x00000000, 0x00204810, 0x000 },
13468 { 0x0004a016, 0x00604411, 0x67c },
13469 { 0x0000a016, 0x00204411, 0x000 },
13470 { 0x00000000, 0x00204810, 0x000 },
13471 { 0x0004a017, 0x00604411, 0x67c },
13472 { 0x0000a017, 0x00204411, 0x000 },
13473 { 0x00000000, 0x00204810, 0x000 },
13474 { 0x00042004, 0x00604411, 0x67c },
13475 { 0x0000002c, 0x0080062d, 0x000 },
13476 { 0xff000000, 0x00204411, 0x000 },
13477 { 0x00000000, 0x00204811, 0x000 },
13478 { 0x00000001, 0x00204811, 0x000 },
13479 { 0x00000002, 0x00804811, 0x000 },
13480 { 0x00000000, 0x0ee00000, 0x630 },
13481 { 0x00000030, 0x0020062d, 0x000 },
13482 { 0x00000002, 0x00280621, 0x000 },
13483 { 0x00000000, 0x002f0221, 0x000 },
13484 { 0x00000000, 0x0ce00000, 0x62e },
13485 { 0x81000000, 0x00204411, 0x000 },
13486 { 0x00000001, 0x00204811, 0x000 },
13487 { 0x00042004, 0x00604411, 0x67c },
13488 { 0x00001000, 0x00200811, 0x000 },
13489 { 0x0000002b, 0x00203622, 0x000 },
13490 { 0x00000000, 0x00600000, 0x634 },
13491 { 0x00000000, 0x00600000, 0x5bc },
13492 { 0x98000000, 0x00204411, 0x000 },
13493 { 0x00000000, 0x00804811, 0x000 },
13494 { 0x00000000, 0xc0600000, 0x634 },
13495 { 0x00000000, 0xc0400400, 0x001 },
13496 { 0x0000a2a4, 0x00204411, 0x000 },
13497 { 0x00000022, 0x00204811, 0x000 },
13498 { 0x89000000, 0x00204411, 0x000 },
13499 { 0x00000001, 0x00404811, 0x620 },
13500 { 0x97000000, 0x00204411, 0x000 },
13501 { 0x00000000, 0x00204811, 0x000 },
13502 { 0x8a000000, 0x00204411, 0x000 },
13503 { 0x00000000, 0x00404811, 0x620 },
13504 { 0x00000000, 0x00600000, 0x64d },
13505 { 0x0001a2a4, 0xc0204411, 0x000 },
13506 { 0x00000016, 0x00604811, 0x36a },
13507 { 0x00002010, 0x00204411, 0x000 },
13508 { 0x00010000, 0x00204811, 0x000 },
13509 { 0x81000000, 0x00204411, 0x000 },
13510 { 0x00000001, 0x00204811, 0x000 },
13511 { 0x0000217c, 0x00204411, 0x000 },
13512 { 0x09800000, 0x00204811, 0x000 },
13513 { 0xffffffff, 0x00204811, 0x000 },
13514 { 0x00000000, 0x00204811, 0x000 },
13515 { 0x00000000, 0x17000000, 0x000 },
13516 { 0x0004217f, 0x00604411, 0x67c },
13517 { 0x0000001f, 0x00210230, 0x000 },
13518 { 0x00000000, 0x14c00000, 0x000 },
13519 { 0x00000004, 0x00404c11, 0x647 },
13520 { 0x00000000, 0x00400000, 0x000 },
13521 { 0x00000017, 0x00201e2d, 0x000 },
13522 { 0x00000004, 0x00291e27, 0x000 },
13523 { 0x00000017, 0x00803627, 0x000 },
13524 { 0x00000017, 0x00201e2d, 0x000 },
13525 { 0xfffffffb, 0x00281e27, 0x000 },
13526 { 0x00000017, 0x00803627, 0x000 },
13527 { 0x00000017, 0x00201e2d, 0x000 },
13528 { 0x00000008, 0x00291e27, 0x000 },
13529 { 0x00000017, 0x00803627, 0x000 },
13530 { 0x00000017, 0x00201e2d, 0x000 },
13531 { 0xfffffff7, 0x00281e27, 0x000 },
13532 { 0x00000017, 0x00803627, 0x000 },
13533 { 0x0001a2a4, 0x00204411, 0x000 },
13534 { 0x00000016, 0x00604811, 0x36a },
13535 { 0x00002010, 0x00204411, 0x000 },
13536 { 0x00010000, 0x00204811, 0x000 },
13537 { 0x0000217c, 0x00204411, 0x000 },
13538 { 0x01800000, 0x00204811, 0x000 },
13539 { 0xffffffff, 0x00204811, 0x000 },
13540 { 0x00000000, 0x00204811, 0x000 },
13541 { 0x00000000, 0x17000000, 0x000 },
13542 { 0x81000000, 0x00204411, 0x000 },
13543 { 0x00000001, 0x00204811, 0x000 },
13544 { 0x0004217f, 0x00604411, 0x67c },
13545 { 0x0000001f, 0x00210230, 0x000 },
13546 { 0x00000000, 0x14c00000, 0x67b },
13547 { 0x00000010, 0x00404c11, 0x661 },
13548 { 0x00000000, 0xc0200400, 0x000 },
13549 { 0x00000000, 0x38c00000, 0x000 },
13550 { 0x0000001d, 0x00200a2d, 0x000 },
13551 { 0x0000001e, 0x00200e2d, 0x000 },
13552 { 0x0000001f, 0x0020122d, 0x000 },
13553 { 0x00000020, 0x0020162d, 0x000 },
13554 { 0x00002169, 0x00204411, 0x000 },
13555 { 0x00000000, 0x00204804, 0x000 },
13556 { 0x00000000, 0x00204805, 0x000 },
13557 { 0x00000000, 0x00204801, 0x000 },
13558 { 0xcafebabe, 0x00204811, 0x000 },
13559 { 0x00000004, 0x00301224, 0x000 },
13560 { 0x00000000, 0x002f0064, 0x000 },
13561 { 0x00000000, 0x0cc00000, 0x67a },
13562 { 0x00000003, 0x00281a22, 0x000 },
13563 { 0x00000008, 0x00221222, 0x000 },
13564 { 0xfffff000, 0x00281224, 0x000 },
13565 { 0x00000000, 0x002910c4, 0x000 },
13566 { 0x0000001f, 0x00403624, 0x000 },
13567 { 0x00000000, 0x00800000, 0x000 },
13568 { 0x00000000, 0x1ac00000, 0x67c },
13569 { 0x9f000000, 0x00204411, 0x000 },
13570 { 0xcafebabe, 0x00204811, 0x000 },
13571 { 0x00000000, 0x1ae00000, 0x67f },
13572 { 0x00000000, 0x00800000, 0x000 },
13573 { 0x00000000, 0x1ac00000, 0x681 },
13574 { 0x9e000000, 0x00204411, 0x000 },
13575 { 0xcafebabe, 0x00204811, 0x000 },
13576 { 0x00000000, 0x1ae00000, 0x684 },
13577 { 0x00000000, 0x00800000, 0x000 },
13578 { 0x00000000, 0x00600000, 0x00b },
13579 { 0x00001000, 0x00600411, 0x315 },
13580 { 0x00000000, 0x00200411, 0x000 },
13581 { 0x00000000, 0x00600811, 0x1b2 },
13582 { 0x0000225c, 0x00204411, 0x000 },
13583 { 0x00000003, 0x00204811, 0x000 },
13584 { 0x00002256, 0x00204411, 0x000 },
13585 { 0x0000001b, 0x00204811, 0x000 },
13586 { 0x0000a1fc, 0x00204411, 0x000 },
13587 { 0x00000001, 0x00204811, 0x000 },
13588 { 0x0001a1fd, 0xc0204411, 0x000 },
13589 { 0x00000021, 0x00201e2d, 0x000 },
13590 { 0x00000010, 0x00221e27, 0x000 },
13591 { 0x00000024, 0x0020222d, 0x000 },
13592 { 0x0000ffff, 0x00282228, 0x000 },
13593 { 0x00000000, 0x00294907, 0x000 },
13594 { 0x00000000, 0x00204811, 0x000 },
13595 { 0x00000022, 0x0020222d, 0x000 },
13596 { 0x0000ffff, 0x00282228, 0x000 },
13597 { 0x00000000, 0x00294907, 0x000 },
13598 { 0x00000000, 0x00204811, 0x000 },
13599 { 0x00000023, 0x00201e2d, 0x000 },
13600 { 0x00000010, 0x00221e27, 0x000 },
13601 { 0x00000000, 0x00294907, 0x000 },
13602 { 0x00000000, 0x00404811, 0x000 },
13603 { 0x00000000, 0x00000000, 0x000 },
13604 { 0x00000000, 0x00000000, 0x000 },
13605 { 0x00000000, 0x00000000, 0x000 },
13606 { 0x00000000, 0x00000000, 0x000 },
13607 { 0x00000000, 0x00000000, 0x000 },
13608 { 0x00000000, 0x00000000, 0x000 },
13609 { 0x00000000, 0x00000000, 0x000 },
13610 { 0x00000000, 0x00000000, 0x000 },
13611 { 0x00000000, 0x00000000, 0x000 },
13612 { 0x00000000, 0x00000000, 0x000 },
13613 { 0x00000000, 0x00000000, 0x000 },
13614 { 0x00000000, 0x00000000, 0x000 },
13615 { 0x00000000, 0x00000000, 0x000 },
13616 { 0x00000000, 0x00000000, 0x000 },
13617 { 0x00000000, 0x00000000, 0x000 },
13618 { 0x00000000, 0x00000000, 0x000 },
13619 { 0x00000000, 0x00000000, 0x000 },
13620 { 0x00000000, 0x00000000, 0x000 },
13621 { 0x00000000, 0x00000000, 0x000 },
13622 { 0x00000000, 0x00000000, 0x000 },
13623 { 0x00000000, 0x00000000, 0x000 },
13624 { 0x00000000, 0x00000000, 0x000 },
13625 { 0x00000000, 0x00000000, 0x000 },
13626 { 0x00000000, 0x00000000, 0x000 },
13627 { 0x00000000, 0x00000000, 0x000 },
13628 { 0x00000000, 0x00000000, 0x000 },
13629 { 0x00000000, 0x00000000, 0x000 },
13630 { 0x00000000, 0x00000000, 0x000 },
13631 { 0x00000000, 0x00000000, 0x000 },
13632 { 0x00000000, 0x00000000, 0x000 },
13633 { 0x00000000, 0x00000000, 0x000 },
13634 { 0x00000000, 0x00000000, 0x000 },
13635 { 0x00000000, 0x00000000, 0x000 },
13636 { 0x00000000, 0x00000000, 0x000 },
13637 { 0x00000000, 0x00000000, 0x000 },
13638 { 0x00000000, 0x00000000, 0x000 },
13639 { 0x00000000, 0x00000000, 0x000 },
13640 { 0x00000000, 0x00000000, 0x000 },
13641 { 0x00000000, 0x00000000, 0x000 },
13642 { 0x00000000, 0x00000000, 0x000 },
13643 { 0x00000000, 0x00000000, 0x000 },
13644 { 0x00000000, 0x00000000, 0x000 },
13645 { 0x00000000, 0x00000000, 0x000 },
13646 { 0x00000000, 0x00000000, 0x000 },
13647 { 0x00000000, 0x00000000, 0x000 },
13648 { 0x00000000, 0x00000000, 0x000 },
13649 { 0x00000000, 0x00000000, 0x000 },
13650 { 0x00000000, 0x00000000, 0x000 },
13651 { 0x00000000, 0x00000000, 0x000 },
13652 { 0x00000000, 0x00000000, 0x000 },
13653 { 0x00000000, 0x00000000, 0x000 },
13654 { 0x00000000, 0x00000000, 0x000 },
13655 { 0x00000000, 0x00000000, 0x000 },
13656 { 0x00000000, 0x00000000, 0x000 },
13657 { 0x00000000, 0x00000000, 0x000 },
13658 { 0x00000000, 0x00000000, 0x000 },
13659 { 0x00000000, 0x00000000, 0x000 },
13660 { 0x00000000, 0x00000000, 0x000 },
13661 { 0x00000000, 0x00000000, 0x000 },
13662 { 0x00000000, 0x00000000, 0x000 },
13663 { 0x00000000, 0x00000000, 0x000 },
13664 { 0x00000000, 0x00000000, 0x000 },
13665 { 0x00000000, 0x00000000, 0x000 },
13666 { 0x00000000, 0x00000000, 0x000 },
13667 { 0x00000000, 0x00000000, 0x000 },
13668 { 0x00000000, 0x00000000, 0x000 },
13669 { 0x00000000, 0x00000000, 0x000 },
13670 { 0x00000000, 0x00000000, 0x000 },
13671 { 0x00000000, 0x00000000, 0x000 },
13672 { 0x014204f5, 0x05b30250, 0x000 },
13673 { 0x01c30168, 0x043505b3, 0x000 },
13674 { 0x02250209, 0x02500151, 0x000 },
13675 { 0x02230245, 0x02a00241, 0x000 },
13676 { 0x03cd05b3, 0x05b305b3, 0x000 },
13677 { 0x063c063d, 0x031f05b3, 0x000 },
13678 { 0x05b305b8, 0x03200340, 0x000 },
13679 { 0x032a0282, 0x03420334, 0x000 },
13680 { 0x05b305b3, 0x05b305b3, 0x000 },
13681 { 0x05b30544, 0x05b305b3, 0x000 },
13682 { 0x03b205b3, 0x04ae0344, 0x000 },
13683 { 0x048d0443, 0x043305b3, 0x000 },
13684 { 0x04c305b3, 0x043704d0, 0x000 },
13685 { 0x044304fa, 0x03510371, 0x000 },
13686 { 0x05b305b3, 0x05b305b3, 0x000 },
13687 { 0x05b305b3, 0x05b305b3, 0x000 },
13688 { 0x05b305b3, 0x063205ba, 0x000 },
13689 { 0x05b305b3, 0x000705b3, 0x000 },
13690 { 0x05b305b3, 0x05b305b3, 0x000 },
13691 { 0x05b305b3, 0x05b305b3, 0x000 },
13692 { 0x03ee03e3, 0x03fe03fc, 0x000 },
13693 { 0x04040400, 0x04020406, 0x000 },
13694 { 0x0412040e, 0x041a0416, 0x000 },
13695 { 0x0422041e, 0x042a0426, 0x000 },
13696 { 0x05b305b3, 0x042e05b3, 0x000 },
13697 { 0x05b305b3, 0x05b305b3, 0x000 },
13698 { 0x05b305b3, 0x05b305b3, 0x000 },
13699 { 0x00020668, 0x06860006, 0x000 },
13700};
13701
13702static const u32 RV670_pfp_microcode[] = {
137030xca0400,
137040xa00000,
137050x7e828b,
137060x7c038b,
137070x8001b8,
137080x7c038b,
137090xd4401e,
137100xee001e,
137110xca0400,
137120xa00000,
137130x7e828b,
137140xc41838,
137150xca2400,
137160xca2800,
137170x9581a8,
137180xc41c3a,
137190xc3c000,
137200xca0800,
137210xca0c00,
137220x7c744b,
137230xc20005,
137240x99c000,
137250xc41c3a,
137260x7c744c,
137270xc0fff0,
137280x042c04,
137290x309002,
137300x7d2500,
137310x351402,
137320x7d350b,
137330x255403,
137340x7cd580,
137350x259c03,
137360x95c004,
137370xd5001b,
137380x7eddc1,
137390x7d9d80,
137400xd6801b,
137410xd5801b,
137420xd4401e,
137430xd5401e,
137440xd6401e,
137450xd6801e,
137460xd4801e,
137470xd4c01e,
137480x9783d3,
137490xd5c01e,
137500xca0800,
137510x80001a,
137520xca0c00,
137530xe4011e,
137540xd4001e,
137550x80000c,
137560xc41838,
137570xe4013e,
137580xd4001e,
137590x80000c,
137600xc41838,
137610xd4401e,
137620xee001e,
137630xca0400,
137640xa00000,
137650x7e828b,
137660xe4011e,
137670xd4001e,
137680xd4401e,
137690xee001e,
137700xca0400,
137710xa00000,
137720x7e828b,
137730xe4013e,
137740xd4001e,
137750xd4401e,
137760xee001e,
137770xca0400,
137780xa00000,
137790x7e828b,
137800xca1800,
137810xd4401e,
137820xd5801e,
137830x800053,
137840xd40075,
137850xd4401e,
137860xca0800,
137870xca0c00,
137880xca1000,
137890xd48019,
137900xd4c018,
137910xd50017,
137920xd4801e,
137930xd4c01e,
137940xd5001e,
137950xe2001e,
137960xca0400,
137970xa00000,
137980x7e828b,
137990xca0800,
138000xd48060,
138010xd4401e,
138020x800000,
138030xd4801e,
138040xca0800,
138050xd48061,
138060xd4401e,
138070x800000,
138080xd4801e,
138090xca0800,
138100xca0c00,
138110xd4401e,
138120xd48016,
138130xd4c016,
138140xd4801e,
138150x8001b8,
138160xd4c01e,
138170xc60843,
138180xca0c00,
138190xca1000,
138200x948004,
138210xca1400,
138220xe420f3,
138230xd42013,
138240xd56065,
138250xd4e01c,
138260xd5201c,
138270xd5601c,
138280x800000,
138290x062001,
138300xc60843,
138310xca0c00,
138320xca1000,
138330x9483f7,
138340xca1400,
138350xe420f3,
138360x800079,
138370xd42013,
138380xc60843,
138390xca0c00,
138400xca1000,
138410x9883ef,
138420xca1400,
138430xd40064,
138440x80008d,
138450x000000,
138460xc41432,
138470xc61843,
138480xc4082f,
138490x954005,
138500xc40c30,
138510xd4401e,
138520x800000,
138530xee001e,
138540x9583f5,
138550xc41031,
138560xd44033,
138570xd52065,
138580xd4a01c,
138590xd4e01c,
138600xd5201c,
138610xe4015e,
138620xd4001e,
138630x800000,
138640x062001,
138650xca1800,
138660x0a2001,
138670xd60076,
138680xc40836,
138690x988007,
138700xc61045,
138710x950110,
138720xd4001f,
138730xd46062,
138740x800000,
138750xd42062,
138760xcc3835,
138770xcc1433,
138780x8401bb,
138790xd40072,
138800xd5401e,
138810x800000,
138820xee001e,
138830xe2001a,
138840x8401bb,
138850xe2001a,
138860xcc104b,
138870xcc0447,
138880x2c9401,
138890x7d098b,
138900x984005,
138910x7d15cb,
138920xd4001a,
138930x8001b8,
138940xd4006d,
138950x344401,
138960xcc0c48,
138970x98403a,
138980xcc2c4a,
138990x958004,
139000xcc0449,
139010x8001b8,
139020xd4001a,
139030xd4c01a,
139040x282801,
139050x8400f0,
139060xcc1003,
139070x98801b,
139080x04380c,
139090x8400f0,
139100xcc1003,
139110x988017,
139120x043808,
139130x8400f0,
139140xcc1003,
139150x988013,
139160x043804,
139170x8400f0,
139180xcc1003,
139190x988014,
139200xcc104c,
139210x9a8009,
139220xcc144d,
139230x9840dc,
139240xd4006d,
139250xcc1848,
139260xd5001a,
139270xd5401a,
139280x8000c9,
139290xd5801a,
139300x96c0d5,
139310xd4006d,
139320x8001b8,
139330xd4006e,
139340x9ac003,
139350xd4006d,
139360xd4006e,
139370x800000,
139380xec007f,
139390x9ac0cc,
139400xd4006d,
139410x8001b8,
139420xd4006e,
139430xcc1403,
139440xcc1803,
139450xcc1c03,
139460x7d9103,
139470x7dd583,
139480x7d190c,
139490x35cc1f,
139500x35701f,
139510x7cf0cb,
139520x7cd08b,
139530x880000,
139540x7e8e8b,
139550x95c004,
139560xd4006e,
139570x8001b8,
139580xd4001a,
139590xd4c01a,
139600xcc0803,
139610xcc0c03,
139620xcc1003,
139630xcc1403,
139640xcc1803,
139650xcc1c03,
139660xcc2403,
139670xcc2803,
139680x35c41f,
139690x36b01f,
139700x7c704b,
139710x34f01f,
139720x7c704b,
139730x35701f,
139740x7c704b,
139750x7d8881,
139760x7dccc1,
139770x7e5101,
139780x7e9541,
139790x7c9082,
139800x7cd4c2,
139810x7c848b,
139820x9ac003,
139830x7c8c8b,
139840x2c8801,
139850x98809e,
139860xd4006d,
139870x98409c,
139880xd4006e,
139890xcc084c,
139900xcc0c4d,
139910xcc1048,
139920xd4801a,
139930xd4c01a,
139940x800101,
139950xd5001a,
139960xcc0832,
139970xd40032,
139980x9482d9,
139990xca0c00,
140000xd4401e,
140010x800000,
140020xd4001e,
140030xe4011e,
140040xd4001e,
140050xca0800,
140060xca0c00,
140070xca1000,
140080xd4401e,
140090xca1400,
140100xd4801e,
140110xd4c01e,
140120xd5001e,
140130xd5401e,
140140xd54034,
140150x800000,
140160xee001e,
140170x280404,
140180xe2001a,
140190xe2001a,
140200xd4401a,
140210xca3800,
140220xcc0803,
140230xcc0c03,
140240xcc0c03,
140250xcc0c03,
140260x9882bd,
140270x000000,
140280x8401bb,
140290xd7a06f,
140300x800000,
140310xee001f,
140320xca0400,
140330xc2ff00,
140340xcc0834,
140350xc13fff,
140360x7c74cb,
140370x7cc90b,
140380x7d010f,
140390x9902b0,
140400x7c738b,
140410x8401bb,
140420xd7a06f,
140430x800000,
140440xee001f,
140450xca0800,
140460x281900,
140470x7d898b,
140480x958014,
140490x281404,
140500xca0c00,
140510xca1000,
140520xca1c00,
140530xca2400,
140540xe2001f,
140550xd4c01a,
140560xd5001a,
140570xd5401a,
140580xcc1803,
140590xcc2c03,
140600xcc2c03,
140610xcc2c03,
140620x7da58b,
140630x7d9c47,
140640x984297,
140650x000000,
140660x800161,
140670xd4c01a,
140680xd4401e,
140690xd4801e,
140700x800000,
140710xee001e,
140720xe4011e,
140730xd4001e,
140740xd4401e,
140750xee001e,
140760xca0400,
140770xa00000,
140780x7e828b,
140790xe4013e,
140800xd4001e,
140810xd4401e,
140820xee001e,
140830xca0400,
140840xa00000,
140850x7e828b,
140860xca0800,
140870x248c06,
140880x0ccc06,
140890x98c006,
140900xcc104e,
140910x990004,
140920xd40073,
140930xe4011e,
140940xd4001e,
140950xd4401e,
140960xd4801e,
140970x800000,
140980xee001e,
140990xca0800,
141000xca0c00,
141010x34d018,
141020x251001,
141030x950021,
141040xc17fff,
141050xca1000,
141060xca1400,
141070xca1800,
141080xd4801d,
141090xd4c01d,
141100x7db18b,
141110xc14202,
141120xc2c001,
141130xd5801d,
141140x34dc0e,
141150x7d5d4c,
141160x7f734c,
141170xd7401e,
141180xd5001e,
141190xd5401e,
141200xc14200,
141210xc2c000,
141220x099c01,
141230x31dc10,
141240x7f5f4c,
141250x7f734c,
141260x042802,
141270x7d8380,
141280xd5a86f,
141290xd58066,
141300xd7401e,
141310xec005e,
141320xc82402,
141330xc82402,
141340x8001b8,
141350xd60076,
141360xd4401e,
141370xd4801e,
141380xd4c01e,
141390x800000,
141400xee001e,
141410x800000,
141420xee001f,
141430xd4001f,
141440x800000,
141450xd4001f,
141460xd4001f,
141470x880000,
141480xd4001f,
141490x000000,
141500x000000,
141510x000000,
141520x000000,
141530x000000,
141540x000000,
141550x000000,
141560x000000,
141570x000000,
141580x000000,
141590x000000,
141600x000000,
141610x000000,
141620x000000,
141630x000000,
141640x000000,
141650x000000,
141660x000000,
141670x000000,
141680x000000,
141690x000000,
141700x000000,
141710x000000,
141720x000000,
141730x000000,
141740x000000,
141750x000000,
141760x000000,
141770x000000,
141780x000000,
141790x000000,
141800x000000,
141810x000000,
141820x000000,
141830x000000,
141840x000000,
141850x000000,
141860x000000,
141870x000000,
141880x000000,
141890x000000,
141900x000000,
141910x000000,
141920x000000,
141930x000000,
141940x000000,
141950x000000,
141960x000000,
141970x000000,
141980x000000,
141990x000000,
142000x000000,
142010x000000,
142020x000000,
142030x000000,
142040x000000,
142050x000000,
142060x000000,
142070x000000,
142080x000000,
142090x000000,
142100x000000,
142110x000000,
142120x000000,
142130x000000,
142140x000000,
142150x010171,
142160x020178,
142170x03008f,
142180x04007f,
142190x050003,
142200x06003f,
142210x070032,
142220x08012c,
142230x090046,
142240x0a0036,
142250x1001b6,
142260x1700a2,
142270x22013a,
142280x230149,
142290x2000b4,
142300x240125,
142310x27004d,
142320x28006a,
142330x2a0060,
142340x2b0052,
142350x2f0065,
142360x320087,
142370x34017f,
142380x3c0156,
142390x3f0072,
142400x41018c,
142410x44012e,
142420x550173,
142430x56017a,
142440x60000b,
142450x610034,
142460x620038,
142470x630038,
142480x640038,
142490x650038,
142500x660038,
142510x670038,
142520x68003a,
142530x690041,
142540x6a0048,
142550x6b0048,
142560x6c0048,
142570x6d0048,
142580x6e0048,
142590x6f0048,
142600x000006,
142610x000006,
142620x000006,
142630x000006,
142640x000006,
142650x000006,
142660x000006,
142670x000006,
142680x000006,
142690x000006,
142700x000006,
142710x000006,
142720x000006,
142730x000006,
142740x000006,
142750x000006,
142760x000006,
142770x000006,
142780x000006,
14279};
14280
14281static const u32 RS780_cp_microcode[][3] = {
14282 { 0x00000000, 0xc0200400, 0x000 },
14283 { 0x00000000, 0x00a0000a, 0x000 },
14284 { 0x0000ffff, 0x00284621, 0x000 },
14285 { 0x00000000, 0xd9004800, 0x000 },
14286 { 0x00000000, 0xc0200400, 0x000 },
14287 { 0x00000000, 0x00a0000a, 0x000 },
14288 { 0x00000000, 0x00e00000, 0x000 },
14289 { 0x00010000, 0xc0294620, 0x000 },
14290 { 0x00000000, 0xd9004800, 0x000 },
14291 { 0x00000000, 0xc0200400, 0x000 },
14292 { 0x00000000, 0x00a0000a, 0x000 },
14293 { 0x81000000, 0x00204411, 0x000 },
14294 { 0x00000001, 0x00204811, 0x000 },
14295 { 0x00042004, 0x00604411, 0x622 },
14296 { 0x00000000, 0x00600000, 0x5d1 },
14297 { 0x00000000, 0x00600000, 0x5de },
14298 { 0x00000000, 0xc0200800, 0x000 },
14299 { 0x00000f00, 0x00281622, 0x000 },
14300 { 0x00000008, 0x00211625, 0x000 },
14301 { 0x00000018, 0x00203625, 0x000 },
14302 { 0x8d000000, 0x00204411, 0x000 },
14303 { 0x00000004, 0x002f0225, 0x000 },
14304 { 0x00000000, 0x0ce00000, 0x018 },
14305 { 0x00412000, 0x00404811, 0x019 },
14306 { 0x00422000, 0x00204811, 0x000 },
14307 { 0x8e000000, 0x00204411, 0x000 },
14308 { 0x00000028, 0x00204a2d, 0x000 },
14309 { 0x90000000, 0x00204411, 0x000 },
14310 { 0x00000000, 0x00204805, 0x000 },
14311 { 0x0000000c, 0x00211622, 0x000 },
14312 { 0x00000003, 0x00281625, 0x000 },
14313 { 0x00000019, 0x00211a22, 0x000 },
14314 { 0x00000004, 0x00281a26, 0x000 },
14315 { 0x00000000, 0x002914c5, 0x000 },
14316 { 0x00000019, 0x00203625, 0x000 },
14317 { 0x00000000, 0x003a1402, 0x000 },
14318 { 0x00000016, 0x00211625, 0x000 },
14319 { 0x00000003, 0x00281625, 0x000 },
14320 { 0x00000017, 0x00200e2d, 0x000 },
14321 { 0xfffffffc, 0x00280e23, 0x000 },
14322 { 0x00000000, 0x002914a3, 0x000 },
14323 { 0x00000017, 0x00203625, 0x000 },
14324 { 0x00008000, 0x00280e22, 0x000 },
14325 { 0x00000007, 0x00220e23, 0x000 },
14326 { 0x00000000, 0x0029386e, 0x000 },
14327 { 0x20000000, 0x00280e22, 0x000 },
14328 { 0x00000006, 0x00210e23, 0x000 },
14329 { 0x00000000, 0x0029386e, 0x000 },
14330 { 0x00000000, 0x00220222, 0x000 },
14331 { 0x00000000, 0x14e00000, 0x038 },
14332 { 0x00000000, 0x2ee00000, 0x035 },
14333 { 0x00000000, 0x2ce00000, 0x037 },
14334 { 0x00000000, 0x00400e2d, 0x039 },
14335 { 0x00000008, 0x00200e2d, 0x000 },
14336 { 0x00000009, 0x0040122d, 0x046 },
14337 { 0x00000001, 0x00400e2d, 0x039 },
14338 { 0x00000000, 0xc0200c00, 0x000 },
14339 { 0x003ffffc, 0x00281223, 0x000 },
14340 { 0x00000002, 0x00221224, 0x000 },
14341 { 0x0000001f, 0x00211e23, 0x000 },
14342 { 0x00000000, 0x14e00000, 0x03e },
14343 { 0x00000008, 0x00401c11, 0x041 },
14344 { 0x0000000d, 0x00201e2d, 0x000 },
14345 { 0x0000000f, 0x00281e27, 0x000 },
14346 { 0x00000003, 0x00221e27, 0x000 },
14347 { 0x7fc00000, 0x00281a23, 0x000 },
14348 { 0x00000014, 0x00211a26, 0x000 },
14349 { 0x00000001, 0x00331a26, 0x000 },
14350 { 0x00000008, 0x00221a26, 0x000 },
14351 { 0x00000000, 0x00290cc7, 0x000 },
14352 { 0x00000027, 0x00203624, 0x000 },
14353 { 0x00007f00, 0x00281221, 0x000 },
14354 { 0x00001400, 0x002f0224, 0x000 },
14355 { 0x00000000, 0x0ce00000, 0x04b },
14356 { 0x00000001, 0x00290e23, 0x000 },
14357 { 0x0000000e, 0x00203623, 0x000 },
14358 { 0x0000e000, 0x00204411, 0x000 },
14359 { 0xfff80000, 0x00294a23, 0x000 },
14360 { 0x00000000, 0x003a2c02, 0x000 },
14361 { 0x00000002, 0x00220e2b, 0x000 },
14362 { 0xfc000000, 0x00280e23, 0x000 },
14363 { 0x0000000f, 0x00203623, 0x000 },
14364 { 0x00001fff, 0x00294a23, 0x000 },
14365 { 0x00000027, 0x00204a2d, 0x000 },
14366 { 0x00000000, 0x00204811, 0x000 },
14367 { 0x00000029, 0x00200e2d, 0x000 },
14368 { 0x060a0200, 0x00294a23, 0x000 },
14369 { 0x00000000, 0x00204811, 0x000 },
14370 { 0x00000000, 0x00204811, 0x000 },
14371 { 0x00000001, 0x00210222, 0x000 },
14372 { 0x00000000, 0x14e00000, 0x061 },
14373 { 0x00000000, 0x2ee00000, 0x05f },
14374 { 0x00000000, 0x2ce00000, 0x05e },
14375 { 0x00000000, 0x00400e2d, 0x062 },
14376 { 0x00000001, 0x00400e2d, 0x062 },
14377 { 0x0000000a, 0x00200e2d, 0x000 },
14378 { 0x0000000b, 0x0040122d, 0x06a },
14379 { 0x00000000, 0xc0200c00, 0x000 },
14380 { 0x003ffffc, 0x00281223, 0x000 },
14381 { 0x00000002, 0x00221224, 0x000 },
14382 { 0x7fc00000, 0x00281623, 0x000 },
14383 { 0x00000014, 0x00211625, 0x000 },
14384 { 0x00000001, 0x00331625, 0x000 },
14385 { 0x80000000, 0x00280e23, 0x000 },
14386 { 0x00000000, 0x00290ca3, 0x000 },
14387 { 0x3ffffc00, 0x00290e23, 0x000 },
14388 { 0x0000001f, 0x00211e23, 0x000 },
14389 { 0x00000000, 0x14e00000, 0x06d },
14390 { 0x00000100, 0x00401c11, 0x070 },
14391 { 0x0000000d, 0x00201e2d, 0x000 },
14392 { 0x000000f0, 0x00281e27, 0x000 },
14393 { 0x00000004, 0x00221e27, 0x000 },
14394 { 0x81000000, 0x00204411, 0x000 },
14395 { 0x0000000d, 0x00204811, 0x000 },
14396 { 0xfffff0ff, 0x00281a30, 0x000 },
14397 { 0x0000a028, 0x00204411, 0x000 },
14398 { 0x00000000, 0x002948e6, 0x000 },
14399 { 0x0000a018, 0x00204411, 0x000 },
14400 { 0x3fffffff, 0x00284a23, 0x000 },
14401 { 0x0000a010, 0x00204411, 0x000 },
14402 { 0x00000000, 0x00204804, 0x000 },
14403 { 0x00000030, 0x0020162d, 0x000 },
14404 { 0x00000002, 0x00291625, 0x000 },
14405 { 0x00000030, 0x00203625, 0x000 },
14406 { 0x00000025, 0x0020162d, 0x000 },
14407 { 0x00000000, 0x002f00a3, 0x000 },
14408 { 0x00000000, 0x0cc00000, 0x083 },
14409 { 0x00000026, 0x0020162d, 0x000 },
14410 { 0x00000000, 0x002f00a4, 0x000 },
14411 { 0x00000000, 0x0cc00000, 0x084 },
14412 { 0x00000000, 0x00400000, 0x08a },
14413 { 0x00000025, 0x00203623, 0x000 },
14414 { 0x00000026, 0x00203624, 0x000 },
14415 { 0x00000017, 0x00201e2d, 0x000 },
14416 { 0x00000002, 0x00210227, 0x000 },
14417 { 0x00000000, 0x14e00000, 0x08a },
14418 { 0x00000000, 0x00600000, 0x5ff },
14419 { 0x00000000, 0x00600000, 0x5f3 },
14420 { 0x00000002, 0x00210e22, 0x000 },
14421 { 0x00000000, 0x14c00000, 0x08d },
14422 { 0x00000012, 0xc0403620, 0x093 },
14423 { 0x00000000, 0x2ee00000, 0x091 },
14424 { 0x00000000, 0x2ce00000, 0x090 },
14425 { 0x00000002, 0x00400e2d, 0x092 },
14426 { 0x00000003, 0x00400e2d, 0x092 },
14427 { 0x0000000c, 0x00200e2d, 0x000 },
14428 { 0x00000012, 0x00203623, 0x000 },
14429 { 0x00000003, 0x00210e22, 0x000 },
14430 { 0x00000000, 0x14c00000, 0x098 },
14431 { 0x0000a00c, 0x00204411, 0x000 },
14432 { 0x00000000, 0xc0204800, 0x000 },
14433 { 0x00000000, 0xc0404800, 0x0a0 },
14434 { 0x0000a00c, 0x00204411, 0x000 },
14435 { 0x00000000, 0x00204811, 0x000 },
14436 { 0x00000000, 0x2ee00000, 0x09e },
14437 { 0x00000000, 0x2ce00000, 0x09d },
14438 { 0x00000002, 0x00400e2d, 0x09f },
14439 { 0x00000003, 0x00400e2d, 0x09f },
14440 { 0x0000000c, 0x00200e2d, 0x000 },
14441 { 0x00000000, 0x00204803, 0x000 },
14442 { 0x00000000, 0x003a0c02, 0x000 },
14443 { 0x003f0000, 0x00280e23, 0x000 },
14444 { 0x00000010, 0x00210e23, 0x000 },
14445 { 0x00000011, 0x00203623, 0x000 },
14446 { 0x0000001e, 0x0021022b, 0x000 },
14447 { 0x00000000, 0x14c00000, 0x0a7 },
14448 { 0x00000016, 0xc0203620, 0x000 },
14449 { 0x0000001f, 0x0021022b, 0x000 },
14450 { 0x00000000, 0x14c00000, 0x0aa },
14451 { 0x00000015, 0xc0203620, 0x000 },
14452 { 0x00000008, 0x00210e2b, 0x000 },
14453 { 0x0000007f, 0x00280e23, 0x000 },
14454 { 0x00000000, 0x002f0223, 0x000 },
14455 { 0x00000000, 0x0ce00000, 0x0e1 },
14456 { 0x00000000, 0x27000000, 0x000 },
14457 { 0x00000000, 0x00600000, 0x2a3 },
14458 { 0x00000001, 0x002f0223, 0x000 },
14459 { 0x00000000, 0x0ae00000, 0x0b3 },
14460 { 0x00000000, 0x00600000, 0x13a },
14461 { 0x81000000, 0x00204411, 0x000 },
14462 { 0x00000006, 0x00204811, 0x000 },
14463 { 0x0000000c, 0x00221e30, 0x000 },
14464 { 0x99800000, 0x00204411, 0x000 },
14465 { 0x00000004, 0x0020122d, 0x000 },
14466 { 0x00000008, 0x00221224, 0x000 },
14467 { 0x00000010, 0x00201811, 0x000 },
14468 { 0x00000000, 0x00291ce4, 0x000 },
14469 { 0x00000000, 0x00604807, 0x12f },
14470 { 0x9b000000, 0x00204411, 0x000 },
14471 { 0x00000000, 0x00204802, 0x000 },
14472 { 0x9c000000, 0x00204411, 0x000 },
14473 { 0x00000000, 0x0033146f, 0x000 },
14474 { 0x00000001, 0x00333e23, 0x000 },
14475 { 0x00000000, 0xd9004800, 0x000 },
14476 { 0x00000000, 0x00203c05, 0x000 },
14477 { 0x81000000, 0x00204411, 0x000 },
14478 { 0x0000000e, 0x00204811, 0x000 },
14479 { 0x00000000, 0x00201010, 0x000 },
14480 { 0x0000e007, 0x00204411, 0x000 },
14481 { 0x0000000f, 0x0021022b, 0x000 },
14482 { 0x00000000, 0x14c00000, 0x0cb },
14483 { 0x00f8ff08, 0x00204811, 0x000 },
14484 { 0x98000000, 0x00404811, 0x0dc },
14485 { 0x000000f0, 0x00280e22, 0x000 },
14486 { 0x000000a0, 0x002f0223, 0x000 },
14487 { 0x00000000, 0x0cc00000, 0x0da },
14488 { 0x00000011, 0x00200e2d, 0x000 },
14489 { 0x00000001, 0x002f0223, 0x000 },
14490 { 0x00000000, 0x0ce00000, 0x0d5 },
14491 { 0x00000002, 0x002f0223, 0x000 },
14492 { 0x00000000, 0x0ce00000, 0x0d4 },
14493 { 0x00003f00, 0x00400c11, 0x0d6 },
14494 { 0x00001f00, 0x00400c11, 0x0d6 },
14495 { 0x00000f00, 0x00200c11, 0x000 },
14496 { 0x00380009, 0x00294a23, 0x000 },
14497 { 0x3f000000, 0x00280e2b, 0x000 },
14498 { 0x00000002, 0x00220e23, 0x000 },
14499 { 0x00000007, 0x00494a23, 0x0dc },
14500 { 0x00380f09, 0x00204811, 0x000 },
14501 { 0x68000007, 0x00204811, 0x000 },
14502 { 0x00000008, 0x00214a27, 0x000 },
14503 { 0x00000000, 0x00204811, 0x000 },
14504 { 0x060a0200, 0x00294a24, 0x000 },
14505 { 0x00000000, 0x00204811, 0x000 },
14506 { 0x00000000, 0x00204811, 0x000 },
14507 { 0x0000a202, 0x00204411, 0x000 },
14508 { 0x00ff0000, 0x00280e22, 0x000 },
14509 { 0x00000080, 0x00294a23, 0x000 },
14510 { 0x00000027, 0x00200e2d, 0x000 },
14511 { 0x00000026, 0x0020122d, 0x000 },
14512 { 0x00000000, 0x002f0083, 0x000 },
14513 { 0x00000000, 0x0ce00000, 0x0ea },
14514 { 0x00000000, 0x00600000, 0x5f9 },
14515 { 0x00000000, 0x00400000, 0x0eb },
14516 { 0x00000000, 0x00600000, 0x5fc },
14517 { 0x00000007, 0x0020222d, 0x000 },
14518 { 0x00000005, 0x00220e22, 0x000 },
14519 { 0x00100000, 0x00280e23, 0x000 },
14520 { 0x00000000, 0x00292068, 0x000 },
14521 { 0x00000000, 0x003a0c02, 0x000 },
14522 { 0x000000ef, 0x00280e23, 0x000 },
14523 { 0x00000000, 0x00292068, 0x000 },
14524 { 0x00000017, 0x00200e2d, 0x000 },
14525 { 0x00000003, 0x00210223, 0x000 },
14526 { 0x00000000, 0x14e00000, 0x0f8 },
14527 { 0x0000000b, 0x00210228, 0x000 },
14528 { 0x00000000, 0x14c00000, 0x0f8 },
14529 { 0x00000400, 0x00292228, 0x000 },
14530 { 0x00000014, 0x00203628, 0x000 },
14531 { 0x0000001c, 0x00210e22, 0x000 },
14532 { 0x00000000, 0x14c00000, 0x0fd },
14533 { 0x0000a30c, 0x00204411, 0x000 },
14534 { 0x00000000, 0x00204811, 0x000 },
14535 { 0x0000001e, 0x00210e22, 0x000 },
14536 { 0x00000000, 0x14c00000, 0x10b },
14537 { 0x0000a30f, 0x00204411, 0x000 },
14538 { 0x00000011, 0x00200e2d, 0x000 },
14539 { 0x00000001, 0x002f0223, 0x000 },
14540 { 0x00000000, 0x0cc00000, 0x104 },
14541 { 0xffffffff, 0x00404811, 0x10b },
14542 { 0x00000002, 0x002f0223, 0x000 },
14543 { 0x00000000, 0x0cc00000, 0x107 },
14544 { 0x0000ffff, 0x00404811, 0x10b },
14545 { 0x00000004, 0x002f0223, 0x000 },
14546 { 0x00000000, 0x0cc00000, 0x10a },
14547 { 0x000000ff, 0x00404811, 0x10b },
14548 { 0x00000001, 0x00204811, 0x000 },
14549 { 0x0002c400, 0x00204411, 0x000 },
14550 { 0x0000001f, 0x00210e22, 0x000 },
14551 { 0x00000000, 0x14c00000, 0x112 },
14552 { 0x00000010, 0x40210e20, 0x000 },
14553 { 0x00000013, 0x00203623, 0x000 },
14554 { 0x00000018, 0x40224a20, 0x000 },
14555 { 0x00000010, 0xc0424a20, 0x114 },
14556 { 0x00000000, 0x00200c11, 0x000 },
14557 { 0x00000013, 0x00203623, 0x000 },
14558 { 0x00000000, 0x00204811, 0x000 },
14559 { 0x00000000, 0x00204811, 0x000 },
14560 { 0x0000000a, 0x00201011, 0x000 },
14561 { 0x00000000, 0x002f0224, 0x000 },
14562 { 0x00000000, 0x0ce00000, 0x11b },
14563 { 0x00000000, 0x00204811, 0x000 },
14564 { 0x00000001, 0x00531224, 0x117 },
14565 { 0xffbfffff, 0x00283a2e, 0x000 },
14566 { 0x0000001b, 0x00210222, 0x000 },
14567 { 0x00000000, 0x14c00000, 0x12e },
14568 { 0x81000000, 0x00204411, 0x000 },
14569 { 0x0000000d, 0x00204811, 0x000 },
14570 { 0x00000018, 0x00220e30, 0x000 },
14571 { 0xfc000000, 0x00280e23, 0x000 },
14572 { 0x81000000, 0x00204411, 0x000 },
14573 { 0x0000000e, 0x00204811, 0x000 },
14574 { 0x00000000, 0x00201010, 0x000 },
14575 { 0x0000e00e, 0x00204411, 0x000 },
14576 { 0x07f8ff08, 0x00204811, 0x000 },
14577 { 0x00000000, 0x00294a23, 0x000 },
14578 { 0x0000001c, 0x00201e2d, 0x000 },
14579 { 0x00000008, 0x00214a27, 0x000 },
14580 { 0x00000000, 0x00204811, 0x000 },
14581 { 0x060a0200, 0x00294a24, 0x000 },
14582 { 0x00000000, 0x00204811, 0x000 },
14583 { 0x00000000, 0x00204811, 0x000 },
14584 { 0x00000000, 0x00800000, 0x000 },
14585 { 0x81000000, 0x00204411, 0x000 },
14586 { 0x00000001, 0x00204811, 0x000 },
14587 { 0x0000217c, 0x00204411, 0x000 },
14588 { 0x00800000, 0x00204811, 0x000 },
14589 { 0x00000000, 0x00204806, 0x000 },
14590 { 0x00000008, 0x00214a27, 0x000 },
14591 { 0x00000000, 0x17000000, 0x000 },
14592 { 0x0004217f, 0x00604411, 0x622 },
14593 { 0x0000001f, 0x00210230, 0x000 },
14594 { 0x00000000, 0x14c00000, 0x621 },
14595 { 0x00000004, 0x00404c11, 0x135 },
14596 { 0x81000000, 0x00204411, 0x000 },
14597 { 0x00000001, 0x00204811, 0x000 },
14598 { 0x000021f8, 0x00204411, 0x000 },
14599 { 0x0000001c, 0x00204811, 0x000 },
14600 { 0x000421f9, 0x00604411, 0x622 },
14601 { 0x00000011, 0x00210230, 0x000 },
14602 { 0x00000000, 0x14e00000, 0x13c },
14603 { 0x00000000, 0x00800000, 0x000 },
14604 { 0x00000000, 0x00600000, 0x00b },
14605 { 0x00000000, 0x00600411, 0x315 },
14606 { 0x00000000, 0x00200411, 0x000 },
14607 { 0x00000000, 0x00600811, 0x1b2 },
14608 { 0x00000000, 0x00600000, 0x160 },
14609 { 0x0000ffff, 0x40280e20, 0x000 },
14610 { 0x00000010, 0xc0211220, 0x000 },
14611 { 0x0000ffff, 0x40280620, 0x000 },
14612 { 0x00000010, 0xc0210a20, 0x000 },
14613 { 0x00000000, 0x00341461, 0x000 },
14614 { 0x00000000, 0x00741882, 0x2bb },
14615 { 0x0001a1fd, 0x00604411, 0x2e0 },
14616 { 0x00003fff, 0x002f022f, 0x000 },
14617 { 0x00000000, 0x0cc00000, 0x147 },
14618 { 0x00000000, 0xc0400400, 0x001 },
14619 { 0x00000000, 0x00600000, 0x00b },
14620 { 0x00000000, 0x00600411, 0x315 },
14621 { 0x00000000, 0x00200411, 0x000 },
14622 { 0x00000000, 0x00600811, 0x1b2 },
14623 { 0x00003fff, 0x002f022f, 0x000 },
14624 { 0x00000000, 0x0ce00000, 0x000 },
14625 { 0x00000000, 0x00600000, 0x160 },
14626 { 0x00000010, 0x40210e20, 0x000 },
14627 { 0x0000ffff, 0xc0281220, 0x000 },
14628 { 0x00000010, 0x40211620, 0x000 },
14629 { 0x0000ffff, 0xc0681a20, 0x2bb },
14630 { 0x0001a1fd, 0x00604411, 0x2e0 },
14631 { 0x00003fff, 0x002f022f, 0x000 },
14632 { 0x00000000, 0x0cc00000, 0x158 },
14633 { 0x00000000, 0xc0400400, 0x001 },
14634 { 0x0000225c, 0x00204411, 0x000 },
14635 { 0x00000001, 0x00300a2f, 0x000 },
14636 { 0x00000001, 0x00210a22, 0x000 },
14637 { 0x00000003, 0x00384a22, 0x000 },
14638 { 0x00002256, 0x00204411, 0x000 },
14639 { 0x0000001a, 0x00204811, 0x000 },
14640 { 0x0000a1fc, 0x00204411, 0x000 },
14641 { 0x00000001, 0x00804811, 0x000 },
14642 { 0x00000000, 0x00600000, 0x00b },
14643 { 0x00000000, 0x00600000, 0x18f },
14644 { 0x00000000, 0x00600000, 0x1a0 },
14645 { 0x00003fff, 0x002f022f, 0x000 },
14646 { 0x00000000, 0x0ce00000, 0x000 },
14647 { 0x00000000, 0x00202c08, 0x000 },
14648 { 0x00000000, 0x00202411, 0x000 },
14649 { 0x00000000, 0x00202811, 0x000 },
14650 { 0x00002256, 0x00204411, 0x000 },
14651 { 0x00000016, 0x00204811, 0x000 },
14652 { 0x0000225c, 0x00204411, 0x000 },
14653 { 0x00000003, 0x00204811, 0x000 },
14654 { 0x93800000, 0x00204411, 0x000 },
14655 { 0x00000002, 0x00221e29, 0x000 },
14656 { 0x00000000, 0x007048eb, 0x19c },
14657 { 0x00000000, 0x00600000, 0x2bb },
14658 { 0x00000001, 0x40330620, 0x000 },
14659 { 0x00000000, 0xc0302409, 0x000 },
14660 { 0x00003fff, 0x002f022f, 0x000 },
14661 { 0x00000000, 0x0ce00000, 0x000 },
14662 { 0x00000000, 0x00600000, 0x2a3 },
14663 { 0x00000000, 0x002f0221, 0x000 },
14664 { 0x00000000, 0x0ae00000, 0x181 },
14665 { 0x00000000, 0x00600000, 0x13a },
14666 { 0x00000000, 0x00400000, 0x186 },
14667 { 0x95000000, 0x00204411, 0x000 },
14668 { 0x00000000, 0x002f0221, 0x000 },
14669 { 0x00000000, 0x0ce00000, 0x186 },
14670 { 0x00000000, 0xc0204800, 0x000 },
14671 { 0x00000001, 0x00530621, 0x182 },
14672 { 0x92000000, 0x00204411, 0x000 },
14673 { 0x00000000, 0xc0604800, 0x197 },
14674 { 0x0001a1fd, 0x00204411, 0x000 },
14675 { 0x00000011, 0x0020062d, 0x000 },
14676 { 0x00000000, 0x0078042a, 0x2fb },
14677 { 0x00000000, 0x00202809, 0x000 },
14678 { 0x00003fff, 0x002f022f, 0x000 },
14679 { 0x00000000, 0x0cc00000, 0x174 },
14680 { 0x00000000, 0xc0400400, 0x001 },
14681 { 0x00000210, 0x00600411, 0x315 },
14682 { 0x00003fff, 0x002f022f, 0x000 },
14683 { 0x00000000, 0x0ce00000, 0x194 },
14684 { 0x00000015, 0xc0203620, 0x000 },
14685 { 0x00000016, 0xc0203620, 0x000 },
14686 { 0x3f800000, 0x00200411, 0x000 },
14687 { 0x46000000, 0x00600811, 0x1b2 },
14688 { 0x00000000, 0x00800000, 0x000 },
14689 { 0x0000a1fc, 0x00204411, 0x000 },
14690 { 0x00003fff, 0x002f022f, 0x000 },
14691 { 0x00000000, 0x0cc00000, 0x19b },
14692 { 0x00000001, 0x00804811, 0x000 },
14693 { 0x00000021, 0x00804811, 0x000 },
14694 { 0x0000ffff, 0x40280e20, 0x000 },
14695 { 0x00000010, 0xc0211220, 0x000 },
14696 { 0x0000ffff, 0x40281620, 0x000 },
14697 { 0x00000010, 0xc0811a20, 0x000 },
14698 { 0x81000000, 0x00204411, 0x000 },
14699 { 0x00000006, 0x00204811, 0x000 },
14700 { 0x00000008, 0x00221e30, 0x000 },
14701 { 0x00000029, 0x00201a2d, 0x000 },
14702 { 0x0000e000, 0x00204411, 0x000 },
14703 { 0xfffbff09, 0x00204811, 0x000 },
14704 { 0x0000000f, 0x0020222d, 0x000 },
14705 { 0x00001fff, 0x00294a28, 0x000 },
14706 { 0x00000006, 0x0020222d, 0x000 },
14707 { 0x00000000, 0x002920e8, 0x000 },
14708 { 0x00000000, 0x00204808, 0x000 },
14709 { 0x00000000, 0x00204811, 0x000 },
14710 { 0x060a0200, 0x00294a26, 0x000 },
14711 { 0x00000000, 0x00204811, 0x000 },
14712 { 0x00000000, 0x00204811, 0x000 },
14713 { 0x00000100, 0x00201811, 0x000 },
14714 { 0x00000008, 0x00621e28, 0x12f },
14715 { 0x00000008, 0x00822228, 0x000 },
14716 { 0x0002c000, 0x00204411, 0x000 },
14717 { 0x00000015, 0x00600e2d, 0x1bd },
14718 { 0x00000016, 0x00600e2d, 0x1bd },
14719 { 0x0000c008, 0x00204411, 0x000 },
14720 { 0x00000017, 0x00200e2d, 0x000 },
14721 { 0x00000000, 0x14c00000, 0x1b9 },
14722 { 0x00000000, 0x00200411, 0x000 },
14723 { 0x00000000, 0x00204801, 0x000 },
14724 { 0x39000000, 0x00204811, 0x000 },
14725 { 0x00000000, 0x00204811, 0x000 },
14726 { 0x00000000, 0x00804802, 0x000 },
14727 { 0x00000018, 0x00202e2d, 0x000 },
14728 { 0x00000000, 0x003b0d63, 0x000 },
14729 { 0x00000008, 0x00224a23, 0x000 },
14730 { 0x00000010, 0x00224a23, 0x000 },
14731 { 0x00000018, 0x00224a23, 0x000 },
14732 { 0x00000000, 0x00804803, 0x000 },
14733 { 0x00000000, 0x00600000, 0x00b },
14734 { 0x00001000, 0x00600411, 0x315 },
14735 { 0x00000000, 0x00200411, 0x000 },
14736 { 0x00000000, 0x00600811, 0x1b2 },
14737 { 0x00000007, 0x0021062f, 0x000 },
14738 { 0x00000013, 0x00200a2d, 0x000 },
14739 { 0x00000001, 0x00202c11, 0x000 },
14740 { 0x0000ffff, 0x40282220, 0x000 },
14741 { 0x0000000f, 0x00262228, 0x000 },
14742 { 0x00000010, 0x40212620, 0x000 },
14743 { 0x0000000f, 0x00262629, 0x000 },
14744 { 0x00000000, 0x00202802, 0x000 },
14745 { 0x00002256, 0x00204411, 0x000 },
14746 { 0x0000001b, 0x00204811, 0x000 },
14747 { 0x00000000, 0x002f0221, 0x000 },
14748 { 0x00000000, 0x0ce00000, 0x1e0 },
14749 { 0x0000225c, 0x00204411, 0x000 },
14750 { 0x00000081, 0x00204811, 0x000 },
14751 { 0x0000a1fc, 0x00204411, 0x000 },
14752 { 0x00000001, 0x00204811, 0x000 },
14753 { 0x00000080, 0x00201c11, 0x000 },
14754 { 0x00000000, 0x002f0227, 0x000 },
14755 { 0x00000000, 0x0ce00000, 0x1dc },
14756 { 0x00000000, 0x00600000, 0x1e9 },
14757 { 0x00000001, 0x00531e27, 0x1d8 },
14758 { 0x00000001, 0x00202c11, 0x000 },
14759 { 0x0000001f, 0x00280a22, 0x000 },
14760 { 0x0000001f, 0x00282a2a, 0x000 },
14761 { 0x00000001, 0x00530621, 0x1d1 },
14762 { 0x0000225c, 0x00204411, 0x000 },
14763 { 0x00000002, 0x00304a2f, 0x000 },
14764 { 0x0000a1fc, 0x00204411, 0x000 },
14765 { 0x00000001, 0x00204811, 0x000 },
14766 { 0x00000001, 0x00301e2f, 0x000 },
14767 { 0x00000000, 0x002f0227, 0x000 },
14768 { 0x00000000, 0x0ce00000, 0x000 },
14769 { 0x00000000, 0x00600000, 0x1e9 },
14770 { 0x00000001, 0x00531e27, 0x1e5 },
14771 { 0x0000ffff, 0x40280e20, 0x000 },
14772 { 0x0000000f, 0x00260e23, 0x000 },
14773 { 0x00000010, 0xc0211220, 0x000 },
14774 { 0x0000000f, 0x00261224, 0x000 },
14775 { 0x00000000, 0x00201411, 0x000 },
14776 { 0x00000000, 0x00601811, 0x2bb },
14777 { 0x0001a1fd, 0x00204411, 0x000 },
14778 { 0x00000000, 0x002f022b, 0x000 },
14779 { 0x00000000, 0x0ce00000, 0x1f8 },
14780 { 0x00000010, 0x00221628, 0x000 },
14781 { 0xffff0000, 0x00281625, 0x000 },
14782 { 0x0000ffff, 0x00281a29, 0x000 },
14783 { 0x00000000, 0x002948c5, 0x000 },
14784 { 0x00000000, 0x0020480a, 0x000 },
14785 { 0x00000000, 0x00202c11, 0x000 },
14786 { 0x00000010, 0x00221623, 0x000 },
14787 { 0xffff0000, 0x00281625, 0x000 },
14788 { 0x0000ffff, 0x00281a24, 0x000 },
14789 { 0x00000000, 0x002948c5, 0x000 },
14790 { 0x00000000, 0x00731503, 0x205 },
14791 { 0x00000000, 0x00201805, 0x000 },
14792 { 0x00000000, 0x00731524, 0x205 },
14793 { 0x00000000, 0x002d14c5, 0x000 },
14794 { 0x00000000, 0x003008a2, 0x000 },
14795 { 0x00000000, 0x00204802, 0x000 },
14796 { 0x00000000, 0x00202802, 0x000 },
14797 { 0x00000000, 0x00202003, 0x000 },
14798 { 0x00000000, 0x00802404, 0x000 },
14799 { 0x0000000f, 0x00210225, 0x000 },
14800 { 0x00000000, 0x14c00000, 0x621 },
14801 { 0x00000000, 0x002b1405, 0x000 },
14802 { 0x00000001, 0x00901625, 0x000 },
14803 { 0x00000000, 0x00600000, 0x00b },
14804 { 0x00000000, 0x00600411, 0x315 },
14805 { 0x00000000, 0x00200411, 0x000 },
14806 { 0x00000000, 0x00600811, 0x1b2 },
14807 { 0x00002256, 0x00204411, 0x000 },
14808 { 0x0000001a, 0x00294a22, 0x000 },
14809 { 0x00000000, 0xc0200000, 0x000 },
14810 { 0x00003fff, 0x002f022f, 0x000 },
14811 { 0x00000000, 0x0ce00000, 0x000 },
14812 { 0x00000000, 0xc0200400, 0x000 },
14813 { 0x0000225c, 0x00204411, 0x000 },
14814 { 0x00000003, 0x00384a21, 0x000 },
14815 { 0x0000a1fc, 0x00204411, 0x000 },
14816 { 0x00000001, 0x00204811, 0x000 },
14817 { 0x0000ffff, 0x40281220, 0x000 },
14818 { 0x00000010, 0xc0211a20, 0x000 },
14819 { 0x0000ffff, 0x40280e20, 0x000 },
14820 { 0x00000010, 0xc0211620, 0x000 },
14821 { 0x00000000, 0x00741465, 0x2bb },
14822 { 0x0001a1fd, 0x00604411, 0x2e0 },
14823 { 0x00000001, 0x00330621, 0x000 },
14824 { 0x00000000, 0x002f0221, 0x000 },
14825 { 0x00000000, 0x0cc00000, 0x219 },
14826 { 0x00003fff, 0x002f022f, 0x000 },
14827 { 0x00000000, 0x0cc00000, 0x212 },
14828 { 0x00000000, 0xc0400400, 0x001 },
14829 { 0x00000000, 0x00600000, 0x5de },
14830 { 0x00000000, 0x0040040f, 0x213 },
14831 { 0x00000000, 0x00600000, 0x5d1 },
14832 { 0x00000000, 0x00600000, 0x5de },
14833 { 0x00000210, 0x00600411, 0x315 },
14834 { 0x00000000, 0x00600000, 0x1a0 },
14835 { 0x00000000, 0x00600000, 0x19c },
14836 { 0x00000000, 0x00600000, 0x2bb },
14837 { 0x00000000, 0x00600000, 0x2a3 },
14838 { 0x93800000, 0x00204411, 0x000 },
14839 { 0x00000000, 0x00204808, 0x000 },
14840 { 0x00000000, 0x002f022f, 0x000 },
14841 { 0x00000000, 0x0ae00000, 0x232 },
14842 { 0x00000000, 0x00600000, 0x13a },
14843 { 0x00000000, 0x00400000, 0x236 },
14844 { 0x95000000, 0x00204411, 0x000 },
14845 { 0x00000000, 0x002f022f, 0x000 },
14846 { 0x00000000, 0x0ce00000, 0x236 },
14847 { 0x00000000, 0xc0404800, 0x233 },
14848 { 0x92000000, 0x00204411, 0x000 },
14849 { 0x00000000, 0xc0204800, 0x000 },
14850 { 0x00002256, 0x00204411, 0x000 },
14851 { 0x00000016, 0x00204811, 0x000 },
14852 { 0x0000225c, 0x00204411, 0x000 },
14853 { 0x00000003, 0x00204811, 0x000 },
14854 { 0x0000a1fc, 0x00204411, 0x000 },
14855 { 0x00000001, 0x00204811, 0x000 },
14856 { 0x0001a1fd, 0x00204411, 0x000 },
14857 { 0x00000000, 0x00600411, 0x2fb },
14858 { 0x00000000, 0xc0400400, 0x001 },
14859 { 0x00000000, 0x00600000, 0x5d1 },
14860 { 0x0000a00c, 0x00204411, 0x000 },
14861 { 0x00000000, 0xc0204800, 0x000 },
14862 { 0x00000000, 0xc0404800, 0x000 },
14863 { 0x00000000, 0x00600000, 0x00b },
14864 { 0x00000018, 0x40210a20, 0x000 },
14865 { 0x00000003, 0x002f0222, 0x000 },
14866 { 0x00000000, 0x0ae00000, 0x24c },
14867 { 0x00000014, 0x0020222d, 0x000 },
14868 { 0x00080101, 0x00292228, 0x000 },
14869 { 0x00000014, 0x00203628, 0x000 },
14870 { 0x0000a30c, 0x00204411, 0x000 },
14871 { 0x00000000, 0xc0204800, 0x000 },
14872 { 0x00000000, 0xc0204800, 0x000 },
14873 { 0x00000000, 0xc0404800, 0x251 },
14874 { 0x00000000, 0x00600000, 0x00b },
14875 { 0x00000010, 0x00600411, 0x315 },
14876 { 0x3f800000, 0x00200411, 0x000 },
14877 { 0x00000000, 0x00600811, 0x1b2 },
14878 { 0x0000225c, 0x00204411, 0x000 },
14879 { 0x00000003, 0x00204811, 0x000 },
14880 { 0x00000000, 0x00600000, 0x27c },
14881 { 0x00000017, 0x00201e2d, 0x000 },
14882 { 0x00000001, 0x00211e27, 0x000 },
14883 { 0x00000000, 0x14e00000, 0x26a },
14884 { 0x00000012, 0x00201e2d, 0x000 },
14885 { 0x0000ffff, 0x00281e27, 0x000 },
14886 { 0x00000000, 0x00341c27, 0x000 },
14887 { 0x00000000, 0x12c00000, 0x25f },
14888 { 0x00000000, 0x00201c11, 0x000 },
14889 { 0x00000000, 0x002f00e5, 0x000 },
14890 { 0x00000000, 0x08c00000, 0x262 },
14891 { 0x00000000, 0x00201407, 0x000 },
14892 { 0x00000012, 0x00201e2d, 0x000 },
14893 { 0x00000010, 0x00211e27, 0x000 },
14894 { 0x00000000, 0x00341c47, 0x000 },
14895 { 0x00000000, 0x12c00000, 0x267 },
14896 { 0x00000000, 0x00201c11, 0x000 },
14897 { 0x00000000, 0x002f00e6, 0x000 },
14898 { 0x00000000, 0x08c00000, 0x26a },
14899 { 0x00000000, 0x00201807, 0x000 },
14900 { 0x00000000, 0x00600000, 0x2c1 },
14901 { 0x00002256, 0x00204411, 0x000 },
14902 { 0x00000000, 0x00342023, 0x000 },
14903 { 0x00000000, 0x12c00000, 0x272 },
14904 { 0x00000000, 0x00342044, 0x000 },
14905 { 0x00000000, 0x12c00000, 0x271 },
14906 { 0x00000016, 0x00404811, 0x276 },
14907 { 0x00000018, 0x00404811, 0x276 },
14908 { 0x00000000, 0x00342044, 0x000 },
14909 { 0x00000000, 0x12c00000, 0x275 },
14910 { 0x00000017, 0x00404811, 0x276 },
14911 { 0x00000019, 0x00204811, 0x000 },
14912 { 0x0000a1fc, 0x00204411, 0x000 },
14913 { 0x00000001, 0x00204811, 0x000 },
14914 { 0x0001a1fd, 0x00604411, 0x2e9 },
14915 { 0x00003fff, 0x002f022f, 0x000 },
14916 { 0x00000000, 0x0cc00000, 0x256 },
14917 { 0x00000000, 0xc0400400, 0x001 },
14918 { 0x00000010, 0x40210620, 0x000 },
14919 { 0x0000ffff, 0xc0280a20, 0x000 },
14920 { 0x00000010, 0x40210e20, 0x000 },
14921 { 0x0000ffff, 0xc0281220, 0x000 },
14922 { 0x00000010, 0x40211620, 0x000 },
14923 { 0x0000ffff, 0xc0881a20, 0x000 },
14924 { 0x81000000, 0x00204411, 0x000 },
14925 { 0x00000001, 0x00204811, 0x000 },
14926 { 0x00042004, 0x00604411, 0x622 },
14927 { 0x00000000, 0x00600000, 0x5d1 },
14928 { 0x00000000, 0xc0600000, 0x2a3 },
14929 { 0x00000005, 0x00200a2d, 0x000 },
14930 { 0x00000008, 0x00220a22, 0x000 },
14931 { 0x0000002b, 0x00201a2d, 0x000 },
14932 { 0x0000001c, 0x00201e2d, 0x000 },
14933 { 0x00007000, 0x00281e27, 0x000 },
14934 { 0x00000000, 0x00311ce6, 0x000 },
14935 { 0x0000002a, 0x00201a2d, 0x000 },
14936 { 0x0000000c, 0x00221a26, 0x000 },
14937 { 0x00000000, 0x002f00e6, 0x000 },
14938 { 0x00000000, 0x06e00000, 0x292 },
14939 { 0x00000000, 0x00201c11, 0x000 },
14940 { 0x00000000, 0x00200c11, 0x000 },
14941 { 0x0000002b, 0x00203623, 0x000 },
14942 { 0x00000010, 0x00201811, 0x000 },
14943 { 0x00000000, 0x00691ce2, 0x12f },
14944 { 0x93800000, 0x00204411, 0x000 },
14945 { 0x00000000, 0x00204807, 0x000 },
14946 { 0x95000000, 0x00204411, 0x000 },
14947 { 0x00000000, 0x002f022f, 0x000 },
14948 { 0x00000000, 0x0ce00000, 0x29d },
14949 { 0x00000001, 0x00333e2f, 0x000 },
14950 { 0x00000000, 0xd9004800, 0x000 },
14951 { 0x92000000, 0x00204411, 0x000 },
14952 { 0x00000000, 0xc0204800, 0x000 },
14953 { 0x0000001c, 0x00403627, 0x000 },
14954 { 0x0000000c, 0xc0220a20, 0x000 },
14955 { 0x00000029, 0x00203622, 0x000 },
14956 { 0x00000028, 0xc0403620, 0x000 },
14957 { 0x0000a2a4, 0x00204411, 0x000 },
14958 { 0x00000009, 0x00204811, 0x000 },
14959 { 0xa1000000, 0x00204411, 0x000 },
14960 { 0x00000001, 0x00804811, 0x000 },
14961 { 0x00000021, 0x00201e2d, 0x000 },
14962 { 0x00000000, 0x002c1ce3, 0x000 },
14963 { 0x00000021, 0x00203627, 0x000 },
14964 { 0x00000022, 0x00201e2d, 0x000 },
14965 { 0x00000000, 0x002c1ce4, 0x000 },
14966 { 0x00000022, 0x00203627, 0x000 },
14967 { 0x00000023, 0x00201e2d, 0x000 },
14968 { 0x00000000, 0x003120a3, 0x000 },
14969 { 0x00000000, 0x002d1d07, 0x000 },
14970 { 0x00000023, 0x00203627, 0x000 },
14971 { 0x00000024, 0x00201e2d, 0x000 },
14972 { 0x00000000, 0x003120c4, 0x000 },
14973 { 0x00000000, 0x002d1d07, 0x000 },
14974 { 0x00000024, 0x00803627, 0x000 },
14975 { 0x00000021, 0x00203623, 0x000 },
14976 { 0x00000022, 0x00203624, 0x000 },
14977 { 0x00000000, 0x00311ca3, 0x000 },
14978 { 0x00000023, 0x00203627, 0x000 },
14979 { 0x00000000, 0x00311cc4, 0x000 },
14980 { 0x00000024, 0x00803627, 0x000 },
14981 { 0x0000001a, 0x00203627, 0x000 },
14982 { 0x0000001b, 0x00203628, 0x000 },
14983 { 0x00000017, 0x00201e2d, 0x000 },
14984 { 0x00000002, 0x00210227, 0x000 },
14985 { 0x00000000, 0x14c00000, 0x2dc },
14986 { 0x00000000, 0x00400000, 0x2d9 },
14987 { 0x0000001a, 0x00203627, 0x000 },
14988 { 0x0000001b, 0x00203628, 0x000 },
14989 { 0x00000017, 0x00201e2d, 0x000 },
14990 { 0x00000002, 0x00210227, 0x000 },
14991 { 0x00000000, 0x14e00000, 0x2d9 },
14992 { 0x00000003, 0x00210227, 0x000 },
14993 { 0x00000000, 0x14e00000, 0x2dc },
14994 { 0x00000023, 0x00201e2d, 0x000 },
14995 { 0x00000000, 0x002e00e1, 0x000 },
14996 { 0x00000000, 0x02c00000, 0x2dc },
14997 { 0x00000021, 0x00201e2d, 0x000 },
14998 { 0x00000000, 0x003120a1, 0x000 },
14999 { 0x00000000, 0x002e00e8, 0x000 },
15000 { 0x00000000, 0x06c00000, 0x2dc },
15001 { 0x00000024, 0x00201e2d, 0x000 },
15002 { 0x00000000, 0x002e00e2, 0x000 },
15003 { 0x00000000, 0x02c00000, 0x2dc },
15004 { 0x00000022, 0x00201e2d, 0x000 },
15005 { 0x00000000, 0x003120c2, 0x000 },
15006 { 0x00000000, 0x002e00e8, 0x000 },
15007 { 0x00000000, 0x06c00000, 0x2dc },
15008 { 0x00000000, 0x00600000, 0x5ff },
15009 { 0x00000000, 0x00600000, 0x2b5 },
15010 { 0x00000000, 0x00400000, 0x2de },
15011 { 0x00000000, 0x00600000, 0x2b5 },
15012 { 0x00000000, 0x00600000, 0x5f6 },
15013 { 0x00000000, 0x00400000, 0x2de },
15014 { 0x00000000, 0x00600000, 0x2a7 },
15015 { 0x00000000, 0x00400000, 0x2de },
15016 { 0x0000001a, 0x00201e2d, 0x000 },
15017 { 0x0000001b, 0x0080222d, 0x000 },
15018 { 0x00000010, 0x00221e23, 0x000 },
15019 { 0x00000000, 0x00294887, 0x000 },
15020 { 0x00000000, 0x00311ca3, 0x000 },
15021 { 0x00000010, 0x00221e27, 0x000 },
15022 { 0x00000000, 0x00294887, 0x000 },
15023 { 0x00000010, 0x00221e23, 0x000 },
15024 { 0x00000000, 0x003120c4, 0x000 },
15025 { 0x0000ffff, 0x00282228, 0x000 },
15026 { 0x00000000, 0x00894907, 0x000 },
15027 { 0x00000010, 0x00221e23, 0x000 },
15028 { 0x00000000, 0x00294887, 0x000 },
15029 { 0x00000010, 0x00221e21, 0x000 },
15030 { 0x00000000, 0x00294847, 0x000 },
15031 { 0x00000000, 0x00311ca3, 0x000 },
15032 { 0x00000010, 0x00221e27, 0x000 },
15033 { 0x00000000, 0x00294887, 0x000 },
15034 { 0x00000000, 0x00311ca1, 0x000 },
15035 { 0x00000010, 0x00221e27, 0x000 },
15036 { 0x00000000, 0x00294847, 0x000 },
15037 { 0x00000010, 0x00221e23, 0x000 },
15038 { 0x00000000, 0x003120c4, 0x000 },
15039 { 0x0000ffff, 0x00282228, 0x000 },
15040 { 0x00000000, 0x00294907, 0x000 },
15041 { 0x00000010, 0x00221e21, 0x000 },
15042 { 0x00000000, 0x003120c2, 0x000 },
15043 { 0x0000ffff, 0x00282228, 0x000 },
15044 { 0x00000000, 0x00894907, 0x000 },
15045 { 0x00000010, 0x00221e23, 0x000 },
15046 { 0x00000000, 0x00294887, 0x000 },
15047 { 0x00000001, 0x00220a21, 0x000 },
15048 { 0x00000000, 0x003308a2, 0x000 },
15049 { 0x00000010, 0x00221e22, 0x000 },
15050 { 0x00000010, 0x00212222, 0x000 },
15051 { 0x00000000, 0x00294907, 0x000 },
15052 { 0x00000000, 0x00311ca3, 0x000 },
15053 { 0x00000010, 0x00221e27, 0x000 },
15054 { 0x00000000, 0x00294887, 0x000 },
15055 { 0x00000001, 0x00220a21, 0x000 },
15056 { 0x00000000, 0x003008a2, 0x000 },
15057 { 0x00000010, 0x00221e22, 0x000 },
15058 { 0x00000010, 0x00212222, 0x000 },
15059 { 0x00000000, 0x00294907, 0x000 },
15060 { 0x00000010, 0x00221e23, 0x000 },
15061 { 0x00000000, 0x003120c4, 0x000 },
15062 { 0x0000ffff, 0x00282228, 0x000 },
15063 { 0x00000000, 0x00294907, 0x000 },
15064 { 0x00000000, 0x003808c5, 0x000 },
15065 { 0x00000000, 0x00300841, 0x000 },
15066 { 0x00000001, 0x00220a22, 0x000 },
15067 { 0x00000000, 0x003308a2, 0x000 },
15068 { 0x00000010, 0x00221e22, 0x000 },
15069 { 0x00000010, 0x00212222, 0x000 },
15070 { 0x00000000, 0x00894907, 0x000 },
15071 { 0x00000017, 0x0020222d, 0x000 },
15072 { 0x00000000, 0x14c00000, 0x318 },
15073 { 0xffffffef, 0x00280621, 0x000 },
15074 { 0x00000014, 0x0020222d, 0x000 },
15075 { 0x0000f8e0, 0x00204411, 0x000 },
15076 { 0x00000000, 0x00294901, 0x000 },
15077 { 0x00000000, 0x00894901, 0x000 },
15078 { 0x00000000, 0x00204811, 0x000 },
15079 { 0x00000000, 0x00204811, 0x000 },
15080 { 0x060a0200, 0x00804811, 0x000 },
15081 { 0x00000000, 0xc0200000, 0x000 },
15082 { 0x97000000, 0xc0204411, 0x000 },
15083 { 0x00000000, 0xc0204811, 0x000 },
15084 { 0x8a000000, 0x00204411, 0x000 },
15085 { 0x00000000, 0x00204811, 0x000 },
15086 { 0x0000225c, 0x00204411, 0x000 },
15087 { 0x00000000, 0xc0204800, 0x000 },
15088 { 0x0000a1fc, 0x00204411, 0x000 },
15089 { 0x00000000, 0xc0204800, 0x000 },
15090 { 0x00000000, 0xc0200400, 0x000 },
15091 { 0x00000000, 0x00a0000a, 0x000 },
15092 { 0x97000000, 0xc0204411, 0x000 },
15093 { 0x00000000, 0xc0204811, 0x000 },
15094 { 0x8a000000, 0xc0204411, 0x000 },
15095 { 0x00000000, 0x00204811, 0x000 },
15096 { 0x0000225c, 0x00204411, 0x000 },
15097 { 0x00000000, 0xc0204800, 0x000 },
15098 { 0x0000a1fc, 0x00204411, 0x000 },
15099 { 0x00000000, 0xc0204800, 0x000 },
15100 { 0x00000000, 0xc0200400, 0x000 },
15101 { 0x00000000, 0x00a0000a, 0x000 },
15102 { 0x97000000, 0x00204411, 0x000 },
15103 { 0x00000000, 0x00204811, 0x000 },
15104 { 0x8a000000, 0x00204411, 0x000 },
15105 { 0x00000000, 0x00204811, 0x000 },
15106 { 0x0000225c, 0x00204411, 0x000 },
15107 { 0x00000000, 0xc0204800, 0x000 },
15108 { 0x0000a1fc, 0x00204411, 0x000 },
15109 { 0x00000000, 0xc0204800, 0x000 },
15110 { 0x00000000, 0xc0200400, 0x000 },
15111 { 0x00000000, 0x00a0000a, 0x000 },
15112 { 0x97000000, 0x00204411, 0x000 },
15113 { 0x00000000, 0x00204811, 0x000 },
15114 { 0x8a000000, 0x00204411, 0x000 },
15115 { 0x00000000, 0x00204811, 0x000 },
15116 { 0x0000225c, 0x00204411, 0x000 },
15117 { 0x00000000, 0xc0204800, 0x000 },
15118 { 0x0000a1fc, 0x00204411, 0x000 },
15119 { 0x00000000, 0xc0204800, 0x000 },
15120 { 0x0001a1fd, 0x00204411, 0x000 },
15121 { 0x00000000, 0xd9004800, 0x000 },
15122 { 0x00000000, 0xc0200400, 0x000 },
15123 { 0x00000000, 0x00a0000a, 0x000 },
15124 { 0x00002257, 0x00204411, 0x000 },
15125 { 0x00000003, 0xc0484a20, 0x000 },
15126 { 0x0000225d, 0x00204411, 0x000 },
15127 { 0x00000000, 0xc0404800, 0x000 },
15128 { 0x00000000, 0x00600000, 0x5de },
15129 { 0x00000000, 0xc0200800, 0x000 },
15130 { 0x0000225c, 0x00204411, 0x000 },
15131 { 0x00000003, 0x00384a22, 0x000 },
15132 { 0x0000a1fc, 0x00204411, 0x000 },
15133 { 0x00000000, 0xc0204800, 0x000 },
15134 { 0x0001a1fd, 0x00204411, 0x000 },
15135 { 0x00000000, 0x002f0222, 0x000 },
15136 { 0x00000000, 0x0ce00000, 0x000 },
15137 { 0x00000000, 0x40204800, 0x000 },
15138 { 0x00000001, 0x40304a20, 0x000 },
15139 { 0x00000002, 0xc0304a20, 0x000 },
15140 { 0x00000001, 0x00530a22, 0x355 },
15141 { 0x0000003f, 0xc0280a20, 0x000 },
15142 { 0x81000000, 0x00204411, 0x000 },
15143 { 0x00000001, 0x00204811, 0x000 },
15144 { 0x000021f8, 0x00204411, 0x000 },
15145 { 0x00000018, 0x00204811, 0x000 },
15146 { 0x000421f9, 0x00604411, 0x622 },
15147 { 0x00000011, 0x00210230, 0x000 },
15148 { 0x00000000, 0x14e00000, 0x35e },
15149 { 0x00000014, 0x002f0222, 0x000 },
15150 { 0x00000000, 0x0cc00000, 0x36c },
15151 { 0x0001a2a4, 0x00204411, 0x000 },
15152 { 0x00000000, 0x00604802, 0x374 },
15153 { 0x00002100, 0x00204411, 0x000 },
15154 { 0x00000000, 0xc0204800, 0x000 },
15155 { 0x00000000, 0xc0204800, 0x000 },
15156 { 0x00000000, 0xc0204800, 0x000 },
15157 { 0x00000000, 0xc0404800, 0x000 },
15158 { 0x00000004, 0x002f0222, 0x000 },
15159 { 0x00000000, 0x0cc00000, 0x370 },
15160 { 0x0001a2a4, 0x00204411, 0x000 },
15161 { 0x00000000, 0x00404802, 0x367 },
15162 { 0x00000028, 0x002f0222, 0x000 },
15163 { 0x00000000, 0x0cc00000, 0x5ba },
15164 { 0x0001a2a4, 0x00204411, 0x000 },
15165 { 0x00000000, 0x00404802, 0x367 },
15166 { 0x0000002c, 0x00203626, 0x000 },
15167 { 0x00000049, 0x00201811, 0x000 },
15168 { 0x0000003f, 0x00204811, 0x000 },
15169 { 0x00000001, 0x00331a26, 0x000 },
15170 { 0x00000000, 0x002f0226, 0x000 },
15171 { 0x00000000, 0x0cc00000, 0x376 },
15172 { 0x0000002c, 0x00801a2d, 0x000 },
15173 { 0x0000003f, 0xc0280a20, 0x000 },
15174 { 0x00000015, 0x002f0222, 0x000 },
15175 { 0x00000000, 0x0ce00000, 0x38c },
15176 { 0x00000006, 0x002f0222, 0x000 },
15177 { 0x00000000, 0x0ce00000, 0x3b7 },
15178 { 0x00000016, 0x002f0222, 0x000 },
15179 { 0x00000000, 0x0ce00000, 0x3b9 },
15180 { 0x00000020, 0x002f0222, 0x000 },
15181 { 0x00000000, 0x0ce00000, 0x3a2 },
15182 { 0x0000000f, 0x002f0222, 0x000 },
15183 { 0x00000000, 0x0ce00000, 0x3ae },
15184 { 0x00000010, 0x002f0222, 0x000 },
15185 { 0x00000000, 0x0ce00000, 0x3ae },
15186 { 0x0000001e, 0x002f0222, 0x000 },
15187 { 0x00000000, 0x0ce00000, 0x396 },
15188 { 0x0000a2a4, 0x00204411, 0x000 },
15189 { 0x00000000, 0x00404802, 0x000 },
15190 { 0x08000000, 0x00290a22, 0x000 },
15191 { 0x00000003, 0x40210e20, 0x000 },
15192 { 0x0000000c, 0xc0211220, 0x000 },
15193 { 0x00080000, 0x00281224, 0x000 },
15194 { 0x00000014, 0xc0221620, 0x000 },
15195 { 0x00000000, 0x002914a4, 0x000 },
15196 { 0x0000a2a4, 0x00204411, 0x000 },
15197 { 0x00000000, 0x002948a2, 0x000 },
15198 { 0x0000a1fe, 0x00204411, 0x000 },
15199 { 0x00000000, 0x00404803, 0x000 },
15200 { 0x81000000, 0x00204411, 0x000 },
15201 { 0x00000001, 0x00204811, 0x000 },
15202 { 0x000021f8, 0x00204411, 0x000 },
15203 { 0x00000016, 0x00204811, 0x000 },
15204 { 0x000421f9, 0x00604411, 0x622 },
15205 { 0x00000015, 0x00210230, 0x000 },
15206 { 0x00000000, 0x14e00000, 0x398 },
15207 { 0x0000210e, 0x00204411, 0x000 },
15208 { 0x00000000, 0xc0204800, 0x000 },
15209 { 0x00000000, 0xc0204800, 0x000 },
15210 { 0x0000a2a4, 0x00204411, 0x000 },
15211 { 0x00000000, 0x00404802, 0x000 },
15212 { 0x81000000, 0x00204411, 0x000 },
15213 { 0x00000001, 0x00204811, 0x000 },
15214 { 0x000021f8, 0x00204411, 0x000 },
15215 { 0x00000017, 0x00204811, 0x000 },
15216 { 0x000421f9, 0x00604411, 0x622 },
15217 { 0x00000003, 0x00210230, 0x000 },
15218 { 0x00000000, 0x14e00000, 0x3a4 },
15219 { 0x00002108, 0x00204411, 0x000 },
15220 { 0x00000000, 0xc0204800, 0x000 },
15221 { 0x00000000, 0xc0204800, 0x000 },
15222 { 0x0000a2a4, 0x00204411, 0x000 },
15223 { 0x00000000, 0x00404802, 0x000 },
15224 { 0x0000a2a4, 0x00204411, 0x000 },
15225 { 0x00000000, 0x00204802, 0x000 },
15226 { 0x80000000, 0x00204411, 0x000 },
15227 { 0x00000000, 0x00204811, 0x000 },
15228 { 0x81000000, 0x00204411, 0x000 },
15229 { 0x00000010, 0x00204811, 0x000 },
15230 { 0x00000000, 0x00200010, 0x000 },
15231 { 0x00000000, 0x14c00000, 0x3b4 },
15232 { 0x00000000, 0x00400000, 0x000 },
15233 { 0x0001a2a4, 0x00204411, 0x000 },
15234 { 0x00000006, 0x00404811, 0x000 },
15235 { 0x0001a2a4, 0x00204411, 0x000 },
15236 { 0x00000016, 0x00604811, 0x374 },
15237 { 0x00000000, 0x00400000, 0x000 },
15238 { 0x00000000, 0xc0200800, 0x000 },
15239 { 0x00000000, 0xc0200c00, 0x000 },
15240 { 0x0000001d, 0x00210223, 0x000 },
15241 { 0x00000000, 0x14e00000, 0x3ce },
15242 { 0x81000000, 0x00204411, 0x000 },
15243 { 0x00000001, 0x00204811, 0x000 },
15244 { 0x000021f8, 0x00204411, 0x000 },
15245 { 0x00000018, 0x00204811, 0x000 },
15246 { 0x000421f9, 0x00604411, 0x622 },
15247 { 0x00000011, 0x00210230, 0x000 },
15248 { 0x00000000, 0x14e00000, 0x3c2 },
15249 { 0x00002100, 0x00204411, 0x000 },
15250 { 0x00000000, 0x00204802, 0x000 },
15251 { 0x00000000, 0x00204803, 0x000 },
15252 { 0xbabecafe, 0x00204811, 0x000 },
15253 { 0xcafebabe, 0x00204811, 0x000 },
15254 { 0x0000a2a4, 0x00204411, 0x000 },
15255 { 0x00000004, 0x00404811, 0x000 },
15256 { 0x00002170, 0x00204411, 0x000 },
15257 { 0x00000000, 0x00204802, 0x000 },
15258 { 0x00000000, 0x00204803, 0x000 },
15259 { 0x81000000, 0x00204411, 0x000 },
15260 { 0x0000000a, 0x00204811, 0x000 },
15261 { 0x00000000, 0x00200010, 0x000 },
15262 { 0x00000000, 0x14c00000, 0x3d3 },
15263 { 0x8c000000, 0x00204411, 0x000 },
15264 { 0xcafebabe, 0x00404811, 0x000 },
15265 { 0x81000000, 0x00204411, 0x000 },
15266 { 0x00000001, 0x00204811, 0x000 },
15267 { 0x00003fff, 0x40280a20, 0x000 },
15268 { 0x80000000, 0x40280e20, 0x000 },
15269 { 0x40000000, 0xc0281220, 0x000 },
15270 { 0x00040000, 0x00694622, 0x622 },
15271 { 0x00000000, 0x00201410, 0x000 },
15272 { 0x00000000, 0x002f0223, 0x000 },
15273 { 0x00000000, 0x0cc00000, 0x3e1 },
15274 { 0x00000000, 0xc0401800, 0x3e4 },
15275 { 0x00003fff, 0xc0281a20, 0x000 },
15276 { 0x00040000, 0x00694626, 0x622 },
15277 { 0x00000000, 0x00201810, 0x000 },
15278 { 0x00000000, 0x002f0224, 0x000 },
15279 { 0x00000000, 0x0cc00000, 0x3e7 },
15280 { 0x00000000, 0xc0401c00, 0x3ea },
15281 { 0x00003fff, 0xc0281e20, 0x000 },
15282 { 0x00040000, 0x00694627, 0x622 },
15283 { 0x00000000, 0x00201c10, 0x000 },
15284 { 0x00000000, 0x00204402, 0x000 },
15285 { 0x00000000, 0x002820c5, 0x000 },
15286 { 0x00000000, 0x004948e8, 0x000 },
15287 { 0xa5800000, 0x00200811, 0x000 },
15288 { 0x00002000, 0x00200c11, 0x000 },
15289 { 0x83000000, 0x00604411, 0x412 },
15290 { 0x00000000, 0x00204402, 0x000 },
15291 { 0x00000000, 0xc0204800, 0x000 },
15292 { 0x00000000, 0x40204800, 0x000 },
15293 { 0x0000001f, 0xc0210220, 0x000 },
15294 { 0x00000000, 0x14c00000, 0x3f7 },
15295 { 0x00002010, 0x00204411, 0x000 },
15296 { 0x00008000, 0x00204811, 0x000 },
15297 { 0x0000ffff, 0xc0481220, 0x3ff },
15298 { 0xa7800000, 0x00200811, 0x000 },
15299 { 0x0000a000, 0x00200c11, 0x000 },
15300 { 0x83000000, 0x00604411, 0x412 },
15301 { 0x00000000, 0x00204402, 0x000 },
15302 { 0x00000000, 0xc0204800, 0x000 },
15303 { 0x00000000, 0xc0204800, 0x000 },
15304 { 0x0000ffff, 0xc0281220, 0x000 },
15305 { 0x83000000, 0x00204411, 0x000 },
15306 { 0x00000000, 0x00304883, 0x000 },
15307 { 0x84000000, 0x00204411, 0x000 },
15308 { 0x00000000, 0xc0204800, 0x000 },
15309 { 0x00000000, 0x1d000000, 0x000 },
15310 { 0x83000000, 0x00604411, 0x412 },
15311 { 0x00000000, 0xc0400400, 0x001 },
15312 { 0xa9800000, 0x00200811, 0x000 },
15313 { 0x0000c000, 0x00400c11, 0x3fa },
15314 { 0xab800000, 0x00200811, 0x000 },
15315 { 0x0000f8e0, 0x00400c11, 0x3fa },
15316 { 0xad800000, 0x00200811, 0x000 },
15317 { 0x0000f880, 0x00400c11, 0x3fa },
15318 { 0xb3800000, 0x00200811, 0x000 },
15319 { 0x0000f3fc, 0x00400c11, 0x3fa },
15320 { 0xaf800000, 0x00200811, 0x000 },
15321 { 0x0000e000, 0x00400c11, 0x3fa },
15322 { 0xb1800000, 0x00200811, 0x000 },
15323 { 0x0000f000, 0x00400c11, 0x3fa },
15324 { 0x83000000, 0x00204411, 0x000 },
15325 { 0x00002148, 0x00204811, 0x000 },
15326 { 0x84000000, 0x00204411, 0x000 },
15327 { 0x00000000, 0xc0204800, 0x000 },
15328 { 0x00000000, 0x1d000000, 0x000 },
15329 { 0x00000000, 0x00800000, 0x000 },
15330 { 0x01182000, 0xc0304620, 0x000 },
15331 { 0x00000000, 0xd9004800, 0x000 },
15332 { 0x00000000, 0xc0200400, 0x000 },
15333 { 0x00000000, 0x00a0000a, 0x000 },
15334 { 0x0218a000, 0xc0304620, 0x000 },
15335 { 0x00000000, 0xd9004800, 0x000 },
15336 { 0x00000000, 0xc0200400, 0x000 },
15337 { 0x00000000, 0x00a0000a, 0x000 },
15338 { 0x0318c000, 0xc0304620, 0x000 },
15339 { 0x00000000, 0xd9004800, 0x000 },
15340 { 0x00000000, 0xc0200400, 0x000 },
15341 { 0x00000000, 0x00a0000a, 0x000 },
15342 { 0x0418f8e0, 0xc0304620, 0x000 },
15343 { 0x00000000, 0xd9004800, 0x000 },
15344 { 0x00000000, 0xc0200400, 0x000 },
15345 { 0x00000000, 0x00a0000a, 0x000 },
15346 { 0x0518f880, 0xc0304620, 0x000 },
15347 { 0x00000000, 0xd9004800, 0x000 },
15348 { 0x00000000, 0xc0200400, 0x000 },
15349 { 0x00000000, 0x00a0000a, 0x000 },
15350 { 0x0618e000, 0xc0304620, 0x000 },
15351 { 0x00000000, 0xd9004800, 0x000 },
15352 { 0x00000000, 0xc0200400, 0x000 },
15353 { 0x00000000, 0x00a0000a, 0x000 },
15354 { 0x0718f000, 0xc0304620, 0x000 },
15355 { 0x00000000, 0xd9004800, 0x000 },
15356 { 0x00000000, 0xc0200400, 0x000 },
15357 { 0x00000000, 0x00a0000a, 0x000 },
15358 { 0x0818f3fc, 0xc0304620, 0x000 },
15359 { 0x00000000, 0xd9004800, 0x000 },
15360 { 0x00000000, 0xc0200400, 0x000 },
15361 { 0x00000000, 0x00a0000a, 0x000 },
15362 { 0x00000033, 0xc0300a20, 0x000 },
15363 { 0x00000000, 0xc0403440, 0x000 },
15364 { 0x00000030, 0x00200a2d, 0x000 },
15365 { 0x00000000, 0xc0290c40, 0x000 },
15366 { 0x00000030, 0x00203623, 0x000 },
15367 { 0x00000000, 0xc0200400, 0x000 },
15368 { 0x00000000, 0x00a0000a, 0x000 },
15369 { 0x86000000, 0x00204411, 0x000 },
15370 { 0x00000000, 0x00404801, 0x000 },
15371 { 0x85000000, 0xc0204411, 0x000 },
15372 { 0x00000000, 0x00404801, 0x000 },
15373 { 0x0000217c, 0x00204411, 0x000 },
15374 { 0x00000018, 0x40210220, 0x000 },
15375 { 0x00000000, 0x14c00000, 0x447 },
15376 { 0x00800000, 0xc0494a20, 0x448 },
15377 { 0x00000000, 0xc0204800, 0x000 },
15378 { 0x00000000, 0xc0204800, 0x000 },
15379 { 0x00000000, 0xc0204800, 0x000 },
15380 { 0x81000000, 0x00204411, 0x000 },
15381 { 0x00000001, 0x00204811, 0x000 },
15382 { 0x00000000, 0xc0200800, 0x000 },
15383 { 0x00000004, 0x002f0222, 0x000 },
15384 { 0x00000000, 0x06e00000, 0x450 },
15385 { 0x00000004, 0x00200811, 0x000 },
15386 { 0x00000000, 0x17000000, 0x000 },
15387 { 0x0004217f, 0x00604411, 0x622 },
15388 { 0x0000001f, 0x00210230, 0x000 },
15389 { 0x00000000, 0x14c00000, 0x000 },
15390 { 0x00000000, 0x00404c02, 0x450 },
15391 { 0x00000000, 0xc0200c00, 0x000 },
15392 { 0x00000000, 0xc0201000, 0x000 },
15393 { 0x00000000, 0xc0201400, 0x000 },
15394 { 0x00000000, 0xc0201800, 0x000 },
15395 { 0x00000000, 0xc0201c00, 0x000 },
15396 { 0x00007f00, 0x00280a21, 0x000 },
15397 { 0x00004500, 0x002f0222, 0x000 },
15398 { 0x00000000, 0x0ce00000, 0x461 },
15399 { 0x00000000, 0xc0202000, 0x000 },
15400 { 0x00000004, 0x002f0228, 0x000 },
15401 { 0x00000000, 0x06e00000, 0x461 },
15402 { 0x00000004, 0x00202011, 0x000 },
15403 { 0x00000000, 0x17000000, 0x000 },
15404 { 0x00000010, 0x00280a23, 0x000 },
15405 { 0x00000010, 0x002f0222, 0x000 },
15406 { 0x00000000, 0x0ce00000, 0x469 },
15407 { 0x81000000, 0x00204411, 0x000 },
15408 { 0x00000001, 0x00204811, 0x000 },
15409 { 0x00040000, 0x00694624, 0x622 },
15410 { 0x00000000, 0x00400000, 0x46e },
15411 { 0x81000000, 0x00204411, 0x000 },
15412 { 0x00000000, 0x00204811, 0x000 },
15413 { 0x0000216d, 0x00204411, 0x000 },
15414 { 0x00000000, 0x00204804, 0x000 },
15415 { 0x00000000, 0x00604805, 0x627 },
15416 { 0x00000000, 0x002824f0, 0x000 },
15417 { 0x00000007, 0x00280a23, 0x000 },
15418 { 0x00000001, 0x002f0222, 0x000 },
15419 { 0x00000000, 0x0ae00000, 0x475 },
15420 { 0x00000000, 0x002f00c9, 0x000 },
15421 { 0x00000000, 0x04e00000, 0x48e },
15422 { 0x00000000, 0x00400000, 0x49b },
15423 { 0x00000002, 0x002f0222, 0x000 },
15424 { 0x00000000, 0x0ae00000, 0x47a },
15425 { 0x00000000, 0x002f00c9, 0x000 },
15426 { 0x00000000, 0x02e00000, 0x48e },
15427 { 0x00000000, 0x00400000, 0x49b },
15428 { 0x00000003, 0x002f0222, 0x000 },
15429 { 0x00000000, 0x0ae00000, 0x47f },
15430 { 0x00000000, 0x002f00c9, 0x000 },
15431 { 0x00000000, 0x0ce00000, 0x48e },
15432 { 0x00000000, 0x00400000, 0x49b },
15433 { 0x00000004, 0x002f0222, 0x000 },
15434 { 0x00000000, 0x0ae00000, 0x484 },
15435 { 0x00000000, 0x002f00c9, 0x000 },
15436 { 0x00000000, 0x0ae00000, 0x48e },
15437 { 0x00000000, 0x00400000, 0x49b },
15438 { 0x00000005, 0x002f0222, 0x000 },
15439 { 0x00000000, 0x0ae00000, 0x489 },
15440 { 0x00000000, 0x002f00c9, 0x000 },
15441 { 0x00000000, 0x06e00000, 0x48e },
15442 { 0x00000000, 0x00400000, 0x49b },
15443 { 0x00000006, 0x002f0222, 0x000 },
15444 { 0x00000000, 0x0ae00000, 0x48e },
15445 { 0x00000000, 0x002f00c9, 0x000 },
15446 { 0x00000000, 0x08e00000, 0x48e },
15447 { 0x00000000, 0x00400000, 0x49b },
15448 { 0x00007f00, 0x00280a21, 0x000 },
15449 { 0x00004500, 0x002f0222, 0x000 },
15450 { 0x00000000, 0x0ae00000, 0x000 },
15451 { 0x00000008, 0x00210a23, 0x000 },
15452 { 0x00000000, 0x14c00000, 0x498 },
15453 { 0x00002169, 0x00204411, 0x000 },
15454 { 0x00000000, 0xc0204800, 0x000 },
15455 { 0x00000000, 0xc0204800, 0x000 },
15456 { 0x00000000, 0xc0204800, 0x000 },
15457 { 0xcafebabe, 0x00404811, 0x000 },
15458 { 0x00000000, 0xc0204400, 0x000 },
15459 { 0x00000000, 0xc0200000, 0x000 },
15460 { 0x00000000, 0xc0404800, 0x000 },
15461 { 0x00007f00, 0x00280a21, 0x000 },
15462 { 0x00004500, 0x002f0222, 0x000 },
15463 { 0x00000000, 0x0ae00000, 0x4a1 },
15464 { 0x00000000, 0xc0200000, 0x000 },
15465 { 0x00000000, 0xc0200000, 0x000 },
15466 { 0x00000000, 0xc0400000, 0x000 },
15467 { 0x00000000, 0x00404c08, 0x461 },
15468 { 0x00000000, 0xc0200800, 0x000 },
15469 { 0x00000010, 0x40210e20, 0x000 },
15470 { 0x00000011, 0x40211220, 0x000 },
15471 { 0x00000012, 0x40211620, 0x000 },
15472 { 0x00002169, 0x00204411, 0x000 },
15473 { 0x00000000, 0x00204802, 0x000 },
15474 { 0x00000000, 0x00210225, 0x000 },
15475 { 0x00000000, 0x14e00000, 0x4ab },
15476 { 0x00040000, 0xc0494a20, 0x4ac },
15477 { 0xfffbffff, 0xc0284a20, 0x000 },
15478 { 0x00000000, 0x00210223, 0x000 },
15479 { 0x00000000, 0x14e00000, 0x4b8 },
15480 { 0x00000000, 0xc0204800, 0x000 },
15481 { 0x00000000, 0xc0204800, 0x000 },
15482 { 0x00000000, 0x00210224, 0x000 },
15483 { 0x00000000, 0x14c00000, 0x000 },
15484 { 0x81000000, 0x00204411, 0x000 },
15485 { 0x0000000c, 0x00204811, 0x000 },
15486 { 0x00000000, 0x00200010, 0x000 },
15487 { 0x00000000, 0x14c00000, 0x4b4 },
15488 { 0xa0000000, 0x00204411, 0x000 },
15489 { 0xcafebabe, 0x00404811, 0x000 },
15490 { 0x81000000, 0x00204411, 0x000 },
15491 { 0x00000004, 0x00204811, 0x000 },
15492 { 0x0000216b, 0x00204411, 0x000 },
15493 { 0x00000000, 0xc0204810, 0x000 },
15494 { 0x81000000, 0x00204411, 0x000 },
15495 { 0x00000005, 0x00204811, 0x000 },
15496 { 0x0000216c, 0x00204411, 0x000 },
15497 { 0x00000000, 0xc0204810, 0x000 },
15498 { 0x00000000, 0x002f0224, 0x000 },
15499 { 0x00000000, 0x0ce00000, 0x000 },
15500 { 0x00000000, 0x00400000, 0x4b2 },
15501 { 0x00000000, 0xc0210a20, 0x000 },
15502 { 0x00000000, 0x14c00000, 0x4cb },
15503 { 0x81000000, 0x00204411, 0x000 },
15504 { 0x00000000, 0x00204811, 0x000 },
15505 { 0x0000216d, 0x00204411, 0x000 },
15506 { 0x00000000, 0xc0204800, 0x000 },
15507 { 0x00000000, 0xc0604800, 0x627 },
15508 { 0x00000000, 0x00400000, 0x4cf },
15509 { 0x81000000, 0x00204411, 0x000 },
15510 { 0x00000001, 0x00204811, 0x000 },
15511 { 0x00040000, 0xc0294620, 0x000 },
15512 { 0x00000000, 0xc0600000, 0x622 },
15513 { 0x00000001, 0x00210222, 0x000 },
15514 { 0x00000000, 0x14c00000, 0x4d6 },
15515 { 0x00002169, 0x00204411, 0x000 },
15516 { 0x00000000, 0xc0204800, 0x000 },
15517 { 0x00000000, 0xc0204800, 0x000 },
15518 { 0x00000000, 0x00204810, 0x000 },
15519 { 0xcafebabe, 0x00404811, 0x000 },
15520 { 0x00000000, 0xc0204400, 0x000 },
15521 { 0x00000000, 0xc0404810, 0x000 },
15522 { 0x81000000, 0x00204411, 0x000 },
15523 { 0x00000001, 0x00204811, 0x000 },
15524 { 0x000021f8, 0x00204411, 0x000 },
15525 { 0x0000000e, 0x00204811, 0x000 },
15526 { 0x000421f9, 0x00604411, 0x622 },
15527 { 0x00000000, 0x00210230, 0x000 },
15528 { 0x00000000, 0x14c00000, 0x4d8 },
15529 { 0x00002180, 0x00204411, 0x000 },
15530 { 0x00000000, 0xc0204800, 0x000 },
15531 { 0x00000000, 0xc0200000, 0x000 },
15532 { 0x00000000, 0xc0204800, 0x000 },
15533 { 0x00000000, 0xc0200000, 0x000 },
15534 { 0x00000000, 0xc0404800, 0x000 },
15535 { 0x00000003, 0x00333e2f, 0x000 },
15536 { 0x00000001, 0x00210221, 0x000 },
15537 { 0x00000000, 0x14e00000, 0x508 },
15538 { 0x0000002c, 0x00200a2d, 0x000 },
15539 { 0x00040000, 0x18e00c11, 0x4f7 },
15540 { 0x00000001, 0x00333e2f, 0x000 },
15541 { 0x00002169, 0x00204411, 0x000 },
15542 { 0x00000000, 0x00204802, 0x000 },
15543 { 0x00000000, 0x00204803, 0x000 },
15544 { 0x00000008, 0x00300a22, 0x000 },
15545 { 0x00000000, 0xc0204800, 0x000 },
15546 { 0x00000000, 0xc0204800, 0x000 },
15547 { 0x00002169, 0x00204411, 0x000 },
15548 { 0x00000000, 0x00204802, 0x000 },
15549 { 0x00000000, 0x00204803, 0x000 },
15550 { 0x00000008, 0x00300a22, 0x000 },
15551 { 0x00000000, 0xc0204800, 0x000 },
15552 { 0x00000000, 0xd8c04800, 0x4eb },
15553 { 0x00002169, 0x00204411, 0x000 },
15554 { 0x00000000, 0x00204802, 0x000 },
15555 { 0x00000000, 0x00204803, 0x000 },
15556 { 0x00000008, 0x00300a22, 0x000 },
15557 { 0x00000000, 0xc0204800, 0x000 },
15558 { 0x00000000, 0xc0204800, 0x000 },
15559 { 0x0000002d, 0x0020122d, 0x000 },
15560 { 0x00000000, 0x00290c83, 0x000 },
15561 { 0x00002169, 0x00204411, 0x000 },
15562 { 0x00000000, 0x00204802, 0x000 },
15563 { 0x00000000, 0x00204803, 0x000 },
15564 { 0x00000008, 0x00300a22, 0x000 },
15565 { 0x00000000, 0xc0204800, 0x000 },
15566 { 0x00000000, 0xc0204800, 0x000 },
15567 { 0x00000011, 0x00210224, 0x000 },
15568 { 0x00000000, 0x14c00000, 0x000 },
15569 { 0x00000000, 0x00400000, 0x4b2 },
15570 { 0x0000002c, 0xc0203620, 0x000 },
15571 { 0x0000002d, 0xc0403620, 0x000 },
15572 { 0x0000000f, 0x00210221, 0x000 },
15573 { 0x00000000, 0x14c00000, 0x50d },
15574 { 0x00000000, 0x00600000, 0x00b },
15575 { 0x00000000, 0xd9000000, 0x000 },
15576 { 0x00000000, 0xc0400400, 0x001 },
15577 { 0xb5000000, 0x00204411, 0x000 },
15578 { 0x00002000, 0x00204811, 0x000 },
15579 { 0xb6000000, 0x00204411, 0x000 },
15580 { 0x0000a000, 0x00204811, 0x000 },
15581 { 0xb7000000, 0x00204411, 0x000 },
15582 { 0x0000c000, 0x00204811, 0x000 },
15583 { 0xb8000000, 0x00204411, 0x000 },
15584 { 0x0000f8e0, 0x00204811, 0x000 },
15585 { 0xb9000000, 0x00204411, 0x000 },
15586 { 0x0000f880, 0x00204811, 0x000 },
15587 { 0xba000000, 0x00204411, 0x000 },
15588 { 0x0000e000, 0x00204811, 0x000 },
15589 { 0xbb000000, 0x00204411, 0x000 },
15590 { 0x0000f000, 0x00204811, 0x000 },
15591 { 0xbc000000, 0x00204411, 0x000 },
15592 { 0x0000f3fc, 0x00204811, 0x000 },
15593 { 0x81000000, 0x00204411, 0x000 },
15594 { 0x00000002, 0x00204811, 0x000 },
15595 { 0x000000ff, 0x00280e30, 0x000 },
15596 { 0x00000000, 0x002f0223, 0x000 },
15597 { 0x00000000, 0x0cc00000, 0x521 },
15598 { 0x00000000, 0xc0200800, 0x000 },
15599 { 0x00000000, 0x14c00000, 0x536 },
15600 { 0x00000000, 0x00200c11, 0x000 },
15601 { 0x0000001c, 0x00203623, 0x000 },
15602 { 0x0000002b, 0x00203623, 0x000 },
15603 { 0x00000029, 0x00203623, 0x000 },
15604 { 0x00000028, 0x00203623, 0x000 },
15605 { 0x00000017, 0x00203623, 0x000 },
15606 { 0x00000025, 0x00203623, 0x000 },
15607 { 0x00000026, 0x00203623, 0x000 },
15608 { 0x00000015, 0x00203623, 0x000 },
15609 { 0x00000016, 0x00203623, 0x000 },
15610 { 0xffffe000, 0x00200c11, 0x000 },
15611 { 0x00000021, 0x00203623, 0x000 },
15612 { 0x00000022, 0x00203623, 0x000 },
15613 { 0x00001fff, 0x00200c11, 0x000 },
15614 { 0x00000023, 0x00203623, 0x000 },
15615 { 0x00000024, 0x00203623, 0x000 },
15616 { 0xf1ffffff, 0x00283a2e, 0x000 },
15617 { 0x0000001a, 0xc0220e20, 0x000 },
15618 { 0x00000000, 0x0029386e, 0x000 },
15619 { 0x81000000, 0x00204411, 0x000 },
15620 { 0x00000006, 0x00204811, 0x000 },
15621 { 0x0000002a, 0x40203620, 0x000 },
15622 { 0x87000000, 0x00204411, 0x000 },
15623 { 0x00000000, 0xc0204800, 0x000 },
15624 { 0x0000a1f4, 0x00204411, 0x000 },
15625 { 0x00000000, 0x00204810, 0x000 },
15626 { 0x9d000000, 0x00204411, 0x000 },
15627 { 0x0000001f, 0x40214a20, 0x000 },
15628 { 0x96000000, 0x00204411, 0x000 },
15629 { 0x00000000, 0xc0204800, 0x000 },
15630 { 0x00000000, 0xc0200c00, 0x000 },
15631 { 0x00000000, 0xc0201000, 0x000 },
15632 { 0x0000001f, 0x00211624, 0x000 },
15633 { 0x00000000, 0x14c00000, 0x000 },
15634 { 0x0000001d, 0x00203623, 0x000 },
15635 { 0x00000003, 0x00281e23, 0x000 },
15636 { 0x00000008, 0x00222223, 0x000 },
15637 { 0xfffff000, 0x00282228, 0x000 },
15638 { 0x00000000, 0x002920e8, 0x000 },
15639 { 0x0000001f, 0x00203628, 0x000 },
15640 { 0x00000018, 0x00211e23, 0x000 },
15641 { 0x00000020, 0x00203627, 0x000 },
15642 { 0x00000002, 0x00221624, 0x000 },
15643 { 0x00000000, 0x003014a8, 0x000 },
15644 { 0x0000001e, 0x00203625, 0x000 },
15645 { 0x00000003, 0x00211a24, 0x000 },
15646 { 0x10000000, 0x00281a26, 0x000 },
15647 { 0xefffffff, 0x00283a2e, 0x000 },
15648 { 0x00000000, 0x004938ce, 0x610 },
15649 { 0x00000001, 0x40280a20, 0x000 },
15650 { 0x00000006, 0x40280e20, 0x000 },
15651 { 0x00000300, 0xc0281220, 0x000 },
15652 { 0x00000008, 0x00211224, 0x000 },
15653 { 0x00000000, 0xc0201620, 0x000 },
15654 { 0x00000000, 0xc0201a20, 0x000 },
15655 { 0x00000000, 0x00210222, 0x000 },
15656 { 0x00000000, 0x14c00000, 0x56c },
15657 { 0x81000000, 0x00204411, 0x000 },
15658 { 0x00000001, 0x00204811, 0x000 },
15659 { 0x00002258, 0x00300a24, 0x000 },
15660 { 0x00040000, 0x00694622, 0x622 },
15661 { 0x00002169, 0x00204411, 0x000 },
15662 { 0x00000000, 0x00204805, 0x000 },
15663 { 0x00020000, 0x00294a26, 0x000 },
15664 { 0x00000000, 0x00204810, 0x000 },
15665 { 0xcafebabe, 0x00204811, 0x000 },
15666 { 0x00000002, 0x002f0223, 0x000 },
15667 { 0x00000000, 0x0cc00000, 0x574 },
15668 { 0x00000000, 0xc0201c10, 0x000 },
15669 { 0x00000000, 0xc0400000, 0x582 },
15670 { 0x00000002, 0x002f0223, 0x000 },
15671 { 0x00000000, 0x0cc00000, 0x574 },
15672 { 0x81000000, 0x00204411, 0x000 },
15673 { 0x00000001, 0x00204811, 0x000 },
15674 { 0x00002258, 0x00300a24, 0x000 },
15675 { 0x00040000, 0x00694622, 0x622 },
15676 { 0x00000000, 0xc0201c10, 0x000 },
15677 { 0x00000000, 0xc0400000, 0x582 },
15678 { 0x00000000, 0x002f0223, 0x000 },
15679 { 0x00000000, 0x0cc00000, 0x578 },
15680 { 0x00000000, 0xc0201c00, 0x000 },
15681 { 0x00000000, 0xc0400000, 0x582 },
15682 { 0x00000004, 0x002f0223, 0x000 },
15683 { 0x00000000, 0x0cc00000, 0x580 },
15684 { 0x81000000, 0x00204411, 0x000 },
15685 { 0x00000000, 0x00204811, 0x000 },
15686 { 0x0000216d, 0x00204411, 0x000 },
15687 { 0x00000000, 0xc0204800, 0x000 },
15688 { 0x00000000, 0xc0604800, 0x627 },
15689 { 0x00000000, 0x00401c10, 0x582 },
15690 { 0x00000000, 0xc0200000, 0x000 },
15691 { 0x00000000, 0xc0400000, 0x000 },
15692 { 0x00000000, 0x0ee00000, 0x584 },
15693 { 0x00000000, 0x00600000, 0x5c3 },
15694 { 0x00000000, 0x002f0224, 0x000 },
15695 { 0x00000000, 0x0cc00000, 0x592 },
15696 { 0x0000a2b7, 0x00204411, 0x000 },
15697 { 0x00000000, 0x00204807, 0x000 },
15698 { 0x00000033, 0x0020262d, 0x000 },
15699 { 0x0000001a, 0x00212229, 0x000 },
15700 { 0x00000006, 0x00222629, 0x000 },
15701 { 0x0000a2c4, 0x00204411, 0x000 },
15702 { 0x00000000, 0x003048e9, 0x000 },
15703 { 0x00000000, 0x00e00000, 0x590 },
15704 { 0x0000a2d1, 0x00204411, 0x000 },
15705 { 0x00000000, 0x00404808, 0x000 },
15706 { 0x0000a2d1, 0x00204411, 0x000 },
15707 { 0x00000001, 0x00504a28, 0x000 },
15708 { 0x00000001, 0x002f0224, 0x000 },
15709 { 0x00000000, 0x0cc00000, 0x5a0 },
15710 { 0x0000a2bb, 0x00204411, 0x000 },
15711 { 0x00000000, 0x00204807, 0x000 },
15712 { 0x00000034, 0x0020262d, 0x000 },
15713 { 0x0000001a, 0x00212229, 0x000 },
15714 { 0x00000006, 0x00222629, 0x000 },
15715 { 0x0000a2c5, 0x00204411, 0x000 },
15716 { 0x00000000, 0x003048e9, 0x000 },
15717 { 0x00000000, 0x00e00000, 0x59e },
15718 { 0x0000a2d2, 0x00204411, 0x000 },
15719 { 0x00000000, 0x00404808, 0x000 },
15720 { 0x0000a2d2, 0x00204411, 0x000 },
15721 { 0x00000001, 0x00504a28, 0x000 },
15722 { 0x00000002, 0x002f0224, 0x000 },
15723 { 0x00000000, 0x0cc00000, 0x5ae },
15724 { 0x0000a2bf, 0x00204411, 0x000 },
15725 { 0x00000000, 0x00204807, 0x000 },
15726 { 0x00000035, 0x0020262d, 0x000 },
15727 { 0x0000001a, 0x00212229, 0x000 },
15728 { 0x00000006, 0x00222629, 0x000 },
15729 { 0x0000a2c6, 0x00204411, 0x000 },
15730 { 0x00000000, 0x003048e9, 0x000 },
15731 { 0x00000000, 0x00e00000, 0x5ac },
15732 { 0x0000a2d3, 0x00204411, 0x000 },
15733 { 0x00000000, 0x00404808, 0x000 },
15734 { 0x0000a2d3, 0x00204411, 0x000 },
15735 { 0x00000001, 0x00504a28, 0x000 },
15736 { 0x0000a2c3, 0x00204411, 0x000 },
15737 { 0x00000000, 0x00204807, 0x000 },
15738 { 0x00000036, 0x0020262d, 0x000 },
15739 { 0x0000001a, 0x00212229, 0x000 },
15740 { 0x00000006, 0x00222629, 0x000 },
15741 { 0x0000a2c7, 0x00204411, 0x000 },
15742 { 0x00000000, 0x003048e9, 0x000 },
15743 { 0x00000000, 0x00e00000, 0x5b8 },
15744 { 0x0000a2d4, 0x00204411, 0x000 },
15745 { 0x00000000, 0x00404808, 0x000 },
15746 { 0x0000a2d4, 0x00204411, 0x000 },
15747 { 0x00000001, 0x00504a28, 0x000 },
15748 { 0x85000000, 0x00204411, 0x000 },
15749 { 0x00000000, 0x00204801, 0x000 },
15750 { 0x0000304a, 0x00204411, 0x000 },
15751 { 0x01000000, 0x00204811, 0x000 },
15752 { 0x00000000, 0x00400000, 0x5be },
15753 { 0xa4000000, 0xc0204411, 0x000 },
15754 { 0x00000000, 0xc0404800, 0x000 },
15755 { 0x00000000, 0xc0600000, 0x5c3 },
15756 { 0x00000000, 0xc0400400, 0x001 },
15757 { 0x0001a2a4, 0x00204411, 0x000 },
15758 { 0x0000003f, 0x00204811, 0x000 },
15759 { 0x0000003f, 0x00204811, 0x000 },
15760 { 0x0000003f, 0x00204811, 0x000 },
15761 { 0x0000003f, 0x00204811, 0x000 },
15762 { 0x00000005, 0x00204811, 0x000 },
15763 { 0x0000a1f4, 0x00204411, 0x000 },
15764 { 0x00000000, 0x00204811, 0x000 },
15765 { 0x88000000, 0x00204411, 0x000 },
15766 { 0x00000001, 0x00204811, 0x000 },
15767 { 0xff000000, 0x00204411, 0x000 },
15768 { 0x00000000, 0x00204811, 0x000 },
15769 { 0x00000001, 0x00204811, 0x000 },
15770 { 0x00000002, 0x00804811, 0x000 },
15771 { 0x00000000, 0x0ee00000, 0x5d6 },
15772 { 0x00001000, 0x00200811, 0x000 },
15773 { 0x0000002b, 0x00203622, 0x000 },
15774 { 0x00000000, 0x00600000, 0x5da },
15775 { 0x00000000, 0x00600000, 0x5c3 },
15776 { 0x98000000, 0x00204411, 0x000 },
15777 { 0x00000000, 0x00804811, 0x000 },
15778 { 0x00000000, 0xc0600000, 0x5da },
15779 { 0x00000000, 0xc0400400, 0x001 },
15780 { 0x0000a2a4, 0x00204411, 0x000 },
15781 { 0x00000022, 0x00204811, 0x000 },
15782 { 0x89000000, 0x00204411, 0x000 },
15783 { 0x00000001, 0x00404811, 0x5cd },
15784 { 0x97000000, 0x00204411, 0x000 },
15785 { 0x00000000, 0x00204811, 0x000 },
15786 { 0x8a000000, 0x00204411, 0x000 },
15787 { 0x00000000, 0x00404811, 0x5cd },
15788 { 0x00000000, 0x00600000, 0x5f3 },
15789 { 0x0001a2a4, 0xc0204411, 0x000 },
15790 { 0x00000016, 0x00604811, 0x374 },
15791 { 0x00002010, 0x00204411, 0x000 },
15792 { 0x00010000, 0x00204811, 0x000 },
15793 { 0x81000000, 0x00204411, 0x000 },
15794 { 0x00000001, 0x00204811, 0x000 },
15795 { 0x0000217c, 0x00204411, 0x000 },
15796 { 0x09800000, 0x00204811, 0x000 },
15797 { 0xffffffff, 0x00204811, 0x000 },
15798 { 0x00000000, 0x00204811, 0x000 },
15799 { 0x00000000, 0x17000000, 0x000 },
15800 { 0x0004217f, 0x00604411, 0x622 },
15801 { 0x0000001f, 0x00210230, 0x000 },
15802 { 0x00000000, 0x14c00000, 0x000 },
15803 { 0x00000004, 0x00404c11, 0x5ed },
15804 { 0x00000000, 0x00400000, 0x000 },
15805 { 0x00000017, 0x00201e2d, 0x000 },
15806 { 0x00000004, 0x00291e27, 0x000 },
15807 { 0x00000017, 0x00803627, 0x000 },
15808 { 0x00000017, 0x00201e2d, 0x000 },
15809 { 0xfffffffb, 0x00281e27, 0x000 },
15810 { 0x00000017, 0x00803627, 0x000 },
15811 { 0x00000017, 0x00201e2d, 0x000 },
15812 { 0x00000008, 0x00291e27, 0x000 },
15813 { 0x00000017, 0x00803627, 0x000 },
15814 { 0x00000017, 0x00201e2d, 0x000 },
15815 { 0xfffffff7, 0x00281e27, 0x000 },
15816 { 0x00000017, 0x00803627, 0x000 },
15817 { 0x0001a2a4, 0x00204411, 0x000 },
15818 { 0x00000016, 0x00604811, 0x374 },
15819 { 0x00002010, 0x00204411, 0x000 },
15820 { 0x00010000, 0x00204811, 0x000 },
15821 { 0x0000217c, 0x00204411, 0x000 },
15822 { 0x01800000, 0x00204811, 0x000 },
15823 { 0xffffffff, 0x00204811, 0x000 },
15824 { 0x00000000, 0x00204811, 0x000 },
15825 { 0x00000000, 0x17000000, 0x000 },
15826 { 0x81000000, 0x00204411, 0x000 },
15827 { 0x00000001, 0x00204811, 0x000 },
15828 { 0x0004217f, 0x00604411, 0x622 },
15829 { 0x0000001f, 0x00210230, 0x000 },
15830 { 0x00000000, 0x14c00000, 0x621 },
15831 { 0x00000010, 0x00404c11, 0x607 },
15832 { 0x00000000, 0xc0200400, 0x000 },
15833 { 0x00000000, 0x38c00000, 0x000 },
15834 { 0x0000001d, 0x00200a2d, 0x000 },
15835 { 0x0000001e, 0x00200e2d, 0x000 },
15836 { 0x0000001f, 0x0020122d, 0x000 },
15837 { 0x00000020, 0x0020162d, 0x000 },
15838 { 0x00002169, 0x00204411, 0x000 },
15839 { 0x00000000, 0x00204804, 0x000 },
15840 { 0x00000000, 0x00204805, 0x000 },
15841 { 0x00000000, 0x00204801, 0x000 },
15842 { 0xcafebabe, 0x00204811, 0x000 },
15843 { 0x00000004, 0x00301224, 0x000 },
15844 { 0x00000000, 0x002f0064, 0x000 },
15845 { 0x00000000, 0x0cc00000, 0x620 },
15846 { 0x00000003, 0x00281a22, 0x000 },
15847 { 0x00000008, 0x00221222, 0x000 },
15848 { 0xfffff000, 0x00281224, 0x000 },
15849 { 0x00000000, 0x002910c4, 0x000 },
15850 { 0x0000001f, 0x00403624, 0x000 },
15851 { 0x00000000, 0x00800000, 0x000 },
15852 { 0x00000000, 0x1ac00000, 0x622 },
15853 { 0x9f000000, 0x00204411, 0x000 },
15854 { 0xcafebabe, 0x00204811, 0x000 },
15855 { 0x00000000, 0x1ae00000, 0x625 },
15856 { 0x00000000, 0x00800000, 0x000 },
15857 { 0x00000000, 0x1ac00000, 0x627 },
15858 { 0x9e000000, 0x00204411, 0x000 },
15859 { 0xcafebabe, 0x00204811, 0x000 },
15860 { 0x00000000, 0x1ae00000, 0x62a },
15861 { 0x00000000, 0x00800000, 0x000 },
15862 { 0x00000000, 0x00600000, 0x00b },
15863 { 0x00001000, 0x00600411, 0x315 },
15864 { 0x00000000, 0x00200411, 0x000 },
15865 { 0x00000000, 0x00600811, 0x1b2 },
15866 { 0x0000225c, 0x00204411, 0x000 },
15867 { 0x00000003, 0x00204811, 0x000 },
15868 { 0x00002256, 0x00204411, 0x000 },
15869 { 0x0000001b, 0x00204811, 0x000 },
15870 { 0x0000a1fc, 0x00204411, 0x000 },
15871 { 0x00000001, 0x00204811, 0x000 },
15872 { 0x0001a1fd, 0xc0204411, 0x000 },
15873 { 0x00000021, 0x00201e2d, 0x000 },
15874 { 0x00000010, 0x00221e27, 0x000 },
15875 { 0x00000024, 0x0020222d, 0x000 },
15876 { 0x0000ffff, 0x00282228, 0x000 },
15877 { 0x00000000, 0x00294907, 0x000 },
15878 { 0x00000000, 0x00204811, 0x000 },
15879 { 0x00000022, 0x0020222d, 0x000 },
15880 { 0x0000ffff, 0x00282228, 0x000 },
15881 { 0x00000000, 0x00294907, 0x000 },
15882 { 0x00000000, 0x00204811, 0x000 },
15883 { 0x00000023, 0x00201e2d, 0x000 },
15884 { 0x00000010, 0x00221e27, 0x000 },
15885 { 0x00000000, 0x00294907, 0x000 },
15886 { 0x00000000, 0x00404811, 0x000 },
15887 { 0x00000000, 0x00000000, 0x000 },
15888 { 0x00000000, 0x00000000, 0x000 },
15889 { 0x00000000, 0x00000000, 0x000 },
15890 { 0x00000000, 0x00000000, 0x000 },
15891 { 0x00000000, 0x00000000, 0x000 },
15892 { 0x00000000, 0x00000000, 0x000 },
15893 { 0x00000000, 0x00000000, 0x000 },
15894 { 0x00000000, 0x00000000, 0x000 },
15895 { 0x00000000, 0x00000000, 0x000 },
15896 { 0x00000000, 0x00000000, 0x000 },
15897 { 0x00000000, 0x00000000, 0x000 },
15898 { 0x00000000, 0x00000000, 0x000 },
15899 { 0x00000000, 0x00000000, 0x000 },
15900 { 0x00000000, 0x00000000, 0x000 },
15901 { 0x00000000, 0x00000000, 0x000 },
15902 { 0x00000000, 0x00000000, 0x000 },
15903 { 0x00000000, 0x00000000, 0x000 },
15904 { 0x00000000, 0x00000000, 0x000 },
15905 { 0x00000000, 0x00000000, 0x000 },
15906 { 0x00000000, 0x00000000, 0x000 },
15907 { 0x00000000, 0x00000000, 0x000 },
15908 { 0x00000000, 0x00000000, 0x000 },
15909 { 0x00000000, 0x00000000, 0x000 },
15910 { 0x00000000, 0x00000000, 0x000 },
15911 { 0x00000000, 0x00000000, 0x000 },
15912 { 0x00000000, 0x00000000, 0x000 },
15913 { 0x00000000, 0x00000000, 0x000 },
15914 { 0x00000000, 0x00000000, 0x000 },
15915 { 0x00000000, 0x00000000, 0x000 },
15916 { 0x00000000, 0x00000000, 0x000 },
15917 { 0x00000000, 0x00000000, 0x000 },
15918 { 0x00000000, 0x00000000, 0x000 },
15919 { 0x00000000, 0x00000000, 0x000 },
15920 { 0x00000000, 0x00000000, 0x000 },
15921 { 0x00000000, 0x00000000, 0x000 },
15922 { 0x00000000, 0x00000000, 0x000 },
15923 { 0x00000000, 0x00000000, 0x000 },
15924 { 0x00000000, 0x00000000, 0x000 },
15925 { 0x00000000, 0x00000000, 0x000 },
15926 { 0x00000000, 0x00000000, 0x000 },
15927 { 0x00000000, 0x00000000, 0x000 },
15928 { 0x00000000, 0x00000000, 0x000 },
15929 { 0x00000000, 0x00000000, 0x000 },
15930 { 0x00000000, 0x00000000, 0x000 },
15931 { 0x00000000, 0x00000000, 0x000 },
15932 { 0x00000000, 0x00000000, 0x000 },
15933 { 0x00000000, 0x00000000, 0x000 },
15934 { 0x00000000, 0x00000000, 0x000 },
15935 { 0x00000000, 0x00000000, 0x000 },
15936 { 0x00000000, 0x00000000, 0x000 },
15937 { 0x00000000, 0x00000000, 0x000 },
15938 { 0x00000000, 0x00000000, 0x000 },
15939 { 0x00000000, 0x00000000, 0x000 },
15940 { 0x00000000, 0x00000000, 0x000 },
15941 { 0x00000000, 0x00000000, 0x000 },
15942 { 0x00000000, 0x00000000, 0x000 },
15943 { 0x00000000, 0x00000000, 0x000 },
15944 { 0x00000000, 0x00000000, 0x000 },
15945 { 0x00000000, 0x00000000, 0x000 },
15946 { 0x00000000, 0x00000000, 0x000 },
15947 { 0x00000000, 0x00000000, 0x000 },
15948 { 0x00000000, 0x00000000, 0x000 },
15949 { 0x00000000, 0x00000000, 0x000 },
15950 { 0x00000000, 0x00000000, 0x000 },
15951 { 0x00000000, 0x00000000, 0x000 },
15952 { 0x00000000, 0x00000000, 0x000 },
15953 { 0x00000000, 0x00000000, 0x000 },
15954 { 0x00000000, 0x00000000, 0x000 },
15955 { 0x00000000, 0x00000000, 0x000 },
15956 { 0x00000000, 0x00000000, 0x000 },
15957 { 0x00000000, 0x00000000, 0x000 },
15958 { 0x00000000, 0x00000000, 0x000 },
15959 { 0x00000000, 0x00000000, 0x000 },
15960 { 0x00000000, 0x00000000, 0x000 },
15961 { 0x00000000, 0x00000000, 0x000 },
15962 { 0x00000000, 0x00000000, 0x000 },
15963 { 0x00000000, 0x00000000, 0x000 },
15964 { 0x00000000, 0x00000000, 0x000 },
15965 { 0x00000000, 0x00000000, 0x000 },
15966 { 0x00000000, 0x00000000, 0x000 },
15967 { 0x00000000, 0x00000000, 0x000 },
15968 { 0x00000000, 0x00000000, 0x000 },
15969 { 0x00000000, 0x00000000, 0x000 },
15970 { 0x00000000, 0x00000000, 0x000 },
15971 { 0x00000000, 0x00000000, 0x000 },
15972 { 0x00000000, 0x00000000, 0x000 },
15973 { 0x00000000, 0x00000000, 0x000 },
15974 { 0x00000000, 0x00000000, 0x000 },
15975 { 0x00000000, 0x00000000, 0x000 },
15976 { 0x00000000, 0x00000000, 0x000 },
15977 { 0x00000000, 0x00000000, 0x000 },
15978 { 0x00000000, 0x00000000, 0x000 },
15979 { 0x00000000, 0x00000000, 0x000 },
15980 { 0x00000000, 0x00000000, 0x000 },
15981 { 0x00000000, 0x00000000, 0x000 },
15982 { 0x00000000, 0x00000000, 0x000 },
15983 { 0x00000000, 0x00000000, 0x000 },
15984 { 0x00000000, 0x00000000, 0x000 },
15985 { 0x00000000, 0x00000000, 0x000 },
15986 { 0x00000000, 0x00000000, 0x000 },
15987 { 0x00000000, 0x00000000, 0x000 },
15988 { 0x00000000, 0x00000000, 0x000 },
15989 { 0x00000000, 0x00000000, 0x000 },
15990 { 0x00000000, 0x00000000, 0x000 },
15991 { 0x00000000, 0x00000000, 0x000 },
15992 { 0x00000000, 0x00000000, 0x000 },
15993 { 0x00000000, 0x00000000, 0x000 },
15994 { 0x00000000, 0x00000000, 0x000 },
15995 { 0x00000000, 0x00000000, 0x000 },
15996 { 0x00000000, 0x00000000, 0x000 },
15997 { 0x00000000, 0x00000000, 0x000 },
15998 { 0x00000000, 0x00000000, 0x000 },
15999 { 0x00000000, 0x00000000, 0x000 },
16000 { 0x00000000, 0x00000000, 0x000 },
16001 { 0x00000000, 0x00000000, 0x000 },
16002 { 0x00000000, 0x00000000, 0x000 },
16003 { 0x00000000, 0x00000000, 0x000 },
16004 { 0x00000000, 0x00000000, 0x000 },
16005 { 0x00000000, 0x00000000, 0x000 },
16006 { 0x00000000, 0x00000000, 0x000 },
16007 { 0x00000000, 0x00000000, 0x000 },
16008 { 0x00000000, 0x00000000, 0x000 },
16009 { 0x00000000, 0x00000000, 0x000 },
16010 { 0x00000000, 0x00000000, 0x000 },
16011 { 0x00000000, 0x00000000, 0x000 },
16012 { 0x00000000, 0x00000000, 0x000 },
16013 { 0x00000000, 0x00000000, 0x000 },
16014 { 0x00000000, 0x00000000, 0x000 },
16015 { 0x00000000, 0x00000000, 0x000 },
16016 { 0x00000000, 0x00000000, 0x000 },
16017 { 0x00000000, 0x00000000, 0x000 },
16018 { 0x00000000, 0x00000000, 0x000 },
16019 { 0x00000000, 0x00000000, 0x000 },
16020 { 0x00000000, 0x00000000, 0x000 },
16021 { 0x00000000, 0x00000000, 0x000 },
16022 { 0x00000000, 0x00000000, 0x000 },
16023 { 0x00000000, 0x00000000, 0x000 },
16024 { 0x00000000, 0x00000000, 0x000 },
16025 { 0x00000000, 0x00000000, 0x000 },
16026 { 0x00000000, 0x00000000, 0x000 },
16027 { 0x00000000, 0x00000000, 0x000 },
16028 { 0x00000000, 0x00000000, 0x000 },
16029 { 0x00000000, 0x00000000, 0x000 },
16030 { 0x00000000, 0x00000000, 0x000 },
16031 { 0x00000000, 0x00000000, 0x000 },
16032 { 0x00000000, 0x00000000, 0x000 },
16033 { 0x00000000, 0x00000000, 0x000 },
16034 { 0x00000000, 0x00000000, 0x000 },
16035 { 0x00000000, 0x00000000, 0x000 },
16036 { 0x00000000, 0x00000000, 0x000 },
16037 { 0x00000000, 0x00000000, 0x000 },
16038 { 0x00000000, 0x00000000, 0x000 },
16039 { 0x00000000, 0x00000000, 0x000 },
16040 { 0x00000000, 0x00000000, 0x000 },
16041 { 0x00000000, 0x00000000, 0x000 },
16042 { 0x00000000, 0x00000000, 0x000 },
16043 { 0x00000000, 0x00000000, 0x000 },
16044 { 0x00000000, 0x00000000, 0x000 },
16045 { 0x00000000, 0x00000000, 0x000 },
16046 { 0x0142050a, 0x05ba0250, 0x000 },
16047 { 0x01c30168, 0x044105ba, 0x000 },
16048 { 0x02250209, 0x02500151, 0x000 },
16049 { 0x02230245, 0x02a00241, 0x000 },
16050 { 0x03d705ba, 0x05ba05ba, 0x000 },
16051 { 0x05e205e3, 0x031f05ba, 0x000 },
16052 { 0x032005bf, 0x0320034a, 0x000 },
16053 { 0x03340282, 0x034c033e, 0x000 },
16054 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16055 { 0x05ba0557, 0x05ba032a, 0x000 },
16056 { 0x03bc05ba, 0x04c3034e, 0x000 },
16057 { 0x04a20455, 0x043f05ba, 0x000 },
16058 { 0x04d805ba, 0x044304e5, 0x000 },
16059 { 0x0455050f, 0x035b037b, 0x000 },
16060 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16061 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16062 { 0x05ba05ba, 0x05d805c1, 0x000 },
16063 { 0x05ba05ba, 0x000705ba, 0x000 },
16064 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16065 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16066 { 0x03f803ed, 0x04080406, 0x000 },
16067 { 0x040e040a, 0x040c0410, 0x000 },
16068 { 0x041c0418, 0x04240420, 0x000 },
16069 { 0x042c0428, 0x04340430, 0x000 },
16070 { 0x05ba05ba, 0x043a0438, 0x000 },
16071 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16072 { 0x05ba05ba, 0x05ba05ba, 0x000 },
16073 { 0x0002060e, 0x062c0006, 0x000 },
16074};
16075
16076static const u32 RS780_pfp_microcode[] = {
160770xca0400,
160780xa00000,
160790x7e828b,
160800x7c038b,
160810x8001db,
160820x7c038b,
160830xd4401e,
160840xee001e,
160850xca0400,
160860xa00000,
160870x7e828b,
160880xc41838,
160890xca2400,
160900xca2800,
160910x9581cb,
160920xc41c3a,
160930xc3c000,
160940xca0800,
160950xca0c00,
160960x7c744b,
160970xc20005,
160980x99c000,
160990xc41c3a,
161000x7c744c,
161010xc0ffe0,
161020x042c08,
161030x309002,
161040x7d2500,
161050x351402,
161060x7d350b,
161070x255407,
161080x7cd580,
161090x259c07,
161100x95c004,
161110xd5001b,
161120x7eddc1,
161130x7d9d80,
161140xd6801b,
161150xd5801b,
161160xd4401e,
161170xd5401e,
161180xd6401e,
161190xd6801e,
161200xd4801e,
161210xd4c01e,
161220x9783d3,
161230xd5c01e,
161240xca0800,
161250x80001a,
161260xca0c00,
161270xe4011e,
161280xd4001e,
161290x80000c,
161300xc41838,
161310xe4013e,
161320xd4001e,
161330x80000c,
161340xc41838,
161350xd4401e,
161360xee001e,
161370xca0400,
161380xa00000,
161390x7e828b,
161400xe4011e,
161410xd4001e,
161420xd4401e,
161430xee001e,
161440xca0400,
161450xa00000,
161460x7e828b,
161470xe4013e,
161480xd4001e,
161490xd4401e,
161500xee001e,
161510xca0400,
161520xa00000,
161530x7e828b,
161540xca0800,
161550xca0c00,
161560x8001db,
161570xd48024,
161580xca0800,
161590x7c00c0,
161600xc81425,
161610xc81824,
161620x7c9488,
161630x7c9880,
161640xc20003,
161650xd40075,
161660x7c744c,
161670x800064,
161680xd4401e,
161690xca1800,
161700xd4401e,
161710xd5801e,
161720x800062,
161730xd40075,
161740xd4401e,
161750xca0800,
161760xca0c00,
161770xca1000,
161780xd48019,
161790xd4c018,
161800xd50017,
161810xd4801e,
161820xd4c01e,
161830xd5001e,
161840xe2001e,
161850xca0400,
161860xa00000,
161870x7e828b,
161880xd40075,
161890xd4401e,
161900xca0800,
161910xca0c00,
161920xca1000,
161930xd48019,
161940xd4c018,
161950xd50017,
161960xd4801e,
161970xd4c01e,
161980xd5001e,
161990xee001e,
162000xca0400,
162010xa00000,
162020x7e828b,
162030xca0800,
162040x248c01,
162050xd48060,
162060x94c003,
162070x041001,
162080x041002,
162090xd50025,
162100xd4401e,
162110x800000,
162120xd4801e,
162130xca0800,
162140xd48061,
162150xd4401e,
162160x800000,
162170xd4801e,
162180xca0800,
162190xca0c00,
162200xd4401e,
162210xd48016,
162220xd4c016,
162230xd4801e,
162240x8001db,
162250xd4c01e,
162260xc60843,
162270xca0c00,
162280xca1000,
162290x948004,
162300xca1400,
162310xe420f3,
162320xd42013,
162330xd56065,
162340xd4e01c,
162350xd5201c,
162360xd5601c,
162370x800000,
162380x062001,
162390xc60843,
162400xca0c00,
162410xca1000,
162420x9483f7,
162430xca1400,
162440xe420f3,
162450x80009c,
162460xd42013,
162470xc60843,
162480xca0c00,
162490xca1000,
162500x9883ef,
162510xca1400,
162520xd40064,
162530x8000b0,
162540x000000,
162550xc41432,
162560xc61843,
162570xc4082f,
162580x954005,
162590xc40c30,
162600xd4401e,
162610x800000,
162620xee001e,
162630x9583f5,
162640xc41031,
162650xd44033,
162660xd52065,
162670xd4a01c,
162680xd4e01c,
162690xd5201c,
162700xe4015e,
162710xd4001e,
162720x800000,
162730x062001,
162740xca1800,
162750x0a2001,
162760xd60076,
162770xc40836,
162780x988007,
162790xc61045,
162800x950110,
162810xd4001f,
162820xd46062,
162830x800000,
162840xd42062,
162850xcc3835,
162860xcc1433,
162870x8401de,
162880xd40072,
162890xd5401e,
162900x800000,
162910xee001e,
162920xe2001a,
162930x8401de,
162940xe2001a,
162950xcc104b,
162960xcc0447,
162970x2c9401,
162980x7d098b,
162990x984005,
163000x7d15cb,
163010xd4001a,
163020x8001db,
163030xd4006d,
163040x344401,
163050xcc0c48,
163060x98403a,
163070xcc2c4a,
163080x958004,
163090xcc0449,
163100x8001db,
163110xd4001a,
163120xd4c01a,
163130x282801,
163140x840113,
163150xcc1003,
163160x98801b,
163170x04380c,
163180x840113,
163190xcc1003,
163200x988017,
163210x043808,
163220x840113,
163230xcc1003,
163240x988013,
163250x043804,
163260x840113,
163270xcc1003,
163280x988014,
163290xcc104c,
163300x9a8009,
163310xcc144d,
163320x9840dc,
163330xd4006d,
163340xcc1848,
163350xd5001a,
163360xd5401a,
163370x8000ec,
163380xd5801a,
163390x96c0d5,
163400xd4006d,
163410x8001db,
163420xd4006e,
163430x9ac003,
163440xd4006d,
163450xd4006e,
163460x800000,
163470xec007f,
163480x9ac0cc,
163490xd4006d,
163500x8001db,
163510xd4006e,
163520xcc1403,
163530xcc1803,
163540xcc1c03,
163550x7d9103,
163560x7dd583,
163570x7d190c,
163580x35cc1f,
163590x35701f,
163600x7cf0cb,
163610x7cd08b,
163620x880000,
163630x7e8e8b,
163640x95c004,
163650xd4006e,
163660x8001db,
163670xd4001a,
163680xd4c01a,
163690xcc0803,
163700xcc0c03,
163710xcc1003,
163720xcc1403,
163730xcc1803,
163740xcc1c03,
163750xcc2403,
163760xcc2803,
163770x35c41f,
163780x36b01f,
163790x7c704b,
163800x34f01f,
163810x7c704b,
163820x35701f,
163830x7c704b,
163840x7d8881,
163850x7dccc1,
163860x7e5101,
163870x7e9541,
163880x7c9082,
163890x7cd4c2,
163900x7c848b,
163910x9ac003,
163920x7c8c8b,
163930x2c8801,
163940x98809e,
163950xd4006d,
163960x98409c,
163970xd4006e,
163980xcc084c,
163990xcc0c4d,
164000xcc1048,
164010xd4801a,
164020xd4c01a,
164030x800124,
164040xd5001a,
164050xcc0832,
164060xd40032,
164070x9482b6,
164080xca0c00,
164090xd4401e,
164100x800000,
164110xd4001e,
164120xe4011e,
164130xd4001e,
164140xca0800,
164150xca0c00,
164160xca1000,
164170xd4401e,
164180xca1400,
164190xd4801e,
164200xd4c01e,
164210xd5001e,
164220xd5401e,
164230xd54034,
164240x800000,
164250xee001e,
164260x280404,
164270xe2001a,
164280xe2001a,
164290xd4401a,
164300xca3800,
164310xcc0803,
164320xcc0c03,
164330xcc0c03,
164340xcc0c03,
164350x98829a,
164360x000000,
164370x8401de,
164380xd7a06f,
164390x800000,
164400xee001f,
164410xca0400,
164420xc2ff00,
164430xcc0834,
164440xc13fff,
164450x7c74cb,
164460x7cc90b,
164470x7d010f,
164480x99028d,
164490x7c738b,
164500x8401de,
164510xd7a06f,
164520x800000,
164530xee001f,
164540xca0800,
164550x281900,
164560x7d898b,
164570x958014,
164580x281404,
164590xca0c00,
164600xca1000,
164610xca1c00,
164620xca2400,
164630xe2001f,
164640xd4c01a,
164650xd5001a,
164660xd5401a,
164670xcc1803,
164680xcc2c03,
164690xcc2c03,
164700xcc2c03,
164710x7da58b,
164720x7d9c47,
164730x984274,
164740x000000,
164750x800184,
164760xd4c01a,
164770xd4401e,
164780xd4801e,
164790x800000,
164800xee001e,
164810xe4011e,
164820xd4001e,
164830xd4401e,
164840xee001e,
164850xca0400,
164860xa00000,
164870x7e828b,
164880xe4013e,
164890xd4001e,
164900xd4401e,
164910xee001e,
164920xca0400,
164930xa00000,
164940x7e828b,
164950xca0800,
164960x248c06,
164970x0ccc06,
164980x98c006,
164990xcc104e,
165000x990004,
165010xd40073,
165020xe4011e,
165030xd4001e,
165040xd4401e,
165050xd4801e,
165060x800000,
165070xee001e,
165080xca0800,
165090xca0c00,
165100x34d018,
165110x251001,
165120x950021,
165130xc17fff,
165140xca1000,
165150xca1400,
165160xca1800,
165170xd4801d,
165180xd4c01d,
165190x7db18b,
165200xc14202,
165210xc2c001,
165220xd5801d,
165230x34dc0e,
165240x7d5d4c,
165250x7f734c,
165260xd7401e,
165270xd5001e,
165280xd5401e,
165290xc14200,
165300xc2c000,
165310x099c01,
165320x31dc10,
165330x7f5f4c,
165340x7f734c,
165350x042802,
165360x7d8380,
165370xd5a86f,
165380xd58066,
165390xd7401e,
165400xec005e,
165410xc82402,
165420xc82402,
165430x8001db,
165440xd60076,
165450xd4401e,
165460xd4801e,
165470xd4c01e,
165480x800000,
165490xee001e,
165500x800000,
165510xee001f,
165520xd4001f,
165530x800000,
165540xd4001f,
165550xd4001f,
165560x880000,
165570xd4001f,
165580x000000,
165590x000000,
165600x000000,
165610x000000,
165620x000000,
165630x000000,
165640x000000,
165650x000000,
165660x000000,
165670x000000,
165680x000000,
165690x000000,
165700x000000,
165710x000000,
165720x000000,
165730x000000,
165740x000000,
165750x000000,
165760x000000,
165770x000000,
165780x000000,
165790x000000,
165800x000000,
165810x000000,
165820x000000,
165830x000000,
165840x000000,
165850x000000,
165860x000000,
165870x000000,
165880x000000,
165890x010194,
165900x02019b,
165910x0300b2,
165920x0400a2,
165930x050003,
165940x06003f,
165950x070032,
165960x08014f,
165970x090046,
165980x0a0036,
165990x1001d9,
166000x1700c5,
166010x22015d,
166020x23016c,
166030x2000d7,
166040x240148,
166050x26004d,
166060x27005c,
166070x28008d,
166080x290051,
166090x2a007e,
166100x2b0061,
166110x2f0088,
166120x3200aa,
166130x3401a2,
166140x36006f,
166150x3c0179,
166160x3f0095,
166170x4101af,
166180x440151,
166190x550196,
166200x56019d,
166210x60000b,
166220x610034,
166230x620038,
166240x630038,
166250x640038,
166260x650038,
166270x660038,
166280x670038,
166290x68003a,
166300x690041,
166310x6a0048,
166320x6b0048,
166330x6c0048,
166340x6d0048,
166350x6e0048,
166360x6f0048,
166370x7301d9,
166380x000006,
166390x000006,
166400x000006,
166410x000006,
166420x000006,
166430x000006,
166440x000006,
166450x000006,
166460x000006,
166470x000006,
166480x000006,
166490x000006,
166500x000006,
166510x000006,
166520x000006,
16653};
16654
16655static const u32 RV770_cp_microcode[] = {
166560xcc0003ea,
166570x7c408000,
166580xa0000000,
166590xcc800062,
166600x80000001,
166610xd040007f,
166620x80000001,
166630xcc400041,
166640x7c40c000,
166650xc0160004,
166660x30d03fff,
166670x7d15000c,
166680xcc110000,
166690x28d8001e,
166700x31980001,
166710x28dc001f,
166720xc8200004,
166730x95c00006,
166740x7c424000,
166750xcc000062,
166760x7e56800c,
166770xcc290000,
166780xc8240004,
166790x7e26000b,
166800x95800006,
166810x7c42c000,
166820xcc000062,
166830x7ed7000c,
166840xcc310000,
166850xc82c0004,
166860x7e2e000c,
166870xcc000062,
166880x31103fff,
166890x80000001,
166900xce110000,
166910x7c40c000,
166920x80000001,
166930xcc400040,
166940x80000001,
166950xcc412257,
166960x7c418000,
166970xcc400045,
166980xcc400048,
166990xcc41225c,
167000xcc41a1fc,
167010x7c408000,
167020xa0000000,
167030xcc800062,
167040xcc400045,
167050xcc400048,
167060x7c40c000,
167070xcc41225c,
167080xcc41a1fc,
167090x7c408000,
167100xa0000000,
167110xcc800062,
167120xcc000045,
167130xcc000048,
167140xcc41225c,
167150xcc41a1fc,
167160x7c408000,
167170xa0000000,
167180xcc800062,
167190x040ca1fd,
167200xc0120001,
167210xcc000045,
167220xcc000048,
167230x7cd0c00c,
167240xcc41225c,
167250xcc41a1fc,
167260xd04d0000,
167270x7c408000,
167280xa0000000,
167290xcc800062,
167300x80000001,
167310xcc41225d,
167320x7c408000,
167330x7c40c000,
167340xc02a0002,
167350x7c410000,
167360x7d29000c,
167370x30940001,
167380x30980006,
167390x309c0300,
167400x29dc0008,
167410x7c420000,
167420x7c424000,
167430x9540000f,
167440xc02e0004,
167450x05f02258,
167460x7f2f000c,
167470xcc310000,
167480xc8280004,
167490xccc12169,
167500xcd01216a,
167510xce81216b,
167520x0db40002,
167530xcc01216c,
167540x9740000e,
167550x0db40000,
167560x8000007b,
167570xc834000a,
167580x0db40002,
167590x97400009,
167600x0db40000,
167610xc02e0004,
167620x05f02258,
167630x7f2f000c,
167640xcc310000,
167650xc8280004,
167660x8000007b,
167670xc834000a,
167680x97400004,
167690x7e028000,
167700x8000007b,
167710xc834000a,
167720x0db40004,
167730x9740ff8c,
167740x00000000,
167750xce01216d,
167760xce41216e,
167770xc8280003,
167780xc834000a,
167790x9b400004,
167800x043c0005,
167810x8400026d,
167820xcc000062,
167830x0df40000,
167840x9740000b,
167850xc82c03e6,
167860xce81a2b7,
167870xc0300006,
167880x7ef34028,
167890xc0300020,
167900x7f6b8020,
167910x7fb3c029,
167920xcf81a2c4,
167930x80000001,
167940xcfc1a2d1,
167950x0df40001,
167960x9740000b,
167970xc82c03e7,
167980xce81a2bb,
167990xc0300006,
168000x7ef34028,
168010xc0300020,
168020x7f6b8020,
168030x7fb3c029,
168040xcf81a2c5,
168050x80000001,
168060xcfc1a2d2,
168070x0df40002,
168080x9740000b,
168090xc82c03e8,
168100xce81a2bf,
168110xc0300006,
168120x7ef34028,
168130xc0300020,
168140x7f6b8020,
168150x7fb3c029,
168160xcf81a2c6,
168170x80000001,
168180xcfc1a2d3,
168190xc82c03e9,
168200xce81a2c3,
168210xc0300006,
168220x7ef34028,
168230xc0300020,
168240x7f6b8020,
168250x7fb3c029,
168260xcf81a2c7,
168270x80000001,
168280xcfc1a2d4,
168290x80000001,
168300xcc400042,
168310x7c40c000,
168320x7c410000,
168330x2914001d,
168340x31540001,
168350x9940000d,
168360x31181000,
168370xc81c0011,
168380x09dc0001,
168390x95c0ffff,
168400xc81c0011,
168410xccc12100,
168420xcd012101,
168430xccc12102,
168440xcd012103,
168450x04180004,
168460x8000039f,
168470xcd81a2a4,
168480xc02a0004,
168490x95800008,
168500x36a821a3,
168510xcc290000,
168520xc8280004,
168530xc81c0011,
168540x0de40040,
168550x9640ffff,
168560xc81c0011,
168570xccc12170,
168580xcd012171,
168590xc8200012,
168600x96000000,
168610xc8200012,
168620x8000039f,
168630xcc000064,
168640x7c40c000,
168650x7c410000,
168660xcc000045,
168670xcc000048,
168680x40d40003,
168690xcd41225c,
168700xcd01a1fc,
168710xc01a0001,
168720x041ca1fd,
168730x7dd9c00c,
168740x7c420000,
168750x08cc0001,
168760x06240001,
168770x06280002,
168780xce1d0000,
168790xce5d0000,
168800x98c0fffa,
168810xce9d0000,
168820x7c408000,
168830xa0000000,
168840xcc800062,
168850x7c40c000,
168860x30d00001,
168870x28cc0001,
168880x7c414000,
168890x95000006,
168900x7c418000,
168910xcd41216d,
168920xcd81216e,
168930x800000f3,
168940xc81c0003,
168950xc0220004,
168960x7e16000c,
168970xcc210000,
168980xc81c0004,
168990x7c424000,
169000x98c00004,
169010x7c428000,
169020x80000001,
169030xcde50000,
169040xce412169,
169050xce81216a,
169060xcdc1216b,
169070x80000001,
169080xcc01216c,
169090x7c40c000,
169100x7c410000,
169110x7c414000,
169120x7c418000,
169130x7c41c000,
169140x28a40008,
169150x326400ff,
169160x0e68003c,
169170x9680000a,
169180x7c020000,
169190x7c420000,
169200x1e300003,
169210xcc00006a,
169220x9b000003,
169230x42200005,
169240x04200040,
169250x80000110,
169260x7c024000,
169270x7e024000,
169280x9a400000,
169290x0a640001,
169300x30ec0010,
169310x9ac0000a,
169320xcc000062,
169330xc02a0004,
169340xc82c0021,
169350x7e92800c,
169360xcc000041,
169370xcc290000,
169380xcec00021,
169390x80000120,
169400xc8300004,
169410xcd01216d,
169420xcd41216e,
169430xc8300003,
169440x7f1f000b,
169450x30f40007,
169460x27780001,
169470x9740002a,
169480x07b80125,
169490x9f800000,
169500x00000000,
169510x80000135,
169520x7f1b8004,
169530x80000139,
169540x7f1b8005,
169550x8000013d,
169560x7f1b8002,
169570x80000141,
169580x7f1b8003,
169590x80000145,
169600x7f1b8007,
169610x80000149,
169620x7f1b8006,
169630x8000014e,
169640x28a40008,
169650x9b800019,
169660x28a40008,
169670x8000015e,
169680x326400ff,
169690x9b800015,
169700x28a40008,
169710x8000015e,
169720x326400ff,
169730x9b800011,
169740x28a40008,
169750x8000015e,
169760x326400ff,
169770x9b80000d,
169780x28a40008,
169790x8000015e,
169800x326400ff,
169810x9b800009,
169820x28a40008,
169830x8000015e,
169840x326400ff,
169850x9b800005,
169860x28a40008,
169870x8000015e,
169880x326400ff,
169890x28a40008,
169900x326400ff,
169910x0e68003c,
169920x9a80feb1,
169930x28ec0008,
169940x7c434000,
169950x7c438000,
169960x7c43c000,
169970x96c00007,
169980xcc000062,
169990xcf412169,
170000xcf81216a,
170010xcfc1216b,
170020x80000001,
170030xcc01216c,
170040x80000001,
170050xcff50000,
170060xcc00006b,
170070x840003a2,
170080x0e68003c,
170090x9a800004,
170100xc8280015,
170110x80000001,
170120xd040007f,
170130x9680ffab,
170140x7e024000,
170150x8400023b,
170160xc00e0002,
170170xcc000041,
170180x80000239,
170190xccc1304a,
170200x7c40c000,
170210x7c410000,
170220xc01e0001,
170230x29240012,
170240xc0220002,
170250x96400005,
170260xc0260004,
170270xc027fffb,
170280x7d25000b,
170290xc0260000,
170300x7dd2800b,
170310x7e12c00b,
170320x7d25000c,
170330x7c414000,
170340x7c418000,
170350xccc12169,
170360x9a80000a,
170370xcd01216a,
170380xcd41216b,
170390x96c0fe82,
170400xcd81216c,
170410xc8300018,
170420x97000000,
170430xc8300018,
170440x80000001,
170450xcc000018,
170460x840003a2,
170470xcc00007f,
170480xc8140013,
170490xc8180014,
170500xcd41216b,
170510x96c0fe76,
170520xcd81216c,
170530x80000182,
170540xc8300018,
170550xc80c0008,
170560x98c00000,
170570xc80c0008,
170580x7c410000,
170590x95000002,
170600x00000000,
170610x7c414000,
170620xc8200009,
170630xcc400043,
170640xce01a1f4,
170650xcc400044,
170660xc00e8000,
170670x7c424000,
170680x7c428000,
170690x2aac001f,
170700x96c0fe63,
170710xc035f000,
170720xce4003e2,
170730x32780003,
170740x267c0008,
170750x7ff7c00b,
170760x7ffbc00c,
170770x2a780018,
170780xcfc003e3,
170790xcf8003e4,
170800x26b00002,
170810x7f3f0000,
170820xcf0003e5,
170830x8000031f,
170840x7c80c000,
170850x7c40c000,
170860x28d00008,
170870x3110000f,
170880x9500000f,
170890x25280001,
170900x06a801b3,
170910x9e800000,
170920x00000000,
170930x800001d4,
170940xc0120800,
170950x800001e2,
170960xc814000f,
170970x800001e9,
170980xc8140010,
170990x800001f0,
171000xccc1a2a4,
171010x800001f9,
171020xc8140011,
171030x30d0003f,
171040x0d280015,
171050x9a800012,
171060x0d28001e,
171070x9a80001e,
171080x0d280020,
171090x9a800023,
171100x0d24000f,
171110x0d280010,
171120x7e6a800c,
171130x9a800026,
171140x0d200004,
171150x0d240014,
171160x0d280028,
171170x7e62400c,
171180x7ea6800c,
171190x9a80002a,
171200xc8140011,
171210x80000001,
171220xccc1a2a4,
171230xc0120800,
171240x7c414000,
171250x7d0cc00c,
171260xc0120008,
171270x29580003,
171280x295c000c,
171290x7c420000,
171300x7dd1c00b,
171310x26200014,
171320x7e1e400c,
171330x7e4e800c,
171340xce81a2a4,
171350x80000001,
171360xcd81a1fe,
171370xc814000f,
171380x0410210e,
171390x95400000,
171400xc814000f,
171410xd0510000,
171420x80000001,
171430xccc1a2a4,
171440xc8140010,
171450x04102108,
171460x95400000,
171470xc8140010,
171480xd0510000,
171490x80000001,
171500xccc1a2a4,
171510xccc1a2a4,
171520x04100001,
171530xcd000019,
171540x840003a2,
171550xcc00007f,
171560xc8100019,
171570x99000000,
171580xc8100019,
171590x80000002,
171600x7c408000,
171610x04102100,
171620x09540001,
171630x9540ffff,
171640xc8140011,
171650xd0510000,
171660x8000039f,
171670xccc1a2a4,
171680x7c40c000,
171690xcc40000d,
171700x94c0fdff,
171710xcc40000e,
171720x7c410000,
171730x95000005,
171740x08cc0001,
171750xc8140005,
171760x99400014,
171770x00000000,
171780x98c0fffb,
171790x7c410000,
171800x80000002,
171810x7d008000,
171820xc8140005,
171830x7c40c000,
171840x9940000c,
171850xc818000c,
171860x7c410000,
171870x9580fdee,
171880xc820000e,
171890xc81c000d,
171900x66200020,
171910x7e1e002c,
171920x25240002,
171930x7e624020,
171940x80000001,
171950xcce60000,
171960x7c410000,
171970xcc00006c,
171980xcc00006d,
171990xc818001f,
172000xc81c001e,
172010x65980020,
172020x7dd9c02c,
172030x7cd4c00c,
172040xccde0000,
172050x45dc0004,
172060xc8280017,
172070x9680000f,
172080xc00e0001,
172090x28680008,
172100x2aac0016,
172110x32a800ff,
172120x0eb00049,
172130x7f2f000b,
172140x97000006,
172150x00000000,
172160xc8140005,
172170x7c40c000,
172180x80000223,
172190x7c410000,
172200x80000226,
172210xd040007f,
172220x8400023b,
172230xcc000041,
172240xccc1304a,
172250x94000000,
172260xc83c001a,
172270x043c0005,
172280xcfc1a2a4,
172290xc0361f90,
172300xc0387fff,
172310x7c03c010,
172320x7f7b400c,
172330xcf41217c,
172340xcfc1217d,
172350xcc01217e,
172360xc03a0004,
172370x0434217f,
172380x7f7b400c,
172390xcc350000,
172400xc83c0004,
172410x2bfc001f,
172420x04380020,
172430x97c00005,
172440xcc000062,
172450x9b800000,
172460x0bb80001,
172470x80000247,
172480xcc000071,
172490xcc01a1f4,
172500x04380016,
172510xc0360002,
172520xcf81a2a4,
172530x88000000,
172540xcf412010,
172550x7c40c000,
172560x28d0001c,
172570x95000005,
172580x04d40001,
172590xcd400065,
172600x80000001,
172610xcd400068,
172620x09540002,
172630x80000001,
172640xcd400066,
172650x8400026c,
172660xc81803ea,
172670x7c40c000,
172680x9980fd9d,
172690xc8140016,
172700x08d00001,
172710x9940002b,
172720xcd000068,
172730x7c408000,
172740xa0000000,
172750xcc800062,
172760x043c0005,
172770xcfc1a2a4,
172780xcc01a1f4,
172790x840003a2,
172800xcc000046,
172810x88000000,
172820xcc00007f,
172830x8400027e,
172840xc81803ea,
172850x7c40c000,
172860x9980fd8b,
172870xc8140016,
172880x08d00001,
172890x99400019,
172900xcd000068,
172910x7c408000,
172920xa0000000,
172930xcc800062,
172940x043c0022,
172950xcfc1a2a4,
172960x840003a2,
172970xcc000047,
172980x88000000,
172990xcc00007f,
173000xc8100016,
173010x9900000d,
173020xcc400067,
173030x80000002,
173040x7c408000,
173050xc81803ea,
173060x9980fd77,
173070x7c40c000,
173080x94c00003,
173090xc8100016,
173100x99000004,
173110xccc00068,
173120x80000002,
173130x7c408000,
173140x8400023b,
173150xc0148000,
173160xcc000041,
173170xcd41304a,
173180xc0148000,
173190x99000000,
173200xc8100016,
173210x80000002,
173220x7c408000,
173230xc0120001,
173240x7c51400c,
173250x80000001,
173260xd0550000,
173270x7c40c000,
173280x7c410000,
173290x7c414000,
173300x7c418000,
173310x291c001f,
173320xccc0004a,
173330xcd00004b,
173340x95c00003,
173350xc01c8000,
173360xcdc12010,
173370xdd830000,
173380x055c2000,
173390xcc000062,
173400x80000001,
173410xd81f4100,
173420x7c40c000,
173430x7c410000,
173440x7c414000,
173450x7c418000,
173460xccc0004c,
173470xcd00004d,
173480xdd830000,
173490x055ca000,
173500x80000001,
173510xd81f4100,
173520x7c40c000,
173530x7c410000,
173540x7c414000,
173550x7c418000,
173560xccc0004e,
173570xcd00004f,
173580xdd830000,
173590x055cc000,
173600x80000001,
173610xd81f4100,
173620x7c40c000,
173630x7c410000,
173640x7c414000,
173650x7c418000,
173660xccc00050,
173670xcd000051,
173680xdd830000,
173690x055cf8e0,
173700x80000001,
173710xd81f4100,
173720x7c40c000,
173730x7c410000,
173740x7c414000,
173750x7c418000,
173760xccc00052,
173770xcd000053,
173780xdd830000,
173790x055cf880,
173800x80000001,
173810xd81f4100,
173820x7c40c000,
173830x7c410000,
173840x7c414000,
173850x7c418000,
173860xccc00054,
173870xcd000055,
173880xdd830000,
173890x055ce000,
173900x80000001,
173910xd81f4100,
173920x7c40c000,
173930x7c410000,
173940x7c414000,
173950x7c418000,
173960xccc00056,
173970xcd000057,
173980xdd830000,
173990x055cf000,
174000x80000001,
174010xd81f4100,
174020x7c40c000,
174030x7c410000,
174040x7c414000,
174050x7c418000,
174060xccc00058,
174070xcd000059,
174080xdd830000,
174090x055cf3fc,
174100x80000001,
174110xd81f4100,
174120xd0432000,
174130x7c408000,
174140xa0000000,
174150xcc800062,
174160xd043a000,
174170x7c408000,
174180xa0000000,
174190xcc800062,
174200xd043c000,
174210x7c408000,
174220xa0000000,
174230xcc800062,
174240xd043f8e0,
174250x7c408000,
174260xa0000000,
174270xcc800062,
174280xd043f880,
174290x7c408000,
174300xa0000000,
174310xcc800062,
174320xd043e000,
174330x7c408000,
174340xa0000000,
174350xcc800062,
174360xd043f000,
174370x7c408000,
174380xa0000000,
174390xcc800062,
174400xd043f3fc,
174410x7c408000,
174420xa0000000,
174430xcc800062,
174440xc81403e0,
174450xcc430000,
174460xcc430000,
174470xcc430000,
174480x7d45c000,
174490xcdc30000,
174500xd0430000,
174510x7c408000,
174520xa0000000,
174530xcc800062,
174540x7c40c000,
174550xc81003e2,
174560xc81403e5,
174570xc81803e3,
174580xc81c03e4,
174590xcd812169,
174600xcdc1216a,
174610xccc1216b,
174620xcc01216c,
174630x04200004,
174640x7da18000,
174650x7d964002,
174660x9640fcd7,
174670xcd8003e3,
174680x31280003,
174690xc02df000,
174700x25180008,
174710x7dad800b,
174720x7da9800c,
174730x80000001,
174740xcd8003e3,
174750x308cffff,
174760xd04d0000,
174770x7c408000,
174780xa0000000,
174790xcc800062,
174800x7c40c000,
174810x7c410000,
174820x29240018,
174830x32640001,
174840x9a400013,
174850xc8140020,
174860x15580002,
174870x9580ffff,
174880xc8140020,
174890xcc00006e,
174900xccc12180,
174910xcd01218d,
174920xcc412181,
174930x2914001f,
174940x34588000,
174950xcd81218c,
174960x9540fcb9,
174970xcc412182,
174980xc8140020,
174990x9940ffff,
175000xc8140020,
175010x80000002,
175020x7c408000,
175030x7c414000,
175040x7c418000,
175050x7c41c000,
175060x65b40020,
175070x7f57402c,
175080xd4378100,
175090x47740004,
175100xd4378100,
175110x47740004,
175120xd4378100,
175130x47740004,
175140x09dc0004,
175150xd4378100,
175160x99c0fff8,
175170x47740004,
175180x2924001f,
175190xc0380019,
175200x9640fca1,
175210xc03e0004,
175220xcf8121f8,
175230x37e021f9,
175240xcc210000,
175250xc8200004,
175260x2a200018,
175270x32200001,
175280x9a00fffb,
175290xcf8121f8,
175300x80000002,
175310x7c408000,
175320x7c40c000,
175330x28d00018,
175340x31100001,
175350xc0160080,
175360x95000003,
175370xc02a0004,
175380x7cd4c00c,
175390xccc1217c,
175400xcc41217d,
175410xcc41217e,
175420x7c418000,
175430x1db00003,
175440x36a0217f,
175450x9b000003,
175460x419c0005,
175470x041c0040,
175480x99c00000,
175490x09dc0001,
175500xcc210000,
175510xc8240004,
175520x2a6c001f,
175530x419c0005,
175540x9ac0fffa,
175550xcc800062,
175560x80000002,
175570x7c408000,
175580x7c40c000,
175590x04d403e6,
175600x80000001,
175610xcc540000,
175620x8000039f,
175630xcc4003ea,
175640xc01c8000,
175650x044ca000,
175660xcdc12010,
175670x7c410000,
175680xc8140009,
175690x04180000,
175700x041c0008,
175710xcd800071,
175720x09dc0001,
175730x05980001,
175740xcd0d0000,
175750x99c0fffc,
175760xcc800062,
175770x8000039f,
175780xcd400071,
175790xc00e0100,
175800xcc000041,
175810xccc1304a,
175820xc83c007f,
175830xcc00007f,
175840x80000001,
175850xcc00007f,
175860xcc00007f,
175870x88000000,
175880xcc00007f,
175890x00000000,
175900x00000000,
175910x00000000,
175920x00000000,
175930x00000000,
175940x00000000,
175950x00000000,
175960x00000000,
175970x00000000,
175980x00000000,
175990x00000000,
176000x00000000,
176010x00000000,
176020x00000000,
176030x00000000,
176040x00000000,
176050x00000000,
176060x00000000,
176070x00000000,
176080x00000000,
176090x00000000,
176100x00000000,
176110x00000000,
176120x00000000,
176130x00000000,
176140x00000000,
176150x00000000,
176160x00000000,
176170x00000000,
176180x00000000,
176190x00000000,
176200x00000000,
176210x00000000,
176220x00000000,
176230x00000000,
176240x00000000,
176250x00000000,
176260x00000000,
176270x00000000,
176280x00000000,
176290x00000000,
176300x00000000,
176310x00000000,
176320x00000000,
176330x00000000,
176340x00000000,
176350x00000000,
176360x00000000,
176370x00000000,
176380x00000000,
176390x00000000,
176400x00000000,
176410x00000000,
176420x00000000,
176430x00000000,
176440x00000000,
176450x00000000,
176460x00000000,
176470x00000000,
176480x00000000,
176490x00000000,
176500x00000000,
176510x00000000,
176520x00000000,
176530x00000000,
176540x00000000,
176550x00000000,
176560x00000000,
176570x00000000,
176580x00000000,
176590x00000000,
176600x00000000,
176610x00000000,
176620x00000000,
176630x00000000,
176640x00000000,
176650x00000000,
176660x00000000,
176670x00000000,
176680x00000000,
176690x00000000,
176700x00000000,
176710x00000000,
176720x00000000,
176730x00000000,
176740x00000000,
176750x00000000,
176760x00000000,
176770x00000000,
176780x00000000,
176790x00000000,
176800x00000000,
176810x00000000,
176820x00000000,
176830x00000000,
176840x00000000,
176850x00000000,
176860x00000000,
176870x00000000,
176880x00000000,
176890x00000000,
176900x00000000,
176910x00000000,
176920x00000000,
176930x00000000,
176940x00000000,
176950x00000000,
176960x00000000,
176970x00000000,
176980x00000000,
176990x00000000,
177000x00000000,
177010x00000000,
177020x00000000,
177030x00000000,
177040x00000000,
177050x00000000,
177060x00000000,
177070x00000000,
177080x00000000,
177090x00000000,
177100x00000000,
177110x00000000,
177120x00000000,
177130x00000000,
177140x00000000,
177150x00000000,
177160x00000000,
177170x00000000,
177180x00000000,
177190x00000000,
177200x00000000,
177210x00000000,
177220x00000000,
177230x00000000,
177240x00000000,
177250x00000000,
177260x00000000,
177270x00000000,
177280x00000000,
177290x00000000,
177300x00000000,
177310x00000000,
177320x00000000,
177330x00000000,
177340x00000000,
177350x00000000,
177360x00000000,
177370x00000000,
177380x00000000,
177390x00000000,
177400x00000000,
177410x00000000,
177420x00000000,
177430x00000000,
177440x00000000,
177450x00000000,
177460x00000000,
177470x00000000,
177480x00000000,
177490x00000000,
177500x00000000,
177510x00000000,
177520x00000000,
177530x00000000,
177540x00000000,
177550x00000000,
177560x00000000,
177570x00000000,
177580x00000000,
177590x00000000,
177600x00000000,
177610x00000000,
177620x00000000,
177630x00000000,
177640x00000000,
177650x00000000,
177660x00000000,
177670x00000000,
177680x00000000,
177690x00000000,
177700x00000000,
177710x00000000,
177720x00000000,
177730x00000000,
177740x00000000,
177750x00000000,
177760x00000000,
177770x00000000,
177780x00000000,
177790x00000000,
177800x00000000,
177810x00000000,
177820x00000000,
177830x00000000,
177840x00000000,
177850x00000000,
177860x00000000,
177870x00000000,
177880x00000000,
177890x00000000,
177900x00000000,
177910x00000000,
177920x00000000,
177930x00000000,
177940x00000000,
177950x00000000,
177960x00000000,
177970x00000000,
177980x00000000,
177990x00000000,
178000x00000000,
178010x00000000,
178020x00000000,
178030x00000000,
178040x00000000,
178050x00000000,
178060x00000000,
178070x00000000,
178080x00000000,
178090x00000000,
178100x00000000,
178110x00000000,
178120x00000000,
178130x00000000,
178140x00000000,
178150x00000000,
178160x00000000,
178170x00000000,
178180x00000000,
178190x00000000,
178200x00000000,
178210x00000000,
178220x00000000,
178230x00000000,
178240x00000000,
178250x00000000,
178260x00000000,
178270x00000000,
178280x00000000,
178290x00000000,
178300x00000000,
178310x00000000,
178320x00000000,
178330x00000000,
178340x00000000,
178350x00000000,
178360x00000000,
178370x00000000,
178380x00000000,
178390x00000000,
178400x00000000,
178410x00000000,
178420x00000000,
178430x00000000,
178440x00000000,
178450x00000000,
178460x00000000,
178470x00000000,
178480x00000000,
178490x00000000,
178500x00000000,
178510x00000000,
178520x00000000,
178530x00000000,
178540x00000000,
178550x00000000,
178560x00000000,
178570x00000000,
178580x00000000,
178590x00000000,
178600x00000000,
178610x00000000,
178620x00000000,
178630x00000000,
178640x00000000,
178650x00000000,
178660x00000000,
178670x00000000,
178680x00000000,
178690x00000000,
178700x00000000,
178710x00000000,
178720x00000000,
178730x00000000,
178740x00000000,
178750x00000000,
178760x00000000,
178770x00000000,
178780x00000000,
178790x00000000,
178800x00000000,
178810x00000000,
178820x00000000,
178830x00000000,
178840x00000000,
178850x00000000,
178860x00000000,
178870x00000000,
178880x00000000,
178890x00000000,
178900x00000000,
178910x00000000,
178920x00000000,
178930x00000000,
178940x00000000,
178950x00000000,
178960x00000000,
178970x00000000,
178980x00000000,
178990x00000000,
179000x00000000,
179010x00000000,
179020x00000000,
179030x00000000,
179040x00000000,
179050x00000000,
179060x00000000,
179070x00000000,
179080x00000000,
179090x00000000,
179100x00000000,
179110x00000000,
179120x00000000,
179130x00000000,
179140x00000000,
179150x00000000,
179160x00000000,
179170x00000000,
179180x00000000,
179190x00000000,
179200x00000000,
179210x00000000,
179220x00000000,
179230x00000000,
179240x00000000,
179250x00000000,
179260x00000000,
179270x00000000,
179280x00000000,
179290x00000000,
179300x00000000,
179310x00000000,
179320x00000000,
179330x00000000,
179340x00000000,
179350x00000000,
179360x00010333,
179370x00100004,
179380x00170006,
179390x00210008,
179400x00270028,
179410x00280023,
179420x00290029,
179430x002a0026,
179440x002b0029,
179450x002d0038,
179460x002e003f,
179470x002f004a,
179480x0034004c,
179490x00360030,
179500x003900af,
179510x003a00d0,
179520x003b00e5,
179530x003c00fd,
179540x003d016c,
179550x003f00ad,
179560x00410338,
179570x0043036c,
179580x0044018f,
179590x004500fd,
179600x004601ad,
179610x004701ad,
179620x00480200,
179630x0049020e,
179640x004a0257,
179650x004b0284,
179660x00520261,
179670x00530273,
179680x00540289,
179690x0057029b,
179700x0060029f,
179710x006102ae,
179720x006202b8,
179730x006302c2,
179740x006402cc,
179750x006502d6,
179760x006602e0,
179770x006702ea,
179780x006802f4,
179790x006902f8,
179800x006a02fc,
179810x006b0300,
179820x006c0304,
179830x006d0308,
179840x006e030c,
179850x006f0310,
179860x00700314,
179870x00720386,
179880x0074038c,
179890x0079038a,
179900x007c031e,
179910x000f039b,
179920x000f039b,
179930x000f039b,
179940x000f039b,
179950x000f039b,
179960x000f039b,
179970x000f039b,
179980x000f039b,
179990x000f039b,
180000x000f039b,
180010x000f039b,
180020x000f039b,
180030x000f039b,
180040x000f039b,
180050x000f039b,
180060x000f039b,
180070x000f039b,
180080x000f039b,
180090x000f039b,
180100x000f039b,
180110x000f039b,
180120x000f039b,
180130x000f039b,
180140x000f039b,
180150x000f039b,
18016};
18017
18018static const u32 RV770_pfp_microcode[] = {
180190x7c408000,
180200xa0000000,
180210x7e82800b,
180220x80000000,
180230xdc030000,
180240xcc800040,
180250xd0400040,
180260x7c408000,
180270xa0000000,
180280x7e82800b,
180290xc818000e,
180300x31980001,
180310x7c424000,
180320x95800252,
180330x7c428000,
180340xc81c001c,
180350xc037c000,
180360x7c40c000,
180370x7c410000,
180380x7cb4800b,
180390xc0360003,
180400x99c00000,
180410xc81c001c,
180420x7cb4800c,
180430x24d40002,
180440x7d654000,
180450xcd400043,
180460xce800043,
180470xcd000043,
180480xcc800040,
180490xce400040,
180500xce800040,
180510xccc00040,
180520xdc3a0000,
180530x9780ffde,
180540xcd000040,
180550x7c40c000,
180560x80000018,
180570x7c410000,
180580xd4000340,
180590xd4000fc0,
180600xd4000fa2,
180610xc818000e,
180620x8000000c,
180630x31980002,
180640xd40003c0,
180650xd4000fc0,
180660xd4000fa2,
180670xc818000e,
180680x288c0008,
180690x30cc000f,
180700x34100001,
180710x7d0d0008,
180720x8000000c,
180730x7d91800b,
180740xcc800040,
180750xd0400040,
180760x7c408000,
180770xa0000000,
180780x7e82800b,
180790xd4000340,
180800xd4000fc0,
180810xd4000fa2,
180820xcc800040,
180830xd0400040,
180840x7c408000,
180850xa0000000,
180860x7e82800b,
180870xd40003c0,
180880xd4000fc0,
180890xd4000fa2,
180900xcc800040,
180910xd0400040,
180920x7c408000,
180930xa0000000,
180940x7e82800b,
180950xcc4003f9,
180960x80000261,
180970xcc4003f8,
180980xc82003f8,
180990xc81c03f9,
181000xc81803fb,
181010xc037ffff,
181020x7c414000,
181030xcf41a29e,
181040x66200020,
181050x7de1c02c,
181060x7d58c008,
181070x7cdcc020,
181080x68d00020,
181090xc0360003,
181100xcc000054,
181110x7cb4800c,
181120x8000006a,
181130xcc800040,
181140x7c418000,
181150xcd81a29e,
181160xcc800040,
181170xcd800040,
181180x80000068,
181190xcc000054,
181200xc019ffff,
181210xcc800040,
181220xcd81a29e,
181230x7c40c000,
181240x7c410000,
181250x7c414000,
181260xccc1a1fa,
181270xcd01a1f9,
181280xcd41a29d,
181290xccc00040,
181300xcd000040,
181310xcd400040,
181320xcc400040,
181330x7c408000,
181340xa0000000,
181350x7e82800b,
181360xcc000054,
181370xcc800040,
181380x7c40c000,
181390x7c410000,
181400x7c414000,
181410xccc1a1fa,
181420xcd01a1f9,
181430xcd41a29d,
181440xccc00040,
181450xcd000040,
181460xcd400040,
181470xd0400040,
181480x7c408000,
181490xa0000000,
181500x7e82800b,
181510x7c40c000,
181520x30d00001,
181530xccc1a29f,
181540x95000003,
181550x04140001,
181560x04140002,
181570xcd4003fb,
181580xcc800040,
181590x80000000,
181600xccc00040,
181610x7c40c000,
181620xcc800040,
181630xccc1a2a2,
181640x80000000,
181650xccc00040,
181660x7c40c000,
181670x28d4001f,
181680xcc800040,
181690x95400003,
181700x7c410000,
181710xccc00057,
181720x2918001f,
181730xccc00040,
181740x95800003,
181750xcd000040,
181760xcd000058,
181770x80000261,
181780xcc00007f,
181790xc8200017,
181800xc8300022,
181810x9a000006,
181820x0e280001,
181830xc824001e,
181840x0a640001,
181850xd4001240,
181860xce400040,
181870xc036c000,
181880x96800007,
181890x37747900,
181900x041c0001,
181910xcf400040,
181920xcdc00040,
181930xcf0003fa,
181940x7c030000,
181950xca0c0010,
181960x7c410000,
181970x94c00004,
181980x7c414000,
181990xd42002c4,
182000xcde00044,
182010x9b00000b,
182020x7c418000,
182030xcc00004b,
182040xcda00049,
182050xcd200041,
182060xcd600041,
182070xcda00041,
182080x06200001,
182090xce000056,
182100x80000261,
182110xcc00007f,
182120xc8280020,
182130xc82c0021,
182140xcc000063,
182150x7eea4001,
182160x65740020,
182170x7f53402c,
182180x269c0002,
182190x7df5c020,
182200x69f80020,
182210xce80004b,
182220xce600049,
182230xcde00041,
182240xcfa00041,
182250xce600041,
182260x271c0002,
182270x7df5c020,
182280x69f80020,
182290x7db24001,
182300xcf00004b,
182310xce600049,
182320xcde00041,
182330xcfa00041,
182340x800000bd,
182350xce600041,
182360xc8200017,
182370xc8300022,
182380x9a000006,
182390x0e280001,
182400xc824001e,
182410x0a640001,
182420xd4001240,
182430xce400040,
182440xca0c0010,
182450x7c410000,
182460x94c0000b,
182470xc036c000,
182480x96800007,
182490x37747900,
182500x041c0001,
182510xcf400040,
182520xcdc00040,
182530xcf0003fa,
182540x7c030000,
182550x800000b6,
182560x7c414000,
182570xcc000048,
182580x800000ef,
182590x00000000,
182600xc8200017,
182610xc81c0023,
182620x0e240002,
182630x99c00015,
182640x7c418000,
182650x0a200001,
182660xce000056,
182670xd4000440,
182680xcc000040,
182690xc036c000,
182700xca140013,
182710x96400007,
182720x37747900,
182730xcf400040,
182740xcc000040,
182750xc83003fa,
182760x80000104,
182770xcf000022,
182780xcc000022,
182790x9540015d,
182800xcc00007f,
182810xcca00046,
182820x80000000,
182830xcc200046,
182840x80000261,
182850xcc000064,
182860xc8200017,
182870xc810001f,
182880x96000005,
182890x09100001,
182900xd4000440,
182910xcd000040,
182920xcd000022,
182930xcc800040,
182940xd0400040,
182950xc80c0025,
182960x94c0feeb,
182970xc8100008,
182980xcd000040,
182990xd4000fc0,
183000x80000000,
183010xd4000fa2,
183020x7c40c000,
183030x7c410000,
183040xccc003fd,
183050xcd0003fc,
183060xccc00042,
183070xcd000042,
183080x2914001f,
183090x29180010,
183100x31980007,
183110x3b5c0001,
183120x7d76000b,
183130x99800005,
183140x7d5e400b,
183150xcc000042,
183160x80000261,
183170xcc00004d,
183180x29980001,
183190x292c0008,
183200x9980003d,
183210x32ec0001,
183220x96000004,
183230x2930000c,
183240x80000261,
183250xcc000042,
183260x04140010,
183270xcd400042,
183280x33300001,
183290x34280001,
183300x8400015e,
183310xc8140003,
183320x9b40001b,
183330x0438000c,
183340x8400015e,
183350xc8140003,
183360x9b400017,
183370x04380008,
183380x8400015e,
183390xc8140003,
183400x9b400013,
183410x04380004,
183420x8400015e,
183430xc8140003,
183440x9b400015,
183450xc80c03fd,
183460x9a800009,
183470xc81003fc,
183480x9b000118,
183490xcc00004d,
183500x04140010,
183510xccc00042,
183520xcd000042,
183530x80000136,
183540xcd400042,
183550x96c00111,
183560xcc00004d,
183570x80000261,
183580xcc00004e,
183590x9ac00003,
183600xcc00004d,
183610xcc00004e,
183620xdf830000,
183630x80000000,
183640xd80301ff,
183650x9ac00107,
183660xcc00004d,
183670x80000261,
183680xcc00004e,
183690xc8180003,
183700xc81c0003,
183710xc8200003,
183720x7d5d4003,
183730x7da1c003,
183740x7d5d400c,
183750x2a10001f,
183760x299c001f,
183770x7d1d000b,
183780x7d17400b,
183790x88000000,
183800x7e92800b,
183810x96400004,
183820xcc00004e,
183830x80000261,
183840xcc000042,
183850x04380008,
183860xcf800042,
183870xc8080003,
183880xc80c0003,
183890xc8100003,
183900xc8140003,
183910xc8180003,
183920xc81c0003,
183930xc8240003,
183940xc8280003,
183950x29fc001f,
183960x2ab0001f,
183970x7ff3c00b,
183980x28f0001f,
183990x7ff3c00b,
184000x2970001f,
184010x7ff3c00b,
184020x7d888001,
184030x7dccc001,
184040x7e510001,
184050x7e954001,
184060x7c908002,
184070x7cd4c002,
184080x7cbc800b,
184090x9ac00003,
184100x7c8f400b,
184110x38b40001,
184120x9b4000d8,
184130xcc00004d,
184140x9bc000d6,
184150xcc00004e,
184160xc80c03fd,
184170xc81003fc,
184180xccc00042,
184190x8000016f,
184200xcd000042,
184210xd4000340,
184220xd4000fc0,
184230xd4000fa2,
184240xcc800040,
184250xcc400040,
184260xcc400040,
184270xcc400040,
184280x7c40c000,
184290xccc00040,
184300xccc0000d,
184310x80000000,
184320xd0400040,
184330x7c40c000,
184340x7c410000,
184350x65140020,
184360x7d4d402c,
184370x24580002,
184380x7d598020,
184390x7c41c000,
184400xcd800042,
184410x69980020,
184420xcd800042,
184430xcdc00042,
184440xc023c000,
184450x05e40002,
184460x7ca0800b,
184470x26640010,
184480x7ca4800c,
184490xcc800040,
184500xcdc00040,
184510xccc00040,
184520x95c0000e,
184530xcd000040,
184540x09dc0001,
184550xc8280003,
184560x96800008,
184570xce800040,
184580xc834001d,
184590x97400000,
184600xc834001d,
184610x26a80008,
184620x84000264,
184630xcc2b0000,
184640x99c0fff7,
184650x09dc0001,
184660xdc3a0000,
184670x97800004,
184680x7c418000,
184690x800001a3,
184700x25980002,
184710xa0000000,
184720x7d808000,
184730xc818001d,
184740x7c40c000,
184750x64d00008,
184760x95800000,
184770xc818001d,
184780xcc130000,
184790xcc800040,
184800xccc00040,
184810x80000000,
184820xcc400040,
184830xc810001f,
184840x7c40c000,
184850xcc800040,
184860x7cd1400c,
184870xcd400040,
184880x05180001,
184890x80000000,
184900xcd800022,
184910x7c40c000,
184920x64500020,
184930x84000264,
184940xcc000061,
184950x7cd0c02c,
184960xc8200017,
184970xc8d60000,
184980x99400008,
184990x7c438000,
185000xdf830000,
185010xcfa0004f,
185020x84000264,
185030xcc000062,
185040x80000000,
185050xd040007f,
185060x80000261,
185070xcc000062,
185080x84000264,
185090xcc000061,
185100xc8200017,
185110x7c40c000,
185120xc036ff00,
185130xc810000d,
185140xc0303fff,
185150x7cf5400b,
185160x7d51800b,
185170x7d81800f,
185180x99800008,
185190x7cf3800b,
185200xdf830000,
185210xcfa0004f,
185220x84000264,
185230xcc000062,
185240x80000000,
185250xd040007f,
185260x80000261,
185270xcc000062,
185280x84000264,
185290x7c40c000,
185300x28dc0008,
185310x95c00019,
185320x30dc0010,
185330x7c410000,
185340x99c00004,
185350x64540020,
185360x80000209,
185370xc91d0000,
185380x7d15002c,
185390xc91e0000,
185400x7c420000,
185410x7c424000,
185420x7c418000,
185430x7de5c00b,
185440x7de28007,
185450x9a80000e,
185460x41ac0005,
185470x9ac00000,
185480x0aec0001,
185490x30dc0010,
185500x99c00004,
185510x00000000,
185520x8000020c,
185530xc91d0000,
185540x8000020c,
185550xc91e0000,
185560xcc800040,
185570xccc00040,
185580xd0400040,
185590xc80c0025,
185600x94c0fde3,
185610xc8100008,
185620xcd000040,
185630xd4000fc0,
185640x80000000,
185650xd4000fa2,
185660xd4000340,
185670xd4000fc0,
185680xd4000fa2,
185690xcc800040,
185700xd0400040,
185710x7c408000,
185720xa0000000,
185730x7e82800b,
185740xd40003c0,
185750xd4000fc0,
185760xd4000fa2,
185770xcc800040,
185780xd0400040,
185790x7c408000,
185800xa0000000,
185810x7e82800b,
185820x7c40c000,
185830x30d00006,
185840x0d100006,
185850x99000007,
185860xc8140015,
185870x99400005,
185880xcc000052,
185890xd4000340,
185900xd4000fc0,
185910xd4000fa2,
185920xcc800040,
185930xccc00040,
185940x80000000,
185950xd0400040,
185960x7c40c000,
185970xcc4d0000,
185980xdc3a0000,
185990x9780fdbc,
186000x04cc0001,
186010x80000243,
186020xcc4d0000,
186030x7c40c000,
186040x7c410000,
186050x29240018,
186060x32640001,
186070x9640000f,
186080xcc800040,
186090x7c414000,
186100x7c418000,
186110x7c41c000,
186120xccc00043,
186130xcd000043,
186140x31dc7fff,
186150xcdc00043,
186160xccc00040,
186170xcd000040,
186180xcd400040,
186190xcd800040,
186200x80000000,
186210xcdc00040,
186220xccc00040,
186230xcd000040,
186240x80000000,
186250xd0400040,
186260x80000000,
186270xd040007f,
186280xcc00007f,
186290x80000000,
186300xcc00007f,
186310xcc00007f,
186320x88000000,
186330xcc00007f,
186340x00000000,
186350x00000000,
186360x00000000,
186370x00000000,
186380x00000000,
186390x00000000,
186400x00000000,
186410x00000000,
186420x00000000,
186430x00000000,
186440x00000000,
186450x00000000,
186460x00000000,
186470x00000000,
186480x00000000,
186490x00000000,
186500x00000000,
186510x00000000,
186520x00000000,
186530x00000000,
186540x00000000,
186550x00000000,
186560x00000000,
186570x00000000,
186580x00000000,
186590x00000000,
186600x00000000,
186610x00000000,
186620x00000000,
186630x00000000,
186640x00000000,
186650x00000000,
186660x00000000,
186670x00000000,
186680x00000000,
186690x00000000,
186700x00000000,
186710x00000000,
186720x00000000,
186730x00000000,
186740x00000000,
186750x00000000,
186760x00000000,
186770x00000000,
186780x00000000,
186790x00000000,
186800x00000000,
186810x00000000,
186820x00000000,
186830x00000000,
186840x00000000,
186850x00000000,
186860x00000000,
186870x00000000,
186880x00000000,
186890x00000000,
186900x00000000,
186910x00000000,
186920x00000000,
186930x00000000,
186940x00000000,
186950x00000000,
186960x00000000,
186970x00000000,
186980x00000000,
186990x00000000,
187000x00000000,
187010x00000000,
187020x00000000,
187030x00000000,
187040x00000000,
187050x00000000,
187060x00000000,
187070x00000000,
187080x00000000,
187090x00000000,
187100x00000000,
187110x00000000,
187120x00000000,
187130x00000000,
187140x00000000,
187150x00000000,
187160x00000000,
187170x00000000,
187180x00000000,
187190x00000000,
187200x00000000,
187210x00000000,
187220x00000000,
187230x00000000,
187240x00000000,
187250x00000000,
187260x00000000,
187270x00000000,
187280x00000000,
187290x00000000,
187300x00000000,
187310x00000000,
187320x00000000,
187330x00000000,
187340x00000000,
187350x00000000,
187360x00000000,
187370x00000000,
187380x00000000,
187390x00000000,
187400x00000000,
187410x00000000,
187420x00000000,
187430x00000000,
187440x00000000,
187450x00000000,
187460x00000000,
187470x00000000,
187480x00000000,
187490x00000000,
187500x00000000,
187510x00000000,
187520x00000000,
187530x00000000,
187540x00000000,
187550x00000000,
187560x00000000,
187570x00000000,
187580x00000000,
187590x00000000,
187600x00000000,
187610x00000000,
187620x00000000,
187630x00000000,
187640x00000000,
187650x00000000,
187660x00000000,
187670x00000000,
187680x00000000,
187690x00000000,
187700x00000000,
187710x00000000,
187720x00000000,
187730x00000000,
187740x00000000,
187750x00000000,
187760x00000000,
187770x00000000,
187780x00000000,
187790x00000000,
187800x00000000,
187810x00000000,
187820x00000000,
187830x00000000,
187840x00000000,
187850x00000000,
187860x00000000,
187870x00030223,
187880x0004022b,
187890x000500a0,
187900x00020003,
187910x0006003c,
187920x00070027,
187930x00080192,
187940x00090044,
187950x000a002d,
187960x0010025f,
187970x001700f1,
187980x002201d8,
187990x002301e9,
188000x0026004c,
188010x0027005f,
188020x0020011b,
188030x00280093,
188040x0029004f,
188050x002a0084,
188060x002b0065,
188070x002f008e,
188080x003200d9,
188090x00340233,
188100x00360075,
188110x0039010b,
188120x003c01fd,
188130x003f00a0,
188140x00410248,
188150x00440195,
188160x0048019e,
188170x004901c6,
188180x004a01d0,
188190x00550226,
188200x0056022e,
188210x0060000a,
188220x0061002a,
188230x00620030,
188240x00630030,
188250x00640030,
188260x00650030,
188270x00660030,
188280x00670030,
188290x00680037,
188300x0069003f,
188310x006a0047,
188320x006b0047,
188330x006c0047,
188340x006d0047,
188350x006e0047,
188360x006f0047,
188370x00700047,
188380x0073025f,
188390x007b0241,
188400x00000005,
188410x00000005,
188420x00000005,
188430x00000005,
188440x00000005,
188450x00000005,
188460x00000005,
188470x00000005,
188480x00000005,
188490x00000005,
188500x00000005,
188510x00000005,
188520x00000005,
188530x00000005,
188540x00000005,
188550x00000005,
188560x00000005,
188570x00000005,
188580x00000005,
188590x00000005,
188600x00000005,
188610x00000005,
188620x00000005,
188630x00000005,
188640x00000005,
188650x00000005,
188660x00000005,
18867};
18868
18869static const u32 RV730_pfp_microcode[] = {
188700x7c408000,
188710xa0000000,
188720x7e82800b,
188730x80000000,
188740xdc030000,
188750xcc800040,
188760xd0400040,
188770x7c408000,
188780xa0000000,
188790x7e82800b,
188800xc818000e,
188810x31980001,
188820x7c424000,
188830x9580023a,
188840x7c428000,
188850xc81c001c,
188860xc037c000,
188870x7c40c000,
188880x7c410000,
188890x7cb4800b,
188900xc0360003,
188910x99c00000,
188920xc81c001c,
188930x7cb4800c,
188940x24d40002,
188950x7d654000,
188960xcd400043,
188970xce800043,
188980xcd000043,
188990xcc800040,
189000xce400040,
189010xce800040,
189020xccc00040,
189030xdc3a0000,
189040x9780ffde,
189050xcd000040,
189060x7c40c000,
189070x80000018,
189080x7c410000,
189090xd4000340,
189100xd4000fc0,
189110xd4000fa2,
189120xc818000e,
189130x8000000c,
189140x31980002,
189150xd40003c0,
189160xd4000fc0,
189170xd4000fa2,
189180xc818000e,
189190x288c0008,
189200x30cc000f,
189210x34100001,
189220x7d0d0008,
189230x8000000c,
189240x7d91800b,
189250xcc800040,
189260xd0400040,
189270x7c408000,
189280xa0000000,
189290x7e82800b,
189300xd4000340,
189310xd4000fc0,
189320xd4000fa2,
189330xcc800040,
189340xd0400040,
189350x7c408000,
189360xa0000000,
189370x7e82800b,
189380xd40003c0,
189390xd4000fc0,
189400xd4000fa2,
189410xcc800040,
189420xd0400040,
189430x7c408000,
189440xa0000000,
189450x7e82800b,
189460xcc4003f9,
189470x80000249,
189480xcc4003f8,
189490xc037ffff,
189500x7c414000,
189510xcf41a29e,
189520xc82003f8,
189530xc81c03f9,
189540x66200020,
189550xc81803fb,
189560x7de1c02c,
189570x7d58c008,
189580x7cdcc020,
189590x69100020,
189600xc0360003,
189610xcc000054,
189620x7cb4800c,
189630x80000069,
189640xcc800040,
189650x7c418000,
189660xcd81a29e,
189670xcc800040,
189680x80000067,
189690xcd800040,
189700xc019ffff,
189710xcc800040,
189720xcd81a29e,
189730x7c40c000,
189740x7c410000,
189750x7c414000,
189760xccc1a1fa,
189770xcd01a1f9,
189780xcd41a29d,
189790xccc00040,
189800xcd000040,
189810xcd400040,
189820xcc400040,
189830x7c408000,
189840xa0000000,
189850x7e82800b,
189860xcc000054,
189870xcc800040,
189880x7c40c000,
189890x7c410000,
189900x7c414000,
189910xccc1a1fa,
189920xcd01a1f9,
189930xcd41a29d,
189940xccc00040,
189950xcd000040,
189960xcd400040,
189970xd0400040,
189980x7c408000,
189990xa0000000,
190000x7e82800b,
190010x7c40c000,
190020x30d00001,
190030xccc1a29f,
190040x95000003,
190050x04140001,
190060x04140002,
190070xcd4003fb,
190080xcc800040,
190090x80000000,
190100xccc00040,
190110x7c40c000,
190120xcc800040,
190130xccc1a2a2,
190140x80000000,
190150xccc00040,
190160x7c40c000,
190170x28d4001f,
190180xcc800040,
190190x95400003,
190200x7c410000,
190210xccc00057,
190220x2918001f,
190230xccc00040,
190240x95800003,
190250xcd000040,
190260xcd000058,
190270x80000249,
190280xcc00007f,
190290xc8200017,
190300xc8300022,
190310x9a000006,
190320x0e280001,
190330xc824001e,
190340x0a640001,
190350xd4001240,
190360xce400040,
190370xc036c000,
190380x96800007,
190390x37747900,
190400x041c0001,
190410xcf400040,
190420xcdc00040,
190430xcf0003fa,
190440x7c030000,
190450xca0c0010,
190460x7c410000,
190470x94c00004,
190480x7c414000,
190490xd42002c4,
190500xcde00044,
190510x9b00000b,
190520x7c418000,
190530xcc00004b,
190540xcda00049,
190550xcd200041,
190560xcd600041,
190570xcda00041,
190580x06200001,
190590xce000056,
190600x80000249,
190610xcc00007f,
190620xc8280020,
190630xc82c0021,
190640xcc000063,
190650x7eea4001,
190660x65740020,
190670x7f53402c,
190680x269c0002,
190690x7df5c020,
190700x69f80020,
190710xce80004b,
190720xce600049,
190730xcde00041,
190740xcfa00041,
190750xce600041,
190760x271c0002,
190770x7df5c020,
190780x69f80020,
190790x7db24001,
190800xcf00004b,
190810xce600049,
190820xcde00041,
190830xcfa00041,
190840x800000bc,
190850xce600041,
190860xc8200017,
190870xc8300022,
190880x9a000006,
190890x0e280001,
190900xc824001e,
190910x0a640001,
190920xd4001240,
190930xce400040,
190940xca0c0010,
190950x7c410000,
190960x94c0000b,
190970xc036c000,
190980x96800007,
190990x37747900,
191000x041c0001,
191010xcf400040,
191020xcdc00040,
191030xcf0003fa,
191040x7c030000,
191050x800000b5,
191060x7c414000,
191070xcc000048,
191080x800000ee,
191090x00000000,
191100xc8200017,
191110xc81c0023,
191120x0e240002,
191130x99c00015,
191140x7c418000,
191150x0a200001,
191160xce000056,
191170xd4000440,
191180xcc000040,
191190xc036c000,
191200xca140013,
191210x96400007,
191220x37747900,
191230xcf400040,
191240xcc000040,
191250xc83003fa,
191260x80000103,
191270xcf000022,
191280xcc000022,
191290x95400146,
191300xcc00007f,
191310xcca00046,
191320x80000000,
191330xcc200046,
191340x80000249,
191350xcc000064,
191360xc8200017,
191370xc810001f,
191380x96000005,
191390x09100001,
191400xd4000440,
191410xcd000040,
191420xcd000022,
191430xcc800040,
191440xd0400040,
191450xc80c0025,
191460x94c0feec,
191470xc8100008,
191480xcd000040,
191490xd4000fc0,
191500x80000000,
191510xd4000fa2,
191520x7c40c000,
191530x7c410000,
191540xccc003fd,
191550xcd0003fc,
191560xccc00042,
191570xcd000042,
191580x2914001f,
191590x29180010,
191600x31980007,
191610x3b5c0001,
191620x7d76000b,
191630x99800005,
191640x7d5e400b,
191650xcc000042,
191660x80000249,
191670xcc00004d,
191680x29980001,
191690x292c0008,
191700x9980003d,
191710x32ec0001,
191720x96000004,
191730x2930000c,
191740x80000249,
191750xcc000042,
191760x04140010,
191770xcd400042,
191780x33300001,
191790x34280001,
191800x8400015d,
191810xc8140003,
191820x9b40001b,
191830x0438000c,
191840x8400015d,
191850xc8140003,
191860x9b400017,
191870x04380008,
191880x8400015d,
191890xc8140003,
191900x9b400013,
191910x04380004,
191920x8400015d,
191930xc8140003,
191940x9b400015,
191950xc80c03fd,
191960x9a800009,
191970xc81003fc,
191980x9b000101,
191990xcc00004d,
192000x04140010,
192010xccc00042,
192020xcd000042,
192030x80000135,
192040xcd400042,
192050x96c000fa,
192060xcc00004d,
192070x80000249,
192080xcc00004e,
192090x9ac00003,
192100xcc00004d,
192110xcc00004e,
192120xdf830000,
192130x80000000,
192140xd80301ff,
192150x9ac000f0,
192160xcc00004d,
192170x80000249,
192180xcc00004e,
192190xc8180003,
192200xc81c0003,
192210xc8200003,
192220x7d5d4003,
192230x7da1c003,
192240x7d5d400c,
192250x2a10001f,
192260x299c001f,
192270x7d1d000b,
192280x7d17400b,
192290x88000000,
192300x7e92800b,
192310x96400004,
192320xcc00004e,
192330x80000249,
192340xcc000042,
192350x04380008,
192360xcf800042,
192370xc8080003,
192380xc80c0003,
192390xc8100003,
192400xc8140003,
192410xc8180003,
192420xc81c0003,
192430xc8240003,
192440xc8280003,
192450x29fc001f,
192460x2ab0001f,
192470x7ff3c00b,
192480x28f0001f,
192490x7ff3c00b,
192500x2970001f,
192510x7ff3c00b,
192520x7d888001,
192530x7dccc001,
192540x7e510001,
192550x7e954001,
192560x7c908002,
192570x7cd4c002,
192580x7cbc800b,
192590x9ac00003,
192600x7c8f400b,
192610x38b40001,
192620x9b4000c1,
192630xcc00004d,
192640x9bc000bf,
192650xcc00004e,
192660xc80c03fd,
192670xc81003fc,
192680xccc00042,
192690x8000016e,
192700xcd000042,
192710xd4000340,
192720xd4000fc0,
192730xd4000fa2,
192740xcc800040,
192750xcc400040,
192760xcc400040,
192770xcc400040,
192780x7c40c000,
192790xccc00040,
192800xccc0000d,
192810x80000000,
192820xd0400040,
192830x7c40c000,
192840x7c410000,
192850x65140020,
192860x7d4d402c,
192870x24580002,
192880x7d598020,
192890x7c41c000,
192900xcd800042,
192910x69980020,
192920xcd800042,
192930xcdc00042,
192940xc023c000,
192950x05e40002,
192960x7ca0800b,
192970x26640010,
192980x7ca4800c,
192990xcc800040,
193000xcdc00040,
193010xccc00040,
193020x95c0000e,
193030xcd000040,
193040x09dc0001,
193050xc8280003,
193060x96800008,
193070xce800040,
193080xc834001d,
193090x97400000,
193100xc834001d,
193110x26a80008,
193120x8400024c,
193130xcc2b0000,
193140x99c0fff7,
193150x09dc0001,
193160xdc3a0000,
193170x97800004,
193180x7c418000,
193190x800001a2,
193200x25980002,
193210xa0000000,
193220x7d808000,
193230xc818001d,
193240x7c40c000,
193250x64d00008,
193260x95800000,
193270xc818001d,
193280xcc130000,
193290xcc800040,
193300xccc00040,
193310x80000000,
193320xcc400040,
193330xc810001f,
193340x7c40c000,
193350xcc800040,
193360x7cd1400c,
193370xcd400040,
193380x05180001,
193390x80000000,
193400xcd800022,
193410x7c40c000,
193420x64500020,
193430x8400024c,
193440xcc000061,
193450x7cd0c02c,
193460xc8200017,
193470xc8d60000,
193480x99400008,
193490x7c438000,
193500xdf830000,
193510xcfa0004f,
193520x8400024c,
193530xcc000062,
193540x80000000,
193550xd040007f,
193560x80000249,
193570xcc000062,
193580x8400024c,
193590xcc000061,
193600xc8200017,
193610x7c40c000,
193620xc036ff00,
193630xc810000d,
193640xc0303fff,
193650x7cf5400b,
193660x7d51800b,
193670x7d81800f,
193680x99800008,
193690x7cf3800b,
193700xdf830000,
193710xcfa0004f,
193720x8400024c,
193730xcc000062,
193740x80000000,
193750xd040007f,
193760x80000249,
193770xcc000062,
193780x8400024c,
193790x7c40c000,
193800x28dc0008,
193810x95c00019,
193820x30dc0010,
193830x7c410000,
193840x99c00004,
193850x64540020,
193860x80000208,
193870xc91d0000,
193880x7d15002c,
193890xc91e0000,
193900x7c420000,
193910x7c424000,
193920x7c418000,
193930x7de5c00b,
193940x7de28007,
193950x9a80000e,
193960x41ac0005,
193970x9ac00000,
193980x0aec0001,
193990x30dc0010,
194000x99c00004,
194010x00000000,
194020x8000020b,
194030xc91d0000,
194040x8000020b,
194050xc91e0000,
194060xcc800040,
194070xccc00040,
194080xd0400040,
194090xc80c0025,
194100x94c0fde4,
194110xc8100008,
194120xcd000040,
194130xd4000fc0,
194140x80000000,
194150xd4000fa2,
194160xd4000340,
194170xd4000fc0,
194180xd4000fa2,
194190xcc800040,
194200xd0400040,
194210x7c408000,
194220xa0000000,
194230x7e82800b,
194240xd40003c0,
194250xd4000fc0,
194260xd4000fa2,
194270xcc800040,
194280xd0400040,
194290x7c408000,
194300xa0000000,
194310x7e82800b,
194320x7c40c000,
194330x30d00006,
194340x0d100006,
194350x99000007,
194360xc8140015,
194370x99400005,
194380xcc000052,
194390xd4000340,
194400xd4000fc0,
194410xd4000fa2,
194420xcc800040,
194430xccc00040,
194440x80000000,
194450xd0400040,
194460x7c40c000,
194470xcc4d0000,
194480xdc3a0000,
194490x9780fdbd,
194500x04cc0001,
194510x80000242,
194520xcc4d0000,
194530x80000000,
194540xd040007f,
194550xcc00007f,
194560x80000000,
194570xcc00007f,
194580xcc00007f,
194590x88000000,
194600xcc00007f,
194610x00000000,
194620x00000000,
194630x00000000,
194640x00000000,
194650x00000000,
194660x00000000,
194670x00000000,
194680x00000000,
194690x00000000,
194700x00000000,
194710x00000000,
194720x00000000,
194730x00000000,
194740x00000000,
194750x00000000,
194760x00000000,
194770x00000000,
194780x00000000,
194790x00000000,
194800x00000000,
194810x00000000,
194820x00000000,
194830x00000000,
194840x00000000,
194850x00000000,
194860x00000000,
194870x00000000,
194880x00000000,
194890x00000000,
194900x00000000,
194910x00000000,
194920x00000000,
194930x00000000,
194940x00000000,
194950x00000000,
194960x00000000,
194970x00000000,
194980x00000000,
194990x00000000,
195000x00000000,
195010x00000000,
195020x00000000,
195030x00000000,
195040x00000000,
195050x00000000,
195060x00000000,
195070x00000000,
195080x00000000,
195090x00000000,
195100x00000000,
195110x00000000,
195120x00000000,
195130x00000000,
195140x00000000,
195150x00000000,
195160x00000000,
195170x00000000,
195180x00000000,
195190x00000000,
195200x00000000,
195210x00000000,
195220x00000000,
195230x00000000,
195240x00000000,
195250x00000000,
195260x00000000,
195270x00000000,
195280x00000000,
195290x00000000,
195300x00000000,
195310x00000000,
195320x00000000,
195330x00000000,
195340x00000000,
195350x00000000,
195360x00000000,
195370x00000000,
195380x00000000,
195390x00000000,
195400x00000000,
195410x00000000,
195420x00000000,
195430x00000000,
195440x00000000,
195450x00000000,
195460x00000000,
195470x00000000,
195480x00000000,
195490x00000000,
195500x00000000,
195510x00000000,
195520x00000000,
195530x00000000,
195540x00000000,
195550x00000000,
195560x00000000,
195570x00000000,
195580x00000000,
195590x00000000,
195600x00000000,
195610x00000000,
195620x00000000,
195630x00000000,
195640x00000000,
195650x00000000,
195660x00000000,
195670x00000000,
195680x00000000,
195690x00000000,
195700x00000000,
195710x00000000,
195720x00000000,
195730x00000000,
195740x00000000,
195750x00000000,
195760x00000000,
195770x00000000,
195780x00000000,
195790x00000000,
195800x00000000,
195810x00000000,
195820x00000000,
195830x00000000,
195840x00000000,
195850x00000000,
195860x00000000,
195870x00000000,
195880x00000000,
195890x00000000,
195900x00000000,
195910x00000000,
195920x00000000,
195930x00000000,
195940x00000000,
195950x00000000,
195960x00000000,
195970x00000000,
195980x00000000,
195990x00000000,
196000x00000000,
196010x00000000,
196020x00000000,
196030x00000000,
196040x00000000,
196050x00000000,
196060x00000000,
196070x00000000,
196080x00000000,
196090x00000000,
196100x00000000,
196110x00000000,
196120x00000000,
196130x00000000,
196140x00000000,
196150x00000000,
196160x00000000,
196170x00000000,
196180x00000000,
196190x00000000,
196200x00000000,
196210x00000000,
196220x00000000,
196230x00000000,
196240x00000000,
196250x00000000,
196260x00000000,
196270x00000000,
196280x00000000,
196290x00000000,
196300x00000000,
196310x00000000,
196320x00000000,
196330x00000000,
196340x00000000,
196350x00000000,
196360x00000000,
196370x00000000,
196380x00030222,
196390x0004022a,
196400x0005009f,
196410x00020003,
196420x0006003c,
196430x00070027,
196440x00080191,
196450x00090044,
196460x000a002d,
196470x00100247,
196480x001700f0,
196490x002201d7,
196500x002301e8,
196510x0026004c,
196520x0027005f,
196530x0020011a,
196540x00280092,
196550x0029004f,
196560x002a0083,
196570x002b0064,
196580x002f008d,
196590x003200d8,
196600x00340232,
196610x00360074,
196620x0039010a,
196630x003c01fc,
196640x003f009f,
196650x00410005,
196660x00440194,
196670x0048019d,
196680x004901c5,
196690x004a01cf,
196700x00550225,
196710x0056022d,
196720x0060000a,
196730x0061002a,
196740x00620030,
196750x00630030,
196760x00640030,
196770x00650030,
196780x00660030,
196790x00670030,
196800x00680037,
196810x0069003f,
196820x006a0047,
196830x006b0047,
196840x006c0047,
196850x006d0047,
196860x006e0047,
196870x006f0047,
196880x00700047,
196890x00730247,
196900x007b0240,
196910x00000005,
196920x00000005,
196930x00000005,
196940x00000005,
196950x00000005,
196960x00000005,
196970x00000005,
196980x00000005,
196990x00000005,
197000x00000005,
197010x00000005,
197020x00000005,
197030x00000005,
197040x00000005,
197050x00000005,
197060x00000005,
197070x00000005,
197080x00000005,
197090x00000005,
197100x00000005,
197110x00000005,
197120x00000005,
197130x00000005,
197140x00000005,
197150x00000005,
197160x00000005,
197170x00000005,
19718};
19719
19720static const u32 RV730_cp_microcode[] = {
197210xcc0003ea,
197220x7c408000,
197230xa0000000,
197240xcc800062,
197250x80000001,
197260xd040007f,
197270x80000001,
197280xcc400041,
197290x7c40c000,
197300xc0160004,
197310x30d03fff,
197320x7d15000c,
197330xcc110000,
197340x28d8001e,
197350x31980001,
197360x28dc001f,
197370xc8200004,
197380x95c00006,
197390x7c424000,
197400xcc000062,
197410x7e56800c,
197420xcc290000,
197430xc8240004,
197440x7e26000b,
197450x95800006,
197460x7c42c000,
197470xcc000062,
197480x7ed7000c,
197490xcc310000,
197500xc82c0004,
197510x7e2e000c,
197520xcc000062,
197530x31103fff,
197540x80000001,
197550xce110000,
197560x7c40c000,
197570x80000001,
197580xcc400040,
197590x80000001,
197600xcc412257,
197610x7c418000,
197620xcc400045,
197630xcc400048,
197640xcc41225c,
197650xcc41a1fc,
197660x7c408000,
197670xa0000000,
197680xcc800062,
197690xcc400045,
197700xcc400048,
197710x7c40c000,
197720xcc41225c,
197730xcc41a1fc,
197740x7c408000,
197750xa0000000,
197760xcc800062,
197770xcc000045,
197780xcc000048,
197790xcc41225c,
197800xcc41a1fc,
197810x7c408000,
197820xa0000000,
197830xcc800062,
197840x040ca1fd,
197850xc0120001,
197860xcc000045,
197870xcc000048,
197880x7cd0c00c,
197890xcc41225c,
197900xcc41a1fc,
197910xd04d0000,
197920x7c408000,
197930xa0000000,
197940xcc800062,
197950x80000001,
197960xcc41225d,
197970x7c408000,
197980x7c40c000,
197990xc02a0002,
198000x7c410000,
198010x7d29000c,
198020x30940001,
198030x30980006,
198040x309c0300,
198050x29dc0008,
198060x7c420000,
198070x7c424000,
198080x9540000f,
198090xc02e0004,
198100x05f02258,
198110x7f2f000c,
198120xcc310000,
198130xc8280004,
198140xccc12169,
198150xcd01216a,
198160xce81216b,
198170x0db40002,
198180xcc01216c,
198190x9740000e,
198200x0db40000,
198210x8000007b,
198220xc834000a,
198230x0db40002,
198240x97400009,
198250x0db40000,
198260xc02e0004,
198270x05f02258,
198280x7f2f000c,
198290xcc310000,
198300xc8280004,
198310x8000007b,
198320xc834000a,
198330x97400004,
198340x7e028000,
198350x8000007b,
198360xc834000a,
198370x0db40004,
198380x9740ff8c,
198390x00000000,
198400xce01216d,
198410xce41216e,
198420xc8280003,
198430xc834000a,
198440x9b400004,
198450x043c0005,
198460x8400026b,
198470xcc000062,
198480x0df40000,
198490x9740000b,
198500xc82c03e6,
198510xce81a2b7,
198520xc0300006,
198530x7ef34028,
198540xc0300020,
198550x7f6b8020,
198560x7fb3c029,
198570xcf81a2c4,
198580x80000001,
198590xcfc1a2d1,
198600x0df40001,
198610x9740000b,
198620xc82c03e7,
198630xce81a2bb,
198640xc0300006,
198650x7ef34028,
198660xc0300020,
198670x7f6b8020,
198680x7fb3c029,
198690xcf81a2c5,
198700x80000001,
198710xcfc1a2d2,
198720x0df40002,
198730x9740000b,
198740xc82c03e8,
198750xce81a2bf,
198760xc0300006,
198770x7ef34028,
198780xc0300020,
198790x7f6b8020,
198800x7fb3c029,
198810xcf81a2c6,
198820x80000001,
198830xcfc1a2d3,
198840xc82c03e9,
198850xce81a2c3,
198860xc0300006,
198870x7ef34028,
198880xc0300020,
198890x7f6b8020,
198900x7fb3c029,
198910xcf81a2c7,
198920x80000001,
198930xcfc1a2d4,
198940x80000001,
198950xcc400042,
198960x7c40c000,
198970x7c410000,
198980x2914001d,
198990x31540001,
199000x9940000c,
199010x31181000,
199020xc81c0011,
199030x95c00000,
199040xc81c0011,
199050xccc12100,
199060xcd012101,
199070xccc12102,
199080xcd012103,
199090x04180004,
199100x8000037c,
199110xcd81a2a4,
199120xc02a0004,
199130x95800008,
199140x36a821a3,
199150xcc290000,
199160xc8280004,
199170xc81c0011,
199180x0de40040,
199190x9640ffff,
199200xc81c0011,
199210xccc12170,
199220xcd012171,
199230xc8200012,
199240x96000000,
199250xc8200012,
199260x8000037c,
199270xcc000064,
199280x7c40c000,
199290x7c410000,
199300xcc000045,
199310xcc000048,
199320x40d40003,
199330xcd41225c,
199340xcd01a1fc,
199350xc01a0001,
199360x041ca1fd,
199370x7dd9c00c,
199380x7c420000,
199390x08cc0001,
199400x06240001,
199410x06280002,
199420xce1d0000,
199430xce5d0000,
199440x98c0fffa,
199450xce9d0000,
199460x7c408000,
199470xa0000000,
199480xcc800062,
199490x7c40c000,
199500x30d00001,
199510x28cc0001,
199520x7c414000,
199530x95000006,
199540x7c418000,
199550xcd41216d,
199560xcd81216e,
199570x800000f2,
199580xc81c0003,
199590xc0220004,
199600x7e16000c,
199610xcc210000,
199620xc81c0004,
199630x7c424000,
199640x98c00004,
199650x7c428000,
199660x80000001,
199670xcde50000,
199680xce412169,
199690xce81216a,
199700xcdc1216b,
199710x80000001,
199720xcc01216c,
199730x7c40c000,
199740x7c410000,
199750x7c414000,
199760x7c418000,
199770x7c41c000,
199780x28a40008,
199790x326400ff,
199800x0e68003c,
199810x9680000a,
199820x7c020000,
199830x7c420000,
199840x1e300003,
199850xcc00006a,
199860x9b000003,
199870x42200005,
199880x04200040,
199890x8000010f,
199900x7c024000,
199910x7e024000,
199920x9a400000,
199930x0a640001,
199940x30ec0010,
199950x9ac0000a,
199960xcc000062,
199970xc02a0004,
199980xc82c0021,
199990x7e92800c,
200000xcc000041,
200010xcc290000,
200020xcec00021,
200030x8000011f,
200040xc8300004,
200050xcd01216d,
200060xcd41216e,
200070xc8300003,
200080x7f1f000b,
200090x30f40007,
200100x27780001,
200110x9740002a,
200120x07b80124,
200130x9f800000,
200140x00000000,
200150x80000134,
200160x7f1b8004,
200170x80000138,
200180x7f1b8005,
200190x8000013c,
200200x7f1b8002,
200210x80000140,
200220x7f1b8003,
200230x80000144,
200240x7f1b8007,
200250x80000148,
200260x7f1b8006,
200270x8000014d,
200280x28a40008,
200290x9b800019,
200300x28a40008,
200310x8000015d,
200320x326400ff,
200330x9b800015,
200340x28a40008,
200350x8000015d,
200360x326400ff,
200370x9b800011,
200380x28a40008,
200390x8000015d,
200400x326400ff,
200410x9b80000d,
200420x28a40008,
200430x8000015d,
200440x326400ff,
200450x9b800009,
200460x28a40008,
200470x8000015d,
200480x326400ff,
200490x9b800005,
200500x28a40008,
200510x8000015d,
200520x326400ff,
200530x28a40008,
200540x326400ff,
200550x0e68003c,
200560x9a80feb2,
200570x28ec0008,
200580x7c434000,
200590x7c438000,
200600x7c43c000,
200610x96c00007,
200620xcc000062,
200630xcf412169,
200640xcf81216a,
200650xcfc1216b,
200660x80000001,
200670xcc01216c,
200680x80000001,
200690xcff50000,
200700xcc00006b,
200710x8400037f,
200720x0e68003c,
200730x9a800004,
200740xc8280015,
200750x80000001,
200760xd040007f,
200770x9680ffab,
200780x7e024000,
200790x84000239,
200800xc00e0002,
200810xcc000041,
200820x80000237,
200830xccc1304a,
200840x7c40c000,
200850x7c410000,
200860xc01e0001,
200870x29240012,
200880xc0220002,
200890x96400005,
200900xc0260004,
200910xc027fffb,
200920x7d25000b,
200930xc0260000,
200940x7dd2800b,
200950x7e12c00b,
200960x7d25000c,
200970x7c414000,
200980x7c418000,
200990xccc12169,
201000x9a80000a,
201010xcd01216a,
201020xcd41216b,
201030x96c0fe83,
201040xcd81216c,
201050xc8300018,
201060x97000000,
201070xc8300018,
201080x80000001,
201090xcc000018,
201100x8400037f,
201110xcc00007f,
201120xc8140013,
201130xc8180014,
201140xcd41216b,
201150x96c0fe77,
201160xcd81216c,
201170x80000181,
201180xc8300018,
201190xc80c0008,
201200x98c00000,
201210xc80c0008,
201220x7c410000,
201230x95000002,
201240x00000000,
201250x7c414000,
201260xc8200009,
201270xcc400043,
201280xce01a1f4,
201290xcc400044,
201300xc00e8000,
201310x7c424000,
201320x7c428000,
201330x2aac001f,
201340x96c0fe64,
201350xc035f000,
201360xce4003e2,
201370x32780003,
201380x267c0008,
201390x7ff7c00b,
201400x7ffbc00c,
201410x2a780018,
201420xcfc003e3,
201430xcf8003e4,
201440x26b00002,
201450x7f3f0000,
201460xcf0003e5,
201470x8000031d,
201480x7c80c000,
201490x7c40c000,
201500x28d00008,
201510x3110000f,
201520x9500000f,
201530x25280001,
201540x06a801b2,
201550x9e800000,
201560x00000000,
201570x800001d3,
201580xc0120800,
201590x800001e1,
201600xc814000f,
201610x800001e8,
201620xc8140010,
201630x800001ef,
201640xccc1a2a4,
201650x800001f8,
201660xc8140011,
201670x30d0003f,
201680x0d280015,
201690x9a800012,
201700x0d28001e,
201710x9a80001e,
201720x0d280020,
201730x9a800023,
201740x0d24000f,
201750x0d280010,
201760x7e6a800c,
201770x9a800026,
201780x0d200004,
201790x0d240014,
201800x0d280028,
201810x7e62400c,
201820x7ea6800c,
201830x9a80002a,
201840xc8140011,
201850x80000001,
201860xccc1a2a4,
201870xc0120800,
201880x7c414000,
201890x7d0cc00c,
201900xc0120008,
201910x29580003,
201920x295c000c,
201930x7c420000,
201940x7dd1c00b,
201950x26200014,
201960x7e1e400c,
201970x7e4e800c,
201980xce81a2a4,
201990x80000001,
202000xcd81a1fe,
202010xc814000f,
202020x0410210e,
202030x95400000,
202040xc814000f,
202050xd0510000,
202060x80000001,
202070xccc1a2a4,
202080xc8140010,
202090x04102108,
202100x95400000,
202110xc8140010,
202120xd0510000,
202130x80000001,
202140xccc1a2a4,
202150xccc1a2a4,
202160x04100001,
202170xcd000019,
202180x8400037f,
202190xcc00007f,
202200xc8100019,
202210x99000000,
202220xc8100019,
202230x80000002,
202240x7c408000,
202250x04102100,
202260x95400000,
202270xc8140011,
202280xd0510000,
202290x8000037c,
202300xccc1a2a4,
202310x7c40c000,
202320xcc40000d,
202330x94c0fe01,
202340xcc40000e,
202350x7c410000,
202360x95000005,
202370x08cc0001,
202380xc8140005,
202390x99400014,
202400x00000000,
202410x98c0fffb,
202420x7c410000,
202430x80000002,
202440x7d008000,
202450xc8140005,
202460x7c40c000,
202470x9940000c,
202480xc818000c,
202490x7c410000,
202500x9580fdf0,
202510xc820000e,
202520xc81c000d,
202530x66200020,
202540x7e1e002c,
202550x25240002,
202560x7e624020,
202570x80000001,
202580xcce60000,
202590x7c410000,
202600xcc00006c,
202610xcc00006d,
202620xc818001f,
202630xc81c001e,
202640x65980020,
202650x7dd9c02c,
202660x7cd4c00c,
202670xccde0000,
202680x45dc0004,
202690xc8280017,
202700x9680000f,
202710xc00e0001,
202720x28680008,
202730x2aac0016,
202740x32a800ff,
202750x0eb00049,
202760x7f2f000b,
202770x97000006,
202780x00000000,
202790xc8140005,
202800x7c40c000,
202810x80000221,
202820x7c410000,
202830x80000224,
202840xd040007f,
202850x84000239,
202860xcc000041,
202870xccc1304a,
202880x94000000,
202890xc83c001a,
202900x043c0005,
202910xcfc1a2a4,
202920xc0361f90,
202930xc0387fff,
202940x7c03c010,
202950x7f7b400c,
202960xcf41217c,
202970xcfc1217d,
202980xcc01217e,
202990xc03a0004,
203000x0434217f,
203010x7f7b400c,
203020xcc350000,
203030xc83c0004,
203040x2bfc001f,
203050x04380020,
203060x97c00005,
203070xcc000062,
203080x9b800000,
203090x0bb80001,
203100x80000245,
203110xcc000071,
203120xcc01a1f4,
203130x04380016,
203140xc0360002,
203150xcf81a2a4,
203160x88000000,
203170xcf412010,
203180x7c40c000,
203190x28d0001c,
203200x95000005,
203210x04d40001,
203220xcd400065,
203230x80000001,
203240xcd400068,
203250x09540002,
203260x80000001,
203270xcd400066,
203280x8400026a,
203290xc81803ea,
203300x7c40c000,
203310x9980fd9f,
203320xc8140016,
203330x08d00001,
203340x9940002b,
203350xcd000068,
203360x7c408000,
203370xa0000000,
203380xcc800062,
203390x043c0005,
203400xcfc1a2a4,
203410xcc01a1f4,
203420x8400037f,
203430xcc000046,
203440x88000000,
203450xcc00007f,
203460x8400027c,
203470xc81803ea,
203480x7c40c000,
203490x9980fd8d,
203500xc8140016,
203510x08d00001,
203520x99400019,
203530xcd000068,
203540x7c408000,
203550xa0000000,
203560xcc800062,
203570x043c0022,
203580xcfc1a2a4,
203590x8400037f,
203600xcc000047,
203610x88000000,
203620xcc00007f,
203630xc8100016,
203640x9900000d,
203650xcc400067,
203660x80000002,
203670x7c408000,
203680xc81803ea,
203690x9980fd79,
203700x7c40c000,
203710x94c00003,
203720xc8100016,
203730x99000004,
203740xccc00068,
203750x80000002,
203760x7c408000,
203770x84000239,
203780xc0148000,
203790xcc000041,
203800xcd41304a,
203810xc0148000,
203820x99000000,
203830xc8100016,
203840x80000002,
203850x7c408000,
203860xc0120001,
203870x7c51400c,
203880x80000001,
203890xd0550000,
203900x7c40c000,
203910x7c410000,
203920x7c414000,
203930x7c418000,
203940x291c001f,
203950xccc0004a,
203960xcd00004b,
203970x95c00003,
203980xc01c8000,
203990xcdc12010,
204000xdd830000,
204010x055c2000,
204020xcc000062,
204030x80000001,
204040xd81f4100,
204050x7c40c000,
204060x7c410000,
204070x7c414000,
204080x7c418000,
204090xccc0004c,
204100xcd00004d,
204110xdd830000,
204120x055ca000,
204130x80000001,
204140xd81f4100,
204150x7c40c000,
204160x7c410000,
204170x7c414000,
204180x7c418000,
204190xccc0004e,
204200xcd00004f,
204210xdd830000,
204220x055cc000,
204230x80000001,
204240xd81f4100,
204250x7c40c000,
204260x7c410000,
204270x7c414000,
204280x7c418000,
204290xccc00050,
204300xcd000051,
204310xdd830000,
204320x055cf8e0,
204330x80000001,
204340xd81f4100,
204350x7c40c000,
204360x7c410000,
204370x7c414000,
204380x7c418000,
204390xccc00052,
204400xcd000053,
204410xdd830000,
204420x055cf880,
204430x80000001,
204440xd81f4100,
204450x7c40c000,
204460x7c410000,
204470x7c414000,
204480x7c418000,
204490xccc00054,
204500xcd000055,
204510xdd830000,
204520x055ce000,
204530x80000001,
204540xd81f4100,
204550x7c40c000,
204560x7c410000,
204570x7c414000,
204580x7c418000,
204590xccc00056,
204600xcd000057,
204610xdd830000,
204620x055cf000,
204630x80000001,
204640xd81f4100,
204650x7c40c000,
204660x7c410000,
204670x7c414000,
204680x7c418000,
204690xccc00058,
204700xcd000059,
204710xdd830000,
204720x055cf3fc,
204730x80000001,
204740xd81f4100,
204750xd0432000,
204760x7c408000,
204770xa0000000,
204780xcc800062,
204790xd043a000,
204800x7c408000,
204810xa0000000,
204820xcc800062,
204830xd043c000,
204840x7c408000,
204850xa0000000,
204860xcc800062,
204870xd043f8e0,
204880x7c408000,
204890xa0000000,
204900xcc800062,
204910xd043f880,
204920x7c408000,
204930xa0000000,
204940xcc800062,
204950xd043e000,
204960x7c408000,
204970xa0000000,
204980xcc800062,
204990xd043f000,
205000x7c408000,
205010xa0000000,
205020xcc800062,
205030xd043f3fc,
205040x7c408000,
205050xa0000000,
205060xcc800062,
205070xc81403e0,
205080xcc430000,
205090xcc430000,
205100xcc430000,
205110x7d45c000,
205120xcdc30000,
205130xd0430000,
205140x7c408000,
205150xa0000000,
205160xcc800062,
205170x7c40c000,
205180xc81003e2,
205190xc81403e5,
205200xc81803e3,
205210xc81c03e4,
205220xcd812169,
205230xcdc1216a,
205240xccc1216b,
205250xcc01216c,
205260x04200004,
205270x7da18000,
205280x7d964002,
205290x9640fcd9,
205300xcd8003e3,
205310x31280003,
205320xc02df000,
205330x25180008,
205340x7dad800b,
205350x7da9800c,
205360x80000001,
205370xcd8003e3,
205380x308cffff,
205390xd04d0000,
205400x7c408000,
205410xa0000000,
205420xcc800062,
205430xc8140020,
205440x15580002,
205450x9580ffff,
205460xc8140020,
205470xcc00006e,
205480xcc412180,
205490x7c40c000,
205500xccc1218d,
205510xcc412181,
205520x28d0001f,
205530x34588000,
205540xcd81218c,
205550x9500fcbf,
205560xcc412182,
205570xc8140020,
205580x9940ffff,
205590xc8140020,
205600x80000002,
205610x7c408000,
205620x7c40c000,
205630x28d00018,
205640x31100001,
205650xc0160080,
205660x95000003,
205670xc02a0004,
205680x7cd4c00c,
205690xccc1217c,
205700xcc41217d,
205710xcc41217e,
205720x7c418000,
205730x1db00003,
205740x36a0217f,
205750x9b000003,
205760x419c0005,
205770x041c0040,
205780x99c00000,
205790x09dc0001,
205800xcc210000,
205810xc8240004,
205820x2a6c001f,
205830x419c0005,
205840x9ac0fffa,
205850xcc800062,
205860x80000002,
205870x7c408000,
205880x7c40c000,
205890x04d403e6,
205900x80000001,
205910xcc540000,
205920x8000037c,
205930xcc4003ea,
205940xc01c8000,
205950x044ca000,
205960xcdc12010,
205970x7c410000,
205980xc8140009,
205990x04180000,
206000x041c0008,
206010xcd800071,
206020x09dc0001,
206030x05980001,
206040xcd0d0000,
206050x99c0fffc,
206060xcc800062,
206070x8000037c,
206080xcd400071,
206090xc00e0100,
206100xcc000041,
206110xccc1304a,
206120xc83c007f,
206130xcc00007f,
206140x80000001,
206150xcc00007f,
206160xcc00007f,
206170x88000000,
206180xcc00007f,
206190x00000000,
206200x00000000,
206210x00000000,
206220x00000000,
206230x00000000,
206240x00000000,
206250x00000000,
206260x00000000,
206270x00000000,
206280x00000000,
206290x00000000,
206300x00000000,
206310x00000000,
206320x00000000,
206330x00000000,
206340x00000000,
206350x00000000,
206360x00000000,
206370x00000000,
206380x00000000,
206390x00000000,
206400x00000000,
206410x00000000,
206420x00000000,
206430x00000000,
206440x00000000,
206450x00000000,
206460x00000000,
206470x00000000,
206480x00000000,
206490x00000000,
206500x00000000,
206510x00000000,
206520x00000000,
206530x00000000,
206540x00000000,
206550x00000000,
206560x00000000,
206570x00000000,
206580x00000000,
206590x00000000,
206600x00000000,
206610x00000000,
206620x00000000,
206630x00000000,
206640x00000000,
206650x00000000,
206660x00000000,
206670x00000000,
206680x00000000,
206690x00000000,
206700x00000000,
206710x00000000,
206720x00000000,
206730x00000000,
206740x00000000,
206750x00000000,
206760x00000000,
206770x00000000,
206780x00000000,
206790x00000000,
206800x00000000,
206810x00000000,
206820x00000000,
206830x00000000,
206840x00000000,
206850x00000000,
206860x00000000,
206870x00000000,
206880x00000000,
206890x00000000,
206900x00000000,
206910x00000000,
206920x00000000,
206930x00000000,
206940x00000000,
206950x00000000,
206960x00000000,
206970x00000000,
206980x00000000,
206990x00000000,
207000x00000000,
207010x00000000,
207020x00000000,
207030x00000000,
207040x00000000,
207050x00000000,
207060x00000000,
207070x00000000,
207080x00000000,
207090x00000000,
207100x00000000,
207110x00000000,
207120x00000000,
207130x00000000,
207140x00000000,
207150x00000000,
207160x00000000,
207170x00000000,
207180x00000000,
207190x00000000,
207200x00000000,
207210x00000000,
207220x00000000,
207230x00000000,
207240x00000000,
207250x00000000,
207260x00000000,
207270x00000000,
207280x00000000,
207290x00000000,
207300x00000000,
207310x00000000,
207320x00000000,
207330x00000000,
207340x00000000,
207350x00000000,
207360x00000000,
207370x00000000,
207380x00000000,
207390x00000000,
207400x00000000,
207410x00000000,
207420x00000000,
207430x00000000,
207440x00000000,
207450x00000000,
207460x00000000,
207470x00000000,
207480x00000000,
207490x00000000,
207500x00000000,
207510x00000000,
207520x00000000,
207530x00000000,
207540x00000000,
207550x00000000,
207560x00000000,
207570x00000000,
207580x00000000,
207590x00000000,
207600x00000000,
207610x00000000,
207620x00000000,
207630x00000000,
207640x00000000,
207650x00000000,
207660x00000000,
207670x00000000,
207680x00000000,
207690x00000000,
207700x00000000,
207710x00000000,
207720x00000000,
207730x00000000,
207740x00000000,
207750x00000000,
207760x00000000,
207770x00000000,
207780x00000000,
207790x00000000,
207800x00000000,
207810x00000000,
207820x00000000,
207830x00000000,
207840x00000000,
207850x00000000,
207860x00000000,
207870x00000000,
207880x00000000,
207890x00000000,
207900x00000000,
207910x00000000,
207920x00000000,
207930x00000000,
207940x00000000,
207950x00000000,
207960x00000000,
207970x00000000,
207980x00000000,
207990x00000000,
208000x00000000,
208010x00000000,
208020x00000000,
208030x00000000,
208040x00000000,
208050x00000000,
208060x00000000,
208070x00000000,
208080x00000000,
208090x00000000,
208100x00000000,
208110x00000000,
208120x00000000,
208130x00000000,
208140x00000000,
208150x00000000,
208160x00000000,
208170x00000000,
208180x00000000,
208190x00000000,
208200x00000000,
208210x00000000,
208220x00000000,
208230x00000000,
208240x00000000,
208250x00000000,
208260x00000000,
208270x00000000,
208280x00000000,
208290x00000000,
208300x00000000,
208310x00000000,
208320x00000000,
208330x00000000,
208340x00000000,
208350x00000000,
208360x00000000,
208370x00000000,
208380x00000000,
208390x00000000,
208400x00000000,
208410x00000000,
208420x00000000,
208430x00000000,
208440x00000000,
208450x00000000,
208460x00000000,
208470x00000000,
208480x00000000,
208490x00000000,
208500x00000000,
208510x00000000,
208520x00000000,
208530x00000000,
208540x00000000,
208550x00000000,
208560x00000000,
208570x00000000,
208580x00000000,
208590x00000000,
208600x00000000,
208610x00000000,
208620x00000000,
208630x00000000,
208640x00000000,
208650x00000000,
208660x00000000,
208670x00000000,
208680x00000000,
208690x00000000,
208700x00000000,
208710x00000000,
208720x00000000,
208730x00000000,
208740x00000000,
208750x00000000,
208760x00000000,
208770x00000000,
208780x00000000,
208790x00000000,
208800x00000000,
208810x00000000,
208820x00000000,
208830x00000000,
208840x00000000,
208850x00000000,
208860x00000000,
208870x00000000,
208880x00000000,
208890x00000000,
208900x00000000,
208910x00000000,
208920x00000000,
208930x00000000,
208940x00000000,
208950x00000000,
208960x00000000,
208970x00000000,
208980x00000000,
208990x00000000,
209000x00000000,
209010x00000000,
209020x00000000,
209030x00000000,
209040x00000000,
209050x00000000,
209060x00000000,
209070x00000000,
209080x00000000,
209090x00000000,
209100x00000000,
209110x00000000,
209120x00000000,
209130x00000000,
209140x00000000,
209150x00000000,
209160x00000000,
209170x00000000,
209180x00000000,
209190x00000000,
209200x00000000,
209210x00000000,
209220x00000000,
209230x00000000,
209240x00000000,
209250x00000000,
209260x00000000,
209270x00000000,
209280x00000000,
209290x00000000,
209300x00000000,
209310x00000000,
209320x00000000,
209330x00000000,
209340x00000000,
209350x00000000,
209360x00000000,
209370x00000000,
209380x00000000,
209390x00000000,
209400x00000000,
209410x00000000,
209420x00000000,
209430x00000000,
209440x00000000,
209450x00000000,
209460x00000000,
209470x00000000,
209480x00000000,
209490x00000000,
209500x00000000,
209510x00000000,
209520x00000000,
209530x00000000,
209540x00000000,
209550x00000000,
209560x00000000,
209570x00000000,
209580x00000000,
209590x00000000,
209600x00000000,
209610x00000000,
209620x00000000,
209630x00000000,
209640x00000000,
209650x00000000,
209660x00000000,
209670x00000000,
209680x00000000,
209690x00000000,
209700x00000000,
209710x00000000,
209720x00000000,
209730x00000000,
209740x00000000,
209750x00000000,
209760x00000000,
209770x00000000,
209780x00000000,
209790x00000000,
209800x00000000,
209810x00000000,
209820x00000000,
209830x00000000,
209840x00000000,
209850x00000000,
209860x00000000,
209870x00000000,
209880x00000000,
209890x00000000,
209900x00000000,
209910x00000000,
209920x00000000,
209930x00000000,
209940x00000000,
209950x00000000,
209960x00000000,
209970x00000000,
209980x00000000,
209990x00000000,
210000x00000000,
210010x00010331,
210020x00100004,
210030x00170006,
210040x00210008,
210050x00270028,
210060x00280023,
210070x00290029,
210080x002a0026,
210090x002b0029,
210100x002d0038,
210110x002e003f,
210120x002f004a,
210130x0034004c,
210140x00360030,
210150x003900af,
210160x003a00cf,
210170x003b00e4,
210180x003c00fc,
210190x003d016b,
210200x003f00ad,
210210x00410336,
210220x00430349,
210230x0044018e,
210240x004500fc,
210250x004601ac,
210260x004701ac,
210270x004801fe,
210280x0049020c,
210290x004a0255,
210300x004b0282,
210310x0052025f,
210320x00530271,
210330x00540287,
210340x00570299,
210350x0060029d,
210360x006102ac,
210370x006202b6,
210380x006302c0,
210390x006402ca,
210400x006502d4,
210410x006602de,
210420x006702e8,
210430x006802f2,
210440x006902f6,
210450x006a02fa,
210460x006b02fe,
210470x006c0302,
210480x006d0306,
210490x006e030a,
210500x006f030e,
210510x00700312,
210520x00720363,
210530x00740369,
210540x00790367,
210550x007c031c,
210560x000f0378,
210570x000f0378,
210580x000f0378,
210590x000f0378,
210600x000f0378,
210610x000f0378,
210620x000f0378,
210630x000f0378,
210640x000f0378,
210650x000f0378,
210660x000f0378,
210670x000f0378,
210680x000f0378,
210690x000f0378,
210700x000f0378,
210710x000f0378,
210720x000f0378,
210730x000f0378,
210740x000f0378,
210750x000f0378,
210760x000f0378,
210770x000f0378,
210780x000f0378,
210790x000f0378,
210800x000f0378,
21081};
21082
21083static const u32 RV710_pfp_microcode[] = {
210840x7c408000,
210850xa0000000,
210860x7e82800b,
210870x80000000,
210880xdc030000,
210890xcc800040,
210900xd0400040,
210910x7c408000,
210920xa0000000,
210930x7e82800b,
210940xc818000e,
210950x31980001,
210960x7c424000,
210970x9580023a,
210980x7c428000,
210990xc81c001c,
211000xc037c000,
211010x7c40c000,
211020x7c410000,
211030x7cb4800b,
211040xc0360003,
211050x99c00000,
211060xc81c001c,
211070x7cb4800c,
211080x24d40002,
211090x7d654000,
211100xcd400043,
211110xce800043,
211120xcd000043,
211130xcc800040,
211140xce400040,
211150xce800040,
211160xccc00040,
211170xdc3a0000,
211180x9780ffde,
211190xcd000040,
211200x7c40c000,
211210x80000018,
211220x7c410000,
211230xd4000340,
211240xd4000fc0,
211250xd4000fa2,
211260xc818000e,
211270x8000000c,
211280x31980002,
211290xd40003c0,
211300xd4000fc0,
211310xd4000fa2,
211320xc818000e,
211330x288c0008,
211340x30cc000f,
211350x34100001,
211360x7d0d0008,
211370x8000000c,
211380x7d91800b,
211390xcc800040,
211400xd0400040,
211410x7c408000,
211420xa0000000,
211430x7e82800b,
211440xd4000340,
211450xd4000fc0,
211460xd4000fa2,
211470xcc800040,
211480xd0400040,
211490x7c408000,
211500xa0000000,
211510x7e82800b,
211520xd40003c0,
211530xd4000fc0,
211540xd4000fa2,
211550xcc800040,
211560xd0400040,
211570x7c408000,
211580xa0000000,
211590x7e82800b,
211600xcc4003f9,
211610x80000249,
211620xcc4003f8,
211630xc037ffff,
211640x7c414000,
211650xcf41a29e,
211660xc82003f8,
211670xc81c03f9,
211680x66200020,
211690xc81803fb,
211700x7de1c02c,
211710x7d58c008,
211720x7cdcc020,
211730x69100020,
211740xc0360003,
211750xcc000054,
211760x7cb4800c,
211770x80000069,
211780xcc800040,
211790x7c418000,
211800xcd81a29e,
211810xcc800040,
211820x80000067,
211830xcd800040,
211840xc019ffff,
211850xcc800040,
211860xcd81a29e,
211870x7c40c000,
211880x7c410000,
211890x7c414000,
211900xccc1a1fa,
211910xcd01a1f9,
211920xcd41a29d,
211930xccc00040,
211940xcd000040,
211950xcd400040,
211960xcc400040,
211970x7c408000,
211980xa0000000,
211990x7e82800b,
212000xcc000054,
212010xcc800040,
212020x7c40c000,
212030x7c410000,
212040x7c414000,
212050xccc1a1fa,
212060xcd01a1f9,
212070xcd41a29d,
212080xccc00040,
212090xcd000040,
212100xcd400040,
212110xd0400040,
212120x7c408000,
212130xa0000000,
212140x7e82800b,
212150x7c40c000,
212160x30d00001,
212170xccc1a29f,
212180x95000003,
212190x04140001,
212200x04140002,
212210xcd4003fb,
212220xcc800040,
212230x80000000,
212240xccc00040,
212250x7c40c000,
212260xcc800040,
212270xccc1a2a2,
212280x80000000,
212290xccc00040,
212300x7c40c000,
212310x28d4001f,
212320xcc800040,
212330x95400003,
212340x7c410000,
212350xccc00057,
212360x2918001f,
212370xccc00040,
212380x95800003,
212390xcd000040,
212400xcd000058,
212410x80000249,
212420xcc00007f,
212430xc8200017,
212440xc8300022,
212450x9a000006,
212460x0e280001,
212470xc824001e,
212480x0a640001,
212490xd4001240,
212500xce400040,
212510xc036c000,
212520x96800007,
212530x37747900,
212540x041c0001,
212550xcf400040,
212560xcdc00040,
212570xcf0003fa,
212580x7c030000,
212590xca0c0010,
212600x7c410000,
212610x94c00004,
212620x7c414000,
212630xd42002c4,
212640xcde00044,
212650x9b00000b,
212660x7c418000,
212670xcc00004b,
212680xcda00049,
212690xcd200041,
212700xcd600041,
212710xcda00041,
212720x06200001,
212730xce000056,
212740x80000249,
212750xcc00007f,
212760xc8280020,
212770xc82c0021,
212780xcc000063,
212790x7eea4001,
212800x65740020,
212810x7f53402c,
212820x269c0002,
212830x7df5c020,
212840x69f80020,
212850xce80004b,
212860xce600049,
212870xcde00041,
212880xcfa00041,
212890xce600041,
212900x271c0002,
212910x7df5c020,
212920x69f80020,
212930x7db24001,
212940xcf00004b,
212950xce600049,
212960xcde00041,
212970xcfa00041,
212980x800000bc,
212990xce600041,
213000xc8200017,
213010xc8300022,
213020x9a000006,
213030x0e280001,
213040xc824001e,
213050x0a640001,
213060xd4001240,
213070xce400040,
213080xca0c0010,
213090x7c410000,
213100x94c0000b,
213110xc036c000,
213120x96800007,
213130x37747900,
213140x041c0001,
213150xcf400040,
213160xcdc00040,
213170xcf0003fa,
213180x7c030000,
213190x800000b5,
213200x7c414000,
213210xcc000048,
213220x800000ee,
213230x00000000,
213240xc8200017,
213250xc81c0023,
213260x0e240002,
213270x99c00015,
213280x7c418000,
213290x0a200001,
213300xce000056,
213310xd4000440,
213320xcc000040,
213330xc036c000,
213340xca140013,
213350x96400007,
213360x37747900,
213370xcf400040,
213380xcc000040,
213390xc83003fa,
213400x80000103,
213410xcf000022,
213420xcc000022,
213430x95400146,
213440xcc00007f,
213450xcca00046,
213460x80000000,
213470xcc200046,
213480x80000249,
213490xcc000064,
213500xc8200017,
213510xc810001f,
213520x96000005,
213530x09100001,
213540xd4000440,
213550xcd000040,
213560xcd000022,
213570xcc800040,
213580xd0400040,
213590xc80c0025,
213600x94c0feec,
213610xc8100008,
213620xcd000040,
213630xd4000fc0,
213640x80000000,
213650xd4000fa2,
213660x7c40c000,
213670x7c410000,
213680xccc003fd,
213690xcd0003fc,
213700xccc00042,
213710xcd000042,
213720x2914001f,
213730x29180010,
213740x31980007,
213750x3b5c0001,
213760x7d76000b,
213770x99800005,
213780x7d5e400b,
213790xcc000042,
213800x80000249,
213810xcc00004d,
213820x29980001,
213830x292c0008,
213840x9980003d,
213850x32ec0001,
213860x96000004,
213870x2930000c,
213880x80000249,
213890xcc000042,
213900x04140010,
213910xcd400042,
213920x33300001,
213930x34280001,
213940x8400015d,
213950xc8140003,
213960x9b40001b,
213970x0438000c,
213980x8400015d,
213990xc8140003,
214000x9b400017,
214010x04380008,
214020x8400015d,
214030xc8140003,
214040x9b400013,
214050x04380004,
214060x8400015d,
214070xc8140003,
214080x9b400015,
214090xc80c03fd,
214100x9a800009,
214110xc81003fc,
214120x9b000101,
214130xcc00004d,
214140x04140010,
214150xccc00042,
214160xcd000042,
214170x80000135,
214180xcd400042,
214190x96c000fa,
214200xcc00004d,
214210x80000249,
214220xcc00004e,
214230x9ac00003,
214240xcc00004d,
214250xcc00004e,
214260xdf830000,
214270x80000000,
214280xd80301ff,
214290x9ac000f0,
214300xcc00004d,
214310x80000249,
214320xcc00004e,
214330xc8180003,
214340xc81c0003,
214350xc8200003,
214360x7d5d4003,
214370x7da1c003,
214380x7d5d400c,
214390x2a10001f,
214400x299c001f,
214410x7d1d000b,
214420x7d17400b,
214430x88000000,
214440x7e92800b,
214450x96400004,
214460xcc00004e,
214470x80000249,
214480xcc000042,
214490x04380008,
214500xcf800042,
214510xc8080003,
214520xc80c0003,
214530xc8100003,
214540xc8140003,
214550xc8180003,
214560xc81c0003,
214570xc8240003,
214580xc8280003,
214590x29fc001f,
214600x2ab0001f,
214610x7ff3c00b,
214620x28f0001f,
214630x7ff3c00b,
214640x2970001f,
214650x7ff3c00b,
214660x7d888001,
214670x7dccc001,
214680x7e510001,
214690x7e954001,
214700x7c908002,
214710x7cd4c002,
214720x7cbc800b,
214730x9ac00003,
214740x7c8f400b,
214750x38b40001,
214760x9b4000c1,
214770xcc00004d,
214780x9bc000bf,
214790xcc00004e,
214800xc80c03fd,
214810xc81003fc,
214820xccc00042,
214830x8000016e,
214840xcd000042,
214850xd4000340,
214860xd4000fc0,
214870xd4000fa2,
214880xcc800040,
214890xcc400040,
214900xcc400040,
214910xcc400040,
214920x7c40c000,
214930xccc00040,
214940xccc0000d,
214950x80000000,
214960xd0400040,
214970x7c40c000,
214980x7c410000,
214990x65140020,
215000x7d4d402c,
215010x24580002,
215020x7d598020,
215030x7c41c000,
215040xcd800042,
215050x69980020,
215060xcd800042,
215070xcdc00042,
215080xc023c000,
215090x05e40002,
215100x7ca0800b,
215110x26640010,
215120x7ca4800c,
215130xcc800040,
215140xcdc00040,
215150xccc00040,
215160x95c0000e,
215170xcd000040,
215180x09dc0001,
215190xc8280003,
215200x96800008,
215210xce800040,
215220xc834001d,
215230x97400000,
215240xc834001d,
215250x26a80008,
215260x8400024c,
215270xcc2b0000,
215280x99c0fff7,
215290x09dc0001,
215300xdc3a0000,
215310x97800004,
215320x7c418000,
215330x800001a2,
215340x25980002,
215350xa0000000,
215360x7d808000,
215370xc818001d,
215380x7c40c000,
215390x64d00008,
215400x95800000,
215410xc818001d,
215420xcc130000,
215430xcc800040,
215440xccc00040,
215450x80000000,
215460xcc400040,
215470xc810001f,
215480x7c40c000,
215490xcc800040,
215500x7cd1400c,
215510xcd400040,
215520x05180001,
215530x80000000,
215540xcd800022,
215550x7c40c000,
215560x64500020,
215570x8400024c,
215580xcc000061,
215590x7cd0c02c,
215600xc8200017,
215610xc8d60000,
215620x99400008,
215630x7c438000,
215640xdf830000,
215650xcfa0004f,
215660x8400024c,
215670xcc000062,
215680x80000000,
215690xd040007f,
215700x80000249,
215710xcc000062,
215720x8400024c,
215730xcc000061,
215740xc8200017,
215750x7c40c000,
215760xc036ff00,
215770xc810000d,
215780xc0303fff,
215790x7cf5400b,
215800x7d51800b,
215810x7d81800f,
215820x99800008,
215830x7cf3800b,
215840xdf830000,
215850xcfa0004f,
215860x8400024c,
215870xcc000062,
215880x80000000,
215890xd040007f,
215900x80000249,
215910xcc000062,
215920x8400024c,
215930x7c40c000,
215940x28dc0008,
215950x95c00019,
215960x30dc0010,
215970x7c410000,
215980x99c00004,
215990x64540020,
216000x80000208,
216010xc91d0000,
216020x7d15002c,
216030xc91e0000,
216040x7c420000,
216050x7c424000,
216060x7c418000,
216070x7de5c00b,
216080x7de28007,
216090x9a80000e,
216100x41ac0005,
216110x9ac00000,
216120x0aec0001,
216130x30dc0010,
216140x99c00004,
216150x00000000,
216160x8000020b,
216170xc91d0000,
216180x8000020b,
216190xc91e0000,
216200xcc800040,
216210xccc00040,
216220xd0400040,
216230xc80c0025,
216240x94c0fde4,
216250xc8100008,
216260xcd000040,
216270xd4000fc0,
216280x80000000,
216290xd4000fa2,
216300xd4000340,
216310xd4000fc0,
216320xd4000fa2,
216330xcc800040,
216340xd0400040,
216350x7c408000,
216360xa0000000,
216370x7e82800b,
216380xd40003c0,
216390xd4000fc0,
216400xd4000fa2,
216410xcc800040,
216420xd0400040,
216430x7c408000,
216440xa0000000,
216450x7e82800b,
216460x7c40c000,
216470x30d00006,
216480x0d100006,
216490x99000007,
216500xc8140015,
216510x99400005,
216520xcc000052,
216530xd4000340,
216540xd4000fc0,
216550xd4000fa2,
216560xcc800040,
216570xccc00040,
216580x80000000,
216590xd0400040,
216600x7c40c000,
216610xcc4d0000,
216620xdc3a0000,
216630x9780fdbd,
216640x04cc0001,
216650x80000242,
216660xcc4d0000,
216670x80000000,
216680xd040007f,
216690xcc00007f,
216700x80000000,
216710xcc00007f,
216720xcc00007f,
216730x88000000,
216740xcc00007f,
216750x00000000,
216760x00000000,
216770x00000000,
216780x00000000,
216790x00000000,
216800x00000000,
216810x00000000,
216820x00000000,
216830x00000000,
216840x00000000,
216850x00000000,
216860x00000000,
216870x00000000,
216880x00000000,
216890x00000000,
216900x00000000,
216910x00000000,
216920x00000000,
216930x00000000,
216940x00000000,
216950x00000000,
216960x00000000,
216970x00000000,
216980x00000000,
216990x00000000,
217000x00000000,
217010x00000000,
217020x00000000,
217030x00000000,
217040x00000000,
217050x00000000,
217060x00000000,
217070x00000000,
217080x00000000,
217090x00000000,
217100x00000000,
217110x00000000,
217120x00000000,
217130x00000000,
217140x00000000,
217150x00000000,
217160x00000000,
217170x00000000,
217180x00000000,
217190x00000000,
217200x00000000,
217210x00000000,
217220x00000000,
217230x00000000,
217240x00000000,
217250x00000000,
217260x00000000,
217270x00000000,
217280x00000000,
217290x00000000,
217300x00000000,
217310x00000000,
217320x00000000,
217330x00000000,
217340x00000000,
217350x00000000,
217360x00000000,
217370x00000000,
217380x00000000,
217390x00000000,
217400x00000000,
217410x00000000,
217420x00000000,
217430x00000000,
217440x00000000,
217450x00000000,
217460x00000000,
217470x00000000,
217480x00000000,
217490x00000000,
217500x00000000,
217510x00000000,
217520x00000000,
217530x00000000,
217540x00000000,
217550x00000000,
217560x00000000,
217570x00000000,
217580x00000000,
217590x00000000,
217600x00000000,
217610x00000000,
217620x00000000,
217630x00000000,
217640x00000000,
217650x00000000,
217660x00000000,
217670x00000000,
217680x00000000,
217690x00000000,
217700x00000000,
217710x00000000,
217720x00000000,
217730x00000000,
217740x00000000,
217750x00000000,
217760x00000000,
217770x00000000,
217780x00000000,
217790x00000000,
217800x00000000,
217810x00000000,
217820x00000000,
217830x00000000,
217840x00000000,
217850x00000000,
217860x00000000,
217870x00000000,
217880x00000000,
217890x00000000,
217900x00000000,
217910x00000000,
217920x00000000,
217930x00000000,
217940x00000000,
217950x00000000,
217960x00000000,
217970x00000000,
217980x00000000,
217990x00000000,
218000x00000000,
218010x00000000,
218020x00000000,
218030x00000000,
218040x00000000,
218050x00000000,
218060x00000000,
218070x00000000,
218080x00000000,
218090x00000000,
218100x00000000,
218110x00000000,
218120x00000000,
218130x00000000,
218140x00000000,
218150x00000000,
218160x00000000,
218170x00000000,
218180x00000000,
218190x00000000,
218200x00000000,
218210x00000000,
218220x00000000,
218230x00000000,
218240x00000000,
218250x00000000,
218260x00000000,
218270x00000000,
218280x00000000,
218290x00000000,
218300x00000000,
218310x00000000,
218320x00000000,
218330x00000000,
218340x00000000,
218350x00000000,
218360x00000000,
218370x00000000,
218380x00000000,
218390x00000000,
218400x00000000,
218410x00000000,
218420x00000000,
218430x00000000,
218440x00000000,
218450x00000000,
218460x00000000,
218470x00000000,
218480x00000000,
218490x00000000,
218500x00000000,
218510x00000000,
218520x00030222,
218530x0004022a,
218540x0005009f,
218550x00020003,
218560x0006003c,
218570x00070027,
218580x00080191,
218590x00090044,
218600x000a002d,
218610x00100247,
218620x001700f0,
218630x002201d7,
218640x002301e8,
218650x0026004c,
218660x0027005f,
218670x0020011a,
218680x00280092,
218690x0029004f,
218700x002a0083,
218710x002b0064,
218720x002f008d,
218730x003200d8,
218740x00340232,
218750x00360074,
218760x0039010a,
218770x003c01fc,
218780x003f009f,
218790x00410005,
218800x00440194,
218810x0048019d,
218820x004901c5,
218830x004a01cf,
218840x00550225,
218850x0056022d,
218860x0060000a,
218870x0061002a,
218880x00620030,
218890x00630030,
218900x00640030,
218910x00650030,
218920x00660030,
218930x00670030,
218940x00680037,
218950x0069003f,
218960x006a0047,
218970x006b0047,
218980x006c0047,
218990x006d0047,
219000x006e0047,
219010x006f0047,
219020x00700047,
219030x00730247,
219040x007b0240,
219050x00000005,
219060x00000005,
219070x00000005,
219080x00000005,
219090x00000005,
219100x00000005,
219110x00000005,
219120x00000005,
219130x00000005,
219140x00000005,
219150x00000005,
219160x00000005,
219170x00000005,
219180x00000005,
219190x00000005,
219200x00000005,
219210x00000005,
219220x00000005,
219230x00000005,
219240x00000005,
219250x00000005,
219260x00000005,
219270x00000005,
219280x00000005,
219290x00000005,
219300x00000005,
219310x00000005,
21932};
21933
21934static const u32 RV710_cp_microcode[] = {
219350xcc0003ea,
219360x04080003,
219370xcc800043,
219380x7c408000,
219390xa0000000,
219400xcc800062,
219410x80000003,
219420xd040007f,
219430x80000003,
219440xcc400041,
219450x7c40c000,
219460xc0160004,
219470x30d03fff,
219480x7d15000c,
219490xcc110000,
219500x28d8001e,
219510x31980001,
219520x28dc001f,
219530xc8200004,
219540x95c00006,
219550x7c424000,
219560xcc000062,
219570x7e56800c,
219580xcc290000,
219590xc8240004,
219600x7e26000b,
219610x95800006,
219620x7c42c000,
219630xcc000062,
219640x7ed7000c,
219650xcc310000,
219660xc82c0004,
219670x7e2e000c,
219680xcc000062,
219690x31103fff,
219700x80000003,
219710xce110000,
219720x7c40c000,
219730x80000003,
219740xcc400040,
219750x80000003,
219760xcc412257,
219770x7c418000,
219780xcc400045,
219790xcc400048,
219800xcc41225c,
219810xcc41a1fc,
219820x7c408000,
219830xa0000000,
219840xcc800062,
219850xcc400045,
219860xcc400048,
219870x7c40c000,
219880xcc41225c,
219890xcc41a1fc,
219900x7c408000,
219910xa0000000,
219920xcc800062,
219930xcc000045,
219940xcc000048,
219950xcc41225c,
219960xcc41a1fc,
219970x7c408000,
219980xa0000000,
219990xcc800062,
220000x040ca1fd,
220010xc0120001,
220020xcc000045,
220030xcc000048,
220040x7cd0c00c,
220050xcc41225c,
220060xcc41a1fc,
220070xd04d0000,
220080x7c408000,
220090xa0000000,
220100xcc800062,
220110x80000003,
220120xcc41225d,
220130x7c408000,
220140x7c40c000,
220150xc02a0002,
220160x7c410000,
220170x7d29000c,
220180x30940001,
220190x30980006,
220200x309c0300,
220210x29dc0008,
220220x7c420000,
220230x7c424000,
220240x9540000f,
220250xc02e0004,
220260x05f02258,
220270x7f2f000c,
220280xcc310000,
220290xc8280004,
220300xccc12169,
220310xcd01216a,
220320xce81216b,
220330x0db40002,
220340xcc01216c,
220350x9740000e,
220360x0db40000,
220370x8000007d,
220380xc834000a,
220390x0db40002,
220400x97400009,
220410x0db40000,
220420xc02e0004,
220430x05f02258,
220440x7f2f000c,
220450xcc310000,
220460xc8280004,
220470x8000007d,
220480xc834000a,
220490x97400004,
220500x7e028000,
220510x8000007d,
220520xc834000a,
220530x0db40004,
220540x9740ff8c,
220550x00000000,
220560xce01216d,
220570xce41216e,
220580xc8280003,
220590xc834000a,
220600x9b400004,
220610x043c0005,
220620x8400026d,
220630xcc000062,
220640x0df40000,
220650x9740000b,
220660xc82c03e6,
220670xce81a2b7,
220680xc0300006,
220690x7ef34028,
220700xc0300020,
220710x7f6b8020,
220720x7fb3c029,
220730xcf81a2c4,
220740x80000003,
220750xcfc1a2d1,
220760x0df40001,
220770x9740000b,
220780xc82c03e7,
220790xce81a2bb,
220800xc0300006,
220810x7ef34028,
220820xc0300020,
220830x7f6b8020,
220840x7fb3c029,
220850xcf81a2c5,
220860x80000003,
220870xcfc1a2d2,
220880x0df40002,
220890x9740000b,
220900xc82c03e8,
220910xce81a2bf,
220920xc0300006,
220930x7ef34028,
220940xc0300020,
220950x7f6b8020,
220960x7fb3c029,
220970xcf81a2c6,
220980x80000003,
220990xcfc1a2d3,
221000xc82c03e9,
221010xce81a2c3,
221020xc0300006,
221030x7ef34028,
221040xc0300020,
221050x7f6b8020,
221060x7fb3c029,
221070xcf81a2c7,
221080x80000003,
221090xcfc1a2d4,
221100x80000003,
221110xcc400042,
221120x7c40c000,
221130x7c410000,
221140x2914001d,
221150x31540001,
221160x9940000c,
221170x31181000,
221180xc81c0011,
221190x95c00000,
221200xc81c0011,
221210xccc12100,
221220xcd012101,
221230xccc12102,
221240xcd012103,
221250x04180004,
221260x8000037e,
221270xcd81a2a4,
221280xc02a0004,
221290x95800008,
221300x36a821a3,
221310xcc290000,
221320xc8280004,
221330xc81c0011,
221340x0de40040,
221350x9640ffff,
221360xc81c0011,
221370xccc12170,
221380xcd012171,
221390xc8200012,
221400x96000000,
221410xc8200012,
221420x8000037e,
221430xcc000064,
221440x7c40c000,
221450x7c410000,
221460xcc000045,
221470xcc000048,
221480x40d40003,
221490xcd41225c,
221500xcd01a1fc,
221510xc01a0001,
221520x041ca1fd,
221530x7dd9c00c,
221540x7c420000,
221550x08cc0001,
221560x06240001,
221570x06280002,
221580xce1d0000,
221590xce5d0000,
221600x98c0fffa,
221610xce9d0000,
221620x7c408000,
221630xa0000000,
221640xcc800062,
221650x7c40c000,
221660x30d00001,
221670x28cc0001,
221680x7c414000,
221690x95000006,
221700x7c418000,
221710xcd41216d,
221720xcd81216e,
221730x800000f4,
221740xc81c0003,
221750xc0220004,
221760x7e16000c,
221770xcc210000,
221780xc81c0004,
221790x7c424000,
221800x98c00004,
221810x7c428000,
221820x80000003,
221830xcde50000,
221840xce412169,
221850xce81216a,
221860xcdc1216b,
221870x80000003,
221880xcc01216c,
221890x7c40c000,
221900x7c410000,
221910x7c414000,
221920x7c418000,
221930x7c41c000,
221940x28a40008,
221950x326400ff,
221960x0e68003c,
221970x9680000a,
221980x7c020000,
221990x7c420000,
222000x1e300003,
222010xcc00006a,
222020x9b000003,
222030x42200005,
222040x04200040,
222050x80000111,
222060x7c024000,
222070x7e024000,
222080x9a400000,
222090x0a640001,
222100x30ec0010,
222110x9ac0000a,
222120xcc000062,
222130xc02a0004,
222140xc82c0021,
222150x7e92800c,
222160xcc000041,
222170xcc290000,
222180xcec00021,
222190x80000121,
222200xc8300004,
222210xcd01216d,
222220xcd41216e,
222230xc8300003,
222240x7f1f000b,
222250x30f40007,
222260x27780001,
222270x9740002a,
222280x07b80126,
222290x9f800000,
222300x00000000,
222310x80000136,
222320x7f1b8004,
222330x8000013a,
222340x7f1b8005,
222350x8000013e,
222360x7f1b8002,
222370x80000142,
222380x7f1b8003,
222390x80000146,
222400x7f1b8007,
222410x8000014a,
222420x7f1b8006,
222430x8000014f,
222440x28a40008,
222450x9b800019,
222460x28a40008,
222470x8000015f,
222480x326400ff,
222490x9b800015,
222500x28a40008,
222510x8000015f,
222520x326400ff,
222530x9b800011,
222540x28a40008,
222550x8000015f,
222560x326400ff,
222570x9b80000d,
222580x28a40008,
222590x8000015f,
222600x326400ff,
222610x9b800009,
222620x28a40008,
222630x8000015f,
222640x326400ff,
222650x9b800005,
222660x28a40008,
222670x8000015f,
222680x326400ff,
222690x28a40008,
222700x326400ff,
222710x0e68003c,
222720x9a80feb2,
222730x28ec0008,
222740x7c434000,
222750x7c438000,
222760x7c43c000,
222770x96c00007,
222780xcc000062,
222790xcf412169,
222800xcf81216a,
222810xcfc1216b,
222820x80000003,
222830xcc01216c,
222840x80000003,
222850xcff50000,
222860xcc00006b,
222870x84000381,
222880x0e68003c,
222890x9a800004,
222900xc8280015,
222910x80000003,
222920xd040007f,
222930x9680ffab,
222940x7e024000,
222950x8400023b,
222960xc00e0002,
222970xcc000041,
222980x80000239,
222990xccc1304a,
223000x7c40c000,
223010x7c410000,
223020xc01e0001,
223030x29240012,
223040xc0220002,
223050x96400005,
223060xc0260004,
223070xc027fffb,
223080x7d25000b,
223090xc0260000,
223100x7dd2800b,
223110x7e12c00b,
223120x7d25000c,
223130x7c414000,
223140x7c418000,
223150xccc12169,
223160x9a80000a,
223170xcd01216a,
223180xcd41216b,
223190x96c0fe83,
223200xcd81216c,
223210xc8300018,
223220x97000000,
223230xc8300018,
223240x80000003,
223250xcc000018,
223260x84000381,
223270xcc00007f,
223280xc8140013,
223290xc8180014,
223300xcd41216b,
223310x96c0fe77,
223320xcd81216c,
223330x80000183,
223340xc8300018,
223350xc80c0008,
223360x98c00000,
223370xc80c0008,
223380x7c410000,
223390x95000002,
223400x00000000,
223410x7c414000,
223420xc8200009,
223430xcc400043,
223440xce01a1f4,
223450xcc400044,
223460xc00e8000,
223470x7c424000,
223480x7c428000,
223490x2aac001f,
223500x96c0fe64,
223510xc035f000,
223520xce4003e2,
223530x32780003,
223540x267c0008,
223550x7ff7c00b,
223560x7ffbc00c,
223570x2a780018,
223580xcfc003e3,
223590xcf8003e4,
223600x26b00002,
223610x7f3f0000,
223620xcf0003e5,
223630x8000031f,
223640x7c80c000,
223650x7c40c000,
223660x28d00008,
223670x3110000f,
223680x9500000f,
223690x25280001,
223700x06a801b4,
223710x9e800000,
223720x00000000,
223730x800001d5,
223740xc0120800,
223750x800001e3,
223760xc814000f,
223770x800001ea,
223780xc8140010,
223790x800001f1,
223800xccc1a2a4,
223810x800001fa,
223820xc8140011,
223830x30d0003f,
223840x0d280015,
223850x9a800012,
223860x0d28001e,
223870x9a80001e,
223880x0d280020,
223890x9a800023,
223900x0d24000f,
223910x0d280010,
223920x7e6a800c,
223930x9a800026,
223940x0d200004,
223950x0d240014,
223960x0d280028,
223970x7e62400c,
223980x7ea6800c,
223990x9a80002a,
224000xc8140011,
224010x80000003,
224020xccc1a2a4,
224030xc0120800,
224040x7c414000,
224050x7d0cc00c,
224060xc0120008,
224070x29580003,
224080x295c000c,
224090x7c420000,
224100x7dd1c00b,
224110x26200014,
224120x7e1e400c,
224130x7e4e800c,
224140xce81a2a4,
224150x80000003,
224160xcd81a1fe,
224170xc814000f,
224180x0410210e,
224190x95400000,
224200xc814000f,
224210xd0510000,
224220x80000003,
224230xccc1a2a4,
224240xc8140010,
224250x04102108,
224260x95400000,
224270xc8140010,
224280xd0510000,
224290x80000003,
224300xccc1a2a4,
224310xccc1a2a4,
224320x04100001,
224330xcd000019,
224340x84000381,
224350xcc00007f,
224360xc8100019,
224370x99000000,
224380xc8100019,
224390x80000004,
224400x7c408000,
224410x04102100,
224420x95400000,
224430xc8140011,
224440xd0510000,
224450x8000037e,
224460xccc1a2a4,
224470x7c40c000,
224480xcc40000d,
224490x94c0fe01,
224500xcc40000e,
224510x7c410000,
224520x95000005,
224530x08cc0001,
224540xc8140005,
224550x99400014,
224560x00000000,
224570x98c0fffb,
224580x7c410000,
224590x80000004,
224600x7d008000,
224610xc8140005,
224620x7c40c000,
224630x9940000c,
224640xc818000c,
224650x7c410000,
224660x9580fdf0,
224670xc820000e,
224680xc81c000d,
224690x66200020,
224700x7e1e002c,
224710x25240002,
224720x7e624020,
224730x80000003,
224740xcce60000,
224750x7c410000,
224760xcc00006c,
224770xcc00006d,
224780xc818001f,
224790xc81c001e,
224800x65980020,
224810x7dd9c02c,
224820x7cd4c00c,
224830xccde0000,
224840x45dc0004,
224850xc8280017,
224860x9680000f,
224870xc00e0001,
224880x28680008,
224890x2aac0016,
224900x32a800ff,
224910x0eb00049,
224920x7f2f000b,
224930x97000006,
224940x00000000,
224950xc8140005,
224960x7c40c000,
224970x80000223,
224980x7c410000,
224990x80000226,
225000xd040007f,
225010x8400023b,
225020xcc000041,
225030xccc1304a,
225040x94000000,
225050xc83c001a,
225060x043c0005,
225070xcfc1a2a4,
225080xc0361f90,
225090xc0387fff,
225100x7c03c010,
225110x7f7b400c,
225120xcf41217c,
225130xcfc1217d,
225140xcc01217e,
225150xc03a0004,
225160x0434217f,
225170x7f7b400c,
225180xcc350000,
225190xc83c0004,
225200x2bfc001f,
225210x04380020,
225220x97c00005,
225230xcc000062,
225240x9b800000,
225250x0bb80001,
225260x80000247,
225270xcc000071,
225280xcc01a1f4,
225290x04380016,
225300xc0360002,
225310xcf81a2a4,
225320x88000000,
225330xcf412010,
225340x7c40c000,
225350x28d0001c,
225360x95000005,
225370x04d40001,
225380xcd400065,
225390x80000003,
225400xcd400068,
225410x09540002,
225420x80000003,
225430xcd400066,
225440x8400026c,
225450xc81803ea,
225460x7c40c000,
225470x9980fd9f,
225480xc8140016,
225490x08d00001,
225500x9940002b,
225510xcd000068,
225520x7c408000,
225530xa0000000,
225540xcc800062,
225550x043c0005,
225560xcfc1a2a4,
225570xcc01a1f4,
225580x84000381,
225590xcc000046,
225600x88000000,
225610xcc00007f,
225620x8400027e,
225630xc81803ea,
225640x7c40c000,
225650x9980fd8d,
225660xc8140016,
225670x08d00001,
225680x99400019,
225690xcd000068,
225700x7c408000,
225710xa0000000,
225720xcc800062,
225730x043c0022,
225740xcfc1a2a4,
225750x84000381,
225760xcc000047,
225770x88000000,
225780xcc00007f,
225790xc8100016,
225800x9900000d,
225810xcc400067,
225820x80000004,
225830x7c408000,
225840xc81803ea,
225850x9980fd79,
225860x7c40c000,
225870x94c00003,
225880xc8100016,
225890x99000004,
225900xccc00068,
225910x80000004,
225920x7c408000,
225930x8400023b,
225940xc0148000,
225950xcc000041,
225960xcd41304a,
225970xc0148000,
225980x99000000,
225990xc8100016,
226000x80000004,
226010x7c408000,
226020xc0120001,
226030x7c51400c,
226040x80000003,
226050xd0550000,
226060x7c40c000,
226070x7c410000,
226080x7c414000,
226090x7c418000,
226100x291c001f,
226110xccc0004a,
226120xcd00004b,
226130x95c00003,
226140xc01c8000,
226150xcdc12010,
226160xdd830000,
226170x055c2000,
226180xcc000062,
226190x80000003,
226200xd81f4100,
226210x7c40c000,
226220x7c410000,
226230x7c414000,
226240x7c418000,
226250xccc0004c,
226260xcd00004d,
226270xdd830000,
226280x055ca000,
226290x80000003,
226300xd81f4100,
226310x7c40c000,
226320x7c410000,
226330x7c414000,
226340x7c418000,
226350xccc0004e,
226360xcd00004f,
226370xdd830000,
226380x055cc000,
226390x80000003,
226400xd81f4100,
226410x7c40c000,
226420x7c410000,
226430x7c414000,
226440x7c418000,
226450xccc00050,
226460xcd000051,
226470xdd830000,
226480x055cf8e0,
226490x80000003,
226500xd81f4100,
226510x7c40c000,
226520x7c410000,
226530x7c414000,
226540x7c418000,
226550xccc00052,
226560xcd000053,
226570xdd830000,
226580x055cf880,
226590x80000003,
226600xd81f4100,
226610x7c40c000,
226620x7c410000,
226630x7c414000,
226640x7c418000,
226650xccc00054,
226660xcd000055,
226670xdd830000,
226680x055ce000,
226690x80000003,
226700xd81f4100,
226710x7c40c000,
226720x7c410000,
226730x7c414000,
226740x7c418000,
226750xccc00056,
226760xcd000057,
226770xdd830000,
226780x055cf000,
226790x80000003,
226800xd81f4100,
226810x7c40c000,
226820x7c410000,
226830x7c414000,
226840x7c418000,
226850xccc00058,
226860xcd000059,
226870xdd830000,
226880x055cf3fc,
226890x80000003,
226900xd81f4100,
226910xd0432000,
226920x7c408000,
226930xa0000000,
226940xcc800062,
226950xd043a000,
226960x7c408000,
226970xa0000000,
226980xcc800062,
226990xd043c000,
227000x7c408000,
227010xa0000000,
227020xcc800062,
227030xd043f8e0,
227040x7c408000,
227050xa0000000,
227060xcc800062,
227070xd043f880,
227080x7c408000,
227090xa0000000,
227100xcc800062,
227110xd043e000,
227120x7c408000,
227130xa0000000,
227140xcc800062,
227150xd043f000,
227160x7c408000,
227170xa0000000,
227180xcc800062,
227190xd043f3fc,
227200x7c408000,
227210xa0000000,
227220xcc800062,
227230xc81403e0,
227240xcc430000,
227250xcc430000,
227260xcc430000,
227270x7d45c000,
227280xcdc30000,
227290xd0430000,
227300x7c408000,
227310xa0000000,
227320xcc800062,
227330x7c40c000,
227340xc81003e2,
227350xc81403e5,
227360xc81803e3,
227370xc81c03e4,
227380xcd812169,
227390xcdc1216a,
227400xccc1216b,
227410xcc01216c,
227420x04200004,
227430x7da18000,
227440x7d964002,
227450x9640fcd9,
227460xcd8003e3,
227470x31280003,
227480xc02df000,
227490x25180008,
227500x7dad800b,
227510x7da9800c,
227520x80000003,
227530xcd8003e3,
227540x308cffff,
227550xd04d0000,
227560x7c408000,
227570xa0000000,
227580xcc800062,
227590xc8140020,
227600x15580002,
227610x9580ffff,
227620xc8140020,
227630xcc00006e,
227640xcc412180,
227650x7c40c000,
227660xccc1218d,
227670xcc412181,
227680x28d0001f,
227690x34588000,
227700xcd81218c,
227710x9500fcbf,
227720xcc412182,
227730xc8140020,
227740x9940ffff,
227750xc8140020,
227760x80000004,
227770x7c408000,
227780x7c40c000,
227790x28d00018,
227800x31100001,
227810xc0160080,
227820x95000003,
227830xc02a0004,
227840x7cd4c00c,
227850xccc1217c,
227860xcc41217d,
227870xcc41217e,
227880x7c418000,
227890x1db00003,
227900x36a0217f,
227910x9b000003,
227920x419c0005,
227930x041c0040,
227940x99c00000,
227950x09dc0001,
227960xcc210000,
227970xc8240004,
227980x2a6c001f,
227990x419c0005,
228000x9ac0fffa,
228010xcc800062,
228020x80000004,
228030x7c408000,
228040x7c40c000,
228050x04d403e6,
228060x80000003,
228070xcc540000,
228080x8000037e,
228090xcc4003ea,
228100xc01c8000,
228110x044ca000,
228120xcdc12010,
228130x7c410000,
228140xc8140009,
228150x04180000,
228160x041c0008,
228170xcd800071,
228180x09dc0001,
228190x05980001,
228200xcd0d0000,
228210x99c0fffc,
228220xcc800062,
228230x8000037e,
228240xcd400071,
228250xc00e0100,
228260xcc000041,
228270xccc1304a,
228280xc83c007f,
228290xcc00007f,
228300x80000003,
228310xcc00007f,
228320xcc00007f,
228330x88000000,
228340xcc00007f,
228350x00000000,
228360x00000000,
228370x00000000,
228380x00000000,
228390x00000000,
228400x00000000,
228410x00000000,
228420x00000000,
228430x00000000,
228440x00000000,
228450x00000000,
228460x00000000,
228470x00000000,
228480x00000000,
228490x00000000,
228500x00000000,
228510x00000000,
228520x00000000,
228530x00000000,
228540x00000000,
228550x00000000,
228560x00000000,
228570x00000000,
228580x00000000,
228590x00000000,
228600x00000000,
228610x00000000,
228620x00000000,
228630x00000000,
228640x00000000,
228650x00000000,
228660x00000000,
228670x00000000,
228680x00000000,
228690x00000000,
228700x00000000,
228710x00000000,
228720x00000000,
228730x00000000,
228740x00000000,
228750x00000000,
228760x00000000,
228770x00000000,
228780x00000000,
228790x00000000,
228800x00000000,
228810x00000000,
228820x00000000,
228830x00000000,
228840x00000000,
228850x00000000,
228860x00000000,
228870x00000000,
228880x00000000,
228890x00000000,
228900x00000000,
228910x00000000,
228920x00000000,
228930x00000000,
228940x00000000,
228950x00000000,
228960x00000000,
228970x00000000,
228980x00000000,
228990x00000000,
229000x00000000,
229010x00000000,
229020x00000000,
229030x00000000,
229040x00000000,
229050x00000000,
229060x00000000,
229070x00000000,
229080x00000000,
229090x00000000,
229100x00000000,
229110x00000000,
229120x00000000,
229130x00000000,
229140x00000000,
229150x00000000,
229160x00000000,
229170x00000000,
229180x00000000,
229190x00000000,
229200x00000000,
229210x00000000,
229220x00000000,
229230x00000000,
229240x00000000,
229250x00000000,
229260x00000000,
229270x00000000,
229280x00000000,
229290x00000000,
229300x00000000,
229310x00000000,
229320x00000000,
229330x00000000,
229340x00000000,
229350x00000000,
229360x00000000,
229370x00000000,
229380x00000000,
229390x00000000,
229400x00000000,
229410x00000000,
229420x00000000,
229430x00000000,
229440x00000000,
229450x00000000,
229460x00000000,
229470x00000000,
229480x00000000,
229490x00000000,
229500x00000000,
229510x00000000,
229520x00000000,
229530x00000000,
229540x00000000,
229550x00000000,
229560x00000000,
229570x00000000,
229580x00000000,
229590x00000000,
229600x00000000,
229610x00000000,
229620x00000000,
229630x00000000,
229640x00000000,
229650x00000000,
229660x00000000,
229670x00000000,
229680x00000000,
229690x00000000,
229700x00000000,
229710x00000000,
229720x00000000,
229730x00000000,
229740x00000000,
229750x00000000,
229760x00000000,
229770x00000000,
229780x00000000,
229790x00000000,
229800x00000000,
229810x00000000,
229820x00000000,
229830x00000000,
229840x00000000,
229850x00000000,
229860x00000000,
229870x00000000,
229880x00000000,
229890x00000000,
229900x00000000,
229910x00000000,
229920x00000000,
229930x00000000,
229940x00000000,
229950x00000000,
229960x00000000,
229970x00000000,
229980x00000000,
229990x00000000,
230000x00000000,
230010x00000000,
230020x00000000,
230030x00000000,
230040x00000000,
230050x00000000,
230060x00000000,
230070x00000000,
230080x00000000,
230090x00000000,
230100x00000000,
230110x00000000,
230120x00000000,
230130x00000000,
230140x00000000,
230150x00000000,
230160x00000000,
230170x00000000,
230180x00000000,
230190x00000000,
230200x00000000,
230210x00000000,
230220x00000000,
230230x00000000,
230240x00000000,
230250x00000000,
230260x00000000,
230270x00000000,
230280x00000000,
230290x00000000,
230300x00000000,
230310x00000000,
230320x00000000,
230330x00000000,
230340x00000000,
230350x00000000,
230360x00000000,
230370x00000000,
230380x00000000,
230390x00000000,
230400x00000000,
230410x00000000,
230420x00000000,
230430x00000000,
230440x00000000,
230450x00000000,
230460x00000000,
230470x00000000,
230480x00000000,
230490x00000000,
230500x00000000,
230510x00000000,
230520x00000000,
230530x00000000,
230540x00000000,
230550x00000000,
230560x00000000,
230570x00000000,
230580x00000000,
230590x00000000,
230600x00000000,
230610x00000000,
230620x00000000,
230630x00000000,
230640x00000000,
230650x00000000,
230660x00000000,
230670x00000000,
230680x00000000,
230690x00000000,
230700x00000000,
230710x00000000,
230720x00000000,
230730x00000000,
230740x00000000,
230750x00000000,
230760x00000000,
230770x00000000,
230780x00000000,
230790x00000000,
230800x00000000,
230810x00000000,
230820x00000000,
230830x00000000,
230840x00000000,
230850x00000000,
230860x00000000,
230870x00000000,
230880x00000000,
230890x00000000,
230900x00000000,
230910x00000000,
230920x00000000,
230930x00000000,
230940x00000000,
230950x00000000,
230960x00000000,
230970x00000000,
230980x00000000,
230990x00000000,
231000x00000000,
231010x00000000,
231020x00000000,
231030x00000000,
231040x00000000,
231050x00000000,
231060x00000000,
231070x00000000,
231080x00000000,
231090x00000000,
231100x00000000,
231110x00000000,
231120x00000000,
231130x00000000,
231140x00000000,
231150x00000000,
231160x00000000,
231170x00000000,
231180x00000000,
231190x00000000,
231200x00000000,
231210x00000000,
231220x00000000,
231230x00000000,
231240x00000000,
231250x00000000,
231260x00000000,
231270x00000000,
231280x00000000,
231290x00000000,
231300x00000000,
231310x00000000,
231320x00000000,
231330x00000000,
231340x00000000,
231350x00000000,
231360x00000000,
231370x00000000,
231380x00000000,
231390x00000000,
231400x00000000,
231410x00000000,
231420x00000000,
231430x00000000,
231440x00000000,
231450x00000000,
231460x00000000,
231470x00000000,
231480x00000000,
231490x00000000,
231500x00000000,
231510x00000000,
231520x00000000,
231530x00000000,
231540x00000000,
231550x00000000,
231560x00000000,
231570x00000000,
231580x00000000,
231590x00000000,
231600x00000000,
231610x00000000,
231620x00000000,
231630x00000000,
231640x00000000,
231650x00000000,
231660x00000000,
231670x00000000,
231680x00000000,
231690x00000000,
231700x00000000,
231710x00000000,
231720x00000000,
231730x00000000,
231740x00000000,
231750x00000000,
231760x00000000,
231770x00000000,
231780x00000000,
231790x00000000,
231800x00000000,
231810x00000000,
231820x00000000,
231830x00000000,
231840x00000000,
231850x00000000,
231860x00000000,
231870x00000000,
231880x00000000,
231890x00000000,
231900x00000000,
231910x00000000,
231920x00000000,
231930x00000000,
231940x00000000,
231950x00000000,
231960x00000000,
231970x00000000,
231980x00000000,
231990x00000000,
232000x00000000,
232010x00000000,
232020x00000000,
232030x00000000,
232040x00000000,
232050x00000000,
232060x00000000,
232070x00000000,
232080x00000000,
232090x00000000,
232100x00000000,
232110x00000000,
232120x00000000,
232130x00000000,
232140x00000000,
232150x00010333,
232160x00100006,
232170x00170008,
232180x0021000a,
232190x0027002a,
232200x00280025,
232210x0029002b,
232220x002a0028,
232230x002b002b,
232240x002d003a,
232250x002e0041,
232260x002f004c,
232270x0034004e,
232280x00360032,
232290x003900b1,
232300x003a00d1,
232310x003b00e6,
232320x003c00fe,
232330x003d016d,
232340x003f00af,
232350x00410338,
232360x0043034b,
232370x00440190,
232380x004500fe,
232390x004601ae,
232400x004701ae,
232410x00480200,
232420x0049020e,
232430x004a0257,
232440x004b0284,
232450x00520261,
232460x00530273,
232470x00540289,
232480x0057029b,
232490x0060029f,
232500x006102ae,
232510x006202b8,
232520x006302c2,
232530x006402cc,
232540x006502d6,
232550x006602e0,
232560x006702ea,
232570x006802f4,
232580x006902f8,
232590x006a02fc,
232600x006b0300,
232610x006c0304,
232620x006d0308,
232630x006e030c,
232640x006f0310,
232650x00700314,
232660x00720365,
232670x0074036b,
232680x00790369,
232690x007c031e,
232700x000f037a,
232710x000f037a,
232720x000f037a,
232730x000f037a,
232740x000f037a,
232750x000f037a,
232760x000f037a,
232770x000f037a,
232780x000f037a,
232790x000f037a,
232800x000f037a,
232810x000f037a,
232820x000f037a,
232830x000f037a,
232840x000f037a,
232850x000f037a,
232860x000f037a,
232870x000f037a,
232880x000f037a,
232890x000f037a,
232900x000f037a,
232910x000f037a,
232920x000f037a,
232930x000f037a,
232940x000f037a,
23295};
23296
23297#endif
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
new file mode 100644
index 000000000000..4a9028a85c9b
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -0,0 +1,662 @@
1/*
2 * Copyright 2009 Advanced Micro Devices, Inc.
3 * Copyright 2009 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 * Jerome Glisse
26 */
27#ifndef R600D_H
28#define R600D_H
29
30#define CP_PACKET2 0x80000000
31#define PACKET2_PAD_SHIFT 0
32#define PACKET2_PAD_MASK (0x3fffffff << 0)
33
34#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
35
36#define R6XX_MAX_SH_GPRS 256
37#define R6XX_MAX_TEMP_GPRS 16
38#define R6XX_MAX_SH_THREADS 256
39#define R6XX_MAX_SH_STACK_ENTRIES 4096
40#define R6XX_MAX_BACKENDS 8
41#define R6XX_MAX_BACKENDS_MASK 0xff
42#define R6XX_MAX_SIMDS 8
43#define R6XX_MAX_SIMDS_MASK 0xff
44#define R6XX_MAX_PIPES 8
45#define R6XX_MAX_PIPES_MASK 0xff
46
47/* PTE flags */
48#define PTE_VALID (1 << 0)
49#define PTE_SYSTEM (1 << 1)
50#define PTE_SNOOPED (1 << 2)
51#define PTE_READABLE (1 << 5)
52#define PTE_WRITEABLE (1 << 6)
53
54/* Registers */
55#define ARB_POP 0x2418
56#define ENABLE_TC128 (1 << 30)
57#define ARB_GDEC_RD_CNTL 0x246C
58
59#define CC_GC_SHADER_PIPE_CONFIG 0x8950
60#define CC_RB_BACKEND_DISABLE 0x98F4
61#define BACKEND_DISABLE(x) ((x) << 16)
62
63#define CB_COLOR0_BASE 0x28040
64#define CB_COLOR1_BASE 0x28044
65#define CB_COLOR2_BASE 0x28048
66#define CB_COLOR3_BASE 0x2804C
67#define CB_COLOR4_BASE 0x28050
68#define CB_COLOR5_BASE 0x28054
69#define CB_COLOR6_BASE 0x28058
70#define CB_COLOR7_BASE 0x2805C
71#define CB_COLOR7_FRAG 0x280FC
72
73#define CB_COLOR0_SIZE 0x28060
74#define CB_COLOR0_VIEW 0x28080
75#define CB_COLOR0_INFO 0x280a0
76#define CB_COLOR0_TILE 0x280c0
77#define CB_COLOR0_FRAG 0x280e0
78#define CB_COLOR0_MASK 0x28100
79
80#define CONFIG_MEMSIZE 0x5428
81#define CONFIG_CNTL 0x5424
82#define CP_STAT 0x8680
83#define CP_COHER_BASE 0x85F8
84#define CP_DEBUG 0xC1FC
85#define R_0086D8_CP_ME_CNTL 0x86D8
86#define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28)
87#define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF)
88#define CP_ME_RAM_DATA 0xC160
89#define CP_ME_RAM_RADDR 0xC158
90#define CP_ME_RAM_WADDR 0xC15C
91#define CP_MEQ_THRESHOLDS 0x8764
92#define MEQ_END(x) ((x) << 16)
93#define ROQ_END(x) ((x) << 24)
94#define CP_PERFMON_CNTL 0x87FC
95#define CP_PFP_UCODE_ADDR 0xC150
96#define CP_PFP_UCODE_DATA 0xC154
97#define CP_QUEUE_THRESHOLDS 0x8760
98#define ROQ_IB1_START(x) ((x) << 0)
99#define ROQ_IB2_START(x) ((x) << 8)
100#define CP_RB_BASE 0xC100
101#define CP_RB_CNTL 0xC104
102#define RB_BUFSZ(x) ((x)<<0)
103#define RB_BLKSZ(x) ((x)<<8)
104#define RB_NO_UPDATE (1<<27)
105#define RB_RPTR_WR_ENA (1<<31)
106#define BUF_SWAP_32BIT (2 << 16)
107#define CP_RB_RPTR 0x8700
108#define CP_RB_RPTR_ADDR 0xC10C
109#define CP_RB_RPTR_ADDR_HI 0xC110
110#define CP_RB_RPTR_WR 0xC108
111#define CP_RB_WPTR 0xC114
112#define CP_RB_WPTR_ADDR 0xC118
113#define CP_RB_WPTR_ADDR_HI 0xC11C
114#define CP_RB_WPTR_DELAY 0x8704
115#define CP_ROQ_IB1_STAT 0x8784
116#define CP_ROQ_IB2_STAT 0x8788
117#define CP_SEM_WAIT_TIMER 0x85BC
118
119#define DB_DEBUG 0x9830
120#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
121#define DB_DEPTH_BASE 0x2800C
122#define DB_WATERMARKS 0x9838
123#define DEPTH_FREE(x) ((x) << 0)
124#define DEPTH_FLUSH(x) ((x) << 5)
125#define DEPTH_PENDING_FREE(x) ((x) << 15)
126#define DEPTH_CACHELINE_FREE(x) ((x) << 20)
127
128#define DCP_TILING_CONFIG 0x6CA0
129#define PIPE_TILING(x) ((x) << 1)
130#define BANK_TILING(x) ((x) << 4)
131#define GROUP_SIZE(x) ((x) << 6)
132#define ROW_TILING(x) ((x) << 8)
133#define BANK_SWAPS(x) ((x) << 11)
134#define SAMPLE_SPLIT(x) ((x) << 14)
135#define BACKEND_MAP(x) ((x) << 16)
136
137#define GB_TILING_CONFIG 0x98F0
138
139#define GC_USER_SHADER_PIPE_CONFIG 0x8954
140#define INACTIVE_QD_PIPES(x) ((x) << 8)
141#define INACTIVE_QD_PIPES_MASK 0x0000FF00
142#define INACTIVE_SIMDS(x) ((x) << 16)
143#define INACTIVE_SIMDS_MASK 0x00FF0000
144
145#define SQ_CONFIG 0x8c00
146# define VC_ENABLE (1 << 0)
147# define EXPORT_SRC_C (1 << 1)
148# define DX9_CONSTS (1 << 2)
149# define ALU_INST_PREFER_VECTOR (1 << 3)
150# define DX10_CLAMP (1 << 4)
151# define CLAUSE_SEQ_PRIO(x) ((x) << 8)
152# define PS_PRIO(x) ((x) << 24)
153# define VS_PRIO(x) ((x) << 26)
154# define GS_PRIO(x) ((x) << 28)
155# define ES_PRIO(x) ((x) << 30)
156#define SQ_GPR_RESOURCE_MGMT_1 0x8c04
157# define NUM_PS_GPRS(x) ((x) << 0)
158# define NUM_VS_GPRS(x) ((x) << 16)
159# define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28)
160#define SQ_GPR_RESOURCE_MGMT_2 0x8c08
161# define NUM_GS_GPRS(x) ((x) << 0)
162# define NUM_ES_GPRS(x) ((x) << 16)
163#define SQ_THREAD_RESOURCE_MGMT 0x8c0c
164# define NUM_PS_THREADS(x) ((x) << 0)
165# define NUM_VS_THREADS(x) ((x) << 8)
166# define NUM_GS_THREADS(x) ((x) << 16)
167# define NUM_ES_THREADS(x) ((x) << 24)
168#define SQ_STACK_RESOURCE_MGMT_1 0x8c10
169# define NUM_PS_STACK_ENTRIES(x) ((x) << 0)
170# define NUM_VS_STACK_ENTRIES(x) ((x) << 16)
171#define SQ_STACK_RESOURCE_MGMT_2 0x8c14
172# define NUM_GS_STACK_ENTRIES(x) ((x) << 0)
173# define NUM_ES_STACK_ENTRIES(x) ((x) << 16)
174
175#define GRBM_CNTL 0x8000
176# define GRBM_READ_TIMEOUT(x) ((x) << 0)
177#define GRBM_STATUS 0x8010
178#define CMDFIFO_AVAIL_MASK 0x0000001F
179#define GUI_ACTIVE (1<<31)
180#define GRBM_STATUS2 0x8014
181#define GRBM_SOFT_RESET 0x8020
182#define SOFT_RESET_CP (1<<0)
183
184#define HDP_HOST_PATH_CNTL 0x2C00
185#define HDP_NONSURFACE_BASE 0x2C04
186#define HDP_NONSURFACE_INFO 0x2C08
187#define HDP_NONSURFACE_SIZE 0x2C0C
188#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
189#define HDP_TILING_CONFIG 0x2F3C
190
191#define MC_VM_AGP_TOP 0x2184
192#define MC_VM_AGP_BOT 0x2188
193#define MC_VM_AGP_BASE 0x218C
194#define MC_VM_FB_LOCATION 0x2180
195#define MC_VM_L1_TLB_MCD_RD_A_CNTL 0x219C
196#define ENABLE_L1_TLB (1 << 0)
197#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1)
198#define ENABLE_L1_STRICT_ORDERING (1 << 2)
199#define SYSTEM_ACCESS_MODE_MASK 0x000000C0
200#define SYSTEM_ACCESS_MODE_SHIFT 6
201#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6)
202#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6)
203#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 6)
204#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6)
205#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8)
206#define SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8)
207#define ENABLE_SEMAPHORE_MODE (1 << 10)
208#define ENABLE_WAIT_L2_QUERY (1 << 11)
209#define EFFECTIVE_L1_TLB_SIZE(x) (((x) & 7) << 12)
210#define EFFECTIVE_L1_TLB_SIZE_MASK 0x00007000
211#define EFFECTIVE_L1_TLB_SIZE_SHIFT 12
212#define EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 7) << 15)
213#define EFFECTIVE_L1_QUEUE_SIZE_MASK 0x00038000
214#define EFFECTIVE_L1_QUEUE_SIZE_SHIFT 15
215#define MC_VM_L1_TLB_MCD_RD_B_CNTL 0x21A0
216#define MC_VM_L1_TLB_MCB_RD_GFX_CNTL 0x21FC
217#define MC_VM_L1_TLB_MCB_RD_HDP_CNTL 0x2204
218#define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL 0x2208
219#define MC_VM_L1_TLB_MCB_RD_SEM_CNTL 0x220C
220#define MC_VM_L1_TLB_MCB_RD_SYS_CNTL 0x2200
221#define MC_VM_L1_TLB_MCD_WR_A_CNTL 0x21A4
222#define MC_VM_L1_TLB_MCD_WR_B_CNTL 0x21A8
223#define MC_VM_L1_TLB_MCB_WR_GFX_CNTL 0x2210
224#define MC_VM_L1_TLB_MCB_WR_HDP_CNTL 0x2218
225#define MC_VM_L1_TLB_MCB_WR_PDMA_CNTL 0x221C
226#define MC_VM_L1_TLB_MCB_WR_SEM_CNTL 0x2220
227#define MC_VM_L1_TLB_MCB_WR_SYS_CNTL 0x2214
228#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190
229#define LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF
230#define LOGICAL_PAGE_NUMBER_SHIFT 0
231#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194
232#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198
233
234#define PA_CL_ENHANCE 0x8A14
235#define CLIP_VTX_REORDER_ENA (1 << 0)
236#define NUM_CLIP_SEQ(x) ((x) << 1)
237#define PA_SC_AA_CONFIG 0x28C04
238#define PA_SC_AA_SAMPLE_LOCS_2S 0x8B40
239#define PA_SC_AA_SAMPLE_LOCS_4S 0x8B44
240#define PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8B48
241#define PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8B4C
242#define S0_X(x) ((x) << 0)
243#define S0_Y(x) ((x) << 4)
244#define S1_X(x) ((x) << 8)
245#define S1_Y(x) ((x) << 12)
246#define S2_X(x) ((x) << 16)
247#define S2_Y(x) ((x) << 20)
248#define S3_X(x) ((x) << 24)
249#define S3_Y(x) ((x) << 28)
250#define S4_X(x) ((x) << 0)
251#define S4_Y(x) ((x) << 4)
252#define S5_X(x) ((x) << 8)
253#define S5_Y(x) ((x) << 12)
254#define S6_X(x) ((x) << 16)
255#define S6_Y(x) ((x) << 20)
256#define S7_X(x) ((x) << 24)
257#define S7_Y(x) ((x) << 28)
258#define PA_SC_CLIPRECT_RULE 0x2820c
259#define PA_SC_ENHANCE 0x8BF0
260#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0)
261#define FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12)
262#define PA_SC_LINE_STIPPLE 0x28A0C
263#define PA_SC_LINE_STIPPLE_STATE 0x8B10
264#define PA_SC_MODE_CNTL 0x28A4C
265#define PA_SC_MULTI_CHIP_CNTL 0x8B20
266
267#define PA_SC_SCREEN_SCISSOR_TL 0x28030
268#define PA_SC_GENERIC_SCISSOR_TL 0x28240
269#define PA_SC_WINDOW_SCISSOR_TL 0x28204
270
271#define PCIE_PORT_INDEX 0x0038
272#define PCIE_PORT_DATA 0x003C
273
274#define RAMCFG 0x2408
275#define NOOFBANK_SHIFT 0
276#define NOOFBANK_MASK 0x00000001
277#define NOOFRANK_SHIFT 1
278#define NOOFRANK_MASK 0x00000002
279#define NOOFROWS_SHIFT 2
280#define NOOFROWS_MASK 0x0000001C
281#define NOOFCOLS_SHIFT 5
282#define NOOFCOLS_MASK 0x00000060
283#define CHANSIZE_SHIFT 7
284#define CHANSIZE_MASK 0x00000080
285#define BURSTLENGTH_SHIFT 8
286#define BURSTLENGTH_MASK 0x00000100
287#define CHANSIZE_OVERRIDE (1 << 10)
288
289#define SCRATCH_REG0 0x8500
290#define SCRATCH_REG1 0x8504
291#define SCRATCH_REG2 0x8508
292#define SCRATCH_REG3 0x850C
293#define SCRATCH_REG4 0x8510
294#define SCRATCH_REG5 0x8514
295#define SCRATCH_REG6 0x8518
296#define SCRATCH_REG7 0x851C
297#define SCRATCH_UMSK 0x8540
298#define SCRATCH_ADDR 0x8544
299
300#define SPI_CONFIG_CNTL 0x9100
301#define GPR_WRITE_PRIORITY(x) ((x) << 0)
302#define DISABLE_INTERP_1 (1 << 5)
303#define SPI_CONFIG_CNTL_1 0x913C
304#define VTX_DONE_DELAY(x) ((x) << 0)
305#define INTERP_ONE_PRIM_PER_ROW (1 << 4)
306#define SPI_INPUT_Z 0x286D8
307#define SPI_PS_IN_CONTROL_0 0x286CC
308#define NUM_INTERP(x) ((x)<<0)
309#define POSITION_ENA (1<<8)
310#define POSITION_CENTROID (1<<9)
311#define POSITION_ADDR(x) ((x)<<10)
312#define PARAM_GEN(x) ((x)<<15)
313#define PARAM_GEN_ADDR(x) ((x)<<19)
314#define BARYC_SAMPLE_CNTL(x) ((x)<<26)
315#define PERSP_GRADIENT_ENA (1<<28)
316#define LINEAR_GRADIENT_ENA (1<<29)
317#define POSITION_SAMPLE (1<<30)
318#define BARYC_AT_SAMPLE_ENA (1<<31)
319#define SPI_PS_IN_CONTROL_1 0x286D0
320#define GEN_INDEX_PIX (1<<0)
321#define GEN_INDEX_PIX_ADDR(x) ((x)<<1)
322#define FRONT_FACE_ENA (1<<8)
323#define FRONT_FACE_CHAN(x) ((x)<<9)
324#define FRONT_FACE_ALL_BITS (1<<11)
325#define FRONT_FACE_ADDR(x) ((x)<<12)
326#define FOG_ADDR(x) ((x)<<17)
327#define FIXED_PT_POSITION_ENA (1<<24)
328#define FIXED_PT_POSITION_ADDR(x) ((x)<<25)
329
330#define SQ_MS_FIFO_SIZES 0x8CF0
331#define CACHE_FIFO_SIZE(x) ((x) << 0)
332#define FETCH_FIFO_HIWATER(x) ((x) << 8)
333#define DONE_FIFO_HIWATER(x) ((x) << 16)
334#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24)
335#define SQ_PGM_START_ES 0x28880
336#define SQ_PGM_START_FS 0x28894
337#define SQ_PGM_START_GS 0x2886C
338#define SQ_PGM_START_PS 0x28840
339#define SQ_PGM_RESOURCES_PS 0x28850
340#define SQ_PGM_EXPORTS_PS 0x28854
341#define SQ_PGM_CF_OFFSET_PS 0x288cc
342#define SQ_PGM_START_VS 0x28858
343#define SQ_PGM_RESOURCES_VS 0x28868
344#define SQ_PGM_CF_OFFSET_VS 0x288d0
345#define SQ_VTX_CONSTANT_WORD6_0 0x38018
346#define S__SQ_VTX_CONSTANT_TYPE(x) (((x) & 3) << 30)
347#define G__SQ_VTX_CONSTANT_TYPE(x) (((x) >> 30) & 3)
348#define SQ_TEX_VTX_INVALID_TEXTURE 0x0
349#define SQ_TEX_VTX_INVALID_BUFFER 0x1
350#define SQ_TEX_VTX_VALID_TEXTURE 0x2
351#define SQ_TEX_VTX_VALID_BUFFER 0x3
352
353
354#define SX_MISC 0x28350
355#define SX_DEBUG_1 0x9054
356#define SMX_EVENT_RELEASE (1 << 0)
357#define ENABLE_NEW_SMX_ADDRESS (1 << 16)
358
359#define TA_CNTL_AUX 0x9508
360#define DISABLE_CUBE_WRAP (1 << 0)
361#define DISABLE_CUBE_ANISO (1 << 1)
362#define SYNC_GRADIENT (1 << 24)
363#define SYNC_WALKER (1 << 25)
364#define SYNC_ALIGNER (1 << 26)
365#define BILINEAR_PRECISION_6_BIT (0 << 31)
366#define BILINEAR_PRECISION_8_BIT (1 << 31)
367
368#define TC_CNTL 0x9608
369#define TC_L2_SIZE(x) ((x)<<5)
370#define L2_DISABLE_LATE_HIT (1<<9)
371
372
373#define VGT_CACHE_INVALIDATION 0x88C4
374#define CACHE_INVALIDATION(x) ((x)<<0)
375#define VC_ONLY 0
376#define TC_ONLY 1
377#define VC_AND_TC 2
378#define VGT_DMA_BASE 0x287E8
379#define VGT_DMA_BASE_HI 0x287E4
380#define VGT_ES_PER_GS 0x88CC
381#define VGT_GS_PER_ES 0x88C8
382#define VGT_GS_PER_VS 0x88E8
383#define VGT_GS_VERTEX_REUSE 0x88D4
384#define VGT_PRIMITIVE_TYPE 0x8958
385#define VGT_NUM_INSTANCES 0x8974
386#define VGT_OUT_DEALLOC_CNTL 0x28C5C
387#define DEALLOC_DIST_MASK 0x0000007F
388#define VGT_STRMOUT_BASE_OFFSET_0 0x28B10
389#define VGT_STRMOUT_BASE_OFFSET_1 0x28B14
390#define VGT_STRMOUT_BASE_OFFSET_2 0x28B18
391#define VGT_STRMOUT_BASE_OFFSET_3 0x28B1c
392#define VGT_STRMOUT_BASE_OFFSET_HI_0 0x28B44
393#define VGT_STRMOUT_BASE_OFFSET_HI_1 0x28B48
394#define VGT_STRMOUT_BASE_OFFSET_HI_2 0x28B4c
395#define VGT_STRMOUT_BASE_OFFSET_HI_3 0x28B50
396#define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8
397#define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8
398#define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8
399#define VGT_STRMOUT_BUFFER_BASE_3 0x28B08
400#define VGT_STRMOUT_BUFFER_OFFSET_0 0x28ADC
401#define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC
402#define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC
403#define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C
404#define VGT_STRMOUT_EN 0x28AB0
405#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58
406#define VTX_REUSE_DEPTH_MASK 0x000000FF
407#define VGT_EVENT_INITIATOR 0x28a90
408# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0)
409
410#define VM_CONTEXT0_CNTL 0x1410
411#define ENABLE_CONTEXT (1 << 0)
412#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1)
413#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
414#define VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490
415#define VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14B0
416#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574
417#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594
418#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15B4
419#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1554
420#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470
421#define REQUEST_TYPE(x) (((x) & 0xf) << 0)
422#define RESPONSE_TYPE_MASK 0x000000F0
423#define RESPONSE_TYPE_SHIFT 4
424#define VM_L2_CNTL 0x1400
425#define ENABLE_L2_CACHE (1 << 0)
426#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1)
427#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9)
428#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 13)
429#define VM_L2_CNTL2 0x1404
430#define INVALIDATE_ALL_L1_TLBS (1 << 0)
431#define INVALIDATE_L2_CACHE (1 << 1)
432#define VM_L2_CNTL3 0x1408
433#define BANK_SELECT_0(x) (((x) & 0x1f) << 0)
434#define BANK_SELECT_1(x) (((x) & 0x1f) << 5)
435#define L2_CACHE_UPDATE_MODE(x) (((x) & 3) << 10)
436#define VM_L2_STATUS 0x140C
437#define L2_BUSY (1 << 0)
438
439#define WAIT_UNTIL 0x8040
440#define WAIT_2D_IDLE_bit (1 << 14)
441#define WAIT_3D_IDLE_bit (1 << 15)
442#define WAIT_2D_IDLECLEAN_bit (1 << 16)
443#define WAIT_3D_IDLECLEAN_bit (1 << 17)
444
445
446
447/*
448 * PM4
449 */
450#define PACKET_TYPE0 0
451#define PACKET_TYPE1 1
452#define PACKET_TYPE2 2
453#define PACKET_TYPE3 3
454
455#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
456#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
457#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2)
458#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
459#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \
460 (((reg) >> 2) & 0xFFFF) | \
461 ((n) & 0x3FFF) << 16)
462#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \
463 (((op) & 0xFF) << 8) | \
464 ((n) & 0x3FFF) << 16)
465
466/* Packet 3 types */
467#define PACKET3_NOP 0x10
468#define PACKET3_INDIRECT_BUFFER_END 0x17
469#define PACKET3_SET_PREDICATION 0x20
470#define PACKET3_REG_RMW 0x21
471#define PACKET3_COND_EXEC 0x22
472#define PACKET3_PRED_EXEC 0x23
473#define PACKET3_START_3D_CMDBUF 0x24
474#define PACKET3_DRAW_INDEX_2 0x27
475#define PACKET3_CONTEXT_CONTROL 0x28
476#define PACKET3_DRAW_INDEX_IMMD_BE 0x29
477#define PACKET3_INDEX_TYPE 0x2A
478#define PACKET3_DRAW_INDEX 0x2B
479#define PACKET3_DRAW_INDEX_AUTO 0x2D
480#define PACKET3_DRAW_INDEX_IMMD 0x2E
481#define PACKET3_NUM_INSTANCES 0x2F
482#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34
483#define PACKET3_INDIRECT_BUFFER_MP 0x38
484#define PACKET3_MEM_SEMAPHORE 0x39
485#define PACKET3_MPEG_INDEX 0x3A
486#define PACKET3_WAIT_REG_MEM 0x3C
487#define PACKET3_MEM_WRITE 0x3D
488#define PACKET3_INDIRECT_BUFFER 0x32
489#define PACKET3_CP_INTERRUPT 0x40
490#define PACKET3_SURFACE_SYNC 0x43
491# define PACKET3_CB0_DEST_BASE_ENA (1 << 6)
492# define PACKET3_TC_ACTION_ENA (1 << 23)
493# define PACKET3_VC_ACTION_ENA (1 << 24)
494# define PACKET3_CB_ACTION_ENA (1 << 25)
495# define PACKET3_DB_ACTION_ENA (1 << 26)
496# define PACKET3_SH_ACTION_ENA (1 << 27)
497# define PACKET3_SMX_ACTION_ENA (1 << 28)
498#define PACKET3_ME_INITIALIZE 0x44
499#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
500#define PACKET3_COND_WRITE 0x45
501#define PACKET3_EVENT_WRITE 0x46
502#define PACKET3_EVENT_WRITE_EOP 0x47
503#define PACKET3_ONE_REG_WRITE 0x57
504#define PACKET3_SET_CONFIG_REG 0x68
505#define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000
506#define PACKET3_SET_CONFIG_REG_END 0x0000ac00
507#define PACKET3_SET_CONTEXT_REG 0x69
508#define PACKET3_SET_CONTEXT_REG_OFFSET 0x00028000
509#define PACKET3_SET_CONTEXT_REG_END 0x00029000
510#define PACKET3_SET_ALU_CONST 0x6A
511#define PACKET3_SET_ALU_CONST_OFFSET 0x00030000
512#define PACKET3_SET_ALU_CONST_END 0x00032000
513#define PACKET3_SET_BOOL_CONST 0x6B
514#define PACKET3_SET_BOOL_CONST_OFFSET 0x0003e380
515#define PACKET3_SET_BOOL_CONST_END 0x00040000
516#define PACKET3_SET_LOOP_CONST 0x6C
517#define PACKET3_SET_LOOP_CONST_OFFSET 0x0003e200
518#define PACKET3_SET_LOOP_CONST_END 0x0003e380
519#define PACKET3_SET_RESOURCE 0x6D
520#define PACKET3_SET_RESOURCE_OFFSET 0x00038000
521#define PACKET3_SET_RESOURCE_END 0x0003c000
522#define PACKET3_SET_SAMPLER 0x6E
523#define PACKET3_SET_SAMPLER_OFFSET 0x0003c000
524#define PACKET3_SET_SAMPLER_END 0x0003cff0
525#define PACKET3_SET_CTL_CONST 0x6F
526#define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0
527#define PACKET3_SET_CTL_CONST_END 0x0003e200
528#define PACKET3_SURFACE_BASE_UPDATE 0x73
529
530
531#define R_008020_GRBM_SOFT_RESET 0x8020
532#define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0)
533#define S_008020_SOFT_RESET_CB(x) (((x) & 1) << 1)
534#define S_008020_SOFT_RESET_CR(x) (((x) & 1) << 2)
535#define S_008020_SOFT_RESET_DB(x) (((x) & 1) << 3)
536#define S_008020_SOFT_RESET_PA(x) (((x) & 1) << 5)
537#define S_008020_SOFT_RESET_SC(x) (((x) & 1) << 6)
538#define S_008020_SOFT_RESET_SMX(x) (((x) & 1) << 7)
539#define S_008020_SOFT_RESET_SPI(x) (((x) & 1) << 8)
540#define S_008020_SOFT_RESET_SH(x) (((x) & 1) << 9)
541#define S_008020_SOFT_RESET_SX(x) (((x) & 1) << 10)
542#define S_008020_SOFT_RESET_TC(x) (((x) & 1) << 11)
543#define S_008020_SOFT_RESET_TA(x) (((x) & 1) << 12)
544#define S_008020_SOFT_RESET_VC(x) (((x) & 1) << 13)
545#define S_008020_SOFT_RESET_VGT(x) (((x) & 1) << 14)
546#define R_008010_GRBM_STATUS 0x8010
547#define S_008010_CMDFIFO_AVAIL(x) (((x) & 0x1F) << 0)
548#define S_008010_CP_RQ_PENDING(x) (((x) & 1) << 6)
549#define S_008010_CF_RQ_PENDING(x) (((x) & 1) << 7)
550#define S_008010_PF_RQ_PENDING(x) (((x) & 1) << 8)
551#define S_008010_GRBM_EE_BUSY(x) (((x) & 1) << 10)
552#define S_008010_VC_BUSY(x) (((x) & 1) << 11)
553#define S_008010_DB03_CLEAN(x) (((x) & 1) << 12)
554#define S_008010_CB03_CLEAN(x) (((x) & 1) << 13)
555#define S_008010_VGT_BUSY_NO_DMA(x) (((x) & 1) << 16)
556#define S_008010_VGT_BUSY(x) (((x) & 1) << 17)
557#define S_008010_TA03_BUSY(x) (((x) & 1) << 18)
558#define S_008010_TC_BUSY(x) (((x) & 1) << 19)
559#define S_008010_SX_BUSY(x) (((x) & 1) << 20)
560#define S_008010_SH_BUSY(x) (((x) & 1) << 21)
561#define S_008010_SPI03_BUSY(x) (((x) & 1) << 22)
562#define S_008010_SMX_BUSY(x) (((x) & 1) << 23)
563#define S_008010_SC_BUSY(x) (((x) & 1) << 24)
564#define S_008010_PA_BUSY(x) (((x) & 1) << 25)
565#define S_008010_DB03_BUSY(x) (((x) & 1) << 26)
566#define S_008010_CR_BUSY(x) (((x) & 1) << 27)
567#define S_008010_CP_COHERENCY_BUSY(x) (((x) & 1) << 28)
568#define S_008010_CP_BUSY(x) (((x) & 1) << 29)
569#define S_008010_CB03_BUSY(x) (((x) & 1) << 30)
570#define S_008010_GUI_ACTIVE(x) (((x) & 1) << 31)
571#define G_008010_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x1F)
572#define G_008010_CP_RQ_PENDING(x) (((x) >> 6) & 1)
573#define G_008010_CF_RQ_PENDING(x) (((x) >> 7) & 1)
574#define G_008010_PF_RQ_PENDING(x) (((x) >> 8) & 1)
575#define G_008010_GRBM_EE_BUSY(x) (((x) >> 10) & 1)
576#define G_008010_VC_BUSY(x) (((x) >> 11) & 1)
577#define G_008010_DB03_CLEAN(x) (((x) >> 12) & 1)
578#define G_008010_CB03_CLEAN(x) (((x) >> 13) & 1)
579#define G_008010_VGT_BUSY_NO_DMA(x) (((x) >> 16) & 1)
580#define G_008010_VGT_BUSY(x) (((x) >> 17) & 1)
581#define G_008010_TA03_BUSY(x) (((x) >> 18) & 1)
582#define G_008010_TC_BUSY(x) (((x) >> 19) & 1)
583#define G_008010_SX_BUSY(x) (((x) >> 20) & 1)
584#define G_008010_SH_BUSY(x) (((x) >> 21) & 1)
585#define G_008010_SPI03_BUSY(x) (((x) >> 22) & 1)
586#define G_008010_SMX_BUSY(x) (((x) >> 23) & 1)
587#define G_008010_SC_BUSY(x) (((x) >> 24) & 1)
588#define G_008010_PA_BUSY(x) (((x) >> 25) & 1)
589#define G_008010_DB03_BUSY(x) (((x) >> 26) & 1)
590#define G_008010_CR_BUSY(x) (((x) >> 27) & 1)
591#define G_008010_CP_COHERENCY_BUSY(x) (((x) >> 28) & 1)
592#define G_008010_CP_BUSY(x) (((x) >> 29) & 1)
593#define G_008010_CB03_BUSY(x) (((x) >> 30) & 1)
594#define G_008010_GUI_ACTIVE(x) (((x) >> 31) & 1)
595#define R_008014_GRBM_STATUS2 0x8014
596#define S_008014_CR_CLEAN(x) (((x) & 1) << 0)
597#define S_008014_SMX_CLEAN(x) (((x) & 1) << 1)
598#define S_008014_SPI0_BUSY(x) (((x) & 1) << 8)
599#define S_008014_SPI1_BUSY(x) (((x) & 1) << 9)
600#define S_008014_SPI2_BUSY(x) (((x) & 1) << 10)
601#define S_008014_SPI3_BUSY(x) (((x) & 1) << 11)
602#define S_008014_TA0_BUSY(x) (((x) & 1) << 12)
603#define S_008014_TA1_BUSY(x) (((x) & 1) << 13)
604#define S_008014_TA2_BUSY(x) (((x) & 1) << 14)
605#define S_008014_TA3_BUSY(x) (((x) & 1) << 15)
606#define S_008014_DB0_BUSY(x) (((x) & 1) << 16)
607#define S_008014_DB1_BUSY(x) (((x) & 1) << 17)
608#define S_008014_DB2_BUSY(x) (((x) & 1) << 18)
609#define S_008014_DB3_BUSY(x) (((x) & 1) << 19)
610#define S_008014_CB0_BUSY(x) (((x) & 1) << 20)
611#define S_008014_CB1_BUSY(x) (((x) & 1) << 21)
612#define S_008014_CB2_BUSY(x) (((x) & 1) << 22)
613#define S_008014_CB3_BUSY(x) (((x) & 1) << 23)
614#define G_008014_CR_CLEAN(x) (((x) >> 0) & 1)
615#define G_008014_SMX_CLEAN(x) (((x) >> 1) & 1)
616#define G_008014_SPI0_BUSY(x) (((x) >> 8) & 1)
617#define G_008014_SPI1_BUSY(x) (((x) >> 9) & 1)
618#define G_008014_SPI2_BUSY(x) (((x) >> 10) & 1)
619#define G_008014_SPI3_BUSY(x) (((x) >> 11) & 1)
620#define G_008014_TA0_BUSY(x) (((x) >> 12) & 1)
621#define G_008014_TA1_BUSY(x) (((x) >> 13) & 1)
622#define G_008014_TA2_BUSY(x) (((x) >> 14) & 1)
623#define G_008014_TA3_BUSY(x) (((x) >> 15) & 1)
624#define G_008014_DB0_BUSY(x) (((x) >> 16) & 1)
625#define G_008014_DB1_BUSY(x) (((x) >> 17) & 1)
626#define G_008014_DB2_BUSY(x) (((x) >> 18) & 1)
627#define G_008014_DB3_BUSY(x) (((x) >> 19) & 1)
628#define G_008014_CB0_BUSY(x) (((x) >> 20) & 1)
629#define G_008014_CB1_BUSY(x) (((x) >> 21) & 1)
630#define G_008014_CB2_BUSY(x) (((x) >> 22) & 1)
631#define G_008014_CB3_BUSY(x) (((x) >> 23) & 1)
632#define R_000E50_SRBM_STATUS 0x0E50
633#define G_000E50_RLC_RQ_PENDING(x) (((x) >> 3) & 1)
634#define G_000E50_RCU_RQ_PENDING(x) (((x) >> 4) & 1)
635#define G_000E50_GRBM_RQ_PENDING(x) (((x) >> 5) & 1)
636#define G_000E50_HI_RQ_PENDING(x) (((x) >> 6) & 1)
637#define G_000E50_IO_EXTERN_SIGNAL(x) (((x) >> 7) & 1)
638#define G_000E50_VMC_BUSY(x) (((x) >> 8) & 1)
639#define G_000E50_MCB_BUSY(x) (((x) >> 9) & 1)
640#define G_000E50_MCDZ_BUSY(x) (((x) >> 10) & 1)
641#define G_000E50_MCDY_BUSY(x) (((x) >> 11) & 1)
642#define G_000E50_MCDX_BUSY(x) (((x) >> 12) & 1)
643#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1)
644#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1)
645#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1)
646#define R_000E60_SRBM_SOFT_RESET 0x0E60
647#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1)
648#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2)
649#define S_000E60_SOFT_RESET_CMC(x) (((x) & 1) << 3)
650#define S_000E60_SOFT_RESET_CSC(x) (((x) & 1) << 4)
651#define S_000E60_SOFT_RESET_DC(x) (((x) & 1) << 5)
652#define S_000E60_SOFT_RESET_GRBM(x) (((x) & 1) << 8)
653#define S_000E60_SOFT_RESET_HDP(x) (((x) & 1) << 9)
654#define S_000E60_SOFT_RESET_IH(x) (((x) & 1) << 10)
655#define S_000E60_SOFT_RESET_MC(x) (((x) & 1) << 11)
656#define S_000E60_SOFT_RESET_RLC(x) (((x) & 1) << 13)
657#define S_000E60_SOFT_RESET_ROM(x) (((x) & 1) << 14)
658#define S_000E60_SOFT_RESET_SEM(x) (((x) & 1) << 15)
659#define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16)
660#define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17)
661
662#endif
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b519fb2fecbb..c839b608970f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -51,7 +51,6 @@
51 51
52#include "radeon_mode.h" 52#include "radeon_mode.h"
53#include "radeon_reg.h" 53#include "radeon_reg.h"
54#include "r300.h"
55 54
56/* 55/*
57 * Modules parameters. 56 * Modules parameters.
@@ -66,6 +65,7 @@ extern int radeon_gart_size;
66extern int radeon_benchmarking; 65extern int radeon_benchmarking;
67extern int radeon_testing; 66extern int radeon_testing;
68extern int radeon_connector_table; 67extern int radeon_connector_table;
68extern int radeon_tv;
69 69
70/* 70/*
71 * Copy from radeon_drv.h so we don't have to include both and have conflicting 71 * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -75,6 +75,7 @@ extern int radeon_connector_table;
75#define RADEON_IB_POOL_SIZE 16 75#define RADEON_IB_POOL_SIZE 16
76#define RADEON_DEBUGFS_MAX_NUM_FILES 32 76#define RADEON_DEBUGFS_MAX_NUM_FILES 32
77#define RADEONFB_CONN_LIMIT 4 77#define RADEONFB_CONN_LIMIT 4
78#define RADEON_BIOS_NUM_SCRATCH 8
78 79
79enum radeon_family { 80enum radeon_family {
80 CHIP_R100, 81 CHIP_R100,
@@ -107,14 +108,15 @@ enum radeon_family {
107 CHIP_R600, 108 CHIP_R600,
108 CHIP_RV610, 109 CHIP_RV610,
109 CHIP_RV630, 110 CHIP_RV630,
111 CHIP_RV670,
110 CHIP_RV620, 112 CHIP_RV620,
111 CHIP_RV635, 113 CHIP_RV635,
112 CHIP_RV670,
113 CHIP_RS780, 114 CHIP_RS780,
115 CHIP_RS880,
114 CHIP_RV770, 116 CHIP_RV770,
115 CHIP_RV730, 117 CHIP_RV730,
116 CHIP_RV710, 118 CHIP_RV710,
117 CHIP_RS880, 119 CHIP_RV740,
118 CHIP_LAST, 120 CHIP_LAST,
119}; 121};
120 122
@@ -151,10 +153,21 @@ struct radeon_device;
151 */ 153 */
152bool radeon_get_bios(struct radeon_device *rdev); 154bool radeon_get_bios(struct radeon_device *rdev);
153 155
156
154/* 157/*
155 * Clocks 158 * Dummy page
156 */ 159 */
160struct radeon_dummy_page {
161 struct page *page;
162 dma_addr_t addr;
163};
164int radeon_dummy_page_init(struct radeon_device *rdev);
165void radeon_dummy_page_fini(struct radeon_device *rdev);
166
157 167
168/*
169 * Clocks
170 */
158struct radeon_clock { 171struct radeon_clock {
159 struct radeon_pll p1pll; 172 struct radeon_pll p1pll;
160 struct radeon_pll p2pll; 173 struct radeon_pll p2pll;
@@ -165,6 +178,7 @@ struct radeon_clock {
165 uint32_t default_sclk; 178 uint32_t default_sclk;
166}; 179};
167 180
181
168/* 182/*
169 * Fences. 183 * Fences.
170 */ 184 */
@@ -331,14 +345,18 @@ struct radeon_mc {
331 resource_size_t aper_size; 345 resource_size_t aper_size;
332 resource_size_t aper_base; 346 resource_size_t aper_base;
333 resource_size_t agp_base; 347 resource_size_t agp_base;
334 unsigned gtt_location;
335 unsigned gtt_size;
336 unsigned vram_location;
337 /* for some chips with <= 32MB we need to lie 348 /* for some chips with <= 32MB we need to lie
338 * about vram size near mc fb location */ 349 * about vram size near mc fb location */
339 unsigned mc_vram_size; 350 u64 mc_vram_size;
351 u64 gtt_location;
352 u64 gtt_size;
353 u64 gtt_start;
354 u64 gtt_end;
355 u64 vram_location;
356 u64 vram_start;
357 u64 vram_end;
340 unsigned vram_width; 358 unsigned vram_width;
341 unsigned real_vram_size; 359 u64 real_vram_size;
342 int vram_mtrr; 360 int vram_mtrr;
343 bool vram_is_ddr; 361 bool vram_is_ddr;
344}; 362};
@@ -385,6 +403,10 @@ struct radeon_ib {
385 uint32_t length_dw; 403 uint32_t length_dw;
386}; 404};
387 405
406/*
407 * locking -
408 * mutex protects scheduled_ibs, ready, alloc_bm
409 */
388struct radeon_ib_pool { 410struct radeon_ib_pool {
389 struct mutex mutex; 411 struct mutex mutex;
390 struct radeon_object *robj; 412 struct radeon_object *robj;
@@ -410,6 +432,16 @@ struct radeon_cp {
410 bool ready; 432 bool ready;
411}; 433};
412 434
435struct r600_blit {
436 struct radeon_object *shader_obj;
437 u64 shader_gpu_addr;
438 u32 vs_offset, ps_offset;
439 u32 state_offset;
440 u32 state_len;
441 u32 vb_used, vb_total;
442 struct radeon_ib *vb_ib;
443};
444
413int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib); 445int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib);
414void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); 446void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
415int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); 447int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
@@ -462,6 +494,7 @@ struct radeon_cs_parser {
462 int chunk_relocs_idx; 494 int chunk_relocs_idx;
463 struct radeon_ib *ib; 495 struct radeon_ib *ib;
464 void *track; 496 void *track;
497 unsigned family;
465}; 498};
466 499
467struct radeon_cs_packet { 500struct radeon_cs_packet {
@@ -558,13 +591,19 @@ int r100_debugfs_cp_init(struct radeon_device *rdev);
558 */ 591 */
559struct radeon_asic { 592struct radeon_asic {
560 int (*init)(struct radeon_device *rdev); 593 int (*init)(struct radeon_device *rdev);
594 void (*fini)(struct radeon_device *rdev);
595 int (*resume)(struct radeon_device *rdev);
596 int (*suspend)(struct radeon_device *rdev);
561 void (*errata)(struct radeon_device *rdev); 597 void (*errata)(struct radeon_device *rdev);
562 void (*vram_info)(struct radeon_device *rdev); 598 void (*vram_info)(struct radeon_device *rdev);
599 void (*vga_set_state)(struct radeon_device *rdev, bool state);
563 int (*gpu_reset)(struct radeon_device *rdev); 600 int (*gpu_reset)(struct radeon_device *rdev);
564 int (*mc_init)(struct radeon_device *rdev); 601 int (*mc_init)(struct radeon_device *rdev);
565 void (*mc_fini)(struct radeon_device *rdev); 602 void (*mc_fini)(struct radeon_device *rdev);
566 int (*wb_init)(struct radeon_device *rdev); 603 int (*wb_init)(struct radeon_device *rdev);
567 void (*wb_fini)(struct radeon_device *rdev); 604 void (*wb_fini)(struct radeon_device *rdev);
605 int (*gart_init)(struct radeon_device *rdev);
606 void (*gart_fini)(struct radeon_device *rdev);
568 int (*gart_enable)(struct radeon_device *rdev); 607 int (*gart_enable)(struct radeon_device *rdev);
569 void (*gart_disable)(struct radeon_device *rdev); 608 void (*gart_disable)(struct radeon_device *rdev);
570 void (*gart_tlb_flush)(struct radeon_device *rdev); 609 void (*gart_tlb_flush)(struct radeon_device *rdev);
@@ -572,7 +611,11 @@ struct radeon_asic {
572 int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); 611 int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
573 void (*cp_fini)(struct radeon_device *rdev); 612 void (*cp_fini)(struct radeon_device *rdev);
574 void (*cp_disable)(struct radeon_device *rdev); 613 void (*cp_disable)(struct radeon_device *rdev);
614 void (*cp_commit)(struct radeon_device *rdev);
575 void (*ring_start)(struct radeon_device *rdev); 615 void (*ring_start)(struct radeon_device *rdev);
616 int (*ring_test)(struct radeon_device *rdev);
617 void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
618 int (*ib_test)(struct radeon_device *rdev);
576 int (*irq_set)(struct radeon_device *rdev); 619 int (*irq_set)(struct radeon_device *rdev);
577 int (*irq_process)(struct radeon_device *rdev); 620 int (*irq_process)(struct radeon_device *rdev);
578 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); 621 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@ -604,8 +647,60 @@ struct radeon_asic {
604 void (*bandwidth_update)(struct radeon_device *rdev); 647 void (*bandwidth_update)(struct radeon_device *rdev);
605}; 648};
606 649
650/*
651 * Asic structures
652 */
653struct r100_asic {
654 const unsigned *reg_safe_bm;
655 unsigned reg_safe_bm_size;
656};
657
658struct r300_asic {
659 const unsigned *reg_safe_bm;
660 unsigned reg_safe_bm_size;
661};
662
663struct r600_asic {
664 unsigned max_pipes;
665 unsigned max_tile_pipes;
666 unsigned max_simds;
667 unsigned max_backends;
668 unsigned max_gprs;
669 unsigned max_threads;
670 unsigned max_stack_entries;
671 unsigned max_hw_contexts;
672 unsigned max_gs_threads;
673 unsigned sx_max_export_size;
674 unsigned sx_max_export_pos_size;
675 unsigned sx_max_export_smx_size;
676 unsigned sq_num_cf_insts;
677};
678
679struct rv770_asic {
680 unsigned max_pipes;
681 unsigned max_tile_pipes;
682 unsigned max_simds;
683 unsigned max_backends;
684 unsigned max_gprs;
685 unsigned max_threads;
686 unsigned max_stack_entries;
687 unsigned max_hw_contexts;
688 unsigned max_gs_threads;
689 unsigned sx_max_export_size;
690 unsigned sx_max_export_pos_size;
691 unsigned sx_max_export_smx_size;
692 unsigned sq_num_cf_insts;
693 unsigned sx_num_of_sets;
694 unsigned sc_prim_fifo_size;
695 unsigned sc_hiz_tile_fifo_size;
696 unsigned sc_earlyz_tile_fifo_fize;
697};
698
607union radeon_asic_config { 699union radeon_asic_config {
608 struct r300_asic r300; 700 struct r300_asic r300;
701 struct r100_asic r100;
702 struct r600_asic r600;
703 struct rv770_asic rv770;
609}; 704};
610 705
611 706
@@ -646,6 +741,7 @@ typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t);
646typedef void (*radeon_wreg_t)(struct radeon_device*, uint32_t, uint32_t); 741typedef void (*radeon_wreg_t)(struct radeon_device*, uint32_t, uint32_t);
647 742
648struct radeon_device { 743struct radeon_device {
744 struct device *dev;
649 struct drm_device *ddev; 745 struct drm_device *ddev;
650 struct pci_dev *pdev; 746 struct pci_dev *pdev;
651 /* ASIC */ 747 /* ASIC */
@@ -689,13 +785,20 @@ struct radeon_device {
689 struct radeon_asic *asic; 785 struct radeon_asic *asic;
690 struct radeon_gem gem; 786 struct radeon_gem gem;
691 struct radeon_pm pm; 787 struct radeon_pm pm;
788 uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH];
692 struct mutex cs_mutex; 789 struct mutex cs_mutex;
693 struct radeon_wb wb; 790 struct radeon_wb wb;
791 struct radeon_dummy_page dummy_page;
694 bool gpu_lockup; 792 bool gpu_lockup;
695 bool shutdown; 793 bool shutdown;
696 bool suspend; 794 bool suspend;
697 bool need_dma32; 795 bool need_dma32;
796 bool new_init_path;
797 bool accel_working;
698 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; 798 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
799 const struct firmware *me_fw; /* all family ME firmware */
800 const struct firmware *pfp_fw; /* r6/700 PFP firmware */
801 struct r600_blit r600_blit;
699}; 802};
700 803
701int radeon_device_init(struct radeon_device *rdev, 804int radeon_device_init(struct radeon_device *rdev,
@@ -705,6 +808,13 @@ int radeon_device_init(struct radeon_device *rdev,
705void radeon_device_fini(struct radeon_device *rdev); 808void radeon_device_fini(struct radeon_device *rdev);
706int radeon_gpu_wait_for_idle(struct radeon_device *rdev); 809int radeon_gpu_wait_for_idle(struct radeon_device *rdev);
707 810
811/* r600 blit */
812int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes);
813void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence);
814void r600_kms_blit_copy(struct radeon_device *rdev,
815 u64 src_gpu_addr, u64 dst_gpu_addr,
816 int size_bytes);
817
708static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) 818static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg)
709{ 819{
710 if (reg < 0x10000) 820 if (reg < 0x10000)
@@ -732,6 +842,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
732#define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) 842#define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg))
733#define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) 843#define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg))
734#define RREG32(reg) r100_mm_rreg(rdev, (reg)) 844#define RREG32(reg) r100_mm_rreg(rdev, (reg))
845#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg)))
735#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) 846#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v))
736#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) 847#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
737#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) 848#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
@@ -755,6 +866,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
755 tmp_ |= ((val) & ~(mask)); \ 866 tmp_ |= ((val) & ~(mask)); \
756 WREG32_PLL(reg, tmp_); \ 867 WREG32_PLL(reg, tmp_); \
757 } while (0) 868 } while (0)
869#define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg)))
758 870
759/* 871/*
760 * Indirect registers accessor 872 * Indirect registers accessor
@@ -819,51 +931,6 @@ void radeon_atombios_fini(struct radeon_device *rdev);
819/* 931/*
820 * RING helpers. 932 * RING helpers.
821 */ 933 */
822#define CP_PACKET0 0x00000000
823#define PACKET0_BASE_INDEX_SHIFT 0
824#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0)
825#define PACKET0_COUNT_SHIFT 16
826#define PACKET0_COUNT_MASK (0x3fff << 16)
827#define CP_PACKET1 0x40000000
828#define CP_PACKET2 0x80000000
829#define PACKET2_PAD_SHIFT 0
830#define PACKET2_PAD_MASK (0x3fffffff << 0)
831#define CP_PACKET3 0xC0000000
832#define PACKET3_IT_OPCODE_SHIFT 8
833#define PACKET3_IT_OPCODE_MASK (0xff << 8)
834#define PACKET3_COUNT_SHIFT 16
835#define PACKET3_COUNT_MASK (0x3fff << 16)
836/* PACKET3 op code */
837#define PACKET3_NOP 0x10
838#define PACKET3_3D_DRAW_VBUF 0x28
839#define PACKET3_3D_DRAW_IMMD 0x29
840#define PACKET3_3D_DRAW_INDX 0x2A
841#define PACKET3_3D_LOAD_VBPNTR 0x2F
842#define PACKET3_INDX_BUFFER 0x33
843#define PACKET3_3D_DRAW_VBUF_2 0x34
844#define PACKET3_3D_DRAW_IMMD_2 0x35
845#define PACKET3_3D_DRAW_INDX_2 0x36
846#define PACKET3_BITBLT_MULTI 0x9B
847
848#define PACKET0(reg, n) (CP_PACKET0 | \
849 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \
850 REG_SET(PACKET0_COUNT, (n)))
851#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
852#define PACKET3(op, n) (CP_PACKET3 | \
853 REG_SET(PACKET3_IT_OPCODE, (op)) | \
854 REG_SET(PACKET3_COUNT, (n)))
855
856#define PACKET_TYPE0 0
857#define PACKET_TYPE1 1
858#define PACKET_TYPE2 2
859#define PACKET_TYPE3 3
860
861#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
862#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
863#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
864#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
865#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
866
867static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) 934static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
868{ 935{
869#if DRM_DEBUG_CODE 936#if DRM_DEBUG_CODE
@@ -882,14 +949,20 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
882 * ASICs macro. 949 * ASICs macro.
883 */ 950 */
884#define radeon_init(rdev) (rdev)->asic->init((rdev)) 951#define radeon_init(rdev) (rdev)->asic->init((rdev))
952#define radeon_fini(rdev) (rdev)->asic->fini((rdev))
953#define radeon_resume(rdev) (rdev)->asic->resume((rdev))
954#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
885#define radeon_cs_parse(p) rdev->asic->cs_parse((p)) 955#define radeon_cs_parse(p) rdev->asic->cs_parse((p))
886#define radeon_errata(rdev) (rdev)->asic->errata((rdev)) 956#define radeon_errata(rdev) (rdev)->asic->errata((rdev))
887#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) 957#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
958#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
888#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev)) 959#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
889#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev)) 960#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
890#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev)) 961#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
891#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev)) 962#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
892#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev)) 963#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
964#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
965#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
893#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev)) 966#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
894#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev)) 967#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
895#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) 968#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
@@ -897,7 +970,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
897#define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize)) 970#define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
898#define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev)) 971#define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
899#define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev)) 972#define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
973#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
900#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) 974#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
975#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
976#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
977#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
901#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) 978#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
902#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) 979#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
903#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) 980#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -913,4 +990,88 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
913#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) 990#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
914#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) 991#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
915 992
993/* Common functions */
994extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
995extern int radeon_modeset_init(struct radeon_device *rdev);
996extern void radeon_modeset_fini(struct radeon_device *rdev);
997extern bool radeon_card_posted(struct radeon_device *rdev);
998extern int radeon_clocks_init(struct radeon_device *rdev);
999extern void radeon_clocks_fini(struct radeon_device *rdev);
1000extern void radeon_scratch_init(struct radeon_device *rdev);
1001extern void radeon_surface_init(struct radeon_device *rdev);
1002extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
1003
1004/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
1005struct r100_mc_save {
1006 u32 GENMO_WT;
1007 u32 CRTC_EXT_CNTL;
1008 u32 CRTC_GEN_CNTL;
1009 u32 CRTC2_GEN_CNTL;
1010 u32 CUR_OFFSET;
1011 u32 CUR2_OFFSET;
1012};
1013extern void r100_cp_disable(struct radeon_device *rdev);
1014extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
1015extern void r100_cp_fini(struct radeon_device *rdev);
1016extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
1017extern int r100_pci_gart_init(struct radeon_device *rdev);
1018extern void r100_pci_gart_fini(struct radeon_device *rdev);
1019extern int r100_pci_gart_enable(struct radeon_device *rdev);
1020extern void r100_pci_gart_disable(struct radeon_device *rdev);
1021extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
1022extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
1023extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
1024extern void r100_ib_fini(struct radeon_device *rdev);
1025extern int r100_ib_init(struct radeon_device *rdev);
1026extern void r100_irq_disable(struct radeon_device *rdev);
1027extern int r100_irq_set(struct radeon_device *rdev);
1028extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
1029extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
1030extern void r100_vram_init_sizes(struct radeon_device *rdev);
1031extern void r100_wb_disable(struct radeon_device *rdev);
1032extern void r100_wb_fini(struct radeon_device *rdev);
1033extern int r100_wb_init(struct radeon_device *rdev);
1034
1035/* r300,r350,rv350,rv370,rv380 */
1036extern void r300_set_reg_safe(struct radeon_device *rdev);
1037extern void r300_mc_program(struct radeon_device *rdev);
1038extern void r300_vram_info(struct radeon_device *rdev);
1039extern int rv370_pcie_gart_init(struct radeon_device *rdev);
1040extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
1041extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
1042extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
1043
1044/* r420,r423,rv410 */
1045extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
1046extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
1047extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
1048
1049/* rv515 */
1050extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
1051
1052/* rs690, rs740 */
1053extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
1054 struct drm_display_mode *mode1,
1055 struct drm_display_mode *mode2);
1056
1057/* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
1058extern bool r600_card_posted(struct radeon_device *rdev);
1059extern void r600_cp_stop(struct radeon_device *rdev);
1060extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size);
1061extern int r600_cp_resume(struct radeon_device *rdev);
1062extern int r600_count_pipe_bits(uint32_t val);
1063extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
1064extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
1065extern int r600_pcie_gart_init(struct radeon_device *rdev);
1066extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
1067extern int r600_ib_test(struct radeon_device *rdev);
1068extern int r600_ring_test(struct radeon_device *rdev);
1069extern int r600_wb_init(struct radeon_device *rdev);
1070extern void r600_wb_fini(struct radeon_device *rdev);
1071extern void r600_scratch_init(struct radeon_device *rdev);
1072extern int r600_blit_init(struct radeon_device *rdev);
1073extern void r600_blit_fini(struct radeon_device *rdev);
1074extern int r600_cp_init_microcode(struct radeon_device *rdev);
1075extern int r600_gpu_reset(struct radeon_device *rdev);
1076
916#endif 1077#endif
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 93d8f8889302..8968f78fa1e3 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -42,23 +42,28 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
42 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 42 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
43 */ 43 */
44int r100_init(struct radeon_device *rdev); 44int r100_init(struct radeon_device *rdev);
45int r200_init(struct radeon_device *rdev);
45uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); 46uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
46void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 47void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
47void r100_errata(struct radeon_device *rdev); 48void r100_errata(struct radeon_device *rdev);
48void r100_vram_info(struct radeon_device *rdev); 49void r100_vram_info(struct radeon_device *rdev);
50void r100_vga_set_state(struct radeon_device *rdev, bool state);
49int r100_gpu_reset(struct radeon_device *rdev); 51int r100_gpu_reset(struct radeon_device *rdev);
50int r100_mc_init(struct radeon_device *rdev); 52int r100_mc_init(struct radeon_device *rdev);
51void r100_mc_fini(struct radeon_device *rdev); 53void r100_mc_fini(struct radeon_device *rdev);
52u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); 54u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
53int r100_wb_init(struct radeon_device *rdev); 55int r100_wb_init(struct radeon_device *rdev);
54void r100_wb_fini(struct radeon_device *rdev); 56void r100_wb_fini(struct radeon_device *rdev);
55int r100_gart_enable(struct radeon_device *rdev); 57int r100_pci_gart_init(struct radeon_device *rdev);
58void r100_pci_gart_fini(struct radeon_device *rdev);
59int r100_pci_gart_enable(struct radeon_device *rdev);
56void r100_pci_gart_disable(struct radeon_device *rdev); 60void r100_pci_gart_disable(struct radeon_device *rdev);
57void r100_pci_gart_tlb_flush(struct radeon_device *rdev); 61void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
58int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 62int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
59int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); 63int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
60void r100_cp_fini(struct radeon_device *rdev); 64void r100_cp_fini(struct radeon_device *rdev);
61void r100_cp_disable(struct radeon_device *rdev); 65void r100_cp_disable(struct radeon_device *rdev);
66void r100_cp_commit(struct radeon_device *rdev);
62void r100_ring_start(struct radeon_device *rdev); 67void r100_ring_start(struct radeon_device *rdev);
63int r100_irq_set(struct radeon_device *rdev); 68int r100_irq_set(struct radeon_device *rdev);
64int r100_irq_process(struct radeon_device *rdev); 69int r100_irq_process(struct radeon_device *rdev);
@@ -77,24 +82,34 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
77 uint32_t offset, uint32_t obj_size); 82 uint32_t offset, uint32_t obj_size);
78int r100_clear_surface_reg(struct radeon_device *rdev, int reg); 83int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
79void r100_bandwidth_update(struct radeon_device *rdev); 84void r100_bandwidth_update(struct radeon_device *rdev);
85void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
86int r100_ib_test(struct radeon_device *rdev);
87int r100_ring_test(struct radeon_device *rdev);
80 88
81static struct radeon_asic r100_asic = { 89static struct radeon_asic r100_asic = {
82 .init = &r100_init, 90 .init = &r100_init,
83 .errata = &r100_errata, 91 .errata = &r100_errata,
84 .vram_info = &r100_vram_info, 92 .vram_info = &r100_vram_info,
93 .vga_set_state = &r100_vga_set_state,
85 .gpu_reset = &r100_gpu_reset, 94 .gpu_reset = &r100_gpu_reset,
86 .mc_init = &r100_mc_init, 95 .mc_init = &r100_mc_init,
87 .mc_fini = &r100_mc_fini, 96 .mc_fini = &r100_mc_fini,
88 .wb_init = &r100_wb_init, 97 .wb_init = &r100_wb_init,
89 .wb_fini = &r100_wb_fini, 98 .wb_fini = &r100_wb_fini,
90 .gart_enable = &r100_gart_enable, 99 .gart_init = &r100_pci_gart_init,
100 .gart_fini = &r100_pci_gart_fini,
101 .gart_enable = &r100_pci_gart_enable,
91 .gart_disable = &r100_pci_gart_disable, 102 .gart_disable = &r100_pci_gart_disable,
92 .gart_tlb_flush = &r100_pci_gart_tlb_flush, 103 .gart_tlb_flush = &r100_pci_gart_tlb_flush,
93 .gart_set_page = &r100_pci_gart_set_page, 104 .gart_set_page = &r100_pci_gart_set_page,
94 .cp_init = &r100_cp_init, 105 .cp_init = &r100_cp_init,
95 .cp_fini = &r100_cp_fini, 106 .cp_fini = &r100_cp_fini,
96 .cp_disable = &r100_cp_disable, 107 .cp_disable = &r100_cp_disable,
108 .cp_commit = &r100_cp_commit,
97 .ring_start = &r100_ring_start, 109 .ring_start = &r100_ring_start,
110 .ring_test = &r100_ring_test,
111 .ring_ib_execute = &r100_ring_ib_execute,
112 .ib_test = &r100_ib_test,
98 .irq_set = &r100_irq_set, 113 .irq_set = &r100_irq_set,
99 .irq_process = &r100_irq_process, 114 .irq_process = &r100_irq_process,
100 .get_vblank_counter = &r100_get_vblank_counter, 115 .get_vblank_counter = &r100_get_vblank_counter,
@@ -126,7 +141,9 @@ void r300_ring_start(struct radeon_device *rdev);
126void r300_fence_ring_emit(struct radeon_device *rdev, 141void r300_fence_ring_emit(struct radeon_device *rdev,
127 struct radeon_fence *fence); 142 struct radeon_fence *fence);
128int r300_cs_parse(struct radeon_cs_parser *p); 143int r300_cs_parse(struct radeon_cs_parser *p);
129int r300_gart_enable(struct radeon_device *rdev); 144int rv370_pcie_gart_init(struct radeon_device *rdev);
145void rv370_pcie_gart_fini(struct radeon_device *rdev);
146int rv370_pcie_gart_enable(struct radeon_device *rdev);
130void rv370_pcie_gart_disable(struct radeon_device *rdev); 147void rv370_pcie_gart_disable(struct radeon_device *rdev);
131void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); 148void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
132int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 149int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
@@ -143,19 +160,26 @@ static struct radeon_asic r300_asic = {
143 .init = &r300_init, 160 .init = &r300_init,
144 .errata = &r300_errata, 161 .errata = &r300_errata,
145 .vram_info = &r300_vram_info, 162 .vram_info = &r300_vram_info,
163 .vga_set_state = &r100_vga_set_state,
146 .gpu_reset = &r300_gpu_reset, 164 .gpu_reset = &r300_gpu_reset,
147 .mc_init = &r300_mc_init, 165 .mc_init = &r300_mc_init,
148 .mc_fini = &r300_mc_fini, 166 .mc_fini = &r300_mc_fini,
149 .wb_init = &r100_wb_init, 167 .wb_init = &r100_wb_init,
150 .wb_fini = &r100_wb_fini, 168 .wb_fini = &r100_wb_fini,
151 .gart_enable = &r300_gart_enable, 169 .gart_init = &r100_pci_gart_init,
170 .gart_fini = &r100_pci_gart_fini,
171 .gart_enable = &r100_pci_gart_enable,
152 .gart_disable = &r100_pci_gart_disable, 172 .gart_disable = &r100_pci_gart_disable,
153 .gart_tlb_flush = &r100_pci_gart_tlb_flush, 173 .gart_tlb_flush = &r100_pci_gart_tlb_flush,
154 .gart_set_page = &r100_pci_gart_set_page, 174 .gart_set_page = &r100_pci_gart_set_page,
155 .cp_init = &r100_cp_init, 175 .cp_init = &r100_cp_init,
156 .cp_fini = &r100_cp_fini, 176 .cp_fini = &r100_cp_fini,
157 .cp_disable = &r100_cp_disable, 177 .cp_disable = &r100_cp_disable,
178 .cp_commit = &r100_cp_commit,
158 .ring_start = &r300_ring_start, 179 .ring_start = &r300_ring_start,
180 .ring_test = &r100_ring_test,
181 .ring_ib_execute = &r100_ring_ib_execute,
182 .ib_test = &r100_ib_test,
159 .irq_set = &r100_irq_set, 183 .irq_set = &r100_irq_set,
160 .irq_process = &r100_irq_process, 184 .irq_process = &r100_irq_process,
161 .get_vblank_counter = &r100_get_vblank_counter, 185 .get_vblank_counter = &r100_get_vblank_counter,
@@ -176,27 +200,35 @@ static struct radeon_asic r300_asic = {
176/* 200/*
177 * r420,r423,rv410 201 * r420,r423,rv410
178 */ 202 */
179void r420_errata(struct radeon_device *rdev); 203extern int r420_init(struct radeon_device *rdev);
180void r420_vram_info(struct radeon_device *rdev); 204extern void r420_fini(struct radeon_device *rdev);
181int r420_mc_init(struct radeon_device *rdev); 205extern int r420_suspend(struct radeon_device *rdev);
182void r420_mc_fini(struct radeon_device *rdev); 206extern int r420_resume(struct radeon_device *rdev);
183static struct radeon_asic r420_asic = { 207static struct radeon_asic r420_asic = {
184 .init = &r300_init, 208 .init = &r420_init,
185 .errata = &r420_errata, 209 .fini = &r420_fini,
186 .vram_info = &r420_vram_info, 210 .suspend = &r420_suspend,
211 .resume = &r420_resume,
212 .errata = NULL,
213 .vram_info = NULL,
214 .vga_set_state = &r100_vga_set_state,
187 .gpu_reset = &r300_gpu_reset, 215 .gpu_reset = &r300_gpu_reset,
188 .mc_init = &r420_mc_init, 216 .mc_init = NULL,
189 .mc_fini = &r420_mc_fini, 217 .mc_fini = NULL,
190 .wb_init = &r100_wb_init, 218 .wb_init = NULL,
191 .wb_fini = &r100_wb_fini, 219 .wb_fini = NULL,
192 .gart_enable = &r300_gart_enable, 220 .gart_enable = NULL,
193 .gart_disable = &rv370_pcie_gart_disable, 221 .gart_disable = NULL,
194 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 222 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
195 .gart_set_page = &rv370_pcie_gart_set_page, 223 .gart_set_page = &rv370_pcie_gart_set_page,
196 .cp_init = &r100_cp_init, 224 .cp_init = NULL,
197 .cp_fini = &r100_cp_fini, 225 .cp_fini = NULL,
198 .cp_disable = &r100_cp_disable, 226 .cp_disable = NULL,
227 .cp_commit = &r100_cp_commit,
199 .ring_start = &r300_ring_start, 228 .ring_start = &r300_ring_start,
229 .ring_test = &r100_ring_test,
230 .ring_ib_execute = &r100_ring_ib_execute,
231 .ib_test = NULL,
200 .irq_set = &r100_irq_set, 232 .irq_set = &r100_irq_set,
201 .irq_process = &r100_irq_process, 233 .irq_process = &r100_irq_process,
202 .get_vblank_counter = &r100_get_vblank_counter, 234 .get_vblank_counter = &r100_get_vblank_counter,
@@ -222,6 +254,8 @@ void rs400_errata(struct radeon_device *rdev);
222void rs400_vram_info(struct radeon_device *rdev); 254void rs400_vram_info(struct radeon_device *rdev);
223int rs400_mc_init(struct radeon_device *rdev); 255int rs400_mc_init(struct radeon_device *rdev);
224void rs400_mc_fini(struct radeon_device *rdev); 256void rs400_mc_fini(struct radeon_device *rdev);
257int rs400_gart_init(struct radeon_device *rdev);
258void rs400_gart_fini(struct radeon_device *rdev);
225int rs400_gart_enable(struct radeon_device *rdev); 259int rs400_gart_enable(struct radeon_device *rdev);
226void rs400_gart_disable(struct radeon_device *rdev); 260void rs400_gart_disable(struct radeon_device *rdev);
227void rs400_gart_tlb_flush(struct radeon_device *rdev); 261void rs400_gart_tlb_flush(struct radeon_device *rdev);
@@ -232,11 +266,14 @@ static struct radeon_asic rs400_asic = {
232 .init = &r300_init, 266 .init = &r300_init,
233 .errata = &rs400_errata, 267 .errata = &rs400_errata,
234 .vram_info = &rs400_vram_info, 268 .vram_info = &rs400_vram_info,
269 .vga_set_state = &r100_vga_set_state,
235 .gpu_reset = &r300_gpu_reset, 270 .gpu_reset = &r300_gpu_reset,
236 .mc_init = &rs400_mc_init, 271 .mc_init = &rs400_mc_init,
237 .mc_fini = &rs400_mc_fini, 272 .mc_fini = &rs400_mc_fini,
238 .wb_init = &r100_wb_init, 273 .wb_init = &r100_wb_init,
239 .wb_fini = &r100_wb_fini, 274 .wb_fini = &r100_wb_fini,
275 .gart_init = &rs400_gart_init,
276 .gart_fini = &rs400_gart_fini,
240 .gart_enable = &rs400_gart_enable, 277 .gart_enable = &rs400_gart_enable,
241 .gart_disable = &rs400_gart_disable, 278 .gart_disable = &rs400_gart_disable,
242 .gart_tlb_flush = &rs400_gart_tlb_flush, 279 .gart_tlb_flush = &rs400_gart_tlb_flush,
@@ -244,7 +281,11 @@ static struct radeon_asic rs400_asic = {
244 .cp_init = &r100_cp_init, 281 .cp_init = &r100_cp_init,
245 .cp_fini = &r100_cp_fini, 282 .cp_fini = &r100_cp_fini,
246 .cp_disable = &r100_cp_disable, 283 .cp_disable = &r100_cp_disable,
284 .cp_commit = &r100_cp_commit,
247 .ring_start = &r300_ring_start, 285 .ring_start = &r300_ring_start,
286 .ring_test = &r100_ring_test,
287 .ring_ib_execute = &r100_ring_ib_execute,
288 .ib_test = &r100_ib_test,
248 .irq_set = &r100_irq_set, 289 .irq_set = &r100_irq_set,
249 .irq_process = &r100_irq_process, 290 .irq_process = &r100_irq_process,
250 .get_vblank_counter = &r100_get_vblank_counter, 291 .get_vblank_counter = &r100_get_vblank_counter,
@@ -266,7 +307,7 @@ static struct radeon_asic rs400_asic = {
266/* 307/*
267 * rs600. 308 * rs600.
268 */ 309 */
269int rs600_init(struct radeon_device *dev); 310int rs600_init(struct radeon_device *rdev);
270void rs600_errata(struct radeon_device *rdev); 311void rs600_errata(struct radeon_device *rdev);
271void rs600_vram_info(struct radeon_device *rdev); 312void rs600_vram_info(struct radeon_device *rdev);
272int rs600_mc_init(struct radeon_device *rdev); 313int rs600_mc_init(struct radeon_device *rdev);
@@ -274,6 +315,8 @@ void rs600_mc_fini(struct radeon_device *rdev);
274int rs600_irq_set(struct radeon_device *rdev); 315int rs600_irq_set(struct radeon_device *rdev);
275int rs600_irq_process(struct radeon_device *rdev); 316int rs600_irq_process(struct radeon_device *rdev);
276u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); 317u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
318int rs600_gart_init(struct radeon_device *rdev);
319void rs600_gart_fini(struct radeon_device *rdev);
277int rs600_gart_enable(struct radeon_device *rdev); 320int rs600_gart_enable(struct radeon_device *rdev);
278void rs600_gart_disable(struct radeon_device *rdev); 321void rs600_gart_disable(struct radeon_device *rdev);
279void rs600_gart_tlb_flush(struct radeon_device *rdev); 322void rs600_gart_tlb_flush(struct radeon_device *rdev);
@@ -285,11 +328,14 @@ static struct radeon_asic rs600_asic = {
285 .init = &rs600_init, 328 .init = &rs600_init,
286 .errata = &rs600_errata, 329 .errata = &rs600_errata,
287 .vram_info = &rs600_vram_info, 330 .vram_info = &rs600_vram_info,
331 .vga_set_state = &r100_vga_set_state,
288 .gpu_reset = &r300_gpu_reset, 332 .gpu_reset = &r300_gpu_reset,
289 .mc_init = &rs600_mc_init, 333 .mc_init = &rs600_mc_init,
290 .mc_fini = &rs600_mc_fini, 334 .mc_fini = &rs600_mc_fini,
291 .wb_init = &r100_wb_init, 335 .wb_init = &r100_wb_init,
292 .wb_fini = &r100_wb_fini, 336 .wb_fini = &r100_wb_fini,
337 .gart_init = &rs600_gart_init,
338 .gart_fini = &rs600_gart_fini,
293 .gart_enable = &rs600_gart_enable, 339 .gart_enable = &rs600_gart_enable,
294 .gart_disable = &rs600_gart_disable, 340 .gart_disable = &rs600_gart_disable,
295 .gart_tlb_flush = &rs600_gart_tlb_flush, 341 .gart_tlb_flush = &rs600_gart_tlb_flush,
@@ -297,7 +343,11 @@ static struct radeon_asic rs600_asic = {
297 .cp_init = &r100_cp_init, 343 .cp_init = &r100_cp_init,
298 .cp_fini = &r100_cp_fini, 344 .cp_fini = &r100_cp_fini,
299 .cp_disable = &r100_cp_disable, 345 .cp_disable = &r100_cp_disable,
346 .cp_commit = &r100_cp_commit,
300 .ring_start = &r300_ring_start, 347 .ring_start = &r300_ring_start,
348 .ring_test = &r100_ring_test,
349 .ring_ib_execute = &r100_ring_ib_execute,
350 .ib_test = &r100_ib_test,
301 .irq_set = &rs600_irq_set, 351 .irq_set = &rs600_irq_set,
302 .irq_process = &rs600_irq_process, 352 .irq_process = &rs600_irq_process,
303 .get_vblank_counter = &rs600_get_vblank_counter, 353 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -328,11 +378,14 @@ static struct radeon_asic rs690_asic = {
328 .init = &rs600_init, 378 .init = &rs600_init,
329 .errata = &rs690_errata, 379 .errata = &rs690_errata,
330 .vram_info = &rs690_vram_info, 380 .vram_info = &rs690_vram_info,
381 .vga_set_state = &r100_vga_set_state,
331 .gpu_reset = &r300_gpu_reset, 382 .gpu_reset = &r300_gpu_reset,
332 .mc_init = &rs690_mc_init, 383 .mc_init = &rs690_mc_init,
333 .mc_fini = &rs690_mc_fini, 384 .mc_fini = &rs690_mc_fini,
334 .wb_init = &r100_wb_init, 385 .wb_init = &r100_wb_init,
335 .wb_fini = &r100_wb_fini, 386 .wb_fini = &r100_wb_fini,
387 .gart_init = &rs400_gart_init,
388 .gart_fini = &rs400_gart_fini,
336 .gart_enable = &rs400_gart_enable, 389 .gart_enable = &rs400_gart_enable,
337 .gart_disable = &rs400_gart_disable, 390 .gart_disable = &rs400_gart_disable,
338 .gart_tlb_flush = &rs400_gart_tlb_flush, 391 .gart_tlb_flush = &rs400_gart_tlb_flush,
@@ -340,7 +393,11 @@ static struct radeon_asic rs690_asic = {
340 .cp_init = &r100_cp_init, 393 .cp_init = &r100_cp_init,
341 .cp_fini = &r100_cp_fini, 394 .cp_fini = &r100_cp_fini,
342 .cp_disable = &r100_cp_disable, 395 .cp_disable = &r100_cp_disable,
396 .cp_commit = &r100_cp_commit,
343 .ring_start = &r300_ring_start, 397 .ring_start = &r300_ring_start,
398 .ring_test = &r100_ring_test,
399 .ring_ib_execute = &r100_ring_ib_execute,
400 .ib_test = &r100_ib_test,
344 .irq_set = &rs600_irq_set, 401 .irq_set = &rs600_irq_set,
345 .irq_process = &rs600_irq_process, 402 .irq_process = &rs600_irq_process,
346 .get_vblank_counter = &rs600_get_vblank_counter, 403 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -378,19 +435,26 @@ static struct radeon_asic rv515_asic = {
378 .init = &rv515_init, 435 .init = &rv515_init,
379 .errata = &rv515_errata, 436 .errata = &rv515_errata,
380 .vram_info = &rv515_vram_info, 437 .vram_info = &rv515_vram_info,
438 .vga_set_state = &r100_vga_set_state,
381 .gpu_reset = &rv515_gpu_reset, 439 .gpu_reset = &rv515_gpu_reset,
382 .mc_init = &rv515_mc_init, 440 .mc_init = &rv515_mc_init,
383 .mc_fini = &rv515_mc_fini, 441 .mc_fini = &rv515_mc_fini,
384 .wb_init = &r100_wb_init, 442 .wb_init = &r100_wb_init,
385 .wb_fini = &r100_wb_fini, 443 .wb_fini = &r100_wb_fini,
386 .gart_enable = &r300_gart_enable, 444 .gart_init = &rv370_pcie_gart_init,
445 .gart_fini = &rv370_pcie_gart_fini,
446 .gart_enable = &rv370_pcie_gart_enable,
387 .gart_disable = &rv370_pcie_gart_disable, 447 .gart_disable = &rv370_pcie_gart_disable,
388 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 448 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
389 .gart_set_page = &rv370_pcie_gart_set_page, 449 .gart_set_page = &rv370_pcie_gart_set_page,
390 .cp_init = &r100_cp_init, 450 .cp_init = &r100_cp_init,
391 .cp_fini = &r100_cp_fini, 451 .cp_fini = &r100_cp_fini,
392 .cp_disable = &r100_cp_disable, 452 .cp_disable = &r100_cp_disable,
453 .cp_commit = &r100_cp_commit,
393 .ring_start = &rv515_ring_start, 454 .ring_start = &rv515_ring_start,
455 .ring_test = &r100_ring_test,
456 .ring_ib_execute = &r100_ring_ib_execute,
457 .ib_test = &r100_ib_test,
394 .irq_set = &rs600_irq_set, 458 .irq_set = &rs600_irq_set,
395 .irq_process = &rs600_irq_process, 459 .irq_process = &rs600_irq_process,
396 .get_vblank_counter = &rs600_get_vblank_counter, 460 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -421,19 +485,26 @@ static struct radeon_asic r520_asic = {
421 .init = &rv515_init, 485 .init = &rv515_init,
422 .errata = &r520_errata, 486 .errata = &r520_errata,
423 .vram_info = &r520_vram_info, 487 .vram_info = &r520_vram_info,
488 .vga_set_state = &r100_vga_set_state,
424 .gpu_reset = &rv515_gpu_reset, 489 .gpu_reset = &rv515_gpu_reset,
425 .mc_init = &r520_mc_init, 490 .mc_init = &r520_mc_init,
426 .mc_fini = &r520_mc_fini, 491 .mc_fini = &r520_mc_fini,
427 .wb_init = &r100_wb_init, 492 .wb_init = &r100_wb_init,
428 .wb_fini = &r100_wb_fini, 493 .wb_fini = &r100_wb_fini,
429 .gart_enable = &r300_gart_enable, 494 .gart_init = &rv370_pcie_gart_init,
495 .gart_fini = &rv370_pcie_gart_fini,
496 .gart_enable = &rv370_pcie_gart_enable,
430 .gart_disable = &rv370_pcie_gart_disable, 497 .gart_disable = &rv370_pcie_gart_disable,
431 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 498 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
432 .gart_set_page = &rv370_pcie_gart_set_page, 499 .gart_set_page = &rv370_pcie_gart_set_page,
433 .cp_init = &r100_cp_init, 500 .cp_init = &r100_cp_init,
434 .cp_fini = &r100_cp_fini, 501 .cp_fini = &r100_cp_fini,
435 .cp_disable = &r100_cp_disable, 502 .cp_disable = &r100_cp_disable,
503 .cp_commit = &r100_cp_commit,
436 .ring_start = &rv515_ring_start, 504 .ring_start = &rv515_ring_start,
505 .ring_test = &r100_ring_test,
506 .ring_ib_execute = &r100_ring_ib_execute,
507 .ib_test = &r100_ib_test,
437 .irq_set = &rs600_irq_set, 508 .irq_set = &rs600_irq_set,
438 .irq_process = &rs600_irq_process, 509 .irq_process = &rs600_irq_process,
439 .get_vblank_counter = &rs600_get_vblank_counter, 510 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -452,9 +523,130 @@ static struct radeon_asic r520_asic = {
452}; 523};
453 524
454/* 525/*
455 * r600,rv610,rv630,rv620,rv635,rv670,rs780,rv770,rv730,rv710 526 * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880
456 */ 527 */
528int r600_init(struct radeon_device *rdev);
529void r600_fini(struct radeon_device *rdev);
530int r600_suspend(struct radeon_device *rdev);
531int r600_resume(struct radeon_device *rdev);
532void r600_vga_set_state(struct radeon_device *rdev, bool state);
533int r600_wb_init(struct radeon_device *rdev);
534void r600_wb_fini(struct radeon_device *rdev);
535void r600_cp_commit(struct radeon_device *rdev);
536void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
457uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); 537uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
458void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 538void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
539int r600_cs_parse(struct radeon_cs_parser *p);
540void r600_fence_ring_emit(struct radeon_device *rdev,
541 struct radeon_fence *fence);
542int r600_copy_dma(struct radeon_device *rdev,
543 uint64_t src_offset,
544 uint64_t dst_offset,
545 unsigned num_pages,
546 struct radeon_fence *fence);
547int r600_irq_process(struct radeon_device *rdev);
548int r600_irq_set(struct radeon_device *rdev);
549int r600_gpu_reset(struct radeon_device *rdev);
550int r600_set_surface_reg(struct radeon_device *rdev, int reg,
551 uint32_t tiling_flags, uint32_t pitch,
552 uint32_t offset, uint32_t obj_size);
553int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
554void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
555int r600_ib_test(struct radeon_device *rdev);
556int r600_ring_test(struct radeon_device *rdev);
557int r600_copy_blit(struct radeon_device *rdev,
558 uint64_t src_offset, uint64_t dst_offset,
559 unsigned num_pages, struct radeon_fence *fence);
560
561static struct radeon_asic r600_asic = {
562 .errata = NULL,
563 .init = &r600_init,
564 .fini = &r600_fini,
565 .suspend = &r600_suspend,
566 .resume = &r600_resume,
567 .cp_commit = &r600_cp_commit,
568 .vram_info = NULL,
569 .vga_set_state = &r600_vga_set_state,
570 .gpu_reset = &r600_gpu_reset,
571 .mc_init = NULL,
572 .mc_fini = NULL,
573 .wb_init = &r600_wb_init,
574 .wb_fini = &r600_wb_fini,
575 .gart_enable = NULL,
576 .gart_disable = NULL,
577 .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
578 .gart_set_page = &rs600_gart_set_page,
579 .cp_init = NULL,
580 .cp_fini = NULL,
581 .cp_disable = NULL,
582 .ring_start = NULL,
583 .ring_test = &r600_ring_test,
584 .ring_ib_execute = &r600_ring_ib_execute,
585 .ib_test = &r600_ib_test,
586 .irq_set = &r600_irq_set,
587 .irq_process = &r600_irq_process,
588 .fence_ring_emit = &r600_fence_ring_emit,
589 .cs_parse = &r600_cs_parse,
590 .copy_blit = &r600_copy_blit,
591 .copy_dma = &r600_copy_blit,
592 .copy = &r600_copy_blit,
593 .set_engine_clock = &radeon_atom_set_engine_clock,
594 .set_memory_clock = &radeon_atom_set_memory_clock,
595 .set_pcie_lanes = NULL,
596 .set_clock_gating = &radeon_atom_set_clock_gating,
597 .set_surface_reg = r600_set_surface_reg,
598 .clear_surface_reg = r600_clear_surface_reg,
599 .bandwidth_update = &r520_bandwidth_update,
600};
601
602/*
603 * rv770,rv730,rv710,rv740
604 */
605int rv770_init(struct radeon_device *rdev);
606void rv770_fini(struct radeon_device *rdev);
607int rv770_suspend(struct radeon_device *rdev);
608int rv770_resume(struct radeon_device *rdev);
609int rv770_gpu_reset(struct radeon_device *rdev);
610
611static struct radeon_asic rv770_asic = {
612 .errata = NULL,
613 .init = &rv770_init,
614 .fini = &rv770_fini,
615 .suspend = &rv770_suspend,
616 .resume = &rv770_resume,
617 .cp_commit = &r600_cp_commit,
618 .vram_info = NULL,
619 .gpu_reset = &rv770_gpu_reset,
620 .vga_set_state = &r600_vga_set_state,
621 .mc_init = NULL,
622 .mc_fini = NULL,
623 .wb_init = &r600_wb_init,
624 .wb_fini = &r600_wb_fini,
625 .gart_enable = NULL,
626 .gart_disable = NULL,
627 .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
628 .gart_set_page = &rs600_gart_set_page,
629 .cp_init = NULL,
630 .cp_fini = NULL,
631 .cp_disable = NULL,
632 .ring_start = NULL,
633 .ring_test = &r600_ring_test,
634 .ring_ib_execute = &r600_ring_ib_execute,
635 .ib_test = &r600_ib_test,
636 .irq_set = &r600_irq_set,
637 .irq_process = &r600_irq_process,
638 .fence_ring_emit = &r600_fence_ring_emit,
639 .cs_parse = &r600_cs_parse,
640 .copy_blit = &r600_copy_blit,
641 .copy_dma = &r600_copy_blit,
642 .copy = &r600_copy_blit,
643 .set_engine_clock = &radeon_atom_set_engine_clock,
644 .set_memory_clock = &radeon_atom_set_memory_clock,
645 .set_pcie_lanes = NULL,
646 .set_clock_gating = &radeon_atom_set_clock_gating,
647 .set_surface_reg = r600_set_surface_reg,
648 .clear_surface_reg = r600_clear_surface_reg,
649 .bandwidth_update = &r520_bandwidth_update,
650};
459 651
460#endif 652#endif
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index fcfe5c02d744..743742128307 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -104,7 +104,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
104 uint32_t supported_device, 104 uint32_t supported_device,
105 int *connector_type, 105 int *connector_type,
106 struct radeon_i2c_bus_rec *i2c_bus, 106 struct radeon_i2c_bus_rec *i2c_bus,
107 uint8_t *line_mux) 107 uint16_t *line_mux)
108{ 108{
109 109
110 /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ 110 /* Asus M2A-VM HDMI board lists the DVI port as HDMI */
@@ -143,20 +143,31 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
143 return false; 143 return false;
144 } 144 }
145 145
146 /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */
147 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
148 (*connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
149 if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {
150 return false;
151 }
152 }
153
154 /* ASUS HD 3600 XT board lists the DVI port as HDMI */ 146 /* ASUS HD 3600 XT board lists the DVI port as HDMI */
155 if ((dev->pdev->device == 0x9598) && 147 if ((dev->pdev->device == 0x9598) &&
156 (dev->pdev->subsystem_vendor == 0x1043) && 148 (dev->pdev->subsystem_vendor == 0x1043) &&
157 (dev->pdev->subsystem_device == 0x01da)) { 149 (dev->pdev->subsystem_device == 0x01da)) {
158 if (*connector_type == DRM_MODE_CONNECTOR_HDMIB) { 150 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
159 *connector_type = DRM_MODE_CONNECTOR_DVID; 151 *connector_type = DRM_MODE_CONNECTOR_DVII;
152 }
153 }
154
155 /* ASUS HD 3450 board lists the DVI port as HDMI */
156 if ((dev->pdev->device == 0x95C5) &&
157 (dev->pdev->subsystem_vendor == 0x1043) &&
158 (dev->pdev->subsystem_device == 0x01e2)) {
159 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
160 *connector_type = DRM_MODE_CONNECTOR_DVII;
161 }
162 }
163
164 /* some BIOSes seem to report DAC on HDMI - usually this is a board with
165 * HDMI + VGA reporting as HDMI
166 */
167 if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
168 if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {
169 *connector_type = DRM_MODE_CONNECTOR_VGA;
170 *line_mux = 0;
160 } 171 }
161 } 172 }
162 173
@@ -192,11 +203,11 @@ const int object_connector_convert[] = {
192 DRM_MODE_CONNECTOR_Composite, 203 DRM_MODE_CONNECTOR_Composite,
193 DRM_MODE_CONNECTOR_SVIDEO, 204 DRM_MODE_CONNECTOR_SVIDEO,
194 DRM_MODE_CONNECTOR_Unknown, 205 DRM_MODE_CONNECTOR_Unknown,
206 DRM_MODE_CONNECTOR_Unknown,
195 DRM_MODE_CONNECTOR_9PinDIN, 207 DRM_MODE_CONNECTOR_9PinDIN,
196 DRM_MODE_CONNECTOR_Unknown, 208 DRM_MODE_CONNECTOR_Unknown,
197 DRM_MODE_CONNECTOR_HDMIA, 209 DRM_MODE_CONNECTOR_HDMIA,
198 DRM_MODE_CONNECTOR_HDMIB, 210 DRM_MODE_CONNECTOR_HDMIB,
199 DRM_MODE_CONNECTOR_HDMIB,
200 DRM_MODE_CONNECTOR_LVDS, 211 DRM_MODE_CONNECTOR_LVDS,
201 DRM_MODE_CONNECTOR_9PinDIN, 212 DRM_MODE_CONNECTOR_9PinDIN,
202 DRM_MODE_CONNECTOR_Unknown, 213 DRM_MODE_CONNECTOR_Unknown,
@@ -218,7 +229,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
218 ATOM_OBJECT_HEADER *obj_header; 229 ATOM_OBJECT_HEADER *obj_header;
219 int i, j, path_size, device_support; 230 int i, j, path_size, device_support;
220 int connector_type; 231 int connector_type;
221 uint16_t igp_lane_info; 232 uint16_t igp_lane_info, conn_id;
222 bool linkb; 233 bool linkb;
223 struct radeon_i2c_bus_rec ddc_bus; 234 struct radeon_i2c_bus_rec ddc_bus;
224 235
@@ -370,10 +381,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
370 && record-> 381 && record->
371 ucRecordType <= 382 ucRecordType <=
372 ATOM_MAX_OBJECT_RECORD_NUMBER) { 383 ATOM_MAX_OBJECT_RECORD_NUMBER) {
373 DRM_ERROR
374 ("record type %d\n",
375 record->
376 ucRecordType);
377 switch (record-> 384 switch (record->
378 ucRecordType) { 385 ucRecordType) {
379 case ATOM_I2C_RECORD_TYPE: 386 case ATOM_I2C_RECORD_TYPE:
@@ -409,9 +416,15 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
409 else 416 else
410 ddc_bus = radeon_lookup_gpio(dev, line_mux); 417 ddc_bus = radeon_lookup_gpio(dev, line_mux);
411 418
419 conn_id = le16_to_cpu(path->usConnObjectId);
420
421 if (!radeon_atom_apply_quirks
422 (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
423 &ddc_bus, &conn_id))
424 continue;
425
412 radeon_add_atom_connector(dev, 426 radeon_add_atom_connector(dev,
413 le16_to_cpu(path-> 427 conn_id,
414 usConnObjectId),
415 le16_to_cpu(path-> 428 le16_to_cpu(path->
416 usDeviceTag), 429 usDeviceTag),
417 connector_type, &ddc_bus, 430 connector_type, &ddc_bus,
@@ -427,7 +440,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
427 440
428struct bios_connector { 441struct bios_connector {
429 bool valid; 442 bool valid;
430 uint8_t line_mux; 443 uint16_t line_mux;
431 uint16_t devices; 444 uint16_t devices;
432 int connector_type; 445 int connector_type;
433 struct radeon_i2c_bus_rec ddc_bus; 446 struct radeon_i2c_bus_rec ddc_bus;
@@ -471,11 +484,6 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
471 continue; 484 continue;
472 } 485 }
473 486
474 if (i == ATOM_DEVICE_TV1_INDEX) {
475 DRM_DEBUG("Skipping TV Out\n");
476 continue;
477 }
478
479 bios_connectors[i].connector_type = 487 bios_connectors[i].connector_type =
480 supported_devices_connector_convert[ci.sucConnectorInfo. 488 supported_devices_connector_convert[ci.sucConnectorInfo.
481 sbfAccess. 489 sbfAccess.
@@ -711,9 +719,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
711 return false; 719 return false;
712} 720}
713 721
714struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct 722bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
715 radeon_encoder 723 struct radeon_encoder_int_tmds *tmds)
716 *encoder)
717{ 724{
718 struct drm_device *dev = encoder->base.dev; 725 struct drm_device *dev = encoder->base.dev;
719 struct radeon_device *rdev = dev->dev_private; 726 struct radeon_device *rdev = dev->dev_private;
@@ -724,7 +731,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
724 uint8_t frev, crev; 731 uint8_t frev, crev;
725 uint16_t maxfreq; 732 uint16_t maxfreq;
726 int i; 733 int i;
727 struct radeon_encoder_int_tmds *tmds = NULL;
728 734
729 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 735 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
730 &crev, &data_offset); 736 &crev, &data_offset);
@@ -734,12 +740,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
734 data_offset); 740 data_offset);
735 741
736 if (tmds_info) { 742 if (tmds_info) {
737 tmds =
738 kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
739
740 if (!tmds)
741 return NULL;
742
743 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); 743 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
744 for (i = 0; i < 4; i++) { 744 for (i = 0; i < 4; i++) {
745 tmds->tmds_pll[i].freq = 745 tmds->tmds_pll[i].freq =
@@ -765,8 +765,9 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
765 break; 765 break;
766 } 766 }
767 } 767 }
768 return true;
768 } 769 }
769 return tmds; 770 return false;
770} 771}
771 772
772union lvds_info { 773union lvds_info {
@@ -858,6 +859,72 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
858 return p_dac; 859 return p_dac;
859} 860}
860 861
862bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
863 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
864 int32_t *pixel_clock)
865{
866 struct radeon_mode_info *mode_info = &rdev->mode_info;
867 ATOM_ANALOG_TV_INFO *tv_info;
868 ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;
869 ATOM_DTD_FORMAT *dtd_timings;
870 int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
871 u8 frev, crev;
872 uint16_t data_offset;
873
874 atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
875
876 switch (crev) {
877 case 1:
878 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
879 if (index > MAX_SUPPORTED_TV_TIMING)
880 return false;
881
882 crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
883 crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
884 crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
885 crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
886
887 crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
888 crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
889 crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
890 crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
891
892 crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
893
894 crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
895 crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
896 crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
897 crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
898 *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
899
900 if (index == 1) {
901 /* PAL timings appear to have wrong values for totals */
902 crtc_timing->usH_Total -= 1;
903 crtc_timing->usV_Total -= 1;
904 }
905 break;
906 case 2:
907 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
908 if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
909 return false;
910
911 dtd_timings = &tv_info_v1_2->aModeTimings[index];
912 crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
913 crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
914 crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
915 crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
916 crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
917 crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
918 crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
919 crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
920
921 crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
922 *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
923 break;
924 }
925 return true;
926}
927
861struct radeon_encoder_tv_dac * 928struct radeon_encoder_tv_dac *
862radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) 929radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
863{ 930{
@@ -948,10 +1015,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
948 uint32_t bios_2_scratch, bios_6_scratch; 1015 uint32_t bios_2_scratch, bios_6_scratch;
949 1016
950 if (rdev->family >= CHIP_R600) { 1017 if (rdev->family >= CHIP_R600) {
951 bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH); 1018 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
952 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); 1019 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
953 } else { 1020 } else {
954 bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH); 1021 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
955 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); 1022 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
956 } 1023 }
957 1024
@@ -971,6 +1038,34 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
971 1038
972} 1039}
973 1040
1041void radeon_save_bios_scratch_regs(struct radeon_device *rdev)
1042{
1043 uint32_t scratch_reg;
1044 int i;
1045
1046 if (rdev->family >= CHIP_R600)
1047 scratch_reg = R600_BIOS_0_SCRATCH;
1048 else
1049 scratch_reg = RADEON_BIOS_0_SCRATCH;
1050
1051 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
1052 rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));
1053}
1054
1055void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)
1056{
1057 uint32_t scratch_reg;
1058 int i;
1059
1060 if (rdev->family >= CHIP_R600)
1061 scratch_reg = R600_BIOS_0_SCRATCH;
1062 else
1063 scratch_reg = RADEON_BIOS_0_SCRATCH;
1064
1065 for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
1066 WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);
1067}
1068
974void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) 1069void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
975{ 1070{
976 struct drm_device *dev = encoder->dev; 1071 struct drm_device *dev = encoder->dev;
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index a37cbce53181..152eef13197a 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -102,10 +102,12 @@ void radeon_get_clock_info(struct drm_device *dev)
102 p1pll->reference_div = 12; 102 p1pll->reference_div = 12;
103 if (p2pll->reference_div < 2) 103 if (p2pll->reference_div < 2)
104 p2pll->reference_div = 12; 104 p2pll->reference_div = 12;
105 if (spll->reference_div < 2) 105 if (rdev->family < CHIP_RS600) {
106 spll->reference_div = 106 if (spll->reference_div < 2)
107 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & 107 spll->reference_div =
108 RADEON_M_SPLL_REF_DIV_MASK; 108 RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
109 RADEON_M_SPLL_REF_DIV_MASK;
110 }
109 if (mpll->reference_div < 2) 111 if (mpll->reference_div < 2)
110 mpll->reference_div = spll->reference_div; 112 mpll->reference_div = spll->reference_div;
111 } else { 113 } else {
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 2a027e00762a..748265a105b3 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -863,8 +863,10 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
863 int tmp, i; 863 int tmp, i;
864 struct radeon_encoder_lvds *lvds = NULL; 864 struct radeon_encoder_lvds *lvds = NULL;
865 865
866 if (rdev->bios == NULL) 866 if (rdev->bios == NULL) {
867 return radeon_legacy_get_lvds_info_from_regs(rdev); 867 lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
868 goto out;
869 }
868 870
869 lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); 871 lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
870 872
@@ -965,11 +967,13 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
965 lvds->native_mode.flags = 0; 967 lvds->native_mode.flags = 0;
966 } 968 }
967 } 969 }
968 encoder->native_mode = lvds->native_mode;
969 } else { 970 } else {
970 DRM_INFO("No panel info found in BIOS\n"); 971 DRM_INFO("No panel info found in BIOS\n");
971 return radeon_legacy_get_lvds_info_from_regs(rdev); 972 lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
972 } 973 }
974out:
975 if (lvds)
976 encoder->native_mode = lvds->native_mode;
973 return lvds; 977 return lvds;
974} 978}
975 979
@@ -994,48 +998,37 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
994 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ 998 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */
995}; 999};
996 1000
997static struct radeon_encoder_int_tmds 1001bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
998 *radeon_legacy_get_tmds_info_from_table(struct radeon_device *rdev) 1002 struct radeon_encoder_int_tmds *tmds)
999{ 1003{
1004 struct drm_device *dev = encoder->base.dev;
1005 struct radeon_device *rdev = dev->dev_private;
1000 int i; 1006 int i;
1001 struct radeon_encoder_int_tmds *tmds = NULL;
1002
1003 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1004
1005 if (!tmds)
1006 return NULL;
1007 1007
1008 for (i = 0; i < 4; i++) { 1008 for (i = 0; i < 4; i++) {
1009 tmds->tmds_pll[i].value = 1009 tmds->tmds_pll[i].value =
1010 default_tmds_pll[rdev->family][i].value; 1010 default_tmds_pll[rdev->family][i].value;
1011 tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq; 1011 tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
1012 } 1012 }
1013 1013
1014 return tmds; 1014 return true;
1015} 1015}
1016 1016
1017struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct 1017bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1018 radeon_encoder 1018 struct radeon_encoder_int_tmds *tmds)
1019 *encoder)
1020{ 1019{
1021 struct drm_device *dev = encoder->base.dev; 1020 struct drm_device *dev = encoder->base.dev;
1022 struct radeon_device *rdev = dev->dev_private; 1021 struct radeon_device *rdev = dev->dev_private;
1023 uint16_t tmds_info; 1022 uint16_t tmds_info;
1024 int i, n; 1023 int i, n;
1025 uint8_t ver; 1024 uint8_t ver;
1026 struct radeon_encoder_int_tmds *tmds = NULL;
1027 1025
1028 if (rdev->bios == NULL) 1026 if (rdev->bios == NULL)
1029 return radeon_legacy_get_tmds_info_from_table(rdev); 1027 return false;
1030 1028
1031 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); 1029 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
1032 1030
1033 if (tmds_info) { 1031 if (tmds_info) {
1034 tmds =
1035 kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1036
1037 if (!tmds)
1038 return NULL;
1039 1032
1040 ver = RBIOS8(tmds_info); 1033 ver = RBIOS8(tmds_info);
1041 DRM_INFO("DFP table revision: %d\n", ver); 1034 DRM_INFO("DFP table revision: %d\n", ver);
@@ -1073,6 +1066,23 @@ struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct
1073 } 1066 }
1074 } else 1067 } else
1075 DRM_INFO("No TMDS info found in BIOS\n"); 1068 DRM_INFO("No TMDS info found in BIOS\n");
1069 return true;
1070}
1071
1072struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
1073{
1074 struct radeon_encoder_int_tmds *tmds = NULL;
1075 bool ret;
1076
1077 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1078
1079 if (!tmds)
1080 return NULL;
1081
1082 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
1083 if (ret == false)
1084 radeon_legacy_get_tmds_info_from_table(encoder, tmds);
1085
1076 return tmds; 1086 return tmds;
1077} 1087}
1078 1088
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 70ede6a52d4e..af1d551f1a8f 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -28,6 +28,7 @@
28#include "drm_crtc_helper.h" 28#include "drm_crtc_helper.h"
29#include "radeon_drm.h" 29#include "radeon_drm.h"
30#include "radeon.h" 30#include "radeon.h"
31#include "atom.h"
31 32
32extern void 33extern void
33radeon_combios_connected_scratch_regs(struct drm_connector *connector, 34radeon_combios_connected_scratch_regs(struct drm_connector *connector,
@@ -38,6 +39,15 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
38 struct drm_encoder *encoder, 39 struct drm_encoder *encoder,
39 bool connected); 40 bool connected);
40 41
42static void radeon_property_change_mode(struct drm_encoder *encoder)
43{
44 struct drm_crtc *crtc = encoder->crtc;
45
46 if (crtc && crtc->enabled) {
47 drm_crtc_helper_set_mode(crtc, &crtc->mode,
48 crtc->x, crtc->y, crtc->fb);
49 }
50}
41static void 51static void
42radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) 52radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
43{ 53{
@@ -77,6 +87,27 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
77 } 87 }
78} 88}
79 89
90struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
91{
92 struct drm_mode_object *obj;
93 struct drm_encoder *encoder;
94 int i;
95
96 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
97 if (connector->encoder_ids[i] == 0)
98 break;
99
100 obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
101 if (!obj)
102 continue;
103
104 encoder = obj_to_encoder(obj);
105 if (encoder->encoder_type == encoder_type)
106 return encoder;
107 }
108 return NULL;
109}
110
80struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) 111struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
81{ 112{
82 int enc_id = connector->encoder_ids[0]; 113 int enc_id = connector->encoder_ids[0];
@@ -94,6 +125,53 @@ struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
94 return NULL; 125 return NULL;
95} 126}
96 127
128/*
129 * radeon_connector_analog_encoder_conflict_solve
130 * - search for other connectors sharing this encoder
131 * if priority is true, then set them disconnected if this is connected
132 * if priority is false, set us disconnected if they are connected
133 */
134static enum drm_connector_status
135radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
136 struct drm_encoder *encoder,
137 enum drm_connector_status current_status,
138 bool priority)
139{
140 struct drm_device *dev = connector->dev;
141 struct drm_connector *conflict;
142 int i;
143
144 list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
145 if (conflict == connector)
146 continue;
147
148 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
149 if (conflict->encoder_ids[i] == 0)
150 break;
151
152 /* if the IDs match */
153 if (conflict->encoder_ids[i] == encoder->base.id) {
154 if (conflict->status != connector_status_connected)
155 continue;
156
157 if (priority == true) {
158 DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
159 DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
160 conflict->status = connector_status_disconnected;
161 radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
162 } else {
163 DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
164 DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict));
165 current_status = connector_status_disconnected;
166 }
167 break;
168 }
169 }
170 }
171 return current_status;
172
173}
174
97static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) 175static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
98{ 176{
99 struct drm_device *dev = encoder->dev; 177 struct drm_device *dev = encoder->dev;
@@ -126,12 +204,171 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
126 return mode; 204 return mode;
127} 205}
128 206
207static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector)
208{
209 struct drm_device *dev = encoder->dev;
210 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
211 struct drm_display_mode *mode = NULL;
212 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
213 int i;
214 struct mode_size {
215 int w;
216 int h;
217 } common_modes[17] = {
218 { 640, 480},
219 { 720, 480},
220 { 800, 600},
221 { 848, 480},
222 {1024, 768},
223 {1152, 768},
224 {1280, 720},
225 {1280, 800},
226 {1280, 854},
227 {1280, 960},
228 {1280, 1024},
229 {1440, 900},
230 {1400, 1050},
231 {1680, 1050},
232 {1600, 1200},
233 {1920, 1080},
234 {1920, 1200}
235 };
236
237 for (i = 0; i < 17; i++) {
238 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
239 if (common_modes[i].w > native_mode->panel_xres ||
240 common_modes[i].h > native_mode->panel_yres ||
241 (common_modes[i].w == native_mode->panel_xres &&
242 common_modes[i].h == native_mode->panel_yres))
243 continue;
244 }
245 if (common_modes[i].w < 320 || common_modes[i].h < 200)
246 continue;
247
248 mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false);
249 drm_mode_probed_add(connector, mode);
250 }
251}
252
129int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, 253int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
130 uint64_t val) 254 uint64_t val)
131{ 255{
256 struct drm_device *dev = connector->dev;
257 struct radeon_device *rdev = dev->dev_private;
258 struct drm_encoder *encoder;
259 struct radeon_encoder *radeon_encoder;
260
261 if (property == rdev->mode_info.coherent_mode_property) {
262 struct radeon_encoder_atom_dig *dig;
263
264 /* need to find digital encoder on connector */
265 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
266 if (!encoder)
267 return 0;
268
269 radeon_encoder = to_radeon_encoder(encoder);
270
271 if (!radeon_encoder->enc_priv)
272 return 0;
273
274 dig = radeon_encoder->enc_priv;
275 dig->coherent_mode = val ? true : false;
276 radeon_property_change_mode(&radeon_encoder->base);
277 }
278
279 if (property == rdev->mode_info.tv_std_property) {
280 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
281 if (!encoder) {
282 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC);
283 }
284
285 if (!encoder)
286 return 0;
287
288 radeon_encoder = to_radeon_encoder(encoder);
289 if (!radeon_encoder->enc_priv)
290 return 0;
291 if (rdev->is_atom_bios) {
292 struct radeon_encoder_atom_dac *dac_int;
293 dac_int = radeon_encoder->enc_priv;
294 dac_int->tv_std = val;
295 } else {
296 struct radeon_encoder_tv_dac *dac_int;
297 dac_int = radeon_encoder->enc_priv;
298 dac_int->tv_std = val;
299 }
300 radeon_property_change_mode(&radeon_encoder->base);
301 }
302
303 if (property == rdev->mode_info.load_detect_property) {
304 struct radeon_connector *radeon_connector =
305 to_radeon_connector(connector);
306
307 if (val == 0)
308 radeon_connector->dac_load_detect = false;
309 else
310 radeon_connector->dac_load_detect = true;
311 }
312
313 if (property == rdev->mode_info.tmds_pll_property) {
314 struct radeon_encoder_int_tmds *tmds = NULL;
315 bool ret = false;
316 /* need to find digital encoder on connector */
317 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
318 if (!encoder)
319 return 0;
320
321 radeon_encoder = to_radeon_encoder(encoder);
322
323 tmds = radeon_encoder->enc_priv;
324 if (!tmds)
325 return 0;
326
327 if (val == 0) {
328 if (rdev->is_atom_bios)
329 ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds);
330 else
331 ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds);
332 }
333 if (val == 1 || ret == false) {
334 radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds);
335 }
336 radeon_property_change_mode(&radeon_encoder->base);
337 }
338
132 return 0; 339 return 0;
133} 340}
134 341
342static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
343 struct drm_connector *connector)
344{
345 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
346 struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
347
348 /* Try to get native mode details from EDID if necessary */
349 if (!native_mode->dotclock) {
350 struct drm_display_mode *t, *mode;
351
352 list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
353 if (mode->hdisplay == native_mode->panel_xres &&
354 mode->vdisplay == native_mode->panel_yres) {
355 native_mode->hblank = mode->htotal - mode->hdisplay;
356 native_mode->hoverplus = mode->hsync_start - mode->hdisplay;
357 native_mode->hsync_width = mode->hsync_end - mode->hsync_start;
358 native_mode->vblank = mode->vtotal - mode->vdisplay;
359 native_mode->voverplus = mode->vsync_start - mode->vdisplay;
360 native_mode->vsync_width = mode->vsync_end - mode->vsync_start;
361 native_mode->dotclock = mode->clock;
362 DRM_INFO("Determined LVDS native mode details from EDID\n");
363 break;
364 }
365 }
366 }
367 if (!native_mode->dotclock) {
368 DRM_INFO("No LVDS native mode details, disabling RMX\n");
369 radeon_encoder->rmx_type = RMX_OFF;
370 }
371}
135 372
136static int radeon_lvds_get_modes(struct drm_connector *connector) 373static int radeon_lvds_get_modes(struct drm_connector *connector)
137{ 374{
@@ -143,6 +380,12 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
143 if (radeon_connector->ddc_bus) { 380 if (radeon_connector->ddc_bus) {
144 ret = radeon_ddc_get_modes(radeon_connector); 381 ret = radeon_ddc_get_modes(radeon_connector);
145 if (ret > 0) { 382 if (ret > 0) {
383 encoder = radeon_best_single_encoder(connector);
384 if (encoder) {
385 radeon_fixup_lvds_native_mode(encoder, connector);
386 /* add scaled modes */
387 radeon_add_common_modes(encoder, connector);
388 }
146 return ret; 389 return ret;
147 } 390 }
148 } 391 }
@@ -156,7 +399,10 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
156 if (mode) { 399 if (mode) {
157 ret = 1; 400 ret = 1;
158 drm_mode_probed_add(connector, mode); 401 drm_mode_probed_add(connector, mode);
402 /* add scaled modes */
403 radeon_add_common_modes(encoder, connector);
159 } 404 }
405
160 return ret; 406 return ret;
161} 407}
162 408
@@ -186,6 +432,42 @@ static void radeon_connector_destroy(struct drm_connector *connector)
186 kfree(connector); 432 kfree(connector);
187} 433}
188 434
435static int radeon_lvds_set_property(struct drm_connector *connector,
436 struct drm_property *property,
437 uint64_t value)
438{
439 struct drm_device *dev = connector->dev;
440 struct radeon_encoder *radeon_encoder;
441 enum radeon_rmx_type rmx_type;
442
443 DRM_DEBUG("\n");
444 if (property != dev->mode_config.scaling_mode_property)
445 return 0;
446
447 if (connector->encoder)
448 radeon_encoder = to_radeon_encoder(connector->encoder);
449 else {
450 struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
451 radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
452 }
453
454 switch (value) {
455 case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
456 case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
457 case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
458 default:
459 case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
460 }
461 if (radeon_encoder->rmx_type == rmx_type)
462 return 0;
463
464 radeon_encoder->rmx_type = rmx_type;
465
466 radeon_property_change_mode(&radeon_encoder->base);
467 return 0;
468}
469
470
189struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { 471struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
190 .get_modes = radeon_lvds_get_modes, 472 .get_modes = radeon_lvds_get_modes,
191 .mode_valid = radeon_lvds_mode_valid, 473 .mode_valid = radeon_lvds_mode_valid,
@@ -197,7 +479,7 @@ struct drm_connector_funcs radeon_lvds_connector_funcs = {
197 .detect = radeon_lvds_detect, 479 .detect = radeon_lvds_detect,
198 .fill_modes = drm_helper_probe_single_connector_modes, 480 .fill_modes = drm_helper_probe_single_connector_modes,
199 .destroy = radeon_connector_destroy, 481 .destroy = radeon_connector_destroy,
200 .set_property = radeon_connector_set_property, 482 .set_property = radeon_lvds_set_property,
201}; 483};
202 484
203static int radeon_vga_get_modes(struct drm_connector *connector) 485static int radeon_vga_get_modes(struct drm_connector *connector)
@@ -213,7 +495,6 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
213static int radeon_vga_mode_valid(struct drm_connector *connector, 495static int radeon_vga_mode_valid(struct drm_connector *connector,
214 struct drm_display_mode *mode) 496 struct drm_display_mode *mode)
215{ 497{
216
217 return MODE_OK; 498 return MODE_OK;
218} 499}
219 500
@@ -225,22 +506,24 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
225 bool dret; 506 bool dret;
226 enum drm_connector_status ret = connector_status_disconnected; 507 enum drm_connector_status ret = connector_status_disconnected;
227 508
509 encoder = radeon_best_single_encoder(connector);
510 if (!encoder)
511 ret = connector_status_disconnected;
512
228 radeon_i2c_do_lock(radeon_connector, 1); 513 radeon_i2c_do_lock(radeon_connector, 1);
229 dret = radeon_ddc_probe(radeon_connector); 514 dret = radeon_ddc_probe(radeon_connector);
230 radeon_i2c_do_lock(radeon_connector, 0); 515 radeon_i2c_do_lock(radeon_connector, 0);
231 if (dret) 516 if (dret)
232 ret = connector_status_connected; 517 ret = connector_status_connected;
233 else { 518 else {
234 /* if EDID fails to a load detect */ 519 if (radeon_connector->dac_load_detect) {
235 encoder = radeon_best_single_encoder(connector);
236 if (!encoder)
237 ret = connector_status_disconnected;
238 else {
239 encoder_funcs = encoder->helper_private; 520 encoder_funcs = encoder->helper_private;
240 ret = encoder_funcs->detect(encoder, connector); 521 ret = encoder_funcs->detect(encoder, connector);
241 } 522 }
242 } 523 }
243 524
525 if (ret == connector_status_connected)
526 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
244 radeon_connector_update_scratch_regs(connector, ret); 527 radeon_connector_update_scratch_regs(connector, ret);
245 return ret; 528 return ret;
246} 529}
@@ -259,21 +542,97 @@ struct drm_connector_funcs radeon_vga_connector_funcs = {
259 .set_property = radeon_connector_set_property, 542 .set_property = radeon_connector_set_property,
260}; 543};
261 544
545static int radeon_tv_get_modes(struct drm_connector *connector)
546{
547 struct drm_device *dev = connector->dev;
548 struct radeon_device *rdev = dev->dev_private;
549 struct drm_display_mode *tv_mode;
550 struct drm_encoder *encoder;
551
552 encoder = radeon_best_single_encoder(connector);
553 if (!encoder)
554 return 0;
555
556 /* avivo chips can scale any mode */
557 if (rdev->family >= CHIP_RS600)
558 /* add scaled modes */
559 radeon_add_common_modes(encoder, connector);
560 else {
561 /* only 800x600 is supported right now on pre-avivo chips */
562 tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false);
563 tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
564 drm_mode_probed_add(connector, tv_mode);
565 }
566 return 1;
567}
568
569static int radeon_tv_mode_valid(struct drm_connector *connector,
570 struct drm_display_mode *mode)
571{
572 return MODE_OK;
573}
574
575static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
576{
577 struct drm_encoder *encoder;
578 struct drm_encoder_helper_funcs *encoder_funcs;
579 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
580 enum drm_connector_status ret = connector_status_disconnected;
581
582 if (!radeon_connector->dac_load_detect)
583 return ret;
584
585 encoder = radeon_best_single_encoder(connector);
586 if (!encoder)
587 ret = connector_status_disconnected;
588 else {
589 encoder_funcs = encoder->helper_private;
590 ret = encoder_funcs->detect(encoder, connector);
591 }
592 if (ret == connector_status_connected)
593 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
594 radeon_connector_update_scratch_regs(connector, ret);
595 return ret;
596}
597
598struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
599 .get_modes = radeon_tv_get_modes,
600 .mode_valid = radeon_tv_mode_valid,
601 .best_encoder = radeon_best_single_encoder,
602};
603
604struct drm_connector_funcs radeon_tv_connector_funcs = {
605 .dpms = drm_helper_connector_dpms,
606 .detect = radeon_tv_detect,
607 .fill_modes = drm_helper_probe_single_connector_modes,
608 .destroy = radeon_connector_destroy,
609 .set_property = radeon_connector_set_property,
610};
611
262static int radeon_dvi_get_modes(struct drm_connector *connector) 612static int radeon_dvi_get_modes(struct drm_connector *connector)
263{ 613{
264 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 614 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
265 int ret; 615 int ret;
266 616
267 ret = radeon_ddc_get_modes(radeon_connector); 617 ret = radeon_ddc_get_modes(radeon_connector);
268 /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */
269 radeon_connector_update_scratch_regs(connector, connector_status_connected);
270 return ret; 618 return ret;
271} 619}
272 620
621/*
622 * DVI is complicated
623 * Do a DDC probe, if DDC probe passes, get the full EDID so
624 * we can do analog/digital monitor detection at this point.
625 * If the monitor is an analog monitor or we got no DDC,
626 * we need to find the DAC encoder object for this connector.
627 * If we got no DDC, we do load detection on the DAC encoder object.
628 * If we got analog DDC or load detection passes on the DAC encoder
629 * we have to check if this analog encoder is shared with anyone else (TV)
630 * if its shared we have to set the other connector to disconnected.
631 */
273static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) 632static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
274{ 633{
275 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 634 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
276 struct drm_encoder *encoder; 635 struct drm_encoder *encoder = NULL;
277 struct drm_encoder_helper_funcs *encoder_funcs; 636 struct drm_encoder_helper_funcs *encoder_funcs;
278 struct drm_mode_object *obj; 637 struct drm_mode_object *obj;
279 int i; 638 int i;
@@ -283,9 +642,29 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
283 radeon_i2c_do_lock(radeon_connector, 1); 642 radeon_i2c_do_lock(radeon_connector, 1);
284 dret = radeon_ddc_probe(radeon_connector); 643 dret = radeon_ddc_probe(radeon_connector);
285 radeon_i2c_do_lock(radeon_connector, 0); 644 radeon_i2c_do_lock(radeon_connector, 0);
286 if (dret) 645 if (dret) {
287 ret = connector_status_connected; 646 radeon_i2c_do_lock(radeon_connector, 1);
288 else { 647 radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
648 radeon_i2c_do_lock(radeon_connector, 0);
649
650 if (!radeon_connector->edid) {
651 DRM_ERROR("DDC responded but not EDID found for %s\n",
652 drm_get_connector_name(connector));
653 } else {
654 radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
655
656 /* if this isn't a digital monitor
657 then we need to make sure we don't have any
658 TV conflicts */
659 ret = connector_status_connected;
660 }
661 }
662
663 if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
664 goto out;
665
666 /* find analog encoder */
667 if (radeon_connector->dac_load_detect) {
289 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 668 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
290 if (connector->encoder_ids[i] == 0) 669 if (connector->encoder_ids[i] == 0)
291 break; 670 break;
@@ -300,15 +679,23 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
300 679
301 encoder_funcs = encoder->helper_private; 680 encoder_funcs = encoder->helper_private;
302 if (encoder_funcs->detect) { 681 if (encoder_funcs->detect) {
303 ret = encoder_funcs->detect(encoder, connector); 682 if (ret != connector_status_connected) {
304 if (ret == connector_status_connected) { 683 ret = encoder_funcs->detect(encoder, connector);
305 radeon_connector->use_digital = 0; 684 if (ret == connector_status_connected) {
306 break; 685 radeon_connector->use_digital = false;
686 }
307 } 687 }
688 break;
308 } 689 }
309 } 690 }
310 } 691 }
311 692
693 if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
694 encoder) {
695 ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
696 }
697
698out:
312 /* updated in get modes as well since we need to know if it's analog or digital */ 699 /* updated in get modes as well since we need to know if it's analog or digital */
313 radeon_connector_update_scratch_regs(connector, ret); 700 radeon_connector_update_scratch_regs(connector, ret);
314 return ret; 701 return ret;
@@ -332,7 +719,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
332 719
333 encoder = obj_to_encoder(obj); 720 encoder = obj_to_encoder(obj);
334 721
335 if (radeon_connector->use_digital) { 722 if (radeon_connector->use_digital == true) {
336 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) 723 if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
337 return encoder; 724 return encoder;
338 } else { 725 } else {
@@ -379,16 +766,14 @@ radeon_add_atom_connector(struct drm_device *dev,
379 bool linkb, 766 bool linkb,
380 uint32_t igp_lane_info) 767 uint32_t igp_lane_info)
381{ 768{
769 struct radeon_device *rdev = dev->dev_private;
382 struct drm_connector *connector; 770 struct drm_connector *connector;
383 struct radeon_connector *radeon_connector; 771 struct radeon_connector *radeon_connector;
384 struct radeon_connector_atom_dig *radeon_dig_connector; 772 struct radeon_connector_atom_dig *radeon_dig_connector;
385 uint32_t subpixel_order = SubPixelNone; 773 uint32_t subpixel_order = SubPixelNone;
386 774
387 /* fixme - tv/cv/din */ 775 /* fixme - tv/cv/din */
388 if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || 776 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
389 (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
390 (connector_type == DRM_MODE_CONNECTOR_Composite) ||
391 (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
392 return; 777 return;
393 778
394 /* see if we already added it */ 779 /* see if we already added it */
@@ -417,6 +802,9 @@ radeon_add_atom_connector(struct drm_device *dev,
417 if (!radeon_connector->ddc_bus) 802 if (!radeon_connector->ddc_bus)
418 goto failed; 803 goto failed;
419 } 804 }
805 drm_connector_attach_property(&radeon_connector->base,
806 rdev->mode_info.load_detect_property,
807 1);
420 break; 808 break;
421 case DRM_MODE_CONNECTOR_DVIA: 809 case DRM_MODE_CONNECTOR_DVIA:
422 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 810 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -426,6 +814,9 @@ radeon_add_atom_connector(struct drm_device *dev,
426 if (!radeon_connector->ddc_bus) 814 if (!radeon_connector->ddc_bus)
427 goto failed; 815 goto failed;
428 } 816 }
817 drm_connector_attach_property(&radeon_connector->base,
818 rdev->mode_info.load_detect_property,
819 1);
429 break; 820 break;
430 case DRM_MODE_CONNECTOR_DVII: 821 case DRM_MODE_CONNECTOR_DVII:
431 case DRM_MODE_CONNECTOR_DVID: 822 case DRM_MODE_CONNECTOR_DVID:
@@ -443,6 +834,12 @@ radeon_add_atom_connector(struct drm_device *dev,
443 goto failed; 834 goto failed;
444 } 835 }
445 subpixel_order = SubPixelHorizontalRGB; 836 subpixel_order = SubPixelHorizontalRGB;
837 drm_connector_attach_property(&radeon_connector->base,
838 rdev->mode_info.coherent_mode_property,
839 1);
840 drm_connector_attach_property(&radeon_connector->base,
841 rdev->mode_info.load_detect_property,
842 1);
446 break; 843 break;
447 case DRM_MODE_CONNECTOR_HDMIA: 844 case DRM_MODE_CONNECTOR_HDMIA:
448 case DRM_MODE_CONNECTOR_HDMIB: 845 case DRM_MODE_CONNECTOR_HDMIB:
@@ -459,6 +856,9 @@ radeon_add_atom_connector(struct drm_device *dev,
459 if (!radeon_connector->ddc_bus) 856 if (!radeon_connector->ddc_bus)
460 goto failed; 857 goto failed;
461 } 858 }
859 drm_connector_attach_property(&radeon_connector->base,
860 rdev->mode_info.coherent_mode_property,
861 1);
462 subpixel_order = SubPixelHorizontalRGB; 862 subpixel_order = SubPixelHorizontalRGB;
463 break; 863 break;
464 case DRM_MODE_CONNECTOR_DisplayPort: 864 case DRM_MODE_CONNECTOR_DisplayPort:
@@ -480,6 +880,13 @@ radeon_add_atom_connector(struct drm_device *dev,
480 case DRM_MODE_CONNECTOR_SVIDEO: 880 case DRM_MODE_CONNECTOR_SVIDEO:
481 case DRM_MODE_CONNECTOR_Composite: 881 case DRM_MODE_CONNECTOR_Composite:
482 case DRM_MODE_CONNECTOR_9PinDIN: 882 case DRM_MODE_CONNECTOR_9PinDIN:
883 if (radeon_tv == 1) {
884 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
885 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
886 }
887 drm_connector_attach_property(&radeon_connector->base,
888 rdev->mode_info.load_detect_property,
889 1);
483 break; 890 break;
484 case DRM_MODE_CONNECTOR_LVDS: 891 case DRM_MODE_CONNECTOR_LVDS:
485 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); 892 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -495,6 +902,10 @@ radeon_add_atom_connector(struct drm_device *dev,
495 if (!radeon_connector->ddc_bus) 902 if (!radeon_connector->ddc_bus)
496 goto failed; 903 goto failed;
497 } 904 }
905 drm_mode_create_scaling_mode_property(dev);
906 drm_connector_attach_property(&radeon_connector->base,
907 dev->mode_config.scaling_mode_property,
908 DRM_MODE_SCALE_FULLSCREEN);
498 subpixel_order = SubPixelHorizontalRGB; 909 subpixel_order = SubPixelHorizontalRGB;
499 break; 910 break;
500 } 911 }
@@ -517,15 +928,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
517 int connector_type, 928 int connector_type,
518 struct radeon_i2c_bus_rec *i2c_bus) 929 struct radeon_i2c_bus_rec *i2c_bus)
519{ 930{
931 struct radeon_device *rdev = dev->dev_private;
520 struct drm_connector *connector; 932 struct drm_connector *connector;
521 struct radeon_connector *radeon_connector; 933 struct radeon_connector *radeon_connector;
522 uint32_t subpixel_order = SubPixelNone; 934 uint32_t subpixel_order = SubPixelNone;
523 935
524 /* fixme - tv/cv/din */ 936 /* fixme - tv/cv/din */
525 if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || 937 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
526 (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
527 (connector_type == DRM_MODE_CONNECTOR_Composite) ||
528 (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
529 return; 938 return;
530 939
531 /* see if we already added it */ 940 /* see if we already added it */
@@ -554,6 +963,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
554 if (!radeon_connector->ddc_bus) 963 if (!radeon_connector->ddc_bus)
555 goto failed; 964 goto failed;
556 } 965 }
966 drm_connector_attach_property(&radeon_connector->base,
967 rdev->mode_info.load_detect_property,
968 1);
557 break; 969 break;
558 case DRM_MODE_CONNECTOR_DVIA: 970 case DRM_MODE_CONNECTOR_DVIA:
559 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 971 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -563,6 +975,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
563 if (!radeon_connector->ddc_bus) 975 if (!radeon_connector->ddc_bus)
564 goto failed; 976 goto failed;
565 } 977 }
978 drm_connector_attach_property(&radeon_connector->base,
979 rdev->mode_info.load_detect_property,
980 1);
566 break; 981 break;
567 case DRM_MODE_CONNECTOR_DVII: 982 case DRM_MODE_CONNECTOR_DVII:
568 case DRM_MODE_CONNECTOR_DVID: 983 case DRM_MODE_CONNECTOR_DVID:
@@ -572,12 +987,22 @@ radeon_add_legacy_connector(struct drm_device *dev,
572 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 987 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
573 if (!radeon_connector->ddc_bus) 988 if (!radeon_connector->ddc_bus)
574 goto failed; 989 goto failed;
990 drm_connector_attach_property(&radeon_connector->base,
991 rdev->mode_info.load_detect_property,
992 1);
575 } 993 }
576 subpixel_order = SubPixelHorizontalRGB; 994 subpixel_order = SubPixelHorizontalRGB;
577 break; 995 break;
578 case DRM_MODE_CONNECTOR_SVIDEO: 996 case DRM_MODE_CONNECTOR_SVIDEO:
579 case DRM_MODE_CONNECTOR_Composite: 997 case DRM_MODE_CONNECTOR_Composite:
580 case DRM_MODE_CONNECTOR_9PinDIN: 998 case DRM_MODE_CONNECTOR_9PinDIN:
999 if (radeon_tv == 1) {
1000 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1001 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1002 drm_connector_attach_property(&radeon_connector->base,
1003 rdev->mode_info.load_detect_property,
1004 1);
1005 }
581 break; 1006 break;
582 case DRM_MODE_CONNECTOR_LVDS: 1007 case DRM_MODE_CONNECTOR_LVDS:
583 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); 1008 drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -587,6 +1012,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
587 if (!radeon_connector->ddc_bus) 1012 if (!radeon_connector->ddc_bus)
588 goto failed; 1013 goto failed;
589 } 1014 }
1015 drm_connector_attach_property(&radeon_connector->base,
1016 dev->mode_config.scaling_mode_property,
1017 DRM_MODE_SCALE_FULLSCREEN);
590 subpixel_order = SubPixelHorizontalRGB; 1018 subpixel_order = SubPixelHorizontalRGB;
591 break; 1019 break;
592 } 1020 }
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 7a52c461145c..4f7afc79dd82 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -36,10 +36,25 @@
36#include "radeon_drv.h" 36#include "radeon_drv.h"
37#include "r300_reg.h" 37#include "r300_reg.h"
38 38
39#include "radeon_microcode.h"
40
41#define RADEON_FIFO_DEBUG 0 39#define RADEON_FIFO_DEBUG 0
42 40
41/* Firmware Names */
42#define FIRMWARE_R100 "radeon/R100_cp.bin"
43#define FIRMWARE_R200 "radeon/R200_cp.bin"
44#define FIRMWARE_R300 "radeon/R300_cp.bin"
45#define FIRMWARE_R420 "radeon/R420_cp.bin"
46#define FIRMWARE_RS690 "radeon/RS690_cp.bin"
47#define FIRMWARE_RS600 "radeon/RS600_cp.bin"
48#define FIRMWARE_R520 "radeon/R520_cp.bin"
49
50MODULE_FIRMWARE(FIRMWARE_R100);
51MODULE_FIRMWARE(FIRMWARE_R200);
52MODULE_FIRMWARE(FIRMWARE_R300);
53MODULE_FIRMWARE(FIRMWARE_R420);
54MODULE_FIRMWARE(FIRMWARE_RS690);
55MODULE_FIRMWARE(FIRMWARE_RS600);
56MODULE_FIRMWARE(FIRMWARE_R520);
57
43static int radeon_do_cleanup_cp(struct drm_device * dev); 58static int radeon_do_cleanup_cp(struct drm_device * dev);
44static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); 59static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
45 60
@@ -460,37 +475,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
460 */ 475 */
461 476
462/* Load the microcode for the CP */ 477/* Load the microcode for the CP */
463static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) 478static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv)
464{ 479{
465 int i; 480 struct platform_device *pdev;
481 const char *fw_name = NULL;
482 int err;
483
466 DRM_DEBUG("\n"); 484 DRM_DEBUG("\n");
467 485
468 radeon_do_wait_for_idle(dev_priv); 486 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
487 err = IS_ERR(pdev);
488 if (err) {
489 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
490 return -EINVAL;
491 }
469 492
470 RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
471 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || 493 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
472 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || 494 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
473 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || 495 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
474 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || 496 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
475 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { 497 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
476 DRM_INFO("Loading R100 Microcode\n"); 498 DRM_INFO("Loading R100 Microcode\n");
477 for (i = 0; i < 256; i++) { 499 fw_name = FIRMWARE_R100;
478 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
479 R100_cp_microcode[i][1]);
480 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
481 R100_cp_microcode[i][0]);
482 }
483 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || 500 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
484 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || 501 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
485 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || 502 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
486 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { 503 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
487 DRM_INFO("Loading R200 Microcode\n"); 504 DRM_INFO("Loading R200 Microcode\n");
488 for (i = 0; i < 256; i++) { 505 fw_name = FIRMWARE_R200;
489 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
490 R200_cp_microcode[i][1]);
491 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
492 R200_cp_microcode[i][0]);
493 }
494 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || 506 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
495 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || 507 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
496 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || 508 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
@@ -498,39 +510,19 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
498 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || 510 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
499 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { 511 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
500 DRM_INFO("Loading R300 Microcode\n"); 512 DRM_INFO("Loading R300 Microcode\n");
501 for (i = 0; i < 256; i++) { 513 fw_name = FIRMWARE_R300;
502 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
503 R300_cp_microcode[i][1]);
504 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
505 R300_cp_microcode[i][0]);
506 }
507 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || 514 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
508 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || 515 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) ||
509 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { 516 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
510 DRM_INFO("Loading R400 Microcode\n"); 517 DRM_INFO("Loading R400 Microcode\n");
511 for (i = 0; i < 256; i++) { 518 fw_name = FIRMWARE_R420;
512 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
513 R420_cp_microcode[i][1]);
514 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
515 R420_cp_microcode[i][0]);
516 }
517 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || 519 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
518 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { 520 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
519 DRM_INFO("Loading RS690/RS740 Microcode\n"); 521 DRM_INFO("Loading RS690/RS740 Microcode\n");
520 for (i = 0; i < 256; i++) { 522 fw_name = FIRMWARE_RS690;
521 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
522 RS690_cp_microcode[i][1]);
523 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
524 RS690_cp_microcode[i][0]);
525 }
526 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { 523 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
527 DRM_INFO("Loading RS600 Microcode\n"); 524 DRM_INFO("Loading RS600 Microcode\n");
528 for (i = 0; i < 256; i++) { 525 fw_name = FIRMWARE_RS600;
529 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
530 RS600_cp_microcode[i][1]);
531 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
532 RS600_cp_microcode[i][0]);
533 }
534 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || 526 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
535 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || 527 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
536 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || 528 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
@@ -538,11 +530,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
538 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || 530 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
539 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { 531 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
540 DRM_INFO("Loading R500 Microcode\n"); 532 DRM_INFO("Loading R500 Microcode\n");
541 for (i = 0; i < 256; i++) { 533 fw_name = FIRMWARE_R520;
534 }
535
536 err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev);
537 platform_device_unregister(pdev);
538 if (err) {
539 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
540 fw_name);
541 } else if (dev_priv->me_fw->size % 8) {
542 printk(KERN_ERR
543 "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
544 dev_priv->me_fw->size, fw_name);
545 err = -EINVAL;
546 release_firmware(dev_priv->me_fw);
547 dev_priv->me_fw = NULL;
548 }
549 return err;
550}
551
552static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv)
553{
554 const __be32 *fw_data;
555 int i, size;
556
557 radeon_do_wait_for_idle(dev_priv);
558
559 if (dev_priv->me_fw) {
560 size = dev_priv->me_fw->size / 4;
561 fw_data = (const __be32 *)&dev_priv->me_fw->data[0];
562 RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
563 for (i = 0; i < size; i += 2) {
542 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, 564 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
543 R520_cp_microcode[i][1]); 565 be32_to_cpup(&fw_data[i]));
544 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, 566 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
545 R520_cp_microcode[i][0]); 567 be32_to_cpup(&fw_data[i + 1]));
546 } 568 }
547 } 569 }
548} 570}
@@ -594,6 +616,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
594 616
595 dev_priv->cp_running = 1; 617 dev_priv->cp_running = 1;
596 618
619 /* on r420, any DMA from CP to system memory while 2D is active
620 * can cause a hang. workaround is to queue a CP RESYNC token
621 */
622 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
623 BEGIN_RING(3);
624 OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
625 OUT_RING(5); /* scratch reg 5 */
626 OUT_RING(0xdeadbeef);
627 ADVANCE_RING();
628 COMMIT_RING();
629 }
630
597 BEGIN_RING(8); 631 BEGIN_RING(8);
598 /* isync can only be written through cp on r5xx write it here */ 632 /* isync can only be written through cp on r5xx write it here */
599 OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); 633 OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
@@ -631,8 +665,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
631 */ 665 */
632static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) 666static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
633{ 667{
668 RING_LOCALS;
634 DRM_DEBUG("\n"); 669 DRM_DEBUG("\n");
635 670
671 /* finish the pending CP_RESYNC token */
672 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
673 BEGIN_RING(2);
674 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
675 OUT_RING(R300_RB3D_DC_FINISH);
676 ADVANCE_RING();
677 COMMIT_RING();
678 radeon_do_wait_for_idle(dev_priv);
679 }
680
636 RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); 681 RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
637 682
638 dev_priv->cp_running = 0; 683 dev_priv->cp_running = 0;
@@ -1495,6 +1540,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
1495 radeon_set_pcigart(dev_priv, 1); 1540 radeon_set_pcigart(dev_priv, 1);
1496 } 1541 }
1497 1542
1543 if (!dev_priv->me_fw) {
1544 int err = radeon_cp_init_microcode(dev_priv);
1545 if (err) {
1546 DRM_ERROR("Failed to load firmware!\n");
1547 radeon_do_cleanup_cp(dev);
1548 return err;
1549 }
1550 }
1498 radeon_cp_load_microcode(dev_priv); 1551 radeon_cp_load_microcode(dev_priv);
1499 radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); 1552 radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
1500 1553
@@ -1764,6 +1817,14 @@ void radeon_do_release(struct drm_device * dev)
1764 r600_do_cleanup_cp(dev); 1817 r600_do_cleanup_cp(dev);
1765 else 1818 else
1766 radeon_do_cleanup_cp(dev); 1819 radeon_do_cleanup_cp(dev);
1820 if (dev_priv->me_fw) {
1821 release_firmware(dev_priv->me_fw);
1822 dev_priv->me_fw = NULL;
1823 }
1824 if (dev_priv->pfp_fw) {
1825 release_firmware(dev_priv->pfp_fw);
1826 dev_priv->pfp_fw = NULL;
1827 }
1767 } 1828 }
1768} 1829}
1769 1830
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index a169067efc4e..12f5990c2d2a 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -145,7 +145,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
145 cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; 145 cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
146 146
147 size = p->chunks[i].length_dw * sizeof(uint32_t); 147 size = p->chunks[i].length_dw * sizeof(uint32_t);
148 p->chunks[i].kdata = kzalloc(size, GFP_KERNEL); 148 p->chunks[i].kdata = kmalloc(size, GFP_KERNEL);
149 if (p->chunks[i].kdata == NULL) { 149 if (p->chunks[i].kdata == NULL) {
150 return -ENOMEM; 150 return -ENOMEM;
151 } 151 }
@@ -185,6 +185,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
185 mutex_unlock(&parser->rdev->ddev->struct_mutex); 185 mutex_unlock(&parser->rdev->ddev->struct_mutex);
186 } 186 }
187 } 187 }
188 kfree(parser->track);
188 kfree(parser->relocs); 189 kfree(parser->relocs);
189 kfree(parser->relocs_ptr); 190 kfree(parser->relocs_ptr);
190 for (i = 0; i < parser->nchunks; i++) { 191 for (i = 0; i < parser->nchunks; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 7693f7c67bd3..daf5db780956 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -29,6 +29,7 @@
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include <drm/drm_crtc_helper.h> 30#include <drm/drm_crtc_helper.h>
31#include <drm/radeon_drm.h> 31#include <drm/radeon_drm.h>
32#include <linux/vgaarb.h>
32#include "radeon_reg.h" 33#include "radeon_reg.h"
33#include "radeon.h" 34#include "radeon.h"
34#include "radeon_asic.h" 35#include "radeon_asic.h"
@@ -37,7 +38,7 @@
37/* 38/*
38 * Clear GPU surface registers. 39 * Clear GPU surface registers.
39 */ 40 */
40static void radeon_surface_init(struct radeon_device *rdev) 41void radeon_surface_init(struct radeon_device *rdev)
41{ 42{
42 /* FIXME: check this out */ 43 /* FIXME: check this out */
43 if (rdev->family < CHIP_R600) { 44 if (rdev->family < CHIP_R600) {
@@ -56,7 +57,7 @@ static void radeon_surface_init(struct radeon_device *rdev)
56/* 57/*
57 * GPU scratch registers helpers function. 58 * GPU scratch registers helpers function.
58 */ 59 */
59static void radeon_scratch_init(struct radeon_device *rdev) 60void radeon_scratch_init(struct radeon_device *rdev)
60{ 61{
61 int i; 62 int i;
62 63
@@ -156,16 +157,18 @@ int radeon_mc_setup(struct radeon_device *rdev)
156 tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); 157 tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
157 rdev->mc.gtt_location = tmp; 158 rdev->mc.gtt_location = tmp;
158 } 159 }
159 DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20); 160 rdev->mc.vram_start = rdev->mc.vram_location;
161 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
162 rdev->mc.gtt_start = rdev->mc.gtt_location;
163 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
164 DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20));
160 DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", 165 DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
161 rdev->mc.vram_location, 166 (unsigned)rdev->mc.vram_location,
162 rdev->mc.vram_location + rdev->mc.mc_vram_size - 1); 167 (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1));
163 if (rdev->mc.real_vram_size != rdev->mc.mc_vram_size) 168 DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20));
164 DRM_INFO("radeon: VRAM less than aperture workaround enabled\n");
165 DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
166 DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n", 169 DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
167 rdev->mc.gtt_location, 170 (unsigned)rdev->mc.gtt_location,
168 rdev->mc.gtt_location + rdev->mc.gtt_size - 1); 171 (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1));
169 return 0; 172 return 0;
170} 173}
171 174
@@ -173,7 +176,7 @@ int radeon_mc_setup(struct radeon_device *rdev)
173/* 176/*
174 * GPU helpers function. 177 * GPU helpers function.
175 */ 178 */
176static bool radeon_card_posted(struct radeon_device *rdev) 179bool radeon_card_posted(struct radeon_device *rdev)
177{ 180{
178 uint32_t reg; 181 uint32_t reg;
179 182
@@ -205,6 +208,31 @@ static bool radeon_card_posted(struct radeon_device *rdev)
205 208
206} 209}
207 210
211int radeon_dummy_page_init(struct radeon_device *rdev)
212{
213 rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
214 if (rdev->dummy_page.page == NULL)
215 return -ENOMEM;
216 rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page,
217 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
218 if (!rdev->dummy_page.addr) {
219 __free_page(rdev->dummy_page.page);
220 rdev->dummy_page.page = NULL;
221 return -ENOMEM;
222 }
223 return 0;
224}
225
226void radeon_dummy_page_fini(struct radeon_device *rdev)
227{
228 if (rdev->dummy_page.page == NULL)
229 return;
230 pci_unmap_page(rdev->pdev, rdev->dummy_page.addr,
231 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
232 __free_page(rdev->dummy_page.page);
233 rdev->dummy_page.page = NULL;
234}
235
208 236
209/* 237/*
210 * Registers accessors functions. 238 * Registers accessors functions.
@@ -243,6 +271,10 @@ void radeon_register_accessor_init(struct radeon_device *rdev)
243 rdev->pll_rreg = &r100_pll_rreg; 271 rdev->pll_rreg = &r100_pll_rreg;
244 rdev->pll_wreg = &r100_pll_wreg; 272 rdev->pll_wreg = &r100_pll_wreg;
245 } 273 }
274 if (rdev->family >= CHIP_R420) {
275 rdev->mc_rreg = &r420_mc_rreg;
276 rdev->mc_wreg = &r420_mc_wreg;
277 }
246 if (rdev->family >= CHIP_RV515) { 278 if (rdev->family >= CHIP_RV515) {
247 rdev->mc_rreg = &rv515_mc_rreg; 279 rdev->mc_rreg = &rv515_mc_rreg;
248 rdev->mc_wreg = &rv515_mc_wreg; 280 rdev->mc_wreg = &rv515_mc_wreg;
@@ -289,6 +321,14 @@ int radeon_asic_init(struct radeon_device *rdev)
289 case CHIP_RV350: 321 case CHIP_RV350:
290 case CHIP_RV380: 322 case CHIP_RV380:
291 rdev->asic = &r300_asic; 323 rdev->asic = &r300_asic;
324 if (rdev->flags & RADEON_IS_PCIE) {
325 rdev->asic->gart_init = &rv370_pcie_gart_init;
326 rdev->asic->gart_fini = &rv370_pcie_gart_fini;
327 rdev->asic->gart_enable = &rv370_pcie_gart_enable;
328 rdev->asic->gart_disable = &rv370_pcie_gart_disable;
329 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
330 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
331 }
292 break; 332 break;
293 case CHIP_R420: 333 case CHIP_R420:
294 case CHIP_R423: 334 case CHIP_R423:
@@ -323,9 +363,15 @@ int radeon_asic_init(struct radeon_device *rdev)
323 case CHIP_RV635: 363 case CHIP_RV635:
324 case CHIP_RV670: 364 case CHIP_RV670:
325 case CHIP_RS780: 365 case CHIP_RS780:
366 case CHIP_RS880:
367 rdev->asic = &r600_asic;
368 break;
326 case CHIP_RV770: 369 case CHIP_RV770:
327 case CHIP_RV730: 370 case CHIP_RV730:
328 case CHIP_RV710: 371 case CHIP_RV710:
372 case CHIP_RV740:
373 rdev->asic = &rv770_asic;
374 break;
329 default: 375 default:
330 /* FIXME: not supported yet */ 376 /* FIXME: not supported yet */
331 return -EINVAL; 377 return -EINVAL;
@@ -341,7 +387,6 @@ int radeon_clocks_init(struct radeon_device *rdev)
341{ 387{
342 int r; 388 int r;
343 389
344 radeon_get_clock_info(rdev->ddev);
345 r = radeon_static_clocks_init(rdev->ddev); 390 r = radeon_static_clocks_init(rdev->ddev);
346 if (r) { 391 if (r) {
347 return r; 392 return r;
@@ -436,10 +481,18 @@ void radeon_combios_fini(struct radeon_device *rdev)
436{ 481{
437} 482}
438 483
439int radeon_modeset_init(struct radeon_device *rdev); 484/* if we get transitioned to only one device, tak VGA back */
440void radeon_modeset_fini(struct radeon_device *rdev); 485static unsigned int radeon_vga_set_decode(void *cookie, bool state)
441 486{
487 struct radeon_device *rdev = cookie;
442 488
489 radeon_vga_set_state(rdev, state);
490 if (state)
491 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
492 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
493 else
494 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
495}
443/* 496/*
444 * Radeon device. 497 * Radeon device.
445 */ 498 */
@@ -448,11 +501,12 @@ int radeon_device_init(struct radeon_device *rdev,
448 struct pci_dev *pdev, 501 struct pci_dev *pdev,
449 uint32_t flags) 502 uint32_t flags)
450{ 503{
451 int r, ret; 504 int r;
452 int dma_bits; 505 int dma_bits;
453 506
454 DRM_INFO("radeon: Initializing kernel modesetting.\n"); 507 DRM_INFO("radeon: Initializing kernel modesetting.\n");
455 rdev->shutdown = false; 508 rdev->shutdown = false;
509 rdev->dev = &pdev->dev;
456 rdev->ddev = ddev; 510 rdev->ddev = ddev;
457 rdev->pdev = pdev; 511 rdev->pdev = pdev;
458 rdev->flags = flags; 512 rdev->flags = flags;
@@ -461,37 +515,47 @@ int radeon_device_init(struct radeon_device *rdev,
461 rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; 515 rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
462 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; 516 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
463 rdev->gpu_lockup = false; 517 rdev->gpu_lockup = false;
518 rdev->accel_working = false;
464 /* mutex initialization are all done here so we 519 /* mutex initialization are all done here so we
465 * can recall function without having locking issues */ 520 * can recall function without having locking issues */
466 mutex_init(&rdev->cs_mutex); 521 mutex_init(&rdev->cs_mutex);
467 mutex_init(&rdev->ib_pool.mutex); 522 mutex_init(&rdev->ib_pool.mutex);
468 mutex_init(&rdev->cp.mutex); 523 mutex_init(&rdev->cp.mutex);
469 rwlock_init(&rdev->fence_drv.lock); 524 rwlock_init(&rdev->fence_drv.lock);
525 INIT_LIST_HEAD(&rdev->gem.objects);
526
527 /* Set asic functions */
528 r = radeon_asic_init(rdev);
529 if (r) {
530 return r;
531 }
470 532
471 if (radeon_agpmode == -1) { 533 if (radeon_agpmode == -1) {
472 rdev->flags &= ~RADEON_IS_AGP; 534 rdev->flags &= ~RADEON_IS_AGP;
473 if (rdev->family > CHIP_RV515 || 535 if (rdev->family >= CHIP_RV515 ||
474 rdev->family == CHIP_RV380 || 536 rdev->family == CHIP_RV380 ||
475 rdev->family == CHIP_RV410 || 537 rdev->family == CHIP_RV410 ||
476 rdev->family == CHIP_R423) { 538 rdev->family == CHIP_R423) {
477 DRM_INFO("Forcing AGP to PCIE mode\n"); 539 DRM_INFO("Forcing AGP to PCIE mode\n");
478 rdev->flags |= RADEON_IS_PCIE; 540 rdev->flags |= RADEON_IS_PCIE;
541 rdev->asic->gart_init = &rv370_pcie_gart_init;
542 rdev->asic->gart_fini = &rv370_pcie_gart_fini;
543 rdev->asic->gart_enable = &rv370_pcie_gart_enable;
544 rdev->asic->gart_disable = &rv370_pcie_gart_disable;
545 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
546 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
479 } else { 547 } else {
480 DRM_INFO("Forcing AGP to PCI mode\n"); 548 DRM_INFO("Forcing AGP to PCI mode\n");
481 rdev->flags |= RADEON_IS_PCI; 549 rdev->flags |= RADEON_IS_PCI;
550 rdev->asic->gart_init = &r100_pci_gart_init;
551 rdev->asic->gart_fini = &r100_pci_gart_fini;
552 rdev->asic->gart_enable = &r100_pci_gart_enable;
553 rdev->asic->gart_disable = &r100_pci_gart_disable;
554 rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
555 rdev->asic->gart_set_page = &r100_pci_gart_set_page;
482 } 556 }
483 } 557 }
484 558
485 /* Set asic functions */
486 r = radeon_asic_init(rdev);
487 if (r) {
488 return r;
489 }
490 r = radeon_init(rdev);
491 if (r) {
492 return r;
493 }
494
495 /* set DMA mask + need_dma32 flags. 559 /* set DMA mask + need_dma32 flags.
496 * PCIE - can handle 40-bits. 560 * PCIE - can handle 40-bits.
497 * IGP - can handle 40-bits (in theory) 561 * IGP - can handle 40-bits (in theory)
@@ -521,156 +585,150 @@ int radeon_device_init(struct radeon_device *rdev,
521 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); 585 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
522 DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); 586 DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
523 587
524 /* Setup errata flags */ 588 rdev->new_init_path = false;
525 radeon_errata(rdev); 589 r = radeon_init(rdev);
526 /* Initialize scratch registers */
527 radeon_scratch_init(rdev);
528 /* Initialize surface registers */
529 radeon_surface_init(rdev);
530
531 /* TODO: disable VGA need to use VGA request */
532 /* BIOS*/
533 if (!radeon_get_bios(rdev)) {
534 if (ASIC_IS_AVIVO(rdev))
535 return -EINVAL;
536 }
537 if (rdev->is_atom_bios) {
538 r = radeon_atombios_init(rdev);
539 if (r) {
540 return r;
541 }
542 } else {
543 r = radeon_combios_init(rdev);
544 if (r) {
545 return r;
546 }
547 }
548 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
549 if (radeon_gpu_reset(rdev)) {
550 /* FIXME: what do we want to do here ? */
551 }
552 /* check if cards are posted or not */
553 if (!radeon_card_posted(rdev) && rdev->bios) {
554 DRM_INFO("GPU not posted. posting now...\n");
555 if (rdev->is_atom_bios) {
556 atom_asic_init(rdev->mode_info.atom_context);
557 } else {
558 radeon_combios_asic_init(rdev->ddev);
559 }
560 }
561 /* Initialize clocks */
562 r = radeon_clocks_init(rdev);
563 if (r) {
564 return r;
565 }
566 /* Get vram informations */
567 radeon_vram_info(rdev);
568
569 /* Add an MTRR for the VRAM */
570 rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
571 MTRR_TYPE_WRCOMB, 1);
572 DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n",
573 rdev->mc.real_vram_size >> 20,
574 (unsigned)rdev->mc.aper_size >> 20);
575 DRM_INFO("RAM width %dbits %cDR\n",
576 rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
577 /* Initialize memory controller (also test AGP) */
578 r = radeon_mc_init(rdev);
579 if (r) {
580 return r;
581 }
582 /* Fence driver */
583 r = radeon_fence_driver_init(rdev);
584 if (r) {
585 return r;
586 }
587 r = radeon_irq_kms_init(rdev);
588 if (r) { 590 if (r) {
589 return r; 591 return r;
590 } 592 }
591 /* Memory manager */ 593
592 r = radeon_object_init(rdev); 594 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
595 r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
593 if (r) { 596 if (r) {
594 return r; 597 return -EINVAL;
595 }
596 /* Initialize GART (initialize after TTM so we can allocate
597 * memory through TTM but finalize after TTM) */
598 r = radeon_gart_enable(rdev);
599 if (!r) {
600 r = radeon_gem_init(rdev);
601 } 598 }
602 599
603 /* 1M ring buffer */ 600 if (!rdev->new_init_path) {
604 if (!r) { 601 /* Setup errata flags */
605 r = radeon_cp_init(rdev, 1024 * 1024); 602 radeon_errata(rdev);
606 } 603 /* Initialize scratch registers */
607 if (!r) { 604 radeon_scratch_init(rdev);
608 r = radeon_wb_init(rdev); 605 /* Initialize surface registers */
606 radeon_surface_init(rdev);
607
608 /* BIOS*/
609 if (!radeon_get_bios(rdev)) {
610 if (ASIC_IS_AVIVO(rdev))
611 return -EINVAL;
612 }
613 if (rdev->is_atom_bios) {
614 r = radeon_atombios_init(rdev);
615 if (r) {
616 return r;
617 }
618 } else {
619 r = radeon_combios_init(rdev);
620 if (r) {
621 return r;
622 }
623 }
624 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
625 if (radeon_gpu_reset(rdev)) {
626 /* FIXME: what do we want to do here ? */
627 }
628 /* check if cards are posted or not */
629 if (!radeon_card_posted(rdev) && rdev->bios) {
630 DRM_INFO("GPU not posted. posting now...\n");
631 if (rdev->is_atom_bios) {
632 atom_asic_init(rdev->mode_info.atom_context);
633 } else {
634 radeon_combios_asic_init(rdev->ddev);
635 }
636 }
637 /* Get clock & vram information */
638 radeon_get_clock_info(rdev->ddev);
639 radeon_vram_info(rdev);
640 /* Initialize clocks */
641 r = radeon_clocks_init(rdev);
609 if (r) { 642 if (r) {
610 DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
611 return r; 643 return r;
612 } 644 }
613 } 645
614 if (!r) { 646 /* Initialize memory controller (also test AGP) */
615 r = radeon_ib_pool_init(rdev); 647 r = radeon_mc_init(rdev);
616 if (r) { 648 if (r) {
617 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
618 return r; 649 return r;
619 } 650 }
620 } 651 /* Fence driver */
621 if (!r) { 652 r = radeon_fence_driver_init(rdev);
622 r = radeon_ib_test(rdev);
623 if (r) { 653 if (r) {
624 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
625 return r; 654 return r;
626 } 655 }
656 r = radeon_irq_kms_init(rdev);
657 if (r) {
658 return r;
659 }
660 /* Memory manager */
661 r = radeon_object_init(rdev);
662 if (r) {
663 return r;
664 }
665 r = radeon_gpu_gart_init(rdev);
666 if (r)
667 return r;
668 /* Initialize GART (initialize after TTM so we can allocate
669 * memory through TTM but finalize after TTM) */
670 r = radeon_gart_enable(rdev);
671 if (r)
672 return 0;
673 r = radeon_gem_init(rdev);
674 if (r)
675 return 0;
676
677 /* 1M ring buffer */
678 r = radeon_cp_init(rdev, 1024 * 1024);
679 if (r)
680 return 0;
681 r = radeon_wb_init(rdev);
682 if (r)
683 DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
684 r = radeon_ib_pool_init(rdev);
685 if (r)
686 return 0;
687 r = radeon_ib_test(rdev);
688 if (r)
689 return 0;
690 rdev->accel_working = true;
627 } 691 }
628 ret = r; 692 DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
629 r = radeon_modeset_init(rdev);
630 if (r) {
631 return r;
632 }
633 if (!ret) {
634 DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
635 }
636 if (radeon_testing) { 693 if (radeon_testing) {
637 radeon_test_moves(rdev); 694 radeon_test_moves(rdev);
638 } 695 }
639 if (radeon_benchmarking) { 696 if (radeon_benchmarking) {
640 radeon_benchmark(rdev); 697 radeon_benchmark(rdev);
641 } 698 }
642 return ret; 699 return 0;
643} 700}
644 701
645void radeon_device_fini(struct radeon_device *rdev) 702void radeon_device_fini(struct radeon_device *rdev)
646{ 703{
647 if (rdev == NULL || rdev->rmmio == NULL) {
648 return;
649 }
650 DRM_INFO("radeon: finishing device.\n"); 704 DRM_INFO("radeon: finishing device.\n");
651 rdev->shutdown = true; 705 rdev->shutdown = true;
652 /* Order matter so becarefull if you rearrange anythings */ 706 /* Order matter so becarefull if you rearrange anythings */
653 radeon_modeset_fini(rdev); 707 if (!rdev->new_init_path) {
654 radeon_ib_pool_fini(rdev); 708 radeon_ib_pool_fini(rdev);
655 radeon_cp_fini(rdev); 709 radeon_cp_fini(rdev);
656 radeon_wb_fini(rdev); 710 radeon_wb_fini(rdev);
657 radeon_gem_fini(rdev); 711 radeon_gpu_gart_fini(rdev);
658 radeon_object_fini(rdev); 712 radeon_gem_fini(rdev);
659 /* mc_fini must be after object_fini */ 713 radeon_mc_fini(rdev);
660 radeon_mc_fini(rdev);
661#if __OS_HAS_AGP 714#if __OS_HAS_AGP
662 radeon_agp_fini(rdev); 715 radeon_agp_fini(rdev);
663#endif 716#endif
664 radeon_irq_kms_fini(rdev); 717 radeon_irq_kms_fini(rdev);
665 radeon_fence_driver_fini(rdev); 718 vga_client_register(rdev->pdev, NULL, NULL, NULL);
666 radeon_clocks_fini(rdev); 719 radeon_fence_driver_fini(rdev);
667 if (rdev->is_atom_bios) { 720 radeon_clocks_fini(rdev);
668 radeon_atombios_fini(rdev); 721 radeon_object_fini(rdev);
722 if (rdev->is_atom_bios) {
723 radeon_atombios_fini(rdev);
724 } else {
725 radeon_combios_fini(rdev);
726 }
727 kfree(rdev->bios);
728 rdev->bios = NULL;
669 } else { 729 } else {
670 radeon_combios_fini(rdev); 730 radeon_fini(rdev);
671 } 731 }
672 kfree(rdev->bios);
673 rdev->bios = NULL;
674 iounmap(rdev->rmmio); 732 iounmap(rdev->rmmio);
675 rdev->rmmio = NULL; 733 rdev->rmmio = NULL;
676} 734}
@@ -708,15 +766,19 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
708 /* wait for gpu to finish processing current batch */ 766 /* wait for gpu to finish processing current batch */
709 radeon_fence_wait_last(rdev); 767 radeon_fence_wait_last(rdev);
710 768
711 radeon_cp_disable(rdev); 769 radeon_save_bios_scratch_regs(rdev);
712 radeon_gart_disable(rdev);
713 770
771 if (!rdev->new_init_path) {
772 radeon_cp_disable(rdev);
773 radeon_gart_disable(rdev);
774 rdev->irq.sw_int = false;
775 radeon_irq_set(rdev);
776 } else {
777 radeon_suspend(rdev);
778 }
714 /* evict remaining vram memory */ 779 /* evict remaining vram memory */
715 radeon_object_evict_vram(rdev); 780 radeon_object_evict_vram(rdev);
716 781
717 rdev->irq.sw_int = false;
718 radeon_irq_set(rdev);
719
720 pci_save_state(dev->pdev); 782 pci_save_state(dev->pdev);
721 if (state.event == PM_EVENT_SUSPEND) { 783 if (state.event == PM_EVENT_SUSPEND) {
722 /* Shut down the device */ 784 /* Shut down the device */
@@ -743,38 +805,43 @@ int radeon_resume_kms(struct drm_device *dev)
743 } 805 }
744 pci_set_master(dev->pdev); 806 pci_set_master(dev->pdev);
745 /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 807 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
746 if (radeon_gpu_reset(rdev)) { 808 if (!rdev->new_init_path) {
747 /* FIXME: what do we want to do here ? */ 809 if (radeon_gpu_reset(rdev)) {
748 } 810 /* FIXME: what do we want to do here ? */
749 /* post card */ 811 }
750 if (rdev->is_atom_bios) { 812 /* post card */
751 atom_asic_init(rdev->mode_info.atom_context); 813 if (rdev->is_atom_bios) {
814 atom_asic_init(rdev->mode_info.atom_context);
815 } else {
816 radeon_combios_asic_init(rdev->ddev);
817 }
818 /* Initialize clocks */
819 r = radeon_clocks_init(rdev);
820 if (r) {
821 release_console_sem();
822 return r;
823 }
824 /* Enable IRQ */
825 rdev->irq.sw_int = true;
826 radeon_irq_set(rdev);
827 /* Initialize GPU Memory Controller */
828 r = radeon_mc_init(rdev);
829 if (r) {
830 goto out;
831 }
832 r = radeon_gart_enable(rdev);
833 if (r) {
834 goto out;
835 }
836 r = radeon_cp_init(rdev, rdev->cp.ring_size);
837 if (r) {
838 goto out;
839 }
752 } else { 840 } else {
753 radeon_combios_asic_init(rdev->ddev); 841 radeon_resume(rdev);
754 }
755 /* Initialize clocks */
756 r = radeon_clocks_init(rdev);
757 if (r) {
758 release_console_sem();
759 return r;
760 }
761 /* Enable IRQ */
762 rdev->irq.sw_int = true;
763 radeon_irq_set(rdev);
764 /* Initialize GPU Memory Controller */
765 r = radeon_mc_init(rdev);
766 if (r) {
767 goto out;
768 }
769 r = radeon_gart_enable(rdev);
770 if (r) {
771 goto out;
772 }
773 r = radeon_cp_init(rdev, rdev->cp.ring_size);
774 if (r) {
775 goto out;
776 } 842 }
777out: 843out:
844 radeon_restore_bios_scratch_regs(rdev);
778 fb_set_suspend(rdev->fbdev_info, 0); 845 fb_set_suspend(rdev->fbdev_info, 0);
779 release_console_sem(); 846 release_console_sem();
780 847
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index a8fa1bb84cf7..5d8141b13765 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -158,9 +158,6 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc)
158{ 158{
159 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 159 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
160 160
161 if (radeon_crtc->mode_set.mode) {
162 drm_mode_destroy(crtc->dev, radeon_crtc->mode_set.mode);
163 }
164 drm_crtc_cleanup(crtc); 161 drm_crtc_cleanup(crtc);
165 kfree(radeon_crtc); 162 kfree(radeon_crtc);
166} 163}
@@ -189,9 +186,11 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
189 radeon_crtc->crtc_id = index; 186 radeon_crtc->crtc_id = index;
190 rdev->mode_info.crtcs[index] = radeon_crtc; 187 rdev->mode_info.crtcs[index] = radeon_crtc;
191 188
189#if 0
192 radeon_crtc->mode_set.crtc = &radeon_crtc->base; 190 radeon_crtc->mode_set.crtc = &radeon_crtc->base;
193 radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); 191 radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
194 radeon_crtc->mode_set.num_connectors = 0; 192 radeon_crtc->mode_set.num_connectors = 0;
193#endif
195 194
196 for (i = 0; i < 256; i++) { 195 for (i = 0; i < 256; i++) {
197 radeon_crtc->lut_r[i] = i << 2; 196 radeon_crtc->lut_r[i] = i << 2;
@@ -313,7 +312,7 @@ static void radeon_print_display_setup(struct drm_device *dev)
313 } 312 }
314} 313}
315 314
316bool radeon_setup_enc_conn(struct drm_device *dev) 315static bool radeon_setup_enc_conn(struct drm_device *dev)
317{ 316{
318 struct radeon_device *rdev = dev->dev_private; 317 struct radeon_device *rdev = dev->dev_private;
319 struct drm_connector *drm_connector; 318 struct drm_connector *drm_connector;
@@ -347,9 +346,13 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
347 346
348 if (!radeon_connector->ddc_bus) 347 if (!radeon_connector->ddc_bus)
349 return -1; 348 return -1;
350 radeon_i2c_do_lock(radeon_connector, 1); 349 if (!radeon_connector->edid) {
351 edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); 350 radeon_i2c_do_lock(radeon_connector, 1);
352 radeon_i2c_do_lock(radeon_connector, 0); 351 edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
352 radeon_i2c_do_lock(radeon_connector, 0);
353 } else
354 edid = radeon_connector->edid;
355
353 if (edid) { 356 if (edid) {
354 /* update digital bits here */ 357 /* update digital bits here */
355 if (edid->input & DRM_EDID_INPUT_DIGITAL) 358 if (edid->input & DRM_EDID_INPUT_DIGITAL)
@@ -362,7 +365,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
362 return ret; 365 return ret;
363 } 366 }
364 drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); 367 drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
365 return -1; 368 return 0;
366} 369}
367 370
368static int radeon_ddc_dump(struct drm_connector *connector) 371static int radeon_ddc_dump(struct drm_connector *connector)
@@ -620,6 +623,83 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
620 .fb_changed = radeonfb_probe, 623 .fb_changed = radeonfb_probe,
621}; 624};
622 625
626struct drm_prop_enum_list {
627 int type;
628 char *name;
629};
630
631static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
632{ { 0, "driver" },
633 { 1, "bios" },
634};
635
636static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
637{ { TV_STD_NTSC, "ntsc" },
638 { TV_STD_PAL, "pal" },
639 { TV_STD_PAL_M, "pal-m" },
640 { TV_STD_PAL_60, "pal-60" },
641 { TV_STD_NTSC_J, "ntsc-j" },
642 { TV_STD_SCART_PAL, "scart-pal" },
643 { TV_STD_PAL_CN, "pal-cn" },
644 { TV_STD_SECAM, "secam" },
645};
646
647int radeon_modeset_create_props(struct radeon_device *rdev)
648{
649 int i, sz;
650
651 if (rdev->is_atom_bios) {
652 rdev->mode_info.coherent_mode_property =
653 drm_property_create(rdev->ddev,
654 DRM_MODE_PROP_RANGE,
655 "coherent", 2);
656 if (!rdev->mode_info.coherent_mode_property)
657 return -ENOMEM;
658
659 rdev->mode_info.coherent_mode_property->values[0] = 0;
660 rdev->mode_info.coherent_mode_property->values[0] = 1;
661 }
662
663 if (!ASIC_IS_AVIVO(rdev)) {
664 sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
665 rdev->mode_info.tmds_pll_property =
666 drm_property_create(rdev->ddev,
667 DRM_MODE_PROP_ENUM,
668 "tmds_pll", sz);
669 for (i = 0; i < sz; i++) {
670 drm_property_add_enum(rdev->mode_info.tmds_pll_property,
671 i,
672 radeon_tmds_pll_enum_list[i].type,
673 radeon_tmds_pll_enum_list[i].name);
674 }
675 }
676
677 rdev->mode_info.load_detect_property =
678 drm_property_create(rdev->ddev,
679 DRM_MODE_PROP_RANGE,
680 "load detection", 2);
681 if (!rdev->mode_info.load_detect_property)
682 return -ENOMEM;
683 rdev->mode_info.load_detect_property->values[0] = 0;
684 rdev->mode_info.load_detect_property->values[0] = 1;
685
686 drm_mode_create_scaling_mode_property(rdev->ddev);
687
688 sz = ARRAY_SIZE(radeon_tv_std_enum_list);
689 rdev->mode_info.tv_std_property =
690 drm_property_create(rdev->ddev,
691 DRM_MODE_PROP_ENUM,
692 "tv standard", sz);
693 for (i = 0; i < sz; i++) {
694 drm_property_add_enum(rdev->mode_info.tv_std_property,
695 i,
696 radeon_tv_std_enum_list[i].type,
697 radeon_tv_std_enum_list[i].name);
698 }
699
700 return 0;
701}
702
623int radeon_modeset_init(struct radeon_device *rdev) 703int radeon_modeset_init(struct radeon_device *rdev)
624{ 704{
625 int num_crtc = 2, i; 705 int num_crtc = 2, i;
@@ -640,6 +720,10 @@ int radeon_modeset_init(struct radeon_device *rdev)
640 720
641 rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; 721 rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
642 722
723 ret = radeon_modeset_create_props(rdev);
724 if (ret) {
725 return ret;
726 }
643 /* allocate crtcs - TODO single crtc */ 727 /* allocate crtcs - TODO single crtc */
644 for (i = 0; i < num_crtc; i++) { 728 for (i = 0; i < num_crtc; i++) {
645 radeon_crtc_init(rdev->ddev, i); 729 radeon_crtc_init(rdev->ddev, i);
@@ -678,7 +762,6 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
678 continue; 762 continue;
679 if (first) { 763 if (first) {
680 radeon_crtc->rmx_type = radeon_encoder->rmx_type; 764 radeon_crtc->rmx_type = radeon_encoder->rmx_type;
681 radeon_crtc->devices = radeon_encoder->devices;
682 memcpy(&radeon_crtc->native_mode, 765 memcpy(&radeon_crtc->native_mode,
683 &radeon_encoder->native_mode, 766 &radeon_encoder->native_mode,
684 sizeof(struct radeon_native_mode)); 767 sizeof(struct radeon_native_mode));
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 0bd5879a4957..50fce498910c 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -38,7 +38,6 @@
38#include <linux/console.h> 38#include <linux/console.h>
39 39
40 40
41#if defined(CONFIG_DRM_RADEON_KMS)
42/* 41/*
43 * KMS wrapper. 42 * KMS wrapper.
44 */ 43 */
@@ -77,11 +76,9 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
77int radeon_debugfs_init(struct drm_minor *minor); 76int radeon_debugfs_init(struct drm_minor *minor);
78void radeon_debugfs_cleanup(struct drm_minor *minor); 77void radeon_debugfs_cleanup(struct drm_minor *minor);
79#endif 78#endif
80#endif
81 79
82 80
83int radeon_no_wb; 81int radeon_no_wb;
84#if defined(CONFIG_DRM_RADEON_KMS)
85int radeon_modeset = -1; 82int radeon_modeset = -1;
86int radeon_dynclks = -1; 83int radeon_dynclks = -1;
87int radeon_r4xx_atom = 0; 84int radeon_r4xx_atom = 0;
@@ -91,12 +88,11 @@ int radeon_gart_size = 512; /* default gart size */
91int radeon_benchmarking = 0; 88int radeon_benchmarking = 0;
92int radeon_testing = 0; 89int radeon_testing = 0;
93int radeon_connector_table = 0; 90int radeon_connector_table = 0;
94#endif 91int radeon_tv = 1;
95 92
96MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 93MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
97module_param_named(no_wb, radeon_no_wb, int, 0444); 94module_param_named(no_wb, radeon_no_wb, int, 0444);
98 95
99#if defined(CONFIG_DRM_RADEON_KMS)
100MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 96MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
101module_param_named(modeset, radeon_modeset, int, 0400); 97module_param_named(modeset, radeon_modeset, int, 0400);
102 98
@@ -123,7 +119,9 @@ module_param_named(test, radeon_testing, int, 0444);
123 119
124MODULE_PARM_DESC(connector_table, "Force connector table"); 120MODULE_PARM_DESC(connector_table, "Force connector table");
125module_param_named(connector_table, radeon_connector_table, int, 0444); 121module_param_named(connector_table, radeon_connector_table, int, 0444);
126#endif 122
123MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
124module_param_named(tv, radeon_tv, int, 0444);
127 125
128static int radeon_suspend(struct drm_device *dev, pm_message_t state) 126static int radeon_suspend(struct drm_device *dev, pm_message_t state)
129{ 127{
@@ -215,7 +213,6 @@ static struct drm_driver driver_old = {
215 .patchlevel = DRIVER_PATCHLEVEL, 213 .patchlevel = DRIVER_PATCHLEVEL,
216}; 214};
217 215
218#if defined(CONFIG_DRM_RADEON_KMS)
219static struct drm_driver kms_driver; 216static struct drm_driver kms_driver;
220 217
221static int __devinit 218static int __devinit
@@ -289,7 +286,7 @@ static struct drm_driver kms_driver = {
289 .poll = drm_poll, 286 .poll = drm_poll,
290 .fasync = drm_fasync, 287 .fasync = drm_fasync,
291#ifdef CONFIG_COMPAT 288#ifdef CONFIG_COMPAT
292 .compat_ioctl = NULL, 289 .compat_ioctl = radeon_kms_compat_ioctl,
293#endif 290#endif
294 }, 291 },
295 292
@@ -309,7 +306,6 @@ static struct drm_driver kms_driver = {
309 .minor = KMS_DRIVER_MINOR, 306 .minor = KMS_DRIVER_MINOR,
310 .patchlevel = KMS_DRIVER_PATCHLEVEL, 307 .patchlevel = KMS_DRIVER_PATCHLEVEL,
311}; 308};
312#endif
313 309
314static struct drm_driver *driver; 310static struct drm_driver *driver;
315 311
@@ -317,7 +313,6 @@ static int __init radeon_init(void)
317{ 313{
318 driver = &driver_old; 314 driver = &driver_old;
319 driver->num_ioctls = radeon_max_ioctl; 315 driver->num_ioctls = radeon_max_ioctl;
320#if defined(CONFIG_DRM_RADEON_KMS)
321#ifdef CONFIG_VGA_CONSOLE 316#ifdef CONFIG_VGA_CONSOLE
322 if (vgacon_text_force() && radeon_modeset == -1) { 317 if (vgacon_text_force() && radeon_modeset == -1) {
323 DRM_INFO("VGACON disable radeon kernel modesetting.\n"); 318 DRM_INFO("VGACON disable radeon kernel modesetting.\n");
@@ -328,8 +323,13 @@ static int __init radeon_init(void)
328#endif 323#endif
329 /* if enabled by default */ 324 /* if enabled by default */
330 if (radeon_modeset == -1) { 325 if (radeon_modeset == -1) {
331 DRM_INFO("radeon default to kernel modesetting.\n"); 326#ifdef CONFIG_DRM_RADEON_KMS
327 DRM_INFO("radeon defaulting to kernel modesetting.\n");
332 radeon_modeset = 1; 328 radeon_modeset = 1;
329#else
330 DRM_INFO("radeon defaulting to userspace modesetting.\n");
331 radeon_modeset = 0;
332#endif
333 } 333 }
334 if (radeon_modeset == 1) { 334 if (radeon_modeset == 1) {
335 DRM_INFO("radeon kernel modesetting enabled.\n"); 335 DRM_INFO("radeon kernel modesetting enabled.\n");
@@ -339,7 +339,6 @@ static int __init radeon_init(void)
339 } 339 }
340 /* if the vga console setting is enabled still 340 /* if the vga console setting is enabled still
341 * let modprobe override it */ 341 * let modprobe override it */
342#endif
343 return drm_init(driver); 342 return drm_init(driver);
344} 343}
345 344
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 6fa32dac4e97..cb0cfe4b3082 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -31,6 +31,9 @@
31#ifndef __RADEON_DRV_H__ 31#ifndef __RADEON_DRV_H__
32#define __RADEON_DRV_H__ 32#define __RADEON_DRV_H__
33 33
34#include <linux/firmware.h>
35#include <linux/platform_device.h>
36
34/* General customization: 37/* General customization:
35 */ 38 */
36 39
@@ -353,6 +356,14 @@ typedef struct drm_radeon_private {
353 int r700_sc_hiz_tile_fifo_size; 356 int r700_sc_hiz_tile_fifo_size;
354 int r700_sc_earlyz_tile_fifo_fize; 357 int r700_sc_earlyz_tile_fifo_fize;
355 358
359 struct mutex cs_mutex;
360 u32 cs_id_scnt;
361 u32 cs_id_wcnt;
362 /* r6xx/r7xx drm blit vertex buffer */
363 struct drm_buf *blit_vb;
364
365 /* firmware */
366 const struct firmware *me_fw, *pfp_fw;
356} drm_radeon_private_t; 367} drm_radeon_private_t;
357 368
358typedef struct drm_radeon_buf_priv { 369typedef struct drm_radeon_buf_priv {
@@ -391,6 +402,9 @@ static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
391 (off >= gart_start && off <= gart_end)); 402 (off >= gart_start && off <= gart_end));
392} 403}
393 404
405/* radeon_state.c */
406extern void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf);
407
394 /* radeon_cp.c */ 408 /* radeon_cp.c */
395extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); 409extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
396extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); 410extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -457,6 +471,8 @@ extern int radeon_driver_open(struct drm_device *dev,
457 struct drm_file *file_priv); 471 struct drm_file *file_priv);
458extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, 472extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
459 unsigned long arg); 473 unsigned long arg);
474extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd,
475 unsigned long arg);
460 476
461extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); 477extern int radeon_master_create(struct drm_device *dev, struct drm_master *master);
462extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); 478extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -482,6 +498,22 @@ extern int r600_cp_dispatch_indirect(struct drm_device *dev,
482 struct drm_buf *buf, int start, int end); 498 struct drm_buf *buf, int start, int end);
483extern int r600_page_table_init(struct drm_device *dev); 499extern int r600_page_table_init(struct drm_device *dev);
484extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); 500extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
501extern int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
502extern void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv);
503extern int r600_cp_dispatch_texture(struct drm_device *dev,
504 struct drm_file *file_priv,
505 drm_radeon_texture_t *tex,
506 drm_radeon_tex_image_t *image);
507/* r600_blit.c */
508extern int r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv);
509extern void r600_done_blit_copy(struct drm_device *dev);
510extern void r600_blit_copy(struct drm_device *dev,
511 uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
512 int size_bytes);
513extern void r600_blit_swap(struct drm_device *dev,
514 uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
515 int sx, int sy, int dx, int dy,
516 int w, int h, int src_pitch, int dst_pitch, int cpp);
485 517
486/* Flags for stats.boxes 518/* Flags for stats.boxes
487 */ 519 */
@@ -1067,6 +1099,9 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
1067# define RADEON_CSQ_PRIBM_INDBM (4 << 28) 1099# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
1068# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) 1100# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
1069 1101
1102#define R300_CP_RESYNC_ADDR 0x0778
1103#define R300_CP_RESYNC_DATA 0x077c
1104
1070#define RADEON_AIC_CNTL 0x01d0 1105#define RADEON_AIC_CNTL 0x01d0
1071# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) 1106# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
1072# define RS400_MSI_REARM (1 << 3) 1107# define RS400_MSI_REARM (1 << 3)
@@ -1109,13 +1144,71 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
1109# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 1144# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
1110# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 1145# define RADEON_CNTL_SET_SCISSORS 0xC0001E00
1111 1146
1112# define R600_IT_INDIRECT_BUFFER 0x00003200 1147# define R600_IT_INDIRECT_BUFFER_END 0x00001700
1113# define R600_IT_ME_INITIALIZE 0x00004400 1148# define R600_IT_SET_PREDICATION 0x00002000
1149# define R600_IT_REG_RMW 0x00002100
1150# define R600_IT_COND_EXEC 0x00002200
1151# define R600_IT_PRED_EXEC 0x00002300
1152# define R600_IT_START_3D_CMDBUF 0x00002400
1153# define R600_IT_DRAW_INDEX_2 0x00002700
1154# define R600_IT_CONTEXT_CONTROL 0x00002800
1155# define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900
1156# define R600_IT_INDEX_TYPE 0x00002A00
1157# define R600_IT_DRAW_INDEX 0x00002B00
1158# define R600_IT_DRAW_INDEX_AUTO 0x00002D00
1159# define R600_IT_DRAW_INDEX_IMMD 0x00002E00
1160# define R600_IT_NUM_INSTANCES 0x00002F00
1161# define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400
1162# define R600_IT_INDIRECT_BUFFER_MP 0x00003800
1163# define R600_IT_MEM_SEMAPHORE 0x00003900
1164# define R600_IT_MPEG_INDEX 0x00003A00
1165# define R600_IT_WAIT_REG_MEM 0x00003C00
1166# define R600_IT_MEM_WRITE 0x00003D00
1167# define R600_IT_INDIRECT_BUFFER 0x00003200
1168# define R600_IT_CP_INTERRUPT 0x00004000
1169# define R600_IT_SURFACE_SYNC 0x00004300
1170# define R600_CB0_DEST_BASE_ENA (1 << 6)
1171# define R600_TC_ACTION_ENA (1 << 23)
1172# define R600_VC_ACTION_ENA (1 << 24)
1173# define R600_CB_ACTION_ENA (1 << 25)
1174# define R600_DB_ACTION_ENA (1 << 26)
1175# define R600_SH_ACTION_ENA (1 << 27)
1176# define R600_SMX_ACTION_ENA (1 << 28)
1177# define R600_IT_ME_INITIALIZE 0x00004400
1114# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) 1178# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
1115# define R600_IT_EVENT_WRITE 0x00004600 1179# define R600_IT_COND_WRITE 0x00004500
1116# define R600_IT_SET_CONFIG_REG 0x00006800 1180# define R600_IT_EVENT_WRITE 0x00004600
1117# define R600_SET_CONFIG_REG_OFFSET 0x00008000 1181# define R600_IT_EVENT_WRITE_EOP 0x00004700
1118# define R600_SET_CONFIG_REG_END 0x0000ac00 1182# define R600_IT_ONE_REG_WRITE 0x00005700
1183# define R600_IT_SET_CONFIG_REG 0x00006800
1184# define R600_SET_CONFIG_REG_OFFSET 0x00008000
1185# define R600_SET_CONFIG_REG_END 0x0000ac00
1186# define R600_IT_SET_CONTEXT_REG 0x00006900
1187# define R600_SET_CONTEXT_REG_OFFSET 0x00028000
1188# define R600_SET_CONTEXT_REG_END 0x00029000
1189# define R600_IT_SET_ALU_CONST 0x00006A00
1190# define R600_SET_ALU_CONST_OFFSET 0x00030000
1191# define R600_SET_ALU_CONST_END 0x00032000
1192# define R600_IT_SET_BOOL_CONST 0x00006B00
1193# define R600_SET_BOOL_CONST_OFFSET 0x0003e380
1194# define R600_SET_BOOL_CONST_END 0x00040000
1195# define R600_IT_SET_LOOP_CONST 0x00006C00
1196# define R600_SET_LOOP_CONST_OFFSET 0x0003e200
1197# define R600_SET_LOOP_CONST_END 0x0003e380
1198# define R600_IT_SET_RESOURCE 0x00006D00
1199# define R600_SET_RESOURCE_OFFSET 0x00038000
1200# define R600_SET_RESOURCE_END 0x0003c000
1201# define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0
1202# define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1
1203# define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2
1204# define R600_SQ_TEX_VTX_VALID_BUFFER 0x3
1205# define R600_IT_SET_SAMPLER 0x00006E00
1206# define R600_SET_SAMPLER_OFFSET 0x0003c000
1207# define R600_SET_SAMPLER_END 0x0003cff0
1208# define R600_IT_SET_CTL_CONST 0x00006F00
1209# define R600_SET_CTL_CONST_OFFSET 0x0003cff0
1210# define R600_SET_CTL_CONST_END 0x0003e200
1211# define R600_IT_SURFACE_BASE_UPDATE 0x00007300
1119 1212
1120#define RADEON_CP_PACKET_MASK 0xC0000000 1213#define RADEON_CP_PACKET_MASK 0xC0000000
1121#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 1214#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
@@ -1593,6 +1686,52 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
1593#define R600_CB_COLOR7_BASE 0x2805c 1686#define R600_CB_COLOR7_BASE 0x2805c
1594#define R600_CB_COLOR7_FRAG 0x280fc 1687#define R600_CB_COLOR7_FRAG 0x280fc
1595 1688
1689#define R600_CB_COLOR0_SIZE 0x28060
1690#define R600_CB_COLOR0_VIEW 0x28080
1691#define R600_CB_COLOR0_INFO 0x280a0
1692#define R600_CB_COLOR0_TILE 0x280c0
1693#define R600_CB_COLOR0_FRAG 0x280e0
1694#define R600_CB_COLOR0_MASK 0x28100
1695
1696#define AVIVO_D1MODE_VLINE_START_END 0x6538
1697#define AVIVO_D2MODE_VLINE_START_END 0x6d38
1698#define R600_CP_COHER_BASE 0x85f8
1699#define R600_DB_DEPTH_BASE 0x2800c
1700#define R600_SQ_PGM_START_FS 0x28894
1701#define R600_SQ_PGM_START_ES 0x28880
1702#define R600_SQ_PGM_START_VS 0x28858
1703#define R600_SQ_PGM_RESOURCES_VS 0x28868
1704#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0
1705#define R600_SQ_PGM_START_GS 0x2886c
1706#define R600_SQ_PGM_START_PS 0x28840
1707#define R600_SQ_PGM_RESOURCES_PS 0x28850
1708#define R600_SQ_PGM_EXPORTS_PS 0x28854
1709#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc
1710#define R600_VGT_DMA_BASE 0x287e8
1711#define R600_VGT_DMA_BASE_HI 0x287e4
1712#define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10
1713#define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14
1714#define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18
1715#define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c
1716#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44
1717#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48
1718#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c
1719#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50
1720#define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8
1721#define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8
1722#define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8
1723#define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08
1724#define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc
1725#define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec
1726#define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc
1727#define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c
1728
1729#define R600_VGT_PRIMITIVE_TYPE 0x8958
1730
1731#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030
1732#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240
1733#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204
1734
1596#define R600_TC_CNTL 0x9608 1735#define R600_TC_CNTL 0x9608
1597# define R600_TC_L2_SIZE(x) ((x) << 5) 1736# define R600_TC_L2_SIZE(x) ((x) << 5)
1598# define R600_L2_DISABLE_LATE_HIT (1 << 9) 1737# define R600_L2_DISABLE_LATE_HIT (1 << 9)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 0a92706eac19..621646752cd2 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -126,6 +126,23 @@ radeon_link_encoder_connector(struct drm_device *dev)
126 } 126 }
127} 127}
128 128
129void radeon_encoder_set_active_device(struct drm_encoder *encoder)
130{
131 struct drm_device *dev = encoder->dev;
132 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
133 struct drm_connector *connector;
134
135 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
136 if (connector->encoder == encoder) {
137 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
138 radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
139 DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n",
140 radeon_encoder->active_device, radeon_encoder->devices,
141 radeon_connector->devices, encoder->encoder_type);
142 }
143 }
144}
145
129static struct drm_connector * 146static struct drm_connector *
130radeon_get_connector_for_encoder(struct drm_encoder *encoder) 147radeon_get_connector_for_encoder(struct drm_encoder *encoder)
131{ 148{
@@ -224,9 +241,12 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
224 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 241 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
225 DAC_ENCODER_CONTROL_PS_ALLOCATION args; 242 DAC_ENCODER_CONTROL_PS_ALLOCATION args;
226 int index = 0, num = 0; 243 int index = 0, num = 0;
227 /* fixme - fill in enc_priv for atom dac */ 244 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
228 enum radeon_tv_std tv_std = TV_STD_NTSC; 245 enum radeon_tv_std tv_std = TV_STD_NTSC;
229 246
247 if (dac_info->tv_std)
248 tv_std = dac_info->tv_std;
249
230 memset(&args, 0, sizeof(args)); 250 memset(&args, 0, sizeof(args));
231 251
232 switch (radeon_encoder->encoder_id) { 252 switch (radeon_encoder->encoder_id) {
@@ -244,9 +264,9 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
244 264
245 args.ucAction = action; 265 args.ucAction = action;
246 266
247 if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) 267 if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT))
248 args.ucDacStandard = ATOM_DAC1_PS2; 268 args.ucDacStandard = ATOM_DAC1_PS2;
249 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 269 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
250 args.ucDacStandard = ATOM_DAC1_CV; 270 args.ucDacStandard = ATOM_DAC1_CV;
251 else { 271 else {
252 switch (tv_std) { 272 switch (tv_std) {
@@ -279,16 +299,19 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
279 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 299 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
280 TV_ENCODER_CONTROL_PS_ALLOCATION args; 300 TV_ENCODER_CONTROL_PS_ALLOCATION args;
281 int index = 0; 301 int index = 0;
282 /* fixme - fill in enc_priv for atom dac */ 302 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
283 enum radeon_tv_std tv_std = TV_STD_NTSC; 303 enum radeon_tv_std tv_std = TV_STD_NTSC;
284 304
305 if (dac_info->tv_std)
306 tv_std = dac_info->tv_std;
307
285 memset(&args, 0, sizeof(args)); 308 memset(&args, 0, sizeof(args));
286 309
287 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); 310 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
288 311
289 args.sTVEncoder.ucAction = action; 312 args.sTVEncoder.ucAction = action;
290 313
291 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 314 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
292 args.sTVEncoder.ucTvStandard = ATOM_TV_CV; 315 args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
293 else { 316 else {
294 switch (tv_std) { 317 switch (tv_std) {
@@ -520,6 +543,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
520 543
521 switch (connector->connector_type) { 544 switch (connector->connector_type) {
522 case DRM_MODE_CONNECTOR_DVII: 545 case DRM_MODE_CONNECTOR_DVII:
546 case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
523 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) 547 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
524 return ATOM_ENCODER_MODE_HDMI; 548 return ATOM_ENCODER_MODE_HDMI;
525 else if (radeon_connector->use_digital) 549 else if (radeon_connector->use_digital)
@@ -529,7 +553,6 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
529 break; 553 break;
530 case DRM_MODE_CONNECTOR_DVID: 554 case DRM_MODE_CONNECTOR_DVID:
531 case DRM_MODE_CONNECTOR_HDMIA: 555 case DRM_MODE_CONNECTOR_HDMIA:
532 case DRM_MODE_CONNECTOR_HDMIB:
533 default: 556 default:
534 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) 557 if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
535 return ATOM_ENCODER_MODE_HDMI; 558 return ATOM_ENCODER_MODE_HDMI;
@@ -825,10 +848,10 @@ atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
825 848
826 /* XXX: fix up scratch reg handling */ 849 /* XXX: fix up scratch reg handling */
827 temp = RREG32(reg); 850 temp = RREG32(reg);
828 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 851 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
829 WREG32(reg, (ATOM_S3_TV1_ACTIVE | 852 WREG32(reg, (ATOM_S3_TV1_ACTIVE |
830 (radeon_crtc->crtc_id << 18))); 853 (radeon_crtc->crtc_id << 18)));
831 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 854 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
832 WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); 855 WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
833 else 856 else
834 WREG32(reg, 0); 857 WREG32(reg, 0);
@@ -851,9 +874,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
851 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; 874 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
852 int index = 0; 875 int index = 0;
853 bool is_dig = false; 876 bool is_dig = false;
877 int devices;
854 878
855 memset(&args, 0, sizeof(args)); 879 memset(&args, 0, sizeof(args));
856 880
881 /* on DPMS off we have no idea if active device is meaningful */
882 if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device)
883 devices = radeon_encoder->devices;
884 else
885 devices = radeon_encoder->active_device;
886
887 DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
888 radeon_encoder->encoder_id, mode, radeon_encoder->devices,
889 radeon_encoder->active_device);
857 switch (radeon_encoder->encoder_id) { 890 switch (radeon_encoder->encoder_id) {
858 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 891 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
859 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 892 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -881,18 +914,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
881 break; 914 break;
882 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 915 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
883 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 916 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
884 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 917 if (devices & (ATOM_DEVICE_TV_SUPPORT))
885 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); 918 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
886 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 919 else if (devices & (ATOM_DEVICE_CV_SUPPORT))
887 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); 920 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
888 else 921 else
889 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); 922 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
890 break; 923 break;
891 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 924 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
892 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 925 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
893 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 926 if (devices & (ATOM_DEVICE_TV_SUPPORT))
894 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); 927 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
895 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 928 else if (devices & (ATOM_DEVICE_CV_SUPPORT))
896 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); 929 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
897 else 930 else
898 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); 931 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
@@ -979,18 +1012,18 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
979 break; 1012 break;
980 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1013 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
981 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1014 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
982 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 1015 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
983 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; 1016 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
984 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 1017 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
985 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; 1018 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
986 else 1019 else
987 args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; 1020 args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
988 break; 1021 break;
989 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1022 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
990 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1023 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
991 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 1024 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
992 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; 1025 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
993 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 1026 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
994 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; 1027 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
995 else 1028 else
996 args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; 1029 args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
@@ -1019,17 +1052,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
1019 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; 1052 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
1020 break; 1053 break;
1021 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1054 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1022 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 1055 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1023 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1056 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1024 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 1057 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
1025 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1058 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1026 else 1059 else
1027 args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; 1060 args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
1028 break; 1061 break;
1029 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1062 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1030 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) 1063 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1031 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1064 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1032 else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) 1065 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
1033 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1066 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
1034 else 1067 else
1035 args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; 1068 args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
@@ -1097,7 +1130,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1097 atombios_set_encoder_crtc_source(encoder); 1130 atombios_set_encoder_crtc_source(encoder);
1098 1131
1099 if (ASIC_IS_AVIVO(rdev)) { 1132 if (ASIC_IS_AVIVO(rdev)) {
1100 if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) 1133 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
1101 atombios_yuv_setup(encoder, true); 1134 atombios_yuv_setup(encoder, true);
1102 else 1135 else
1103 atombios_yuv_setup(encoder, false); 1136 atombios_yuv_setup(encoder, false);
@@ -1135,7 +1168,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1135 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1168 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1136 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1169 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1137 atombios_dac_setup(encoder, ATOM_ENABLE); 1170 atombios_dac_setup(encoder, ATOM_ENABLE);
1138 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) 1171 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
1139 atombios_tv_setup(encoder, ATOM_ENABLE); 1172 atombios_tv_setup(encoder, ATOM_ENABLE);
1140 break; 1173 break;
1141 } 1174 }
@@ -1143,11 +1176,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1143} 1176}
1144 1177
1145static bool 1178static bool
1146atombios_dac_load_detect(struct drm_encoder *encoder) 1179atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector)
1147{ 1180{
1148 struct drm_device *dev = encoder->dev; 1181 struct drm_device *dev = encoder->dev;
1149 struct radeon_device *rdev = dev->dev_private; 1182 struct radeon_device *rdev = dev->dev_private;
1150 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1183 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1184 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1151 1185
1152 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | 1186 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
1153 ATOM_DEVICE_CV_SUPPORT | 1187 ATOM_DEVICE_CV_SUPPORT |
@@ -1168,15 +1202,15 @@ atombios_dac_load_detect(struct drm_encoder *encoder)
1168 else 1202 else
1169 args.sDacload.ucDacType = ATOM_DAC_B; 1203 args.sDacload.ucDacType = ATOM_DAC_B;
1170 1204
1171 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) 1205 if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)
1172 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); 1206 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
1173 else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) 1207 else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)
1174 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); 1208 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
1175 else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { 1209 else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
1176 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); 1210 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
1177 if (crev >= 3) 1211 if (crev >= 3)
1178 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; 1212 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
1179 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { 1213 } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
1180 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); 1214 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
1181 if (crev >= 3) 1215 if (crev >= 3)
1182 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; 1216 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
@@ -1195,9 +1229,10 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
1195 struct drm_device *dev = encoder->dev; 1229 struct drm_device *dev = encoder->dev;
1196 struct radeon_device *rdev = dev->dev_private; 1230 struct radeon_device *rdev = dev->dev_private;
1197 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1231 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1232 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1198 uint32_t bios_0_scratch; 1233 uint32_t bios_0_scratch;
1199 1234
1200 if (!atombios_dac_load_detect(encoder)) { 1235 if (!atombios_dac_load_detect(encoder, connector)) {
1201 DRM_DEBUG("detect returned false \n"); 1236 DRM_DEBUG("detect returned false \n");
1202 return connector_status_unknown; 1237 return connector_status_unknown;
1203 } 1238 }
@@ -1207,17 +1242,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
1207 else 1242 else
1208 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); 1243 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
1209 1244
1210 DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch); 1245 DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
1211 if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { 1246 if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
1212 if (bios_0_scratch & ATOM_S0_CRT1_MASK) 1247 if (bios_0_scratch & ATOM_S0_CRT1_MASK)
1213 return connector_status_connected; 1248 return connector_status_connected;
1214 } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { 1249 }
1250 if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
1215 if (bios_0_scratch & ATOM_S0_CRT2_MASK) 1251 if (bios_0_scratch & ATOM_S0_CRT2_MASK)
1216 return connector_status_connected; 1252 return connector_status_connected;
1217 } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { 1253 }
1254 if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
1218 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) 1255 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
1219 return connector_status_connected; 1256 return connector_status_connected;
1220 } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { 1257 }
1258 if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
1221 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) 1259 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
1222 return connector_status_connected; /* CTV */ 1260 return connector_status_connected; /* CTV */
1223 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) 1261 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
@@ -1230,6 +1268,8 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
1230{ 1268{
1231 radeon_atom_output_lock(encoder, true); 1269 radeon_atom_output_lock(encoder, true);
1232 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 1270 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1271
1272 radeon_encoder_set_active_device(encoder);
1233} 1273}
1234 1274
1235static void radeon_atom_encoder_commit(struct drm_encoder *encoder) 1275static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
@@ -1238,12 +1278,20 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
1238 radeon_atom_output_lock(encoder, false); 1278 radeon_atom_output_lock(encoder, false);
1239} 1279}
1240 1280
1281static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
1282{
1283 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1284 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1285 radeon_encoder->active_device = 0;
1286}
1287
1241static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { 1288static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
1242 .dpms = radeon_atom_encoder_dpms, 1289 .dpms = radeon_atom_encoder_dpms,
1243 .mode_fixup = radeon_atom_mode_fixup, 1290 .mode_fixup = radeon_atom_mode_fixup,
1244 .prepare = radeon_atom_encoder_prepare, 1291 .prepare = radeon_atom_encoder_prepare,
1245 .mode_set = radeon_atom_encoder_mode_set, 1292 .mode_set = radeon_atom_encoder_mode_set,
1246 .commit = radeon_atom_encoder_commit, 1293 .commit = radeon_atom_encoder_commit,
1294 .disable = radeon_atom_encoder_disable,
1247 /* no detect for TMDS/LVDS yet */ 1295 /* no detect for TMDS/LVDS yet */
1248}; 1296};
1249 1297
@@ -1268,6 +1316,18 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
1268 .destroy = radeon_enc_destroy, 1316 .destroy = radeon_enc_destroy,
1269}; 1317};
1270 1318
1319struct radeon_encoder_atom_dac *
1320radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
1321{
1322 struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
1323
1324 if (!dac)
1325 return NULL;
1326
1327 dac->tv_std = TV_STD_NTSC;
1328 return dac;
1329}
1330
1271struct radeon_encoder_atom_dig * 1331struct radeon_encoder_atom_dig *
1272radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) 1332radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
1273{ 1333{
@@ -1336,6 +1396,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
1336 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1396 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1337 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1397 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
1338 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); 1398 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
1399 radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
1339 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); 1400 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
1340 break; 1401 break;
1341 case ENCODER_OBJECT_ID_INTERNAL_DVO1: 1402 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
@@ -1345,8 +1406,14 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
1345 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 1406 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
1346 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 1407 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1347 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 1408 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1348 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); 1409 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
1349 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); 1410 radeon_encoder->rmx_type = RMX_FULL;
1411 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
1412 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
1413 } else {
1414 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
1415 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
1416 }
1350 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); 1417 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1351 break; 1418 break;
1352 } 1419 }
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index ec383edf5f38..944e4fa78db5 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -28,15 +28,7 @@
28 */ 28 */
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/errno.h>
33#include <linux/string.h>
34#include <linux/mm.h>
35#include <linux/tty.h>
36#include <linux/slab.h>
37#include <linux/delay.h>
38#include <linux/fb.h> 31#include <linux/fb.h>
39#include <linux/init.h>
40 32
41#include "drmP.h" 33#include "drmP.h"
42#include "drm.h" 34#include "drm.h"
@@ -45,375 +37,24 @@
45#include "radeon_drm.h" 37#include "radeon_drm.h"
46#include "radeon.h" 38#include "radeon.h"
47 39
40#include "drm_fb_helper.h"
41
48struct radeon_fb_device { 42struct radeon_fb_device {
49 struct radeon_device *rdev; 43 struct drm_fb_helper helper;
50 struct drm_display_mode *mode;
51 struct radeon_framebuffer *rfb; 44 struct radeon_framebuffer *rfb;
52 int crtc_count; 45 struct radeon_device *rdev;
53 /* crtc currently bound to this */
54 uint32_t crtc_ids[2];
55}; 46};
56 47
57static int radeonfb_setcolreg(unsigned regno,
58 unsigned red,
59 unsigned green,
60 unsigned blue,
61 unsigned transp,
62 struct fb_info *info)
63{
64 struct radeon_fb_device *rfbdev = info->par;
65 struct drm_device *dev = rfbdev->rdev->ddev;
66 struct drm_crtc *crtc;
67 int i;
68
69 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
70 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
71 struct drm_mode_set *modeset = &radeon_crtc->mode_set;
72 struct drm_framebuffer *fb = modeset->fb;
73
74 for (i = 0; i < rfbdev->crtc_count; i++) {
75 if (crtc->base.id == rfbdev->crtc_ids[i]) {
76 break;
77 }
78 }
79 if (i == rfbdev->crtc_count) {
80 continue;
81 }
82 if (regno > 255) {
83 return 1;
84 }
85 if (fb->depth == 8) {
86 radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno);
87 return 0;
88 }
89
90 if (regno < 16) {
91 switch (fb->depth) {
92 case 15:
93 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
94 ((green & 0xf800) >> 6) |
95 ((blue & 0xf800) >> 11);
96 break;
97 case 16:
98 fb->pseudo_palette[regno] = (red & 0xf800) |
99 ((green & 0xfc00) >> 5) |
100 ((blue & 0xf800) >> 11);
101 break;
102 case 24:
103 case 32:
104 fb->pseudo_palette[regno] =
105 (((red >> 8) & 0xff) << info->var.red.offset) |
106 (((green >> 8) & 0xff) << info->var.green.offset) |
107 (((blue >> 8) & 0xff) << info->var.blue.offset);
108 break;
109 }
110 }
111 }
112 return 0;
113}
114
115static int radeonfb_check_var(struct fb_var_screeninfo *var,
116 struct fb_info *info)
117{
118 struct radeon_fb_device *rfbdev = info->par;
119 struct radeon_framebuffer *rfb = rfbdev->rfb;
120 struct drm_framebuffer *fb = &rfb->base;
121 int depth;
122
123 if (var->pixclock == -1 || !var->pixclock) {
124 return -EINVAL;
125 }
126 /* Need to resize the fb object !!! */
127 if (var->xres > fb->width || var->yres > fb->height) {
128 DRM_ERROR("Requested width/height is greater than current fb "
129 "object %dx%d > %dx%d\n", var->xres, var->yres,
130 fb->width, fb->height);
131 DRM_ERROR("Need resizing code.\n");
132 return -EINVAL;
133 }
134
135 switch (var->bits_per_pixel) {
136 case 16:
137 depth = (var->green.length == 6) ? 16 : 15;
138 break;
139 case 32:
140 depth = (var->transp.length > 0) ? 32 : 24;
141 break;
142 default:
143 depth = var->bits_per_pixel;
144 break;
145 }
146
147 switch (depth) {
148 case 8:
149 var->red.offset = 0;
150 var->green.offset = 0;
151 var->blue.offset = 0;
152 var->red.length = 8;
153 var->green.length = 8;
154 var->blue.length = 8;
155 var->transp.length = 0;
156 var->transp.offset = 0;
157 break;
158#ifdef __LITTLE_ENDIAN
159 case 15:
160 var->red.offset = 10;
161 var->green.offset = 5;
162 var->blue.offset = 0;
163 var->red.length = 5;
164 var->green.length = 5;
165 var->blue.length = 5;
166 var->transp.length = 1;
167 var->transp.offset = 15;
168 break;
169 case 16:
170 var->red.offset = 11;
171 var->green.offset = 5;
172 var->blue.offset = 0;
173 var->red.length = 5;
174 var->green.length = 6;
175 var->blue.length = 5;
176 var->transp.length = 0;
177 var->transp.offset = 0;
178 break;
179 case 24:
180 var->red.offset = 16;
181 var->green.offset = 8;
182 var->blue.offset = 0;
183 var->red.length = 8;
184 var->green.length = 8;
185 var->blue.length = 8;
186 var->transp.length = 0;
187 var->transp.offset = 0;
188 break;
189 case 32:
190 var->red.offset = 16;
191 var->green.offset = 8;
192 var->blue.offset = 0;
193 var->red.length = 8;
194 var->green.length = 8;
195 var->blue.length = 8;
196 var->transp.length = 8;
197 var->transp.offset = 24;
198 break;
199#else
200 case 24:
201 var->red.offset = 8;
202 var->green.offset = 16;
203 var->blue.offset = 24;
204 var->red.length = 8;
205 var->green.length = 8;
206 var->blue.length = 8;
207 var->transp.length = 0;
208 var->transp.offset = 0;
209 break;
210 case 32:
211 var->red.offset = 8;
212 var->green.offset = 16;
213 var->blue.offset = 24;
214 var->red.length = 8;
215 var->green.length = 8;
216 var->blue.length = 8;
217 var->transp.length = 8;
218 var->transp.offset = 0;
219 break;
220#endif
221 default:
222 return -EINVAL;
223 }
224 return 0;
225}
226
227/* this will let fbcon do the mode init */
228static int radeonfb_set_par(struct fb_info *info)
229{
230 struct radeon_fb_device *rfbdev = info->par;
231 struct drm_device *dev = rfbdev->rdev->ddev;
232 struct fb_var_screeninfo *var = &info->var;
233 struct drm_crtc *crtc;
234 int ret;
235 int i;
236
237 if (var->pixclock != -1) {
238 DRM_ERROR("PIXEL CLCOK SET\n");
239 return -EINVAL;
240 }
241
242 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
243 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
244
245 for (i = 0; i < rfbdev->crtc_count; i++) {
246 if (crtc->base.id == rfbdev->crtc_ids[i]) {
247 break;
248 }
249 }
250 if (i == rfbdev->crtc_count) {
251 continue;
252 }
253 if (crtc->fb == radeon_crtc->mode_set.fb) {
254 mutex_lock(&dev->mode_config.mutex);
255 ret = crtc->funcs->set_config(&radeon_crtc->mode_set);
256 mutex_unlock(&dev->mode_config.mutex);
257 if (ret) {
258 return ret;
259 }
260 }
261 }
262 return 0;
263}
264
265static int radeonfb_pan_display(struct fb_var_screeninfo *var,
266 struct fb_info *info)
267{
268 struct radeon_fb_device *rfbdev = info->par;
269 struct drm_device *dev = rfbdev->rdev->ddev;
270 struct drm_mode_set *modeset;
271 struct drm_crtc *crtc;
272 struct radeon_crtc *radeon_crtc;
273 int ret = 0;
274 int i;
275
276 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
277 for (i = 0; i < rfbdev->crtc_count; i++) {
278 if (crtc->base.id == rfbdev->crtc_ids[i]) {
279 break;
280 }
281 }
282
283 if (i == rfbdev->crtc_count) {
284 continue;
285 }
286
287 radeon_crtc = to_radeon_crtc(crtc);
288 modeset = &radeon_crtc->mode_set;
289
290 modeset->x = var->xoffset;
291 modeset->y = var->yoffset;
292
293 if (modeset->num_connectors) {
294 mutex_lock(&dev->mode_config.mutex);
295 ret = crtc->funcs->set_config(modeset);
296 mutex_unlock(&dev->mode_config.mutex);
297 if (!ret) {
298 info->var.xoffset = var->xoffset;
299 info->var.yoffset = var->yoffset;
300 }
301 }
302 }
303 return ret;
304}
305
306static void radeonfb_on(struct fb_info *info)
307{
308 struct radeon_fb_device *rfbdev = info->par;
309 struct drm_device *dev = rfbdev->rdev->ddev;
310 struct drm_crtc *crtc;
311 struct drm_encoder *encoder;
312 int i;
313
314 /*
315 * For each CRTC in this fb, find all associated encoders
316 * and turn them off, then turn off the CRTC.
317 */
318 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
319 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
320
321 for (i = 0; i < rfbdev->crtc_count; i++) {
322 if (crtc->base.id == rfbdev->crtc_ids[i]) {
323 break;
324 }
325 }
326
327 mutex_lock(&dev->mode_config.mutex);
328 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
329 mutex_unlock(&dev->mode_config.mutex);
330
331 /* Found a CRTC on this fb, now find encoders */
332 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
333 if (encoder->crtc == crtc) {
334 struct drm_encoder_helper_funcs *encoder_funcs;
335
336 encoder_funcs = encoder->helper_private;
337 mutex_lock(&dev->mode_config.mutex);
338 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
339 mutex_unlock(&dev->mode_config.mutex);
340 }
341 }
342 }
343}
344
345static void radeonfb_off(struct fb_info *info, int dpms_mode)
346{
347 struct radeon_fb_device *rfbdev = info->par;
348 struct drm_device *dev = rfbdev->rdev->ddev;
349 struct drm_crtc *crtc;
350 struct drm_encoder *encoder;
351 int i;
352
353 /*
354 * For each CRTC in this fb, find all associated encoders
355 * and turn them off, then turn off the CRTC.
356 */
357 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
358 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
359
360 for (i = 0; i < rfbdev->crtc_count; i++) {
361 if (crtc->base.id == rfbdev->crtc_ids[i]) {
362 break;
363 }
364 }
365
366 /* Found a CRTC on this fb, now find encoders */
367 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
368 if (encoder->crtc == crtc) {
369 struct drm_encoder_helper_funcs *encoder_funcs;
370
371 encoder_funcs = encoder->helper_private;
372 mutex_lock(&dev->mode_config.mutex);
373 encoder_funcs->dpms(encoder, dpms_mode);
374 mutex_unlock(&dev->mode_config.mutex);
375 }
376 }
377 if (dpms_mode == DRM_MODE_DPMS_OFF) {
378 mutex_lock(&dev->mode_config.mutex);
379 crtc_funcs->dpms(crtc, dpms_mode);
380 mutex_unlock(&dev->mode_config.mutex);
381 }
382 }
383}
384
385int radeonfb_blank(int blank, struct fb_info *info)
386{
387 switch (blank) {
388 case FB_BLANK_UNBLANK:
389 radeonfb_on(info);
390 break;
391 case FB_BLANK_NORMAL:
392 radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
393 break;
394 case FB_BLANK_HSYNC_SUSPEND:
395 radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
396 break;
397 case FB_BLANK_VSYNC_SUSPEND:
398 radeonfb_off(info, DRM_MODE_DPMS_SUSPEND);
399 break;
400 case FB_BLANK_POWERDOWN:
401 radeonfb_off(info, DRM_MODE_DPMS_OFF);
402 break;
403 }
404 return 0;
405}
406
407static struct fb_ops radeonfb_ops = { 48static struct fb_ops radeonfb_ops = {
408 .owner = THIS_MODULE, 49 .owner = THIS_MODULE,
409 .fb_check_var = radeonfb_check_var, 50 .fb_check_var = drm_fb_helper_check_var,
410 .fb_set_par = radeonfb_set_par, 51 .fb_set_par = drm_fb_helper_set_par,
411 .fb_setcolreg = radeonfb_setcolreg, 52 .fb_setcolreg = drm_fb_helper_setcolreg,
412 .fb_fillrect = cfb_fillrect, 53 .fb_fillrect = cfb_fillrect,
413 .fb_copyarea = cfb_copyarea, 54 .fb_copyarea = cfb_copyarea,
414 .fb_imageblit = cfb_imageblit, 55 .fb_imageblit = cfb_imageblit,
415 .fb_pan_display = radeonfb_pan_display, 56 .fb_pan_display = drm_fb_helper_pan_display,
416 .fb_blank = radeonfb_blank, 57 .fb_blank = drm_fb_helper_blank,
417}; 58};
418 59
419/** 60/**
@@ -456,21 +97,6 @@ int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
456} 97}
457EXPORT_SYMBOL(radeonfb_resize); 98EXPORT_SYMBOL(radeonfb_resize);
458 99
459static struct drm_mode_set panic_mode;
460
461int radeonfb_panic(struct notifier_block *n, unsigned long ununsed,
462 void *panic_str)
463{
464 DRM_ERROR("panic occurred, switching back to text console\n");
465 drm_crtc_helper_set_config(&panic_mode);
466 return 0;
467}
468EXPORT_SYMBOL(radeonfb_panic);
469
470static struct notifier_block paniced = {
471 .notifier_call = radeonfb_panic,
472};
473
474static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) 100static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
475{ 101{
476 int aligned = width; 102 int aligned = width;
@@ -495,11 +121,16 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
495 return aligned; 121 return aligned;
496} 122}
497 123
498int radeonfb_create(struct radeon_device *rdev, 124static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
125 .gamma_set = radeon_crtc_fb_gamma_set,
126};
127
128int radeonfb_create(struct drm_device *dev,
499 uint32_t fb_width, uint32_t fb_height, 129 uint32_t fb_width, uint32_t fb_height,
500 uint32_t surface_width, uint32_t surface_height, 130 uint32_t surface_width, uint32_t surface_height,
501 struct radeon_framebuffer **rfb_p) 131 struct drm_framebuffer **fb_p)
502{ 132{
133 struct radeon_device *rdev = dev->dev_private;
503 struct fb_info *info; 134 struct fb_info *info;
504 struct radeon_fb_device *rfbdev; 135 struct radeon_fb_device *rfbdev;
505 struct drm_framebuffer *fb = NULL; 136 struct drm_framebuffer *fb = NULL;
@@ -513,6 +144,7 @@ int radeonfb_create(struct radeon_device *rdev,
513 void *fbptr = NULL; 144 void *fbptr = NULL;
514 unsigned long tmp; 145 unsigned long tmp;
515 bool fb_tiled = false; /* useful for testing */ 146 bool fb_tiled = false; /* useful for testing */
147 u32 tiling_flags = 0;
516 148
517 mode_cmd.width = surface_width; 149 mode_cmd.width = surface_width;
518 mode_cmd.height = surface_height; 150 mode_cmd.height = surface_height;
@@ -537,7 +169,22 @@ int radeonfb_create(struct radeon_device *rdev,
537 robj = gobj->driver_private; 169 robj = gobj->driver_private;
538 170
539 if (fb_tiled) 171 if (fb_tiled)
540 radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch); 172 tiling_flags = RADEON_TILING_MACRO;
173
174#ifdef __BIG_ENDIAN
175 switch (mode_cmd.bpp) {
176 case 32:
177 tiling_flags |= RADEON_TILING_SWAP_32BIT;
178 break;
179 case 16:
180 tiling_flags |= RADEON_TILING_SWAP_16BIT;
181 default:
182 break;
183 }
184#endif
185
186 if (tiling_flags)
187 radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
541 mutex_lock(&rdev->ddev->struct_mutex); 188 mutex_lock(&rdev->ddev->struct_mutex);
542 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); 189 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
543 if (fb == NULL) { 190 if (fb == NULL) {
@@ -554,8 +201,8 @@ int radeonfb_create(struct radeon_device *rdev,
554 201
555 list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); 202 list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list);
556 203
204 *fb_p = fb;
557 rfb = to_radeon_framebuffer(fb); 205 rfb = to_radeon_framebuffer(fb);
558 *rfb_p = rfb;
559 rdev->fbdev_rfb = rfb; 206 rdev->fbdev_rfb = rfb;
560 rdev->fbdev_robj = robj; 207 rdev->fbdev_robj = robj;
561 208
@@ -564,7 +211,15 @@ int radeonfb_create(struct radeon_device *rdev,
564 ret = -ENOMEM; 211 ret = -ENOMEM;
565 goto out_unref; 212 goto out_unref;
566 } 213 }
214
215 rdev->fbdev_info = info;
567 rfbdev = info->par; 216 rfbdev = info->par;
217 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
218 rfbdev->helper.dev = dev;
219 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2,
220 RADEONFB_CONN_LIMIT);
221 if (ret)
222 goto out_unref;
568 223
569 if (fb_tiled) 224 if (fb_tiled)
570 radeon_object_check_tiling(robj, 0, 0); 225 radeon_object_check_tiling(robj, 0, 0);
@@ -577,33 +232,19 @@ int radeonfb_create(struct radeon_device *rdev,
577 memset_io(fbptr, 0, aligned_size); 232 memset_io(fbptr, 0, aligned_size);
578 233
579 strcpy(info->fix.id, "radeondrmfb"); 234 strcpy(info->fix.id, "radeondrmfb");
580 info->fix.type = FB_TYPE_PACKED_PIXELS; 235
581 info->fix.visual = FB_VISUAL_TRUECOLOR; 236 drm_fb_helper_fill_fix(info, fb->pitch);
582 info->fix.type_aux = 0; 237
583 info->fix.xpanstep = 1; /* doing it in hw */
584 info->fix.ypanstep = 1; /* doing it in hw */
585 info->fix.ywrapstep = 0;
586 info->fix.accel = FB_ACCEL_NONE;
587 info->fix.type_aux = 0;
588 info->flags = FBINFO_DEFAULT; 238 info->flags = FBINFO_DEFAULT;
589 info->fbops = &radeonfb_ops; 239 info->fbops = &radeonfb_ops;
590 info->fix.line_length = fb->pitch; 240
591 tmp = fb_gpuaddr - rdev->mc.vram_location; 241 tmp = fb_gpuaddr - rdev->mc.vram_location;
592 info->fix.smem_start = rdev->mc.aper_base + tmp; 242 info->fix.smem_start = rdev->mc.aper_base + tmp;
593 info->fix.smem_len = size; 243 info->fix.smem_len = size;
594 info->screen_base = fbptr; 244 info->screen_base = fbptr;
595 info->screen_size = size; 245 info->screen_size = size;
596 info->pseudo_palette = fb->pseudo_palette; 246
597 info->var.xres_virtual = fb->width; 247 drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
598 info->var.yres_virtual = fb->height;
599 info->var.bits_per_pixel = fb->bits_per_pixel;
600 info->var.xoffset = 0;
601 info->var.yoffset = 0;
602 info->var.activate = FB_ACTIVATE_NOW;
603 info->var.height = -1;
604 info->var.width = -1;
605 info->var.xres = fb_width;
606 info->var.yres = fb_height;
607 248
608 /* setup aperture base/size for vesafb takeover */ 249 /* setup aperture base/size for vesafb takeover */
609 info->aperture_base = rdev->ddev->mode_config.fb_base; 250 info->aperture_base = rdev->ddev->mode_config.fb_base;
@@ -626,83 +267,6 @@ int radeonfb_create(struct radeon_device *rdev,
626 DRM_INFO("fb depth is %d\n", fb->depth); 267 DRM_INFO("fb depth is %d\n", fb->depth);
627 DRM_INFO(" pitch is %d\n", fb->pitch); 268 DRM_INFO(" pitch is %d\n", fb->pitch);
628 269
629 switch (fb->depth) {
630 case 8:
631 info->var.red.offset = 0;
632 info->var.green.offset = 0;
633 info->var.blue.offset = 0;
634 info->var.red.length = 8; /* 8bit DAC */
635 info->var.green.length = 8;
636 info->var.blue.length = 8;
637 info->var.transp.offset = 0;
638 info->var.transp.length = 0;
639 break;
640#ifdef __LITTLE_ENDIAN
641 case 15:
642 info->var.red.offset = 10;
643 info->var.green.offset = 5;
644 info->var.blue.offset = 0;
645 info->var.red.length = 5;
646 info->var.green.length = 5;
647 info->var.blue.length = 5;
648 info->var.transp.offset = 15;
649 info->var.transp.length = 1;
650 break;
651 case 16:
652 info->var.red.offset = 11;
653 info->var.green.offset = 5;
654 info->var.blue.offset = 0;
655 info->var.red.length = 5;
656 info->var.green.length = 6;
657 info->var.blue.length = 5;
658 info->var.transp.offset = 0;
659 break;
660 case 24:
661 info->var.red.offset = 16;
662 info->var.green.offset = 8;
663 info->var.blue.offset = 0;
664 info->var.red.length = 8;
665 info->var.green.length = 8;
666 info->var.blue.length = 8;
667 info->var.transp.offset = 0;
668 info->var.transp.length = 0;
669 break;
670 case 32:
671 info->var.red.offset = 16;
672 info->var.green.offset = 8;
673 info->var.blue.offset = 0;
674 info->var.red.length = 8;
675 info->var.green.length = 8;
676 info->var.blue.length = 8;
677 info->var.transp.offset = 24;
678 info->var.transp.length = 8;
679 break;
680#else
681 case 24:
682 info->var.red.offset = 8;
683 info->var.green.offset = 16;
684 info->var.blue.offset = 24;
685 info->var.red.length = 8;
686 info->var.green.length = 8;
687 info->var.blue.length = 8;
688 info->var.transp.offset = 0;
689 info->var.transp.length = 0;
690 break;
691 case 32:
692 info->var.red.offset = 8;
693 info->var.green.offset = 16;
694 info->var.blue.offset = 24;
695 info->var.red.length = 8;
696 info->var.green.length = 8;
697 info->var.blue.length = 8;
698 info->var.transp.offset = 0;
699 info->var.transp.length = 8;
700 break;
701 default:
702#endif
703 break;
704 }
705
706 fb->fbdev = info; 270 fb->fbdev = info;
707 rfbdev->rfb = rfb; 271 rfbdev->rfb = rfb;
708 rfbdev->rdev = rdev; 272 rfbdev->rdev = rdev;
@@ -726,145 +290,10 @@ out:
726 return ret; 290 return ret;
727} 291}
728 292
729static int radeonfb_single_fb_probe(struct radeon_device *rdev)
730{
731 struct drm_crtc *crtc;
732 struct drm_connector *connector;
733 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
734 unsigned int surface_width = 0, surface_height = 0;
735 int new_fb = 0;
736 int crtc_count = 0;
737 int ret, i, conn_count = 0;
738 struct radeon_framebuffer *rfb;
739 struct fb_info *info;
740 struct radeon_fb_device *rfbdev;
741 struct drm_mode_set *modeset = NULL;
742
743 /* first up get a count of crtcs now in use and new min/maxes width/heights */
744 list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
745 if (drm_helper_crtc_in_use(crtc)) {
746 if (crtc->desired_mode) {
747 if (crtc->desired_mode->hdisplay < fb_width)
748 fb_width = crtc->desired_mode->hdisplay;
749
750 if (crtc->desired_mode->vdisplay < fb_height)
751 fb_height = crtc->desired_mode->vdisplay;
752
753 if (crtc->desired_mode->hdisplay > surface_width)
754 surface_width = crtc->desired_mode->hdisplay;
755
756 if (crtc->desired_mode->vdisplay > surface_height)
757 surface_height = crtc->desired_mode->vdisplay;
758 }
759 crtc_count++;
760 }
761 }
762
763 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
764 /* hmm everyone went away - assume VGA cable just fell out
765 and will come back later. */
766 return 0;
767 }
768
769 /* do we have an fb already? */
770 if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) {
771 /* create an fb if we don't have one */
772 ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb);
773 if (ret) {
774 return -EINVAL;
775 }
776 new_fb = 1;
777 } else {
778 struct drm_framebuffer *fb;
779 fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head);
780 rfb = to_radeon_framebuffer(fb);
781
782 /* if someone hotplugs something bigger than we have already allocated, we are pwned.
783 As really we can't resize an fbdev that is in the wild currently due to fbdev
784 not really being designed for the lower layers moving stuff around under it.
785 - so in the grand style of things - punt. */
786 if ((fb->width < surface_width) || (fb->height < surface_height)) {
787 DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
788 return -EINVAL;
789 }
790 }
791
792 info = rfb->base.fbdev;
793 rdev->fbdev_info = info;
794 rfbdev = info->par;
795
796 crtc_count = 0;
797 /* okay we need to setup new connector sets in the crtcs */
798 list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
799 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
800 modeset = &radeon_crtc->mode_set;
801 modeset->fb = &rfb->base;
802 conn_count = 0;
803 list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) {
804 if (connector->encoder)
805 if (connector->encoder->crtc == modeset->crtc) {
806 modeset->connectors[conn_count] = connector;
807 conn_count++;
808 if (conn_count > RADEONFB_CONN_LIMIT)
809 BUG();
810 }
811 }
812
813 for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++)
814 modeset->connectors[i] = NULL;
815
816
817 rfbdev->crtc_ids[crtc_count++] = crtc->base.id;
818
819 modeset->num_connectors = conn_count;
820 if (modeset->crtc->desired_mode) {
821 if (modeset->mode) {
822 drm_mode_destroy(rdev->ddev, modeset->mode);
823 }
824 modeset->mode = drm_mode_duplicate(rdev->ddev,
825 modeset->crtc->desired_mode);
826 }
827 }
828 rfbdev->crtc_count = crtc_count;
829
830 if (new_fb) {
831 info->var.pixclock = -1;
832 if (register_framebuffer(info) < 0)
833 return -EINVAL;
834 } else {
835 radeonfb_set_par(info);
836 }
837 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
838 info->fix.id);
839
840 /* Switch back to kernel console on panic */
841 panic_mode = *modeset;
842 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
843 printk(KERN_INFO "registered panic notifier\n");
844
845 return 0;
846}
847
848int radeonfb_probe(struct drm_device *dev) 293int radeonfb_probe(struct drm_device *dev)
849{ 294{
850 int ret; 295 int ret;
851 296 ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
852 /* something has changed in the lower levels of hell - deal with it
853 here */
854
855 /* two modes : a) 1 fb to rule all crtcs.
856 b) one fb per crtc.
857 two actions 1) new connected device
858 2) device removed.
859 case a/1 : if the fb surface isn't big enough - resize the surface fb.
860 if the fb size isn't big enough - resize fb into surface.
861 if everything big enough configure the new crtc/etc.
862 case a/2 : undo the configuration
863 possibly resize down the fb to fit the new configuration.
864 case b/1 : see if it is on a new crtc - setup a new fb and add it.
865 case b/2 : teardown the new fb.
866 */
867 ret = radeonfb_single_fb_probe(dev->dev_private);
868 return ret; 297 return ret;
869} 298}
870EXPORT_SYMBOL(radeonfb_probe); 299EXPORT_SYMBOL(radeonfb_probe);
@@ -880,16 +309,17 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
880 } 309 }
881 info = fb->fbdev; 310 info = fb->fbdev;
882 if (info) { 311 if (info) {
312 struct radeon_fb_device *rfbdev = info->par;
883 robj = rfb->obj->driver_private; 313 robj = rfb->obj->driver_private;
884 unregister_framebuffer(info); 314 unregister_framebuffer(info);
885 radeon_object_kunmap(robj); 315 radeon_object_kunmap(robj);
886 radeon_object_unpin(robj); 316 radeon_object_unpin(robj);
317 drm_fb_helper_free(&rfbdev->helper);
887 framebuffer_release(info); 318 framebuffer_release(info);
888 } 319 }
889 320
890 printk(KERN_INFO "unregistered panic notifier\n"); 321 printk(KERN_INFO "unregistered panic notifier\n");
891 atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); 322
892 memset(&panic_mode, 0, sizeof(struct drm_mode_set));
893 return 0; 323 return 0;
894} 324}
895EXPORT_SYMBOL(radeonfb_remove); 325EXPORT_SYMBOL(radeonfb_remove);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index b4e48dd2e859..3beb26d74719 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -53,9 +53,9 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
53 * away 53 * away
54 */ 54 */
55 WREG32(rdev->fence_drv.scratch_reg, fence->seq); 55 WREG32(rdev->fence_drv.scratch_reg, fence->seq);
56 } else { 56 } else
57 radeon_fence_ring_emit(rdev, fence); 57 radeon_fence_ring_emit(rdev, fence);
58 } 58
59 fence->emited = true; 59 fence->emited = true;
60 fence->timeout = jiffies + ((2000 * HZ) / 1000); 60 fence->timeout = jiffies + ((2000 * HZ) / 1000);
61 list_del(&fence->list); 61 list_del(&fence->list);
@@ -168,7 +168,38 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
168 return signaled; 168 return signaled;
169} 169}
170 170
171int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) 171int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy)
172{
173 struct radeon_device *rdev;
174 int ret = 0;
175
176 rdev = fence->rdev;
177
178 __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
179
180 while (1) {
181 if (radeon_fence_signaled(fence))
182 break;
183
184 if (time_after_eq(jiffies, fence->timeout)) {
185 ret = -EBUSY;
186 break;
187 }
188
189 if (lazy)
190 schedule_timeout(1);
191
192 if (intr && signal_pending(current)) {
193 ret = -ERESTARTSYS;
194 break;
195 }
196 }
197 __set_current_state(TASK_RUNNING);
198 return ret;
199}
200
201
202int radeon_fence_wait(struct radeon_fence *fence, bool intr)
172{ 203{
173 struct radeon_device *rdev; 204 struct radeon_device *rdev;
174 unsigned long cur_jiffies; 205 unsigned long cur_jiffies;
@@ -176,7 +207,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
176 bool expired = false; 207 bool expired = false;
177 int r; 208 int r;
178 209
179
180 if (fence == NULL) { 210 if (fence == NULL) {
181 WARN(1, "Querying an invalid fence : %p !\n", fence); 211 WARN(1, "Querying an invalid fence : %p !\n", fence);
182 return 0; 212 return 0;
@@ -185,13 +215,22 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
185 if (radeon_fence_signaled(fence)) { 215 if (radeon_fence_signaled(fence)) {
186 return 0; 216 return 0;
187 } 217 }
218
219 if (rdev->family >= CHIP_R600) {
220 r = r600_fence_wait(fence, intr, 0);
221 if (r == -ERESTARTSYS)
222 return -EBUSY;
223 return r;
224 }
225
188retry: 226retry:
189 cur_jiffies = jiffies; 227 cur_jiffies = jiffies;
190 timeout = HZ / 100; 228 timeout = HZ / 100;
191 if (time_after(fence->timeout, cur_jiffies)) { 229 if (time_after(fence->timeout, cur_jiffies)) {
192 timeout = fence->timeout - cur_jiffies; 230 timeout = fence->timeout - cur_jiffies;
193 } 231 }
194 if (interruptible) { 232
233 if (intr) {
195 r = wait_event_interruptible_timeout(rdev->fence_drv.queue, 234 r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
196 radeon_fence_signaled(fence), timeout); 235 radeon_fence_signaled(fence), timeout);
197 if (unlikely(r == -ERESTARTSYS)) { 236 if (unlikely(r == -ERESTARTSYS)) {
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 2977539880fb..a931af065dd4 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -75,7 +75,6 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev)
75 75
76int radeon_gart_table_vram_alloc(struct radeon_device *rdev) 76int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
77{ 77{
78 uint64_t gpu_addr;
79 int r; 78 int r;
80 79
81 if (rdev->gart.table.vram.robj == NULL) { 80 if (rdev->gart.table.vram.robj == NULL) {
@@ -88,6 +87,14 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
88 return r; 87 return r;
89 } 88 }
90 } 89 }
90 return 0;
91}
92
93int radeon_gart_table_vram_pin(struct radeon_device *rdev)
94{
95 uint64_t gpu_addr;
96 int r;
97
91 r = radeon_object_pin(rdev->gart.table.vram.robj, 98 r = radeon_object_pin(rdev->gart.table.vram.robj,
92 RADEON_GEM_DOMAIN_VRAM, &gpu_addr); 99 RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
93 if (r) { 100 if (r) {
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
index 56decda2a71f..a1bf11de308a 100644
--- a/drivers/gpu/drm/radeon/radeon_ioc32.c
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -422,3 +422,18 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
422 422
423 return ret; 423 return ret;
424} 424}
425
426long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
427{
428 unsigned int nr = DRM_IOCTL_NR(cmd);
429 int ret;
430
431 if (nr < DRM_COMMAND_BASE)
432 return drm_compat_ioctl(filp, cmd, arg);
433
434 lock_kernel(); /* XXX for now */
435 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
436 unlock_kernel();
437
438 return ret;
439}
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 9836c705a952..b79ecc4a7cc4 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -188,6 +188,9 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
188 u32 stat; 188 u32 stat;
189 u32 r500_disp_int; 189 u32 r500_disp_int;
190 190
191 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
192 return IRQ_NONE;
193
191 /* Only consider the bits we're interested in - others could be used 194 /* Only consider the bits we're interested in - others could be used
192 * outside the DRM 195 * outside the DRM
193 */ 196 */
@@ -286,6 +289,9 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr
286 drm_radeon_irq_emit_t *emit = data; 289 drm_radeon_irq_emit_t *emit = data;
287 int result; 290 int result;
288 291
292 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
293 return -EINVAL;
294
289 LOCK_TEST_WITH_RETURN(dev, file_priv); 295 LOCK_TEST_WITH_RETURN(dev, file_priv);
290 296
291 if (!dev_priv) { 297 if (!dev_priv) {
@@ -315,6 +321,9 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
315 return -EINVAL; 321 return -EINVAL;
316 } 322 }
317 323
324 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
325 return -EINVAL;
326
318 return radeon_wait_irq(dev, irqwait->irq_seq); 327 return radeon_wait_irq(dev, irqwait->irq_seq);
319} 328}
320 329
@@ -326,6 +335,9 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
326 (drm_radeon_private_t *) dev->dev_private; 335 (drm_radeon_private_t *) dev->dev_private;
327 u32 dummy; 336 u32 dummy;
328 337
338 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
339 return;
340
329 /* Disable *all* interrupts */ 341 /* Disable *all* interrupts */
330 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 342 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
331 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 343 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
@@ -345,6 +357,9 @@ int radeon_driver_irq_postinstall(struct drm_device *dev)
345 357
346 dev->max_vblank_count = 0x001fffff; 358 dev->max_vblank_count = 0x001fffff;
347 359
360 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
361 return 0;
362
348 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 363 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
349 364
350 return 0; 365 return 0;
@@ -357,6 +372,9 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
357 if (!dev_priv) 372 if (!dev_priv)
358 return; 373 return;
359 374
375 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
376 return;
377
360 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) 378 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
361 RADEON_WRITE(R500_DxMODE_INT_MASK, 0); 379 RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
362 /* Disable *all* interrupts */ 380 /* Disable *all* interrupts */
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 9805e4b6ca1b..1841145a7c4f 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -28,7 +28,6 @@
28#include "drmP.h" 28#include "drmP.h"
29#include "radeon_drm.h" 29#include "radeon_drm.h"
30#include "radeon_reg.h" 30#include "radeon_reg.h"
31#include "radeon_microcode.h"
32#include "radeon.h" 31#include "radeon.h"
33#include "atom.h" 32#include "atom.h"
34 33
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index dce09ada32bc..709bd892b3a9 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -54,12 +54,23 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
54 flags |= RADEON_IS_PCI; 54 flags |= RADEON_IS_PCI;
55 } 55 }
56 56
57 /* radeon_device_init should report only fatal error
58 * like memory allocation failure or iomapping failure,
59 * or memory manager initialization failure, it must
60 * properly initialize the GPU MC controller and permit
61 * VRAM allocation
62 */
57 r = radeon_device_init(rdev, dev, dev->pdev, flags); 63 r = radeon_device_init(rdev, dev, dev->pdev, flags);
58 if (r) { 64 if (r) {
59 DRM_ERROR("Failed to initialize radeon, disabling IOCTL\n"); 65 DRM_ERROR("Fatal error while trying to initialize radeon.\n");
60 radeon_device_fini(rdev); 66 return r;
61 kfree(rdev); 67 }
62 dev->dev_private = NULL; 68 /* Again modeset_init should fail only on fatal error
69 * otherwise it should provide enough functionalities
70 * for shadowfb to run
71 */
72 r = radeon_modeset_init(rdev);
73 if (r) {
63 return r; 74 return r;
64 } 75 }
65 return 0; 76 return 0;
@@ -69,6 +80,9 @@ int radeon_driver_unload_kms(struct drm_device *dev)
69{ 80{
70 struct radeon_device *rdev = dev->dev_private; 81 struct radeon_device *rdev = dev->dev_private;
71 82
83 if (rdev == NULL)
84 return 0;
85 radeon_modeset_fini(rdev);
72 radeon_device_fini(rdev); 86 radeon_device_fini(rdev);
73 kfree(rdev); 87 kfree(rdev);
74 dev->dev_private = NULL; 88 dev->dev_private = NULL;
@@ -98,6 +112,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
98 case RADEON_INFO_NUM_Z_PIPES: 112 case RADEON_INFO_NUM_Z_PIPES:
99 value = rdev->num_z_pipes; 113 value = rdev->num_z_pipes;
100 break; 114 break;
115 case RADEON_INFO_ACCEL_WORKING:
116 value = rdev->accel_working;
117 break;
101 default: 118 default:
102 DRM_DEBUG("Invalid request %d\n", info->request); 119 DRM_DEBUG("Invalid request %d\n", info->request);
103 return -EINVAL; 120 return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 0da72f18fd3a..2b997a15fb1f 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -28,6 +28,7 @@
28#include <drm/radeon_drm.h> 28#include <drm/radeon_drm.h>
29#include "radeon_fixed.h" 29#include "radeon_fixed.h"
30#include "radeon.h" 30#include "radeon.h"
31#include "atom.h"
31 32
32static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, 33static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
33 struct drm_display_mode *mode, 34 struct drm_display_mode *mode,
@@ -340,6 +341,9 @@ void radeon_legacy_atom_set_surface(struct drm_crtc *crtc)
340 uint32_t crtc_pitch; 341 uint32_t crtc_pitch;
341 342
342 switch (crtc->fb->bits_per_pixel) { 343 switch (crtc->fb->bits_per_pixel) {
344 case 8:
345 format = 2;
346 break;
343 case 15: /* 555 */ 347 case 15: /* 555 */
344 format = 3; 348 format = 3;
345 break; 349 break;
@@ -400,11 +404,33 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
400 uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; 404 uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
401 uint32_t crtc_pitch, pitch_pixels; 405 uint32_t crtc_pitch, pitch_pixels;
402 uint32_t tiling_flags; 406 uint32_t tiling_flags;
407 int format;
408 uint32_t gen_cntl_reg, gen_cntl_val;
403 409
404 DRM_DEBUG("\n"); 410 DRM_DEBUG("\n");
405 411
406 radeon_fb = to_radeon_framebuffer(crtc->fb); 412 radeon_fb = to_radeon_framebuffer(crtc->fb);
407 413
414 switch (crtc->fb->bits_per_pixel) {
415 case 8:
416 format = 2;
417 break;
418 case 15: /* 555 */
419 format = 3;
420 break;
421 case 16: /* 565 */
422 format = 4;
423 break;
424 case 24: /* RGB */
425 format = 5;
426 break;
427 case 32: /* xRGB */
428 format = 6;
429 break;
430 default:
431 return false;
432 }
433
408 obj = radeon_fb->obj; 434 obj = radeon_fb->obj;
409 if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) { 435 if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
410 return -EINVAL; 436 return -EINVAL;
@@ -457,6 +483,9 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
457 } else { 483 } else {
458 int offset = y * pitch_pixels + x; 484 int offset = y * pitch_pixels + x;
459 switch (crtc->fb->bits_per_pixel) { 485 switch (crtc->fb->bits_per_pixel) {
486 case 8:
487 offset *= 1;
488 break;
460 case 15: 489 case 15:
461 case 16: 490 case 16:
462 offset *= 2; 491 offset *= 2;
@@ -475,6 +504,16 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
475 504
476 base &= ~7; 505 base &= ~7;
477 506
507 if (radeon_crtc->crtc_id == 1)
508 gen_cntl_reg = RADEON_CRTC2_GEN_CNTL;
509 else
510 gen_cntl_reg = RADEON_CRTC_GEN_CNTL;
511
512 gen_cntl_val = RREG32(gen_cntl_reg);
513 gen_cntl_val &= ~(0xf << 8);
514 gen_cntl_val |= (format << 8);
515 WREG32(gen_cntl_reg, gen_cntl_val);
516
478 crtc_offset = (u32)base; 517 crtc_offset = (u32)base;
479 518
480 WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr); 519 WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr);
@@ -501,6 +540,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
501 struct drm_device *dev = crtc->dev; 540 struct drm_device *dev = crtc->dev;
502 struct radeon_device *rdev = dev->dev_private; 541 struct radeon_device *rdev = dev->dev_private;
503 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 542 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
543 struct drm_encoder *encoder;
504 int format; 544 int format;
505 int hsync_start; 545 int hsync_start;
506 int hsync_wid; 546 int hsync_wid;
@@ -509,10 +549,24 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
509 uint32_t crtc_h_sync_strt_wid; 549 uint32_t crtc_h_sync_strt_wid;
510 uint32_t crtc_v_total_disp; 550 uint32_t crtc_v_total_disp;
511 uint32_t crtc_v_sync_strt_wid; 551 uint32_t crtc_v_sync_strt_wid;
552 bool is_tv = false;
512 553
513 DRM_DEBUG("\n"); 554 DRM_DEBUG("\n");
555 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
556 if (encoder->crtc == crtc) {
557 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
558 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
559 is_tv = true;
560 DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id);
561 break;
562 }
563 }
564 }
514 565
515 switch (crtc->fb->bits_per_pixel) { 566 switch (crtc->fb->bits_per_pixel) {
567 case 8:
568 format = 2;
569 break;
516 case 15: /* 555 */ 570 case 15: /* 555 */
517 format = 3; 571 format = 3;
518 break; 572 break;
@@ -642,6 +696,11 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
642 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); 696 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
643 } 697 }
644 698
699 if (is_tv)
700 radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp,
701 &crtc_h_sync_strt_wid, &crtc_v_total_disp,
702 &crtc_v_sync_strt_wid);
703
645 WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp); 704 WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp);
646 WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid); 705 WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid);
647 WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp); 706 WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp);
@@ -668,7 +727,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
668 uint32_t pll_ref_div = 0; 727 uint32_t pll_ref_div = 0;
669 uint32_t pll_fb_post_div = 0; 728 uint32_t pll_fb_post_div = 0;
670 uint32_t htotal_cntl = 0; 729 uint32_t htotal_cntl = 0;
671 730 bool is_tv = false;
672 struct radeon_pll *pll; 731 struct radeon_pll *pll;
673 732
674 struct { 733 struct {
@@ -703,6 +762,13 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
703 762
704 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 763 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
705 if (encoder->crtc == crtc) { 764 if (encoder->crtc == crtc) {
765 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
766
767 if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
768 is_tv = true;
769 break;
770 }
771
706 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 772 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
707 pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; 773 pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
708 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { 774 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
@@ -766,6 +832,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
766 ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | 832 ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
767 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); 833 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
768 834
835 if (is_tv) {
836 radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl,
837 &pll_ref_div, &pll_fb_post_div,
838 &pixclks_cntl);
839 }
840
769 WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 841 WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
770 RADEON_PIX2CLK_SRC_SEL_CPUCLK, 842 RADEON_PIX2CLK_SRC_SEL_CPUCLK,
771 ~(RADEON_PIX2CLK_SRC_SEL_MASK)); 843 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
@@ -820,6 +892,15 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
820 892
821 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); 893 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
822 } else { 894 } else {
895 uint32_t pixclks_cntl;
896
897
898 if (is_tv) {
899 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
900 radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div,
901 &pll_fb_post_div, &pixclks_cntl);
902 }
903
823 if (rdev->flags & RADEON_IS_MOBILITY) { 904 if (rdev->flags & RADEON_IS_MOBILITY) {
824 /* A temporal workaround for the occational blanking on certain laptop panels. 905 /* A temporal workaround for the occational blanking on certain laptop panels.
825 This appears to related to the PLL divider registers (fail to lock?). 906 This appears to related to the PLL divider registers (fail to lock?).
@@ -914,6 +995,8 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
914 RADEON_VCLK_SRC_SEL_PPLLCLK, 995 RADEON_VCLK_SRC_SEL_PPLLCLK,
915 ~(RADEON_VCLK_SRC_SEL_MASK)); 996 ~(RADEON_VCLK_SRC_SEL_MASK));
916 997
998 if (is_tv)
999 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
917 } 1000 }
918} 1001}
919 1002
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 9322675ef6d0..b1547f700d73 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -29,6 +29,15 @@
29#include "radeon.h" 29#include "radeon.h"
30#include "atom.h" 30#include "atom.h"
31 31
32static void radeon_legacy_encoder_disable(struct drm_encoder *encoder)
33{
34 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
35 struct drm_encoder_helper_funcs *encoder_funcs;
36
37 encoder_funcs = encoder->helper_private;
38 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
39 radeon_encoder->active_device = 0;
40}
32 41
33static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) 42static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
34{ 43{
@@ -98,6 +107,8 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
98 else 107 else
99 radeon_combios_output_lock(encoder, true); 108 radeon_combios_output_lock(encoder, true);
100 radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); 109 radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
110
111 radeon_encoder_set_active_device(encoder);
101} 112}
102 113
103static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) 114static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
@@ -195,6 +206,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
195 .prepare = radeon_legacy_lvds_prepare, 206 .prepare = radeon_legacy_lvds_prepare,
196 .mode_set = radeon_legacy_lvds_mode_set, 207 .mode_set = radeon_legacy_lvds_mode_set,
197 .commit = radeon_legacy_lvds_commit, 208 .commit = radeon_legacy_lvds_commit,
209 .disable = radeon_legacy_encoder_disable,
198}; 210};
199 211
200 212
@@ -260,6 +272,7 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
260 else 272 else
261 radeon_combios_output_lock(encoder, true); 273 radeon_combios_output_lock(encoder, true);
262 radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); 274 radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
275 radeon_encoder_set_active_device(encoder);
263} 276}
264 277
265static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) 278static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
@@ -402,6 +415,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_fu
402 .mode_set = radeon_legacy_primary_dac_mode_set, 415 .mode_set = radeon_legacy_primary_dac_mode_set,
403 .commit = radeon_legacy_primary_dac_commit, 416 .commit = radeon_legacy_primary_dac_commit,
404 .detect = radeon_legacy_primary_dac_detect, 417 .detect = radeon_legacy_primary_dac_detect,
418 .disable = radeon_legacy_encoder_disable,
405}; 419};
406 420
407 421
@@ -454,6 +468,7 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
454 else 468 else
455 radeon_combios_output_lock(encoder, true); 469 radeon_combios_output_lock(encoder, true);
456 radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); 470 radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
471 radeon_encoder_set_active_device(encoder);
457} 472}
458 473
459static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) 474static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
@@ -566,6 +581,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs
566 .prepare = radeon_legacy_tmds_int_prepare, 581 .prepare = radeon_legacy_tmds_int_prepare,
567 .mode_set = radeon_legacy_tmds_int_mode_set, 582 .mode_set = radeon_legacy_tmds_int_mode_set,
568 .commit = radeon_legacy_tmds_int_commit, 583 .commit = radeon_legacy_tmds_int_commit,
584 .disable = radeon_legacy_encoder_disable,
569}; 585};
570 586
571 587
@@ -620,6 +636,7 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
620 else 636 else
621 radeon_combios_output_lock(encoder, true); 637 radeon_combios_output_lock(encoder, true);
622 radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); 638 radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
639 radeon_encoder_set_active_device(encoder);
623} 640}
624 641
625static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) 642static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
@@ -706,6 +723,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs
706 .prepare = radeon_legacy_tmds_ext_prepare, 723 .prepare = radeon_legacy_tmds_ext_prepare,
707 .mode_set = radeon_legacy_tmds_ext_mode_set, 724 .mode_set = radeon_legacy_tmds_ext_mode_set,
708 .commit = radeon_legacy_tmds_ext_commit, 725 .commit = radeon_legacy_tmds_ext_commit,
726 .disable = radeon_legacy_encoder_disable,
709}; 727};
710 728
711 729
@@ -727,17 +745,21 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
727{ 745{
728 struct drm_device *dev = encoder->dev; 746 struct drm_device *dev = encoder->dev;
729 struct radeon_device *rdev = dev->dev_private; 747 struct radeon_device *rdev = dev->dev_private;
748 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
730 uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; 749 uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0;
731 /* uint32_t tv_master_cntl = 0; */ 750 uint32_t tv_master_cntl = 0;
732 751 bool is_tv;
733 DRM_DEBUG("\n"); 752 DRM_DEBUG("\n");
734 753
754 is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
755
735 if (rdev->family == CHIP_R200) 756 if (rdev->family == CHIP_R200)
736 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 757 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
737 else { 758 else {
738 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 759 if (is_tv)
739 /* FIXME TV */ 760 tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL);
740 /* tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); */ 761 else
762 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
741 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 763 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
742 } 764 }
743 765
@@ -746,20 +768,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
746 if (rdev->family == CHIP_R200) { 768 if (rdev->family == CHIP_R200) {
747 fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); 769 fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
748 } else { 770 } else {
749 crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; 771 if (is_tv)
750 /* tv_master_cntl |= RADEON_TV_ON; */ 772 tv_master_cntl |= RADEON_TV_ON;
773 else
774 crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
775
751 if (rdev->family == CHIP_R420 || 776 if (rdev->family == CHIP_R420 ||
752 rdev->family == CHIP_R423 || 777 rdev->family == CHIP_R423 ||
753 rdev->family == CHIP_RV410) 778 rdev->family == CHIP_RV410)
754 tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | 779 tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
755 R420_TV_DAC_GDACPD | 780 R420_TV_DAC_GDACPD |
756 R420_TV_DAC_BDACPD | 781 R420_TV_DAC_BDACPD |
757 RADEON_TV_DAC_BGSLEEP); 782 RADEON_TV_DAC_BGSLEEP);
758 else 783 else
759 tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | 784 tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
760 RADEON_TV_DAC_GDACPD | 785 RADEON_TV_DAC_GDACPD |
761 RADEON_TV_DAC_BDACPD | 786 RADEON_TV_DAC_BDACPD |
762 RADEON_TV_DAC_BGSLEEP); 787 RADEON_TV_DAC_BGSLEEP);
763 } 788 }
764 break; 789 break;
765 case DRM_MODE_DPMS_STANDBY: 790 case DRM_MODE_DPMS_STANDBY:
@@ -768,8 +793,11 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
768 if (rdev->family == CHIP_R200) 793 if (rdev->family == CHIP_R200)
769 fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); 794 fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
770 else { 795 else {
771 crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; 796 if (is_tv)
772 /* tv_master_cntl &= ~RADEON_TV_ON; */ 797 tv_master_cntl &= ~RADEON_TV_ON;
798 else
799 crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
800
773 if (rdev->family == CHIP_R420 || 801 if (rdev->family == CHIP_R420 ||
774 rdev->family == CHIP_R423 || 802 rdev->family == CHIP_R423 ||
775 rdev->family == CHIP_RV410) 803 rdev->family == CHIP_RV410)
@@ -789,8 +817,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
789 if (rdev->family == CHIP_R200) { 817 if (rdev->family == CHIP_R200) {
790 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 818 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
791 } else { 819 } else {
792 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 820 if (is_tv)
793 /* WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); */ 821 WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
822 else
823 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
794 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 824 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
795 } 825 }
796 826
@@ -809,6 +839,7 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
809 else 839 else
810 radeon_combios_output_lock(encoder, true); 840 radeon_combios_output_lock(encoder, true);
811 radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); 841 radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
842 radeon_encoder_set_active_device(encoder);
812} 843}
813 844
814static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) 845static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
@@ -831,11 +862,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
831 struct radeon_device *rdev = dev->dev_private; 862 struct radeon_device *rdev = dev->dev_private;
832 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 863 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
833 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 864 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
865 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
834 uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; 866 uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0;
835 uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0; 867 uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0;
868 bool is_tv = false;
836 869
837 DRM_DEBUG("\n"); 870 DRM_DEBUG("\n");
838 871
872 is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
873
839 if (rdev->family != CHIP_R200) { 874 if (rdev->family != CHIP_R200) {
840 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 875 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
841 if (rdev->family == CHIP_R420 || 876 if (rdev->family == CHIP_R420 ||
@@ -858,7 +893,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
858 } 893 }
859 894
860 /* FIXME TV */ 895 /* FIXME TV */
861 if (radeon_encoder->enc_priv) { 896 if (tv_dac) {
862 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; 897 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
863 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | 898 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
864 RADEON_TV_DAC_NHOLD | 899 RADEON_TV_DAC_NHOLD |
@@ -875,44 +910,93 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
875 if (ASIC_IS_R300(rdev)) { 910 if (ASIC_IS_R300(rdev)) {
876 gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; 911 gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1;
877 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 912 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
878 } else if (rdev->family == CHIP_R200) 913 }
879 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 914
915 if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev))
916 disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL);
880 else 917 else
881 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); 918 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
882 919
883 dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; 920 if (rdev->family == CHIP_R200)
921 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
884 922
885 if (radeon_crtc->crtc_id == 0) { 923 if (is_tv) {
886 if (ASIC_IS_R300(rdev)) { 924 uint32_t dac_cntl;
887 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 925
888 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; 926 dac_cntl = RREG32(RADEON_DAC_CNTL);
889 } else if (rdev->family == CHIP_R200) { 927 dac_cntl &= ~RADEON_DAC_TVO_EN;
890 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | 928 WREG32(RADEON_DAC_CNTL, dac_cntl);
891 RADEON_FP2_DVO_RATE_SEL_SDR); 929
892 } else 930 if (ASIC_IS_R300(rdev))
893 disp_hw_debug |= RADEON_CRT2_DISP1_SEL; 931 gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1;
932
933 dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL;
934 if (radeon_crtc->crtc_id == 0) {
935 if (ASIC_IS_R300(rdev)) {
936 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
937 disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC |
938 RADEON_DISP_TV_SOURCE_CRTC);
939 }
940 if (rdev->family >= CHIP_R200) {
941 disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2;
942 } else {
943 disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
944 }
945 } else {
946 if (ASIC_IS_R300(rdev)) {
947 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
948 disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC;
949 }
950 if (rdev->family >= CHIP_R200) {
951 disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2;
952 } else {
953 disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
954 }
955 }
956 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
894 } else { 957 } else {
895 if (ASIC_IS_R300(rdev)) {
896 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
897 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
898 } else if (rdev->family == CHIP_R200) {
899 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
900 RADEON_FP2_DVO_RATE_SEL_SDR);
901 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
902 } else
903 disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
904 }
905 958
906 WREG32(RADEON_DAC_CNTL2, dac2_cntl); 959 dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL;
960
961 if (radeon_crtc->crtc_id == 0) {
962 if (ASIC_IS_R300(rdev)) {
963 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
964 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
965 } else if (rdev->family == CHIP_R200) {
966 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
967 RADEON_FP2_DVO_RATE_SEL_SDR);
968 } else
969 disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
970 } else {
971 if (ASIC_IS_R300(rdev)) {
972 disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
973 disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
974 } else if (rdev->family == CHIP_R200) {
975 fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
976 RADEON_FP2_DVO_RATE_SEL_SDR);
977 fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
978 } else
979 disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
980 }
981 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
982 }
907 983
908 if (ASIC_IS_R300(rdev)) { 984 if (ASIC_IS_R300(rdev)) {
909 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); 985 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
910 WREG32(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl); 986 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
911 } else if (rdev->family == CHIP_R200) 987 }
912 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 988
989 if (rdev->family >= CHIP_R200)
990 WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl);
913 else 991 else
914 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); 992 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
915 993
994 if (rdev->family == CHIP_R200)
995 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
996
997 if (is_tv)
998 radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode);
999
916 if (rdev->is_atom_bios) 1000 if (rdev->is_atom_bios)
917 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 1001 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
918 else 1002 else
@@ -920,6 +1004,141 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
920 1004
921} 1005}
922 1006
1007static bool r300_legacy_tv_detect(struct drm_encoder *encoder,
1008 struct drm_connector *connector)
1009{
1010 struct drm_device *dev = encoder->dev;
1011 struct radeon_device *rdev = dev->dev_private;
1012 uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
1013 uint32_t disp_output_cntl, gpiopad_a, tmp;
1014 bool found = false;
1015
1016 /* save regs needed */
1017 gpiopad_a = RREG32(RADEON_GPIOPAD_A);
1018 dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
1019 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
1020 dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
1021 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
1022 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
1023
1024 WREG32_P(RADEON_GPIOPAD_A, 0, ~1);
1025
1026 WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL);
1027
1028 WREG32(RADEON_CRTC2_GEN_CNTL,
1029 RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT);
1030
1031 tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
1032 tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
1033 WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
1034
1035 WREG32(RADEON_DAC_EXT_CNTL,
1036 RADEON_DAC2_FORCE_BLANK_OFF_EN |
1037 RADEON_DAC2_FORCE_DATA_EN |
1038 RADEON_DAC_FORCE_DATA_SEL_RGB |
1039 (0xec << RADEON_DAC_FORCE_DATA_SHIFT));
1040
1041 WREG32(RADEON_TV_DAC_CNTL,
1042 RADEON_TV_DAC_STD_NTSC |
1043 (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
1044 (6 << RADEON_TV_DAC_DACADJ_SHIFT));
1045
1046 RREG32(RADEON_TV_DAC_CNTL);
1047 mdelay(4);
1048
1049 WREG32(RADEON_TV_DAC_CNTL,
1050 RADEON_TV_DAC_NBLANK |
1051 RADEON_TV_DAC_NHOLD |
1052 RADEON_TV_MONITOR_DETECT_EN |
1053 RADEON_TV_DAC_STD_NTSC |
1054 (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
1055 (6 << RADEON_TV_DAC_DACADJ_SHIFT));
1056
1057 RREG32(RADEON_TV_DAC_CNTL);
1058 mdelay(6);
1059
1060 tmp = RREG32(RADEON_TV_DAC_CNTL);
1061 if ((tmp & RADEON_TV_DAC_GDACDET) != 0) {
1062 found = true;
1063 DRM_DEBUG("S-video TV connection detected\n");
1064 } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
1065 found = true;
1066 DRM_DEBUG("Composite TV connection detected\n");
1067 }
1068
1069 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1070 WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
1071 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
1072 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
1073 WREG32(RADEON_DAC_CNTL2, dac_cntl2);
1074 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
1075 return found;
1076}
1077
1078static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
1079 struct drm_connector *connector)
1080{
1081 struct drm_device *dev = encoder->dev;
1082 struct radeon_device *rdev = dev->dev_private;
1083 uint32_t tv_dac_cntl, dac_cntl2;
1084 uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp;
1085 bool found = false;
1086
1087 if (ASIC_IS_R300(rdev))
1088 return r300_legacy_tv_detect(encoder, connector);
1089
1090 dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
1091 tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL);
1092 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
1093 config_cntl = RREG32(RADEON_CONFIG_CNTL);
1094 tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL);
1095
1096 tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
1097 WREG32(RADEON_DAC_CNTL2, tmp);
1098
1099 tmp = tv_master_cntl | RADEON_TV_ON;
1100 tmp &= ~(RADEON_TV_ASYNC_RST |
1101 RADEON_RESTART_PHASE_FIX |
1102 RADEON_CRT_FIFO_CE_EN |
1103 RADEON_TV_FIFO_CE_EN |
1104 RADEON_RE_SYNC_NOW_SEL_MASK);
1105 tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
1106 WREG32(RADEON_TV_MASTER_CNTL, tmp);
1107
1108 tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
1109 RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
1110 (8 << RADEON_TV_DAC_BGADJ_SHIFT);
1111
1112 if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
1113 tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
1114 else
1115 tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
1116 WREG32(RADEON_TV_DAC_CNTL, tmp);
1117
1118 tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
1119 RADEON_RED_MX_FORCE_DAC_DATA |
1120 RADEON_GRN_MX_FORCE_DAC_DATA |
1121 RADEON_BLU_MX_FORCE_DAC_DATA |
1122 (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
1123 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
1124
1125 mdelay(3);
1126 tmp = RREG32(RADEON_TV_DAC_CNTL);
1127 if (tmp & RADEON_TV_DAC_GDACDET) {
1128 found = true;
1129 DRM_DEBUG("S-video TV connection detected\n");
1130 } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
1131 found = true;
1132 DRM_DEBUG("Composite TV connection detected\n");
1133 }
1134
1135 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
1136 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1137 WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
1138 WREG32(RADEON_DAC_CNTL2, dac_cntl2);
1139 return found;
1140}
1141
923static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, 1142static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
924 struct drm_connector *connector) 1143 struct drm_connector *connector)
925{ 1144{
@@ -928,9 +1147,29 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
928 uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; 1147 uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
929 uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; 1148 uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
930 enum drm_connector_status found = connector_status_disconnected; 1149 enum drm_connector_status found = connector_status_disconnected;
1150 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1151 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
931 bool color = true; 1152 bool color = true;
932 1153
933 /* FIXME tv */ 1154 if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO ||
1155 connector->connector_type == DRM_MODE_CONNECTOR_Composite ||
1156 connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) {
1157 bool tv_detect;
1158
1159 if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT))
1160 return connector_status_disconnected;
1161
1162 tv_detect = radeon_legacy_tv_detect(encoder, connector);
1163 if (tv_detect && tv_dac)
1164 found = connector_status_connected;
1165 return found;
1166 }
1167
1168 /* don't probe if the encoder is being used for something else not CRT related */
1169 if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) {
1170 DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device);
1171 return connector_status_disconnected;
1172 }
934 1173
935 /* save the regs we need */ 1174 /* save the regs we need */
936 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); 1175 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -1013,8 +1252,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
1013 } 1252 }
1014 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); 1253 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
1015 1254
1016 /* return found; */ 1255 return found;
1017 return connector_status_disconnected;
1018 1256
1019} 1257}
1020 1258
@@ -1025,6 +1263,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs =
1025 .mode_set = radeon_legacy_tv_dac_mode_set, 1263 .mode_set = radeon_legacy_tv_dac_mode_set,
1026 .commit = radeon_legacy_tv_dac_commit, 1264 .commit = radeon_legacy_tv_dac_commit,
1027 .detect = radeon_legacy_tv_dac_detect, 1265 .detect = radeon_legacy_tv_dac_detect,
1266 .disable = radeon_legacy_encoder_disable,
1028}; 1267};
1029 1268
1030 1269
@@ -1032,6 +1271,30 @@ static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
1032 .destroy = radeon_enc_destroy, 1271 .destroy = radeon_enc_destroy,
1033}; 1272};
1034 1273
1274
1275static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder)
1276{
1277 struct drm_device *dev = encoder->base.dev;
1278 struct radeon_device *rdev = dev->dev_private;
1279 struct radeon_encoder_int_tmds *tmds = NULL;
1280 bool ret;
1281
1282 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1283
1284 if (!tmds)
1285 return NULL;
1286
1287 if (rdev->is_atom_bios)
1288 ret = radeon_atombios_get_tmds_info(encoder, tmds);
1289 else
1290 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
1291
1292 if (ret == false)
1293 radeon_legacy_get_tmds_info_from_table(encoder, tmds);
1294
1295 return tmds;
1296}
1297
1035void 1298void
1036radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) 1299radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1037{ 1300{
@@ -1078,10 +1341,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
1078 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1341 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1079 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); 1342 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
1080 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); 1343 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
1081 if (rdev->is_atom_bios) 1344 radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder);
1082 radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder);
1083 else
1084 radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder);
1085 break; 1345 break;
1086 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1346 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1087 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); 1347 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
new file mode 100644
index 000000000000..3a12bb0c0563
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
@@ -0,0 +1,904 @@
1#include "drmP.h"
2#include "drm_crtc_helper.h"
3#include "radeon.h"
4
5/*
6 * Integrated TV out support based on the GATOS code by
7 * Federico Ulivi <fulivi@lycos.com>
8 */
9
10
11/*
12 * Limits of h/v positions (hPos & vPos)
13 */
14#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
15#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
16
17/*
18 * Unit for hPos (in TV clock periods)
19 */
20#define H_POS_UNIT 10
21
22/*
23 * Indexes in h. code timing table for horizontal line position adjustment
24 */
25#define H_TABLE_POS1 6
26#define H_TABLE_POS2 8
27
28/*
29 * Limits of hor. size (hSize)
30 */
31#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
32
33/* tv standard constants */
34#define NTSC_TV_CLOCK_T 233
35#define NTSC_TV_VFTOTAL 1
36#define NTSC_TV_LINES_PER_FRAME 525
37#define NTSC_TV_ZERO_H_SIZE 479166
38#define NTSC_TV_H_SIZE_UNIT 9478
39
40#define PAL_TV_CLOCK_T 188
41#define PAL_TV_VFTOTAL 3
42#define PAL_TV_LINES_PER_FRAME 625
43#define PAL_TV_ZERO_H_SIZE 473200
44#define PAL_TV_H_SIZE_UNIT 9360
45
46/* tv pll setting for 27 mhz ref clk */
47#define NTSC_TV_PLL_M_27 22
48#define NTSC_TV_PLL_N_27 175
49#define NTSC_TV_PLL_P_27 5
50
51#define PAL_TV_PLL_M_27 113
52#define PAL_TV_PLL_N_27 668
53#define PAL_TV_PLL_P_27 3
54
55/* tv pll setting for 14 mhz ref clk */
56#define NTSC_TV_PLL_M_14 33
57#define NTSC_TV_PLL_N_14 693
58#define NTSC_TV_PLL_P_14 7
59
60#define VERT_LEAD_IN_LINES 2
61#define FRAC_BITS 0xe
62#define FRAC_MASK 0x3fff
63
64struct radeon_tv_mode_constants {
65 uint16_t hor_resolution;
66 uint16_t ver_resolution;
67 enum radeon_tv_std standard;
68 uint16_t hor_total;
69 uint16_t ver_total;
70 uint16_t hor_start;
71 uint16_t hor_syncstart;
72 uint16_t ver_syncstart;
73 unsigned def_restart;
74 uint16_t crtcPLL_N;
75 uint8_t crtcPLL_M;
76 uint8_t crtcPLL_post_div;
77 unsigned pix_to_tv;
78};
79
80static const uint16_t hor_timing_NTSC[] = {
81 0x0007,
82 0x003f,
83 0x0263,
84 0x0a24,
85 0x2a6b,
86 0x0a36,
87 0x126d, /* H_TABLE_POS1 */
88 0x1bfe,
89 0x1a8f, /* H_TABLE_POS2 */
90 0x1ec7,
91 0x3863,
92 0x1bfe,
93 0x1bfe,
94 0x1a2a,
95 0x1e95,
96 0x0e31,
97 0x201b,
98 0
99};
100
101static const uint16_t vert_timing_NTSC[] = {
102 0x2001,
103 0x200d,
104 0x1006,
105 0x0c06,
106 0x1006,
107 0x1818,
108 0x21e3,
109 0x1006,
110 0x0c06,
111 0x1006,
112 0x1817,
113 0x21d4,
114 0x0002,
115 0
116};
117
118static const uint16_t hor_timing_PAL[] = {
119 0x0007,
120 0x0058,
121 0x027c,
122 0x0a31,
123 0x2a77,
124 0x0a95,
125 0x124f, /* H_TABLE_POS1 */
126 0x1bfe,
127 0x1b22, /* H_TABLE_POS2 */
128 0x1ef9,
129 0x387c,
130 0x1bfe,
131 0x1bfe,
132 0x1b31,
133 0x1eb5,
134 0x0e43,
135 0x201b,
136 0
137};
138
139static const uint16_t vert_timing_PAL[] = {
140 0x2001,
141 0x200c,
142 0x1005,
143 0x0c05,
144 0x1005,
145 0x1401,
146 0x1821,
147 0x2240,
148 0x1005,
149 0x0c05,
150 0x1005,
151 0x1401,
152 0x1822,
153 0x2230,
154 0x0002,
155 0
156};
157
158/**********************************************************************
159 *
160 * availableModes
161 *
162 * Table of all allowed modes for tv output
163 *
164 **********************************************************************/
165static const struct radeon_tv_mode_constants available_tv_modes[] = {
166 { /* NTSC timing for 27 Mhz ref clk */
167 800, /* horResolution */
168 600, /* verResolution */
169 TV_STD_NTSC, /* standard */
170 990, /* horTotal */
171 740, /* verTotal */
172 813, /* horStart */
173 824, /* horSyncStart */
174 632, /* verSyncStart */
175 625592, /* defRestart */
176 592, /* crtcPLL_N */
177 91, /* crtcPLL_M */
178 4, /* crtcPLL_postDiv */
179 1022, /* pixToTV */
180 },
181 { /* PAL timing for 27 Mhz ref clk */
182 800, /* horResolution */
183 600, /* verResolution */
184 TV_STD_PAL, /* standard */
185 1144, /* horTotal */
186 706, /* verTotal */
187 812, /* horStart */
188 824, /* horSyncStart */
189 669, /* verSyncStart */
190 696700, /* defRestart */
191 1382, /* crtcPLL_N */
192 231, /* crtcPLL_M */
193 4, /* crtcPLL_postDiv */
194 759, /* pixToTV */
195 },
196 { /* NTSC timing for 14 Mhz ref clk */
197 800, /* horResolution */
198 600, /* verResolution */
199 TV_STD_NTSC, /* standard */
200 1018, /* horTotal */
201 727, /* verTotal */
202 813, /* horStart */
203 840, /* horSyncStart */
204 633, /* verSyncStart */
205 630627, /* defRestart */
206 347, /* crtcPLL_N */
207 14, /* crtcPLL_M */
208 8, /* crtcPLL_postDiv */
209 1022, /* pixToTV */
210 },
211};
212
213#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
214
215static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder,
216 uint16_t *pll_ref_freq)
217{
218 struct drm_device *dev = radeon_encoder->base.dev;
219 struct radeon_device *rdev = dev->dev_private;
220 struct radeon_crtc *radeon_crtc;
221 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
222 const struct radeon_tv_mode_constants *const_ptr;
223 struct radeon_pll *pll;
224
225 radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
226 if (radeon_crtc->crtc_id == 1)
227 pll = &rdev->clock.p2pll;
228 else
229 pll = &rdev->clock.p1pll;
230
231 if (pll_ref_freq)
232 *pll_ref_freq = pll->reference_freq;
233
234 if (tv_dac->tv_std == TV_STD_NTSC ||
235 tv_dac->tv_std == TV_STD_NTSC_J ||
236 tv_dac->tv_std == TV_STD_PAL_M) {
237 if (pll->reference_freq == 2700)
238 const_ptr = &available_tv_modes[0];
239 else
240 const_ptr = &available_tv_modes[2];
241 } else {
242 if (pll->reference_freq == 2700)
243 const_ptr = &available_tv_modes[1];
244 else
245 const_ptr = &available_tv_modes[1]; /* FIX ME */
246 }
247 return const_ptr;
248}
249
250static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
251static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
252static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
253static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
254
255static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests,
256 unsigned n_wait_loops, unsigned cnt_threshold)
257{
258 struct drm_device *dev = encoder->dev;
259 struct radeon_device *rdev = dev->dev_private;
260 uint32_t save_pll_test;
261 unsigned int i, j;
262
263 WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
264 save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL);
265 WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B);
266
267 WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
268 for (i = 0; i < n_tests; i++) {
269 WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
270 for (j = 0; j < n_wait_loops; j++)
271 if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold)
272 break;
273 }
274 WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test);
275 WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
276}
277
278
279static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder,
280 uint16_t addr, uint32_t value)
281{
282 struct drm_device *dev = radeon_encoder->base.dev;
283 struct radeon_device *rdev = dev->dev_private;
284 uint32_t tmp;
285 int i = 0;
286
287 WREG32(RADEON_TV_HOST_WRITE_DATA, value);
288
289 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
290 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
291
292 do {
293 tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
294 if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
295 break;
296 i++;
297 } while (i < 10000);
298 WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
299}
300
301#if 0 /* included for completeness */
302static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr)
303{
304 struct drm_device *dev = radeon_encoder->base.dev;
305 struct radeon_device *rdev = dev->dev_private;
306 uint32_t tmp;
307 int i = 0;
308
309 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
310 WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
311
312 do {
313 tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
314 if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
315 break;
316 i++;
317 } while (i < 10000);
318 WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
319 return RREG32(RADEON_TV_HOST_READ_DATA);
320}
321#endif
322
323static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr)
324{
325 uint16_t h_table;
326
327 switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
328 case 0:
329 h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
330 break;
331 case 1:
332 h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
333 break;
334 case 2:
335 h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
336 break;
337 default:
338 h_table = 0;
339 break;
340 }
341 return h_table;
342}
343
344static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr)
345{
346 uint16_t v_table;
347
348 switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
349 case 0:
350 v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
351 break;
352 case 1:
353 v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
354 break;
355 case 2:
356 v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
357 break;
358 default:
359 v_table = 0;
360 break;
361 }
362 return v_table;
363}
364
365static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder)
366{
367 struct drm_device *dev = radeon_encoder->base.dev;
368 struct radeon_device *rdev = dev->dev_private;
369 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
370 uint16_t h_table, v_table;
371 uint32_t tmp;
372 int i;
373
374 WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr);
375 h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr);
376 v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr);
377
378 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) {
379 tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]);
380 radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp);
381 if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0)
382 break;
383 }
384 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) {
385 tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]);
386 radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp);
387 if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0)
388 break;
389 }
390}
391
392static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder)
393{
394 struct drm_device *dev = radeon_encoder->base.dev;
395 struct radeon_device *rdev = dev->dev_private;
396 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
397 WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart);
398 WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart);
399 WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart);
400}
401
402static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
403{
404 struct drm_device *dev = encoder->dev;
405 struct radeon_device *rdev = dev->dev_private;
406 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
407 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
408 struct radeon_crtc *radeon_crtc;
409 int restart;
410 unsigned int h_total, v_total, f_total;
411 int v_offset, h_offset;
412 u16 p1, p2, h_inc;
413 bool h_changed;
414 const struct radeon_tv_mode_constants *const_ptr;
415 struct radeon_pll *pll;
416
417 radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
418 if (radeon_crtc->crtc_id == 1)
419 pll = &rdev->clock.p2pll;
420 else
421 pll = &rdev->clock.p1pll;
422
423 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
424 if (!const_ptr)
425 return false;
426
427 h_total = const_ptr->hor_total;
428 v_total = const_ptr->ver_total;
429
430 if (tv_dac->tv_std == TV_STD_NTSC ||
431 tv_dac->tv_std == TV_STD_NTSC_J ||
432 tv_dac->tv_std == TV_STD_PAL_M ||
433 tv_dac->tv_std == TV_STD_PAL_60)
434 f_total = NTSC_TV_VFTOTAL + 1;
435 else
436 f_total = PAL_TV_VFTOTAL + 1;
437
438 /* adjust positions 1&2 in hor. cod timing table */
439 h_offset = tv_dac->h_pos * H_POS_UNIT;
440
441 if (tv_dac->tv_std == TV_STD_NTSC ||
442 tv_dac->tv_std == TV_STD_NTSC_J ||
443 tv_dac->tv_std == TV_STD_PAL_M) {
444 h_offset -= 50;
445 p1 = hor_timing_NTSC[H_TABLE_POS1];
446 p2 = hor_timing_NTSC[H_TABLE_POS2];
447 } else {
448 p1 = hor_timing_PAL[H_TABLE_POS1];
449 p2 = hor_timing_PAL[H_TABLE_POS2];
450 }
451
452 p1 = (u16)((int)p1 + h_offset);
453 p2 = (u16)((int)p2 - h_offset);
454
455 h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] ||
456 p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]);
457
458 tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1;
459 tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2;
460
461 /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
462 h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000;
463
464 /* adjust restart */
465 restart = const_ptr->def_restart;
466
467 /*
468 * convert v_pos TV lines to n. of CRTC pixels
469 */
470 if (tv_dac->tv_std == TV_STD_NTSC ||
471 tv_dac->tv_std == TV_STD_NTSC_J ||
472 tv_dac->tv_std == TV_STD_PAL_M ||
473 tv_dac->tv_std == TV_STD_PAL_60)
474 v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME);
475 else
476 v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME);
477
478 restart -= v_offset + h_offset;
479
480 DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
481 const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);
482
483 tv_dac->tv.hrestart = restart % h_total;
484 restart /= h_total;
485 tv_dac->tv.vrestart = restart % v_total;
486 restart /= v_total;
487 tv_dac->tv.frestart = restart % f_total;
488
489 DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n",
490 (unsigned)tv_dac->tv.frestart,
491 (unsigned)tv_dac->tv.vrestart,
492 (unsigned)tv_dac->tv.hrestart);
493
494 /* compute h_inc from hsize */
495 if (tv_dac->tv_std == TV_STD_NTSC ||
496 tv_dac->tv_std == TV_STD_NTSC_J ||
497 tv_dac->tv_std == TV_STD_PAL_M)
498 h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) /
499 (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
500 else
501 h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) /
502 (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
503
504 tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |
505 ((u32)h_inc << RADEON_H_INC_SHIFT);
506
507 DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
508
509 return h_changed;
510}
511
512void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
513 struct drm_display_mode *mode,
514 struct drm_display_mode *adjusted_mode)
515{
516 struct drm_device *dev = encoder->dev;
517 struct radeon_device *rdev = dev->dev_private;
518 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
519 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
520 const struct radeon_tv_mode_constants *const_ptr;
521 struct radeon_crtc *radeon_crtc;
522 int i;
523 uint16_t pll_ref_freq;
524 uint32_t vert_space, flicker_removal, tmp;
525 uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl;
526 uint32_t tv_modulator_cntl1, tv_modulator_cntl2;
527 uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2;
528 uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal;
529 uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl;
530 uint32_t m, n, p;
531 const uint16_t *hor_timing;
532 const uint16_t *vert_timing;
533
534 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq);
535 if (!const_ptr)
536 return;
537
538 radeon_crtc = to_radeon_crtc(encoder->crtc);
539
540 tv_master_cntl = (RADEON_VIN_ASYNC_RST |
541 RADEON_CRT_FIFO_CE_EN |
542 RADEON_TV_FIFO_CE_EN |
543 RADEON_TV_ON);
544
545 if (!ASIC_IS_R300(rdev))
546 tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
547
548 if (tv_dac->tv_std == TV_STD_NTSC ||
549 tv_dac->tv_std == TV_STD_NTSC_J)
550 tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
551
552 tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT |
553 RADEON_SYNC_TIP_LEVEL |
554 RADEON_YFLT_EN |
555 RADEON_UVFLT_EN |
556 (6 << RADEON_CY_FILT_BLEND_SHIFT));
557
558 if (tv_dac->tv_std == TV_STD_NTSC ||
559 tv_dac->tv_std == TV_STD_NTSC_J) {
560 tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) |
561 (0x3b << RADEON_BLANK_LEVEL_SHIFT);
562 tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
563 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
564 } else if (tv_dac->tv_std == TV_STD_SCART_PAL) {
565 tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
566 tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
567 ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
568 } else {
569 tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN |
570 (0x3b << RADEON_SET_UP_LEVEL_SHIFT) |
571 (0x3b << RADEON_BLANK_LEVEL_SHIFT);
572 tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
573 ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
574 }
575
576
577 tv_rgb_cntl = (RADEON_RGB_DITHER_EN
578 | RADEON_TVOUT_SCALE_EN
579 | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
580 | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT)
581 | RADEON_RGB_ATTEN_SEL(0x3)
582 | RADEON_RGB_ATTEN_VAL(0xc));
583
584 if (radeon_crtc->crtc_id == 1)
585 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
586 else {
587 if (radeon_crtc->rmx_type != RMX_OFF)
588 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
589 else
590 tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
591 }
592
593 if (tv_dac->tv_std == TV_STD_NTSC ||
594 tv_dac->tv_std == TV_STD_NTSC_J ||
595 tv_dac->tv_std == TV_STD_PAL_M ||
596 tv_dac->tv_std == TV_STD_PAL_60)
597 vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
598 else
599 vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
600
601 tmp = RREG32(RADEON_TV_VSCALER_CNTL1);
602 tmp &= 0xe3ff0000;
603 tmp |= (vert_space * (1 << FRAC_BITS) / 10000);
604 tv_vscaler_cntl1 = tmp;
605
606 if (pll_ref_freq == 2700)
607 tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
608
609 if (const_ptr->hor_resolution == 1024)
610 tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
611 else
612 tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
613
614 /* scale up for int divide */
615 tmp = const_ptr->ver_total * 2 * 1000;
616 if (tv_dac->tv_std == TV_STD_NTSC ||
617 tv_dac->tv_std == TV_STD_NTSC_J ||
618 tv_dac->tv_std == TV_STD_PAL_M ||
619 tv_dac->tv_std == TV_STD_PAL_60) {
620 tmp /= NTSC_TV_LINES_PER_FRAME;
621 } else {
622 tmp /= PAL_TV_LINES_PER_FRAME;
623 }
624 flicker_removal = (tmp + 500) / 1000;
625
626 if (flicker_removal < 3)
627 flicker_removal = 3;
628 for (i = 0; i < 6; ++i) {
629 if (flicker_removal == SLOPE_limit[i])
630 break;
631 }
632
633 tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +
634 5001) / 10000 / 8 | ((SLOPE_value[i] *
635 (1 << (FRAC_BITS - 1)) / 8) << 16);
636 tv_y_fall_cntl =
637 (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
638 RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
639 1024;
640 tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG|
641 (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
642
643 tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0;
644 tv_vscaler_cntl2 |= (0x10 << 24) |
645 RADEON_DITHER_MODE |
646 RADEON_Y_OUTPUT_DITHER_EN |
647 RADEON_UV_OUTPUT_DITHER_EN |
648 RADEON_UV_TO_BUF_DITHER_EN;
649
650 tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
651 tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
652 tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
653 tv_dac->tv.timing_cntl = tmp;
654
655 if (tv_dac->tv_std == TV_STD_NTSC ||
656 tv_dac->tv_std == TV_STD_NTSC_J ||
657 tv_dac->tv_std == TV_STD_PAL_M ||
658 tv_dac->tv_std == TV_STD_PAL_60)
659 tv_dac_cntl = tv_dac->ntsc_tvdac_adj;
660 else
661 tv_dac_cntl = tv_dac->pal_tvdac_adj;
662
663 tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
664
665 if (tv_dac->tv_std == TV_STD_NTSC ||
666 tv_dac->tv_std == TV_STD_NTSC_J)
667 tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
668 else
669 tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
670
671 if (tv_dac->tv_std == TV_STD_NTSC ||
672 tv_dac->tv_std == TV_STD_NTSC_J) {
673 if (pll_ref_freq == 2700) {
674 m = NTSC_TV_PLL_M_27;
675 n = NTSC_TV_PLL_N_27;
676 p = NTSC_TV_PLL_P_27;
677 } else {
678 m = NTSC_TV_PLL_M_14;
679 n = NTSC_TV_PLL_N_14;
680 p = NTSC_TV_PLL_P_14;
681 }
682 } else {
683 if (pll_ref_freq == 2700) {
684 m = PAL_TV_PLL_M_27;
685 n = PAL_TV_PLL_N_27;
686 p = PAL_TV_PLL_P_27;
687 } else {
688 m = PAL_TV_PLL_M_27;
689 n = PAL_TV_PLL_N_27;
690 p = PAL_TV_PLL_P_27;
691 }
692 }
693
694 tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) |
695 (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
696 ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
697 (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
698 ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
699
700 tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) |
701 ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
702 ((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) |
703 RADEON_TVCLK_SRC_SEL_TVPLL |
704 RADEON_TVPLL_TEST_DIS);
705
706 tv_dac->tv.tv_uv_adr = 0xc8;
707
708 if (tv_dac->tv_std == TV_STD_NTSC ||
709 tv_dac->tv_std == TV_STD_NTSC_J ||
710 tv_dac->tv_std == TV_STD_PAL_M ||
711 tv_dac->tv_std == TV_STD_PAL_60) {
712 tv_ftotal = NTSC_TV_VFTOTAL;
713 hor_timing = hor_timing_NTSC;
714 vert_timing = vert_timing_NTSC;
715 } else {
716 hor_timing = hor_timing_PAL;
717 vert_timing = vert_timing_PAL;
718 tv_ftotal = PAL_TV_VFTOTAL;
719 }
720
721 for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
722 if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0)
723 break;
724 }
725
726 for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
727 if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0)
728 break;
729 }
730
731 radeon_legacy_tv_init_restarts(encoder);
732
733 /* play with DAC_CNTL */
734 /* play with GPIOPAD_A */
735 /* DISP_OUTPUT_CNTL */
736 /* use reference freq */
737
738 /* program the TV registers */
739 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
740 RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST));
741
742 tmp = RREG32(RADEON_TV_DAC_CNTL);
743 tmp &= ~RADEON_TV_DAC_NBLANK;
744 tmp |= RADEON_TV_DAC_BGSLEEP |
745 RADEON_TV_DAC_RDACPD |
746 RADEON_TV_DAC_GDACPD |
747 RADEON_TV_DAC_BDACPD;
748 WREG32(RADEON_TV_DAC_CNTL, tmp);
749
750 /* TV PLL */
751 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
752 WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl);
753 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
754
755 radeon_wait_pll_lock(encoder, 200, 800, 135);
756
757 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
758
759 radeon_wait_pll_lock(encoder, 300, 160, 27);
760 radeon_wait_pll_lock(encoder, 200, 800, 135);
761
762 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf);
763 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
764
765 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
766 WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
767
768 /* TV HV */
769 WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl);
770 WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1);
771 WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1);
772 WREG32(RADEON_TV_HSTART, const_ptr->hor_start);
773
774 WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1);
775 WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1);
776 WREG32(RADEON_TV_FTOTAL, tv_ftotal);
777 WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1);
778 WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2);
779
780 WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl);
781 WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl);
782 WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl);
783
784 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
785 RADEON_CRT_ASYNC_RST));
786
787 /* TV restarts */
788 radeon_legacy_write_tv_restarts(radeon_encoder);
789
790 /* tv timings */
791 radeon_restore_tv_timing_tables(radeon_encoder);
792
793 WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST));
794
795 /* tv std */
796 WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE));
797 WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl);
798 WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1);
799 WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2);
800 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN |
801 RADEON_C_GRN_EN |
802 RADEON_CMP_BLU_EN |
803 RADEON_DAC_DITHER_EN));
804
805 WREG32(RADEON_TV_CRC_CNTL, 0);
806
807 WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
808
809 WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
810 (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT)));
811 WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) |
812 (0x100 << RADEON_Y_GAIN_SHIFT)));
813
814 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
815
816}
817
818void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
819 uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
820 uint32_t *v_total_disp, uint32_t *v_sync_strt_wid)
821{
822 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
823 const struct radeon_tv_mode_constants *const_ptr;
824 uint32_t tmp;
825
826 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
827 if (!const_ptr)
828 return;
829
830 *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
831 (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
832
833 tmp = *h_sync_strt_wid;
834 tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR);
835 tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
836 (const_ptr->hor_syncstart & 7);
837 *h_sync_strt_wid = tmp;
838
839 *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
840 ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
841
842 tmp = *v_sync_strt_wid;
843 tmp &= ~RADEON_CRTC_V_SYNC_STRT;
844 tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
845 *v_sync_strt_wid = tmp;
846}
847
848static inline int get_post_div(int value)
849{
850 int post_div;
851 switch (value) {
852 case 1: post_div = 0; break;
853 case 2: post_div = 1; break;
854 case 3: post_div = 4; break;
855 case 4: post_div = 2; break;
856 case 6: post_div = 6; break;
857 case 8: post_div = 3; break;
858 case 12: post_div = 7; break;
859 case 16:
860 default: post_div = 5; break;
861 }
862 return post_div;
863}
864
865void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
866 uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
867 uint32_t *ppll_div_3, uint32_t *pixclks_cntl)
868{
869 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
870 const struct radeon_tv_mode_constants *const_ptr;
871
872 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
873 if (!const_ptr)
874 return;
875
876 *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN;
877
878 *ppll_ref_div = const_ptr->crtcPLL_M;
879
880 *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
881 *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
882 *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
883}
884
885void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
886 uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
887 uint32_t *p2pll_div_0, uint32_t *pixclks_cntl)
888{
889 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
890 const struct radeon_tv_mode_constants *const_ptr;
891
892 const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
893 if (!const_ptr)
894 return;
895
896 *htotal2_cntl = (const_ptr->hor_total & 0x7);
897
898 *p2pll_ref_div = const_ptr->crtcPLL_M;
899
900 *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
901 *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
902 *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL;
903}
904
diff --git a/drivers/gpu/drm/radeon/radeon_microcode.h b/drivers/gpu/drm/radeon/radeon_microcode.h
deleted file mode 100644
index a348c9e7db1c..000000000000
--- a/drivers/gpu/drm/radeon/radeon_microcode.h
+++ /dev/null
@@ -1,1844 +0,0 @@
1/*
2 * Copyright 2007 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#ifndef RADEON_MICROCODE_H
27#define RADEON_MICROCODE_H
28
29/* production radeon ucode r1xx-r6xx */
30static const u32 R100_cp_microcode[][2] = {
31 { 0x21007000, 0000000000 },
32 { 0x20007000, 0000000000 },
33 { 0x000000b4, 0x00000004 },
34 { 0x000000b8, 0x00000004 },
35 { 0x6f5b4d4c, 0000000000 },
36 { 0x4c4c427f, 0000000000 },
37 { 0x5b568a92, 0000000000 },
38 { 0x4ca09c6d, 0000000000 },
39 { 0xad4c4c4c, 0000000000 },
40 { 0x4ce1af3d, 0000000000 },
41 { 0xd8afafaf, 0000000000 },
42 { 0xd64c4cdc, 0000000000 },
43 { 0x4cd10d10, 0000000000 },
44 { 0x000f0000, 0x00000016 },
45 { 0x362f242d, 0000000000 },
46 { 0x00000012, 0x00000004 },
47 { 0x000f0000, 0x00000016 },
48 { 0x362f282d, 0000000000 },
49 { 0x000380e7, 0x00000002 },
50 { 0x04002c97, 0x00000002 },
51 { 0x000f0001, 0x00000016 },
52 { 0x333a3730, 0000000000 },
53 { 0x000077ef, 0x00000002 },
54 { 0x00061000, 0x00000002 },
55 { 0x00000021, 0x0000001a },
56 { 0x00004000, 0x0000001e },
57 { 0x00061000, 0x00000002 },
58 { 0x00000021, 0x0000001a },
59 { 0x00004000, 0x0000001e },
60 { 0x00061000, 0x00000002 },
61 { 0x00000021, 0x0000001a },
62 { 0x00004000, 0x0000001e },
63 { 0x00000017, 0x00000004 },
64 { 0x0003802b, 0x00000002 },
65 { 0x040067e0, 0x00000002 },
66 { 0x00000017, 0x00000004 },
67 { 0x000077e0, 0x00000002 },
68 { 0x00065000, 0x00000002 },
69 { 0x000037e1, 0x00000002 },
70 { 0x040067e1, 0x00000006 },
71 { 0x000077e0, 0x00000002 },
72 { 0x000077e1, 0x00000002 },
73 { 0x000077e1, 0x00000006 },
74 { 0xffffffff, 0000000000 },
75 { 0x10000000, 0000000000 },
76 { 0x0003802b, 0x00000002 },
77 { 0x040067e0, 0x00000006 },
78 { 0x00007675, 0x00000002 },
79 { 0x00007676, 0x00000002 },
80 { 0x00007677, 0x00000002 },
81 { 0x00007678, 0x00000006 },
82 { 0x0003802c, 0x00000002 },
83 { 0x04002676, 0x00000002 },
84 { 0x00007677, 0x00000002 },
85 { 0x00007678, 0x00000006 },
86 { 0x0000002f, 0x00000018 },
87 { 0x0000002f, 0x00000018 },
88 { 0000000000, 0x00000006 },
89 { 0x00000030, 0x00000018 },
90 { 0x00000030, 0x00000018 },
91 { 0000000000, 0x00000006 },
92 { 0x01605000, 0x00000002 },
93 { 0x00065000, 0x00000002 },
94 { 0x00098000, 0x00000002 },
95 { 0x00061000, 0x00000002 },
96 { 0x64c0603e, 0x00000004 },
97 { 0x000380e6, 0x00000002 },
98 { 0x040025c5, 0x00000002 },
99 { 0x00080000, 0x00000016 },
100 { 0000000000, 0000000000 },
101 { 0x0400251d, 0x00000002 },
102 { 0x00007580, 0x00000002 },
103 { 0x00067581, 0x00000002 },
104 { 0x04002580, 0x00000002 },
105 { 0x00067581, 0x00000002 },
106 { 0x00000049, 0x00000004 },
107 { 0x00005000, 0000000000 },
108 { 0x000380e6, 0x00000002 },
109 { 0x040025c5, 0x00000002 },
110 { 0x00061000, 0x00000002 },
111 { 0x0000750e, 0x00000002 },
112 { 0x00019000, 0x00000002 },
113 { 0x00011055, 0x00000014 },
114 { 0x00000055, 0x00000012 },
115 { 0x0400250f, 0x00000002 },
116 { 0x0000504f, 0x00000004 },
117 { 0x000380e6, 0x00000002 },
118 { 0x040025c5, 0x00000002 },
119 { 0x00007565, 0x00000002 },
120 { 0x00007566, 0x00000002 },
121 { 0x00000058, 0x00000004 },
122 { 0x000380e6, 0x00000002 },
123 { 0x040025c5, 0x00000002 },
124 { 0x01e655b4, 0x00000002 },
125 { 0x4401b0e4, 0x00000002 },
126 { 0x01c110e4, 0x00000002 },
127 { 0x26667066, 0x00000018 },
128 { 0x040c2565, 0x00000002 },
129 { 0x00000066, 0x00000018 },
130 { 0x04002564, 0x00000002 },
131 { 0x00007566, 0x00000002 },
132 { 0x0000005d, 0x00000004 },
133 { 0x00401069, 0x00000008 },
134 { 0x00101000, 0x00000002 },
135 { 0x000d80ff, 0x00000002 },
136 { 0x0080006c, 0x00000008 },
137 { 0x000f9000, 0x00000002 },
138 { 0x000e00ff, 0x00000002 },
139 { 0000000000, 0x00000006 },
140 { 0x0000008f, 0x00000018 },
141 { 0x0000005b, 0x00000004 },
142 { 0x000380e6, 0x00000002 },
143 { 0x040025c5, 0x00000002 },
144 { 0x00007576, 0x00000002 },
145 { 0x00065000, 0x00000002 },
146 { 0x00009000, 0x00000002 },
147 { 0x00041000, 0x00000002 },
148 { 0x0c00350e, 0x00000002 },
149 { 0x00049000, 0x00000002 },
150 { 0x00051000, 0x00000002 },
151 { 0x01e785f8, 0x00000002 },
152 { 0x00200000, 0x00000002 },
153 { 0x0060007e, 0x0000000c },
154 { 0x00007563, 0x00000002 },
155 { 0x006075f0, 0x00000021 },
156 { 0x20007073, 0x00000004 },
157 { 0x00005073, 0x00000004 },
158 { 0x000380e6, 0x00000002 },
159 { 0x040025c5, 0x00000002 },
160 { 0x00007576, 0x00000002 },
161 { 0x00007577, 0x00000002 },
162 { 0x0000750e, 0x00000002 },
163 { 0x0000750f, 0x00000002 },
164 { 0x00a05000, 0x00000002 },
165 { 0x00600083, 0x0000000c },
166 { 0x006075f0, 0x00000021 },
167 { 0x000075f8, 0x00000002 },
168 { 0x00000083, 0x00000004 },
169 { 0x000a750e, 0x00000002 },
170 { 0x000380e6, 0x00000002 },
171 { 0x040025c5, 0x00000002 },
172 { 0x0020750f, 0x00000002 },
173 { 0x00600086, 0x00000004 },
174 { 0x00007570, 0x00000002 },
175 { 0x00007571, 0x00000002 },
176 { 0x00007572, 0x00000006 },
177 { 0x000380e6, 0x00000002 },
178 { 0x040025c5, 0x00000002 },
179 { 0x00005000, 0x00000002 },
180 { 0x00a05000, 0x00000002 },
181 { 0x00007568, 0x00000002 },
182 { 0x00061000, 0x00000002 },
183 { 0x00000095, 0x0000000c },
184 { 0x00058000, 0x00000002 },
185 { 0x0c607562, 0x00000002 },
186 { 0x00000097, 0x00000004 },
187 { 0x000380e6, 0x00000002 },
188 { 0x040025c5, 0x00000002 },
189 { 0x00600096, 0x00000004 },
190 { 0x400070e5, 0000000000 },
191 { 0x000380e6, 0x00000002 },
192 { 0x040025c5, 0x00000002 },
193 { 0x000380e5, 0x00000002 },
194 { 0x000000a8, 0x0000001c },
195 { 0x000650aa, 0x00000018 },
196 { 0x040025bb, 0x00000002 },
197 { 0x000610ab, 0x00000018 },
198 { 0x040075bc, 0000000000 },
199 { 0x000075bb, 0x00000002 },
200 { 0x000075bc, 0000000000 },
201 { 0x00090000, 0x00000006 },
202 { 0x00090000, 0x00000002 },
203 { 0x000d8002, 0x00000006 },
204 { 0x00007832, 0x00000002 },
205 { 0x00005000, 0x00000002 },
206 { 0x000380e7, 0x00000002 },
207 { 0x04002c97, 0x00000002 },
208 { 0x00007820, 0x00000002 },
209 { 0x00007821, 0x00000002 },
210 { 0x00007800, 0000000000 },
211 { 0x01200000, 0x00000002 },
212 { 0x20077000, 0x00000002 },
213 { 0x01200000, 0x00000002 },
214 { 0x20007000, 0x00000002 },
215 { 0x00061000, 0x00000002 },
216 { 0x0120751b, 0x00000002 },
217 { 0x8040750a, 0x00000002 },
218 { 0x8040750b, 0x00000002 },
219 { 0x00110000, 0x00000002 },
220 { 0x000380e5, 0x00000002 },
221 { 0x000000c6, 0x0000001c },
222 { 0x000610ab, 0x00000018 },
223 { 0x844075bd, 0x00000002 },
224 { 0x000610aa, 0x00000018 },
225 { 0x840075bb, 0x00000002 },
226 { 0x000610ab, 0x00000018 },
227 { 0x844075bc, 0x00000002 },
228 { 0x000000c9, 0x00000004 },
229 { 0x804075bd, 0x00000002 },
230 { 0x800075bb, 0x00000002 },
231 { 0x804075bc, 0x00000002 },
232 { 0x00108000, 0x00000002 },
233 { 0x01400000, 0x00000002 },
234 { 0x006000cd, 0x0000000c },
235 { 0x20c07000, 0x00000020 },
236 { 0x000000cf, 0x00000012 },
237 { 0x00800000, 0x00000006 },
238 { 0x0080751d, 0x00000006 },
239 { 0000000000, 0000000000 },
240 { 0x0000775c, 0x00000002 },
241 { 0x00a05000, 0x00000002 },
242 { 0x00661000, 0x00000002 },
243 { 0x0460275d, 0x00000020 },
244 { 0x00004000, 0000000000 },
245 { 0x01e00830, 0x00000002 },
246 { 0x21007000, 0000000000 },
247 { 0x6464614d, 0000000000 },
248 { 0x69687420, 0000000000 },
249 { 0x00000073, 0000000000 },
250 { 0000000000, 0000000000 },
251 { 0x00005000, 0x00000002 },
252 { 0x000380d0, 0x00000002 },
253 { 0x040025e0, 0x00000002 },
254 { 0x000075e1, 0000000000 },
255 { 0x00000001, 0000000000 },
256 { 0x000380e0, 0x00000002 },
257 { 0x04002394, 0x00000002 },
258 { 0x00005000, 0000000000 },
259 { 0000000000, 0000000000 },
260 { 0000000000, 0000000000 },
261 { 0x00000008, 0000000000 },
262 { 0x00000004, 0000000000 },
263 { 0000000000, 0000000000 },
264 { 0000000000, 0000000000 },
265 { 0000000000, 0000000000 },
266 { 0000000000, 0000000000 },
267 { 0000000000, 0000000000 },
268 { 0000000000, 0000000000 },
269 { 0000000000, 0000000000 },
270 { 0000000000, 0000000000 },
271 { 0000000000, 0000000000 },
272 { 0000000000, 0000000000 },
273 { 0000000000, 0000000000 },
274 { 0000000000, 0000000000 },
275 { 0000000000, 0000000000 },
276 { 0000000000, 0000000000 },
277 { 0000000000, 0000000000 },
278 { 0000000000, 0000000000 },
279 { 0000000000, 0000000000 },
280 { 0000000000, 0000000000 },
281 { 0000000000, 0000000000 },
282 { 0000000000, 0000000000 },
283 { 0000000000, 0000000000 },
284 { 0000000000, 0000000000 },
285 { 0000000000, 0000000000 },
286 { 0000000000, 0000000000 },
287};
288
289static const u32 R200_cp_microcode[][2] = {
290 { 0x21007000, 0000000000 },
291 { 0x20007000, 0000000000 },
292 { 0x000000bf, 0x00000004 },
293 { 0x000000c3, 0x00000004 },
294 { 0x7a685e5d, 0000000000 },
295 { 0x5d5d5588, 0000000000 },
296 { 0x68659197, 0000000000 },
297 { 0x5da19f78, 0000000000 },
298 { 0x5d5d5d5d, 0000000000 },
299 { 0x5dee5d50, 0000000000 },
300 { 0xf2acacac, 0000000000 },
301 { 0xe75df9e9, 0000000000 },
302 { 0xb1dd0e11, 0000000000 },
303 { 0xe2afafaf, 0000000000 },
304 { 0x000f0000, 0x00000016 },
305 { 0x452f232d, 0000000000 },
306 { 0x00000013, 0x00000004 },
307 { 0x000f0000, 0x00000016 },
308 { 0x452f272d, 0000000000 },
309 { 0x000f0001, 0x00000016 },
310 { 0x3e4d4a37, 0000000000 },
311 { 0x000077ef, 0x00000002 },
312 { 0x00061000, 0x00000002 },
313 { 0x00000020, 0x0000001a },
314 { 0x00004000, 0x0000001e },
315 { 0x00061000, 0x00000002 },
316 { 0x00000020, 0x0000001a },
317 { 0x00004000, 0x0000001e },
318 { 0x00061000, 0x00000002 },
319 { 0x00000020, 0x0000001a },
320 { 0x00004000, 0x0000001e },
321 { 0x00000016, 0x00000004 },
322 { 0x0003802a, 0x00000002 },
323 { 0x040067e0, 0x00000002 },
324 { 0x00000016, 0x00000004 },
325 { 0x000077e0, 0x00000002 },
326 { 0x00065000, 0x00000002 },
327 { 0x000037e1, 0x00000002 },
328 { 0x040067e1, 0x00000006 },
329 { 0x000077e0, 0x00000002 },
330 { 0x000077e1, 0x00000002 },
331 { 0x000077e1, 0x00000006 },
332 { 0xffffffff, 0000000000 },
333 { 0x10000000, 0000000000 },
334 { 0x07f007f0, 0000000000 },
335 { 0x0003802a, 0x00000002 },
336 { 0x040067e0, 0x00000006 },
337 { 0x0003802c, 0x00000002 },
338 { 0x04002741, 0x00000002 },
339 { 0x04002741, 0x00000002 },
340 { 0x04002743, 0x00000002 },
341 { 0x00007675, 0x00000002 },
342 { 0x00007676, 0x00000002 },
343 { 0x00007677, 0x00000002 },
344 { 0x00007678, 0x00000006 },
345 { 0x0003802c, 0x00000002 },
346 { 0x04002741, 0x00000002 },
347 { 0x04002741, 0x00000002 },
348 { 0x04002743, 0x00000002 },
349 { 0x00007676, 0x00000002 },
350 { 0x00007677, 0x00000002 },
351 { 0x00007678, 0x00000006 },
352 { 0x0003802b, 0x00000002 },
353 { 0x04002676, 0x00000002 },
354 { 0x00007677, 0x00000002 },
355 { 0x0003802c, 0x00000002 },
356 { 0x04002741, 0x00000002 },
357 { 0x04002743, 0x00000002 },
358 { 0x00007678, 0x00000006 },
359 { 0x0003802c, 0x00000002 },
360 { 0x04002741, 0x00000002 },
361 { 0x04002741, 0x00000002 },
362 { 0x04002743, 0x00000002 },
363 { 0x00007678, 0x00000006 },
364 { 0x0000002f, 0x00000018 },
365 { 0x0000002f, 0x00000018 },
366 { 0000000000, 0x00000006 },
367 { 0x00000037, 0x00000018 },
368 { 0x00000037, 0x00000018 },
369 { 0000000000, 0x00000006 },
370 { 0x01605000, 0x00000002 },
371 { 0x00065000, 0x00000002 },
372 { 0x00098000, 0x00000002 },
373 { 0x00061000, 0x00000002 },
374 { 0x64c06051, 0x00000004 },
375 { 0x00080000, 0x00000016 },
376 { 0000000000, 0000000000 },
377 { 0x0400251d, 0x00000002 },
378 { 0x00007580, 0x00000002 },
379 { 0x00067581, 0x00000002 },
380 { 0x04002580, 0x00000002 },
381 { 0x00067581, 0x00000002 },
382 { 0x0000005a, 0x00000004 },
383 { 0x00005000, 0000000000 },
384 { 0x00061000, 0x00000002 },
385 { 0x0000750e, 0x00000002 },
386 { 0x00019000, 0x00000002 },
387 { 0x00011064, 0x00000014 },
388 { 0x00000064, 0x00000012 },
389 { 0x0400250f, 0x00000002 },
390 { 0x0000505e, 0x00000004 },
391 { 0x00007565, 0x00000002 },
392 { 0x00007566, 0x00000002 },
393 { 0x00000065, 0x00000004 },
394 { 0x01e655b4, 0x00000002 },
395 { 0x4401b0f0, 0x00000002 },
396 { 0x01c110f0, 0x00000002 },
397 { 0x26667071, 0x00000018 },
398 { 0x040c2565, 0x00000002 },
399 { 0x00000071, 0x00000018 },
400 { 0x04002564, 0x00000002 },
401 { 0x00007566, 0x00000002 },
402 { 0x00000068, 0x00000004 },
403 { 0x00401074, 0x00000008 },
404 { 0x00101000, 0x00000002 },
405 { 0x000d80ff, 0x00000002 },
406 { 0x00800077, 0x00000008 },
407 { 0x000f9000, 0x00000002 },
408 { 0x000e00ff, 0x00000002 },
409 { 0000000000, 0x00000006 },
410 { 0x00000094, 0x00000018 },
411 { 0x00000068, 0x00000004 },
412 { 0x00007576, 0x00000002 },
413 { 0x00065000, 0x00000002 },
414 { 0x00009000, 0x00000002 },
415 { 0x00041000, 0x00000002 },
416 { 0x0c00350e, 0x00000002 },
417 { 0x00049000, 0x00000002 },
418 { 0x00051000, 0x00000002 },
419 { 0x01e785f8, 0x00000002 },
420 { 0x00200000, 0x00000002 },
421 { 0x00600087, 0x0000000c },
422 { 0x00007563, 0x00000002 },
423 { 0x006075f0, 0x00000021 },
424 { 0x2000707c, 0x00000004 },
425 { 0x0000507c, 0x00000004 },
426 { 0x00007576, 0x00000002 },
427 { 0x00007577, 0x00000002 },
428 { 0x0000750e, 0x00000002 },
429 { 0x0000750f, 0x00000002 },
430 { 0x00a05000, 0x00000002 },
431 { 0x0060008a, 0x0000000c },
432 { 0x006075f0, 0x00000021 },
433 { 0x000075f8, 0x00000002 },
434 { 0x0000008a, 0x00000004 },
435 { 0x000a750e, 0x00000002 },
436 { 0x0020750f, 0x00000002 },
437 { 0x0060008d, 0x00000004 },
438 { 0x00007570, 0x00000002 },
439 { 0x00007571, 0x00000002 },
440 { 0x00007572, 0x00000006 },
441 { 0x00005000, 0x00000002 },
442 { 0x00a05000, 0x00000002 },
443 { 0x00007568, 0x00000002 },
444 { 0x00061000, 0x00000002 },
445 { 0x00000098, 0x0000000c },
446 { 0x00058000, 0x00000002 },
447 { 0x0c607562, 0x00000002 },
448 { 0x0000009a, 0x00000004 },
449 { 0x00600099, 0x00000004 },
450 { 0x400070f1, 0000000000 },
451 { 0x000380f1, 0x00000002 },
452 { 0x000000a7, 0x0000001c },
453 { 0x000650a9, 0x00000018 },
454 { 0x040025bb, 0x00000002 },
455 { 0x000610aa, 0x00000018 },
456 { 0x040075bc, 0000000000 },
457 { 0x000075bb, 0x00000002 },
458 { 0x000075bc, 0000000000 },
459 { 0x00090000, 0x00000006 },
460 { 0x00090000, 0x00000002 },
461 { 0x000d8002, 0x00000006 },
462 { 0x00005000, 0x00000002 },
463 { 0x00007821, 0x00000002 },
464 { 0x00007800, 0000000000 },
465 { 0x00007821, 0x00000002 },
466 { 0x00007800, 0000000000 },
467 { 0x01665000, 0x00000002 },
468 { 0x000a0000, 0x00000002 },
469 { 0x000671cc, 0x00000002 },
470 { 0x0286f1cd, 0x00000002 },
471 { 0x000000b7, 0x00000010 },
472 { 0x21007000, 0000000000 },
473 { 0x000000be, 0x0000001c },
474 { 0x00065000, 0x00000002 },
475 { 0x000a0000, 0x00000002 },
476 { 0x00061000, 0x00000002 },
477 { 0x000b0000, 0x00000002 },
478 { 0x38067000, 0x00000002 },
479 { 0x000a00ba, 0x00000004 },
480 { 0x20007000, 0000000000 },
481 { 0x01200000, 0x00000002 },
482 { 0x20077000, 0x00000002 },
483 { 0x01200000, 0x00000002 },
484 { 0x20007000, 0000000000 },
485 { 0x00061000, 0x00000002 },
486 { 0x0120751b, 0x00000002 },
487 { 0x8040750a, 0x00000002 },
488 { 0x8040750b, 0x00000002 },
489 { 0x00110000, 0x00000002 },
490 { 0x000380f1, 0x00000002 },
491 { 0x000000d1, 0x0000001c },
492 { 0x000610aa, 0x00000018 },
493 { 0x844075bd, 0x00000002 },
494 { 0x000610a9, 0x00000018 },
495 { 0x840075bb, 0x00000002 },
496 { 0x000610aa, 0x00000018 },
497 { 0x844075bc, 0x00000002 },
498 { 0x000000d4, 0x00000004 },
499 { 0x804075bd, 0x00000002 },
500 { 0x800075bb, 0x00000002 },
501 { 0x804075bc, 0x00000002 },
502 { 0x00108000, 0x00000002 },
503 { 0x01400000, 0x00000002 },
504 { 0x006000d8, 0x0000000c },
505 { 0x20c07000, 0x00000020 },
506 { 0x000000da, 0x00000012 },
507 { 0x00800000, 0x00000006 },
508 { 0x0080751d, 0x00000006 },
509 { 0x000025bb, 0x00000002 },
510 { 0x000040d4, 0x00000004 },
511 { 0x0000775c, 0x00000002 },
512 { 0x00a05000, 0x00000002 },
513 { 0x00661000, 0x00000002 },
514 { 0x0460275d, 0x00000020 },
515 { 0x00004000, 0000000000 },
516 { 0x00007999, 0x00000002 },
517 { 0x00a05000, 0x00000002 },
518 { 0x00661000, 0x00000002 },
519 { 0x0460299b, 0x00000020 },
520 { 0x00004000, 0000000000 },
521 { 0x01e00830, 0x00000002 },
522 { 0x21007000, 0000000000 },
523 { 0x00005000, 0x00000002 },
524 { 0x00038056, 0x00000002 },
525 { 0x040025e0, 0x00000002 },
526 { 0x000075e1, 0000000000 },
527 { 0x00000001, 0000000000 },
528 { 0x000380ed, 0x00000002 },
529 { 0x04007394, 0000000000 },
530 { 0000000000, 0000000000 },
531 { 0000000000, 0000000000 },
532 { 0x000078c4, 0x00000002 },
533 { 0x000078c5, 0x00000002 },
534 { 0x000078c6, 0x00000002 },
535 { 0x00007924, 0x00000002 },
536 { 0x00007925, 0x00000002 },
537 { 0x00007926, 0x00000002 },
538 { 0x000000f2, 0x00000004 },
539 { 0x00007924, 0x00000002 },
540 { 0x00007925, 0x00000002 },
541 { 0x00007926, 0x00000002 },
542 { 0x000000f9, 0x00000004 },
543 { 0000000000, 0000000000 },
544 { 0000000000, 0000000000 },
545 { 0000000000, 0000000000 },
546};
547
548static const u32 R300_cp_microcode[][2] = {
549 { 0x4200e000, 0000000000 },
550 { 0x4000e000, 0000000000 },
551 { 0x000000ae, 0x00000008 },
552 { 0x000000b2, 0x00000008 },
553 { 0x67554b4a, 0000000000 },
554 { 0x4a4a4475, 0000000000 },
555 { 0x55527d83, 0000000000 },
556 { 0x4a8c8b65, 0000000000 },
557 { 0x4aef4af6, 0000000000 },
558 { 0x4ae14a4a, 0000000000 },
559 { 0xe4979797, 0000000000 },
560 { 0xdb4aebdd, 0000000000 },
561 { 0x9ccc4a4a, 0000000000 },
562 { 0xd1989898, 0000000000 },
563 { 0x4a0f9ad6, 0000000000 },
564 { 0x000ca000, 0x00000004 },
565 { 0x000d0012, 0x00000038 },
566 { 0x0000e8b4, 0x00000004 },
567 { 0x000d0014, 0x00000038 },
568 { 0x0000e8b6, 0x00000004 },
569 { 0x000d0016, 0x00000038 },
570 { 0x0000e854, 0x00000004 },
571 { 0x000d0018, 0x00000038 },
572 { 0x0000e855, 0x00000004 },
573 { 0x000d001a, 0x00000038 },
574 { 0x0000e856, 0x00000004 },
575 { 0x000d001c, 0x00000038 },
576 { 0x0000e857, 0x00000004 },
577 { 0x000d001e, 0x00000038 },
578 { 0x0000e824, 0x00000004 },
579 { 0x000d0020, 0x00000038 },
580 { 0x0000e825, 0x00000004 },
581 { 0x000d0022, 0x00000038 },
582 { 0x0000e830, 0x00000004 },
583 { 0x000d0024, 0x00000038 },
584 { 0x0000f0c0, 0x00000004 },
585 { 0x000d0026, 0x00000038 },
586 { 0x0000f0c1, 0x00000004 },
587 { 0x000d0028, 0x00000038 },
588 { 0x0000f041, 0x00000004 },
589 { 0x000d002a, 0x00000038 },
590 { 0x0000f184, 0x00000004 },
591 { 0x000d002c, 0x00000038 },
592 { 0x0000f185, 0x00000004 },
593 { 0x000d002e, 0x00000038 },
594 { 0x0000f186, 0x00000004 },
595 { 0x000d0030, 0x00000038 },
596 { 0x0000f187, 0x00000004 },
597 { 0x000d0032, 0x00000038 },
598 { 0x0000f180, 0x00000004 },
599 { 0x000d0034, 0x00000038 },
600 { 0x0000f393, 0x00000004 },
601 { 0x000d0036, 0x00000038 },
602 { 0x0000f38a, 0x00000004 },
603 { 0x000d0038, 0x00000038 },
604 { 0x0000f38e, 0x00000004 },
605 { 0x0000e821, 0x00000004 },
606 { 0x0140a000, 0x00000004 },
607 { 0x00000043, 0x00000018 },
608 { 0x00cce800, 0x00000004 },
609 { 0x001b0001, 0x00000004 },
610 { 0x08004800, 0x00000004 },
611 { 0x001b0001, 0x00000004 },
612 { 0x08004800, 0x00000004 },
613 { 0x001b0001, 0x00000004 },
614 { 0x08004800, 0x00000004 },
615 { 0x0000003a, 0x00000008 },
616 { 0x0000a000, 0000000000 },
617 { 0x2000451d, 0x00000004 },
618 { 0x0000e580, 0x00000004 },
619 { 0x000ce581, 0x00000004 },
620 { 0x08004580, 0x00000004 },
621 { 0x000ce581, 0x00000004 },
622 { 0x00000047, 0x00000008 },
623 { 0x0000a000, 0000000000 },
624 { 0x000c2000, 0x00000004 },
625 { 0x0000e50e, 0x00000004 },
626 { 0x00032000, 0x00000004 },
627 { 0x00022051, 0x00000028 },
628 { 0x00000051, 0x00000024 },
629 { 0x0800450f, 0x00000004 },
630 { 0x0000a04b, 0x00000008 },
631 { 0x0000e565, 0x00000004 },
632 { 0x0000e566, 0x00000004 },
633 { 0x00000052, 0x00000008 },
634 { 0x03cca5b4, 0x00000004 },
635 { 0x05432000, 0x00000004 },
636 { 0x00022000, 0x00000004 },
637 { 0x4ccce05e, 0x00000030 },
638 { 0x08274565, 0x00000004 },
639 { 0x0000005e, 0x00000030 },
640 { 0x08004564, 0x00000004 },
641 { 0x0000e566, 0x00000004 },
642 { 0x00000055, 0x00000008 },
643 { 0x00802061, 0x00000010 },
644 { 0x00202000, 0x00000004 },
645 { 0x001b00ff, 0x00000004 },
646 { 0x01000064, 0x00000010 },
647 { 0x001f2000, 0x00000004 },
648 { 0x001c00ff, 0x00000004 },
649 { 0000000000, 0x0000000c },
650 { 0x00000080, 0x00000030 },
651 { 0x00000055, 0x00000008 },
652 { 0x0000e576, 0x00000004 },
653 { 0x000ca000, 0x00000004 },
654 { 0x00012000, 0x00000004 },
655 { 0x00082000, 0x00000004 },
656 { 0x1800650e, 0x00000004 },
657 { 0x00092000, 0x00000004 },
658 { 0x000a2000, 0x00000004 },
659 { 0x000f0000, 0x00000004 },
660 { 0x00400000, 0x00000004 },
661 { 0x00000074, 0x00000018 },
662 { 0x0000e563, 0x00000004 },
663 { 0x00c0e5f9, 0x000000c2 },
664 { 0x00000069, 0x00000008 },
665 { 0x0000a069, 0x00000008 },
666 { 0x0000e576, 0x00000004 },
667 { 0x0000e577, 0x00000004 },
668 { 0x0000e50e, 0x00000004 },
669 { 0x0000e50f, 0x00000004 },
670 { 0x0140a000, 0x00000004 },
671 { 0x00000077, 0x00000018 },
672 { 0x00c0e5f9, 0x000000c2 },
673 { 0x00000077, 0x00000008 },
674 { 0x0014e50e, 0x00000004 },
675 { 0x0040e50f, 0x00000004 },
676 { 0x00c0007a, 0x00000008 },
677 { 0x0000e570, 0x00000004 },
678 { 0x0000e571, 0x00000004 },
679 { 0x0000e572, 0x0000000c },
680 { 0x0000a000, 0x00000004 },
681 { 0x0140a000, 0x00000004 },
682 { 0x0000e568, 0x00000004 },
683 { 0x000c2000, 0x00000004 },
684 { 0x00000084, 0x00000018 },
685 { 0x000b0000, 0x00000004 },
686 { 0x18c0e562, 0x00000004 },
687 { 0x00000086, 0x00000008 },
688 { 0x00c00085, 0x00000008 },
689 { 0x000700e3, 0x00000004 },
690 { 0x00000092, 0x00000038 },
691 { 0x000ca094, 0x00000030 },
692 { 0x080045bb, 0x00000004 },
693 { 0x000c2095, 0x00000030 },
694 { 0x0800e5bc, 0000000000 },
695 { 0x0000e5bb, 0x00000004 },
696 { 0x0000e5bc, 0000000000 },
697 { 0x00120000, 0x0000000c },
698 { 0x00120000, 0x00000004 },
699 { 0x001b0002, 0x0000000c },
700 { 0x0000a000, 0x00000004 },
701 { 0x0000e821, 0x00000004 },
702 { 0x0000e800, 0000000000 },
703 { 0x0000e821, 0x00000004 },
704 { 0x0000e82e, 0000000000 },
705 { 0x02cca000, 0x00000004 },
706 { 0x00140000, 0x00000004 },
707 { 0x000ce1cc, 0x00000004 },
708 { 0x050de1cd, 0x00000004 },
709 { 0x00400000, 0x00000004 },
710 { 0x000000a4, 0x00000018 },
711 { 0x00c0a000, 0x00000004 },
712 { 0x000000a1, 0x00000008 },
713 { 0x000000a6, 0x00000020 },
714 { 0x4200e000, 0000000000 },
715 { 0x000000ad, 0x00000038 },
716 { 0x000ca000, 0x00000004 },
717 { 0x00140000, 0x00000004 },
718 { 0x000c2000, 0x00000004 },
719 { 0x00160000, 0x00000004 },
720 { 0x700ce000, 0x00000004 },
721 { 0x001400a9, 0x00000008 },
722 { 0x4000e000, 0000000000 },
723 { 0x02400000, 0x00000004 },
724 { 0x400ee000, 0x00000004 },
725 { 0x02400000, 0x00000004 },
726 { 0x4000e000, 0000000000 },
727 { 0x000c2000, 0x00000004 },
728 { 0x0240e51b, 0x00000004 },
729 { 0x0080e50a, 0x00000005 },
730 { 0x0080e50b, 0x00000005 },
731 { 0x00220000, 0x00000004 },
732 { 0x000700e3, 0x00000004 },
733 { 0x000000c0, 0x00000038 },
734 { 0x000c2095, 0x00000030 },
735 { 0x0880e5bd, 0x00000005 },
736 { 0x000c2094, 0x00000030 },
737 { 0x0800e5bb, 0x00000005 },
738 { 0x000c2095, 0x00000030 },
739 { 0x0880e5bc, 0x00000005 },
740 { 0x000000c3, 0x00000008 },
741 { 0x0080e5bd, 0x00000005 },
742 { 0x0000e5bb, 0x00000005 },
743 { 0x0080e5bc, 0x00000005 },
744 { 0x00210000, 0x00000004 },
745 { 0x02800000, 0x00000004 },
746 { 0x00c000c7, 0x00000018 },
747 { 0x4180e000, 0x00000040 },
748 { 0x000000c9, 0x00000024 },
749 { 0x01000000, 0x0000000c },
750 { 0x0100e51d, 0x0000000c },
751 { 0x000045bb, 0x00000004 },
752 { 0x000080c3, 0x00000008 },
753 { 0x0000f3ce, 0x00000004 },
754 { 0x0140a000, 0x00000004 },
755 { 0x00cc2000, 0x00000004 },
756 { 0x08c053cf, 0x00000040 },
757 { 0x00008000, 0000000000 },
758 { 0x0000f3d2, 0x00000004 },
759 { 0x0140a000, 0x00000004 },
760 { 0x00cc2000, 0x00000004 },
761 { 0x08c053d3, 0x00000040 },
762 { 0x00008000, 0000000000 },
763 { 0x0000f39d, 0x00000004 },
764 { 0x0140a000, 0x00000004 },
765 { 0x00cc2000, 0x00000004 },
766 { 0x08c0539e, 0x00000040 },
767 { 0x00008000, 0000000000 },
768 { 0x03c00830, 0x00000004 },
769 { 0x4200e000, 0000000000 },
770 { 0x0000a000, 0x00000004 },
771 { 0x200045e0, 0x00000004 },
772 { 0x0000e5e1, 0000000000 },
773 { 0x00000001, 0000000000 },
774 { 0x000700e0, 0x00000004 },
775 { 0x0800e394, 0000000000 },
776 { 0000000000, 0000000000 },
777 { 0x0000e8c4, 0x00000004 },
778 { 0x0000e8c5, 0x00000004 },
779 { 0x0000e8c6, 0x00000004 },
780 { 0x0000e928, 0x00000004 },
781 { 0x0000e929, 0x00000004 },
782 { 0x0000e92a, 0x00000004 },
783 { 0x000000e4, 0x00000008 },
784 { 0x0000e928, 0x00000004 },
785 { 0x0000e929, 0x00000004 },
786 { 0x0000e92a, 0x00000004 },
787 { 0x000000eb, 0x00000008 },
788 { 0x02c02000, 0x00000004 },
789 { 0x00060000, 0x00000004 },
790 { 0x000000f3, 0x00000034 },
791 { 0x000000f0, 0x00000008 },
792 { 0x00008000, 0x00000004 },
793 { 0xc000e000, 0000000000 },
794 { 0000000000, 0000000000 },
795 { 0x000c2000, 0x00000004 },
796 { 0x001d0018, 0x00000004 },
797 { 0x001a0001, 0x00000004 },
798 { 0x000000fb, 0x00000034 },
799 { 0x0000004a, 0x00000008 },
800 { 0x0500a04a, 0x00000008 },
801 { 0000000000, 0000000000 },
802 { 0000000000, 0000000000 },
803 { 0000000000, 0000000000 },
804 { 0000000000, 0000000000 },
805};
806
807static const u32 R420_cp_microcode[][2] = {
808 { 0x4200e000, 0000000000 },
809 { 0x4000e000, 0000000000 },
810 { 0x00000099, 0x00000008 },
811 { 0x0000009d, 0x00000008 },
812 { 0x4a554b4a, 0000000000 },
813 { 0x4a4a4467, 0000000000 },
814 { 0x55526f75, 0000000000 },
815 { 0x4a7e7d65, 0000000000 },
816 { 0xd9d3dff6, 0000000000 },
817 { 0x4ac54a4a, 0000000000 },
818 { 0xc8828282, 0000000000 },
819 { 0xbf4acfc1, 0000000000 },
820 { 0x87b04a4a, 0000000000 },
821 { 0xb5838383, 0000000000 },
822 { 0x4a0f85ba, 0000000000 },
823 { 0x000ca000, 0x00000004 },
824 { 0x000d0012, 0x00000038 },
825 { 0x0000e8b4, 0x00000004 },
826 { 0x000d0014, 0x00000038 },
827 { 0x0000e8b6, 0x00000004 },
828 { 0x000d0016, 0x00000038 },
829 { 0x0000e854, 0x00000004 },
830 { 0x000d0018, 0x00000038 },
831 { 0x0000e855, 0x00000004 },
832 { 0x000d001a, 0x00000038 },
833 { 0x0000e856, 0x00000004 },
834 { 0x000d001c, 0x00000038 },
835 { 0x0000e857, 0x00000004 },
836 { 0x000d001e, 0x00000038 },
837 { 0x0000e824, 0x00000004 },
838 { 0x000d0020, 0x00000038 },
839 { 0x0000e825, 0x00000004 },
840 { 0x000d0022, 0x00000038 },
841 { 0x0000e830, 0x00000004 },
842 { 0x000d0024, 0x00000038 },
843 { 0x0000f0c0, 0x00000004 },
844 { 0x000d0026, 0x00000038 },
845 { 0x0000f0c1, 0x00000004 },
846 { 0x000d0028, 0x00000038 },
847 { 0x0000f041, 0x00000004 },
848 { 0x000d002a, 0x00000038 },
849 { 0x0000f184, 0x00000004 },
850 { 0x000d002c, 0x00000038 },
851 { 0x0000f185, 0x00000004 },
852 { 0x000d002e, 0x00000038 },
853 { 0x0000f186, 0x00000004 },
854 { 0x000d0030, 0x00000038 },
855 { 0x0000f187, 0x00000004 },
856 { 0x000d0032, 0x00000038 },
857 { 0x0000f180, 0x00000004 },
858 { 0x000d0034, 0x00000038 },
859 { 0x0000f393, 0x00000004 },
860 { 0x000d0036, 0x00000038 },
861 { 0x0000f38a, 0x00000004 },
862 { 0x000d0038, 0x00000038 },
863 { 0x0000f38e, 0x00000004 },
864 { 0x0000e821, 0x00000004 },
865 { 0x0140a000, 0x00000004 },
866 { 0x00000043, 0x00000018 },
867 { 0x00cce800, 0x00000004 },
868 { 0x001b0001, 0x00000004 },
869 { 0x08004800, 0x00000004 },
870 { 0x001b0001, 0x00000004 },
871 { 0x08004800, 0x00000004 },
872 { 0x001b0001, 0x00000004 },
873 { 0x08004800, 0x00000004 },
874 { 0x0000003a, 0x00000008 },
875 { 0x0000a000, 0000000000 },
876 { 0x2000451d, 0x00000004 },
877 { 0x0000e580, 0x00000004 },
878 { 0x000ce581, 0x00000004 },
879 { 0x08004580, 0x00000004 },
880 { 0x000ce581, 0x00000004 },
881 { 0x00000047, 0x00000008 },
882 { 0x0000a000, 0000000000 },
883 { 0x000c2000, 0x00000004 },
884 { 0x0000e50e, 0x00000004 },
885 { 0x00032000, 0x00000004 },
886 { 0x00022051, 0x00000028 },
887 { 0x00000051, 0x00000024 },
888 { 0x0800450f, 0x00000004 },
889 { 0x0000a04b, 0x00000008 },
890 { 0x0000e565, 0x00000004 },
891 { 0x0000e566, 0x00000004 },
892 { 0x00000052, 0x00000008 },
893 { 0x03cca5b4, 0x00000004 },
894 { 0x05432000, 0x00000004 },
895 { 0x00022000, 0x00000004 },
896 { 0x4ccce05e, 0x00000030 },
897 { 0x08274565, 0x00000004 },
898 { 0x0000005e, 0x00000030 },
899 { 0x08004564, 0x00000004 },
900 { 0x0000e566, 0x00000004 },
901 { 0x00000055, 0x00000008 },
902 { 0x00802061, 0x00000010 },
903 { 0x00202000, 0x00000004 },
904 { 0x001b00ff, 0x00000004 },
905 { 0x01000064, 0x00000010 },
906 { 0x001f2000, 0x00000004 },
907 { 0x001c00ff, 0x00000004 },
908 { 0000000000, 0x0000000c },
909 { 0x00000072, 0x00000030 },
910 { 0x00000055, 0x00000008 },
911 { 0x0000e576, 0x00000004 },
912 { 0x0000e577, 0x00000004 },
913 { 0x0000e50e, 0x00000004 },
914 { 0x0000e50f, 0x00000004 },
915 { 0x0140a000, 0x00000004 },
916 { 0x00000069, 0x00000018 },
917 { 0x00c0e5f9, 0x000000c2 },
918 { 0x00000069, 0x00000008 },
919 { 0x0014e50e, 0x00000004 },
920 { 0x0040e50f, 0x00000004 },
921 { 0x00c0006c, 0x00000008 },
922 { 0x0000e570, 0x00000004 },
923 { 0x0000e571, 0x00000004 },
924 { 0x0000e572, 0x0000000c },
925 { 0x0000a000, 0x00000004 },
926 { 0x0140a000, 0x00000004 },
927 { 0x0000e568, 0x00000004 },
928 { 0x000c2000, 0x00000004 },
929 { 0x00000076, 0x00000018 },
930 { 0x000b0000, 0x00000004 },
931 { 0x18c0e562, 0x00000004 },
932 { 0x00000078, 0x00000008 },
933 { 0x00c00077, 0x00000008 },
934 { 0x000700c7, 0x00000004 },
935 { 0x00000080, 0x00000038 },
936 { 0x0000e5bb, 0x00000004 },
937 { 0x0000e5bc, 0000000000 },
938 { 0x0000a000, 0x00000004 },
939 { 0x0000e821, 0x00000004 },
940 { 0x0000e800, 0000000000 },
941 { 0x0000e821, 0x00000004 },
942 { 0x0000e82e, 0000000000 },
943 { 0x02cca000, 0x00000004 },
944 { 0x00140000, 0x00000004 },
945 { 0x000ce1cc, 0x00000004 },
946 { 0x050de1cd, 0x00000004 },
947 { 0x00400000, 0x00000004 },
948 { 0x0000008f, 0x00000018 },
949 { 0x00c0a000, 0x00000004 },
950 { 0x0000008c, 0x00000008 },
951 { 0x00000091, 0x00000020 },
952 { 0x4200e000, 0000000000 },
953 { 0x00000098, 0x00000038 },
954 { 0x000ca000, 0x00000004 },
955 { 0x00140000, 0x00000004 },
956 { 0x000c2000, 0x00000004 },
957 { 0x00160000, 0x00000004 },
958 { 0x700ce000, 0x00000004 },
959 { 0x00140094, 0x00000008 },
960 { 0x4000e000, 0000000000 },
961 { 0x02400000, 0x00000004 },
962 { 0x400ee000, 0x00000004 },
963 { 0x02400000, 0x00000004 },
964 { 0x4000e000, 0000000000 },
965 { 0x000c2000, 0x00000004 },
966 { 0x0240e51b, 0x00000004 },
967 { 0x0080e50a, 0x00000005 },
968 { 0x0080e50b, 0x00000005 },
969 { 0x00220000, 0x00000004 },
970 { 0x000700c7, 0x00000004 },
971 { 0x000000a4, 0x00000038 },
972 { 0x0080e5bd, 0x00000005 },
973 { 0x0000e5bb, 0x00000005 },
974 { 0x0080e5bc, 0x00000005 },
975 { 0x00210000, 0x00000004 },
976 { 0x02800000, 0x00000004 },
977 { 0x00c000ab, 0x00000018 },
978 { 0x4180e000, 0x00000040 },
979 { 0x000000ad, 0x00000024 },
980 { 0x01000000, 0x0000000c },
981 { 0x0100e51d, 0x0000000c },
982 { 0x000045bb, 0x00000004 },
983 { 0x000080a7, 0x00000008 },
984 { 0x0000f3ce, 0x00000004 },
985 { 0x0140a000, 0x00000004 },
986 { 0x00cc2000, 0x00000004 },
987 { 0x08c053cf, 0x00000040 },
988 { 0x00008000, 0000000000 },
989 { 0x0000f3d2, 0x00000004 },
990 { 0x0140a000, 0x00000004 },
991 { 0x00cc2000, 0x00000004 },
992 { 0x08c053d3, 0x00000040 },
993 { 0x00008000, 0000000000 },
994 { 0x0000f39d, 0x00000004 },
995 { 0x0140a000, 0x00000004 },
996 { 0x00cc2000, 0x00000004 },
997 { 0x08c0539e, 0x00000040 },
998 { 0x00008000, 0000000000 },
999 { 0x03c00830, 0x00000004 },
1000 { 0x4200e000, 0000000000 },
1001 { 0x0000a000, 0x00000004 },
1002 { 0x200045e0, 0x00000004 },
1003 { 0x0000e5e1, 0000000000 },
1004 { 0x00000001, 0000000000 },
1005 { 0x000700c4, 0x00000004 },
1006 { 0x0800e394, 0000000000 },
1007 { 0000000000, 0000000000 },
1008 { 0x0000e8c4, 0x00000004 },
1009 { 0x0000e8c5, 0x00000004 },
1010 { 0x0000e8c6, 0x00000004 },
1011 { 0x0000e928, 0x00000004 },
1012 { 0x0000e929, 0x00000004 },
1013 { 0x0000e92a, 0x00000004 },
1014 { 0x000000c8, 0x00000008 },
1015 { 0x0000e928, 0x00000004 },
1016 { 0x0000e929, 0x00000004 },
1017 { 0x0000e92a, 0x00000004 },
1018 { 0x000000cf, 0x00000008 },
1019 { 0x02c02000, 0x00000004 },
1020 { 0x00060000, 0x00000004 },
1021 { 0x000000d7, 0x00000034 },
1022 { 0x000000d4, 0x00000008 },
1023 { 0x00008000, 0x00000004 },
1024 { 0xc000e000, 0000000000 },
1025 { 0x0000e1cc, 0x00000004 },
1026 { 0x0500e1cd, 0x00000004 },
1027 { 0x000ca000, 0x00000004 },
1028 { 0x000000de, 0x00000034 },
1029 { 0x000000da, 0x00000008 },
1030 { 0x0000a000, 0000000000 },
1031 { 0x0019e1cc, 0x00000004 },
1032 { 0x001b0001, 0x00000004 },
1033 { 0x0500a000, 0x00000004 },
1034 { 0x080041cd, 0x00000004 },
1035 { 0x000ca000, 0x00000004 },
1036 { 0x000000fb, 0x00000034 },
1037 { 0x0000004a, 0x00000008 },
1038 { 0000000000, 0000000000 },
1039 { 0000000000, 0000000000 },
1040 { 0000000000, 0000000000 },
1041 { 0000000000, 0000000000 },
1042 { 0000000000, 0000000000 },
1043 { 0000000000, 0000000000 },
1044 { 0000000000, 0000000000 },
1045 { 0000000000, 0000000000 },
1046 { 0000000000, 0000000000 },
1047 { 0000000000, 0000000000 },
1048 { 0000000000, 0000000000 },
1049 { 0000000000, 0000000000 },
1050 { 0000000000, 0000000000 },
1051 { 0000000000, 0000000000 },
1052 { 0000000000, 0000000000 },
1053 { 0000000000, 0000000000 },
1054 { 0x000c2000, 0x00000004 },
1055 { 0x001d0018, 0x00000004 },
1056 { 0x001a0001, 0x00000004 },
1057 { 0x000000fb, 0x00000034 },
1058 { 0x0000004a, 0x00000008 },
1059 { 0x0500a04a, 0x00000008 },
1060 { 0000000000, 0000000000 },
1061 { 0000000000, 0000000000 },
1062 { 0000000000, 0000000000 },
1063 { 0000000000, 0000000000 },
1064};
1065
1066static const u32 RS600_cp_microcode[][2] = {
1067 { 0x4200e000, 0000000000 },
1068 { 0x4000e000, 0000000000 },
1069 { 0x000000a0, 0x00000008 },
1070 { 0x000000a4, 0x00000008 },
1071 { 0x4a554b4a, 0000000000 },
1072 { 0x4a4a4467, 0000000000 },
1073 { 0x55526f75, 0000000000 },
1074 { 0x4a7e7d65, 0000000000 },
1075 { 0x4ae74af6, 0000000000 },
1076 { 0x4ad34a4a, 0000000000 },
1077 { 0xd6898989, 0000000000 },
1078 { 0xcd4addcf, 0000000000 },
1079 { 0x8ebe4ae2, 0000000000 },
1080 { 0xc38a8a8a, 0000000000 },
1081 { 0x4a0f8cc8, 0000000000 },
1082 { 0x000ca000, 0x00000004 },
1083 { 0x000d0012, 0x00000038 },
1084 { 0x0000e8b4, 0x00000004 },
1085 { 0x000d0014, 0x00000038 },
1086 { 0x0000e8b6, 0x00000004 },
1087 { 0x000d0016, 0x00000038 },
1088 { 0x0000e854, 0x00000004 },
1089 { 0x000d0018, 0x00000038 },
1090 { 0x0000e855, 0x00000004 },
1091 { 0x000d001a, 0x00000038 },
1092 { 0x0000e856, 0x00000004 },
1093 { 0x000d001c, 0x00000038 },
1094 { 0x0000e857, 0x00000004 },
1095 { 0x000d001e, 0x00000038 },
1096 { 0x0000e824, 0x00000004 },
1097 { 0x000d0020, 0x00000038 },
1098 { 0x0000e825, 0x00000004 },
1099 { 0x000d0022, 0x00000038 },
1100 { 0x0000e830, 0x00000004 },
1101 { 0x000d0024, 0x00000038 },
1102 { 0x0000f0c0, 0x00000004 },
1103 { 0x000d0026, 0x00000038 },
1104 { 0x0000f0c1, 0x00000004 },
1105 { 0x000d0028, 0x00000038 },
1106 { 0x0000f041, 0x00000004 },
1107 { 0x000d002a, 0x00000038 },
1108 { 0x0000f184, 0x00000004 },
1109 { 0x000d002c, 0x00000038 },
1110 { 0x0000f185, 0x00000004 },
1111 { 0x000d002e, 0x00000038 },
1112 { 0x0000f186, 0x00000004 },
1113 { 0x000d0030, 0x00000038 },
1114 { 0x0000f187, 0x00000004 },
1115 { 0x000d0032, 0x00000038 },
1116 { 0x0000f180, 0x00000004 },
1117 { 0x000d0034, 0x00000038 },
1118 { 0x0000f393, 0x00000004 },
1119 { 0x000d0036, 0x00000038 },
1120 { 0x0000f38a, 0x00000004 },
1121 { 0x000d0038, 0x00000038 },
1122 { 0x0000f38e, 0x00000004 },
1123 { 0x0000e821, 0x00000004 },
1124 { 0x0140a000, 0x00000004 },
1125 { 0x00000043, 0x00000018 },
1126 { 0x00cce800, 0x00000004 },
1127 { 0x001b0001, 0x00000004 },
1128 { 0x08004800, 0x00000004 },
1129 { 0x001b0001, 0x00000004 },
1130 { 0x08004800, 0x00000004 },
1131 { 0x001b0001, 0x00000004 },
1132 { 0x08004800, 0x00000004 },
1133 { 0x0000003a, 0x00000008 },
1134 { 0x0000a000, 0000000000 },
1135 { 0x2000451d, 0x00000004 },
1136 { 0x0000e580, 0x00000004 },
1137 { 0x000ce581, 0x00000004 },
1138 { 0x08004580, 0x00000004 },
1139 { 0x000ce581, 0x00000004 },
1140 { 0x00000047, 0x00000008 },
1141 { 0x0000a000, 0000000000 },
1142 { 0x000c2000, 0x00000004 },
1143 { 0x0000e50e, 0x00000004 },
1144 { 0x00032000, 0x00000004 },
1145 { 0x00022051, 0x00000028 },
1146 { 0x00000051, 0x00000024 },
1147 { 0x0800450f, 0x00000004 },
1148 { 0x0000a04b, 0x00000008 },
1149 { 0x0000e565, 0x00000004 },
1150 { 0x0000e566, 0x00000004 },
1151 { 0x00000052, 0x00000008 },
1152 { 0x03cca5b4, 0x00000004 },
1153 { 0x05432000, 0x00000004 },
1154 { 0x00022000, 0x00000004 },
1155 { 0x4ccce05e, 0x00000030 },
1156 { 0x08274565, 0x00000004 },
1157 { 0x0000005e, 0x00000030 },
1158 { 0x08004564, 0x00000004 },
1159 { 0x0000e566, 0x00000004 },
1160 { 0x00000055, 0x00000008 },
1161 { 0x00802061, 0x00000010 },
1162 { 0x00202000, 0x00000004 },
1163 { 0x001b00ff, 0x00000004 },
1164 { 0x01000064, 0x00000010 },
1165 { 0x001f2000, 0x00000004 },
1166 { 0x001c00ff, 0x00000004 },
1167 { 0000000000, 0x0000000c },
1168 { 0x00000072, 0x00000030 },
1169 { 0x00000055, 0x00000008 },
1170 { 0x0000e576, 0x00000004 },
1171 { 0x0000e577, 0x00000004 },
1172 { 0x0000e50e, 0x00000004 },
1173 { 0x0000e50f, 0x00000004 },
1174 { 0x0140a000, 0x00000004 },
1175 { 0x00000069, 0x00000018 },
1176 { 0x00c0e5f9, 0x000000c2 },
1177 { 0x00000069, 0x00000008 },
1178 { 0x0014e50e, 0x00000004 },
1179 { 0x0040e50f, 0x00000004 },
1180 { 0x00c0006c, 0x00000008 },
1181 { 0x0000e570, 0x00000004 },
1182 { 0x0000e571, 0x00000004 },
1183 { 0x0000e572, 0x0000000c },
1184 { 0x0000a000, 0x00000004 },
1185 { 0x0140a000, 0x00000004 },
1186 { 0x0000e568, 0x00000004 },
1187 { 0x000c2000, 0x00000004 },
1188 { 0x00000076, 0x00000018 },
1189 { 0x000b0000, 0x00000004 },
1190 { 0x18c0e562, 0x00000004 },
1191 { 0x00000078, 0x00000008 },
1192 { 0x00c00077, 0x00000008 },
1193 { 0x000700d5, 0x00000004 },
1194 { 0x00000084, 0x00000038 },
1195 { 0x000ca086, 0x00000030 },
1196 { 0x080045bb, 0x00000004 },
1197 { 0x000c2087, 0x00000030 },
1198 { 0x0800e5bc, 0000000000 },
1199 { 0x0000e5bb, 0x00000004 },
1200 { 0x0000e5bc, 0000000000 },
1201 { 0x00120000, 0x0000000c },
1202 { 0x00120000, 0x00000004 },
1203 { 0x001b0002, 0x0000000c },
1204 { 0x0000a000, 0x00000004 },
1205 { 0x0000e821, 0x00000004 },
1206 { 0x0000e800, 0000000000 },
1207 { 0x0000e821, 0x00000004 },
1208 { 0x0000e82e, 0000000000 },
1209 { 0x02cca000, 0x00000004 },
1210 { 0x00140000, 0x00000004 },
1211 { 0x000ce1cc, 0x00000004 },
1212 { 0x050de1cd, 0x00000004 },
1213 { 0x00400000, 0x00000004 },
1214 { 0x00000096, 0x00000018 },
1215 { 0x00c0a000, 0x00000004 },
1216 { 0x00000093, 0x00000008 },
1217 { 0x00000098, 0x00000020 },
1218 { 0x4200e000, 0000000000 },
1219 { 0x0000009f, 0x00000038 },
1220 { 0x000ca000, 0x00000004 },
1221 { 0x00140000, 0x00000004 },
1222 { 0x000c2000, 0x00000004 },
1223 { 0x00160000, 0x00000004 },
1224 { 0x700ce000, 0x00000004 },
1225 { 0x0014009b, 0x00000008 },
1226 { 0x4000e000, 0000000000 },
1227 { 0x02400000, 0x00000004 },
1228 { 0x400ee000, 0x00000004 },
1229 { 0x02400000, 0x00000004 },
1230 { 0x4000e000, 0000000000 },
1231 { 0x000c2000, 0x00000004 },
1232 { 0x0240e51b, 0x00000004 },
1233 { 0x0080e50a, 0x00000005 },
1234 { 0x0080e50b, 0x00000005 },
1235 { 0x00220000, 0x00000004 },
1236 { 0x000700d5, 0x00000004 },
1237 { 0x000000b2, 0x00000038 },
1238 { 0x000c2087, 0x00000030 },
1239 { 0x0880e5bd, 0x00000005 },
1240 { 0x000c2086, 0x00000030 },
1241 { 0x0800e5bb, 0x00000005 },
1242 { 0x000c2087, 0x00000030 },
1243 { 0x0880e5bc, 0x00000005 },
1244 { 0x000000b5, 0x00000008 },
1245 { 0x0080e5bd, 0x00000005 },
1246 { 0x0000e5bb, 0x00000005 },
1247 { 0x0080e5bc, 0x00000005 },
1248 { 0x00210000, 0x00000004 },
1249 { 0x02800000, 0x00000004 },
1250 { 0x00c000b9, 0x00000018 },
1251 { 0x4180e000, 0x00000040 },
1252 { 0x000000bb, 0x00000024 },
1253 { 0x01000000, 0x0000000c },
1254 { 0x0100e51d, 0x0000000c },
1255 { 0x000045bb, 0x00000004 },
1256 { 0x000080b5, 0x00000008 },
1257 { 0x0000f3ce, 0x00000004 },
1258 { 0x0140a000, 0x00000004 },
1259 { 0x00cc2000, 0x00000004 },
1260 { 0x08c053cf, 0x00000040 },
1261 { 0x00008000, 0000000000 },
1262 { 0x0000f3d2, 0x00000004 },
1263 { 0x0140a000, 0x00000004 },
1264 { 0x00cc2000, 0x00000004 },
1265 { 0x08c053d3, 0x00000040 },
1266 { 0x00008000, 0000000000 },
1267 { 0x0000f39d, 0x00000004 },
1268 { 0x0140a000, 0x00000004 },
1269 { 0x00cc2000, 0x00000004 },
1270 { 0x08c0539e, 0x00000040 },
1271 { 0x00008000, 0000000000 },
1272 { 0x03c00830, 0x00000004 },
1273 { 0x4200e000, 0000000000 },
1274 { 0x0000a000, 0x00000004 },
1275 { 0x200045e0, 0x00000004 },
1276 { 0x0000e5e1, 0000000000 },
1277 { 0x00000001, 0000000000 },
1278 { 0x000700d2, 0x00000004 },
1279 { 0x0800e394, 0000000000 },
1280 { 0000000000, 0000000000 },
1281 { 0x0000e8c4, 0x00000004 },
1282 { 0x0000e8c5, 0x00000004 },
1283 { 0x0000e8c6, 0x00000004 },
1284 { 0x0000e928, 0x00000004 },
1285 { 0x0000e929, 0x00000004 },
1286 { 0x0000e92a, 0x00000004 },
1287 { 0x000000d6, 0x00000008 },
1288 { 0x0000e928, 0x00000004 },
1289 { 0x0000e929, 0x00000004 },
1290 { 0x0000e92a, 0x00000004 },
1291 { 0x000000dd, 0x00000008 },
1292 { 0x00e00116, 0000000000 },
1293 { 0x000700e1, 0x00000004 },
1294 { 0x0800401c, 0x00000004 },
1295 { 0x200050e7, 0x00000004 },
1296 { 0x0000e01d, 0x00000004 },
1297 { 0x000000e4, 0x00000008 },
1298 { 0x02c02000, 0x00000004 },
1299 { 0x00060000, 0x00000004 },
1300 { 0x000000eb, 0x00000034 },
1301 { 0x000000e8, 0x00000008 },
1302 { 0x00008000, 0x00000004 },
1303 { 0xc000e000, 0000000000 },
1304 { 0000000000, 0000000000 },
1305 { 0000000000, 0000000000 },
1306 { 0000000000, 0000000000 },
1307 { 0000000000, 0000000000 },
1308 { 0000000000, 0000000000 },
1309 { 0000000000, 0000000000 },
1310 { 0000000000, 0000000000 },
1311 { 0000000000, 0000000000 },
1312 { 0000000000, 0000000000 },
1313 { 0x000c2000, 0x00000004 },
1314 { 0x001d0018, 0x00000004 },
1315 { 0x001a0001, 0x00000004 },
1316 { 0x000000fb, 0x00000034 },
1317 { 0x0000004a, 0x00000008 },
1318 { 0x0500a04a, 0x00000008 },
1319 { 0000000000, 0000000000 },
1320 { 0000000000, 0000000000 },
1321 { 0000000000, 0000000000 },
1322 { 0000000000, 0000000000 },
1323};
1324
1325static const u32 RS690_cp_microcode[][2] = {
1326 { 0x000000dd, 0x00000008 },
1327 { 0x000000df, 0x00000008 },
1328 { 0x000000a0, 0x00000008 },
1329 { 0x000000a4, 0x00000008 },
1330 { 0x4a554b4a, 0000000000 },
1331 { 0x4a4a4467, 0000000000 },
1332 { 0x55526f75, 0000000000 },
1333 { 0x4a7e7d65, 0000000000 },
1334 { 0x4ad74af6, 0000000000 },
1335 { 0x4ac94a4a, 0000000000 },
1336 { 0xcc898989, 0000000000 },
1337 { 0xc34ad3c5, 0000000000 },
1338 { 0x8e4a4a4a, 0000000000 },
1339 { 0x4a8a8a8a, 0000000000 },
1340 { 0x4a0f8c4a, 0000000000 },
1341 { 0x000ca000, 0x00000004 },
1342 { 0x000d0012, 0x00000038 },
1343 { 0x0000e8b4, 0x00000004 },
1344 { 0x000d0014, 0x00000038 },
1345 { 0x0000e8b6, 0x00000004 },
1346 { 0x000d0016, 0x00000038 },
1347 { 0x0000e854, 0x00000004 },
1348 { 0x000d0018, 0x00000038 },
1349 { 0x0000e855, 0x00000004 },
1350 { 0x000d001a, 0x00000038 },
1351 { 0x0000e856, 0x00000004 },
1352 { 0x000d001c, 0x00000038 },
1353 { 0x0000e857, 0x00000004 },
1354 { 0x000d001e, 0x00000038 },
1355 { 0x0000e824, 0x00000004 },
1356 { 0x000d0020, 0x00000038 },
1357 { 0x0000e825, 0x00000004 },
1358 { 0x000d0022, 0x00000038 },
1359 { 0x0000e830, 0x00000004 },
1360 { 0x000d0024, 0x00000038 },
1361 { 0x0000f0c0, 0x00000004 },
1362 { 0x000d0026, 0x00000038 },
1363 { 0x0000f0c1, 0x00000004 },
1364 { 0x000d0028, 0x00000038 },
1365 { 0x0000f041, 0x00000004 },
1366 { 0x000d002a, 0x00000038 },
1367 { 0x0000f184, 0x00000004 },
1368 { 0x000d002c, 0x00000038 },
1369 { 0x0000f185, 0x00000004 },
1370 { 0x000d002e, 0x00000038 },
1371 { 0x0000f186, 0x00000004 },
1372 { 0x000d0030, 0x00000038 },
1373 { 0x0000f187, 0x00000004 },
1374 { 0x000d0032, 0x00000038 },
1375 { 0x0000f180, 0x00000004 },
1376 { 0x000d0034, 0x00000038 },
1377 { 0x0000f393, 0x00000004 },
1378 { 0x000d0036, 0x00000038 },
1379 { 0x0000f38a, 0x00000004 },
1380 { 0x000d0038, 0x00000038 },
1381 { 0x0000f38e, 0x00000004 },
1382 { 0x0000e821, 0x00000004 },
1383 { 0x0140a000, 0x00000004 },
1384 { 0x00000043, 0x00000018 },
1385 { 0x00cce800, 0x00000004 },
1386 { 0x001b0001, 0x00000004 },
1387 { 0x08004800, 0x00000004 },
1388 { 0x001b0001, 0x00000004 },
1389 { 0x08004800, 0x00000004 },
1390 { 0x001b0001, 0x00000004 },
1391 { 0x08004800, 0x00000004 },
1392 { 0x0000003a, 0x00000008 },
1393 { 0x0000a000, 0000000000 },
1394 { 0x2000451d, 0x00000004 },
1395 { 0x0000e580, 0x00000004 },
1396 { 0x000ce581, 0x00000004 },
1397 { 0x08004580, 0x00000004 },
1398 { 0x000ce581, 0x00000004 },
1399 { 0x00000047, 0x00000008 },
1400 { 0x0000a000, 0000000000 },
1401 { 0x000c2000, 0x00000004 },
1402 { 0x0000e50e, 0x00000004 },
1403 { 0x00032000, 0x00000004 },
1404 { 0x00022051, 0x00000028 },
1405 { 0x00000051, 0x00000024 },
1406 { 0x0800450f, 0x00000004 },
1407 { 0x0000a04b, 0x00000008 },
1408 { 0x0000e565, 0x00000004 },
1409 { 0x0000e566, 0x00000004 },
1410 { 0x00000052, 0x00000008 },
1411 { 0x03cca5b4, 0x00000004 },
1412 { 0x05432000, 0x00000004 },
1413 { 0x00022000, 0x00000004 },
1414 { 0x4ccce05e, 0x00000030 },
1415 { 0x08274565, 0x00000004 },
1416 { 0x0000005e, 0x00000030 },
1417 { 0x08004564, 0x00000004 },
1418 { 0x0000e566, 0x00000004 },
1419 { 0x00000055, 0x00000008 },
1420 { 0x00802061, 0x00000010 },
1421 { 0x00202000, 0x00000004 },
1422 { 0x001b00ff, 0x00000004 },
1423 { 0x01000064, 0x00000010 },
1424 { 0x001f2000, 0x00000004 },
1425 { 0x001c00ff, 0x00000004 },
1426 { 0000000000, 0x0000000c },
1427 { 0x00000072, 0x00000030 },
1428 { 0x00000055, 0x00000008 },
1429 { 0x0000e576, 0x00000004 },
1430 { 0x0000e577, 0x00000004 },
1431 { 0x0000e50e, 0x00000004 },
1432 { 0x0000e50f, 0x00000004 },
1433 { 0x0140a000, 0x00000004 },
1434 { 0x00000069, 0x00000018 },
1435 { 0x00c0e5f9, 0x000000c2 },
1436 { 0x00000069, 0x00000008 },
1437 { 0x0014e50e, 0x00000004 },
1438 { 0x0040e50f, 0x00000004 },
1439 { 0x00c0006c, 0x00000008 },
1440 { 0x0000e570, 0x00000004 },
1441 { 0x0000e571, 0x00000004 },
1442 { 0x0000e572, 0x0000000c },
1443 { 0x0000a000, 0x00000004 },
1444 { 0x0140a000, 0x00000004 },
1445 { 0x0000e568, 0x00000004 },
1446 { 0x000c2000, 0x00000004 },
1447 { 0x00000076, 0x00000018 },
1448 { 0x000b0000, 0x00000004 },
1449 { 0x18c0e562, 0x00000004 },
1450 { 0x00000078, 0x00000008 },
1451 { 0x00c00077, 0x00000008 },
1452 { 0x000700cb, 0x00000004 },
1453 { 0x00000084, 0x00000038 },
1454 { 0x000ca086, 0x00000030 },
1455 { 0x080045bb, 0x00000004 },
1456 { 0x000c2087, 0x00000030 },
1457 { 0x0800e5bc, 0000000000 },
1458 { 0x0000e5bb, 0x00000004 },
1459 { 0x0000e5bc, 0000000000 },
1460 { 0x00120000, 0x0000000c },
1461 { 0x00120000, 0x00000004 },
1462 { 0x001b0002, 0x0000000c },
1463 { 0x0000a000, 0x00000004 },
1464 { 0x0000e821, 0x00000004 },
1465 { 0x0000e800, 0000000000 },
1466 { 0x0000e821, 0x00000004 },
1467 { 0x0000e82e, 0000000000 },
1468 { 0x02cca000, 0x00000004 },
1469 { 0x00140000, 0x00000004 },
1470 { 0x000ce1cc, 0x00000004 },
1471 { 0x050de1cd, 0x00000004 },
1472 { 0x00400000, 0x00000004 },
1473 { 0x00000096, 0x00000018 },
1474 { 0x00c0a000, 0x00000004 },
1475 { 0x00000093, 0x00000008 },
1476 { 0x00000098, 0x00000020 },
1477 { 0x4200e000, 0000000000 },
1478 { 0x0000009f, 0x00000038 },
1479 { 0x000ca000, 0x00000004 },
1480 { 0x00140000, 0x00000004 },
1481 { 0x000c2000, 0x00000004 },
1482 { 0x00160000, 0x00000004 },
1483 { 0x700ce000, 0x00000004 },
1484 { 0x0014009b, 0x00000008 },
1485 { 0x4000e000, 0000000000 },
1486 { 0x02400000, 0x00000004 },
1487 { 0x400ee000, 0x00000004 },
1488 { 0x02400000, 0x00000004 },
1489 { 0x4000e000, 0000000000 },
1490 { 0x00100000, 0x0000002c },
1491 { 0x00004000, 0000000000 },
1492 { 0x080045c8, 0x00000004 },
1493 { 0x00240005, 0x00000004 },
1494 { 0x08004d0b, 0x00000004 },
1495 { 0x000c2000, 0x00000004 },
1496 { 0x0240e51b, 0x00000004 },
1497 { 0x0080e50a, 0x00000005 },
1498 { 0x0080e50b, 0x00000005 },
1499 { 0x00220000, 0x00000004 },
1500 { 0x000700cb, 0x00000004 },
1501 { 0x000000b7, 0x00000038 },
1502 { 0x000c2087, 0x00000030 },
1503 { 0x0880e5bd, 0x00000005 },
1504 { 0x000c2086, 0x00000030 },
1505 { 0x0800e5bb, 0x00000005 },
1506 { 0x000c2087, 0x00000030 },
1507 { 0x0880e5bc, 0x00000005 },
1508 { 0x000000ba, 0x00000008 },
1509 { 0x0080e5bd, 0x00000005 },
1510 { 0x0000e5bb, 0x00000005 },
1511 { 0x0080e5bc, 0x00000005 },
1512 { 0x00210000, 0x00000004 },
1513 { 0x02800000, 0x00000004 },
1514 { 0x00c000be, 0x00000018 },
1515 { 0x4180e000, 0x00000040 },
1516 { 0x000000c0, 0x00000024 },
1517 { 0x01000000, 0x0000000c },
1518 { 0x0100e51d, 0x0000000c },
1519 { 0x000045bb, 0x00000004 },
1520 { 0x000080ba, 0x00000008 },
1521 { 0x03c00830, 0x00000004 },
1522 { 0x4200e000, 0000000000 },
1523 { 0x0000a000, 0x00000004 },
1524 { 0x200045e0, 0x00000004 },
1525 { 0x0000e5e1, 0000000000 },
1526 { 0x00000001, 0000000000 },
1527 { 0x000700c8, 0x00000004 },
1528 { 0x0800e394, 0000000000 },
1529 { 0000000000, 0000000000 },
1530 { 0x0000e8c4, 0x00000004 },
1531 { 0x0000e8c5, 0x00000004 },
1532 { 0x0000e8c6, 0x00000004 },
1533 { 0x0000e928, 0x00000004 },
1534 { 0x0000e929, 0x00000004 },
1535 { 0x0000e92a, 0x00000004 },
1536 { 0x000000cc, 0x00000008 },
1537 { 0x0000e928, 0x00000004 },
1538 { 0x0000e929, 0x00000004 },
1539 { 0x0000e92a, 0x00000004 },
1540 { 0x000000d3, 0x00000008 },
1541 { 0x02c02000, 0x00000004 },
1542 { 0x00060000, 0x00000004 },
1543 { 0x000000db, 0x00000034 },
1544 { 0x000000d8, 0x00000008 },
1545 { 0x00008000, 0x00000004 },
1546 { 0xc000e000, 0000000000 },
1547 { 0x000000e1, 0x00000030 },
1548 { 0x4200e000, 0000000000 },
1549 { 0x000000e1, 0x00000030 },
1550 { 0x4000e000, 0000000000 },
1551 { 0x0025001b, 0x00000004 },
1552 { 0x00230000, 0x00000004 },
1553 { 0x00250005, 0x00000004 },
1554 { 0x000000e6, 0x00000034 },
1555 { 0000000000, 0x0000000c },
1556 { 0x00244000, 0x00000004 },
1557 { 0x080045c8, 0x00000004 },
1558 { 0x00240005, 0x00000004 },
1559 { 0x08004d0b, 0x0000000c },
1560 { 0000000000, 0000000000 },
1561 { 0000000000, 0000000000 },
1562 { 0000000000, 0000000000 },
1563 { 0000000000, 0000000000 },
1564 { 0000000000, 0000000000 },
1565 { 0000000000, 0000000000 },
1566 { 0000000000, 0000000000 },
1567 { 0000000000, 0000000000 },
1568 { 0000000000, 0000000000 },
1569 { 0000000000, 0000000000 },
1570 { 0000000000, 0000000000 },
1571 { 0000000000, 0000000000 },
1572 { 0x000c2000, 0x00000004 },
1573 { 0x001d0018, 0x00000004 },
1574 { 0x001a0001, 0x00000004 },
1575 { 0x000000fb, 0x00000034 },
1576 { 0x0000004a, 0x00000008 },
1577 { 0x0500a04a, 0x00000008 },
1578 { 0000000000, 0000000000 },
1579 { 0000000000, 0000000000 },
1580 { 0000000000, 0000000000 },
1581 { 0000000000, 0000000000 },
1582};
1583
1584static const u32 R520_cp_microcode[][2] = {
1585 { 0x4200e000, 0000000000 },
1586 { 0x4000e000, 0000000000 },
1587 { 0x00000099, 0x00000008 },
1588 { 0x0000009d, 0x00000008 },
1589 { 0x4a554b4a, 0000000000 },
1590 { 0x4a4a4467, 0000000000 },
1591 { 0x55526f75, 0000000000 },
1592 { 0x4a7e7d65, 0000000000 },
1593 { 0xe0dae6f6, 0000000000 },
1594 { 0x4ac54a4a, 0000000000 },
1595 { 0xc8828282, 0000000000 },
1596 { 0xbf4acfc1, 0000000000 },
1597 { 0x87b04ad5, 0000000000 },
1598 { 0xb5838383, 0000000000 },
1599 { 0x4a0f85ba, 0000000000 },
1600 { 0x000ca000, 0x00000004 },
1601 { 0x000d0012, 0x00000038 },
1602 { 0x0000e8b4, 0x00000004 },
1603 { 0x000d0014, 0x00000038 },
1604 { 0x0000e8b6, 0x00000004 },
1605 { 0x000d0016, 0x00000038 },
1606 { 0x0000e854, 0x00000004 },
1607 { 0x000d0018, 0x00000038 },
1608 { 0x0000e855, 0x00000004 },
1609 { 0x000d001a, 0x00000038 },
1610 { 0x0000e856, 0x00000004 },
1611 { 0x000d001c, 0x00000038 },
1612 { 0x0000e857, 0x00000004 },
1613 { 0x000d001e, 0x00000038 },
1614 { 0x0000e824, 0x00000004 },
1615 { 0x000d0020, 0x00000038 },
1616 { 0x0000e825, 0x00000004 },
1617 { 0x000d0022, 0x00000038 },
1618 { 0x0000e830, 0x00000004 },
1619 { 0x000d0024, 0x00000038 },
1620 { 0x0000f0c0, 0x00000004 },
1621 { 0x000d0026, 0x00000038 },
1622 { 0x0000f0c1, 0x00000004 },
1623 { 0x000d0028, 0x00000038 },
1624 { 0x0000e000, 0x00000004 },
1625 { 0x000d002a, 0x00000038 },
1626 { 0x0000e000, 0x00000004 },
1627 { 0x000d002c, 0x00000038 },
1628 { 0x0000e000, 0x00000004 },
1629 { 0x000d002e, 0x00000038 },
1630 { 0x0000e000, 0x00000004 },
1631 { 0x000d0030, 0x00000038 },
1632 { 0x0000e000, 0x00000004 },
1633 { 0x000d0032, 0x00000038 },
1634 { 0x0000f180, 0x00000004 },
1635 { 0x000d0034, 0x00000038 },
1636 { 0x0000f393, 0x00000004 },
1637 { 0x000d0036, 0x00000038 },
1638 { 0x0000f38a, 0x00000004 },
1639 { 0x000d0038, 0x00000038 },
1640 { 0x0000f38e, 0x00000004 },
1641 { 0x0000e821, 0x00000004 },
1642 { 0x0140a000, 0x00000004 },
1643 { 0x00000043, 0x00000018 },
1644 { 0x00cce800, 0x00000004 },
1645 { 0x001b0001, 0x00000004 },
1646 { 0x08004800, 0x00000004 },
1647 { 0x001b0001, 0x00000004 },
1648 { 0x08004800, 0x00000004 },
1649 { 0x001b0001, 0x00000004 },
1650 { 0x08004800, 0x00000004 },
1651 { 0x0000003a, 0x00000008 },
1652 { 0x0000a000, 0000000000 },
1653 { 0x2000451d, 0x00000004 },
1654 { 0x0000e580, 0x00000004 },
1655 { 0x000ce581, 0x00000004 },
1656 { 0x08004580, 0x00000004 },
1657 { 0x000ce581, 0x00000004 },
1658 { 0x00000047, 0x00000008 },
1659 { 0x0000a000, 0000000000 },
1660 { 0x000c2000, 0x00000004 },
1661 { 0x0000e50e, 0x00000004 },
1662 { 0x00032000, 0x00000004 },
1663 { 0x00022051, 0x00000028 },
1664 { 0x00000051, 0x00000024 },
1665 { 0x0800450f, 0x00000004 },
1666 { 0x0000a04b, 0x00000008 },
1667 { 0x0000e565, 0x00000004 },
1668 { 0x0000e566, 0x00000004 },
1669 { 0x00000052, 0x00000008 },
1670 { 0x03cca5b4, 0x00000004 },
1671 { 0x05432000, 0x00000004 },
1672 { 0x00022000, 0x00000004 },
1673 { 0x4ccce05e, 0x00000030 },
1674 { 0x08274565, 0x00000004 },
1675 { 0x0000005e, 0x00000030 },
1676 { 0x08004564, 0x00000004 },
1677 { 0x0000e566, 0x00000004 },
1678 { 0x00000055, 0x00000008 },
1679 { 0x00802061, 0x00000010 },
1680 { 0x00202000, 0x00000004 },
1681 { 0x001b00ff, 0x00000004 },
1682 { 0x01000064, 0x00000010 },
1683 { 0x001f2000, 0x00000004 },
1684 { 0x001c00ff, 0x00000004 },
1685 { 0000000000, 0x0000000c },
1686 { 0x00000072, 0x00000030 },
1687 { 0x00000055, 0x00000008 },
1688 { 0x0000e576, 0x00000004 },
1689 { 0x0000e577, 0x00000004 },
1690 { 0x0000e50e, 0x00000004 },
1691 { 0x0000e50f, 0x00000004 },
1692 { 0x0140a000, 0x00000004 },
1693 { 0x00000069, 0x00000018 },
1694 { 0x00c0e5f9, 0x000000c2 },
1695 { 0x00000069, 0x00000008 },
1696 { 0x0014e50e, 0x00000004 },
1697 { 0x0040e50f, 0x00000004 },
1698 { 0x00c0006c, 0x00000008 },
1699 { 0x0000e570, 0x00000004 },
1700 { 0x0000e571, 0x00000004 },
1701 { 0x0000e572, 0x0000000c },
1702 { 0x0000a000, 0x00000004 },
1703 { 0x0140a000, 0x00000004 },
1704 { 0x0000e568, 0x00000004 },
1705 { 0x000c2000, 0x00000004 },
1706 { 0x00000076, 0x00000018 },
1707 { 0x000b0000, 0x00000004 },
1708 { 0x18c0e562, 0x00000004 },
1709 { 0x00000078, 0x00000008 },
1710 { 0x00c00077, 0x00000008 },
1711 { 0x000700c7, 0x00000004 },
1712 { 0x00000080, 0x00000038 },
1713 { 0x0000e5bb, 0x00000004 },
1714 { 0x0000e5bc, 0000000000 },
1715 { 0x0000a000, 0x00000004 },
1716 { 0x0000e821, 0x00000004 },
1717 { 0x0000e800, 0000000000 },
1718 { 0x0000e821, 0x00000004 },
1719 { 0x0000e82e, 0000000000 },
1720 { 0x02cca000, 0x00000004 },
1721 { 0x00140000, 0x00000004 },
1722 { 0x000ce1cc, 0x00000004 },
1723 { 0x050de1cd, 0x00000004 },
1724 { 0x00400000, 0x00000004 },
1725 { 0x0000008f, 0x00000018 },
1726 { 0x00c0a000, 0x00000004 },
1727 { 0x0000008c, 0x00000008 },
1728 { 0x00000091, 0x00000020 },
1729 { 0x4200e000, 0000000000 },
1730 { 0x00000098, 0x00000038 },
1731 { 0x000ca000, 0x00000004 },
1732 { 0x00140000, 0x00000004 },
1733 { 0x000c2000, 0x00000004 },
1734 { 0x00160000, 0x00000004 },
1735 { 0x700ce000, 0x00000004 },
1736 { 0x00140094, 0x00000008 },
1737 { 0x4000e000, 0000000000 },
1738 { 0x02400000, 0x00000004 },
1739 { 0x400ee000, 0x00000004 },
1740 { 0x02400000, 0x00000004 },
1741 { 0x4000e000, 0000000000 },
1742 { 0x000c2000, 0x00000004 },
1743 { 0x0240e51b, 0x00000004 },
1744 { 0x0080e50a, 0x00000005 },
1745 { 0x0080e50b, 0x00000005 },
1746 { 0x00220000, 0x00000004 },
1747 { 0x000700c7, 0x00000004 },
1748 { 0x000000a4, 0x00000038 },
1749 { 0x0080e5bd, 0x00000005 },
1750 { 0x0000e5bb, 0x00000005 },
1751 { 0x0080e5bc, 0x00000005 },
1752 { 0x00210000, 0x00000004 },
1753 { 0x02800000, 0x00000004 },
1754 { 0x00c000ab, 0x00000018 },
1755 { 0x4180e000, 0x00000040 },
1756 { 0x000000ad, 0x00000024 },
1757 { 0x01000000, 0x0000000c },
1758 { 0x0100e51d, 0x0000000c },
1759 { 0x000045bb, 0x00000004 },
1760 { 0x000080a7, 0x00000008 },
1761 { 0x0000f3ce, 0x00000004 },
1762 { 0x0140a000, 0x00000004 },
1763 { 0x00cc2000, 0x00000004 },
1764 { 0x08c053cf, 0x00000040 },
1765 { 0x00008000, 0000000000 },
1766 { 0x0000f3d2, 0x00000004 },
1767 { 0x0140a000, 0x00000004 },
1768 { 0x00cc2000, 0x00000004 },
1769 { 0x08c053d3, 0x00000040 },
1770 { 0x00008000, 0000000000 },
1771 { 0x0000f39d, 0x00000004 },
1772 { 0x0140a000, 0x00000004 },
1773 { 0x00cc2000, 0x00000004 },
1774 { 0x08c0539e, 0x00000040 },
1775 { 0x00008000, 0000000000 },
1776 { 0x03c00830, 0x00000004 },
1777 { 0x4200e000, 0000000000 },
1778 { 0x0000a000, 0x00000004 },
1779 { 0x200045e0, 0x00000004 },
1780 { 0x0000e5e1, 0000000000 },
1781 { 0x00000001, 0000000000 },
1782 { 0x000700c4, 0x00000004 },
1783 { 0x0800e394, 0000000000 },
1784 { 0000000000, 0000000000 },
1785 { 0x0000e8c4, 0x00000004 },
1786 { 0x0000e8c5, 0x00000004 },
1787 { 0x0000e8c6, 0x00000004 },
1788 { 0x0000e928, 0x00000004 },
1789 { 0x0000e929, 0x00000004 },
1790 { 0x0000e92a, 0x00000004 },
1791 { 0x000000c8, 0x00000008 },
1792 { 0x0000e928, 0x00000004 },
1793 { 0x0000e929, 0x00000004 },
1794 { 0x0000e92a, 0x00000004 },
1795 { 0x000000cf, 0x00000008 },
1796 { 0xdeadbeef, 0000000000 },
1797 { 0x00000116, 0000000000 },
1798 { 0x000700d3, 0x00000004 },
1799 { 0x080050e7, 0x00000004 },
1800 { 0x000700d4, 0x00000004 },
1801 { 0x0800401c, 0x00000004 },
1802 { 0x0000e01d, 0000000000 },
1803 { 0x02c02000, 0x00000004 },
1804 { 0x00060000, 0x00000004 },
1805 { 0x000000de, 0x00000034 },
1806 { 0x000000db, 0x00000008 },
1807 { 0x00008000, 0x00000004 },
1808 { 0xc000e000, 0000000000 },
1809 { 0x0000e1cc, 0x00000004 },
1810 { 0x0500e1cd, 0x00000004 },
1811 { 0x000ca000, 0x00000004 },
1812 { 0x000000e5, 0x00000034 },
1813 { 0x000000e1, 0x00000008 },
1814 { 0x0000a000, 0000000000 },
1815 { 0x0019e1cc, 0x00000004 },
1816 { 0x001b0001, 0x00000004 },
1817 { 0x0500a000, 0x00000004 },
1818 { 0x080041cd, 0x00000004 },
1819 { 0x000ca000, 0x00000004 },
1820 { 0x000000fb, 0x00000034 },
1821 { 0x0000004a, 0x00000008 },
1822 { 0000000000, 0000000000 },
1823 { 0000000000, 0000000000 },
1824 { 0000000000, 0000000000 },
1825 { 0000000000, 0000000000 },
1826 { 0000000000, 0000000000 },
1827 { 0000000000, 0000000000 },
1828 { 0000000000, 0000000000 },
1829 { 0000000000, 0000000000 },
1830 { 0000000000, 0000000000 },
1831 { 0x000c2000, 0x00000004 },
1832 { 0x001d0018, 0x00000004 },
1833 { 0x001a0001, 0x00000004 },
1834 { 0x000000fb, 0x00000034 },
1835 { 0x0000004a, 0x00000008 },
1836 { 0x0500a04a, 0x00000008 },
1837 { 0000000000, 0000000000 },
1838 { 0000000000, 0000000000 },
1839 { 0000000000, 0000000000 },
1840 { 0000000000, 0000000000 },
1841};
1842
1843
1844#endif
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 3b09a1f2d8f9..570a58729daf 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -175,6 +175,15 @@ struct radeon_mode_info {
175 enum radeon_connector_table connector_table; 175 enum radeon_connector_table connector_table;
176 bool mode_config_initialized; 176 bool mode_config_initialized;
177 struct radeon_crtc *crtcs[2]; 177 struct radeon_crtc *crtcs[2];
178 /* DVI-I properties */
179 struct drm_property *coherent_mode_property;
180 /* DAC enable load detect */
181 struct drm_property *load_detect_property;
182 /* TV standard load detect */
183 struct drm_property *tv_std_property;
184 /* legacy TMDS PLL detect */
185 struct drm_property *tmds_pll_property;
186
178}; 187};
179 188
180struct radeon_native_mode { 189struct radeon_native_mode {
@@ -188,6 +197,21 @@ struct radeon_native_mode {
188 uint32_t flags; 197 uint32_t flags;
189}; 198};
190 199
200#define MAX_H_CODE_TIMING_LEN 32
201#define MAX_V_CODE_TIMING_LEN 32
202
203/* need to store these as reading
204 back code tables is excessive */
205struct radeon_tv_regs {
206 uint32_t tv_uv_adr;
207 uint32_t timing_cntl;
208 uint32_t hrestart;
209 uint32_t vrestart;
210 uint32_t frestart;
211 uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN];
212 uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN];
213};
214
191struct radeon_crtc { 215struct radeon_crtc {
192 struct drm_crtc base; 216 struct drm_crtc base;
193 int crtc_id; 217 int crtc_id;
@@ -195,8 +219,6 @@ struct radeon_crtc {
195 bool enabled; 219 bool enabled;
196 bool can_tile; 220 bool can_tile;
197 uint32_t crtc_offset; 221 uint32_t crtc_offset;
198 struct radeon_framebuffer *fbdev_fb;
199 struct drm_mode_set mode_set;
200 struct drm_gem_object *cursor_bo; 222 struct drm_gem_object *cursor_bo;
201 uint64_t cursor_addr; 223 uint64_t cursor_addr;
202 int cursor_width; 224 int cursor_width;
@@ -204,7 +226,6 @@ struct radeon_crtc {
204 uint32_t legacy_display_base_addr; 226 uint32_t legacy_display_base_addr;
205 uint32_t legacy_cursor_offset; 227 uint32_t legacy_cursor_offset;
206 enum radeon_rmx_type rmx_type; 228 enum radeon_rmx_type rmx_type;
207 uint32_t devices;
208 fixed20_12 vsc; 229 fixed20_12 vsc;
209 fixed20_12 hsc; 230 fixed20_12 hsc;
210 struct radeon_native_mode native_mode; 231 struct radeon_native_mode native_mode;
@@ -236,7 +257,13 @@ struct radeon_encoder_tv_dac {
236 uint32_t ntsc_tvdac_adj; 257 uint32_t ntsc_tvdac_adj;
237 uint32_t pal_tvdac_adj; 258 uint32_t pal_tvdac_adj;
238 259
260 int h_pos;
261 int v_pos;
262 int h_size;
263 int supported_tv_stds;
264 bool tv_on;
239 enum radeon_tv_std tv_std; 265 enum radeon_tv_std tv_std;
266 struct radeon_tv_regs tv;
240}; 267};
241 268
242struct radeon_encoder_int_tmds { 269struct radeon_encoder_int_tmds {
@@ -255,10 +282,15 @@ struct radeon_encoder_atom_dig {
255 struct radeon_native_mode native_mode; 282 struct radeon_native_mode native_mode;
256}; 283};
257 284
285struct radeon_encoder_atom_dac {
286 enum radeon_tv_std tv_std;
287};
288
258struct radeon_encoder { 289struct radeon_encoder {
259 struct drm_encoder base; 290 struct drm_encoder base;
260 uint32_t encoder_id; 291 uint32_t encoder_id;
261 uint32_t devices; 292 uint32_t devices;
293 uint32_t active_device;
262 uint32_t flags; 294 uint32_t flags;
263 uint32_t pixel_clock; 295 uint32_t pixel_clock;
264 enum radeon_rmx_type rmx_type; 296 enum radeon_rmx_type rmx_type;
@@ -276,8 +308,12 @@ struct radeon_connector {
276 uint32_t connector_id; 308 uint32_t connector_id;
277 uint32_t devices; 309 uint32_t devices;
278 struct radeon_i2c_chan *ddc_bus; 310 struct radeon_i2c_chan *ddc_bus;
279 int use_digital; 311 bool use_digital;
312 /* we need to mind the EDID between detect
313 and get modes due to analog/digital/tvencoder */
314 struct edid *edid;
280 void *con_priv; 315 void *con_priv;
316 bool dac_load_detect;
281}; 317};
282 318
283struct radeon_framebuffer { 319struct radeon_framebuffer {
@@ -310,6 +346,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, i
310struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); 346struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
311extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); 347extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
312extern int atombios_get_encoder_mode(struct drm_encoder *encoder); 348extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
349extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
313 350
314extern void radeon_crtc_load_lut(struct drm_crtc *crtc); 351extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
315extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, 352extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
@@ -337,16 +374,18 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
337extern bool radeon_combios_get_clock_info(struct drm_device *dev); 374extern bool radeon_combios_get_clock_info(struct drm_device *dev);
338extern struct radeon_encoder_atom_dig * 375extern struct radeon_encoder_atom_dig *
339radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); 376radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
340extern struct radeon_encoder_int_tmds * 377bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
341radeon_atombios_get_tmds_info(struct radeon_encoder *encoder); 378 struct radeon_encoder_int_tmds *tmds);
379bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
380 struct radeon_encoder_int_tmds *tmds);
381bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
382 struct radeon_encoder_int_tmds *tmds);
342extern struct radeon_encoder_primary_dac * 383extern struct radeon_encoder_primary_dac *
343radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); 384radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
344extern struct radeon_encoder_tv_dac * 385extern struct radeon_encoder_tv_dac *
345radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder); 386radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
346extern struct radeon_encoder_lvds * 387extern struct radeon_encoder_lvds *
347radeon_combios_get_lvds_info(struct radeon_encoder *encoder); 388radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
348extern struct radeon_encoder_int_tmds *
349radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
350extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder); 389extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder);
351extern struct radeon_encoder_tv_dac * 390extern struct radeon_encoder_tv_dac *
352radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); 391radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
@@ -356,6 +395,8 @@ extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
356extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); 395extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
357extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); 396extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
358extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev); 397extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev);
398extern void radeon_save_bios_scratch_regs(struct radeon_device *rdev);
399extern void radeon_restore_bios_scratch_regs(struct radeon_device *rdev);
359extern void 400extern void
360radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); 401radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
361extern void 402extern void
@@ -396,6 +437,19 @@ extern int radeon_static_clocks_init(struct drm_device *dev);
396bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, 437bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
397 struct drm_display_mode *mode, 438 struct drm_display_mode *mode,
398 struct drm_display_mode *adjusted_mode); 439 struct drm_display_mode *adjusted_mode);
399void atom_rv515_force_tv_scaler(struct radeon_device *rdev); 440void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
400 441
442/* legacy tv */
443void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
444 uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
445 uint32_t *v_total_disp, uint32_t *v_sync_strt_wid);
446void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
447 uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
448 uint32_t *ppll_div_3, uint32_t *pixclks_cntl);
449void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
450 uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
451 uint32_t *p2pll_div_0, uint32_t *pixclks_cntl);
452void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
453 struct drm_display_mode *mode,
454 struct drm_display_mode *adjusted_mode);
401#endif 455#endif
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index b85fb83d7ae8..73af463b7a59 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr)
188 if (ptr) { 188 if (ptr) {
189 *ptr = robj->kptr; 189 *ptr = robj->kptr;
190 } 190 }
191 radeon_object_check_tiling(robj, 0, 0);
191 return 0; 192 return 0;
192} 193}
193 194
@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj)
200 } 201 }
201 robj->kptr = NULL; 202 robj->kptr = NULL;
202 spin_unlock(&robj->tobj.lock); 203 spin_unlock(&robj->tobj.lock);
204 radeon_object_check_tiling(robj, 0, 0);
203 ttm_bo_kunmap(&robj->kmap); 205 ttm_bo_kunmap(&robj->kmap);
204} 206}
205 207
@@ -369,6 +371,14 @@ void radeon_object_force_delete(struct radeon_device *rdev)
369 371
370int radeon_object_init(struct radeon_device *rdev) 372int radeon_object_init(struct radeon_device *rdev)
371{ 373{
374 /* Add an MTRR for the VRAM */
375 rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
376 MTRR_TYPE_WRCOMB, 1);
377 DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
378 rdev->mc.mc_vram_size >> 20,
379 (unsigned long long)rdev->mc.aper_size >> 20);
380 DRM_INFO("RAM width %dbits %cDR\n",
381 rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
372 return radeon_ttm_init(rdev); 382 return radeon_ttm_init(rdev);
373} 383}
374 384
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 473e4775dc5a..10e8af6bb456 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -37,6 +37,7 @@
37 * TTM. 37 * TTM.
38 */ 38 */
39struct radeon_mman { 39struct radeon_mman {
40 struct ttm_bo_global_ref bo_global_ref;
40 struct ttm_global_reference mem_global_ref; 41 struct ttm_global_reference mem_global_ref;
41 bool mem_global_referenced; 42 bool mem_global_referenced;
42 struct ttm_bo_device bdev; 43 struct ttm_bo_device bdev;
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 4df43f62c678..21da871a793c 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -1945,6 +1945,11 @@
1945# define RADEON_TXFORMAT_DXT1 (12 << 0) 1945# define RADEON_TXFORMAT_DXT1 (12 << 0)
1946# define RADEON_TXFORMAT_DXT23 (14 << 0) 1946# define RADEON_TXFORMAT_DXT23 (14 << 0)
1947# define RADEON_TXFORMAT_DXT45 (15 << 0) 1947# define RADEON_TXFORMAT_DXT45 (15 << 0)
1948# define RADEON_TXFORMAT_SHADOW16 (16 << 0)
1949# define RADEON_TXFORMAT_SHADOW32 (17 << 0)
1950# define RADEON_TXFORMAT_DUDV88 (18 << 0)
1951# define RADEON_TXFORMAT_LDUDV655 (19 << 0)
1952# define RADEON_TXFORMAT_LDUDUV8888 (20 << 0)
1948# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0) 1953# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0)
1949# define RADEON_TXFORMAT_FORMAT_SHIFT 0 1954# define RADEON_TXFORMAT_FORMAT_SHIFT 0
1950# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5) 1955# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5)
@@ -2203,7 +2208,7 @@
2203# define RADEON_ROP_ENABLE (1 << 6) 2208# define RADEON_ROP_ENABLE (1 << 6)
2204# define RADEON_STENCIL_ENABLE (1 << 7) 2209# define RADEON_STENCIL_ENABLE (1 << 7)
2205# define RADEON_Z_ENABLE (1 << 8) 2210# define RADEON_Z_ENABLE (1 << 8)
2206# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) 2211# define RADEON_DEPTHXY_OFFSET_ENABLE (1 << 9)
2207# define RADEON_RB3D_COLOR_FORMAT_SHIFT 10 2212# define RADEON_RB3D_COLOR_FORMAT_SHIFT 10
2208 2213
2209# define RADEON_COLOR_FORMAT_ARGB1555 3 2214# define RADEON_COLOR_FORMAT_ARGB1555 3
@@ -2773,7 +2778,12 @@
2773# define R200_TXFORMAT_DXT1 (12 << 0) 2778# define R200_TXFORMAT_DXT1 (12 << 0)
2774# define R200_TXFORMAT_DXT23 (14 << 0) 2779# define R200_TXFORMAT_DXT23 (14 << 0)
2775# define R200_TXFORMAT_DXT45 (15 << 0) 2780# define R200_TXFORMAT_DXT45 (15 << 0)
2781# define R200_TXFORMAT_DVDU88 (18 << 0)
2782# define R200_TXFORMAT_LDVDU655 (19 << 0)
2783# define R200_TXFORMAT_LDVDU8888 (20 << 0)
2784# define R200_TXFORMAT_GR1616 (21 << 0)
2776# define R200_TXFORMAT_ABGR8888 (22 << 0) 2785# define R200_TXFORMAT_ABGR8888 (22 << 0)
2786# define R200_TXFORMAT_BGR111110 (23 << 0)
2777# define R200_TXFORMAT_FORMAT_MASK (31 << 0) 2787# define R200_TXFORMAT_FORMAT_MASK (31 << 0)
2778# define R200_TXFORMAT_FORMAT_SHIFT 0 2788# define R200_TXFORMAT_FORMAT_SHIFT 0
2779# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) 2789# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6)
@@ -2818,6 +2828,13 @@
2818#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */ 2828#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */
2819#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */ 2829#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */
2820 2830
2831#define R200_PP_CUBIC_FACES_0 0x2c18
2832#define R200_PP_CUBIC_FACES_1 0x2c38
2833#define R200_PP_CUBIC_FACES_2 0x2c58
2834#define R200_PP_CUBIC_FACES_3 0x2c78
2835#define R200_PP_CUBIC_FACES_4 0x2c98
2836#define R200_PP_CUBIC_FACES_5 0x2cb8
2837
2821#define R200_PP_TXOFFSET_0 0x2d00 2838#define R200_PP_TXOFFSET_0 0x2d00
2822# define R200_TXO_ENDIAN_NO_SWAP (0 << 0) 2839# define R200_TXO_ENDIAN_NO_SWAP (0 << 0)
2823# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) 2840# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0)
@@ -2829,11 +2846,44 @@
2829# define R200_TXO_MICRO_TILE (1 << 3) 2846# define R200_TXO_MICRO_TILE (1 << 3)
2830# define R200_TXO_OFFSET_MASK 0xffffffe0 2847# define R200_TXO_OFFSET_MASK 0xffffffe0
2831# define R200_TXO_OFFSET_SHIFT 5 2848# define R200_TXO_OFFSET_SHIFT 5
2849#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
2850#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
2851#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
2852#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
2853#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
2854
2832#define R200_PP_TXOFFSET_1 0x2d18 2855#define R200_PP_TXOFFSET_1 0x2d18
2856#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
2857#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
2858#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
2859#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
2860#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
2861
2833#define R200_PP_TXOFFSET_2 0x2d30 2862#define R200_PP_TXOFFSET_2 0x2d30
2863#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
2864#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
2865#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
2866#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
2867#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
2868
2834#define R200_PP_TXOFFSET_3 0x2d48 2869#define R200_PP_TXOFFSET_3 0x2d48
2870#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
2871#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
2872#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
2873#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
2874#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
2835#define R200_PP_TXOFFSET_4 0x2d60 2875#define R200_PP_TXOFFSET_4 0x2d60
2876#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
2877#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
2878#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
2879#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
2880#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
2836#define R200_PP_TXOFFSET_5 0x2d78 2881#define R200_PP_TXOFFSET_5 0x2d78
2882#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
2883#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
2884#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
2885#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
2886#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
2837 2887
2838#define R200_PP_TFACTOR_0 0x2ee0 2888#define R200_PP_TFACTOR_0 0x2ee0
2839#define R200_PP_TFACTOR_1 0x2ee4 2889#define R200_PP_TFACTOR_1 0x2ee4
@@ -3175,6 +3225,11 @@
3175# define R200_FORCE_INORDER_PROC (1<<31) 3225# define R200_FORCE_INORDER_PROC (1<<31)
3176#define R200_PP_CNTL_X 0x2cc4 3226#define R200_PP_CNTL_X 0x2cc4
3177#define R200_PP_TXMULTI_CTL_0 0x2c1c 3227#define R200_PP_TXMULTI_CTL_0 0x2c1c
3228#define R200_PP_TXMULTI_CTL_1 0x2c3c
3229#define R200_PP_TXMULTI_CTL_2 0x2c5c
3230#define R200_PP_TXMULTI_CTL_3 0x2c7c
3231#define R200_PP_TXMULTI_CTL_4 0x2c9c
3232#define R200_PP_TXMULTI_CTL_5 0x2cbc
3178#define R200_SE_VTX_STATE_CNTL 0x2180 3233#define R200_SE_VTX_STATE_CNTL 0x2180
3179# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16) 3234# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16)
3180 3235
@@ -3200,6 +3255,24 @@
3200#define RADEON_CP_RB_WPTR 0x0714 3255#define RADEON_CP_RB_WPTR 0x0714
3201#define RADEON_CP_RB_RPTR_WR 0x071c 3256#define RADEON_CP_RB_RPTR_WR 0x071c
3202 3257
3258#define RADEON_SCRATCH_UMSK 0x0770
3259#define RADEON_SCRATCH_ADDR 0x0774
3260
3261#define R600_CP_RB_BASE 0xc100
3262#define R600_CP_RB_CNTL 0xc104
3263# define R600_RB_BUFSZ(x) ((x) << 0)
3264# define R600_RB_BLKSZ(x) ((x) << 8)
3265# define R600_RB_NO_UPDATE (1 << 27)
3266# define R600_RB_RPTR_WR_ENA (1 << 31)
3267#define R600_CP_RB_RPTR_WR 0xc108
3268#define R600_CP_RB_RPTR_ADDR 0xc10c
3269#define R600_CP_RB_RPTR_ADDR_HI 0xc110
3270#define R600_CP_RB_WPTR 0xc114
3271#define R600_CP_RB_WPTR_ADDR 0xc118
3272#define R600_CP_RB_WPTR_ADDR_HI 0xc11c
3273#define R600_CP_RB_RPTR 0x8700
3274#define R600_CP_RB_WPTR_DELAY 0x8704
3275
3203#define RADEON_CP_IB_BASE 0x0738 3276#define RADEON_CP_IB_BASE 0x0738
3204#define RADEON_CP_IB_BUFSZ 0x073c 3277#define RADEON_CP_IB_BUFSZ 0x073c
3205 3278
@@ -3407,7 +3480,9 @@
3407# define RADEON_RGB_CONVERT_BY_PASS (1 << 10) 3480# define RADEON_RGB_CONVERT_BY_PASS (1 << 10)
3408# define RADEON_UVRAM_READ_MARGIN_SHIFT 16 3481# define RADEON_UVRAM_READ_MARGIN_SHIFT 16
3409# define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 3482# define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20
3410# define RADEON_TVOUT_SCALE_EN (1 << 26) 3483# define RADEON_RGB_ATTEN_SEL(x) ((x) << 24)
3484# define RADEON_TVOUT_SCALE_EN (1 << 26)
3485# define RADEON_RGB_ATTEN_VAL(x) ((x) << 28)
3411#define RADEON_TV_SYNC_CNTL 0x0808 3486#define RADEON_TV_SYNC_CNTL 0x0808
3412# define RADEON_SYNC_OE (1 << 0) 3487# define RADEON_SYNC_OE (1 << 0)
3413# define RADEON_SYNC_OUT (1 << 1) 3488# define RADEON_SYNC_OUT (1 << 1)
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 60d159308b88..747b4bffb84b 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -56,10 +56,12 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
56 set_bit(i, rdev->ib_pool.alloc_bm); 56 set_bit(i, rdev->ib_pool.alloc_bm);
57 rdev->ib_pool.ibs[i].length_dw = 0; 57 rdev->ib_pool.ibs[i].length_dw = 0;
58 *ib = &rdev->ib_pool.ibs[i]; 58 *ib = &rdev->ib_pool.ibs[i];
59 mutex_unlock(&rdev->ib_pool.mutex);
59 goto out; 60 goto out;
60 } 61 }
61 if (list_empty(&rdev->ib_pool.scheduled_ibs)) { 62 if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
62 /* we go do nothings here */ 63 /* we go do nothings here */
64 mutex_unlock(&rdev->ib_pool.mutex);
63 DRM_ERROR("all IB allocated none scheduled.\n"); 65 DRM_ERROR("all IB allocated none scheduled.\n");
64 r = -EINVAL; 66 r = -EINVAL;
65 goto out; 67 goto out;
@@ -69,10 +71,13 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
69 struct radeon_ib, list); 71 struct radeon_ib, list);
70 if (nib->fence == NULL) { 72 if (nib->fence == NULL) {
71 /* we go do nothings here */ 73 /* we go do nothings here */
74 mutex_unlock(&rdev->ib_pool.mutex);
72 DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx); 75 DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
73 r = -EINVAL; 76 r = -EINVAL;
74 goto out; 77 goto out;
75 } 78 }
79 mutex_unlock(&rdev->ib_pool.mutex);
80
76 r = radeon_fence_wait(nib->fence, false); 81 r = radeon_fence_wait(nib->fence, false);
77 if (r) { 82 if (r) {
78 DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx, 83 DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
@@ -81,12 +86,17 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
81 goto out; 86 goto out;
82 } 87 }
83 radeon_fence_unref(&nib->fence); 88 radeon_fence_unref(&nib->fence);
89
84 nib->length_dw = 0; 90 nib->length_dw = 0;
91
92 /* scheduled list is accessed here */
93 mutex_lock(&rdev->ib_pool.mutex);
85 list_del(&nib->list); 94 list_del(&nib->list);
86 INIT_LIST_HEAD(&nib->list); 95 INIT_LIST_HEAD(&nib->list);
96 mutex_unlock(&rdev->ib_pool.mutex);
97
87 *ib = nib; 98 *ib = nib;
88out: 99out:
89 mutex_unlock(&rdev->ib_pool.mutex);
90 if (r) { 100 if (r) {
91 radeon_fence_unref(&fence); 101 radeon_fence_unref(&fence);
92 } else { 102 } else {
@@ -111,47 +121,36 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
111 } 121 }
112 list_del(&tmp->list); 122 list_del(&tmp->list);
113 INIT_LIST_HEAD(&tmp->list); 123 INIT_LIST_HEAD(&tmp->list);
114 if (tmp->fence) { 124 if (tmp->fence)
115 radeon_fence_unref(&tmp->fence); 125 radeon_fence_unref(&tmp->fence);
116 } 126
117 tmp->length_dw = 0; 127 tmp->length_dw = 0;
118 clear_bit(tmp->idx, rdev->ib_pool.alloc_bm); 128 clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
119 mutex_unlock(&rdev->ib_pool.mutex); 129 mutex_unlock(&rdev->ib_pool.mutex);
120} 130}
121 131
122static void radeon_ib_align(struct radeon_device *rdev, struct radeon_ib *ib)
123{
124 while ((ib->length_dw & rdev->cp.align_mask)) {
125 ib->ptr[ib->length_dw++] = PACKET2(0);
126 }
127}
128
129int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) 132int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
130{ 133{
131 int r = 0; 134 int r = 0;
132 135
133 mutex_lock(&rdev->ib_pool.mutex);
134 radeon_ib_align(rdev, ib);
135 if (!ib->length_dw || !rdev->cp.ready) { 136 if (!ib->length_dw || !rdev->cp.ready) {
136 /* TODO: Nothings in the ib we should report. */ 137 /* TODO: Nothings in the ib we should report. */
137 mutex_unlock(&rdev->ib_pool.mutex);
138 DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx); 138 DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx);
139 return -EINVAL; 139 return -EINVAL;
140 } 140 }
141
141 /* 64 dwords should be enough for fence too */ 142 /* 64 dwords should be enough for fence too */
142 r = radeon_ring_lock(rdev, 64); 143 r = radeon_ring_lock(rdev, 64);
143 if (r) { 144 if (r) {
144 DRM_ERROR("radeon: scheduling IB failled (%d).\n", r); 145 DRM_ERROR("radeon: scheduling IB failled (%d).\n", r);
145 mutex_unlock(&rdev->ib_pool.mutex);
146 return r; 146 return r;
147 } 147 }
148 radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); 148 radeon_ring_ib_execute(rdev, ib);
149 radeon_ring_write(rdev, ib->gpu_addr);
150 radeon_ring_write(rdev, ib->length_dw);
151 radeon_fence_emit(rdev, ib->fence); 149 radeon_fence_emit(rdev, ib->fence);
152 radeon_ring_unlock_commit(rdev); 150 mutex_lock(&rdev->ib_pool.mutex);
153 list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); 151 list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
154 mutex_unlock(&rdev->ib_pool.mutex); 152 mutex_unlock(&rdev->ib_pool.mutex);
153 radeon_ring_unlock_commit(rdev);
155 return 0; 154 return 0;
156} 155}
157 156
@@ -162,6 +161,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
162 int i; 161 int i;
163 int r = 0; 162 int r = 0;
164 163
164 if (rdev->ib_pool.robj)
165 return 0;
165 /* Allocate 1M object buffer */ 166 /* Allocate 1M object buffer */
166 INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); 167 INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
167 r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, 168 r = radeon_object_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
@@ -215,69 +216,16 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
215 mutex_unlock(&rdev->ib_pool.mutex); 216 mutex_unlock(&rdev->ib_pool.mutex);
216} 217}
217 218
218int radeon_ib_test(struct radeon_device *rdev)
219{
220 struct radeon_ib *ib;
221 uint32_t scratch;
222 uint32_t tmp = 0;
223 unsigned i;
224 int r;
225
226 r = radeon_scratch_get(rdev, &scratch);
227 if (r) {
228 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
229 return r;
230 }
231 WREG32(scratch, 0xCAFEDEAD);
232 r = radeon_ib_get(rdev, &ib);
233 if (r) {
234 return r;
235 }
236 ib->ptr[0] = PACKET0(scratch, 0);
237 ib->ptr[1] = 0xDEADBEEF;
238 ib->ptr[2] = PACKET2(0);
239 ib->ptr[3] = PACKET2(0);
240 ib->ptr[4] = PACKET2(0);
241 ib->ptr[5] = PACKET2(0);
242 ib->ptr[6] = PACKET2(0);
243 ib->ptr[7] = PACKET2(0);
244 ib->length_dw = 8;
245 r = radeon_ib_schedule(rdev, ib);
246 if (r) {
247 radeon_scratch_free(rdev, scratch);
248 radeon_ib_free(rdev, &ib);
249 return r;
250 }
251 r = radeon_fence_wait(ib->fence, false);
252 if (r) {
253 return r;
254 }
255 for (i = 0; i < rdev->usec_timeout; i++) {
256 tmp = RREG32(scratch);
257 if (tmp == 0xDEADBEEF) {
258 break;
259 }
260 DRM_UDELAY(1);
261 }
262 if (i < rdev->usec_timeout) {
263 DRM_INFO("ib test succeeded in %u usecs\n", i);
264 } else {
265 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
266 scratch, tmp);
267 r = -EINVAL;
268 }
269 radeon_scratch_free(rdev, scratch);
270 radeon_ib_free(rdev, &ib);
271 return r;
272}
273
274 219
275/* 220/*
276 * Ring. 221 * Ring.
277 */ 222 */
278void radeon_ring_free_size(struct radeon_device *rdev) 223void radeon_ring_free_size(struct radeon_device *rdev)
279{ 224{
280 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); 225 if (rdev->family >= CHIP_R600)
226 rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
227 else
228 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
281 /* This works because ring_size is a power of 2 */ 229 /* This works because ring_size is a power of 2 */
282 rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); 230 rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4));
283 rdev->cp.ring_free_dw -= rdev->cp.wptr; 231 rdev->cp.ring_free_dw -= rdev->cp.wptr;
@@ -320,11 +268,10 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev)
320 count_dw_pad = (rdev->cp.align_mask + 1) - 268 count_dw_pad = (rdev->cp.align_mask + 1) -
321 (rdev->cp.wptr & rdev->cp.align_mask); 269 (rdev->cp.wptr & rdev->cp.align_mask);
322 for (i = 0; i < count_dw_pad; i++) { 270 for (i = 0; i < count_dw_pad; i++) {
323 radeon_ring_write(rdev, PACKET2(0)); 271 radeon_ring_write(rdev, 2 << 30);
324 } 272 }
325 DRM_MEMORYBARRIER(); 273 DRM_MEMORYBARRIER();
326 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); 274 radeon_cp_commit(rdev);
327 (void)RREG32(RADEON_CP_RB_WPTR);
328 mutex_unlock(&rdev->cp.mutex); 275 mutex_unlock(&rdev->cp.mutex);
329} 276}
330 277
@@ -334,46 +281,6 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev)
334 mutex_unlock(&rdev->cp.mutex); 281 mutex_unlock(&rdev->cp.mutex);
335} 282}
336 283
337int radeon_ring_test(struct radeon_device *rdev)
338{
339 uint32_t scratch;
340 uint32_t tmp = 0;
341 unsigned i;
342 int r;
343
344 r = radeon_scratch_get(rdev, &scratch);
345 if (r) {
346 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
347 return r;
348 }
349 WREG32(scratch, 0xCAFEDEAD);
350 r = radeon_ring_lock(rdev, 2);
351 if (r) {
352 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
353 radeon_scratch_free(rdev, scratch);
354 return r;
355 }
356 radeon_ring_write(rdev, PACKET0(scratch, 0));
357 radeon_ring_write(rdev, 0xDEADBEEF);
358 radeon_ring_unlock_commit(rdev);
359 for (i = 0; i < rdev->usec_timeout; i++) {
360 tmp = RREG32(scratch);
361 if (tmp == 0xDEADBEEF) {
362 break;
363 }
364 DRM_UDELAY(1);
365 }
366 if (i < rdev->usec_timeout) {
367 DRM_INFO("ring test succeeded in %d usecs\n", i);
368 } else {
369 DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
370 scratch, tmp);
371 r = -EINVAL;
372 }
373 radeon_scratch_free(rdev, scratch);
374 return r;
375}
376
377int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) 284int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
378{ 285{
379 int r; 286 int r;
diff --git a/drivers/gpu/drm/radeon/radeon_share.h b/drivers/gpu/drm/radeon/radeon_share.h
deleted file mode 100644
index 63a773578f17..000000000000
--- a/drivers/gpu/drm/radeon/radeon_share.h
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RADEON_SHARE_H__
29#define __RADEON_SHARE_H__
30
31void r100_vram_init_sizes(struct radeon_device *rdev);
32
33void rs690_line_buffer_adjust(struct radeon_device *rdev,
34 struct drm_display_mode *mode1,
35 struct drm_display_mode *mode2);
36
37void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
38
39#endif
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index 2882f40d5ec5..38537d971a3e 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1546,7 +1546,7 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
1546 } while (i < nbox); 1546 } while (i < nbox);
1547} 1547}
1548 1548
1549static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) 1549void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
1550{ 1550{
1551 drm_radeon_private_t *dev_priv = dev->dev_private; 1551 drm_radeon_private_t *dev_priv = dev->dev_private;
1552 struct drm_radeon_master_private *master_priv = master->driver_priv; 1552 struct drm_radeon_master_private *master_priv = master->driver_priv;
@@ -2213,7 +2213,10 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
2213 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) 2213 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2214 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; 2214 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2215 2215
2216 radeon_cp_dispatch_swap(dev, file_priv->master); 2216 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2217 r600_cp_dispatch_swap(dev, file_priv);
2218 else
2219 radeon_cp_dispatch_swap(dev, file_priv->master);
2217 sarea_priv->ctx_owner = 0; 2220 sarea_priv->ctx_owner = 0;
2218 2221
2219 COMMIT_RING(); 2222 COMMIT_RING();
@@ -2412,7 +2415,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file
2412 RING_SPACE_TEST_WITH_RETURN(dev_priv); 2415 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2413 VB_AGE_TEST_WITH_RETURN(dev_priv); 2416 VB_AGE_TEST_WITH_RETURN(dev_priv);
2414 2417
2415 ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); 2418 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2419 ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
2420 else
2421 ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
2416 2422
2417 return ret; 2423 return ret;
2418} 2424}
@@ -2495,8 +2501,9 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
2495 radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); 2501 radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2496 } 2502 }
2497 2503
2498 if (indirect->discard) 2504 if (indirect->discard) {
2499 radeon_cp_discard_buffer(dev, file_priv->master, buf); 2505 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2506 }
2500 2507
2501 COMMIT_RING(); 2508 COMMIT_RING();
2502 return 0; 2509 return 0;
@@ -3027,7 +3034,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
3027 value = GET_SCRATCH(dev_priv, 2); 3034 value = GET_SCRATCH(dev_priv, 2);
3028 break; 3035 break;
3029 case RADEON_PARAM_IRQ_NR: 3036 case RADEON_PARAM_IRQ_NR:
3030 value = drm_dev_to_irq(dev); 3037 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
3038 value = 0;
3039 else
3040 value = drm_dev_to_irq(dev);
3031 break; 3041 break;
3032 case RADEON_PARAM_GART_BASE: 3042 case RADEON_PARAM_GART_BASE:
3033 value = dev_priv->gart_vm_start; 3043 value = dev_priv->gart_vm_start;
@@ -3227,7 +3237,8 @@ struct drm_ioctl_desc radeon_ioctls[] = {
3227 DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), 3237 DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
3228 DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), 3238 DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
3229 DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), 3239 DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
3230 DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) 3240 DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
3241 DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
3231}; 3242};
3232 3243
3233int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); 3244int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 15c3531377ed..acd889c94549 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -35,11 +35,14 @@
35#include <ttm/ttm_module.h> 35#include <ttm/ttm_module.h>
36#include <drm/drmP.h> 36#include <drm/drmP.h>
37#include <drm/radeon_drm.h> 37#include <drm/radeon_drm.h>
38#include <linux/seq_file.h>
38#include "radeon_reg.h" 39#include "radeon_reg.h"
39#include "radeon.h" 40#include "radeon.h"
40 41
41#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) 42#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
42 43
44static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
45
43static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) 46static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
44{ 47{
45 struct radeon_mman *mman; 48 struct radeon_mman *mman;
@@ -77,9 +80,25 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
77 global_ref->release = &radeon_ttm_mem_global_release; 80 global_ref->release = &radeon_ttm_mem_global_release;
78 r = ttm_global_item_ref(global_ref); 81 r = ttm_global_item_ref(global_ref);
79 if (r != 0) { 82 if (r != 0) {
80 DRM_ERROR("Failed referencing a global TTM memory object.\n"); 83 DRM_ERROR("Failed setting up TTM memory accounting "
84 "subsystem.\n");
85 return r;
86 }
87
88 rdev->mman.bo_global_ref.mem_glob =
89 rdev->mman.mem_global_ref.object;
90 global_ref = &rdev->mman.bo_global_ref.ref;
91 global_ref->global_type = TTM_GLOBAL_TTM_BO;
92 global_ref->size = sizeof(struct ttm_bo_global);
93 global_ref->init = &ttm_bo_global_init;
94 global_ref->release = &ttm_bo_global_release;
95 r = ttm_global_item_ref(global_ref);
96 if (r != 0) {
97 DRM_ERROR("Failed setting up TTM BO subsystem.\n");
98 ttm_global_item_unref(&rdev->mman.mem_global_ref);
81 return r; 99 return r;
82 } 100 }
101
83 rdev->mman.mem_global_referenced = true; 102 rdev->mman.mem_global_referenced = true;
84 return 0; 103 return 0;
85} 104}
@@ -87,6 +106,7 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
87static void radeon_ttm_global_fini(struct radeon_device *rdev) 106static void radeon_ttm_global_fini(struct radeon_device *rdev)
88{ 107{
89 if (rdev->mman.mem_global_referenced) { 108 if (rdev->mman.mem_global_referenced) {
109 ttm_global_item_unref(&rdev->mman.bo_global_ref.ref);
90 ttm_global_item_unref(&rdev->mman.mem_global_ref); 110 ttm_global_item_unref(&rdev->mman.mem_global_ref);
91 rdev->mman.mem_global_referenced = false; 111 rdev->mman.mem_global_referenced = false;
92 } 112 }
@@ -286,9 +306,11 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
286 r = ttm_bo_move_ttm(bo, true, no_wait, new_mem); 306 r = ttm_bo_move_ttm(bo, true, no_wait, new_mem);
287out_cleanup: 307out_cleanup:
288 if (tmp_mem.mm_node) { 308 if (tmp_mem.mm_node) {
289 spin_lock(&rdev->mman.bdev.lru_lock); 309 struct ttm_bo_global *glob = rdev->mman.bdev.glob;
310
311 spin_lock(&glob->lru_lock);
290 drm_mm_put_block(tmp_mem.mm_node); 312 drm_mm_put_block(tmp_mem.mm_node);
291 spin_unlock(&rdev->mman.bdev.lru_lock); 313 spin_unlock(&glob->lru_lock);
292 return r; 314 return r;
293 } 315 }
294 return r; 316 return r;
@@ -323,9 +345,11 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
323 } 345 }
324out_cleanup: 346out_cleanup:
325 if (tmp_mem.mm_node) { 347 if (tmp_mem.mm_node) {
326 spin_lock(&rdev->mman.bdev.lru_lock); 348 struct ttm_bo_global *glob = rdev->mman.bdev.glob;
349
350 spin_lock(&glob->lru_lock);
327 drm_mm_put_block(tmp_mem.mm_node); 351 drm_mm_put_block(tmp_mem.mm_node);
328 spin_unlock(&rdev->mman.bdev.lru_lock); 352 spin_unlock(&glob->lru_lock);
329 return r; 353 return r;
330 } 354 }
331 return r; 355 return r;
@@ -352,9 +376,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo,
352 radeon_move_null(bo, new_mem); 376 radeon_move_null(bo, new_mem);
353 return 0; 377 return 0;
354 } 378 }
355 if (!rdev->cp.ready) { 379 if (!rdev->cp.ready || rdev->asic->copy == NULL) {
356 /* use memcpy */ 380 /* use memcpy */
357 DRM_ERROR("CP is not ready use memcpy.\n");
358 goto memcpy; 381 goto memcpy;
359 } 382 }
360 383
@@ -446,7 +469,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
446 } 469 }
447 /* No others user of address space so set it to 0 */ 470 /* No others user of address space so set it to 0 */
448 r = ttm_bo_device_init(&rdev->mman.bdev, 471 r = ttm_bo_device_init(&rdev->mman.bdev,
449 rdev->mman.mem_global_ref.object, 472 rdev->mman.bo_global_ref.ref.object,
450 &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, 473 &radeon_bo_driver, DRM_FILE_PAGE_OFFSET,
451 rdev->need_dma32); 474 rdev->need_dma32);
452 if (r) { 475 if (r) {
@@ -471,7 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
471 return r; 494 return r;
472 } 495 }
473 DRM_INFO("radeon: %uM of VRAM memory ready\n", 496 DRM_INFO("radeon: %uM of VRAM memory ready\n",
474 rdev->mc.real_vram_size / (1024 * 1024)); 497 (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
475 r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, 498 r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
476 ((rdev->mc.gtt_size) >> PAGE_SHIFT)); 499 ((rdev->mc.gtt_size) >> PAGE_SHIFT));
477 if (r) { 500 if (r) {
@@ -479,10 +502,16 @@ int radeon_ttm_init(struct radeon_device *rdev)
479 return r; 502 return r;
480 } 503 }
481 DRM_INFO("radeon: %uM of GTT memory ready.\n", 504 DRM_INFO("radeon: %uM of GTT memory ready.\n",
482 rdev->mc.gtt_size / (1024 * 1024)); 505 (unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
483 if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { 506 if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
484 rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; 507 rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
485 } 508 }
509
510 r = radeon_ttm_debugfs_init(rdev);
511 if (r) {
512 DRM_ERROR("Failed to init debugfs\n");
513 return r;
514 }
486 return 0; 515 return 0;
487} 516}
488 517
@@ -657,3 +686,50 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
657 gtt->bound = false; 686 gtt->bound = false;
658 return &gtt->backend; 687 return &gtt->backend;
659} 688}
689
690#define RADEON_DEBUGFS_MEM_TYPES 2
691
692static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
693static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
694
695#if defined(CONFIG_DEBUG_FS)
696static int radeon_mm_dump_table(struct seq_file *m, void *data)
697{
698 struct drm_info_node *node = (struct drm_info_node *)m->private;
699 struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;
700 struct drm_device *dev = node->minor->dev;
701 struct radeon_device *rdev = dev->dev_private;
702 int ret;
703 struct ttm_bo_global *glob = rdev->mman.bdev.glob;
704
705 spin_lock(&glob->lru_lock);
706 ret = drm_mm_dump_table(m, mm);
707 spin_unlock(&glob->lru_lock);
708 return ret;
709}
710#endif
711
712static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
713{
714 unsigned i;
715
716#if defined(CONFIG_DEBUG_FS)
717 for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) {
718 if (i == 0)
719 sprintf(radeon_mem_types_names[i], "radeon_vram_mm");
720 else
721 sprintf(radeon_mem_types_names[i], "radeon_gtt_mm");
722 radeon_mem_types_list[i].name = radeon_mem_types_names[i];
723 radeon_mem_types_list[i].show = &radeon_mm_dump_table;
724 radeon_mem_types_list[i].driver_features = 0;
725 if (i == 0)
726 radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].manager;
727 else
728 radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager;
729
730 }
731 return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES);
732
733#endif
734 return 0;
735}
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r100 b/drivers/gpu/drm/radeon/reg_srcs/r100
new file mode 100644
index 000000000000..f7ee062f1184
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r100
@@ -0,0 +1,105 @@
1r100 0x3294
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
310x1810 FOG_3D_TABLE_START
320x1814 FOG_3D_TABLE_END
330x1a14 FOG_TABLE_INDEX
340x1a18 FOG_TABLE_DATA
350x1c14 PP_MISC
360x1c18 PP_FOG_COLOR
370x1c1c RE_SOLID_COLOR
380x1c20 RB3D_BLENDCNTL
390x1c4c SE_CNTL
400x1c50 SE_COORD_FMT
410x1c60 PP_TXCBLEND_0
420x1c64 PP_TXABLEND_0
430x1c68 PP_TFACTOR_0
440x1c78 PP_TXCBLEND_1
450x1c7c PP_TXABLEND_1
460x1c80 PP_TFACTOR_1
470x1c90 PP_TXCBLEND_2
480x1c94 PP_TXABLEND_2
490x1c98 PP_TFACTOR_2
500x1cc8 RE_STIPPLE_ADDR
510x1ccc RE_STIPPLE_DATA
520x1cd0 RE_LINE_PATTERN
530x1cd4 RE_LINE_STATE
540x1d40 PP_BORDER_COLOR0
550x1d44 PP_BORDER_COLOR1
560x1d48 PP_BORDER_COLOR2
570x1d7c RB3D_STENCILREFMASK
580x1d80 RB3D_ROPCNTL
590x1d84 RB3D_PLANEMASK
600x1d98 VAP_VPORT_XSCALE
610x1d9C VAP_VPORT_XOFFSET
620x1da0 VAP_VPORT_YSCALE
630x1da4 VAP_VPORT_YOFFSET
640x1da8 VAP_VPORT_ZSCALE
650x1dac VAP_VPORT_ZOFFSET
660x1db0 SE_ZBIAS_FACTOR
670x1db4 SE_ZBIAS_CONSTANT
680x1db8 SE_LINE_WIDTH
690x2140 SE_CNTL_STATUS
700x2200 SE_TCL_VECTOR_INDX_REG
710x2204 SE_TCL_VECTOR_DATA_REG
720x2208 SE_TCL_SCALAR_INDX_REG
730x220c SE_TCL_SCALAR_DATA_REG
740x2210 SE_TCL_MATERIAL_EMISSIVE_RED
750x2214 SE_TCL_MATERIAL_EMISSIVE_GREEN
760x2218 SE_TCL_MATERIAL_EMISSIVE_BLUE
770x221c SE_TCL_MATERIAL_EMISSIVE_ALPHA
780x2220 SE_TCL_MATERIAL_AMBIENT_RED
790x2224 SE_TCL_MATERIAL_AMBIENT_GREEN
800x2228 SE_TCL_MATERIAL_AMBIENT_BLUE
810x222c SE_TCL_MATERIAL_AMBIENT_ALPHA
820x2230 SE_TCL_MATERIAL_DIFFUSE_RED
830x2234 SE_TCL_MATERIAL_DIFFUSE_GREEN
840x2238 SE_TCL_MATERIAL_DIFFUSE_BLUE
850x223c SE_TCL_MATERIAL_DIFFUSE_ALPHA
860x2240 SE_TCL_MATERIAL_SPECULAR_RED
870x2244 SE_TCL_MATERIAL_SPECULAR_GREEN
880x2248 SE_TCL_MATERIAL_SPECULAR_BLUE
890x224c SE_TCL_MATERIAL_SPECULAR_ALPHA
900x2250 SE_TCL_SHININESS
910x2254 SE_TCL_OUTPUT_VTX_FMT
920x2258 SE_TCL_OUTPUT_VTX_SEL
930x225c SE_TCL_MATRIX_SELECT_0
940x2260 SE_TCL_MATRIX_SELECT_1
950x2264 SE_TCL_UCP_VERT_BLEND_CNTL
960x2268 SE_TCL_TEXTURE_PROC_CTL
970x226c SE_TCL_LIGHT_MODEL_CTL
980x2270 SE_TCL_PER_LIGHT_CTL_0
990x2274 SE_TCL_PER_LIGHT_CTL_1
1000x2278 SE_TCL_PER_LIGHT_CTL_2
1010x227c SE_TCL_PER_LIGHT_CTL_3
1020x2284 SE_TCL_STATE_FLUSH
1030x26c0 RE_TOP_LEFT
1040x26c4 RE_MISC
1050x3290 RB3D_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r200 b/drivers/gpu/drm/radeon/reg_srcs/r200
new file mode 100644
index 000000000000..6021c8849a16
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r200
@@ -0,0 +1,184 @@
1r200 0x3294
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
310x1c14 PP_MISC
320x1c18 PP_FOG_COLOR
330x1c1c RE_SOLID_COLOR
340x1c20 RB3D_BLENDCNTL
350x1c4c SE_CNTL
360x1c50 RE_CNTL
370x1cc8 RE_STIPPLE_ADDR
380x1ccc RE_STIPPLE_DATA
390x1cd0 RE_LINE_PATTERN
400x1cd4 RE_LINE_STATE
410x1cd8 RE_SCISSOR_TL_0
420x1cdc RE_SCISSOR_BR_0
430x1ce0 RE_SCISSOR_TL_1
440x1ce4 RE_SCISSOR_BR_1
450x1ce8 RE_SCISSOR_TL_2
460x1cec RE_SCISSOR_BR_2
470x1d60 RB3D_DEPTHXY_OFFSET
480x1d7c RB3D_STENCILREFMASK
490x1d80 RB3D_ROPCNTL
500x1d84 RB3D_PLANEMASK
510x1d98 VAP_VPORT_XSCALE
520x1d9c VAP_VPORT_XOFFSET
530x1da0 VAP_VPORT_YSCALE
540x1da4 VAP_VPORT_YOFFSET
550x1da8 VAP_VPORT_ZSCALE
560x1dac VAP_VPORT_ZOFFSET
570x1db0 SE_ZBIAS_FACTOR
580x1db4 SE_ZBIAS_CONSTANT
590x1db8 SE_LINE_WIDTH
600x2080 SE_VAP_CNTL
610x2090 SE_TCL_OUTPUT_VTX_FMT_0
620x2094 SE_TCL_OUTPUT_VTX_FMT_1
630x20b0 SE_VTE_CNTL
640x2140 SE_CNTL_STATUS
650x2180 SE_VTX_STATE_CNTL
660x2200 SE_TCL_VECTOR_INDX_REG
670x2204 SE_TCL_VECTOR_DATA_REG
680x2208 SE_TCL_SCALAR_INDX_REG
690x220c SE_TCL_SCALAR_DATA_REG
700x2230 SE_TCL_MATRIX_SEL_0
710x2234 SE_TCL_MATRIX_SEL_1
720x2238 SE_TCL_MATRIX_SEL_2
730x223c SE_TCL_MATRIX_SEL_3
740x2240 SE_TCL_MATRIX_SEL_4
750x2250 SE_TCL_OUTPUT_VTX_COMP_SEL
760x2254 SE_TCL_INPUT_VTX_VECTOR_ADDR_0
770x2258 SE_TCL_INPUT_VTX_VECTOR_ADDR_1
780x225c SE_TCL_INPUT_VTX_VECTOR_ADDR_2
790x2260 SE_TCL_INPUT_VTX_VECTOR_ADDR_3
800x2268 SE_TCL_LIGHT_MODEL_CTL_0
810x226c SE_TCL_LIGHT_MODEL_CTL_1
820x2270 SE_TCL_PER_LIGHT_CTL_0
830x2274 SE_TCL_PER_LIGHT_CTL_1
840x2278 SE_TCL_PER_LIGHT_CTL_2
850x227c SE_TCL_PER_LIGHT_CTL_3
860x2284 VAP_PVS_STATE_FLUSH_REG
870x22a8 SE_TCL_TEX_PROC_CTL_2
880x22ac SE_TCL_TEX_PROC_CTL_3
890x22b0 SE_TCL_TEX_PROC_CTL_0
900x22b4 SE_TCL_TEX_PROC_CTL_1
910x22b8 SE_TCL_TEX_CYL_WRAP_CTL
920x22c0 SE_TCL_UCP_VERT_BLEND_CNTL
930x22c4 SE_TCL_POINT_SPRITE_CNTL
940x2648 RE_POINTSIZE
950x26c0 RE_TOP_LEFT
960x26c4 RE_MISC
970x26f0 RE_AUX_SCISSOR_CNTL
980x2c14 PP_BORDER_COLOR_0
990x2c34 PP_BORDER_COLOR_1
1000x2c54 PP_BORDER_COLOR_2
1010x2c74 PP_BORDER_COLOR_3
1020x2c94 PP_BORDER_COLOR_4
1030x2cb4 PP_BORDER_COLOR_5
1040x2cc4 PP_CNTL_X
1050x2cf8 PP_TRI_PERF
1060x2cfc PP_PERF_CNTL
1070x2d9c PP_TAM_DEBUG3
1080x2ee0 PP_TFACTOR_0
1090x2ee4 PP_TFACTOR_1
1100x2ee8 PP_TFACTOR_2
1110x2eec PP_TFACTOR_3
1120x2ef0 PP_TFACTOR_4
1130x2ef4 PP_TFACTOR_5
1140x2ef8 PP_TFACTOR_6
1150x2efc PP_TFACTOR_7
1160x2f00 PP_TXCBLEND_0
1170x2f04 PP_TXCBLEND2_0
1180x2f08 PP_TXABLEND_0
1190x2f0c PP_TXABLEND2_0
1200x2f10 PP_TXCBLEND_1
1210x2f14 PP_TXCBLEND2_1
1220x2f18 PP_TXABLEND_1
1230x2f1c PP_TXABLEND2_1
1240x2f20 PP_TXCBLEND_2
1250x2f24 PP_TXCBLEND2_2
1260x2f28 PP_TXABLEND_2
1270x2f2c PP_TXABLEND2_2
1280x2f30 PP_TXCBLEND_3
1290x2f34 PP_TXCBLEND2_3
1300x2f38 PP_TXABLEND_3
1310x2f3c PP_TXABLEND2_3
1320x2f40 PP_TXCBLEND_4
1330x2f44 PP_TXCBLEND2_4
1340x2f48 PP_TXABLEND_4
1350x2f4c PP_TXABLEND2_4
1360x2f50 PP_TXCBLEND_5
1370x2f54 PP_TXCBLEND2_5
1380x2f58 PP_TXABLEND_5
1390x2f5c PP_TXABLEND2_5
1400x2f60 PP_TXCBLEND_6
1410x2f64 PP_TXCBLEND2_6
1420x2f68 PP_TXABLEND_6
1430x2f6c PP_TXABLEND2_6
1440x2f70 PP_TXCBLEND_7
1450x2f74 PP_TXCBLEND2_7
1460x2f78 PP_TXABLEND_7
1470x2f7c PP_TXABLEND2_7
1480x2f80 PP_TXCBLEND_8
1490x2f84 PP_TXCBLEND2_8
1500x2f88 PP_TXABLEND_8
1510x2f8c PP_TXABLEND2_8
1520x2f90 PP_TXCBLEND_9
1530x2f94 PP_TXCBLEND2_9
1540x2f98 PP_TXABLEND_9
1550x2f9c PP_TXABLEND2_9
1560x2fa0 PP_TXCBLEND_10
1570x2fa4 PP_TXCBLEND2_10
1580x2fa8 PP_TXABLEND_10
1590x2fac PP_TXABLEND2_10
1600x2fb0 PP_TXCBLEND_11
1610x2fb4 PP_TXCBLEND2_11
1620x2fb8 PP_TXABLEND_11
1630x2fbc PP_TXABLEND2_11
1640x2fc0 PP_TXCBLEND_12
1650x2fc4 PP_TXCBLEND2_12
1660x2fc8 PP_TXABLEND_12
1670x2fcc PP_TXABLEND2_12
1680x2fd0 PP_TXCBLEND_13
1690x2fd4 PP_TXCBLEND2_13
1700x2fd8 PP_TXABLEND_13
1710x2fdc PP_TXABLEND2_13
1720x2fe0 PP_TXCBLEND_14
1730x2fe4 PP_TXCBLEND2_14
1740x2fe8 PP_TXABLEND_14
1750x2fec PP_TXABLEND2_14
1760x2ff0 PP_TXCBLEND_15
1770x2ff4 PP_TXCBLEND2_15
1780x2ff8 PP_TXABLEND_15
1790x2ffc PP_TXABLEND2_15
1800x3218 RB3D_BLENCOLOR
1810x321c RB3D_ABLENDCNTL
1820x3220 RB3D_CBLENDCNTL
1830x3290 RB3D_ZPASS_DATA
184
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300
new file mode 100644
index 000000000000..19c4663fa9c6
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r300
@@ -0,0 +1,729 @@
1r300 0x4f60
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
310x1D98 VAP_VPORT_XSCALE
320x1D9C VAP_VPORT_XOFFSET
330x1DA0 VAP_VPORT_YSCALE
340x1DA4 VAP_VPORT_YOFFSET
350x1DA8 VAP_VPORT_ZSCALE
360x1DAC VAP_VPORT_ZOFFSET
370x2080 VAP_CNTL
380x2090 VAP_OUT_VTX_FMT_0
390x2094 VAP_OUT_VTX_FMT_1
400x20B0 VAP_VTE_CNTL
410x2138 VAP_VF_MIN_VTX_INDX
420x2140 VAP_CNTL_STATUS
430x2150 VAP_PROG_STREAM_CNTL_0
440x2154 VAP_PROG_STREAM_CNTL_1
450x2158 VAP_PROG_STREAM_CNTL_2
460x215C VAP_PROG_STREAM_CNTL_3
470x2160 VAP_PROG_STREAM_CNTL_4
480x2164 VAP_PROG_STREAM_CNTL_5
490x2168 VAP_PROG_STREAM_CNTL_6
500x216C VAP_PROG_STREAM_CNTL_7
510x2180 VAP_VTX_STATE_CNTL
520x2184 VAP_VSM_VTX_ASSM
530x2188 VAP_VTX_STATE_IND_REG_0
540x218C VAP_VTX_STATE_IND_REG_1
550x2190 VAP_VTX_STATE_IND_REG_2
560x2194 VAP_VTX_STATE_IND_REG_3
570x2198 VAP_VTX_STATE_IND_REG_4
580x219C VAP_VTX_STATE_IND_REG_5
590x21A0 VAP_VTX_STATE_IND_REG_6
600x21A4 VAP_VTX_STATE_IND_REG_7
610x21A8 VAP_VTX_STATE_IND_REG_8
620x21AC VAP_VTX_STATE_IND_REG_9
630x21B0 VAP_VTX_STATE_IND_REG_10
640x21B4 VAP_VTX_STATE_IND_REG_11
650x21B8 VAP_VTX_STATE_IND_REG_12
660x21BC VAP_VTX_STATE_IND_REG_13
670x21C0 VAP_VTX_STATE_IND_REG_14
680x21C4 VAP_VTX_STATE_IND_REG_15
690x21DC VAP_PSC_SGN_NORM_CNTL
700x21E0 VAP_PROG_STREAM_CNTL_EXT_0
710x21E4 VAP_PROG_STREAM_CNTL_EXT_1
720x21E8 VAP_PROG_STREAM_CNTL_EXT_2
730x21EC VAP_PROG_STREAM_CNTL_EXT_3
740x21F0 VAP_PROG_STREAM_CNTL_EXT_4
750x21F4 VAP_PROG_STREAM_CNTL_EXT_5
760x21F8 VAP_PROG_STREAM_CNTL_EXT_6
770x21FC VAP_PROG_STREAM_CNTL_EXT_7
780x2200 VAP_PVS_VECTOR_INDX_REG
790x2204 VAP_PVS_VECTOR_DATA_REG
800x2208 VAP_PVS_VECTOR_DATA_REG_128
810x221C VAP_CLIP_CNTL
820x2220 VAP_GB_VERT_CLIP_ADJ
830x2224 VAP_GB_VERT_DISC_ADJ
840x2228 VAP_GB_HORZ_CLIP_ADJ
850x222C VAP_GB_HORZ_DISC_ADJ
860x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
870x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
880x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
890x223C VAP_PVS_FLOW_CNTL_ADDRS_3
900x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
910x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
920x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
930x224C VAP_PVS_FLOW_CNTL_ADDRS_7
940x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
950x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
960x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
970x225C VAP_PVS_FLOW_CNTL_ADDRS_11
980x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
990x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
1000x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
1010x226C VAP_PVS_FLOW_CNTL_ADDRS_15
1020x2284 VAP_PVS_STATE_FLUSH_REG
1030x2288 VAP_PVS_VTX_TIMEOUT_REG
1040x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
1050x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
1060x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
1070x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
1080x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
1090x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
1100x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
1110x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
1120x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
1130x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
1140x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
1150x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
1160x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
1170x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
1180x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
1190x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
1200x22D0 VAP_PVS_CODE_CNTL_0
1210x22D4 VAP_PVS_CONST_CNTL
1220x22D8 VAP_PVS_CODE_CNTL_1
1230x22DC VAP_PVS_FLOW_CNTL_OPC
1240x342C RB2D_DSTCACHE_CTLSTAT
1250x4000 GB_VAP_RASTER_VTX_FMT_0
1260x4004 GB_VAP_RASTER_VTX_FMT_1
1270x4008 GB_ENABLE
1280x401C GB_SELECT
1290x4020 GB_AA_CONFIG
1300x4024 GB_FIFO_SIZE
1310x4100 TX_INVALTAGS
1320x4200 GA_POINT_S0
1330x4204 GA_POINT_T0
1340x4208 GA_POINT_S1
1350x420C GA_POINT_T1
1360x4214 GA_TRIANGLE_STIPPLE
1370x421C GA_POINT_SIZE
1380x4230 GA_POINT_MINMAX
1390x4234 GA_LINE_CNTL
1400x4238 GA_LINE_STIPPLE_CONFIG
1410x4260 GA_LINE_STIPPLE_VALUE
1420x4264 GA_LINE_S0
1430x4268 GA_LINE_S1
1440x4278 GA_COLOR_CONTROL
1450x427C GA_SOLID_RG
1460x4280 GA_SOLID_BA
1470x4288 GA_POLY_MODE
1480x428C GA_ROUND_MODE
1490x4290 GA_OFFSET
1500x4294 GA_FOG_SCALE
1510x4298 GA_FOG_OFFSET
1520x42A0 SU_TEX_WRAP
1530x42A4 SU_POLY_OFFSET_FRONT_SCALE
1540x42A8 SU_POLY_OFFSET_FRONT_OFFSET
1550x42AC SU_POLY_OFFSET_BACK_SCALE
1560x42B0 SU_POLY_OFFSET_BACK_OFFSET
1570x42B4 SU_POLY_OFFSET_ENABLE
1580x42B8 SU_CULL_MODE
1590x42C0 SU_DEPTH_SCALE
1600x42C4 SU_DEPTH_OFFSET
1610x42C8 SU_REG_DEST
1620x4300 RS_COUNT
1630x4304 RS_INST_COUNT
1640x4310 RS_IP_0
1650x4314 RS_IP_1
1660x4318 RS_IP_2
1670x431C RS_IP_3
1680x4320 RS_IP_4
1690x4324 RS_IP_5
1700x4328 RS_IP_6
1710x432C RS_IP_7
1720x4330 RS_INST_0
1730x4334 RS_INST_1
1740x4338 RS_INST_2
1750x433C RS_INST_3
1760x4340 RS_INST_4
1770x4344 RS_INST_5
1780x4348 RS_INST_6
1790x434C RS_INST_7
1800x4350 RS_INST_8
1810x4354 RS_INST_9
1820x4358 RS_INST_10
1830x435C RS_INST_11
1840x4360 RS_INST_12
1850x4364 RS_INST_13
1860x4368 RS_INST_14
1870x436C RS_INST_15
1880x43A4 SC_HYPERZ_EN
1890x43A8 SC_EDGERULE
1900x43B0 SC_CLIP_0_A
1910x43B4 SC_CLIP_0_B
1920x43B8 SC_CLIP_1_A
1930x43BC SC_CLIP_1_B
1940x43C0 SC_CLIP_2_A
1950x43C4 SC_CLIP_2_B
1960x43C8 SC_CLIP_3_A
1970x43CC SC_CLIP_3_B
1980x43D0 SC_CLIP_RULE
1990x43E0 SC_SCISSOR0
2000x43E8 SC_SCREENDOOR
2010x4440 TX_FILTER1_0
2020x4444 TX_FILTER1_1
2030x4448 TX_FILTER1_2
2040x444C TX_FILTER1_3
2050x4450 TX_FILTER1_4
2060x4454 TX_FILTER1_5
2070x4458 TX_FILTER1_6
2080x445C TX_FILTER1_7
2090x4460 TX_FILTER1_8
2100x4464 TX_FILTER1_9
2110x4468 TX_FILTER1_10
2120x446C TX_FILTER1_11
2130x4470 TX_FILTER1_12
2140x4474 TX_FILTER1_13
2150x4478 TX_FILTER1_14
2160x447C TX_FILTER1_15
2170x4580 TX_CHROMA_KEY_0
2180x4584 TX_CHROMA_KEY_1
2190x4588 TX_CHROMA_KEY_2
2200x458C TX_CHROMA_KEY_3
2210x4590 TX_CHROMA_KEY_4
2220x4594 TX_CHROMA_KEY_5
2230x4598 TX_CHROMA_KEY_6
2240x459C TX_CHROMA_KEY_7
2250x45A0 TX_CHROMA_KEY_8
2260x45A4 TX_CHROMA_KEY_9
2270x45A8 TX_CHROMA_KEY_10
2280x45AC TX_CHROMA_KEY_11
2290x45B0 TX_CHROMA_KEY_12
2300x45B4 TX_CHROMA_KEY_13
2310x45B8 TX_CHROMA_KEY_14
2320x45BC TX_CHROMA_KEY_15
2330x45C0 TX_BORDER_COLOR_0
2340x45C4 TX_BORDER_COLOR_1
2350x45C8 TX_BORDER_COLOR_2
2360x45CC TX_BORDER_COLOR_3
2370x45D0 TX_BORDER_COLOR_4
2380x45D4 TX_BORDER_COLOR_5
2390x45D8 TX_BORDER_COLOR_6
2400x45DC TX_BORDER_COLOR_7
2410x45E0 TX_BORDER_COLOR_8
2420x45E4 TX_BORDER_COLOR_9
2430x45E8 TX_BORDER_COLOR_10
2440x45EC TX_BORDER_COLOR_11
2450x45F0 TX_BORDER_COLOR_12
2460x45F4 TX_BORDER_COLOR_13
2470x45F8 TX_BORDER_COLOR_14
2480x45FC TX_BORDER_COLOR_15
2490x4600 US_CONFIG
2500x4604 US_PIXSIZE
2510x4608 US_CODE_OFFSET
2520x460C US_RESET
2530x4610 US_CODE_ADDR_0
2540x4614 US_CODE_ADDR_1
2550x4618 US_CODE_ADDR_2
2560x461C US_CODE_ADDR_3
2570x4620 US_TEX_INST_0
2580x4624 US_TEX_INST_1
2590x4628 US_TEX_INST_2
2600x462C US_TEX_INST_3
2610x4630 US_TEX_INST_4
2620x4634 US_TEX_INST_5
2630x4638 US_TEX_INST_6
2640x463C US_TEX_INST_7
2650x4640 US_TEX_INST_8
2660x4644 US_TEX_INST_9
2670x4648 US_TEX_INST_10
2680x464C US_TEX_INST_11
2690x4650 US_TEX_INST_12
2700x4654 US_TEX_INST_13
2710x4658 US_TEX_INST_14
2720x465C US_TEX_INST_15
2730x4660 US_TEX_INST_16
2740x4664 US_TEX_INST_17
2750x4668 US_TEX_INST_18
2760x466C US_TEX_INST_19
2770x4670 US_TEX_INST_20
2780x4674 US_TEX_INST_21
2790x4678 US_TEX_INST_22
2800x467C US_TEX_INST_23
2810x4680 US_TEX_INST_24
2820x4684 US_TEX_INST_25
2830x4688 US_TEX_INST_26
2840x468C US_TEX_INST_27
2850x4690 US_TEX_INST_28
2860x4694 US_TEX_INST_29
2870x4698 US_TEX_INST_30
2880x469C US_TEX_INST_31
2890x46A4 US_OUT_FMT_0
2900x46A8 US_OUT_FMT_1
2910x46AC US_OUT_FMT_2
2920x46B0 US_OUT_FMT_3
2930x46B4 US_W_FMT
2940x46C0 US_ALU_RGB_ADDR_0
2950x46C4 US_ALU_RGB_ADDR_1
2960x46C8 US_ALU_RGB_ADDR_2
2970x46CC US_ALU_RGB_ADDR_3
2980x46D0 US_ALU_RGB_ADDR_4
2990x46D4 US_ALU_RGB_ADDR_5
3000x46D8 US_ALU_RGB_ADDR_6
3010x46DC US_ALU_RGB_ADDR_7
3020x46E0 US_ALU_RGB_ADDR_8
3030x46E4 US_ALU_RGB_ADDR_9
3040x46E8 US_ALU_RGB_ADDR_10
3050x46EC US_ALU_RGB_ADDR_11
3060x46F0 US_ALU_RGB_ADDR_12
3070x46F4 US_ALU_RGB_ADDR_13
3080x46F8 US_ALU_RGB_ADDR_14
3090x46FC US_ALU_RGB_ADDR_15
3100x4700 US_ALU_RGB_ADDR_16
3110x4704 US_ALU_RGB_ADDR_17
3120x4708 US_ALU_RGB_ADDR_18
3130x470C US_ALU_RGB_ADDR_19
3140x4710 US_ALU_RGB_ADDR_20
3150x4714 US_ALU_RGB_ADDR_21
3160x4718 US_ALU_RGB_ADDR_22
3170x471C US_ALU_RGB_ADDR_23
3180x4720 US_ALU_RGB_ADDR_24
3190x4724 US_ALU_RGB_ADDR_25
3200x4728 US_ALU_RGB_ADDR_26
3210x472C US_ALU_RGB_ADDR_27
3220x4730 US_ALU_RGB_ADDR_28
3230x4734 US_ALU_RGB_ADDR_29
3240x4738 US_ALU_RGB_ADDR_30
3250x473C US_ALU_RGB_ADDR_31
3260x4740 US_ALU_RGB_ADDR_32
3270x4744 US_ALU_RGB_ADDR_33
3280x4748 US_ALU_RGB_ADDR_34
3290x474C US_ALU_RGB_ADDR_35
3300x4750 US_ALU_RGB_ADDR_36
3310x4754 US_ALU_RGB_ADDR_37
3320x4758 US_ALU_RGB_ADDR_38
3330x475C US_ALU_RGB_ADDR_39
3340x4760 US_ALU_RGB_ADDR_40
3350x4764 US_ALU_RGB_ADDR_41
3360x4768 US_ALU_RGB_ADDR_42
3370x476C US_ALU_RGB_ADDR_43
3380x4770 US_ALU_RGB_ADDR_44
3390x4774 US_ALU_RGB_ADDR_45
3400x4778 US_ALU_RGB_ADDR_46
3410x477C US_ALU_RGB_ADDR_47
3420x4780 US_ALU_RGB_ADDR_48
3430x4784 US_ALU_RGB_ADDR_49
3440x4788 US_ALU_RGB_ADDR_50
3450x478C US_ALU_RGB_ADDR_51
3460x4790 US_ALU_RGB_ADDR_52
3470x4794 US_ALU_RGB_ADDR_53
3480x4798 US_ALU_RGB_ADDR_54
3490x479C US_ALU_RGB_ADDR_55
3500x47A0 US_ALU_RGB_ADDR_56
3510x47A4 US_ALU_RGB_ADDR_57
3520x47A8 US_ALU_RGB_ADDR_58
3530x47AC US_ALU_RGB_ADDR_59
3540x47B0 US_ALU_RGB_ADDR_60
3550x47B4 US_ALU_RGB_ADDR_61
3560x47B8 US_ALU_RGB_ADDR_62
3570x47BC US_ALU_RGB_ADDR_63
3580x47C0 US_ALU_ALPHA_ADDR_0
3590x47C4 US_ALU_ALPHA_ADDR_1
3600x47C8 US_ALU_ALPHA_ADDR_2
3610x47CC US_ALU_ALPHA_ADDR_3
3620x47D0 US_ALU_ALPHA_ADDR_4
3630x47D4 US_ALU_ALPHA_ADDR_5
3640x47D8 US_ALU_ALPHA_ADDR_6
3650x47DC US_ALU_ALPHA_ADDR_7
3660x47E0 US_ALU_ALPHA_ADDR_8
3670x47E4 US_ALU_ALPHA_ADDR_9
3680x47E8 US_ALU_ALPHA_ADDR_10
3690x47EC US_ALU_ALPHA_ADDR_11
3700x47F0 US_ALU_ALPHA_ADDR_12
3710x47F4 US_ALU_ALPHA_ADDR_13
3720x47F8 US_ALU_ALPHA_ADDR_14
3730x47FC US_ALU_ALPHA_ADDR_15
3740x4800 US_ALU_ALPHA_ADDR_16
3750x4804 US_ALU_ALPHA_ADDR_17
3760x4808 US_ALU_ALPHA_ADDR_18
3770x480C US_ALU_ALPHA_ADDR_19
3780x4810 US_ALU_ALPHA_ADDR_20
3790x4814 US_ALU_ALPHA_ADDR_21
3800x4818 US_ALU_ALPHA_ADDR_22
3810x481C US_ALU_ALPHA_ADDR_23
3820x4820 US_ALU_ALPHA_ADDR_24
3830x4824 US_ALU_ALPHA_ADDR_25
3840x4828 US_ALU_ALPHA_ADDR_26
3850x482C US_ALU_ALPHA_ADDR_27
3860x4830 US_ALU_ALPHA_ADDR_28
3870x4834 US_ALU_ALPHA_ADDR_29
3880x4838 US_ALU_ALPHA_ADDR_30
3890x483C US_ALU_ALPHA_ADDR_31
3900x4840 US_ALU_ALPHA_ADDR_32
3910x4844 US_ALU_ALPHA_ADDR_33
3920x4848 US_ALU_ALPHA_ADDR_34
3930x484C US_ALU_ALPHA_ADDR_35
3940x4850 US_ALU_ALPHA_ADDR_36
3950x4854 US_ALU_ALPHA_ADDR_37
3960x4858 US_ALU_ALPHA_ADDR_38
3970x485C US_ALU_ALPHA_ADDR_39
3980x4860 US_ALU_ALPHA_ADDR_40
3990x4864 US_ALU_ALPHA_ADDR_41
4000x4868 US_ALU_ALPHA_ADDR_42
4010x486C US_ALU_ALPHA_ADDR_43
4020x4870 US_ALU_ALPHA_ADDR_44
4030x4874 US_ALU_ALPHA_ADDR_45
4040x4878 US_ALU_ALPHA_ADDR_46
4050x487C US_ALU_ALPHA_ADDR_47
4060x4880 US_ALU_ALPHA_ADDR_48
4070x4884 US_ALU_ALPHA_ADDR_49
4080x4888 US_ALU_ALPHA_ADDR_50
4090x488C US_ALU_ALPHA_ADDR_51
4100x4890 US_ALU_ALPHA_ADDR_52
4110x4894 US_ALU_ALPHA_ADDR_53
4120x4898 US_ALU_ALPHA_ADDR_54
4130x489C US_ALU_ALPHA_ADDR_55
4140x48A0 US_ALU_ALPHA_ADDR_56
4150x48A4 US_ALU_ALPHA_ADDR_57
4160x48A8 US_ALU_ALPHA_ADDR_58
4170x48AC US_ALU_ALPHA_ADDR_59
4180x48B0 US_ALU_ALPHA_ADDR_60
4190x48B4 US_ALU_ALPHA_ADDR_61
4200x48B8 US_ALU_ALPHA_ADDR_62
4210x48BC US_ALU_ALPHA_ADDR_63
4220x48C0 US_ALU_RGB_INST_0
4230x48C4 US_ALU_RGB_INST_1
4240x48C8 US_ALU_RGB_INST_2
4250x48CC US_ALU_RGB_INST_3
4260x48D0 US_ALU_RGB_INST_4
4270x48D4 US_ALU_RGB_INST_5
4280x48D8 US_ALU_RGB_INST_6
4290x48DC US_ALU_RGB_INST_7
4300x48E0 US_ALU_RGB_INST_8
4310x48E4 US_ALU_RGB_INST_9
4320x48E8 US_ALU_RGB_INST_10
4330x48EC US_ALU_RGB_INST_11
4340x48F0 US_ALU_RGB_INST_12
4350x48F4 US_ALU_RGB_INST_13
4360x48F8 US_ALU_RGB_INST_14
4370x48FC US_ALU_RGB_INST_15
4380x4900 US_ALU_RGB_INST_16
4390x4904 US_ALU_RGB_INST_17
4400x4908 US_ALU_RGB_INST_18
4410x490C US_ALU_RGB_INST_19
4420x4910 US_ALU_RGB_INST_20
4430x4914 US_ALU_RGB_INST_21
4440x4918 US_ALU_RGB_INST_22
4450x491C US_ALU_RGB_INST_23
4460x4920 US_ALU_RGB_INST_24
4470x4924 US_ALU_RGB_INST_25
4480x4928 US_ALU_RGB_INST_26
4490x492C US_ALU_RGB_INST_27
4500x4930 US_ALU_RGB_INST_28
4510x4934 US_ALU_RGB_INST_29
4520x4938 US_ALU_RGB_INST_30
4530x493C US_ALU_RGB_INST_31
4540x4940 US_ALU_RGB_INST_32
4550x4944 US_ALU_RGB_INST_33
4560x4948 US_ALU_RGB_INST_34
4570x494C US_ALU_RGB_INST_35
4580x4950 US_ALU_RGB_INST_36
4590x4954 US_ALU_RGB_INST_37
4600x4958 US_ALU_RGB_INST_38
4610x495C US_ALU_RGB_INST_39
4620x4960 US_ALU_RGB_INST_40
4630x4964 US_ALU_RGB_INST_41
4640x4968 US_ALU_RGB_INST_42
4650x496C US_ALU_RGB_INST_43
4660x4970 US_ALU_RGB_INST_44
4670x4974 US_ALU_RGB_INST_45
4680x4978 US_ALU_RGB_INST_46
4690x497C US_ALU_RGB_INST_47
4700x4980 US_ALU_RGB_INST_48
4710x4984 US_ALU_RGB_INST_49
4720x4988 US_ALU_RGB_INST_50
4730x498C US_ALU_RGB_INST_51
4740x4990 US_ALU_RGB_INST_52
4750x4994 US_ALU_RGB_INST_53
4760x4998 US_ALU_RGB_INST_54
4770x499C US_ALU_RGB_INST_55
4780x49A0 US_ALU_RGB_INST_56
4790x49A4 US_ALU_RGB_INST_57
4800x49A8 US_ALU_RGB_INST_58
4810x49AC US_ALU_RGB_INST_59
4820x49B0 US_ALU_RGB_INST_60
4830x49B4 US_ALU_RGB_INST_61
4840x49B8 US_ALU_RGB_INST_62
4850x49BC US_ALU_RGB_INST_63
4860x49C0 US_ALU_ALPHA_INST_0
4870x49C4 US_ALU_ALPHA_INST_1
4880x49C8 US_ALU_ALPHA_INST_2
4890x49CC US_ALU_ALPHA_INST_3
4900x49D0 US_ALU_ALPHA_INST_4
4910x49D4 US_ALU_ALPHA_INST_5
4920x49D8 US_ALU_ALPHA_INST_6
4930x49DC US_ALU_ALPHA_INST_7
4940x49E0 US_ALU_ALPHA_INST_8
4950x49E4 US_ALU_ALPHA_INST_9
4960x49E8 US_ALU_ALPHA_INST_10
4970x49EC US_ALU_ALPHA_INST_11
4980x49F0 US_ALU_ALPHA_INST_12
4990x49F4 US_ALU_ALPHA_INST_13
5000x49F8 US_ALU_ALPHA_INST_14
5010x49FC US_ALU_ALPHA_INST_15
5020x4A00 US_ALU_ALPHA_INST_16
5030x4A04 US_ALU_ALPHA_INST_17
5040x4A08 US_ALU_ALPHA_INST_18
5050x4A0C US_ALU_ALPHA_INST_19
5060x4A10 US_ALU_ALPHA_INST_20
5070x4A14 US_ALU_ALPHA_INST_21
5080x4A18 US_ALU_ALPHA_INST_22
5090x4A1C US_ALU_ALPHA_INST_23
5100x4A20 US_ALU_ALPHA_INST_24
5110x4A24 US_ALU_ALPHA_INST_25
5120x4A28 US_ALU_ALPHA_INST_26
5130x4A2C US_ALU_ALPHA_INST_27
5140x4A30 US_ALU_ALPHA_INST_28
5150x4A34 US_ALU_ALPHA_INST_29
5160x4A38 US_ALU_ALPHA_INST_30
5170x4A3C US_ALU_ALPHA_INST_31
5180x4A40 US_ALU_ALPHA_INST_32
5190x4A44 US_ALU_ALPHA_INST_33
5200x4A48 US_ALU_ALPHA_INST_34
5210x4A4C US_ALU_ALPHA_INST_35
5220x4A50 US_ALU_ALPHA_INST_36
5230x4A54 US_ALU_ALPHA_INST_37
5240x4A58 US_ALU_ALPHA_INST_38
5250x4A5C US_ALU_ALPHA_INST_39
5260x4A60 US_ALU_ALPHA_INST_40
5270x4A64 US_ALU_ALPHA_INST_41
5280x4A68 US_ALU_ALPHA_INST_42
5290x4A6C US_ALU_ALPHA_INST_43
5300x4A70 US_ALU_ALPHA_INST_44
5310x4A74 US_ALU_ALPHA_INST_45
5320x4A78 US_ALU_ALPHA_INST_46
5330x4A7C US_ALU_ALPHA_INST_47
5340x4A80 US_ALU_ALPHA_INST_48
5350x4A84 US_ALU_ALPHA_INST_49
5360x4A88 US_ALU_ALPHA_INST_50
5370x4A8C US_ALU_ALPHA_INST_51
5380x4A90 US_ALU_ALPHA_INST_52
5390x4A94 US_ALU_ALPHA_INST_53
5400x4A98 US_ALU_ALPHA_INST_54
5410x4A9C US_ALU_ALPHA_INST_55
5420x4AA0 US_ALU_ALPHA_INST_56
5430x4AA4 US_ALU_ALPHA_INST_57
5440x4AA8 US_ALU_ALPHA_INST_58
5450x4AAC US_ALU_ALPHA_INST_59
5460x4AB0 US_ALU_ALPHA_INST_60
5470x4AB4 US_ALU_ALPHA_INST_61
5480x4AB8 US_ALU_ALPHA_INST_62
5490x4ABC US_ALU_ALPHA_INST_63
5500x4BC0 FG_FOG_BLEND
5510x4BC4 FG_FOG_FACTOR
5520x4BC8 FG_FOG_COLOR_R
5530x4BCC FG_FOG_COLOR_G
5540x4BD0 FG_FOG_COLOR_B
5550x4BD4 FG_ALPHA_FUNC
5560x4BD8 FG_DEPTH_SRC
5570x4C00 US_ALU_CONST_R_0
5580x4C04 US_ALU_CONST_G_0
5590x4C08 US_ALU_CONST_B_0
5600x4C0C US_ALU_CONST_A_0
5610x4C10 US_ALU_CONST_R_1
5620x4C14 US_ALU_CONST_G_1
5630x4C18 US_ALU_CONST_B_1
5640x4C1C US_ALU_CONST_A_1
5650x4C20 US_ALU_CONST_R_2
5660x4C24 US_ALU_CONST_G_2
5670x4C28 US_ALU_CONST_B_2
5680x4C2C US_ALU_CONST_A_2
5690x4C30 US_ALU_CONST_R_3
5700x4C34 US_ALU_CONST_G_3
5710x4C38 US_ALU_CONST_B_3
5720x4C3C US_ALU_CONST_A_3
5730x4C40 US_ALU_CONST_R_4
5740x4C44 US_ALU_CONST_G_4
5750x4C48 US_ALU_CONST_B_4
5760x4C4C US_ALU_CONST_A_4
5770x4C50 US_ALU_CONST_R_5
5780x4C54 US_ALU_CONST_G_5
5790x4C58 US_ALU_CONST_B_5
5800x4C5C US_ALU_CONST_A_5
5810x4C60 US_ALU_CONST_R_6
5820x4C64 US_ALU_CONST_G_6
5830x4C68 US_ALU_CONST_B_6
5840x4C6C US_ALU_CONST_A_6
5850x4C70 US_ALU_CONST_R_7
5860x4C74 US_ALU_CONST_G_7
5870x4C78 US_ALU_CONST_B_7
5880x4C7C US_ALU_CONST_A_7
5890x4C80 US_ALU_CONST_R_8
5900x4C84 US_ALU_CONST_G_8
5910x4C88 US_ALU_CONST_B_8
5920x4C8C US_ALU_CONST_A_8
5930x4C90 US_ALU_CONST_R_9
5940x4C94 US_ALU_CONST_G_9
5950x4C98 US_ALU_CONST_B_9
5960x4C9C US_ALU_CONST_A_9
5970x4CA0 US_ALU_CONST_R_10
5980x4CA4 US_ALU_CONST_G_10
5990x4CA8 US_ALU_CONST_B_10
6000x4CAC US_ALU_CONST_A_10
6010x4CB0 US_ALU_CONST_R_11
6020x4CB4 US_ALU_CONST_G_11
6030x4CB8 US_ALU_CONST_B_11
6040x4CBC US_ALU_CONST_A_11
6050x4CC0 US_ALU_CONST_R_12
6060x4CC4 US_ALU_CONST_G_12
6070x4CC8 US_ALU_CONST_B_12
6080x4CCC US_ALU_CONST_A_12
6090x4CD0 US_ALU_CONST_R_13
6100x4CD4 US_ALU_CONST_G_13
6110x4CD8 US_ALU_CONST_B_13
6120x4CDC US_ALU_CONST_A_13
6130x4CE0 US_ALU_CONST_R_14
6140x4CE4 US_ALU_CONST_G_14
6150x4CE8 US_ALU_CONST_B_14
6160x4CEC US_ALU_CONST_A_14
6170x4CF0 US_ALU_CONST_R_15
6180x4CF4 US_ALU_CONST_G_15
6190x4CF8 US_ALU_CONST_B_15
6200x4CFC US_ALU_CONST_A_15
6210x4D00 US_ALU_CONST_R_16
6220x4D04 US_ALU_CONST_G_16
6230x4D08 US_ALU_CONST_B_16
6240x4D0C US_ALU_CONST_A_16
6250x4D10 US_ALU_CONST_R_17
6260x4D14 US_ALU_CONST_G_17
6270x4D18 US_ALU_CONST_B_17
6280x4D1C US_ALU_CONST_A_17
6290x4D20 US_ALU_CONST_R_18
6300x4D24 US_ALU_CONST_G_18
6310x4D28 US_ALU_CONST_B_18
6320x4D2C US_ALU_CONST_A_18
6330x4D30 US_ALU_CONST_R_19
6340x4D34 US_ALU_CONST_G_19
6350x4D38 US_ALU_CONST_B_19
6360x4D3C US_ALU_CONST_A_19
6370x4D40 US_ALU_CONST_R_20
6380x4D44 US_ALU_CONST_G_20
6390x4D48 US_ALU_CONST_B_20
6400x4D4C US_ALU_CONST_A_20
6410x4D50 US_ALU_CONST_R_21
6420x4D54 US_ALU_CONST_G_21
6430x4D58 US_ALU_CONST_B_21
6440x4D5C US_ALU_CONST_A_21
6450x4D60 US_ALU_CONST_R_22
6460x4D64 US_ALU_CONST_G_22
6470x4D68 US_ALU_CONST_B_22
6480x4D6C US_ALU_CONST_A_22
6490x4D70 US_ALU_CONST_R_23
6500x4D74 US_ALU_CONST_G_23
6510x4D78 US_ALU_CONST_B_23
6520x4D7C US_ALU_CONST_A_23
6530x4D80 US_ALU_CONST_R_24
6540x4D84 US_ALU_CONST_G_24
6550x4D88 US_ALU_CONST_B_24
6560x4D8C US_ALU_CONST_A_24
6570x4D90 US_ALU_CONST_R_25
6580x4D94 US_ALU_CONST_G_25
6590x4D98 US_ALU_CONST_B_25
6600x4D9C US_ALU_CONST_A_25
6610x4DA0 US_ALU_CONST_R_26
6620x4DA4 US_ALU_CONST_G_26
6630x4DA8 US_ALU_CONST_B_26
6640x4DAC US_ALU_CONST_A_26
6650x4DB0 US_ALU_CONST_R_27
6660x4DB4 US_ALU_CONST_G_27
6670x4DB8 US_ALU_CONST_B_27
6680x4DBC US_ALU_CONST_A_27
6690x4DC0 US_ALU_CONST_R_28
6700x4DC4 US_ALU_CONST_G_28
6710x4DC8 US_ALU_CONST_B_28
6720x4DCC US_ALU_CONST_A_28
6730x4DD0 US_ALU_CONST_R_29
6740x4DD4 US_ALU_CONST_G_29
6750x4DD8 US_ALU_CONST_B_29
6760x4DDC US_ALU_CONST_A_29
6770x4DE0 US_ALU_CONST_R_30
6780x4DE4 US_ALU_CONST_G_30
6790x4DE8 US_ALU_CONST_B_30
6800x4DEC US_ALU_CONST_A_30
6810x4DF0 US_ALU_CONST_R_31
6820x4DF4 US_ALU_CONST_G_31
6830x4DF8 US_ALU_CONST_B_31
6840x4DFC US_ALU_CONST_A_31
6850x4E04 RB3D_BLENDCNTL_R3
6860x4E08 RB3D_ABLENDCNTL_R3
6870x4E0C RB3D_COLOR_CHANNEL_MASK
6880x4E10 RB3D_CONSTANT_COLOR
6890x4E14 RB3D_COLOR_CLEAR_VALUE
6900x4E18 RB3D_ROPCNTL_R3
6910x4E1C RB3D_CLRCMP_FLIPE_R3
6920x4E20 RB3D_CLRCMP_CLR_R3
6930x4E24 RB3D_CLRCMP_MSK_R3
6940x4E48 RB3D_DEBUG_CTL
6950x4E4C RB3D_DSTCACHE_CTLSTAT_R3
6960x4E50 RB3D_DITHER_CTL
6970x4E54 RB3D_CMASK_OFFSET0
6980x4E58 RB3D_CMASK_OFFSET1
6990x4E5C RB3D_CMASK_OFFSET2
7000x4E60 RB3D_CMASK_OFFSET3
7010x4E64 RB3D_CMASK_PITCH0
7020x4E68 RB3D_CMASK_PITCH1
7030x4E6C RB3D_CMASK_PITCH2
7040x4E70 RB3D_CMASK_PITCH3
7050x4E74 RB3D_CMASK_WRINDEX
7060x4E78 RB3D_CMASK_DWORD
7070x4E7C RB3D_CMASK_RDINDEX
7080x4E80 RB3D_AARESOLVE_OFFSET
7090x4E84 RB3D_AARESOLVE_PITCH
7100x4E88 RB3D_AARESOLVE_CTL
7110x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
7120x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
7130x4F04 ZB_ZSTENCILCNTL
7140x4F08 ZB_STENCILREFMASK
7150x4F14 ZB_ZTOP
7160x4F18 ZB_ZCACHE_CTLSTAT
7170x4F1C ZB_BW_CNTL
7180x4F28 ZB_DEPTHCLEARVALUE
7190x4F30 ZB_ZMASK_OFFSET
7200x4F34 ZB_ZMASK_PITCH
7210x4F38 ZB_ZMASK_WRINDEX
7220x4F3C ZB_ZMASK_DWORD
7230x4F40 ZB_ZMASK_RDINDEX
7240x4F44 ZB_HIZ_OFFSET
7250x4F48 ZB_HIZ_WRINDEX
7260x4F4C ZB_HIZ_DWORD
7270x4F50 ZB_HIZ_RDINDEX
7280x4F54 ZB_HIZ_PITCH
7290x4F58 ZB_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rn50 b/drivers/gpu/drm/radeon/reg_srcs/rn50
new file mode 100644
index 000000000000..2687b6307260
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rn50
@@ -0,0 +1,30 @@
1rn50 0x3294
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600
new file mode 100644
index 000000000000..8e3c0b807add
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rs600
@@ -0,0 +1,729 @@
1rs600 0x6d40
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
310x1D98 VAP_VPORT_XSCALE
320x1D9C VAP_VPORT_XOFFSET
330x1DA0 VAP_VPORT_YSCALE
340x1DA4 VAP_VPORT_YOFFSET
350x1DA8 VAP_VPORT_ZSCALE
360x1DAC VAP_VPORT_ZOFFSET
370x2080 VAP_CNTL
380x2090 VAP_OUT_VTX_FMT_0
390x2094 VAP_OUT_VTX_FMT_1
400x20B0 VAP_VTE_CNTL
410x2138 VAP_VF_MIN_VTX_INDX
420x2140 VAP_CNTL_STATUS
430x2150 VAP_PROG_STREAM_CNTL_0
440x2154 VAP_PROG_STREAM_CNTL_1
450x2158 VAP_PROG_STREAM_CNTL_2
460x215C VAP_PROG_STREAM_CNTL_3
470x2160 VAP_PROG_STREAM_CNTL_4
480x2164 VAP_PROG_STREAM_CNTL_5
490x2168 VAP_PROG_STREAM_CNTL_6
500x216C VAP_PROG_STREAM_CNTL_7
510x2180 VAP_VTX_STATE_CNTL
520x2184 VAP_VSM_VTX_ASSM
530x2188 VAP_VTX_STATE_IND_REG_0
540x218C VAP_VTX_STATE_IND_REG_1
550x2190 VAP_VTX_STATE_IND_REG_2
560x2194 VAP_VTX_STATE_IND_REG_3
570x2198 VAP_VTX_STATE_IND_REG_4
580x219C VAP_VTX_STATE_IND_REG_5
590x21A0 VAP_VTX_STATE_IND_REG_6
600x21A4 VAP_VTX_STATE_IND_REG_7
610x21A8 VAP_VTX_STATE_IND_REG_8
620x21AC VAP_VTX_STATE_IND_REG_9
630x21B0 VAP_VTX_STATE_IND_REG_10
640x21B4 VAP_VTX_STATE_IND_REG_11
650x21B8 VAP_VTX_STATE_IND_REG_12
660x21BC VAP_VTX_STATE_IND_REG_13
670x21C0 VAP_VTX_STATE_IND_REG_14
680x21C4 VAP_VTX_STATE_IND_REG_15
690x21DC VAP_PSC_SGN_NORM_CNTL
700x21E0 VAP_PROG_STREAM_CNTL_EXT_0
710x21E4 VAP_PROG_STREAM_CNTL_EXT_1
720x21E8 VAP_PROG_STREAM_CNTL_EXT_2
730x21EC VAP_PROG_STREAM_CNTL_EXT_3
740x21F0 VAP_PROG_STREAM_CNTL_EXT_4
750x21F4 VAP_PROG_STREAM_CNTL_EXT_5
760x21F8 VAP_PROG_STREAM_CNTL_EXT_6
770x21FC VAP_PROG_STREAM_CNTL_EXT_7
780x2200 VAP_PVS_VECTOR_INDX_REG
790x2204 VAP_PVS_VECTOR_DATA_REG
800x2208 VAP_PVS_VECTOR_DATA_REG_128
810x221C VAP_CLIP_CNTL
820x2220 VAP_GB_VERT_CLIP_ADJ
830x2224 VAP_GB_VERT_DISC_ADJ
840x2228 VAP_GB_HORZ_CLIP_ADJ
850x222C VAP_GB_HORZ_DISC_ADJ
860x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
870x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
880x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
890x223C VAP_PVS_FLOW_CNTL_ADDRS_3
900x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
910x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
920x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
930x224C VAP_PVS_FLOW_CNTL_ADDRS_7
940x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
950x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
960x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
970x225C VAP_PVS_FLOW_CNTL_ADDRS_11
980x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
990x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
1000x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
1010x226C VAP_PVS_FLOW_CNTL_ADDRS_15
1020x2284 VAP_PVS_STATE_FLUSH_REG
1030x2288 VAP_PVS_VTX_TIMEOUT_REG
1040x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
1050x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
1060x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
1070x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
1080x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
1090x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
1100x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
1110x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
1120x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
1130x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
1140x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
1150x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
1160x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
1170x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
1180x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
1190x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
1200x22D0 VAP_PVS_CODE_CNTL_0
1210x22D4 VAP_PVS_CONST_CNTL
1220x22D8 VAP_PVS_CODE_CNTL_1
1230x22DC VAP_PVS_FLOW_CNTL_OPC
1240x342C RB2D_DSTCACHE_CTLSTAT
1250x4000 GB_VAP_RASTER_VTX_FMT_0
1260x4004 GB_VAP_RASTER_VTX_FMT_1
1270x4008 GB_ENABLE
1280x401C GB_SELECT
1290x4020 GB_AA_CONFIG
1300x4024 GB_FIFO_SIZE
1310x4100 TX_INVALTAGS
1320x4200 GA_POINT_S0
1330x4204 GA_POINT_T0
1340x4208 GA_POINT_S1
1350x420C GA_POINT_T1
1360x4214 GA_TRIANGLE_STIPPLE
1370x421C GA_POINT_SIZE
1380x4230 GA_POINT_MINMAX
1390x4234 GA_LINE_CNTL
1400x4238 GA_LINE_STIPPLE_CONFIG
1410x4260 GA_LINE_STIPPLE_VALUE
1420x4264 GA_LINE_S0
1430x4268 GA_LINE_S1
1440x4278 GA_COLOR_CONTROL
1450x427C GA_SOLID_RG
1460x4280 GA_SOLID_BA
1470x4288 GA_POLY_MODE
1480x428C GA_ROUND_MODE
1490x4290 GA_OFFSET
1500x4294 GA_FOG_SCALE
1510x4298 GA_FOG_OFFSET
1520x42A0 SU_TEX_WRAP
1530x42A4 SU_POLY_OFFSET_FRONT_SCALE
1540x42A8 SU_POLY_OFFSET_FRONT_OFFSET
1550x42AC SU_POLY_OFFSET_BACK_SCALE
1560x42B0 SU_POLY_OFFSET_BACK_OFFSET
1570x42B4 SU_POLY_OFFSET_ENABLE
1580x42B8 SU_CULL_MODE
1590x42C0 SU_DEPTH_SCALE
1600x42C4 SU_DEPTH_OFFSET
1610x42C8 SU_REG_DEST
1620x4300 RS_COUNT
1630x4304 RS_INST_COUNT
1640x4310 RS_IP_0
1650x4314 RS_IP_1
1660x4318 RS_IP_2
1670x431C RS_IP_3
1680x4320 RS_IP_4
1690x4324 RS_IP_5
1700x4328 RS_IP_6
1710x432C RS_IP_7
1720x4330 RS_INST_0
1730x4334 RS_INST_1
1740x4338 RS_INST_2
1750x433C RS_INST_3
1760x4340 RS_INST_4
1770x4344 RS_INST_5
1780x4348 RS_INST_6
1790x434C RS_INST_7
1800x4350 RS_INST_8
1810x4354 RS_INST_9
1820x4358 RS_INST_10
1830x435C RS_INST_11
1840x4360 RS_INST_12
1850x4364 RS_INST_13
1860x4368 RS_INST_14
1870x436C RS_INST_15
1880x43A4 SC_HYPERZ_EN
1890x43A8 SC_EDGERULE
1900x43B0 SC_CLIP_0_A
1910x43B4 SC_CLIP_0_B
1920x43B8 SC_CLIP_1_A
1930x43BC SC_CLIP_1_B
1940x43C0 SC_CLIP_2_A
1950x43C4 SC_CLIP_2_B
1960x43C8 SC_CLIP_3_A
1970x43CC SC_CLIP_3_B
1980x43D0 SC_CLIP_RULE
1990x43E0 SC_SCISSOR0
2000x43E8 SC_SCREENDOOR
2010x4440 TX_FILTER1_0
2020x4444 TX_FILTER1_1
2030x4448 TX_FILTER1_2
2040x444C TX_FILTER1_3
2050x4450 TX_FILTER1_4
2060x4454 TX_FILTER1_5
2070x4458 TX_FILTER1_6
2080x445C TX_FILTER1_7
2090x4460 TX_FILTER1_8
2100x4464 TX_FILTER1_9
2110x4468 TX_FILTER1_10
2120x446C TX_FILTER1_11
2130x4470 TX_FILTER1_12
2140x4474 TX_FILTER1_13
2150x4478 TX_FILTER1_14
2160x447C TX_FILTER1_15
2170x4580 TX_CHROMA_KEY_0
2180x4584 TX_CHROMA_KEY_1
2190x4588 TX_CHROMA_KEY_2
2200x458C TX_CHROMA_KEY_3
2210x4590 TX_CHROMA_KEY_4
2220x4594 TX_CHROMA_KEY_5
2230x4598 TX_CHROMA_KEY_6
2240x459C TX_CHROMA_KEY_7
2250x45A0 TX_CHROMA_KEY_8
2260x45A4 TX_CHROMA_KEY_9
2270x45A8 TX_CHROMA_KEY_10
2280x45AC TX_CHROMA_KEY_11
2290x45B0 TX_CHROMA_KEY_12
2300x45B4 TX_CHROMA_KEY_13
2310x45B8 TX_CHROMA_KEY_14
2320x45BC TX_CHROMA_KEY_15
2330x45C0 TX_BORDER_COLOR_0
2340x45C4 TX_BORDER_COLOR_1
2350x45C8 TX_BORDER_COLOR_2
2360x45CC TX_BORDER_COLOR_3
2370x45D0 TX_BORDER_COLOR_4
2380x45D4 TX_BORDER_COLOR_5
2390x45D8 TX_BORDER_COLOR_6
2400x45DC TX_BORDER_COLOR_7
2410x45E0 TX_BORDER_COLOR_8
2420x45E4 TX_BORDER_COLOR_9
2430x45E8 TX_BORDER_COLOR_10
2440x45EC TX_BORDER_COLOR_11
2450x45F0 TX_BORDER_COLOR_12
2460x45F4 TX_BORDER_COLOR_13
2470x45F8 TX_BORDER_COLOR_14
2480x45FC TX_BORDER_COLOR_15
2490x4600 US_CONFIG
2500x4604 US_PIXSIZE
2510x4608 US_CODE_OFFSET
2520x460C US_RESET
2530x4610 US_CODE_ADDR_0
2540x4614 US_CODE_ADDR_1
2550x4618 US_CODE_ADDR_2
2560x461C US_CODE_ADDR_3
2570x4620 US_TEX_INST_0
2580x4624 US_TEX_INST_1
2590x4628 US_TEX_INST_2
2600x462C US_TEX_INST_3
2610x4630 US_TEX_INST_4
2620x4634 US_TEX_INST_5
2630x4638 US_TEX_INST_6
2640x463C US_TEX_INST_7
2650x4640 US_TEX_INST_8
2660x4644 US_TEX_INST_9
2670x4648 US_TEX_INST_10
2680x464C US_TEX_INST_11
2690x4650 US_TEX_INST_12
2700x4654 US_TEX_INST_13
2710x4658 US_TEX_INST_14
2720x465C US_TEX_INST_15
2730x4660 US_TEX_INST_16
2740x4664 US_TEX_INST_17
2750x4668 US_TEX_INST_18
2760x466C US_TEX_INST_19
2770x4670 US_TEX_INST_20
2780x4674 US_TEX_INST_21
2790x4678 US_TEX_INST_22
2800x467C US_TEX_INST_23
2810x4680 US_TEX_INST_24
2820x4684 US_TEX_INST_25
2830x4688 US_TEX_INST_26
2840x468C US_TEX_INST_27
2850x4690 US_TEX_INST_28
2860x4694 US_TEX_INST_29
2870x4698 US_TEX_INST_30
2880x469C US_TEX_INST_31
2890x46A4 US_OUT_FMT_0
2900x46A8 US_OUT_FMT_1
2910x46AC US_OUT_FMT_2
2920x46B0 US_OUT_FMT_3
2930x46B4 US_W_FMT
2940x46C0 US_ALU_RGB_ADDR_0
2950x46C4 US_ALU_RGB_ADDR_1
2960x46C8 US_ALU_RGB_ADDR_2
2970x46CC US_ALU_RGB_ADDR_3
2980x46D0 US_ALU_RGB_ADDR_4
2990x46D4 US_ALU_RGB_ADDR_5
3000x46D8 US_ALU_RGB_ADDR_6
3010x46DC US_ALU_RGB_ADDR_7
3020x46E0 US_ALU_RGB_ADDR_8
3030x46E4 US_ALU_RGB_ADDR_9
3040x46E8 US_ALU_RGB_ADDR_10
3050x46EC US_ALU_RGB_ADDR_11
3060x46F0 US_ALU_RGB_ADDR_12
3070x46F4 US_ALU_RGB_ADDR_13
3080x46F8 US_ALU_RGB_ADDR_14
3090x46FC US_ALU_RGB_ADDR_15
3100x4700 US_ALU_RGB_ADDR_16
3110x4704 US_ALU_RGB_ADDR_17
3120x4708 US_ALU_RGB_ADDR_18
3130x470C US_ALU_RGB_ADDR_19
3140x4710 US_ALU_RGB_ADDR_20
3150x4714 US_ALU_RGB_ADDR_21
3160x4718 US_ALU_RGB_ADDR_22
3170x471C US_ALU_RGB_ADDR_23
3180x4720 US_ALU_RGB_ADDR_24
3190x4724 US_ALU_RGB_ADDR_25
3200x4728 US_ALU_RGB_ADDR_26
3210x472C US_ALU_RGB_ADDR_27
3220x4730 US_ALU_RGB_ADDR_28
3230x4734 US_ALU_RGB_ADDR_29
3240x4738 US_ALU_RGB_ADDR_30
3250x473C US_ALU_RGB_ADDR_31
3260x4740 US_ALU_RGB_ADDR_32
3270x4744 US_ALU_RGB_ADDR_33
3280x4748 US_ALU_RGB_ADDR_34
3290x474C US_ALU_RGB_ADDR_35
3300x4750 US_ALU_RGB_ADDR_36
3310x4754 US_ALU_RGB_ADDR_37
3320x4758 US_ALU_RGB_ADDR_38
3330x475C US_ALU_RGB_ADDR_39
3340x4760 US_ALU_RGB_ADDR_40
3350x4764 US_ALU_RGB_ADDR_41
3360x4768 US_ALU_RGB_ADDR_42
3370x476C US_ALU_RGB_ADDR_43
3380x4770 US_ALU_RGB_ADDR_44
3390x4774 US_ALU_RGB_ADDR_45
3400x4778 US_ALU_RGB_ADDR_46
3410x477C US_ALU_RGB_ADDR_47
3420x4780 US_ALU_RGB_ADDR_48
3430x4784 US_ALU_RGB_ADDR_49
3440x4788 US_ALU_RGB_ADDR_50
3450x478C US_ALU_RGB_ADDR_51
3460x4790 US_ALU_RGB_ADDR_52
3470x4794 US_ALU_RGB_ADDR_53
3480x4798 US_ALU_RGB_ADDR_54
3490x479C US_ALU_RGB_ADDR_55
3500x47A0 US_ALU_RGB_ADDR_56
3510x47A4 US_ALU_RGB_ADDR_57
3520x47A8 US_ALU_RGB_ADDR_58
3530x47AC US_ALU_RGB_ADDR_59
3540x47B0 US_ALU_RGB_ADDR_60
3550x47B4 US_ALU_RGB_ADDR_61
3560x47B8 US_ALU_RGB_ADDR_62
3570x47BC US_ALU_RGB_ADDR_63
3580x47C0 US_ALU_ALPHA_ADDR_0
3590x47C4 US_ALU_ALPHA_ADDR_1
3600x47C8 US_ALU_ALPHA_ADDR_2
3610x47CC US_ALU_ALPHA_ADDR_3
3620x47D0 US_ALU_ALPHA_ADDR_4
3630x47D4 US_ALU_ALPHA_ADDR_5
3640x47D8 US_ALU_ALPHA_ADDR_6
3650x47DC US_ALU_ALPHA_ADDR_7
3660x47E0 US_ALU_ALPHA_ADDR_8
3670x47E4 US_ALU_ALPHA_ADDR_9
3680x47E8 US_ALU_ALPHA_ADDR_10
3690x47EC US_ALU_ALPHA_ADDR_11
3700x47F0 US_ALU_ALPHA_ADDR_12
3710x47F4 US_ALU_ALPHA_ADDR_13
3720x47F8 US_ALU_ALPHA_ADDR_14
3730x47FC US_ALU_ALPHA_ADDR_15
3740x4800 US_ALU_ALPHA_ADDR_16
3750x4804 US_ALU_ALPHA_ADDR_17
3760x4808 US_ALU_ALPHA_ADDR_18
3770x480C US_ALU_ALPHA_ADDR_19
3780x4810 US_ALU_ALPHA_ADDR_20
3790x4814 US_ALU_ALPHA_ADDR_21
3800x4818 US_ALU_ALPHA_ADDR_22
3810x481C US_ALU_ALPHA_ADDR_23
3820x4820 US_ALU_ALPHA_ADDR_24
3830x4824 US_ALU_ALPHA_ADDR_25
3840x4828 US_ALU_ALPHA_ADDR_26
3850x482C US_ALU_ALPHA_ADDR_27
3860x4830 US_ALU_ALPHA_ADDR_28
3870x4834 US_ALU_ALPHA_ADDR_29
3880x4838 US_ALU_ALPHA_ADDR_30
3890x483C US_ALU_ALPHA_ADDR_31
3900x4840 US_ALU_ALPHA_ADDR_32
3910x4844 US_ALU_ALPHA_ADDR_33
3920x4848 US_ALU_ALPHA_ADDR_34
3930x484C US_ALU_ALPHA_ADDR_35
3940x4850 US_ALU_ALPHA_ADDR_36
3950x4854 US_ALU_ALPHA_ADDR_37
3960x4858 US_ALU_ALPHA_ADDR_38
3970x485C US_ALU_ALPHA_ADDR_39
3980x4860 US_ALU_ALPHA_ADDR_40
3990x4864 US_ALU_ALPHA_ADDR_41
4000x4868 US_ALU_ALPHA_ADDR_42
4010x486C US_ALU_ALPHA_ADDR_43
4020x4870 US_ALU_ALPHA_ADDR_44
4030x4874 US_ALU_ALPHA_ADDR_45
4040x4878 US_ALU_ALPHA_ADDR_46
4050x487C US_ALU_ALPHA_ADDR_47
4060x4880 US_ALU_ALPHA_ADDR_48
4070x4884 US_ALU_ALPHA_ADDR_49
4080x4888 US_ALU_ALPHA_ADDR_50
4090x488C US_ALU_ALPHA_ADDR_51
4100x4890 US_ALU_ALPHA_ADDR_52
4110x4894 US_ALU_ALPHA_ADDR_53
4120x4898 US_ALU_ALPHA_ADDR_54
4130x489C US_ALU_ALPHA_ADDR_55
4140x48A0 US_ALU_ALPHA_ADDR_56
4150x48A4 US_ALU_ALPHA_ADDR_57
4160x48A8 US_ALU_ALPHA_ADDR_58
4170x48AC US_ALU_ALPHA_ADDR_59
4180x48B0 US_ALU_ALPHA_ADDR_60
4190x48B4 US_ALU_ALPHA_ADDR_61
4200x48B8 US_ALU_ALPHA_ADDR_62
4210x48BC US_ALU_ALPHA_ADDR_63
4220x48C0 US_ALU_RGB_INST_0
4230x48C4 US_ALU_RGB_INST_1
4240x48C8 US_ALU_RGB_INST_2
4250x48CC US_ALU_RGB_INST_3
4260x48D0 US_ALU_RGB_INST_4
4270x48D4 US_ALU_RGB_INST_5
4280x48D8 US_ALU_RGB_INST_6
4290x48DC US_ALU_RGB_INST_7
4300x48E0 US_ALU_RGB_INST_8
4310x48E4 US_ALU_RGB_INST_9
4320x48E8 US_ALU_RGB_INST_10
4330x48EC US_ALU_RGB_INST_11
4340x48F0 US_ALU_RGB_INST_12
4350x48F4 US_ALU_RGB_INST_13
4360x48F8 US_ALU_RGB_INST_14
4370x48FC US_ALU_RGB_INST_15
4380x4900 US_ALU_RGB_INST_16
4390x4904 US_ALU_RGB_INST_17
4400x4908 US_ALU_RGB_INST_18
4410x490C US_ALU_RGB_INST_19
4420x4910 US_ALU_RGB_INST_20
4430x4914 US_ALU_RGB_INST_21
4440x4918 US_ALU_RGB_INST_22
4450x491C US_ALU_RGB_INST_23
4460x4920 US_ALU_RGB_INST_24
4470x4924 US_ALU_RGB_INST_25
4480x4928 US_ALU_RGB_INST_26
4490x492C US_ALU_RGB_INST_27
4500x4930 US_ALU_RGB_INST_28
4510x4934 US_ALU_RGB_INST_29
4520x4938 US_ALU_RGB_INST_30
4530x493C US_ALU_RGB_INST_31
4540x4940 US_ALU_RGB_INST_32
4550x4944 US_ALU_RGB_INST_33
4560x4948 US_ALU_RGB_INST_34
4570x494C US_ALU_RGB_INST_35
4580x4950 US_ALU_RGB_INST_36
4590x4954 US_ALU_RGB_INST_37
4600x4958 US_ALU_RGB_INST_38
4610x495C US_ALU_RGB_INST_39
4620x4960 US_ALU_RGB_INST_40
4630x4964 US_ALU_RGB_INST_41
4640x4968 US_ALU_RGB_INST_42
4650x496C US_ALU_RGB_INST_43
4660x4970 US_ALU_RGB_INST_44
4670x4974 US_ALU_RGB_INST_45
4680x4978 US_ALU_RGB_INST_46
4690x497C US_ALU_RGB_INST_47
4700x4980 US_ALU_RGB_INST_48
4710x4984 US_ALU_RGB_INST_49
4720x4988 US_ALU_RGB_INST_50
4730x498C US_ALU_RGB_INST_51
4740x4990 US_ALU_RGB_INST_52
4750x4994 US_ALU_RGB_INST_53
4760x4998 US_ALU_RGB_INST_54
4770x499C US_ALU_RGB_INST_55
4780x49A0 US_ALU_RGB_INST_56
4790x49A4 US_ALU_RGB_INST_57
4800x49A8 US_ALU_RGB_INST_58
4810x49AC US_ALU_RGB_INST_59
4820x49B0 US_ALU_RGB_INST_60
4830x49B4 US_ALU_RGB_INST_61
4840x49B8 US_ALU_RGB_INST_62
4850x49BC US_ALU_RGB_INST_63
4860x49C0 US_ALU_ALPHA_INST_0
4870x49C4 US_ALU_ALPHA_INST_1
4880x49C8 US_ALU_ALPHA_INST_2
4890x49CC US_ALU_ALPHA_INST_3
4900x49D0 US_ALU_ALPHA_INST_4
4910x49D4 US_ALU_ALPHA_INST_5
4920x49D8 US_ALU_ALPHA_INST_6
4930x49DC US_ALU_ALPHA_INST_7
4940x49E0 US_ALU_ALPHA_INST_8
4950x49E4 US_ALU_ALPHA_INST_9
4960x49E8 US_ALU_ALPHA_INST_10
4970x49EC US_ALU_ALPHA_INST_11
4980x49F0 US_ALU_ALPHA_INST_12
4990x49F4 US_ALU_ALPHA_INST_13
5000x49F8 US_ALU_ALPHA_INST_14
5010x49FC US_ALU_ALPHA_INST_15
5020x4A00 US_ALU_ALPHA_INST_16
5030x4A04 US_ALU_ALPHA_INST_17
5040x4A08 US_ALU_ALPHA_INST_18
5050x4A0C US_ALU_ALPHA_INST_19
5060x4A10 US_ALU_ALPHA_INST_20
5070x4A14 US_ALU_ALPHA_INST_21
5080x4A18 US_ALU_ALPHA_INST_22
5090x4A1C US_ALU_ALPHA_INST_23
5100x4A20 US_ALU_ALPHA_INST_24
5110x4A24 US_ALU_ALPHA_INST_25
5120x4A28 US_ALU_ALPHA_INST_26
5130x4A2C US_ALU_ALPHA_INST_27
5140x4A30 US_ALU_ALPHA_INST_28
5150x4A34 US_ALU_ALPHA_INST_29
5160x4A38 US_ALU_ALPHA_INST_30
5170x4A3C US_ALU_ALPHA_INST_31
5180x4A40 US_ALU_ALPHA_INST_32
5190x4A44 US_ALU_ALPHA_INST_33
5200x4A48 US_ALU_ALPHA_INST_34
5210x4A4C US_ALU_ALPHA_INST_35
5220x4A50 US_ALU_ALPHA_INST_36
5230x4A54 US_ALU_ALPHA_INST_37
5240x4A58 US_ALU_ALPHA_INST_38
5250x4A5C US_ALU_ALPHA_INST_39
5260x4A60 US_ALU_ALPHA_INST_40
5270x4A64 US_ALU_ALPHA_INST_41
5280x4A68 US_ALU_ALPHA_INST_42
5290x4A6C US_ALU_ALPHA_INST_43
5300x4A70 US_ALU_ALPHA_INST_44
5310x4A74 US_ALU_ALPHA_INST_45
5320x4A78 US_ALU_ALPHA_INST_46
5330x4A7C US_ALU_ALPHA_INST_47
5340x4A80 US_ALU_ALPHA_INST_48
5350x4A84 US_ALU_ALPHA_INST_49
5360x4A88 US_ALU_ALPHA_INST_50
5370x4A8C US_ALU_ALPHA_INST_51
5380x4A90 US_ALU_ALPHA_INST_52
5390x4A94 US_ALU_ALPHA_INST_53
5400x4A98 US_ALU_ALPHA_INST_54
5410x4A9C US_ALU_ALPHA_INST_55
5420x4AA0 US_ALU_ALPHA_INST_56
5430x4AA4 US_ALU_ALPHA_INST_57
5440x4AA8 US_ALU_ALPHA_INST_58
5450x4AAC US_ALU_ALPHA_INST_59
5460x4AB0 US_ALU_ALPHA_INST_60
5470x4AB4 US_ALU_ALPHA_INST_61
5480x4AB8 US_ALU_ALPHA_INST_62
5490x4ABC US_ALU_ALPHA_INST_63
5500x4BC0 FG_FOG_BLEND
5510x4BC4 FG_FOG_FACTOR
5520x4BC8 FG_FOG_COLOR_R
5530x4BCC FG_FOG_COLOR_G
5540x4BD0 FG_FOG_COLOR_B
5550x4BD4 FG_ALPHA_FUNC
5560x4BD8 FG_DEPTH_SRC
5570x4C00 US_ALU_CONST_R_0
5580x4C04 US_ALU_CONST_G_0
5590x4C08 US_ALU_CONST_B_0
5600x4C0C US_ALU_CONST_A_0
5610x4C10 US_ALU_CONST_R_1
5620x4C14 US_ALU_CONST_G_1
5630x4C18 US_ALU_CONST_B_1
5640x4C1C US_ALU_CONST_A_1
5650x4C20 US_ALU_CONST_R_2
5660x4C24 US_ALU_CONST_G_2
5670x4C28 US_ALU_CONST_B_2
5680x4C2C US_ALU_CONST_A_2
5690x4C30 US_ALU_CONST_R_3
5700x4C34 US_ALU_CONST_G_3
5710x4C38 US_ALU_CONST_B_3
5720x4C3C US_ALU_CONST_A_3
5730x4C40 US_ALU_CONST_R_4
5740x4C44 US_ALU_CONST_G_4
5750x4C48 US_ALU_CONST_B_4
5760x4C4C US_ALU_CONST_A_4
5770x4C50 US_ALU_CONST_R_5
5780x4C54 US_ALU_CONST_G_5
5790x4C58 US_ALU_CONST_B_5
5800x4C5C US_ALU_CONST_A_5
5810x4C60 US_ALU_CONST_R_6
5820x4C64 US_ALU_CONST_G_6
5830x4C68 US_ALU_CONST_B_6
5840x4C6C US_ALU_CONST_A_6
5850x4C70 US_ALU_CONST_R_7
5860x4C74 US_ALU_CONST_G_7
5870x4C78 US_ALU_CONST_B_7
5880x4C7C US_ALU_CONST_A_7
5890x4C80 US_ALU_CONST_R_8
5900x4C84 US_ALU_CONST_G_8
5910x4C88 US_ALU_CONST_B_8
5920x4C8C US_ALU_CONST_A_8
5930x4C90 US_ALU_CONST_R_9
5940x4C94 US_ALU_CONST_G_9
5950x4C98 US_ALU_CONST_B_9
5960x4C9C US_ALU_CONST_A_9
5970x4CA0 US_ALU_CONST_R_10
5980x4CA4 US_ALU_CONST_G_10
5990x4CA8 US_ALU_CONST_B_10
6000x4CAC US_ALU_CONST_A_10
6010x4CB0 US_ALU_CONST_R_11
6020x4CB4 US_ALU_CONST_G_11
6030x4CB8 US_ALU_CONST_B_11
6040x4CBC US_ALU_CONST_A_11
6050x4CC0 US_ALU_CONST_R_12
6060x4CC4 US_ALU_CONST_G_12
6070x4CC8 US_ALU_CONST_B_12
6080x4CCC US_ALU_CONST_A_12
6090x4CD0 US_ALU_CONST_R_13
6100x4CD4 US_ALU_CONST_G_13
6110x4CD8 US_ALU_CONST_B_13
6120x4CDC US_ALU_CONST_A_13
6130x4CE0 US_ALU_CONST_R_14
6140x4CE4 US_ALU_CONST_G_14
6150x4CE8 US_ALU_CONST_B_14
6160x4CEC US_ALU_CONST_A_14
6170x4CF0 US_ALU_CONST_R_15
6180x4CF4 US_ALU_CONST_G_15
6190x4CF8 US_ALU_CONST_B_15
6200x4CFC US_ALU_CONST_A_15
6210x4D00 US_ALU_CONST_R_16
6220x4D04 US_ALU_CONST_G_16
6230x4D08 US_ALU_CONST_B_16
6240x4D0C US_ALU_CONST_A_16
6250x4D10 US_ALU_CONST_R_17
6260x4D14 US_ALU_CONST_G_17
6270x4D18 US_ALU_CONST_B_17
6280x4D1C US_ALU_CONST_A_17
6290x4D20 US_ALU_CONST_R_18
6300x4D24 US_ALU_CONST_G_18
6310x4D28 US_ALU_CONST_B_18
6320x4D2C US_ALU_CONST_A_18
6330x4D30 US_ALU_CONST_R_19
6340x4D34 US_ALU_CONST_G_19
6350x4D38 US_ALU_CONST_B_19
6360x4D3C US_ALU_CONST_A_19
6370x4D40 US_ALU_CONST_R_20
6380x4D44 US_ALU_CONST_G_20
6390x4D48 US_ALU_CONST_B_20
6400x4D4C US_ALU_CONST_A_20
6410x4D50 US_ALU_CONST_R_21
6420x4D54 US_ALU_CONST_G_21
6430x4D58 US_ALU_CONST_B_21
6440x4D5C US_ALU_CONST_A_21
6450x4D60 US_ALU_CONST_R_22
6460x4D64 US_ALU_CONST_G_22
6470x4D68 US_ALU_CONST_B_22
6480x4D6C US_ALU_CONST_A_22
6490x4D70 US_ALU_CONST_R_23
6500x4D74 US_ALU_CONST_G_23
6510x4D78 US_ALU_CONST_B_23
6520x4D7C US_ALU_CONST_A_23
6530x4D80 US_ALU_CONST_R_24
6540x4D84 US_ALU_CONST_G_24
6550x4D88 US_ALU_CONST_B_24
6560x4D8C US_ALU_CONST_A_24
6570x4D90 US_ALU_CONST_R_25
6580x4D94 US_ALU_CONST_G_25
6590x4D98 US_ALU_CONST_B_25
6600x4D9C US_ALU_CONST_A_25
6610x4DA0 US_ALU_CONST_R_26
6620x4DA4 US_ALU_CONST_G_26
6630x4DA8 US_ALU_CONST_B_26
6640x4DAC US_ALU_CONST_A_26
6650x4DB0 US_ALU_CONST_R_27
6660x4DB4 US_ALU_CONST_G_27
6670x4DB8 US_ALU_CONST_B_27
6680x4DBC US_ALU_CONST_A_27
6690x4DC0 US_ALU_CONST_R_28
6700x4DC4 US_ALU_CONST_G_28
6710x4DC8 US_ALU_CONST_B_28
6720x4DCC US_ALU_CONST_A_28
6730x4DD0 US_ALU_CONST_R_29
6740x4DD4 US_ALU_CONST_G_29
6750x4DD8 US_ALU_CONST_B_29
6760x4DDC US_ALU_CONST_A_29
6770x4DE0 US_ALU_CONST_R_30
6780x4DE4 US_ALU_CONST_G_30
6790x4DE8 US_ALU_CONST_B_30
6800x4DEC US_ALU_CONST_A_30
6810x4DF0 US_ALU_CONST_R_31
6820x4DF4 US_ALU_CONST_G_31
6830x4DF8 US_ALU_CONST_B_31
6840x4DFC US_ALU_CONST_A_31
6850x4E04 RB3D_BLENDCNTL_R3
6860x4E08 RB3D_ABLENDCNTL_R3
6870x4E0C RB3D_COLOR_CHANNEL_MASK
6880x4E10 RB3D_CONSTANT_COLOR
6890x4E14 RB3D_COLOR_CLEAR_VALUE
6900x4E18 RB3D_ROPCNTL_R3
6910x4E1C RB3D_CLRCMP_FLIPE_R3
6920x4E20 RB3D_CLRCMP_CLR_R3
6930x4E24 RB3D_CLRCMP_MSK_R3
6940x4E48 RB3D_DEBUG_CTL
6950x4E4C RB3D_DSTCACHE_CTLSTAT_R3
6960x4E50 RB3D_DITHER_CTL
6970x4E54 RB3D_CMASK_OFFSET0
6980x4E58 RB3D_CMASK_OFFSET1
6990x4E5C RB3D_CMASK_OFFSET2
7000x4E60 RB3D_CMASK_OFFSET3
7010x4E64 RB3D_CMASK_PITCH0
7020x4E68 RB3D_CMASK_PITCH1
7030x4E6C RB3D_CMASK_PITCH2
7040x4E70 RB3D_CMASK_PITCH3
7050x4E74 RB3D_CMASK_WRINDEX
7060x4E78 RB3D_CMASK_DWORD
7070x4E7C RB3D_CMASK_RDINDEX
7080x4E80 RB3D_AARESOLVE_OFFSET
7090x4E84 RB3D_AARESOLVE_PITCH
7100x4E88 RB3D_AARESOLVE_CTL
7110x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
7120x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
7130x4F04 ZB_ZSTENCILCNTL
7140x4F08 ZB_STENCILREFMASK
7150x4F14 ZB_ZTOP
7160x4F18 ZB_ZCACHE_CTLSTAT
7170x4F1C ZB_BW_CNTL
7180x4F28 ZB_DEPTHCLEARVALUE
7190x4F30 ZB_ZMASK_OFFSET
7200x4F34 ZB_ZMASK_PITCH
7210x4F38 ZB_ZMASK_WRINDEX
7220x4F3C ZB_ZMASK_DWORD
7230x4F40 ZB_ZMASK_RDINDEX
7240x4F44 ZB_HIZ_OFFSET
7250x4F48 ZB_HIZ_WRINDEX
7260x4F4C ZB_HIZ_DWORD
7270x4F50 ZB_HIZ_RDINDEX
7280x4F54 ZB_HIZ_PITCH
7290x4F58 ZB_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515
new file mode 100644
index 000000000000..0102a0d5735c
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rv515
@@ -0,0 +1,486 @@
1rv515 0x6d40
20x1434 SRC_Y_X
30x1438 DST_Y_X
40x143C DST_HEIGHT_WIDTH
50x146C DP_GUI_MASTER_CNTL
60x1474 BRUSH_Y_X
70x1478 DP_BRUSH_BKGD_CLR
80x147C DP_BRUSH_FRGD_CLR
90x1480 BRUSH_DATA0
100x1484 BRUSH_DATA1
110x1598 DST_WIDTH_HEIGHT
120x15C0 CLR_CMP_CNTL
130x15C4 CLR_CMP_CLR_SRC
140x15C8 CLR_CMP_CLR_DST
150x15CC CLR_CMP_MSK
160x15D8 DP_SRC_FRGD_CLR
170x15DC DP_SRC_BKGD_CLR
180x1600 DST_LINE_START
190x1604 DST_LINE_END
200x1608 DST_LINE_PATCOUNT
210x16C0 DP_CNTL
220x16CC DP_WRITE_MSK
230x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
240x16E8 DEFAULT_SC_BOTTOM_RIGHT
250x16EC SC_TOP_LEFT
260x16F0 SC_BOTTOM_RIGHT
270x16F4 SRC_SC_BOTTOM_RIGHT
280x1714 DSTCACHE_CTLSTAT
290x1720 WAIT_UNTIL
300x172C RBBM_GUICNTL
310x1D98 VAP_VPORT_XSCALE
320x1D9C VAP_VPORT_XOFFSET
330x1DA0 VAP_VPORT_YSCALE
340x1DA4 VAP_VPORT_YOFFSET
350x1DA8 VAP_VPORT_ZSCALE
360x1DAC VAP_VPORT_ZOFFSET
370x2080 VAP_CNTL
380x2090 VAP_OUT_VTX_FMT_0
390x2094 VAP_OUT_VTX_FMT_1
400x20B0 VAP_VTE_CNTL
410x2138 VAP_VF_MIN_VTX_INDX
420x2140 VAP_CNTL_STATUS
430x2150 VAP_PROG_STREAM_CNTL_0
440x2154 VAP_PROG_STREAM_CNTL_1
450x2158 VAP_PROG_STREAM_CNTL_2
460x215C VAP_PROG_STREAM_CNTL_3
470x2160 VAP_PROG_STREAM_CNTL_4
480x2164 VAP_PROG_STREAM_CNTL_5
490x2168 VAP_PROG_STREAM_CNTL_6
500x216C VAP_PROG_STREAM_CNTL_7
510x2180 VAP_VTX_STATE_CNTL
520x2184 VAP_VSM_VTX_ASSM
530x2188 VAP_VTX_STATE_IND_REG_0
540x218C VAP_VTX_STATE_IND_REG_1
550x2190 VAP_VTX_STATE_IND_REG_2
560x2194 VAP_VTX_STATE_IND_REG_3
570x2198 VAP_VTX_STATE_IND_REG_4
580x219C VAP_VTX_STATE_IND_REG_5
590x21A0 VAP_VTX_STATE_IND_REG_6
600x21A4 VAP_VTX_STATE_IND_REG_7
610x21A8 VAP_VTX_STATE_IND_REG_8
620x21AC VAP_VTX_STATE_IND_REG_9
630x21B0 VAP_VTX_STATE_IND_REG_10
640x21B4 VAP_VTX_STATE_IND_REG_11
650x21B8 VAP_VTX_STATE_IND_REG_12
660x21BC VAP_VTX_STATE_IND_REG_13
670x21C0 VAP_VTX_STATE_IND_REG_14
680x21C4 VAP_VTX_STATE_IND_REG_15
690x21DC VAP_PSC_SGN_NORM_CNTL
700x21E0 VAP_PROG_STREAM_CNTL_EXT_0
710x21E4 VAP_PROG_STREAM_CNTL_EXT_1
720x21E8 VAP_PROG_STREAM_CNTL_EXT_2
730x21EC VAP_PROG_STREAM_CNTL_EXT_3
740x21F0 VAP_PROG_STREAM_CNTL_EXT_4
750x21F4 VAP_PROG_STREAM_CNTL_EXT_5
760x21F8 VAP_PROG_STREAM_CNTL_EXT_6
770x21FC VAP_PROG_STREAM_CNTL_EXT_7
780x2200 VAP_PVS_VECTOR_INDX_REG
790x2204 VAP_PVS_VECTOR_DATA_REG
800x2208 VAP_PVS_VECTOR_DATA_REG_128
810x2218 VAP_TEX_TO_COLOR_CNTL
820x221C VAP_CLIP_CNTL
830x2220 VAP_GB_VERT_CLIP_ADJ
840x2224 VAP_GB_VERT_DISC_ADJ
850x2228 VAP_GB_HORZ_CLIP_ADJ
860x222C VAP_GB_HORZ_DISC_ADJ
870x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
880x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
890x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
900x223C VAP_PVS_FLOW_CNTL_ADDRS_3
910x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
920x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
930x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
940x224C VAP_PVS_FLOW_CNTL_ADDRS_7
950x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
960x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
970x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
980x225C VAP_PVS_FLOW_CNTL_ADDRS_11
990x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
1000x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
1010x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
1020x226C VAP_PVS_FLOW_CNTL_ADDRS_15
1030x2284 VAP_PVS_STATE_FLUSH_REG
1040x2288 VAP_PVS_VTX_TIMEOUT_REG
1050x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
1060x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
1070x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
1080x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
1090x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
1100x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
1110x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
1120x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
1130x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
1140x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
1150x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
1160x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
1170x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
1180x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
1190x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
1200x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
1210x22D0 VAP_PVS_CODE_CNTL_0
1220x22D4 VAP_PVS_CONST_CNTL
1230x22D8 VAP_PVS_CODE_CNTL_1
1240x22DC VAP_PVS_FLOW_CNTL_OPC
1250x2500 VAP_PVS_FLOW_CNTL_ADDRS_LW_0
1260x2504 VAP_PVS_FLOW_CNTL_ADDRS_UW_0
1270x2508 VAP_PVS_FLOW_CNTL_ADDRS_LW_1
1280x250C VAP_PVS_FLOW_CNTL_ADDRS_UW_1
1290x2510 VAP_PVS_FLOW_CNTL_ADDRS_LW_2
1300x2514 VAP_PVS_FLOW_CNTL_ADDRS_UW_2
1310x2518 VAP_PVS_FLOW_CNTL_ADDRS_LW_3
1320x251C VAP_PVS_FLOW_CNTL_ADDRS_UW_3
1330x2520 VAP_PVS_FLOW_CNTL_ADDRS_LW_4
1340x2524 VAP_PVS_FLOW_CNTL_ADDRS_UW_4
1350x2528 VAP_PVS_FLOW_CNTL_ADDRS_LW_5
1360x252C VAP_PVS_FLOW_CNTL_ADDRS_UW_5
1370x2530 VAP_PVS_FLOW_CNTL_ADDRS_LW_6
1380x2534 VAP_PVS_FLOW_CNTL_ADDRS_UW_6
1390x2538 VAP_PVS_FLOW_CNTL_ADDRS_LW_7
1400x253C VAP_PVS_FLOW_CNTL_ADDRS_UW_7
1410x2540 VAP_PVS_FLOW_CNTL_ADDRS_LW_8
1420x2544 VAP_PVS_FLOW_CNTL_ADDRS_UW_8
1430x2548 VAP_PVS_FLOW_CNTL_ADDRS_LW_9
1440x254C VAP_PVS_FLOW_CNTL_ADDRS_UW_9
1450x2550 VAP_PVS_FLOW_CNTL_ADDRS_LW_10
1460x2554 VAP_PVS_FLOW_CNTL_ADDRS_UW_10
1470x2558 VAP_PVS_FLOW_CNTL_ADDRS_LW_11
1480x255C VAP_PVS_FLOW_CNTL_ADDRS_UW_11
1490x2560 VAP_PVS_FLOW_CNTL_ADDRS_LW_12
1500x2564 VAP_PVS_FLOW_CNTL_ADDRS_UW_12
1510x2568 VAP_PVS_FLOW_CNTL_ADDRS_LW_13
1520x256C VAP_PVS_FLOW_CNTL_ADDRS_UW_13
1530x2570 VAP_PVS_FLOW_CNTL_ADDRS_LW_14
1540x2574 VAP_PVS_FLOW_CNTL_ADDRS_UW_14
1550x2578 VAP_PVS_FLOW_CNTL_ADDRS_LW_15
1560x257C VAP_PVS_FLOW_CNTL_ADDRS_UW_15
1570x342C RB2D_DSTCACHE_CTLSTAT
1580x4000 GB_VAP_RASTER_VTX_FMT_0
1590x4004 GB_VAP_RASTER_VTX_FMT_1
1600x4008 GB_ENABLE
1610x401C GB_SELECT
1620x4020 GB_AA_CONFIG
1630x4024 GB_FIFO_SIZE
1640x4100 TX_INVALTAGS
1650x4200 GA_POINT_S0
1660x4204 GA_POINT_T0
1670x4208 GA_POINT_S1
1680x420C GA_POINT_T1
1690x4214 GA_TRIANGLE_STIPPLE
1700x421C GA_POINT_SIZE
1710x4230 GA_POINT_MINMAX
1720x4234 GA_LINE_CNTL
1730x4238 GA_LINE_STIPPLE_CONFIG
1740x4260 GA_LINE_STIPPLE_VALUE
1750x4264 GA_LINE_S0
1760x4268 GA_LINE_S1
1770x4278 GA_COLOR_CONTROL
1780x427C GA_SOLID_RG
1790x4280 GA_SOLID_BA
1800x4288 GA_POLY_MODE
1810x428C GA_ROUND_MODE
1820x4290 GA_OFFSET
1830x4294 GA_FOG_SCALE
1840x4298 GA_FOG_OFFSET
1850x42A0 SU_TEX_WRAP
1860x42A4 SU_POLY_OFFSET_FRONT_SCALE
1870x42A8 SU_POLY_OFFSET_FRONT_OFFSET
1880x42AC SU_POLY_OFFSET_BACK_SCALE
1890x42B0 SU_POLY_OFFSET_BACK_OFFSET
1900x42B4 SU_POLY_OFFSET_ENABLE
1910x42B8 SU_CULL_MODE
1920x42C0 SU_DEPTH_SCALE
1930x42C4 SU_DEPTH_OFFSET
1940x42C8 SU_REG_DEST
1950x4300 RS_COUNT
1960x4304 RS_INST_COUNT
1970x4074 RS_IP_0
1980x4078 RS_IP_1
1990x407C RS_IP_2
2000x4080 RS_IP_3
2010x4084 RS_IP_4
2020x4088 RS_IP_5
2030x408C RS_IP_6
2040x4090 RS_IP_7
2050x4094 RS_IP_8
2060x4098 RS_IP_9
2070x409C RS_IP_10
2080x40A0 RS_IP_11
2090x40A4 RS_IP_12
2100x40A8 RS_IP_13
2110x40AC RS_IP_14
2120x40B0 RS_IP_15
2130x4320 RS_INST_0
2140x4324 RS_INST_1
2150x4328 RS_INST_2
2160x432C RS_INST_3
2170x4330 RS_INST_4
2180x4334 RS_INST_5
2190x4338 RS_INST_6
2200x433C RS_INST_7
2210x4340 RS_INST_8
2220x4344 RS_INST_9
2230x4348 RS_INST_10
2240x434C RS_INST_11
2250x4350 RS_INST_12
2260x4354 RS_INST_13
2270x4358 RS_INST_14
2280x435C RS_INST_15
2290x43A4 SC_HYPERZ_EN
2300x43A8 SC_EDGERULE
2310x43B0 SC_CLIP_0_A
2320x43B4 SC_CLIP_0_B
2330x43B8 SC_CLIP_1_A
2340x43BC SC_CLIP_1_B
2350x43C0 SC_CLIP_2_A
2360x43C4 SC_CLIP_2_B
2370x43C8 SC_CLIP_3_A
2380x43CC SC_CLIP_3_B
2390x43D0 SC_CLIP_RULE
2400x43E0 SC_SCISSOR0
2410x43E8 SC_SCREENDOOR
2420x4440 TX_FILTER1_0
2430x4444 TX_FILTER1_1
2440x4448 TX_FILTER1_2
2450x444C TX_FILTER1_3
2460x4450 TX_FILTER1_4
2470x4454 TX_FILTER1_5
2480x4458 TX_FILTER1_6
2490x445C TX_FILTER1_7
2500x4460 TX_FILTER1_8
2510x4464 TX_FILTER1_9
2520x4468 TX_FILTER1_10
2530x446C TX_FILTER1_11
2540x4470 TX_FILTER1_12
2550x4474 TX_FILTER1_13
2560x4478 TX_FILTER1_14
2570x447C TX_FILTER1_15
2580x4580 TX_CHROMA_KEY_0
2590x4584 TX_CHROMA_KEY_1
2600x4588 TX_CHROMA_KEY_2
2610x458C TX_CHROMA_KEY_3
2620x4590 TX_CHROMA_KEY_4
2630x4594 TX_CHROMA_KEY_5
2640x4598 TX_CHROMA_KEY_6
2650x459C TX_CHROMA_KEY_7
2660x45A0 TX_CHROMA_KEY_8
2670x45A4 TX_CHROMA_KEY_9
2680x45A8 TX_CHROMA_KEY_10
2690x45AC TX_CHROMA_KEY_11
2700x45B0 TX_CHROMA_KEY_12
2710x45B4 TX_CHROMA_KEY_13
2720x45B8 TX_CHROMA_KEY_14
2730x45BC TX_CHROMA_KEY_15
2740x45C0 TX_BORDER_COLOR_0
2750x45C4 TX_BORDER_COLOR_1
2760x45C8 TX_BORDER_COLOR_2
2770x45CC TX_BORDER_COLOR_3
2780x45D0 TX_BORDER_COLOR_4
2790x45D4 TX_BORDER_COLOR_5
2800x45D8 TX_BORDER_COLOR_6
2810x45DC TX_BORDER_COLOR_7
2820x45E0 TX_BORDER_COLOR_8
2830x45E4 TX_BORDER_COLOR_9
2840x45E8 TX_BORDER_COLOR_10
2850x45EC TX_BORDER_COLOR_11
2860x45F0 TX_BORDER_COLOR_12
2870x45F4 TX_BORDER_COLOR_13
2880x45F8 TX_BORDER_COLOR_14
2890x45FC TX_BORDER_COLOR_15
2900x4250 GA_US_VECTOR_INDEX
2910x4254 GA_US_VECTOR_DATA
2920x4600 US_CONFIG
2930x4604 US_PIXSIZE
2940x4620 US_FC_BOOL_CONST
2950x4624 US_FC_CTRL
2960x4630 US_CODE_ADDR
2970x4634 US_CODE_RANGE
2980x4638 US_CODE_OFFSET
2990x46A4 US_OUT_FMT_0
3000x46A8 US_OUT_FMT_1
3010x46AC US_OUT_FMT_2
3020x46B0 US_OUT_FMT_3
3030x46B4 US_W_FMT
3040x4BC0 FG_FOG_BLEND
3050x4BC4 FG_FOG_FACTOR
3060x4BC8 FG_FOG_COLOR_R
3070x4BCC FG_FOG_COLOR_G
3080x4BD0 FG_FOG_COLOR_B
3090x4BD4 FG_ALPHA_FUNC
3100x4BD8 FG_DEPTH_SRC
3110x4C00 US_ALU_CONST_R_0
3120x4C04 US_ALU_CONST_G_0
3130x4C08 US_ALU_CONST_B_0
3140x4C0C US_ALU_CONST_A_0
3150x4C10 US_ALU_CONST_R_1
3160x4C14 US_ALU_CONST_G_1
3170x4C18 US_ALU_CONST_B_1
3180x4C1C US_ALU_CONST_A_1
3190x4C20 US_ALU_CONST_R_2
3200x4C24 US_ALU_CONST_G_2
3210x4C28 US_ALU_CONST_B_2
3220x4C2C US_ALU_CONST_A_2
3230x4C30 US_ALU_CONST_R_3
3240x4C34 US_ALU_CONST_G_3
3250x4C38 US_ALU_CONST_B_3
3260x4C3C US_ALU_CONST_A_3
3270x4C40 US_ALU_CONST_R_4
3280x4C44 US_ALU_CONST_G_4
3290x4C48 US_ALU_CONST_B_4
3300x4C4C US_ALU_CONST_A_4
3310x4C50 US_ALU_CONST_R_5
3320x4C54 US_ALU_CONST_G_5
3330x4C58 US_ALU_CONST_B_5
3340x4C5C US_ALU_CONST_A_5
3350x4C60 US_ALU_CONST_R_6
3360x4C64 US_ALU_CONST_G_6
3370x4C68 US_ALU_CONST_B_6
3380x4C6C US_ALU_CONST_A_6
3390x4C70 US_ALU_CONST_R_7
3400x4C74 US_ALU_CONST_G_7
3410x4C78 US_ALU_CONST_B_7
3420x4C7C US_ALU_CONST_A_7
3430x4C80 US_ALU_CONST_R_8
3440x4C84 US_ALU_CONST_G_8
3450x4C88 US_ALU_CONST_B_8
3460x4C8C US_ALU_CONST_A_8
3470x4C90 US_ALU_CONST_R_9
3480x4C94 US_ALU_CONST_G_9
3490x4C98 US_ALU_CONST_B_9
3500x4C9C US_ALU_CONST_A_9
3510x4CA0 US_ALU_CONST_R_10
3520x4CA4 US_ALU_CONST_G_10
3530x4CA8 US_ALU_CONST_B_10
3540x4CAC US_ALU_CONST_A_10
3550x4CB0 US_ALU_CONST_R_11
3560x4CB4 US_ALU_CONST_G_11
3570x4CB8 US_ALU_CONST_B_11
3580x4CBC US_ALU_CONST_A_11
3590x4CC0 US_ALU_CONST_R_12
3600x4CC4 US_ALU_CONST_G_12
3610x4CC8 US_ALU_CONST_B_12
3620x4CCC US_ALU_CONST_A_12
3630x4CD0 US_ALU_CONST_R_13
3640x4CD4 US_ALU_CONST_G_13
3650x4CD8 US_ALU_CONST_B_13
3660x4CDC US_ALU_CONST_A_13
3670x4CE0 US_ALU_CONST_R_14
3680x4CE4 US_ALU_CONST_G_14
3690x4CE8 US_ALU_CONST_B_14
3700x4CEC US_ALU_CONST_A_14
3710x4CF0 US_ALU_CONST_R_15
3720x4CF4 US_ALU_CONST_G_15
3730x4CF8 US_ALU_CONST_B_15
3740x4CFC US_ALU_CONST_A_15
3750x4D00 US_ALU_CONST_R_16
3760x4D04 US_ALU_CONST_G_16
3770x4D08 US_ALU_CONST_B_16
3780x4D0C US_ALU_CONST_A_16
3790x4D10 US_ALU_CONST_R_17
3800x4D14 US_ALU_CONST_G_17
3810x4D18 US_ALU_CONST_B_17
3820x4D1C US_ALU_CONST_A_17
3830x4D20 US_ALU_CONST_R_18
3840x4D24 US_ALU_CONST_G_18
3850x4D28 US_ALU_CONST_B_18
3860x4D2C US_ALU_CONST_A_18
3870x4D30 US_ALU_CONST_R_19
3880x4D34 US_ALU_CONST_G_19
3890x4D38 US_ALU_CONST_B_19
3900x4D3C US_ALU_CONST_A_19
3910x4D40 US_ALU_CONST_R_20
3920x4D44 US_ALU_CONST_G_20
3930x4D48 US_ALU_CONST_B_20
3940x4D4C US_ALU_CONST_A_20
3950x4D50 US_ALU_CONST_R_21
3960x4D54 US_ALU_CONST_G_21
3970x4D58 US_ALU_CONST_B_21
3980x4D5C US_ALU_CONST_A_21
3990x4D60 US_ALU_CONST_R_22
4000x4D64 US_ALU_CONST_G_22
4010x4D68 US_ALU_CONST_B_22
4020x4D6C US_ALU_CONST_A_22
4030x4D70 US_ALU_CONST_R_23
4040x4D74 US_ALU_CONST_G_23
4050x4D78 US_ALU_CONST_B_23
4060x4D7C US_ALU_CONST_A_23
4070x4D80 US_ALU_CONST_R_24
4080x4D84 US_ALU_CONST_G_24
4090x4D88 US_ALU_CONST_B_24
4100x4D8C US_ALU_CONST_A_24
4110x4D90 US_ALU_CONST_R_25
4120x4D94 US_ALU_CONST_G_25
4130x4D98 US_ALU_CONST_B_25
4140x4D9C US_ALU_CONST_A_25
4150x4DA0 US_ALU_CONST_R_26
4160x4DA4 US_ALU_CONST_G_26
4170x4DA8 US_ALU_CONST_B_26
4180x4DAC US_ALU_CONST_A_26
4190x4DB0 US_ALU_CONST_R_27
4200x4DB4 US_ALU_CONST_G_27
4210x4DB8 US_ALU_CONST_B_27
4220x4DBC US_ALU_CONST_A_27
4230x4DC0 US_ALU_CONST_R_28
4240x4DC4 US_ALU_CONST_G_28
4250x4DC8 US_ALU_CONST_B_28
4260x4DCC US_ALU_CONST_A_28
4270x4DD0 US_ALU_CONST_R_29
4280x4DD4 US_ALU_CONST_G_29
4290x4DD8 US_ALU_CONST_B_29
4300x4DDC US_ALU_CONST_A_29
4310x4DE0 US_ALU_CONST_R_30
4320x4DE4 US_ALU_CONST_G_30
4330x4DE8 US_ALU_CONST_B_30
4340x4DEC US_ALU_CONST_A_30
4350x4DF0 US_ALU_CONST_R_31
4360x4DF4 US_ALU_CONST_G_31
4370x4DF8 US_ALU_CONST_B_31
4380x4DFC US_ALU_CONST_A_31
4390x4E04 RB3D_BLENDCNTL_R3
4400x4E08 RB3D_ABLENDCNTL_R3
4410x4E0C RB3D_COLOR_CHANNEL_MASK
4420x4E10 RB3D_CONSTANT_COLOR
4430x4E14 RB3D_COLOR_CLEAR_VALUE
4440x4E18 RB3D_ROPCNTL_R3
4450x4E1C RB3D_CLRCMP_FLIPE_R3
4460x4E20 RB3D_CLRCMP_CLR_R3
4470x4E24 RB3D_CLRCMP_MSK_R3
4480x4E48 RB3D_DEBUG_CTL
4490x4E4C RB3D_DSTCACHE_CTLSTAT_R3
4500x4E50 RB3D_DITHER_CTL
4510x4E54 RB3D_CMASK_OFFSET0
4520x4E58 RB3D_CMASK_OFFSET1
4530x4E5C RB3D_CMASK_OFFSET2
4540x4E60 RB3D_CMASK_OFFSET3
4550x4E64 RB3D_CMASK_PITCH0
4560x4E68 RB3D_CMASK_PITCH1
4570x4E6C RB3D_CMASK_PITCH2
4580x4E70 RB3D_CMASK_PITCH3
4590x4E74 RB3D_CMASK_WRINDEX
4600x4E78 RB3D_CMASK_DWORD
4610x4E7C RB3D_CMASK_RDINDEX
4620x4E80 RB3D_AARESOLVE_OFFSET
4630x4E84 RB3D_AARESOLVE_PITCH
4640x4E88 RB3D_AARESOLVE_CTL
4650x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
4660x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
4670x4EF8 RB3D_CONSTANT_COLOR_AR
4680x4EFC RB3D_CONSTANT_COLOR_GB
4690x4F04 ZB_ZSTENCILCNTL
4700x4F08 ZB_STENCILREFMASK
4710x4F14 ZB_ZTOP
4720x4F18 ZB_ZCACHE_CTLSTAT
4730x4F1C ZB_BW_CNTL
4740x4F28 ZB_DEPTHCLEARVALUE
4750x4F30 ZB_ZMASK_OFFSET
4760x4F34 ZB_ZMASK_PITCH
4770x4F38 ZB_ZMASK_WRINDEX
4780x4F3C ZB_ZMASK_DWORD
4790x4F40 ZB_ZMASK_RDINDEX
4800x4F44 ZB_HIZ_OFFSET
4810x4F48 ZB_HIZ_WRINDEX
4820x4F4C ZB_HIZ_DWORD
4830x4F50 ZB_HIZ_RDINDEX
4840x4F54 ZB_HIZ_PITCH
4850x4F58 ZB_ZPASS_DATA
4860x4FD4 ZB_STENCILREFMASK_BF
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index b29affd9c5d8..a3fbdad938c7 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -29,7 +29,6 @@
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include "radeon_reg.h" 30#include "radeon_reg.h"
31#include "radeon.h" 31#include "radeon.h"
32#include "radeon_share.h"
33 32
34/* rs400,rs480 depends on : */ 33/* rs400,rs480 depends on : */
35void r100_hdp_reset(struct radeon_device *rdev); 34void r100_hdp_reset(struct radeon_device *rdev);
@@ -63,7 +62,7 @@ void rs400_gart_adjust_size(struct radeon_device *rdev)
63 break; 62 break;
64 default: 63 default:
65 DRM_ERROR("Unable to use IGP GART size %uM\n", 64 DRM_ERROR("Unable to use IGP GART size %uM\n",
66 rdev->mc.gtt_size >> 20); 65 (unsigned)(rdev->mc.gtt_size >> 20));
67 DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n"); 66 DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n");
68 DRM_ERROR("Forcing to 32M GART size\n"); 67 DRM_ERROR("Forcing to 32M GART size\n");
69 rdev->mc.gtt_size = 32 * 1024 * 1024; 68 rdev->mc.gtt_size = 32 * 1024 * 1024;
@@ -93,20 +92,41 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev)
93 WREG32_MC(RS480_GART_CACHE_CNTRL, 0); 92 WREG32_MC(RS480_GART_CACHE_CNTRL, 0);
94} 93}
95 94
96int rs400_gart_enable(struct radeon_device *rdev) 95int rs400_gart_init(struct radeon_device *rdev)
97{ 96{
98 uint32_t size_reg;
99 uint32_t tmp;
100 int r; 97 int r;
101 98
99 if (rdev->gart.table.ram.ptr) {
100 WARN(1, "RS400 GART already initialized.\n");
101 return 0;
102 }
103 /* Check gart size */
104 switch(rdev->mc.gtt_size / (1024 * 1024)) {
105 case 32:
106 case 64:
107 case 128:
108 case 256:
109 case 512:
110 case 1024:
111 case 2048:
112 break;
113 default:
114 return -EINVAL;
115 }
102 /* Initialize common gart structure */ 116 /* Initialize common gart structure */
103 r = radeon_gart_init(rdev); 117 r = radeon_gart_init(rdev);
104 if (r) { 118 if (r)
105 return r; 119 return r;
106 } 120 if (rs400_debugfs_pcie_gart_info_init(rdev))
107 if (rs400_debugfs_pcie_gart_info_init(rdev)) {
108 DRM_ERROR("Failed to register debugfs file for RS400 GART !\n"); 121 DRM_ERROR("Failed to register debugfs file for RS400 GART !\n");
109 } 122 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
123 return radeon_gart_table_ram_alloc(rdev);
124}
125
126int rs400_gart_enable(struct radeon_device *rdev)
127{
128 uint32_t size_reg;
129 uint32_t tmp;
110 130
111 tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); 131 tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
112 tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS; 132 tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
@@ -137,13 +157,6 @@ int rs400_gart_enable(struct radeon_device *rdev)
137 default: 157 default:
138 return -EINVAL; 158 return -EINVAL;
139 } 159 }
140 if (rdev->gart.table.ram.ptr == NULL) {
141 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
142 r = radeon_gart_table_ram_alloc(rdev);
143 if (r) {
144 return r;
145 }
146 }
147 /* It should be fine to program it to max value */ 160 /* It should be fine to program it to max value */
148 if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) { 161 if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {
149 WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF); 162 WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF);
@@ -202,6 +215,13 @@ void rs400_gart_disable(struct radeon_device *rdev)
202 WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0); 215 WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
203} 216}
204 217
218void rs400_gart_fini(struct radeon_device *rdev)
219{
220 rs400_gart_disable(rdev);
221 radeon_gart_table_ram_free(rdev);
222 radeon_gart_fini(rdev);
223}
224
205int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 225int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
206{ 226{
207 uint32_t entry; 227 uint32_t entry;
@@ -256,14 +276,12 @@ int rs400_mc_init(struct radeon_device *rdev)
256 (void)RREG32(RADEON_HOST_PATH_CNTL); 276 (void)RREG32(RADEON_HOST_PATH_CNTL);
257 WREG32(RADEON_HOST_PATH_CNTL, tmp); 277 WREG32(RADEON_HOST_PATH_CNTL, tmp);
258 (void)RREG32(RADEON_HOST_PATH_CNTL); 278 (void)RREG32(RADEON_HOST_PATH_CNTL);
279
259 return 0; 280 return 0;
260} 281}
261 282
262void rs400_mc_fini(struct radeon_device *rdev) 283void rs400_mc_fini(struct radeon_device *rdev)
263{ 284{
264 rs400_gart_disable(rdev);
265 radeon_gart_table_ram_free(rdev);
266 radeon_gart_fini(rdev);
267} 285}
268 286
269 287
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 02fd11aad6a2..0e791e26def3 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -28,6 +28,9 @@
28#include "drmP.h" 28#include "drmP.h"
29#include "radeon_reg.h" 29#include "radeon_reg.h"
30#include "radeon.h" 30#include "radeon.h"
31#include "avivod.h"
32
33#include "rs600_reg_safe.h"
31 34
32/* rs600 depends on : */ 35/* rs600 depends on : */
33void r100_hdp_reset(struct radeon_device *rdev); 36void r100_hdp_reset(struct radeon_device *rdev);
@@ -66,22 +69,35 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
66 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 69 tmp = RREG32_MC(RS600_MC_PT0_CNTL);
67} 70}
68 71
69int rs600_gart_enable(struct radeon_device *rdev) 72int rs600_gart_init(struct radeon_device *rdev)
70{ 73{
71 uint32_t tmp;
72 int i;
73 int r; 74 int r;
74 75
76 if (rdev->gart.table.vram.robj) {
77 WARN(1, "RS600 GART already initialized.\n");
78 return 0;
79 }
75 /* Initialize common gart structure */ 80 /* Initialize common gart structure */
76 r = radeon_gart_init(rdev); 81 r = radeon_gart_init(rdev);
77 if (r) { 82 if (r) {
78 return r; 83 return r;
79 } 84 }
80 rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; 85 rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
81 r = radeon_gart_table_vram_alloc(rdev); 86 return radeon_gart_table_vram_alloc(rdev);
82 if (r) { 87}
83 return r; 88
89int rs600_gart_enable(struct radeon_device *rdev)
90{
91 uint32_t tmp;
92 int r, i;
93
94 if (rdev->gart.table.vram.robj == NULL) {
95 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
96 return -EINVAL;
84 } 97 }
98 r = radeon_gart_table_vram_pin(rdev);
99 if (r)
100 return r;
85 /* FIXME: setup default page */ 101 /* FIXME: setup default page */
86 WREG32_MC(RS600_MC_PT0_CNTL, 102 WREG32_MC(RS600_MC_PT0_CNTL,
87 (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | 103 (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
@@ -136,8 +152,17 @@ void rs600_gart_disable(struct radeon_device *rdev)
136 tmp = RREG32_MC(RS600_MC_CNTL1); 152 tmp = RREG32_MC(RS600_MC_CNTL1);
137 tmp &= ~RS600_ENABLE_PAGE_TABLES; 153 tmp &= ~RS600_ENABLE_PAGE_TABLES;
138 WREG32_MC(RS600_MC_CNTL1, tmp); 154 WREG32_MC(RS600_MC_CNTL1, tmp);
139 radeon_object_kunmap(rdev->gart.table.vram.robj); 155 if (rdev->gart.table.vram.robj) {
140 radeon_object_unpin(rdev->gart.table.vram.robj); 156 radeon_object_kunmap(rdev->gart.table.vram.robj);
157 radeon_object_unpin(rdev->gart.table.vram.robj);
158 }
159}
160
161void rs600_gart_fini(struct radeon_device *rdev)
162{
163 rs600_gart_disable(rdev);
164 radeon_gart_table_vram_free(rdev);
165 radeon_gart_fini(rdev);
141} 166}
142 167
143#define R600_PTE_VALID (1 << 0) 168#define R600_PTE_VALID (1 << 0)
@@ -173,6 +198,8 @@ void rs600_mc_disable_clients(struct radeon_device *rdev)
173 "programming pipes. Bad things might happen.\n"); 198 "programming pipes. Bad things might happen.\n");
174 } 199 }
175 200
201 radeon_avivo_vga_render_disable(rdev);
202
176 tmp = RREG32(AVIVO_D1VGA_CONTROL); 203 tmp = RREG32(AVIVO_D1VGA_CONTROL);
177 WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); 204 WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
178 tmp = RREG32(AVIVO_D2VGA_CONTROL); 205 tmp = RREG32(AVIVO_D2VGA_CONTROL);
@@ -233,9 +260,6 @@ int rs600_mc_init(struct radeon_device *rdev)
233 260
234void rs600_mc_fini(struct radeon_device *rdev) 261void rs600_mc_fini(struct radeon_device *rdev)
235{ 262{
236 rs600_gart_disable(rdev);
237 radeon_gart_table_vram_free(rdev);
238 radeon_gart_fini(rdev);
239} 263}
240 264
241 265
@@ -251,11 +275,9 @@ int rs600_irq_set(struct radeon_device *rdev)
251 tmp |= RADEON_SW_INT_ENABLE; 275 tmp |= RADEON_SW_INT_ENABLE;
252 } 276 }
253 if (rdev->irq.crtc_vblank_int[0]) { 277 if (rdev->irq.crtc_vblank_int[0]) {
254 tmp |= AVIVO_DISPLAY_INT_STATUS;
255 mode_int |= AVIVO_D1MODE_INT_MASK; 278 mode_int |= AVIVO_D1MODE_INT_MASK;
256 } 279 }
257 if (rdev->irq.crtc_vblank_int[1]) { 280 if (rdev->irq.crtc_vblank_int[1]) {
258 tmp |= AVIVO_DISPLAY_INT_STATUS;
259 mode_int |= AVIVO_D2MODE_INT_MASK; 281 mode_int |= AVIVO_D2MODE_INT_MASK;
260 } 282 }
261 WREG32(RADEON_GEN_INT_CNTL, tmp); 283 WREG32(RADEON_GEN_INT_CNTL, tmp);
@@ -410,64 +432,6 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
410 WREG32(RS600_MC_DATA, v); 432 WREG32(RS600_MC_DATA, v);
411} 433}
412 434
413static const unsigned rs600_reg_safe_bm[219] = {
414 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
415 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
416 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
417 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
418 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
419 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
420 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
421 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
422 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
423 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
424 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
425 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
426 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
427 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
428 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
429 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
430 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
431 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
432 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
433 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
434 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
435 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
436 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
437 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
438 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
439 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
440 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
441 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
442 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
443 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
444 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
445 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
446 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
447 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
448 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
449 0x00000000, 0x0000C100, 0x00000000, 0x00000000,
450 0x00000000, 0x00000000, 0x00000000, 0x00000000,
451 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
452 0x00000000, 0x00000000, 0x00000000, 0x00000000,
453 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF,
454 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
455 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
456 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
457 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
458 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
459 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
460 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
461 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
462 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
463 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
464 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
465 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
466 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
467 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
468 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
469};
470
471int rs600_init(struct radeon_device *rdev) 435int rs600_init(struct radeon_device *rdev)
472{ 436{
473 rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; 437 rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 879882533e45..0f585ca8276d 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -94,9 +94,6 @@ int rs690_mc_init(struct radeon_device *rdev)
94 94
95void rs690_mc_fini(struct radeon_device *rdev) 95void rs690_mc_fini(struct radeon_device *rdev)
96{ 96{
97 rs400_gart_disable(rdev);
98 radeon_gart_table_ram_free(rdev);
99 radeon_gart_fini(rdev);
100} 97}
101 98
102 99
@@ -652,4 +649,3 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
652 WREG32(RS690_MC_DATA, v); 649 WREG32(RS690_MC_DATA, v);
653 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); 650 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
654} 651}
655
diff --git a/drivers/gpu/drm/radeon/rs780.c b/drivers/gpu/drm/radeon/rs780.c
deleted file mode 100644
index 0affcff81825..000000000000
--- a/drivers/gpu/drm/radeon/rs780.c
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h"
31
32/* rs780 depends on : */
33void rs600_mc_disable_clients(struct radeon_device *rdev);
34
35/* This files gather functions specifics to:
36 * rs780
37 *
38 * Some of these functions might be used by newer ASICs.
39 */
40int rs780_mc_wait_for_idle(struct radeon_device *rdev);
41void rs780_gpu_init(struct radeon_device *rdev);
42
43
44/*
45 * MC
46 */
47int rs780_mc_init(struct radeon_device *rdev)
48{
49 rs780_gpu_init(rdev);
50 /* FIXME: implement */
51
52 rs600_mc_disable_clients(rdev);
53 if (rs780_mc_wait_for_idle(rdev)) {
54 printk(KERN_WARNING "Failed to wait MC idle while "
55 "programming pipes. Bad things might happen.\n");
56 }
57 return 0;
58}
59
60void rs780_mc_fini(struct radeon_device *rdev)
61{
62 /* FIXME: implement */
63}
64
65
66/*
67 * Global GPU functions
68 */
69void rs780_errata(struct radeon_device *rdev)
70{
71 rdev->pll_errata = 0;
72}
73
74int rs780_mc_wait_for_idle(struct radeon_device *rdev)
75{
76 /* FIXME: implement */
77 return 0;
78}
79
80void rs780_gpu_init(struct radeon_device *rdev)
81{
82 /* FIXME: implement */
83}
84
85
86/*
87 * VRAM info
88 */
89void rs780_vram_get_type(struct radeon_device *rdev)
90{
91 /* FIXME: implement */
92}
93
94void rs780_vram_info(struct radeon_device *rdev)
95{
96 rs780_vram_get_type(rdev);
97
98 /* FIXME: implement */
99 /* Could aper size report 0 ? */
100 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
101 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
102}
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 0566fb67e460..fd799748e7d8 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -27,18 +27,16 @@
27 */ 27 */
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include "drmP.h" 29#include "drmP.h"
30#include "rv515r.h" 30#include "rv515d.h"
31#include "radeon.h" 31#include "radeon.h"
32#include "radeon_share.h"
33 32
33#include "rv515_reg_safe.h"
34/* rv515 depends on : */ 34/* rv515 depends on : */
35void r100_hdp_reset(struct radeon_device *rdev); 35void r100_hdp_reset(struct radeon_device *rdev);
36int r100_cp_reset(struct radeon_device *rdev); 36int r100_cp_reset(struct radeon_device *rdev);
37int r100_rb2d_reset(struct radeon_device *rdev); 37int r100_rb2d_reset(struct radeon_device *rdev);
38int r100_gui_wait_for_idle(struct radeon_device *rdev); 38int r100_gui_wait_for_idle(struct radeon_device *rdev);
39int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); 39int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
40int rv370_pcie_gart_enable(struct radeon_device *rdev);
41void rv370_pcie_gart_disable(struct radeon_device *rdev);
42void r420_pipes_init(struct radeon_device *rdev); 40void r420_pipes_init(struct radeon_device *rdev);
43void rs600_mc_disable_clients(struct radeon_device *rdev); 41void rs600_mc_disable_clients(struct radeon_device *rdev);
44void rs600_disable_vga(struct radeon_device *rdev); 42void rs600_disable_vga(struct radeon_device *rdev);
@@ -126,9 +124,6 @@ int rv515_mc_init(struct radeon_device *rdev)
126 124
127void rv515_mc_fini(struct radeon_device *rdev) 125void rv515_mc_fini(struct radeon_device *rdev)
128{ 126{
129 rv370_pcie_gart_disable(rdev);
130 radeon_gart_table_vram_free(rdev);
131 radeon_gart_fini(rdev);
132} 127}
133 128
134 129
@@ -464,301 +459,244 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
464#endif 459#endif
465} 460}
466 461
467
468/* 462/*
469 * Asic initialization 463 * Asic initialization
470 */ 464 */
471static const unsigned r500_reg_safe_bm[219] = {
472 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
473 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
474 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
475 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
476 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
477 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
479 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
480 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
481 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
482 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
483 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
484 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
485 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
486 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
487 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
488 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
489 0xF0000038, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
490 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
491 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
492 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
493 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
494 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
495 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
496 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
497 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
498 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
499 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
500 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
501 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
502 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
503 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
504 0x1FFFFC78, 0xFFFFE000, 0xFFFFFFFE, 0xFFFFFFFF,
505 0x38CF8F50, 0xFFF88082, 0xFF0000FC, 0xFAE009FF,
506 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
507 0xFFFF8CFC, 0xFFFFC1FF, 0xFFFFFFFF, 0xFFFFFFFF,
508 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
509 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF,
510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF,
512 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
513 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
514 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
515 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
516 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
517 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
518 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
519 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
520 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
521 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
522 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
523 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
524 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
525 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
526 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
527};
528
529int rv515_init(struct radeon_device *rdev) 465int rv515_init(struct radeon_device *rdev)
530{ 466{
531 rdev->config.r300.reg_safe_bm = r500_reg_safe_bm; 467 rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm;
532 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r500_reg_safe_bm); 468 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm);
533 return 0; 469 return 0;
534} 470}
535 471
536void atom_rv515_force_tv_scaler(struct radeon_device *rdev) 472void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc)
537{ 473{
538 474 int index_reg = 0x6578 + crtc->crtc_offset;
539 WREG32(0x659C, 0x0); 475 int data_reg = 0x657c + crtc->crtc_offset;
540 WREG32(0x6594, 0x705); 476
541 WREG32(0x65A4, 0x10001); 477 WREG32(0x659C + crtc->crtc_offset, 0x0);
542 WREG32(0x65D8, 0x0); 478 WREG32(0x6594 + crtc->crtc_offset, 0x705);
543 WREG32(0x65B0, 0x0); 479 WREG32(0x65A4 + crtc->crtc_offset, 0x10001);
544 WREG32(0x65C0, 0x0); 480 WREG32(0x65D8 + crtc->crtc_offset, 0x0);
545 WREG32(0x65D4, 0x0); 481 WREG32(0x65B0 + crtc->crtc_offset, 0x0);
546 WREG32(0x6578, 0x0); 482 WREG32(0x65C0 + crtc->crtc_offset, 0x0);
547 WREG32(0x657C, 0x841880A8); 483 WREG32(0x65D4 + crtc->crtc_offset, 0x0);
548 WREG32(0x6578, 0x1); 484 WREG32(index_reg, 0x0);
549 WREG32(0x657C, 0x84208680); 485 WREG32(data_reg, 0x841880A8);
550 WREG32(0x6578, 0x2); 486 WREG32(index_reg, 0x1);
551 WREG32(0x657C, 0xBFF880B0); 487 WREG32(data_reg, 0x84208680);
552 WREG32(0x6578, 0x100); 488 WREG32(index_reg, 0x2);
553 WREG32(0x657C, 0x83D88088); 489 WREG32(data_reg, 0xBFF880B0);
554 WREG32(0x6578, 0x101); 490 WREG32(index_reg, 0x100);
555 WREG32(0x657C, 0x84608680); 491 WREG32(data_reg, 0x83D88088);
556 WREG32(0x6578, 0x102); 492 WREG32(index_reg, 0x101);
557 WREG32(0x657C, 0xBFF080D0); 493 WREG32(data_reg, 0x84608680);
558 WREG32(0x6578, 0x200); 494 WREG32(index_reg, 0x102);
559 WREG32(0x657C, 0x83988068); 495 WREG32(data_reg, 0xBFF080D0);
560 WREG32(0x6578, 0x201); 496 WREG32(index_reg, 0x200);
561 WREG32(0x657C, 0x84A08680); 497 WREG32(data_reg, 0x83988068);
562 WREG32(0x6578, 0x202); 498 WREG32(index_reg, 0x201);
563 WREG32(0x657C, 0xBFF080F8); 499 WREG32(data_reg, 0x84A08680);
564 WREG32(0x6578, 0x300); 500 WREG32(index_reg, 0x202);
565 WREG32(0x657C, 0x83588058); 501 WREG32(data_reg, 0xBFF080F8);
566 WREG32(0x6578, 0x301); 502 WREG32(index_reg, 0x300);
567 WREG32(0x657C, 0x84E08660); 503 WREG32(data_reg, 0x83588058);
568 WREG32(0x6578, 0x302); 504 WREG32(index_reg, 0x301);
569 WREG32(0x657C, 0xBFF88120); 505 WREG32(data_reg, 0x84E08660);
570 WREG32(0x6578, 0x400); 506 WREG32(index_reg, 0x302);
571 WREG32(0x657C, 0x83188040); 507 WREG32(data_reg, 0xBFF88120);
572 WREG32(0x6578, 0x401); 508 WREG32(index_reg, 0x400);
573 WREG32(0x657C, 0x85008660); 509 WREG32(data_reg, 0x83188040);
574 WREG32(0x6578, 0x402); 510 WREG32(index_reg, 0x401);
575 WREG32(0x657C, 0xBFF88150); 511 WREG32(data_reg, 0x85008660);
576 WREG32(0x6578, 0x500); 512 WREG32(index_reg, 0x402);
577 WREG32(0x657C, 0x82D88030); 513 WREG32(data_reg, 0xBFF88150);
578 WREG32(0x6578, 0x501); 514 WREG32(index_reg, 0x500);
579 WREG32(0x657C, 0x85408640); 515 WREG32(data_reg, 0x82D88030);
580 WREG32(0x6578, 0x502); 516 WREG32(index_reg, 0x501);
581 WREG32(0x657C, 0xBFF88180); 517 WREG32(data_reg, 0x85408640);
582 WREG32(0x6578, 0x600); 518 WREG32(index_reg, 0x502);
583 WREG32(0x657C, 0x82A08018); 519 WREG32(data_reg, 0xBFF88180);
584 WREG32(0x6578, 0x601); 520 WREG32(index_reg, 0x600);
585 WREG32(0x657C, 0x85808620); 521 WREG32(data_reg, 0x82A08018);
586 WREG32(0x6578, 0x602); 522 WREG32(index_reg, 0x601);
587 WREG32(0x657C, 0xBFF081B8); 523 WREG32(data_reg, 0x85808620);
588 WREG32(0x6578, 0x700); 524 WREG32(index_reg, 0x602);
589 WREG32(0x657C, 0x82608010); 525 WREG32(data_reg, 0xBFF081B8);
590 WREG32(0x6578, 0x701); 526 WREG32(index_reg, 0x700);
591 WREG32(0x657C, 0x85A08600); 527 WREG32(data_reg, 0x82608010);
592 WREG32(0x6578, 0x702); 528 WREG32(index_reg, 0x701);
593 WREG32(0x657C, 0x800081F0); 529 WREG32(data_reg, 0x85A08600);
594 WREG32(0x6578, 0x800); 530 WREG32(index_reg, 0x702);
595 WREG32(0x657C, 0x8228BFF8); 531 WREG32(data_reg, 0x800081F0);
596 WREG32(0x6578, 0x801); 532 WREG32(index_reg, 0x800);
597 WREG32(0x657C, 0x85E085E0); 533 WREG32(data_reg, 0x8228BFF8);
598 WREG32(0x6578, 0x802); 534 WREG32(index_reg, 0x801);
599 WREG32(0x657C, 0xBFF88228); 535 WREG32(data_reg, 0x85E085E0);
600 WREG32(0x6578, 0x10000); 536 WREG32(index_reg, 0x802);
601 WREG32(0x657C, 0x82A8BF00); 537 WREG32(data_reg, 0xBFF88228);
602 WREG32(0x6578, 0x10001); 538 WREG32(index_reg, 0x10000);
603 WREG32(0x657C, 0x82A08CC0); 539 WREG32(data_reg, 0x82A8BF00);
604 WREG32(0x6578, 0x10002); 540 WREG32(index_reg, 0x10001);
605 WREG32(0x657C, 0x8008BEF8); 541 WREG32(data_reg, 0x82A08CC0);
606 WREG32(0x6578, 0x10100); 542 WREG32(index_reg, 0x10002);
607 WREG32(0x657C, 0x81F0BF28); 543 WREG32(data_reg, 0x8008BEF8);
608 WREG32(0x6578, 0x10101); 544 WREG32(index_reg, 0x10100);
609 WREG32(0x657C, 0x83608CA0); 545 WREG32(data_reg, 0x81F0BF28);
610 WREG32(0x6578, 0x10102); 546 WREG32(index_reg, 0x10101);
611 WREG32(0x657C, 0x8018BED0); 547 WREG32(data_reg, 0x83608CA0);
612 WREG32(0x6578, 0x10200); 548 WREG32(index_reg, 0x10102);
613 WREG32(0x657C, 0x8148BF38); 549 WREG32(data_reg, 0x8018BED0);
614 WREG32(0x6578, 0x10201); 550 WREG32(index_reg, 0x10200);
615 WREG32(0x657C, 0x84408C80); 551 WREG32(data_reg, 0x8148BF38);
616 WREG32(0x6578, 0x10202); 552 WREG32(index_reg, 0x10201);
617 WREG32(0x657C, 0x8008BEB8); 553 WREG32(data_reg, 0x84408C80);
618 WREG32(0x6578, 0x10300); 554 WREG32(index_reg, 0x10202);
619 WREG32(0x657C, 0x80B0BF78); 555 WREG32(data_reg, 0x8008BEB8);
620 WREG32(0x6578, 0x10301); 556 WREG32(index_reg, 0x10300);
621 WREG32(0x657C, 0x85008C20); 557 WREG32(data_reg, 0x80B0BF78);
622 WREG32(0x6578, 0x10302); 558 WREG32(index_reg, 0x10301);
623 WREG32(0x657C, 0x8020BEA0); 559 WREG32(data_reg, 0x85008C20);
624 WREG32(0x6578, 0x10400); 560 WREG32(index_reg, 0x10302);
625 WREG32(0x657C, 0x8028BF90); 561 WREG32(data_reg, 0x8020BEA0);
626 WREG32(0x6578, 0x10401); 562 WREG32(index_reg, 0x10400);
627 WREG32(0x657C, 0x85E08BC0); 563 WREG32(data_reg, 0x8028BF90);
628 WREG32(0x6578, 0x10402); 564 WREG32(index_reg, 0x10401);
629 WREG32(0x657C, 0x8018BE90); 565 WREG32(data_reg, 0x85E08BC0);
630 WREG32(0x6578, 0x10500); 566 WREG32(index_reg, 0x10402);
631 WREG32(0x657C, 0xBFB8BFB0); 567 WREG32(data_reg, 0x8018BE90);
632 WREG32(0x6578, 0x10501); 568 WREG32(index_reg, 0x10500);
633 WREG32(0x657C, 0x86C08B40); 569 WREG32(data_reg, 0xBFB8BFB0);
634 WREG32(0x6578, 0x10502); 570 WREG32(index_reg, 0x10501);
635 WREG32(0x657C, 0x8010BE90); 571 WREG32(data_reg, 0x86C08B40);
636 WREG32(0x6578, 0x10600); 572 WREG32(index_reg, 0x10502);
637 WREG32(0x657C, 0xBF58BFC8); 573 WREG32(data_reg, 0x8010BE90);
638 WREG32(0x6578, 0x10601); 574 WREG32(index_reg, 0x10600);
639 WREG32(0x657C, 0x87A08AA0); 575 WREG32(data_reg, 0xBF58BFC8);
640 WREG32(0x6578, 0x10602); 576 WREG32(index_reg, 0x10601);
641 WREG32(0x657C, 0x8010BE98); 577 WREG32(data_reg, 0x87A08AA0);
642 WREG32(0x6578, 0x10700); 578 WREG32(index_reg, 0x10602);
643 WREG32(0x657C, 0xBF10BFF0); 579 WREG32(data_reg, 0x8010BE98);
644 WREG32(0x6578, 0x10701); 580 WREG32(index_reg, 0x10700);
645 WREG32(0x657C, 0x886089E0); 581 WREG32(data_reg, 0xBF10BFF0);
646 WREG32(0x6578, 0x10702); 582 WREG32(index_reg, 0x10701);
647 WREG32(0x657C, 0x8018BEB0); 583 WREG32(data_reg, 0x886089E0);
648 WREG32(0x6578, 0x10800); 584 WREG32(index_reg, 0x10702);
649 WREG32(0x657C, 0xBED8BFE8); 585 WREG32(data_reg, 0x8018BEB0);
650 WREG32(0x6578, 0x10801); 586 WREG32(index_reg, 0x10800);
651 WREG32(0x657C, 0x89408940); 587 WREG32(data_reg, 0xBED8BFE8);
652 WREG32(0x6578, 0x10802); 588 WREG32(index_reg, 0x10801);
653 WREG32(0x657C, 0xBFE8BED8); 589 WREG32(data_reg, 0x89408940);
654 WREG32(0x6578, 0x20000); 590 WREG32(index_reg, 0x10802);
655 WREG32(0x657C, 0x80008000); 591 WREG32(data_reg, 0xBFE8BED8);
656 WREG32(0x6578, 0x20001); 592 WREG32(index_reg, 0x20000);
657 WREG32(0x657C, 0x90008000); 593 WREG32(data_reg, 0x80008000);
658 WREG32(0x6578, 0x20002); 594 WREG32(index_reg, 0x20001);
659 WREG32(0x657C, 0x80008000); 595 WREG32(data_reg, 0x90008000);
660 WREG32(0x6578, 0x20003); 596 WREG32(index_reg, 0x20002);
661 WREG32(0x657C, 0x80008000); 597 WREG32(data_reg, 0x80008000);
662 WREG32(0x6578, 0x20100); 598 WREG32(index_reg, 0x20003);
663 WREG32(0x657C, 0x80108000); 599 WREG32(data_reg, 0x80008000);
664 WREG32(0x6578, 0x20101); 600 WREG32(index_reg, 0x20100);
665 WREG32(0x657C, 0x8FE0BF70); 601 WREG32(data_reg, 0x80108000);
666 WREG32(0x6578, 0x20102); 602 WREG32(index_reg, 0x20101);
667 WREG32(0x657C, 0xBFE880C0); 603 WREG32(data_reg, 0x8FE0BF70);
668 WREG32(0x6578, 0x20103); 604 WREG32(index_reg, 0x20102);
669 WREG32(0x657C, 0x80008000); 605 WREG32(data_reg, 0xBFE880C0);
670 WREG32(0x6578, 0x20200); 606 WREG32(index_reg, 0x20103);
671 WREG32(0x657C, 0x8018BFF8); 607 WREG32(data_reg, 0x80008000);
672 WREG32(0x6578, 0x20201); 608 WREG32(index_reg, 0x20200);
673 WREG32(0x657C, 0x8F80BF08); 609 WREG32(data_reg, 0x8018BFF8);
674 WREG32(0x6578, 0x20202); 610 WREG32(index_reg, 0x20201);
675 WREG32(0x657C, 0xBFD081A0); 611 WREG32(data_reg, 0x8F80BF08);
676 WREG32(0x6578, 0x20203); 612 WREG32(index_reg, 0x20202);
677 WREG32(0x657C, 0xBFF88000); 613 WREG32(data_reg, 0xBFD081A0);
678 WREG32(0x6578, 0x20300); 614 WREG32(index_reg, 0x20203);
679 WREG32(0x657C, 0x80188000); 615 WREG32(data_reg, 0xBFF88000);
680 WREG32(0x6578, 0x20301); 616 WREG32(index_reg, 0x20300);
681 WREG32(0x657C, 0x8EE0BEC0); 617 WREG32(data_reg, 0x80188000);
682 WREG32(0x6578, 0x20302); 618 WREG32(index_reg, 0x20301);
683 WREG32(0x657C, 0xBFB082A0); 619 WREG32(data_reg, 0x8EE0BEC0);
684 WREG32(0x6578, 0x20303); 620 WREG32(index_reg, 0x20302);
685 WREG32(0x657C, 0x80008000); 621 WREG32(data_reg, 0xBFB082A0);
686 WREG32(0x6578, 0x20400); 622 WREG32(index_reg, 0x20303);
687 WREG32(0x657C, 0x80188000); 623 WREG32(data_reg, 0x80008000);
688 WREG32(0x6578, 0x20401); 624 WREG32(index_reg, 0x20400);
689 WREG32(0x657C, 0x8E00BEA0); 625 WREG32(data_reg, 0x80188000);
690 WREG32(0x6578, 0x20402); 626 WREG32(index_reg, 0x20401);
691 WREG32(0x657C, 0xBF8883C0); 627 WREG32(data_reg, 0x8E00BEA0);
692 WREG32(0x6578, 0x20403); 628 WREG32(index_reg, 0x20402);
693 WREG32(0x657C, 0x80008000); 629 WREG32(data_reg, 0xBF8883C0);
694 WREG32(0x6578, 0x20500); 630 WREG32(index_reg, 0x20403);
695 WREG32(0x657C, 0x80188000); 631 WREG32(data_reg, 0x80008000);
696 WREG32(0x6578, 0x20501); 632 WREG32(index_reg, 0x20500);
697 WREG32(0x657C, 0x8D00BE90); 633 WREG32(data_reg, 0x80188000);
698 WREG32(0x6578, 0x20502); 634 WREG32(index_reg, 0x20501);
699 WREG32(0x657C, 0xBF588500); 635 WREG32(data_reg, 0x8D00BE90);
700 WREG32(0x6578, 0x20503); 636 WREG32(index_reg, 0x20502);
701 WREG32(0x657C, 0x80008008); 637 WREG32(data_reg, 0xBF588500);
702 WREG32(0x6578, 0x20600); 638 WREG32(index_reg, 0x20503);
703 WREG32(0x657C, 0x80188000); 639 WREG32(data_reg, 0x80008008);
704 WREG32(0x6578, 0x20601); 640 WREG32(index_reg, 0x20600);
705 WREG32(0x657C, 0x8BC0BE98); 641 WREG32(data_reg, 0x80188000);
706 WREG32(0x6578, 0x20602); 642 WREG32(index_reg, 0x20601);
707 WREG32(0x657C, 0xBF308660); 643 WREG32(data_reg, 0x8BC0BE98);
708 WREG32(0x6578, 0x20603); 644 WREG32(index_reg, 0x20602);
709 WREG32(0x657C, 0x80008008); 645 WREG32(data_reg, 0xBF308660);
710 WREG32(0x6578, 0x20700); 646 WREG32(index_reg, 0x20603);
711 WREG32(0x657C, 0x80108000); 647 WREG32(data_reg, 0x80008008);
712 WREG32(0x6578, 0x20701); 648 WREG32(index_reg, 0x20700);
713 WREG32(0x657C, 0x8A80BEB0); 649 WREG32(data_reg, 0x80108000);
714 WREG32(0x6578, 0x20702); 650 WREG32(index_reg, 0x20701);
715 WREG32(0x657C, 0xBF0087C0); 651 WREG32(data_reg, 0x8A80BEB0);
716 WREG32(0x6578, 0x20703); 652 WREG32(index_reg, 0x20702);
717 WREG32(0x657C, 0x80008008); 653 WREG32(data_reg, 0xBF0087C0);
718 WREG32(0x6578, 0x20800); 654 WREG32(index_reg, 0x20703);
719 WREG32(0x657C, 0x80108000); 655 WREG32(data_reg, 0x80008008);
720 WREG32(0x6578, 0x20801); 656 WREG32(index_reg, 0x20800);
721 WREG32(0x657C, 0x8920BED0); 657 WREG32(data_reg, 0x80108000);
722 WREG32(0x6578, 0x20802); 658 WREG32(index_reg, 0x20801);
723 WREG32(0x657C, 0xBED08920); 659 WREG32(data_reg, 0x8920BED0);
724 WREG32(0x6578, 0x20803); 660 WREG32(index_reg, 0x20802);
725 WREG32(0x657C, 0x80008010); 661 WREG32(data_reg, 0xBED08920);
726 WREG32(0x6578, 0x30000); 662 WREG32(index_reg, 0x20803);
727 WREG32(0x657C, 0x90008000); 663 WREG32(data_reg, 0x80008010);
728 WREG32(0x6578, 0x30001); 664 WREG32(index_reg, 0x30000);
729 WREG32(0x657C, 0x80008000); 665 WREG32(data_reg, 0x90008000);
730 WREG32(0x6578, 0x30100); 666 WREG32(index_reg, 0x30001);
731 WREG32(0x657C, 0x8FE0BF90); 667 WREG32(data_reg, 0x80008000);
732 WREG32(0x6578, 0x30101); 668 WREG32(index_reg, 0x30100);
733 WREG32(0x657C, 0xBFF880A0); 669 WREG32(data_reg, 0x8FE0BF90);
734 WREG32(0x6578, 0x30200); 670 WREG32(index_reg, 0x30101);
735 WREG32(0x657C, 0x8F60BF40); 671 WREG32(data_reg, 0xBFF880A0);
736 WREG32(0x6578, 0x30201); 672 WREG32(index_reg, 0x30200);
737 WREG32(0x657C, 0xBFE88180); 673 WREG32(data_reg, 0x8F60BF40);
738 WREG32(0x6578, 0x30300); 674 WREG32(index_reg, 0x30201);
739 WREG32(0x657C, 0x8EC0BF00); 675 WREG32(data_reg, 0xBFE88180);
740 WREG32(0x6578, 0x30301); 676 WREG32(index_reg, 0x30300);
741 WREG32(0x657C, 0xBFC88280); 677 WREG32(data_reg, 0x8EC0BF00);
742 WREG32(0x6578, 0x30400); 678 WREG32(index_reg, 0x30301);
743 WREG32(0x657C, 0x8DE0BEE0); 679 WREG32(data_reg, 0xBFC88280);
744 WREG32(0x6578, 0x30401); 680 WREG32(index_reg, 0x30400);
745 WREG32(0x657C, 0xBFA083A0); 681 WREG32(data_reg, 0x8DE0BEE0);
746 WREG32(0x6578, 0x30500); 682 WREG32(index_reg, 0x30401);
747 WREG32(0x657C, 0x8CE0BED0); 683 WREG32(data_reg, 0xBFA083A0);
748 WREG32(0x6578, 0x30501); 684 WREG32(index_reg, 0x30500);
749 WREG32(0x657C, 0xBF7884E0); 685 WREG32(data_reg, 0x8CE0BED0);
750 WREG32(0x6578, 0x30600); 686 WREG32(index_reg, 0x30501);
751 WREG32(0x657C, 0x8BA0BED8); 687 WREG32(data_reg, 0xBF7884E0);
752 WREG32(0x6578, 0x30601); 688 WREG32(index_reg, 0x30600);
753 WREG32(0x657C, 0xBF508640); 689 WREG32(data_reg, 0x8BA0BED8);
754 WREG32(0x6578, 0x30700); 690 WREG32(index_reg, 0x30601);
755 WREG32(0x657C, 0x8A60BEE8); 691 WREG32(data_reg, 0xBF508640);
756 WREG32(0x6578, 0x30701); 692 WREG32(index_reg, 0x30700);
757 WREG32(0x657C, 0xBF2087A0); 693 WREG32(data_reg, 0x8A60BEE8);
758 WREG32(0x6578, 0x30800); 694 WREG32(index_reg, 0x30701);
759 WREG32(0x657C, 0x8900BF00); 695 WREG32(data_reg, 0xBF2087A0);
760 WREG32(0x6578, 0x30801); 696 WREG32(index_reg, 0x30800);
761 WREG32(0x657C, 0xBF008900); 697 WREG32(data_reg, 0x8900BF00);
698 WREG32(index_reg, 0x30801);
699 WREG32(data_reg, 0xBF008900);
762} 700}
763 701
764struct rv515_watermark { 702struct rv515_watermark {
diff --git a/drivers/gpu/drm/radeon/rv515r.h b/drivers/gpu/drm/radeon/rv515d.h
index f3cf84039906..a65e17ec1c08 100644
--- a/drivers/gpu/drm/radeon/rv515r.h
+++ b/drivers/gpu/drm/radeon/rv515d.h
@@ -25,10 +25,12 @@
25 * Alex Deucher 25 * Alex Deucher
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#ifndef RV515R_H 28#ifndef __RV515D_H__
29#define RV515R_H 29#define __RV515D_H__
30 30
31/* RV515 registers */ 31/*
32 * RV515 registers
33 */
32#define PCIE_INDEX 0x0030 34#define PCIE_INDEX 0x0030
33#define PCIE_DATA 0x0034 35#define PCIE_DATA 0x0034
34#define MC_IND_INDEX 0x0070 36#define MC_IND_INDEX 0x0070
@@ -166,5 +168,53 @@
166#define MC_GLOBW_INIT_LAT_MASK 0xF0000000 168#define MC_GLOBW_INIT_LAT_MASK 0xF0000000
167 169
168 170
171/*
172 * PM4 packet
173 */
174#define CP_PACKET0 0x00000000
175#define PACKET0_BASE_INDEX_SHIFT 0
176#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0)
177#define PACKET0_COUNT_SHIFT 16
178#define PACKET0_COUNT_MASK (0x3fff << 16)
179#define CP_PACKET1 0x40000000
180#define CP_PACKET2 0x80000000
181#define PACKET2_PAD_SHIFT 0
182#define PACKET2_PAD_MASK (0x3fffffff << 0)
183#define CP_PACKET3 0xC0000000
184#define PACKET3_IT_OPCODE_SHIFT 8
185#define PACKET3_IT_OPCODE_MASK (0xff << 8)
186#define PACKET3_COUNT_SHIFT 16
187#define PACKET3_COUNT_MASK (0x3fff << 16)
188/* PACKET3 op code */
189#define PACKET3_NOP 0x10
190#define PACKET3_3D_DRAW_VBUF 0x28
191#define PACKET3_3D_DRAW_IMMD 0x29
192#define PACKET3_3D_DRAW_INDX 0x2A
193#define PACKET3_3D_LOAD_VBPNTR 0x2F
194#define PACKET3_INDX_BUFFER 0x33
195#define PACKET3_3D_DRAW_VBUF_2 0x34
196#define PACKET3_3D_DRAW_IMMD_2 0x35
197#define PACKET3_3D_DRAW_INDX_2 0x36
198#define PACKET3_BITBLT_MULTI 0x9B
199
200#define PACKET0(reg, n) (CP_PACKET0 | \
201 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \
202 REG_SET(PACKET0_COUNT, (n)))
203#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
204#define PACKET3(op, n) (CP_PACKET3 | \
205 REG_SET(PACKET3_IT_OPCODE, (op)) | \
206 REG_SET(PACKET3_COUNT, (n)))
207
208#define PACKET_TYPE0 0
209#define PACKET_TYPE1 1
210#define PACKET_TYPE2 2
211#define PACKET_TYPE3 3
212
213#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
214#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
215#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
216#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
217#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
218
169#endif 219#endif
170 220
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 21d8ffd57308..b574c73a5109 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -25,100 +25,1038 @@
25 * Alex Deucher 25 * Alex Deucher
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include <linux/firmware.h>
29#include <linux/platform_device.h>
28#include "drmP.h" 30#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h" 31#include "radeon.h"
32#include "radeon_drm.h"
33#include "rv770d.h"
34#include "avivod.h"
35#include "atom.h"
31 36
32/* rv770,rv730,rv710 depends on : */ 37#define R700_PFP_UCODE_SIZE 848
33void rs600_mc_disable_clients(struct radeon_device *rdev); 38#define R700_PM4_UCODE_SIZE 1360
34 39
35/* This files gather functions specifics to: 40static void rv770_gpu_init(struct radeon_device *rdev);
36 * rv770,rv730,rv710 41void rv770_fini(struct radeon_device *rdev);
37 *
38 * Some of these functions might be used by newer ASICs.
39 */
40int rv770_mc_wait_for_idle(struct radeon_device *rdev);
41void rv770_gpu_init(struct radeon_device *rdev);
42 42
43 43
44/* 44/*
45 * MC 45 * GART
46 */ 46 */
47int rv770_mc_init(struct radeon_device *rdev) 47int rv770_pcie_gart_enable(struct radeon_device *rdev)
48{ 48{
49 uint32_t tmp; 49 u32 tmp;
50 int r, i;
50 51
51 rv770_gpu_init(rdev); 52 if (rdev->gart.table.vram.robj == NULL) {
53 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
54 return -EINVAL;
55 }
56 r = radeon_gart_table_vram_pin(rdev);
57 if (r)
58 return r;
59 /* Setup L2 cache */
60 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
61 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
62 EFFECTIVE_L2_QUEUE_SIZE(7));
63 WREG32(VM_L2_CNTL2, 0);
64 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
65 /* Setup TLB control */
66 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
67 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
68 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
69 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
70 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
71 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
72 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
73 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
74 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
75 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
76 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
77 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
78 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
79 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
80 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
81 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
82 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
83 (u32)(rdev->dummy_page.addr >> 12));
84 for (i = 1; i < 7; i++)
85 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
52 86
53 /* setup the gart before changing location so we can ask to 87 r600_pcie_gart_tlb_flush(rdev);
54 * discard unmapped mc request 88 rdev->gart.ready = true;
55 */
56 /* FIXME: disable out of gart access */
57 tmp = rdev->mc.gtt_location / 4096;
58 tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp);
59 WREG32(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp);
60 tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096;
61 tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp);
62 WREG32(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp);
63
64 rs600_mc_disable_clients(rdev);
65 if (rv770_mc_wait_for_idle(rdev)) {
66 printk(KERN_WARNING "Failed to wait MC idle while "
67 "programming pipes. Bad things might happen.\n");
68 }
69
70 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
71 tmp = REG_SET(R700_MC_FB_TOP, tmp >> 24);
72 tmp |= REG_SET(R700_MC_FB_BASE, rdev->mc.vram_location >> 24);
73 WREG32(R700_MC_VM_FB_LOCATION, tmp);
74 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
75 tmp = REG_SET(R700_MC_AGP_TOP, tmp >> 22);
76 WREG32(R700_MC_VM_AGP_TOP, tmp);
77 tmp = REG_SET(R700_MC_AGP_BOT, rdev->mc.gtt_location >> 22);
78 WREG32(R700_MC_VM_AGP_BOT, tmp);
79 return 0; 89 return 0;
80} 90}
81 91
82void rv770_mc_fini(struct radeon_device *rdev) 92void rv770_pcie_gart_disable(struct radeon_device *rdev)
93{
94 u32 tmp;
95 int i;
96
97 /* Disable all tables */
98 for (i = 0; i < 7; i++)
99 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
100
101 /* Setup L2 cache */
102 WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
103 EFFECTIVE_L2_QUEUE_SIZE(7));
104 WREG32(VM_L2_CNTL2, 0);
105 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
106 /* Setup TLB control */
107 tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
108 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
109 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
110 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
111 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
112 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
113 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
114 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
115 if (rdev->gart.table.vram.robj) {
116 radeon_object_kunmap(rdev->gart.table.vram.robj);
117 radeon_object_unpin(rdev->gart.table.vram.robj);
118 }
119}
120
121void rv770_pcie_gart_fini(struct radeon_device *rdev)
83{ 122{
84 /* FIXME: implement */ 123 rv770_pcie_gart_disable(rdev);
124 radeon_gart_table_vram_free(rdev);
125 radeon_gart_fini(rdev);
85} 126}
86 127
87 128
88/* 129/*
89 * Global GPU functions 130 * MC
90 */ 131 */
91void rv770_errata(struct radeon_device *rdev) 132static void rv770_mc_resume(struct radeon_device *rdev)
92{ 133{
93 rdev->pll_errata = 0; 134 u32 d1vga_control, d2vga_control;
135 u32 vga_render_control, vga_hdp_control;
136 u32 d1crtc_control, d2crtc_control;
137 u32 new_d1grph_primary, new_d1grph_secondary;
138 u32 new_d2grph_primary, new_d2grph_secondary;
139 u64 old_vram_start;
140 u32 tmp;
141 int i, j;
142
143 /* Initialize HDP */
144 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
145 WREG32((0x2c14 + j), 0x00000000);
146 WREG32((0x2c18 + j), 0x00000000);
147 WREG32((0x2c1c + j), 0x00000000);
148 WREG32((0x2c20 + j), 0x00000000);
149 WREG32((0x2c24 + j), 0x00000000);
150 }
151 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
152
153 d1vga_control = RREG32(D1VGA_CONTROL);
154 d2vga_control = RREG32(D2VGA_CONTROL);
155 vga_render_control = RREG32(VGA_RENDER_CONTROL);
156 vga_hdp_control = RREG32(VGA_HDP_CONTROL);
157 d1crtc_control = RREG32(D1CRTC_CONTROL);
158 d2crtc_control = RREG32(D2CRTC_CONTROL);
159 old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
160 new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
161 new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
162 new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
163 new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
164 new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
165 new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
166 new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
167 new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
168
169 /* Stop all video */
170 WREG32(D1VGA_CONTROL, 0);
171 WREG32(D2VGA_CONTROL, 0);
172 WREG32(VGA_RENDER_CONTROL, 0);
173 WREG32(D1CRTC_UPDATE_LOCK, 1);
174 WREG32(D2CRTC_UPDATE_LOCK, 1);
175 WREG32(D1CRTC_CONTROL, 0);
176 WREG32(D2CRTC_CONTROL, 0);
177 WREG32(D1CRTC_UPDATE_LOCK, 0);
178 WREG32(D2CRTC_UPDATE_LOCK, 0);
179
180 mdelay(1);
181 if (r600_mc_wait_for_idle(rdev)) {
182 printk(KERN_WARNING "[drm] MC not idle !\n");
183 }
184
185 /* Lockout access through VGA aperture*/
186 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
187
188 /* Update configuration */
189 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
190 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
191 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
192 tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
193 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
194 WREG32(MC_VM_FB_LOCATION, tmp);
195 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
196 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
197 WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
198 if (rdev->flags & RADEON_IS_AGP) {
199 WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
200 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
201 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
202 } else {
203 WREG32(MC_VM_AGP_BASE, 0);
204 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
205 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
206 }
207 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
208 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
209 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
210 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
211 WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
212
213 /* Unlock host access */
214 WREG32(VGA_HDP_CONTROL, vga_hdp_control);
215
216 mdelay(1);
217 if (r600_mc_wait_for_idle(rdev)) {
218 printk(KERN_WARNING "[drm] MC not idle !\n");
219 }
220
221 /* Restore video state */
222 WREG32(D1CRTC_UPDATE_LOCK, 1);
223 WREG32(D2CRTC_UPDATE_LOCK, 1);
224 WREG32(D1CRTC_CONTROL, d1crtc_control);
225 WREG32(D2CRTC_CONTROL, d2crtc_control);
226 WREG32(D1CRTC_UPDATE_LOCK, 0);
227 WREG32(D2CRTC_UPDATE_LOCK, 0);
228 WREG32(D1VGA_CONTROL, d1vga_control);
229 WREG32(D2VGA_CONTROL, d2vga_control);
230 WREG32(VGA_RENDER_CONTROL, vga_render_control);
231
232 /* we need to own VRAM, so turn off the VGA renderer here
233 * to stop it overwriting our objects */
234 radeon_avivo_vga_render_disable(rdev);
94} 235}
95 236
96int rv770_mc_wait_for_idle(struct radeon_device *rdev) 237
238/*
239 * CP.
240 */
241void r700_cp_stop(struct radeon_device *rdev)
97{ 242{
98 /* FIXME: implement */ 243 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
99 return 0;
100} 244}
101 245
102void rv770_gpu_init(struct radeon_device *rdev) 246
247static int rv770_cp_load_microcode(struct radeon_device *rdev)
103{ 248{
104 /* FIXME: implement */ 249 const __be32 *fw_data;
250 int i;
251
252 if (!rdev->me_fw || !rdev->pfp_fw)
253 return -EINVAL;
254
255 r700_cp_stop(rdev);
256 WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0));
257
258 /* Reset cp */
259 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
260 RREG32(GRBM_SOFT_RESET);
261 mdelay(15);
262 WREG32(GRBM_SOFT_RESET, 0);
263
264 fw_data = (const __be32 *)rdev->pfp_fw->data;
265 WREG32(CP_PFP_UCODE_ADDR, 0);
266 for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
267 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
268 WREG32(CP_PFP_UCODE_ADDR, 0);
269
270 fw_data = (const __be32 *)rdev->me_fw->data;
271 WREG32(CP_ME_RAM_WADDR, 0);
272 for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
273 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
274
275 WREG32(CP_PFP_UCODE_ADDR, 0);
276 WREG32(CP_ME_RAM_WADDR, 0);
277 WREG32(CP_ME_RAM_RADDR, 0);
278 return 0;
105} 279}
106 280
107 281
108/* 282/*
109 * VRAM info 283 * Core functions
110 */ 284 */
111void rv770_vram_get_type(struct radeon_device *rdev) 285static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
286 u32 num_backends,
287 u32 backend_disable_mask)
288{
289 u32 backend_map = 0;
290 u32 enabled_backends_mask;
291 u32 enabled_backends_count;
292 u32 cur_pipe;
293 u32 swizzle_pipe[R7XX_MAX_PIPES];
294 u32 cur_backend;
295 u32 i;
296
297 if (num_tile_pipes > R7XX_MAX_PIPES)
298 num_tile_pipes = R7XX_MAX_PIPES;
299 if (num_tile_pipes < 1)
300 num_tile_pipes = 1;
301 if (num_backends > R7XX_MAX_BACKENDS)
302 num_backends = R7XX_MAX_BACKENDS;
303 if (num_backends < 1)
304 num_backends = 1;
305
306 enabled_backends_mask = 0;
307 enabled_backends_count = 0;
308 for (i = 0; i < R7XX_MAX_BACKENDS; ++i) {
309 if (((backend_disable_mask >> i) & 1) == 0) {
310 enabled_backends_mask |= (1 << i);
311 ++enabled_backends_count;
312 }
313 if (enabled_backends_count == num_backends)
314 break;
315 }
316
317 if (enabled_backends_count == 0) {
318 enabled_backends_mask = 1;
319 enabled_backends_count = 1;
320 }
321
322 if (enabled_backends_count != num_backends)
323 num_backends = enabled_backends_count;
324
325 memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
326 switch (num_tile_pipes) {
327 case 1:
328 swizzle_pipe[0] = 0;
329 break;
330 case 2:
331 swizzle_pipe[0] = 0;
332 swizzle_pipe[1] = 1;
333 break;
334 case 3:
335 swizzle_pipe[0] = 0;
336 swizzle_pipe[1] = 2;
337 swizzle_pipe[2] = 1;
338 break;
339 case 4:
340 swizzle_pipe[0] = 0;
341 swizzle_pipe[1] = 2;
342 swizzle_pipe[2] = 3;
343 swizzle_pipe[3] = 1;
344 break;
345 case 5:
346 swizzle_pipe[0] = 0;
347 swizzle_pipe[1] = 2;
348 swizzle_pipe[2] = 4;
349 swizzle_pipe[3] = 1;
350 swizzle_pipe[4] = 3;
351 break;
352 case 6:
353 swizzle_pipe[0] = 0;
354 swizzle_pipe[1] = 2;
355 swizzle_pipe[2] = 4;
356 swizzle_pipe[3] = 5;
357 swizzle_pipe[4] = 3;
358 swizzle_pipe[5] = 1;
359 break;
360 case 7:
361 swizzle_pipe[0] = 0;
362 swizzle_pipe[1] = 2;
363 swizzle_pipe[2] = 4;
364 swizzle_pipe[3] = 6;
365 swizzle_pipe[4] = 3;
366 swizzle_pipe[5] = 1;
367 swizzle_pipe[6] = 5;
368 break;
369 case 8:
370 swizzle_pipe[0] = 0;
371 swizzle_pipe[1] = 2;
372 swizzle_pipe[2] = 4;
373 swizzle_pipe[3] = 6;
374 swizzle_pipe[4] = 3;
375 swizzle_pipe[5] = 1;
376 swizzle_pipe[6] = 7;
377 swizzle_pipe[7] = 5;
378 break;
379 }
380
381 cur_backend = 0;
382 for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
383 while (((1 << cur_backend) & enabled_backends_mask) == 0)
384 cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
385
386 backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
387
388 cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
389 }
390
391 return backend_map;
392}
393
394static void rv770_gpu_init(struct radeon_device *rdev)
112{ 395{
113 /* FIXME: implement */ 396 int i, j, num_qd_pipes;
397 u32 sx_debug_1;
398 u32 smx_dc_ctl0;
399 u32 num_gs_verts_per_thread;
400 u32 vgt_gs_per_es;
401 u32 gs_prim_buffer_depth = 0;
402 u32 sq_ms_fifo_sizes;
403 u32 sq_config;
404 u32 sq_thread_resource_mgmt;
405 u32 hdp_host_path_cntl;
406 u32 sq_dyn_gpr_size_simd_ab_0;
407 u32 backend_map;
408 u32 gb_tiling_config = 0;
409 u32 cc_rb_backend_disable = 0;
410 u32 cc_gc_shader_pipe_config = 0;
411 u32 mc_arb_ramcfg;
412 u32 db_debug4;
413
414 /* setup chip specs */
415 switch (rdev->family) {
416 case CHIP_RV770:
417 rdev->config.rv770.max_pipes = 4;
418 rdev->config.rv770.max_tile_pipes = 8;
419 rdev->config.rv770.max_simds = 10;
420 rdev->config.rv770.max_backends = 4;
421 rdev->config.rv770.max_gprs = 256;
422 rdev->config.rv770.max_threads = 248;
423 rdev->config.rv770.max_stack_entries = 512;
424 rdev->config.rv770.max_hw_contexts = 8;
425 rdev->config.rv770.max_gs_threads = 16 * 2;
426 rdev->config.rv770.sx_max_export_size = 128;
427 rdev->config.rv770.sx_max_export_pos_size = 16;
428 rdev->config.rv770.sx_max_export_smx_size = 112;
429 rdev->config.rv770.sq_num_cf_insts = 2;
430
431 rdev->config.rv770.sx_num_of_sets = 7;
432 rdev->config.rv770.sc_prim_fifo_size = 0xF9;
433 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
434 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
435 break;
436 case CHIP_RV730:
437 rdev->config.rv770.max_pipes = 2;
438 rdev->config.rv770.max_tile_pipes = 4;
439 rdev->config.rv770.max_simds = 8;
440 rdev->config.rv770.max_backends = 2;
441 rdev->config.rv770.max_gprs = 128;
442 rdev->config.rv770.max_threads = 248;
443 rdev->config.rv770.max_stack_entries = 256;
444 rdev->config.rv770.max_hw_contexts = 8;
445 rdev->config.rv770.max_gs_threads = 16 * 2;
446 rdev->config.rv770.sx_max_export_size = 256;
447 rdev->config.rv770.sx_max_export_pos_size = 32;
448 rdev->config.rv770.sx_max_export_smx_size = 224;
449 rdev->config.rv770.sq_num_cf_insts = 2;
450
451 rdev->config.rv770.sx_num_of_sets = 7;
452 rdev->config.rv770.sc_prim_fifo_size = 0xf9;
453 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
454 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
455 if (rdev->config.rv770.sx_max_export_pos_size > 16) {
456 rdev->config.rv770.sx_max_export_pos_size -= 16;
457 rdev->config.rv770.sx_max_export_smx_size += 16;
458 }
459 break;
460 case CHIP_RV710:
461 rdev->config.rv770.max_pipes = 2;
462 rdev->config.rv770.max_tile_pipes = 2;
463 rdev->config.rv770.max_simds = 2;
464 rdev->config.rv770.max_backends = 1;
465 rdev->config.rv770.max_gprs = 256;
466 rdev->config.rv770.max_threads = 192;
467 rdev->config.rv770.max_stack_entries = 256;
468 rdev->config.rv770.max_hw_contexts = 4;
469 rdev->config.rv770.max_gs_threads = 8 * 2;
470 rdev->config.rv770.sx_max_export_size = 128;
471 rdev->config.rv770.sx_max_export_pos_size = 16;
472 rdev->config.rv770.sx_max_export_smx_size = 112;
473 rdev->config.rv770.sq_num_cf_insts = 1;
474
475 rdev->config.rv770.sx_num_of_sets = 7;
476 rdev->config.rv770.sc_prim_fifo_size = 0x40;
477 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
478 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
479 break;
480 case CHIP_RV740:
481 rdev->config.rv770.max_pipes = 4;
482 rdev->config.rv770.max_tile_pipes = 4;
483 rdev->config.rv770.max_simds = 8;
484 rdev->config.rv770.max_backends = 4;
485 rdev->config.rv770.max_gprs = 256;
486 rdev->config.rv770.max_threads = 248;
487 rdev->config.rv770.max_stack_entries = 512;
488 rdev->config.rv770.max_hw_contexts = 8;
489 rdev->config.rv770.max_gs_threads = 16 * 2;
490 rdev->config.rv770.sx_max_export_size = 256;
491 rdev->config.rv770.sx_max_export_pos_size = 32;
492 rdev->config.rv770.sx_max_export_smx_size = 224;
493 rdev->config.rv770.sq_num_cf_insts = 2;
494
495 rdev->config.rv770.sx_num_of_sets = 7;
496 rdev->config.rv770.sc_prim_fifo_size = 0x100;
497 rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
498 rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
499
500 if (rdev->config.rv770.sx_max_export_pos_size > 16) {
501 rdev->config.rv770.sx_max_export_pos_size -= 16;
502 rdev->config.rv770.sx_max_export_smx_size += 16;
503 }
504 break;
505 default:
506 break;
507 }
508
509 /* Initialize HDP */
510 j = 0;
511 for (i = 0; i < 32; i++) {
512 WREG32((0x2c14 + j), 0x00000000);
513 WREG32((0x2c18 + j), 0x00000000);
514 WREG32((0x2c1c + j), 0x00000000);
515 WREG32((0x2c20 + j), 0x00000000);
516 WREG32((0x2c24 + j), 0x00000000);
517 j += 0x18;
518 }
519
520 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
521
522 /* setup tiling, simd, pipe config */
523 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
524
525 switch (rdev->config.rv770.max_tile_pipes) {
526 case 1:
527 gb_tiling_config |= PIPE_TILING(0);
528 break;
529 case 2:
530 gb_tiling_config |= PIPE_TILING(1);
531 break;
532 case 4:
533 gb_tiling_config |= PIPE_TILING(2);
534 break;
535 case 8:
536 gb_tiling_config |= PIPE_TILING(3);
537 break;
538 default:
539 break;
540 }
541
542 if (rdev->family == CHIP_RV770)
543 gb_tiling_config |= BANK_TILING(1);
544 else
545 gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK);
546
547 gb_tiling_config |= GROUP_SIZE(0);
548
549 if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) {
550 gb_tiling_config |= ROW_TILING(3);
551 gb_tiling_config |= SAMPLE_SPLIT(3);
552 } else {
553 gb_tiling_config |=
554 ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
555 gb_tiling_config |=
556 SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
557 }
558
559 gb_tiling_config |= BANK_SWAPS(1);
560
561 backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
562 rdev->config.rv770.max_backends,
563 (0xff << rdev->config.rv770.max_backends) & 0xff);
564 gb_tiling_config |= BACKEND_MAP(backend_map);
565
566 cc_gc_shader_pipe_config =
567 INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK);
568 cc_gc_shader_pipe_config |=
569 INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK);
570
571 cc_rb_backend_disable =
572 BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
573
574 WREG32(GB_TILING_CONFIG, gb_tiling_config);
575 WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
576 WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
577
578 WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
579 WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
580 WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
581
582 WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
583 WREG32(CGTS_SYS_TCC_DISABLE, 0);
584 WREG32(CGTS_TCC_DISABLE, 0);
585 WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
586 WREG32(CGTS_USER_TCC_DISABLE, 0);
587
588 num_qd_pipes =
589 R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK);
590 WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
591 WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
592
593 /* set HW defaults for 3D engine */
594 WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
595 ROQ_IB2_START(0x2b)));
596
597 WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
598
599 WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
600 SYNC_GRADIENT |
601 SYNC_WALKER |
602 SYNC_ALIGNER));
603
604 sx_debug_1 = RREG32(SX_DEBUG_1);
605 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
606 WREG32(SX_DEBUG_1, sx_debug_1);
607
608 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
609 smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff);
610 smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
611 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
612
613 WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
614 GS_FLUSH_CTL(4) |
615 ACK_FLUSH_CTL(3) |
616 SYNC_FLUSH_CTL));
617
618 if (rdev->family == CHIP_RV770)
619 WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
620 else {
621 db_debug4 = RREG32(DB_DEBUG4);
622 db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
623 WREG32(DB_DEBUG4, db_debug4);
624 }
625
626 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
627 POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
628 SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
629
630 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
631 SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
632 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
633
634 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
635
636 WREG32(VGT_NUM_INSTANCES, 1);
637
638 WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
639
640 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
641
642 WREG32(CP_PERFMON_CNTL, 0);
643
644 sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) |
645 DONE_FIFO_HIWATER(0xe0) |
646 ALU_UPDATE_FIFO_HIWATER(0x8));
647 switch (rdev->family) {
648 case CHIP_RV770:
649 sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
650 break;
651 case CHIP_RV730:
652 case CHIP_RV710:
653 case CHIP_RV740:
654 default:
655 sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
656 break;
657 }
658 WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
659
660 /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
661 * should be adjusted as needed by the 2D/3D drivers. This just sets default values
662 */
663 sq_config = RREG32(SQ_CONFIG);
664 sq_config &= ~(PS_PRIO(3) |
665 VS_PRIO(3) |
666 GS_PRIO(3) |
667 ES_PRIO(3));
668 sq_config |= (DX9_CONSTS |
669 VC_ENABLE |
670 EXPORT_SRC_C |
671 PS_PRIO(0) |
672 VS_PRIO(1) |
673 GS_PRIO(2) |
674 ES_PRIO(3));
675 if (rdev->family == CHIP_RV710)
676 /* no vertex cache */
677 sq_config &= ~VC_ENABLE;
678
679 WREG32(SQ_CONFIG, sq_config);
680
681 WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
682 NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
683 NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2)));
684
685 WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) |
686 NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64)));
687
688 sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) |
689 NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) |
690 NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8));
691 if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads)
692 sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads);
693 else
694 sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8);
695 WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
696
697 WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
698 NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
699
700 WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
701 NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
702
703 sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) |
704 SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) |
705 SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) |
706 SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64));
707
708 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
709 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
710 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
711 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
712 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
713 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
714 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
715 WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
716
717 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
718 FORCE_EOV_MAX_REZ_CNT(255)));
719
720 if (rdev->family == CHIP_RV710)
721 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) |
722 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
723 else
724 WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) |
725 AUTO_INVLD_EN(ES_AND_GS_AUTO)));
726
727 switch (rdev->family) {
728 case CHIP_RV770:
729 case CHIP_RV730:
730 case CHIP_RV740:
731 gs_prim_buffer_depth = 384;
732 break;
733 case CHIP_RV710:
734 gs_prim_buffer_depth = 128;
735 break;
736 default:
737 break;
738 }
739
740 num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16;
741 vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
742 /* Max value for this is 256 */
743 if (vgt_gs_per_es > 256)
744 vgt_gs_per_es = 256;
745
746 WREG32(VGT_ES_PER_GS, 128);
747 WREG32(VGT_GS_PER_ES, vgt_gs_per_es);
748 WREG32(VGT_GS_PER_VS, 2);
749
750 /* more default values. 2D/3D driver should adjust as needed */
751 WREG32(VGT_GS_VERTEX_REUSE, 16);
752 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
753 WREG32(VGT_STRMOUT_EN, 0);
754 WREG32(SX_MISC, 0);
755 WREG32(PA_SC_MODE_CNTL, 0);
756 WREG32(PA_SC_EDGERULE, 0xaaaaaaaa);
757 WREG32(PA_SC_AA_CONFIG, 0);
758 WREG32(PA_SC_CLIPRECT_RULE, 0xffff);
759 WREG32(PA_SC_LINE_STIPPLE, 0);
760 WREG32(SPI_INPUT_Z, 0);
761 WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
762 WREG32(CB_COLOR7_FRAG, 0);
763
764 /* clear render buffer base addresses */
765 WREG32(CB_COLOR0_BASE, 0);
766 WREG32(CB_COLOR1_BASE, 0);
767 WREG32(CB_COLOR2_BASE, 0);
768 WREG32(CB_COLOR3_BASE, 0);
769 WREG32(CB_COLOR4_BASE, 0);
770 WREG32(CB_COLOR5_BASE, 0);
771 WREG32(CB_COLOR6_BASE, 0);
772 WREG32(CB_COLOR7_BASE, 0);
773
774 WREG32(TCP_CNTL, 0);
775
776 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
777 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
778
779 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
780
781 WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
782 NUM_CLIP_SEQ(3)));
783
114} 784}
115 785
116void rv770_vram_info(struct radeon_device *rdev) 786int rv770_mc_init(struct radeon_device *rdev)
117{ 787{
118 rv770_vram_get_type(rdev); 788 fixed20_12 a;
789 u32 tmp;
790 int r;
119 791
120 /* FIXME: implement */ 792 /* Get VRAM informations */
793 /* FIXME: Don't know how to determine vram width, need to check
794 * vram_width usage
795 */
796 rdev->mc.vram_width = 128;
797 rdev->mc.vram_is_ddr = true;
121 /* Could aper size report 0 ? */ 798 /* Could aper size report 0 ? */
122 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); 799 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
123 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); 800 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
801 /* Setup GPU memory space */
802 rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
803 rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
804 if (rdev->flags & RADEON_IS_AGP) {
805 r = radeon_agp_init(rdev);
806 if (r)
807 return r;
808 /* gtt_size is setup by radeon_agp_init */
809 rdev->mc.gtt_location = rdev->mc.agp_base;
810 tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
811 /* Try to put vram before or after AGP because we
812 * we want SYSTEM_APERTURE to cover both VRAM and
813 * AGP so that GPU can catch out of VRAM/AGP access
814 */
815 if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
816 /* Enought place before */
817 rdev->mc.vram_location = rdev->mc.gtt_location -
818 rdev->mc.mc_vram_size;
819 } else if (tmp > rdev->mc.mc_vram_size) {
820 /* Enought place after */
821 rdev->mc.vram_location = rdev->mc.gtt_location +
822 rdev->mc.gtt_size;
823 } else {
824 /* Try to setup VRAM then AGP might not
825 * not work on some card
826 */
827 rdev->mc.vram_location = 0x00000000UL;
828 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
829 }
830 } else {
831 rdev->mc.vram_location = 0x00000000UL;
832 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
833 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
834 }
835 rdev->mc.vram_start = rdev->mc.vram_location;
836 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
837 rdev->mc.gtt_start = rdev->mc.gtt_location;
838 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
839 /* FIXME: we should enforce default clock in case GPU is not in
840 * default setup
841 */
842 a.full = rfixed_const(100);
843 rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
844 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
845 return 0;
846}
847int rv770_gpu_reset(struct radeon_device *rdev)
848{
849 /* FIXME: implement any rv770 specific bits */
850 return r600_gpu_reset(rdev);
851}
852
853static int rv770_startup(struct radeon_device *rdev)
854{
855 int r;
856
857 radeon_gpu_reset(rdev);
858 rv770_mc_resume(rdev);
859 r = rv770_pcie_gart_enable(rdev);
860 if (r)
861 return r;
862 rv770_gpu_init(rdev);
863
864 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
865 &rdev->r600_blit.shader_gpu_addr);
866 if (r) {
867 DRM_ERROR("failed to pin blit object %d\n", r);
868 return r;
869 }
870
871 r = radeon_ring_init(rdev, rdev->cp.ring_size);
872 if (r)
873 return r;
874 r = rv770_cp_load_microcode(rdev);
875 if (r)
876 return r;
877 r = r600_cp_resume(rdev);
878 if (r)
879 return r;
880 r = r600_wb_init(rdev);
881 if (r)
882 return r;
883 return 0;
884}
885
886int rv770_resume(struct radeon_device *rdev)
887{
888 int r;
889
890 if (radeon_gpu_reset(rdev)) {
891 /* FIXME: what do we want to do here ? */
892 }
893 /* post card */
894 if (rdev->is_atom_bios) {
895 atom_asic_init(rdev->mode_info.atom_context);
896 } else {
897 radeon_combios_asic_init(rdev->ddev);
898 }
899 /* Initialize clocks */
900 r = radeon_clocks_init(rdev);
901 if (r) {
902 return r;
903 }
904
905 r = rv770_startup(rdev);
906 if (r) {
907 DRM_ERROR("r600 startup failed on resume\n");
908 return r;
909 }
910
911 r = radeon_ib_test(rdev);
912 if (r) {
913 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
914 return r;
915 }
916 return r;
917
918}
919
920int rv770_suspend(struct radeon_device *rdev)
921{
922 /* FIXME: we should wait for ring to be empty */
923 r700_cp_stop(rdev);
924 rdev->cp.ready = false;
925 rv770_pcie_gart_disable(rdev);
926
927 /* unpin shaders bo */
928 radeon_object_unpin(rdev->r600_blit.shader_obj);
929 return 0;
930}
931
932/* Plan is to move initialization in that function and use
933 * helper function so that radeon_device_init pretty much
934 * do nothing more than calling asic specific function. This
935 * should also allow to remove a bunch of callback function
936 * like vram_info.
937 */
938int rv770_init(struct radeon_device *rdev)
939{
940 int r;
941
942 rdev->new_init_path = true;
943 r = radeon_dummy_page_init(rdev);
944 if (r)
945 return r;
946 /* This don't do much */
947 r = radeon_gem_init(rdev);
948 if (r)
949 return r;
950 /* Read BIOS */
951 if (!radeon_get_bios(rdev)) {
952 if (ASIC_IS_AVIVO(rdev))
953 return -EINVAL;
954 }
955 /* Must be an ATOMBIOS */
956 if (!rdev->is_atom_bios)
957 return -EINVAL;
958 r = radeon_atombios_init(rdev);
959 if (r)
960 return r;
961 /* Post card if necessary */
962 if (!r600_card_posted(rdev) && rdev->bios) {
963 DRM_INFO("GPU not posted. posting now...\n");
964 atom_asic_init(rdev->mode_info.atom_context);
965 }
966 /* Initialize scratch registers */
967 r600_scratch_init(rdev);
968 /* Initialize surface registers */
969 radeon_surface_init(rdev);
970 radeon_get_clock_info(rdev->ddev);
971 r = radeon_clocks_init(rdev);
972 if (r)
973 return r;
974 /* Fence driver */
975 r = radeon_fence_driver_init(rdev);
976 if (r)
977 return r;
978 r = rv770_mc_init(rdev);
979 if (r) {
980 if (rdev->flags & RADEON_IS_AGP) {
981 /* Retry with disabling AGP */
982 rv770_fini(rdev);
983 rdev->flags &= ~RADEON_IS_AGP;
984 return rv770_init(rdev);
985 }
986 return r;
987 }
988 /* Memory manager */
989 r = radeon_object_init(rdev);
990 if (r)
991 return r;
992 rdev->cp.ring_obj = NULL;
993 r600_ring_init(rdev, 1024 * 1024);
994
995 if (!rdev->me_fw || !rdev->pfp_fw) {
996 r = r600_cp_init_microcode(rdev);
997 if (r) {
998 DRM_ERROR("Failed to load firmware!\n");
999 return r;
1000 }
1001 }
1002
1003 r = r600_pcie_gart_init(rdev);
1004 if (r)
1005 return r;
1006
1007 rdev->accel_working = true;
1008 r = r600_blit_init(rdev);
1009 if (r) {
1010 DRM_ERROR("radeon: failled blitter (%d).\n", r);
1011 rdev->accel_working = false;
1012 }
1013
1014 r = rv770_startup(rdev);
1015 if (r) {
1016 if (rdev->flags & RADEON_IS_AGP) {
1017 /* Retry with disabling AGP */
1018 rv770_fini(rdev);
1019 rdev->flags &= ~RADEON_IS_AGP;
1020 return rv770_init(rdev);
1021 }
1022 rdev->accel_working = false;
1023 }
1024 if (rdev->accel_working) {
1025 r = radeon_ib_pool_init(rdev);
1026 if (r) {
1027 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
1028 rdev->accel_working = false;
1029 }
1030 r = radeon_ib_test(rdev);
1031 if (r) {
1032 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1033 rdev->accel_working = false;
1034 }
1035 }
1036 return 0;
1037}
1038
1039void rv770_fini(struct radeon_device *rdev)
1040{
1041 rv770_suspend(rdev);
1042
1043 r600_blit_fini(rdev);
1044 radeon_ring_fini(rdev);
1045 rv770_pcie_gart_fini(rdev);
1046 radeon_gem_fini(rdev);
1047 radeon_fence_driver_fini(rdev);
1048 radeon_clocks_fini(rdev);
1049#if __OS_HAS_AGP
1050 if (rdev->flags & RADEON_IS_AGP)
1051 radeon_agp_fini(rdev);
1052#endif
1053 radeon_object_fini(rdev);
1054 if (rdev->is_atom_bios) {
1055 radeon_atombios_fini(rdev);
1056 } else {
1057 radeon_combios_fini(rdev);
1058 }
1059 kfree(rdev->bios);
1060 rdev->bios = NULL;
1061 radeon_dummy_page_fini(rdev);
124} 1062}
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
new file mode 100644
index 000000000000..4b9c3d6396ff
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -0,0 +1,341 @@
1/*
2 * Copyright 2009 Advanced Micro Devices, Inc.
3 * Copyright 2009 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: Dave Airlie
24 * Alex Deucher
25 * Jerome Glisse
26 */
27#ifndef RV770_H
28#define RV770_H
29
30#define R7XX_MAX_SH_GPRS 256
31#define R7XX_MAX_TEMP_GPRS 16
32#define R7XX_MAX_SH_THREADS 256
33#define R7XX_MAX_SH_STACK_ENTRIES 4096
34#define R7XX_MAX_BACKENDS 8
35#define R7XX_MAX_BACKENDS_MASK 0xff
36#define R7XX_MAX_SIMDS 16
37#define R7XX_MAX_SIMDS_MASK 0xffff
38#define R7XX_MAX_PIPES 8
39#define R7XX_MAX_PIPES_MASK 0xff
40
41/* Registers */
42#define CB_COLOR0_BASE 0x28040
43#define CB_COLOR1_BASE 0x28044
44#define CB_COLOR2_BASE 0x28048
45#define CB_COLOR3_BASE 0x2804C
46#define CB_COLOR4_BASE 0x28050
47#define CB_COLOR5_BASE 0x28054
48#define CB_COLOR6_BASE 0x28058
49#define CB_COLOR7_BASE 0x2805C
50#define CB_COLOR7_FRAG 0x280FC
51
52#define CC_GC_SHADER_PIPE_CONFIG 0x8950
53#define CC_RB_BACKEND_DISABLE 0x98F4
54#define BACKEND_DISABLE(x) ((x) << 16)
55#define CC_SYS_RB_BACKEND_DISABLE 0x3F88
56
57#define CGTS_SYS_TCC_DISABLE 0x3F90
58#define CGTS_TCC_DISABLE 0x9148
59#define CGTS_USER_SYS_TCC_DISABLE 0x3F94
60#define CGTS_USER_TCC_DISABLE 0x914C
61
62#define CONFIG_MEMSIZE 0x5428
63
64#define CP_ME_CNTL 0x86D8
65#define CP_ME_HALT (1<<28)
66#define CP_PFP_HALT (1<<26)
67#define CP_ME_RAM_DATA 0xC160
68#define CP_ME_RAM_RADDR 0xC158
69#define CP_ME_RAM_WADDR 0xC15C
70#define CP_MEQ_THRESHOLDS 0x8764
71#define STQ_SPLIT(x) ((x) << 0)
72#define CP_PERFMON_CNTL 0x87FC
73#define CP_PFP_UCODE_ADDR 0xC150
74#define CP_PFP_UCODE_DATA 0xC154
75#define CP_QUEUE_THRESHOLDS 0x8760
76#define ROQ_IB1_START(x) ((x) << 0)
77#define ROQ_IB2_START(x) ((x) << 8)
78#define CP_RB_CNTL 0xC104
79#define RB_BUFSZ(x) ((x)<<0)
80#define RB_BLKSZ(x) ((x)<<8)
81#define RB_NO_UPDATE (1<<27)
82#define RB_RPTR_WR_ENA (1<<31)
83#define BUF_SWAP_32BIT (2 << 16)
84#define CP_RB_RPTR 0x8700
85#define CP_RB_RPTR_ADDR 0xC10C
86#define CP_RB_RPTR_ADDR_HI 0xC110
87#define CP_RB_RPTR_WR 0xC108
88#define CP_RB_WPTR 0xC114
89#define CP_RB_WPTR_ADDR 0xC118
90#define CP_RB_WPTR_ADDR_HI 0xC11C
91#define CP_RB_WPTR_DELAY 0x8704
92#define CP_SEM_WAIT_TIMER 0x85BC
93
94#define DB_DEBUG3 0x98B0
95#define DB_CLK_OFF_DELAY(x) ((x) << 11)
96#define DB_DEBUG4 0x9B8C
97#define DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6)
98
99#define DCP_TILING_CONFIG 0x6CA0
100#define PIPE_TILING(x) ((x) << 1)
101#define BANK_TILING(x) ((x) << 4)
102#define GROUP_SIZE(x) ((x) << 6)
103#define ROW_TILING(x) ((x) << 8)
104#define BANK_SWAPS(x) ((x) << 11)
105#define SAMPLE_SPLIT(x) ((x) << 14)
106#define BACKEND_MAP(x) ((x) << 16)
107
108#define GB_TILING_CONFIG 0x98F0
109
110#define GC_USER_SHADER_PIPE_CONFIG 0x8954
111#define INACTIVE_QD_PIPES(x) ((x) << 8)
112#define INACTIVE_QD_PIPES_MASK 0x0000FF00
113#define INACTIVE_SIMDS(x) ((x) << 16)
114#define INACTIVE_SIMDS_MASK 0x00FF0000
115
116#define GRBM_CNTL 0x8000
117#define GRBM_READ_TIMEOUT(x) ((x) << 0)
118#define GRBM_SOFT_RESET 0x8020
119#define SOFT_RESET_CP (1<<0)
120#define GRBM_STATUS 0x8010
121#define CMDFIFO_AVAIL_MASK 0x0000000F
122#define GUI_ACTIVE (1<<31)
123#define GRBM_STATUS2 0x8014
124
125#define HDP_HOST_PATH_CNTL 0x2C00
126#define HDP_NONSURFACE_BASE 0x2C04
127#define HDP_NONSURFACE_INFO 0x2C08
128#define HDP_NONSURFACE_SIZE 0x2C0C
129#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
130#define HDP_TILING_CONFIG 0x2F3C
131
132#define MC_ARB_RAMCFG 0x2760
133#define NOOFBANK_SHIFT 0
134#define NOOFBANK_MASK 0x00000003
135#define NOOFRANK_SHIFT 2
136#define NOOFRANK_MASK 0x00000004
137#define NOOFROWS_SHIFT 3
138#define NOOFROWS_MASK 0x00000038
139#define NOOFCOLS_SHIFT 6
140#define NOOFCOLS_MASK 0x000000C0
141#define CHANSIZE_SHIFT 8
142#define CHANSIZE_MASK 0x00000100
143#define BURSTLENGTH_SHIFT 9
144#define BURSTLENGTH_MASK 0x00000200
145#define MC_VM_AGP_TOP 0x2028
146#define MC_VM_AGP_BOT 0x202C
147#define MC_VM_AGP_BASE 0x2030
148#define MC_VM_FB_LOCATION 0x2024
149#define MC_VM_MB_L1_TLB0_CNTL 0x2234
150#define MC_VM_MB_L1_TLB1_CNTL 0x2238
151#define MC_VM_MB_L1_TLB2_CNTL 0x223C
152#define MC_VM_MB_L1_TLB3_CNTL 0x2240
153#define ENABLE_L1_TLB (1 << 0)
154#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1)
155#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3)
156#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3)
157#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3)
158#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3)
159#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5)
160#define EFFECTIVE_L1_TLB_SIZE(x) ((x)<<15)
161#define EFFECTIVE_L1_QUEUE_SIZE(x) ((x)<<18)
162#define MC_VM_MD_L1_TLB0_CNTL 0x2654
163#define MC_VM_MD_L1_TLB1_CNTL 0x2658
164#define MC_VM_MD_L1_TLB2_CNTL 0x265C
165#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C
166#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038
167#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034
168
169#define PA_CL_ENHANCE 0x8A14
170#define CLIP_VTX_REORDER_ENA (1 << 0)
171#define NUM_CLIP_SEQ(x) ((x) << 1)
172#define PA_SC_AA_CONFIG 0x28C04
173#define PA_SC_CLIPRECT_RULE 0x2820C
174#define PA_SC_EDGERULE 0x28230
175#define PA_SC_FIFO_SIZE 0x8BCC
176#define SC_PRIM_FIFO_SIZE(x) ((x) << 0)
177#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12)
178#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24
179#define FORCE_EOV_MAX_CLK_CNT(x) ((x)<<0)
180#define FORCE_EOV_MAX_REZ_CNT(x) ((x)<<16)
181#define PA_SC_LINE_STIPPLE 0x28A0C
182#define PA_SC_LINE_STIPPLE_STATE 0x8B10
183#define PA_SC_MODE_CNTL 0x28A4C
184#define PA_SC_MULTI_CHIP_CNTL 0x8B20
185#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20)
186
187#define SCRATCH_REG0 0x8500
188#define SCRATCH_REG1 0x8504
189#define SCRATCH_REG2 0x8508
190#define SCRATCH_REG3 0x850C
191#define SCRATCH_REG4 0x8510
192#define SCRATCH_REG5 0x8514
193#define SCRATCH_REG6 0x8518
194#define SCRATCH_REG7 0x851C
195#define SCRATCH_UMSK 0x8540
196#define SCRATCH_ADDR 0x8544
197
198#define SMX_DC_CTL0 0xA020
199#define USE_HASH_FUNCTION (1 << 0)
200#define CACHE_DEPTH(x) ((x) << 1)
201#define FLUSH_ALL_ON_EVENT (1 << 10)
202#define STALL_ON_EVENT (1 << 11)
203#define SMX_EVENT_CTL 0xA02C
204#define ES_FLUSH_CTL(x) ((x) << 0)
205#define GS_FLUSH_CTL(x) ((x) << 3)
206#define ACK_FLUSH_CTL(x) ((x) << 6)
207#define SYNC_FLUSH_CTL (1 << 8)
208
209#define SPI_CONFIG_CNTL 0x9100
210#define GPR_WRITE_PRIORITY(x) ((x) << 0)
211#define DISABLE_INTERP_1 (1 << 5)
212#define SPI_CONFIG_CNTL_1 0x913C
213#define VTX_DONE_DELAY(x) ((x) << 0)
214#define INTERP_ONE_PRIM_PER_ROW (1 << 4)
215#define SPI_INPUT_Z 0x286D8
216#define SPI_PS_IN_CONTROL_0 0x286CC
217#define NUM_INTERP(x) ((x)<<0)
218#define POSITION_ENA (1<<8)
219#define POSITION_CENTROID (1<<9)
220#define POSITION_ADDR(x) ((x)<<10)
221#define PARAM_GEN(x) ((x)<<15)
222#define PARAM_GEN_ADDR(x) ((x)<<19)
223#define BARYC_SAMPLE_CNTL(x) ((x)<<26)
224#define PERSP_GRADIENT_ENA (1<<28)
225#define LINEAR_GRADIENT_ENA (1<<29)
226#define POSITION_SAMPLE (1<<30)
227#define BARYC_AT_SAMPLE_ENA (1<<31)
228
229#define SQ_CONFIG 0x8C00
230#define VC_ENABLE (1 << 0)
231#define EXPORT_SRC_C (1 << 1)
232#define DX9_CONSTS (1 << 2)
233#define ALU_INST_PREFER_VECTOR (1 << 3)
234#define DX10_CLAMP (1 << 4)
235#define CLAUSE_SEQ_PRIO(x) ((x) << 8)
236#define PS_PRIO(x) ((x) << 24)
237#define VS_PRIO(x) ((x) << 26)
238#define GS_PRIO(x) ((x) << 28)
239#define SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8DB0
240#define SIMDA_RING0(x) ((x)<<0)
241#define SIMDA_RING1(x) ((x)<<8)
242#define SIMDB_RING0(x) ((x)<<16)
243#define SIMDB_RING1(x) ((x)<<24)
244#define SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8DB4
245#define SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8DB8
246#define SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8DBC
247#define SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8DC0
248#define SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8DC4
249#define SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8DC8
250#define SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8DCC
251#define ES_PRIO(x) ((x) << 30)
252#define SQ_GPR_RESOURCE_MGMT_1 0x8C04
253#define NUM_PS_GPRS(x) ((x) << 0)
254#define NUM_VS_GPRS(x) ((x) << 16)
255#define DYN_GPR_ENABLE (1 << 27)
256#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28)
257#define SQ_GPR_RESOURCE_MGMT_2 0x8C08
258#define NUM_GS_GPRS(x) ((x) << 0)
259#define NUM_ES_GPRS(x) ((x) << 16)
260#define SQ_MS_FIFO_SIZES 0x8CF0
261#define CACHE_FIFO_SIZE(x) ((x) << 0)
262#define FETCH_FIFO_HIWATER(x) ((x) << 8)
263#define DONE_FIFO_HIWATER(x) ((x) << 16)
264#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24)
265#define SQ_STACK_RESOURCE_MGMT_1 0x8C10
266#define NUM_PS_STACK_ENTRIES(x) ((x) << 0)
267#define NUM_VS_STACK_ENTRIES(x) ((x) << 16)
268#define SQ_STACK_RESOURCE_MGMT_2 0x8C14
269#define NUM_GS_STACK_ENTRIES(x) ((x) << 0)
270#define NUM_ES_STACK_ENTRIES(x) ((x) << 16)
271#define SQ_THREAD_RESOURCE_MGMT 0x8C0C
272#define NUM_PS_THREADS(x) ((x) << 0)
273#define NUM_VS_THREADS(x) ((x) << 8)
274#define NUM_GS_THREADS(x) ((x) << 16)
275#define NUM_ES_THREADS(x) ((x) << 24)
276
277#define SX_DEBUG_1 0x9058
278#define ENABLE_NEW_SMX_ADDRESS (1 << 16)
279#define SX_EXPORT_BUFFER_SIZES 0x900C
280#define COLOR_BUFFER_SIZE(x) ((x) << 0)
281#define POSITION_BUFFER_SIZE(x) ((x) << 8)
282#define SMX_BUFFER_SIZE(x) ((x) << 16)
283#define SX_MISC 0x28350
284
285#define TA_CNTL_AUX 0x9508
286#define DISABLE_CUBE_WRAP (1 << 0)
287#define DISABLE_CUBE_ANISO (1 << 1)
288#define SYNC_GRADIENT (1 << 24)
289#define SYNC_WALKER (1 << 25)
290#define SYNC_ALIGNER (1 << 26)
291#define BILINEAR_PRECISION_6_BIT (0 << 31)
292#define BILINEAR_PRECISION_8_BIT (1 << 31)
293
294#define TCP_CNTL 0x9610
295
296#define VGT_CACHE_INVALIDATION 0x88C4
297#define CACHE_INVALIDATION(x) ((x)<<0)
298#define VC_ONLY 0
299#define TC_ONLY 1
300#define VC_AND_TC 2
301#define AUTO_INVLD_EN(x) ((x) << 6)
302#define NO_AUTO 0
303#define ES_AUTO 1
304#define GS_AUTO 2
305#define ES_AND_GS_AUTO 3
306#define VGT_ES_PER_GS 0x88CC
307#define VGT_GS_PER_ES 0x88C8
308#define VGT_GS_PER_VS 0x88E8
309#define VGT_GS_VERTEX_REUSE 0x88D4
310#define VGT_NUM_INSTANCES 0x8974
311#define VGT_OUT_DEALLOC_CNTL 0x28C5C
312#define DEALLOC_DIST_MASK 0x0000007F
313#define VGT_STRMOUT_EN 0x28AB0
314#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58
315#define VTX_REUSE_DEPTH_MASK 0x000000FF
316
317#define VM_CONTEXT0_CNTL 0x1410
318#define ENABLE_CONTEXT (1 << 0)
319#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1)
320#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
321#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C
322#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C
323#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C
324#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518
325#define VM_L2_CNTL 0x1400
326#define ENABLE_L2_CACHE (1 << 0)
327#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1)
328#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9)
329#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14)
330#define VM_L2_CNTL2 0x1404
331#define INVALIDATE_ALL_L1_TLBS (1 << 0)
332#define INVALIDATE_L2_CACHE (1 << 1)
333#define VM_L2_CNTL3 0x1408
334#define BANK_SELECT(x) ((x) << 0)
335#define CACHE_UPDATE_MODE(x) ((x) << 6)
336#define VM_L2_STATUS 0x140C
337#define L2_BUSY (1 << 0)
338
339#define WAIT_UNTIL 0x8040
340
341#endif
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index c2b0d710d10f..87c06252d464 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -44,6 +44,39 @@
44 44
45static int ttm_bo_setup_vm(struct ttm_buffer_object *bo); 45static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
46static int ttm_bo_swapout(struct ttm_mem_shrink *shrink); 46static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
47static void ttm_bo_global_kobj_release(struct kobject *kobj);
48
49static struct attribute ttm_bo_count = {
50 .name = "bo_count",
51 .mode = S_IRUGO
52};
53
54static ssize_t ttm_bo_global_show(struct kobject *kobj,
55 struct attribute *attr,
56 char *buffer)
57{
58 struct ttm_bo_global *glob =
59 container_of(kobj, struct ttm_bo_global, kobj);
60
61 return snprintf(buffer, PAGE_SIZE, "%lu\n",
62 (unsigned long) atomic_read(&glob->bo_count));
63}
64
65static struct attribute *ttm_bo_global_attrs[] = {
66 &ttm_bo_count,
67 NULL
68};
69
70static struct sysfs_ops ttm_bo_global_ops = {
71 .show = &ttm_bo_global_show
72};
73
74static struct kobj_type ttm_bo_glob_kobj_type = {
75 .release = &ttm_bo_global_kobj_release,
76 .sysfs_ops = &ttm_bo_global_ops,
77 .default_attrs = ttm_bo_global_attrs
78};
79
47 80
48static inline uint32_t ttm_bo_type_flags(unsigned type) 81static inline uint32_t ttm_bo_type_flags(unsigned type)
49{ 82{
@@ -66,10 +99,11 @@ static void ttm_bo_release_list(struct kref *list_kref)
66 99
67 if (bo->ttm) 100 if (bo->ttm)
68 ttm_tt_destroy(bo->ttm); 101 ttm_tt_destroy(bo->ttm);
102 atomic_dec(&bo->glob->bo_count);
69 if (bo->destroy) 103 if (bo->destroy)
70 bo->destroy(bo); 104 bo->destroy(bo);
71 else { 105 else {
72 ttm_mem_global_free(bdev->mem_glob, bo->acc_size, false); 106 ttm_mem_global_free(bdev->glob->mem_glob, bo->acc_size);
73 kfree(bo); 107 kfree(bo);
74 } 108 }
75} 109}
@@ -106,7 +140,7 @@ static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
106 kref_get(&bo->list_kref); 140 kref_get(&bo->list_kref);
107 141
108 if (bo->ttm != NULL) { 142 if (bo->ttm != NULL) {
109 list_add_tail(&bo->swap, &bdev->swap_lru); 143 list_add_tail(&bo->swap, &bo->glob->swap_lru);
110 kref_get(&bo->list_kref); 144 kref_get(&bo->list_kref);
111 } 145 }
112 } 146 }
@@ -141,7 +175,7 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
141 bool interruptible, 175 bool interruptible,
142 bool no_wait, bool use_sequence, uint32_t sequence) 176 bool no_wait, bool use_sequence, uint32_t sequence)
143{ 177{
144 struct ttm_bo_device *bdev = bo->bdev; 178 struct ttm_bo_global *glob = bo->glob;
145 int ret; 179 int ret;
146 180
147 while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { 181 while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
@@ -153,9 +187,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
153 if (no_wait) 187 if (no_wait)
154 return -EBUSY; 188 return -EBUSY;
155 189
156 spin_unlock(&bdev->lru_lock); 190 spin_unlock(&glob->lru_lock);
157 ret = ttm_bo_wait_unreserved(bo, interruptible); 191 ret = ttm_bo_wait_unreserved(bo, interruptible);
158 spin_lock(&bdev->lru_lock); 192 spin_lock(&glob->lru_lock);
159 193
160 if (unlikely(ret)) 194 if (unlikely(ret))
161 return ret; 195 return ret;
@@ -181,16 +215,16 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo,
181 bool interruptible, 215 bool interruptible,
182 bool no_wait, bool use_sequence, uint32_t sequence) 216 bool no_wait, bool use_sequence, uint32_t sequence)
183{ 217{
184 struct ttm_bo_device *bdev = bo->bdev; 218 struct ttm_bo_global *glob = bo->glob;
185 int put_count = 0; 219 int put_count = 0;
186 int ret; 220 int ret;
187 221
188 spin_lock(&bdev->lru_lock); 222 spin_lock(&glob->lru_lock);
189 ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence, 223 ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence,
190 sequence); 224 sequence);
191 if (likely(ret == 0)) 225 if (likely(ret == 0))
192 put_count = ttm_bo_del_from_lru(bo); 226 put_count = ttm_bo_del_from_lru(bo);
193 spin_unlock(&bdev->lru_lock); 227 spin_unlock(&glob->lru_lock);
194 228
195 while (put_count--) 229 while (put_count--)
196 kref_put(&bo->list_kref, ttm_bo_ref_bug); 230 kref_put(&bo->list_kref, ttm_bo_ref_bug);
@@ -200,13 +234,13 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo,
200 234
201void ttm_bo_unreserve(struct ttm_buffer_object *bo) 235void ttm_bo_unreserve(struct ttm_buffer_object *bo)
202{ 236{
203 struct ttm_bo_device *bdev = bo->bdev; 237 struct ttm_bo_global *glob = bo->glob;
204 238
205 spin_lock(&bdev->lru_lock); 239 spin_lock(&glob->lru_lock);
206 ttm_bo_add_to_lru(bo); 240 ttm_bo_add_to_lru(bo);
207 atomic_set(&bo->reserved, 0); 241 atomic_set(&bo->reserved, 0);
208 wake_up_all(&bo->event_queue); 242 wake_up_all(&bo->event_queue);
209 spin_unlock(&bdev->lru_lock); 243 spin_unlock(&glob->lru_lock);
210} 244}
211EXPORT_SYMBOL(ttm_bo_unreserve); 245EXPORT_SYMBOL(ttm_bo_unreserve);
212 246
@@ -217,6 +251,7 @@ EXPORT_SYMBOL(ttm_bo_unreserve);
217static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) 251static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
218{ 252{
219 struct ttm_bo_device *bdev = bo->bdev; 253 struct ttm_bo_device *bdev = bo->bdev;
254 struct ttm_bo_global *glob = bo->glob;
220 int ret = 0; 255 int ret = 0;
221 uint32_t page_flags = 0; 256 uint32_t page_flags = 0;
222 257
@@ -232,14 +267,14 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
232 page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC; 267 page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC;
233 case ttm_bo_type_kernel: 268 case ttm_bo_type_kernel:
234 bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, 269 bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
235 page_flags, bdev->dummy_read_page); 270 page_flags, glob->dummy_read_page);
236 if (unlikely(bo->ttm == NULL)) 271 if (unlikely(bo->ttm == NULL))
237 ret = -ENOMEM; 272 ret = -ENOMEM;
238 break; 273 break;
239 case ttm_bo_type_user: 274 case ttm_bo_type_user:
240 bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, 275 bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
241 page_flags | TTM_PAGE_FLAG_USER, 276 page_flags | TTM_PAGE_FLAG_USER,
242 bdev->dummy_read_page); 277 glob->dummy_read_page);
243 if (unlikely(bo->ttm == NULL)) 278 if (unlikely(bo->ttm == NULL))
244 ret = -ENOMEM; 279 ret = -ENOMEM;
245 break; 280 break;
@@ -360,6 +395,7 @@ out_err:
360static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) 395static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
361{ 396{
362 struct ttm_bo_device *bdev = bo->bdev; 397 struct ttm_bo_device *bdev = bo->bdev;
398 struct ttm_bo_global *glob = bo->glob;
363 struct ttm_bo_driver *driver = bdev->driver; 399 struct ttm_bo_driver *driver = bdev->driver;
364 int ret; 400 int ret;
365 401
@@ -371,7 +407,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
371 407
372 spin_unlock(&bo->lock); 408 spin_unlock(&bo->lock);
373 409
374 spin_lock(&bdev->lru_lock); 410 spin_lock(&glob->lru_lock);
375 ret = ttm_bo_reserve_locked(bo, false, false, false, 0); 411 ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
376 BUG_ON(ret); 412 BUG_ON(ret);
377 if (bo->ttm) 413 if (bo->ttm)
@@ -386,7 +422,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
386 bo->mem.mm_node = NULL; 422 bo->mem.mm_node = NULL;
387 } 423 }
388 put_count = ttm_bo_del_from_lru(bo); 424 put_count = ttm_bo_del_from_lru(bo);
389 spin_unlock(&bdev->lru_lock); 425 spin_unlock(&glob->lru_lock);
390 426
391 atomic_set(&bo->reserved, 0); 427 atomic_set(&bo->reserved, 0);
392 428
@@ -396,14 +432,14 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
396 return 0; 432 return 0;
397 } 433 }
398 434
399 spin_lock(&bdev->lru_lock); 435 spin_lock(&glob->lru_lock);
400 if (list_empty(&bo->ddestroy)) { 436 if (list_empty(&bo->ddestroy)) {
401 void *sync_obj = bo->sync_obj; 437 void *sync_obj = bo->sync_obj;
402 void *sync_obj_arg = bo->sync_obj_arg; 438 void *sync_obj_arg = bo->sync_obj_arg;
403 439
404 kref_get(&bo->list_kref); 440 kref_get(&bo->list_kref);
405 list_add_tail(&bo->ddestroy, &bdev->ddestroy); 441 list_add_tail(&bo->ddestroy, &bdev->ddestroy);
406 spin_unlock(&bdev->lru_lock); 442 spin_unlock(&glob->lru_lock);
407 spin_unlock(&bo->lock); 443 spin_unlock(&bo->lock);
408 444
409 if (sync_obj) 445 if (sync_obj)
@@ -413,7 +449,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
413 ret = 0; 449 ret = 0;
414 450
415 } else { 451 } else {
416 spin_unlock(&bdev->lru_lock); 452 spin_unlock(&glob->lru_lock);
417 spin_unlock(&bo->lock); 453 spin_unlock(&bo->lock);
418 ret = -EBUSY; 454 ret = -EBUSY;
419 } 455 }
@@ -428,11 +464,12 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
428 464
429static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) 465static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
430{ 466{
467 struct ttm_bo_global *glob = bdev->glob;
431 struct ttm_buffer_object *entry, *nentry; 468 struct ttm_buffer_object *entry, *nentry;
432 struct list_head *list, *next; 469 struct list_head *list, *next;
433 int ret; 470 int ret;
434 471
435 spin_lock(&bdev->lru_lock); 472 spin_lock(&glob->lru_lock);
436 list_for_each_safe(list, next, &bdev->ddestroy) { 473 list_for_each_safe(list, next, &bdev->ddestroy) {
437 entry = list_entry(list, struct ttm_buffer_object, ddestroy); 474 entry = list_entry(list, struct ttm_buffer_object, ddestroy);
438 nentry = NULL; 475 nentry = NULL;
@@ -449,16 +486,16 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
449 } 486 }
450 kref_get(&entry->list_kref); 487 kref_get(&entry->list_kref);
451 488
452 spin_unlock(&bdev->lru_lock); 489 spin_unlock(&glob->lru_lock);
453 ret = ttm_bo_cleanup_refs(entry, remove_all); 490 ret = ttm_bo_cleanup_refs(entry, remove_all);
454 kref_put(&entry->list_kref, ttm_bo_release_list); 491 kref_put(&entry->list_kref, ttm_bo_release_list);
455 492
456 spin_lock(&bdev->lru_lock); 493 spin_lock(&glob->lru_lock);
457 if (nentry) { 494 if (nentry) {
458 bool next_onlist = !list_empty(next); 495 bool next_onlist = !list_empty(next);
459 spin_unlock(&bdev->lru_lock); 496 spin_unlock(&glob->lru_lock);
460 kref_put(&nentry->list_kref, ttm_bo_release_list); 497 kref_put(&nentry->list_kref, ttm_bo_release_list);
461 spin_lock(&bdev->lru_lock); 498 spin_lock(&glob->lru_lock);
462 /* 499 /*
463 * Someone might have raced us and removed the 500 * Someone might have raced us and removed the
464 * next entry from the list. We don't bother restarting 501 * next entry from the list. We don't bother restarting
@@ -472,7 +509,7 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
472 break; 509 break;
473 } 510 }
474 ret = !list_empty(&bdev->ddestroy); 511 ret = !list_empty(&bdev->ddestroy);
475 spin_unlock(&bdev->lru_lock); 512 spin_unlock(&glob->lru_lock);
476 513
477 return ret; 514 return ret;
478} 515}
@@ -522,6 +559,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
522{ 559{
523 int ret = 0; 560 int ret = 0;
524 struct ttm_bo_device *bdev = bo->bdev; 561 struct ttm_bo_device *bdev = bo->bdev;
562 struct ttm_bo_global *glob = bo->glob;
525 struct ttm_mem_reg evict_mem; 563 struct ttm_mem_reg evict_mem;
526 uint32_t proposed_placement; 564 uint32_t proposed_placement;
527 565
@@ -570,12 +608,12 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
570 goto out; 608 goto out;
571 } 609 }
572 610
573 spin_lock(&bdev->lru_lock); 611 spin_lock(&glob->lru_lock);
574 if (evict_mem.mm_node) { 612 if (evict_mem.mm_node) {
575 drm_mm_put_block(evict_mem.mm_node); 613 drm_mm_put_block(evict_mem.mm_node);
576 evict_mem.mm_node = NULL; 614 evict_mem.mm_node = NULL;
577 } 615 }
578 spin_unlock(&bdev->lru_lock); 616 spin_unlock(&glob->lru_lock);
579 bo->evicted = true; 617 bo->evicted = true;
580out: 618out:
581 return ret; 619 return ret;
@@ -590,6 +628,7 @@ static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
590 uint32_t mem_type, 628 uint32_t mem_type,
591 bool interruptible, bool no_wait) 629 bool interruptible, bool no_wait)
592{ 630{
631 struct ttm_bo_global *glob = bdev->glob;
593 struct drm_mm_node *node; 632 struct drm_mm_node *node;
594 struct ttm_buffer_object *entry; 633 struct ttm_buffer_object *entry;
595 struct ttm_mem_type_manager *man = &bdev->man[mem_type]; 634 struct ttm_mem_type_manager *man = &bdev->man[mem_type];
@@ -603,7 +642,7 @@ retry_pre_get:
603 if (unlikely(ret != 0)) 642 if (unlikely(ret != 0))
604 return ret; 643 return ret;
605 644
606 spin_lock(&bdev->lru_lock); 645 spin_lock(&glob->lru_lock);
607 do { 646 do {
608 node = drm_mm_search_free(&man->manager, num_pages, 647 node = drm_mm_search_free(&man->manager, num_pages,
609 mem->page_alignment, 1); 648 mem->page_alignment, 1);
@@ -624,7 +663,7 @@ retry_pre_get:
624 if (likely(ret == 0)) 663 if (likely(ret == 0))
625 put_count = ttm_bo_del_from_lru(entry); 664 put_count = ttm_bo_del_from_lru(entry);
626 665
627 spin_unlock(&bdev->lru_lock); 666 spin_unlock(&glob->lru_lock);
628 667
629 if (unlikely(ret != 0)) 668 if (unlikely(ret != 0))
630 return ret; 669 return ret;
@@ -640,21 +679,21 @@ retry_pre_get:
640 if (ret) 679 if (ret)
641 return ret; 680 return ret;
642 681
643 spin_lock(&bdev->lru_lock); 682 spin_lock(&glob->lru_lock);
644 } while (1); 683 } while (1);
645 684
646 if (!node) { 685 if (!node) {
647 spin_unlock(&bdev->lru_lock); 686 spin_unlock(&glob->lru_lock);
648 return -ENOMEM; 687 return -ENOMEM;
649 } 688 }
650 689
651 node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment); 690 node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment);
652 if (unlikely(!node)) { 691 if (unlikely(!node)) {
653 spin_unlock(&bdev->lru_lock); 692 spin_unlock(&glob->lru_lock);
654 goto retry_pre_get; 693 goto retry_pre_get;
655 } 694 }
656 695
657 spin_unlock(&bdev->lru_lock); 696 spin_unlock(&glob->lru_lock);
658 mem->mm_node = node; 697 mem->mm_node = node;
659 mem->mem_type = mem_type; 698 mem->mem_type = mem_type;
660 return 0; 699 return 0;
@@ -723,6 +762,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
723 bool interruptible, bool no_wait) 762 bool interruptible, bool no_wait)
724{ 763{
725 struct ttm_bo_device *bdev = bo->bdev; 764 struct ttm_bo_device *bdev = bo->bdev;
765 struct ttm_bo_global *glob = bo->glob;
726 struct ttm_mem_type_manager *man; 766 struct ttm_mem_type_manager *man;
727 767
728 uint32_t num_prios = bdev->driver->num_mem_type_prio; 768 uint32_t num_prios = bdev->driver->num_mem_type_prio;
@@ -762,20 +802,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
762 if (unlikely(ret)) 802 if (unlikely(ret))
763 return ret; 803 return ret;
764 804
765 spin_lock(&bdev->lru_lock); 805 spin_lock(&glob->lru_lock);
766 node = drm_mm_search_free(&man->manager, 806 node = drm_mm_search_free(&man->manager,
767 mem->num_pages, 807 mem->num_pages,
768 mem->page_alignment, 808 mem->page_alignment,
769 1); 809 1);
770 if (unlikely(!node)) { 810 if (unlikely(!node)) {
771 spin_unlock(&bdev->lru_lock); 811 spin_unlock(&glob->lru_lock);
772 break; 812 break;
773 } 813 }
774 node = drm_mm_get_block_atomic(node, 814 node = drm_mm_get_block_atomic(node,
775 mem->num_pages, 815 mem->num_pages,
776 mem-> 816 mem->
777 page_alignment); 817 page_alignment);
778 spin_unlock(&bdev->lru_lock); 818 spin_unlock(&glob->lru_lock);
779 } while (!node); 819 } while (!node);
780 } 820 }
781 if (node) 821 if (node)
@@ -848,7 +888,7 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
848 uint32_t proposed_placement, 888 uint32_t proposed_placement,
849 bool interruptible, bool no_wait) 889 bool interruptible, bool no_wait)
850{ 890{
851 struct ttm_bo_device *bdev = bo->bdev; 891 struct ttm_bo_global *glob = bo->glob;
852 int ret = 0; 892 int ret = 0;
853 struct ttm_mem_reg mem; 893 struct ttm_mem_reg mem;
854 894
@@ -884,9 +924,9 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
884 924
885out_unlock: 925out_unlock:
886 if (ret && mem.mm_node) { 926 if (ret && mem.mm_node) {
887 spin_lock(&bdev->lru_lock); 927 spin_lock(&glob->lru_lock);
888 drm_mm_put_block(mem.mm_node); 928 drm_mm_put_block(mem.mm_node);
889 spin_unlock(&bdev->lru_lock); 929 spin_unlock(&glob->lru_lock);
890 } 930 }
891 return ret; 931 return ret;
892} 932}
@@ -1022,6 +1062,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
1022 INIT_LIST_HEAD(&bo->ddestroy); 1062 INIT_LIST_HEAD(&bo->ddestroy);
1023 INIT_LIST_HEAD(&bo->swap); 1063 INIT_LIST_HEAD(&bo->swap);
1024 bo->bdev = bdev; 1064 bo->bdev = bdev;
1065 bo->glob = bdev->glob;
1025 bo->type = type; 1066 bo->type = type;
1026 bo->num_pages = num_pages; 1067 bo->num_pages = num_pages;
1027 bo->mem.mem_type = TTM_PL_SYSTEM; 1068 bo->mem.mem_type = TTM_PL_SYSTEM;
@@ -1034,6 +1075,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
1034 bo->seq_valid = false; 1075 bo->seq_valid = false;
1035 bo->persistant_swap_storage = persistant_swap_storage; 1076 bo->persistant_swap_storage = persistant_swap_storage;
1036 bo->acc_size = acc_size; 1077 bo->acc_size = acc_size;
1078 atomic_inc(&bo->glob->bo_count);
1037 1079
1038 ret = ttm_bo_check_placement(bo, flags, 0ULL); 1080 ret = ttm_bo_check_placement(bo, flags, 0ULL);
1039 if (unlikely(ret != 0)) 1081 if (unlikely(ret != 0))
@@ -1072,13 +1114,13 @@ out_err:
1072} 1114}
1073EXPORT_SYMBOL(ttm_buffer_object_init); 1115EXPORT_SYMBOL(ttm_buffer_object_init);
1074 1116
1075static inline size_t ttm_bo_size(struct ttm_bo_device *bdev, 1117static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
1076 unsigned long num_pages) 1118 unsigned long num_pages)
1077{ 1119{
1078 size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) & 1120 size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
1079 PAGE_MASK; 1121 PAGE_MASK;
1080 1122
1081 return bdev->ttm_bo_size + 2 * page_array_size; 1123 return glob->ttm_bo_size + 2 * page_array_size;
1082} 1124}
1083 1125
1084int ttm_buffer_object_create(struct ttm_bo_device *bdev, 1126int ttm_buffer_object_create(struct ttm_bo_device *bdev,
@@ -1093,18 +1135,18 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev,
1093{ 1135{
1094 struct ttm_buffer_object *bo; 1136 struct ttm_buffer_object *bo;
1095 int ret; 1137 int ret;
1096 struct ttm_mem_global *mem_glob = bdev->mem_glob; 1138 struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
1097 1139
1098 size_t acc_size = 1140 size_t acc_size =
1099 ttm_bo_size(bdev, (size + PAGE_SIZE - 1) >> PAGE_SHIFT); 1141 ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
1100 ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false); 1142 ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
1101 if (unlikely(ret != 0)) 1143 if (unlikely(ret != 0))
1102 return ret; 1144 return ret;
1103 1145
1104 bo = kzalloc(sizeof(*bo), GFP_KERNEL); 1146 bo = kzalloc(sizeof(*bo), GFP_KERNEL);
1105 1147
1106 if (unlikely(bo == NULL)) { 1148 if (unlikely(bo == NULL)) {
1107 ttm_mem_global_free(mem_glob, acc_size, false); 1149 ttm_mem_global_free(mem_glob, acc_size);
1108 return -ENOMEM; 1150 return -ENOMEM;
1109 } 1151 }
1110 1152
@@ -1150,6 +1192,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
1150 struct list_head *head, 1192 struct list_head *head,
1151 unsigned mem_type, bool allow_errors) 1193 unsigned mem_type, bool allow_errors)
1152{ 1194{
1195 struct ttm_bo_global *glob = bdev->glob;
1153 struct ttm_buffer_object *entry; 1196 struct ttm_buffer_object *entry;
1154 int ret; 1197 int ret;
1155 int put_count; 1198 int put_count;
@@ -1158,30 +1201,31 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
1158 * Can't use standard list traversal since we're unlocking. 1201 * Can't use standard list traversal since we're unlocking.
1159 */ 1202 */
1160 1203
1161 spin_lock(&bdev->lru_lock); 1204 spin_lock(&glob->lru_lock);
1162 1205
1163 while (!list_empty(head)) { 1206 while (!list_empty(head)) {
1164 entry = list_first_entry(head, struct ttm_buffer_object, lru); 1207 entry = list_first_entry(head, struct ttm_buffer_object, lru);
1165 kref_get(&entry->list_kref); 1208 kref_get(&entry->list_kref);
1166 ret = ttm_bo_reserve_locked(entry, false, false, false, 0); 1209 ret = ttm_bo_reserve_locked(entry, false, false, false, 0);
1167 put_count = ttm_bo_del_from_lru(entry); 1210 put_count = ttm_bo_del_from_lru(entry);
1168 spin_unlock(&bdev->lru_lock); 1211 spin_unlock(&glob->lru_lock);
1169 while (put_count--) 1212 while (put_count--)
1170 kref_put(&entry->list_kref, ttm_bo_ref_bug); 1213 kref_put(&entry->list_kref, ttm_bo_ref_bug);
1171 BUG_ON(ret); 1214 BUG_ON(ret);
1172 ret = ttm_bo_leave_list(entry, mem_type, allow_errors); 1215 ret = ttm_bo_leave_list(entry, mem_type, allow_errors);
1173 ttm_bo_unreserve(entry); 1216 ttm_bo_unreserve(entry);
1174 kref_put(&entry->list_kref, ttm_bo_release_list); 1217 kref_put(&entry->list_kref, ttm_bo_release_list);
1175 spin_lock(&bdev->lru_lock); 1218 spin_lock(&glob->lru_lock);
1176 } 1219 }
1177 1220
1178 spin_unlock(&bdev->lru_lock); 1221 spin_unlock(&glob->lru_lock);
1179 1222
1180 return 0; 1223 return 0;
1181} 1224}
1182 1225
1183int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) 1226int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
1184{ 1227{
1228 struct ttm_bo_global *glob = bdev->glob;
1185 struct ttm_mem_type_manager *man; 1229 struct ttm_mem_type_manager *man;
1186 int ret = -EINVAL; 1230 int ret = -EINVAL;
1187 1231
@@ -1204,13 +1248,13 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
1204 if (mem_type > 0) { 1248 if (mem_type > 0) {
1205 ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false); 1249 ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false);
1206 1250
1207 spin_lock(&bdev->lru_lock); 1251 spin_lock(&glob->lru_lock);
1208 if (drm_mm_clean(&man->manager)) 1252 if (drm_mm_clean(&man->manager))
1209 drm_mm_takedown(&man->manager); 1253 drm_mm_takedown(&man->manager);
1210 else 1254 else
1211 ret = -EBUSY; 1255 ret = -EBUSY;
1212 1256
1213 spin_unlock(&bdev->lru_lock); 1257 spin_unlock(&glob->lru_lock);
1214 } 1258 }
1215 1259
1216 return ret; 1260 return ret;
@@ -1284,11 +1328,82 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
1284} 1328}
1285EXPORT_SYMBOL(ttm_bo_init_mm); 1329EXPORT_SYMBOL(ttm_bo_init_mm);
1286 1330
1331static void ttm_bo_global_kobj_release(struct kobject *kobj)
1332{
1333 struct ttm_bo_global *glob =
1334 container_of(kobj, struct ttm_bo_global, kobj);
1335
1336 ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink);
1337 __free_page(glob->dummy_read_page);
1338 kfree(glob);
1339}
1340
1341void ttm_bo_global_release(struct ttm_global_reference *ref)
1342{
1343 struct ttm_bo_global *glob = ref->object;
1344
1345 kobject_del(&glob->kobj);
1346 kobject_put(&glob->kobj);
1347}
1348EXPORT_SYMBOL(ttm_bo_global_release);
1349
1350int ttm_bo_global_init(struct ttm_global_reference *ref)
1351{
1352 struct ttm_bo_global_ref *bo_ref =
1353 container_of(ref, struct ttm_bo_global_ref, ref);
1354 struct ttm_bo_global *glob = ref->object;
1355 int ret;
1356
1357 mutex_init(&glob->device_list_mutex);
1358 spin_lock_init(&glob->lru_lock);
1359 glob->mem_glob = bo_ref->mem_glob;
1360 glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
1361
1362 if (unlikely(glob->dummy_read_page == NULL)) {
1363 ret = -ENOMEM;
1364 goto out_no_drp;
1365 }
1366
1367 INIT_LIST_HEAD(&glob->swap_lru);
1368 INIT_LIST_HEAD(&glob->device_list);
1369
1370 ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout);
1371 ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink);
1372 if (unlikely(ret != 0)) {
1373 printk(KERN_ERR TTM_PFX
1374 "Could not register buffer object swapout.\n");
1375 goto out_no_shrink;
1376 }
1377
1378 glob->ttm_bo_extra_size =
1379 ttm_round_pot(sizeof(struct ttm_tt)) +
1380 ttm_round_pot(sizeof(struct ttm_backend));
1381
1382 glob->ttm_bo_size = glob->ttm_bo_extra_size +
1383 ttm_round_pot(sizeof(struct ttm_buffer_object));
1384
1385 atomic_set(&glob->bo_count, 0);
1386
1387 kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type);
1388 ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects");
1389 if (unlikely(ret != 0))
1390 kobject_put(&glob->kobj);
1391 return ret;
1392out_no_shrink:
1393 __free_page(glob->dummy_read_page);
1394out_no_drp:
1395 kfree(glob);
1396 return ret;
1397}
1398EXPORT_SYMBOL(ttm_bo_global_init);
1399
1400
1287int ttm_bo_device_release(struct ttm_bo_device *bdev) 1401int ttm_bo_device_release(struct ttm_bo_device *bdev)
1288{ 1402{
1289 int ret = 0; 1403 int ret = 0;
1290 unsigned i = TTM_NUM_MEM_TYPES; 1404 unsigned i = TTM_NUM_MEM_TYPES;
1291 struct ttm_mem_type_manager *man; 1405 struct ttm_mem_type_manager *man;
1406 struct ttm_bo_global *glob = bdev->glob;
1292 1407
1293 while (i--) { 1408 while (i--) {
1294 man = &bdev->man[i]; 1409 man = &bdev->man[i];
@@ -1304,100 +1419,74 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev)
1304 } 1419 }
1305 } 1420 }
1306 1421
1422 mutex_lock(&glob->device_list_mutex);
1423 list_del(&bdev->device_list);
1424 mutex_unlock(&glob->device_list_mutex);
1425
1307 if (!cancel_delayed_work(&bdev->wq)) 1426 if (!cancel_delayed_work(&bdev->wq))
1308 flush_scheduled_work(); 1427 flush_scheduled_work();
1309 1428
1310 while (ttm_bo_delayed_delete(bdev, true)) 1429 while (ttm_bo_delayed_delete(bdev, true))
1311 ; 1430 ;
1312 1431
1313 spin_lock(&bdev->lru_lock); 1432 spin_lock(&glob->lru_lock);
1314 if (list_empty(&bdev->ddestroy)) 1433 if (list_empty(&bdev->ddestroy))
1315 TTM_DEBUG("Delayed destroy list was clean\n"); 1434 TTM_DEBUG("Delayed destroy list was clean\n");
1316 1435
1317 if (list_empty(&bdev->man[0].lru)) 1436 if (list_empty(&bdev->man[0].lru))
1318 TTM_DEBUG("Swap list was clean\n"); 1437 TTM_DEBUG("Swap list was clean\n");
1319 spin_unlock(&bdev->lru_lock); 1438 spin_unlock(&glob->lru_lock);
1320 1439
1321 ttm_mem_unregister_shrink(bdev->mem_glob, &bdev->shrink);
1322 BUG_ON(!drm_mm_clean(&bdev->addr_space_mm)); 1440 BUG_ON(!drm_mm_clean(&bdev->addr_space_mm));
1323 write_lock(&bdev->vm_lock); 1441 write_lock(&bdev->vm_lock);
1324 drm_mm_takedown(&bdev->addr_space_mm); 1442 drm_mm_takedown(&bdev->addr_space_mm);
1325 write_unlock(&bdev->vm_lock); 1443 write_unlock(&bdev->vm_lock);
1326 1444
1327 __free_page(bdev->dummy_read_page);
1328 return ret; 1445 return ret;
1329} 1446}
1330EXPORT_SYMBOL(ttm_bo_device_release); 1447EXPORT_SYMBOL(ttm_bo_device_release);
1331 1448
1332/*
1333 * This function is intended to be called on drm driver load.
1334 * If you decide to call it from firstopen, you must protect the call
1335 * from a potentially racing ttm_bo_driver_finish in lastclose.
1336 * (This may happen on X server restart).
1337 */
1338
1339int ttm_bo_device_init(struct ttm_bo_device *bdev, 1449int ttm_bo_device_init(struct ttm_bo_device *bdev,
1340 struct ttm_mem_global *mem_glob, 1450 struct ttm_bo_global *glob,
1341 struct ttm_bo_driver *driver, uint64_t file_page_offset, 1451 struct ttm_bo_driver *driver,
1452 uint64_t file_page_offset,
1342 bool need_dma32) 1453 bool need_dma32)
1343{ 1454{
1344 int ret = -EINVAL; 1455 int ret = -EINVAL;
1345 1456
1346 bdev->dummy_read_page = NULL;
1347 rwlock_init(&bdev->vm_lock); 1457 rwlock_init(&bdev->vm_lock);
1348 spin_lock_init(&bdev->lru_lock);
1349
1350 bdev->driver = driver; 1458 bdev->driver = driver;
1351 bdev->mem_glob = mem_glob;
1352 1459
1353 memset(bdev->man, 0, sizeof(bdev->man)); 1460 memset(bdev->man, 0, sizeof(bdev->man));
1354 1461
1355 bdev->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
1356 if (unlikely(bdev->dummy_read_page == NULL)) {
1357 ret = -ENOMEM;
1358 goto out_err0;
1359 }
1360
1361 /* 1462 /*
1362 * Initialize the system memory buffer type. 1463 * Initialize the system memory buffer type.
1363 * Other types need to be driver / IOCTL initialized. 1464 * Other types need to be driver / IOCTL initialized.
1364 */ 1465 */
1365 ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0); 1466 ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0);
1366 if (unlikely(ret != 0)) 1467 if (unlikely(ret != 0))
1367 goto out_err1; 1468 goto out_no_sys;
1368 1469
1369 bdev->addr_space_rb = RB_ROOT; 1470 bdev->addr_space_rb = RB_ROOT;
1370 ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000); 1471 ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
1371 if (unlikely(ret != 0)) 1472 if (unlikely(ret != 0))
1372 goto out_err2; 1473 goto out_no_addr_mm;
1373 1474
1374 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); 1475 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
1375 bdev->nice_mode = true; 1476 bdev->nice_mode = true;
1376 INIT_LIST_HEAD(&bdev->ddestroy); 1477 INIT_LIST_HEAD(&bdev->ddestroy);
1377 INIT_LIST_HEAD(&bdev->swap_lru);
1378 bdev->dev_mapping = NULL; 1478 bdev->dev_mapping = NULL;
1479 bdev->glob = glob;
1379 bdev->need_dma32 = need_dma32; 1480 bdev->need_dma32 = need_dma32;
1380 ttm_mem_init_shrink(&bdev->shrink, ttm_bo_swapout);
1381 ret = ttm_mem_register_shrink(mem_glob, &bdev->shrink);
1382 if (unlikely(ret != 0)) {
1383 printk(KERN_ERR TTM_PFX
1384 "Could not register buffer object swapout.\n");
1385 goto out_err2;
1386 }
1387 1481
1388 bdev->ttm_bo_extra_size = 1482 mutex_lock(&glob->device_list_mutex);
1389 ttm_round_pot(sizeof(struct ttm_tt)) + 1483 list_add_tail(&bdev->device_list, &glob->device_list);
1390 ttm_round_pot(sizeof(struct ttm_backend)); 1484 mutex_unlock(&glob->device_list_mutex);
1391
1392 bdev->ttm_bo_size = bdev->ttm_bo_extra_size +
1393 ttm_round_pot(sizeof(struct ttm_buffer_object));
1394 1485
1395 return 0; 1486 return 0;
1396out_err2: 1487out_no_addr_mm:
1397 ttm_bo_clean_mm(bdev, 0); 1488 ttm_bo_clean_mm(bdev, 0);
1398out_err1: 1489out_no_sys:
1399 __free_page(bdev->dummy_read_page);
1400out_err0:
1401 return ret; 1490 return ret;
1402} 1491}
1403EXPORT_SYMBOL(ttm_bo_device_init); 1492EXPORT_SYMBOL(ttm_bo_device_init);
@@ -1647,21 +1736,21 @@ void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
1647 1736
1648static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) 1737static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
1649{ 1738{
1650 struct ttm_bo_device *bdev = 1739 struct ttm_bo_global *glob =
1651 container_of(shrink, struct ttm_bo_device, shrink); 1740 container_of(shrink, struct ttm_bo_global, shrink);
1652 struct ttm_buffer_object *bo; 1741 struct ttm_buffer_object *bo;
1653 int ret = -EBUSY; 1742 int ret = -EBUSY;
1654 int put_count; 1743 int put_count;
1655 uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); 1744 uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
1656 1745
1657 spin_lock(&bdev->lru_lock); 1746 spin_lock(&glob->lru_lock);
1658 while (ret == -EBUSY) { 1747 while (ret == -EBUSY) {
1659 if (unlikely(list_empty(&bdev->swap_lru))) { 1748 if (unlikely(list_empty(&glob->swap_lru))) {
1660 spin_unlock(&bdev->lru_lock); 1749 spin_unlock(&glob->lru_lock);
1661 return -EBUSY; 1750 return -EBUSY;
1662 } 1751 }
1663 1752
1664 bo = list_first_entry(&bdev->swap_lru, 1753 bo = list_first_entry(&glob->swap_lru,
1665 struct ttm_buffer_object, swap); 1754 struct ttm_buffer_object, swap);
1666 kref_get(&bo->list_kref); 1755 kref_get(&bo->list_kref);
1667 1756
@@ -1673,16 +1762,16 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
1673 1762
1674 ret = ttm_bo_reserve_locked(bo, false, true, false, 0); 1763 ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
1675 if (unlikely(ret == -EBUSY)) { 1764 if (unlikely(ret == -EBUSY)) {
1676 spin_unlock(&bdev->lru_lock); 1765 spin_unlock(&glob->lru_lock);
1677 ttm_bo_wait_unreserved(bo, false); 1766 ttm_bo_wait_unreserved(bo, false);
1678 kref_put(&bo->list_kref, ttm_bo_release_list); 1767 kref_put(&bo->list_kref, ttm_bo_release_list);
1679 spin_lock(&bdev->lru_lock); 1768 spin_lock(&glob->lru_lock);
1680 } 1769 }
1681 } 1770 }
1682 1771
1683 BUG_ON(ret != 0); 1772 BUG_ON(ret != 0);
1684 put_count = ttm_bo_del_from_lru(bo); 1773 put_count = ttm_bo_del_from_lru(bo);
1685 spin_unlock(&bdev->lru_lock); 1774 spin_unlock(&glob->lru_lock);
1686 1775
1687 while (put_count--) 1776 while (put_count--)
1688 kref_put(&bo->list_kref, ttm_bo_ref_bug); 1777 kref_put(&bo->list_kref, ttm_bo_ref_bug);
@@ -1736,6 +1825,6 @@ out:
1736 1825
1737void ttm_bo_swapout_all(struct ttm_bo_device *bdev) 1826void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
1738{ 1827{
1739 while (ttm_bo_swapout(&bdev->shrink) == 0) 1828 while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
1740 ; 1829 ;
1741} 1830}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index ad4ada07c6cf..c70927ecda21 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -41,9 +41,9 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
41 struct ttm_mem_reg *old_mem = &bo->mem; 41 struct ttm_mem_reg *old_mem = &bo->mem;
42 42
43 if (old_mem->mm_node) { 43 if (old_mem->mm_node) {
44 spin_lock(&bo->bdev->lru_lock); 44 spin_lock(&bo->glob->lru_lock);
45 drm_mm_put_block(old_mem->mm_node); 45 drm_mm_put_block(old_mem->mm_node);
46 spin_unlock(&bo->bdev->lru_lock); 46 spin_unlock(&bo->glob->lru_lock);
47 } 47 }
48 old_mem->mm_node = NULL; 48 old_mem->mm_node = NULL;
49} 49}
diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c
index 0b14eb1972b8..541744d00d3e 100644
--- a/drivers/gpu/drm/ttm/ttm_global.c
+++ b/drivers/gpu/drm/ttm/ttm_global.c
@@ -71,7 +71,7 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
71 71
72 mutex_lock(&item->mutex); 72 mutex_lock(&item->mutex);
73 if (item->refcount == 0) { 73 if (item->refcount == 0) {
74 item->object = kmalloc(ref->size, GFP_KERNEL); 74 item->object = kzalloc(ref->size, GFP_KERNEL);
75 if (unlikely(item->object == NULL)) { 75 if (unlikely(item->object == NULL)) {
76 ret = -ENOMEM; 76 ret = -ENOMEM;
77 goto out_err; 77 goto out_err;
@@ -89,7 +89,6 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
89 mutex_unlock(&item->mutex); 89 mutex_unlock(&item->mutex);
90 return 0; 90 return 0;
91out_err: 91out_err:
92 kfree(item->object);
93 mutex_unlock(&item->mutex); 92 mutex_unlock(&item->mutex);
94 item->object = NULL; 93 item->object = NULL;
95 return ret; 94 return ret;
@@ -105,7 +104,6 @@ void ttm_global_item_unref(struct ttm_global_reference *ref)
105 BUG_ON(ref->object != item->object); 104 BUG_ON(ref->object != item->object);
106 if (--item->refcount == 0) { 105 if (--item->refcount == 0) {
107 ref->release(ref); 106 ref->release(ref);
108 kfree(item->object);
109 item->object = NULL; 107 item->object = NULL;
110 } 108 }
111 mutex_unlock(&item->mutex); 109 mutex_unlock(&item->mutex);
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index 87323d4ff68d..072c281a6bb5 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -26,15 +26,180 @@
26 **************************************************************************/ 26 **************************************************************************/
27 27
28#include "ttm/ttm_memory.h" 28#include "ttm/ttm_memory.h"
29#include "ttm/ttm_module.h"
29#include <linux/spinlock.h> 30#include <linux/spinlock.h>
30#include <linux/sched.h> 31#include <linux/sched.h>
31#include <linux/wait.h> 32#include <linux/wait.h>
32#include <linux/mm.h> 33#include <linux/mm.h>
33#include <linux/module.h> 34#include <linux/module.h>
34 35
35#define TTM_PFX "[TTM] "
36#define TTM_MEMORY_ALLOC_RETRIES 4 36#define TTM_MEMORY_ALLOC_RETRIES 4
37 37
38struct ttm_mem_zone {
39 struct kobject kobj;
40 struct ttm_mem_global *glob;
41 const char *name;
42 uint64_t zone_mem;
43 uint64_t emer_mem;
44 uint64_t max_mem;
45 uint64_t swap_limit;
46 uint64_t used_mem;
47};
48
49static struct attribute ttm_mem_sys = {
50 .name = "zone_memory",
51 .mode = S_IRUGO
52};
53static struct attribute ttm_mem_emer = {
54 .name = "emergency_memory",
55 .mode = S_IRUGO | S_IWUSR
56};
57static struct attribute ttm_mem_max = {
58 .name = "available_memory",
59 .mode = S_IRUGO | S_IWUSR
60};
61static struct attribute ttm_mem_swap = {
62 .name = "swap_limit",
63 .mode = S_IRUGO | S_IWUSR
64};
65static struct attribute ttm_mem_used = {
66 .name = "used_memory",
67 .mode = S_IRUGO
68};
69
70static void ttm_mem_zone_kobj_release(struct kobject *kobj)
71{
72 struct ttm_mem_zone *zone =
73 container_of(kobj, struct ttm_mem_zone, kobj);
74
75 printk(KERN_INFO TTM_PFX
76 "Zone %7s: Used memory at exit: %llu kiB.\n",
77 zone->name, (unsigned long long) zone->used_mem >> 10);
78 kfree(zone);
79}
80
81static ssize_t ttm_mem_zone_show(struct kobject *kobj,
82 struct attribute *attr,
83 char *buffer)
84{
85 struct ttm_mem_zone *zone =
86 container_of(kobj, struct ttm_mem_zone, kobj);
87 uint64_t val = 0;
88
89 spin_lock(&zone->glob->lock);
90 if (attr == &ttm_mem_sys)
91 val = zone->zone_mem;
92 else if (attr == &ttm_mem_emer)
93 val = zone->emer_mem;
94 else if (attr == &ttm_mem_max)
95 val = zone->max_mem;
96 else if (attr == &ttm_mem_swap)
97 val = zone->swap_limit;
98 else if (attr == &ttm_mem_used)
99 val = zone->used_mem;
100 spin_unlock(&zone->glob->lock);
101
102 return snprintf(buffer, PAGE_SIZE, "%llu\n",
103 (unsigned long long) val >> 10);
104}
105
106static void ttm_check_swapping(struct ttm_mem_global *glob);
107
108static ssize_t ttm_mem_zone_store(struct kobject *kobj,
109 struct attribute *attr,
110 const char *buffer,
111 size_t size)
112{
113 struct ttm_mem_zone *zone =
114 container_of(kobj, struct ttm_mem_zone, kobj);
115 int chars;
116 unsigned long val;
117 uint64_t val64;
118
119 chars = sscanf(buffer, "%lu", &val);
120 if (chars == 0)
121 return size;
122
123 val64 = val;
124 val64 <<= 10;
125
126 spin_lock(&zone->glob->lock);
127 if (val64 > zone->zone_mem)
128 val64 = zone->zone_mem;
129 if (attr == &ttm_mem_emer) {
130 zone->emer_mem = val64;
131 if (zone->max_mem > val64)
132 zone->max_mem = val64;
133 } else if (attr == &ttm_mem_max) {
134 zone->max_mem = val64;
135 if (zone->emer_mem < val64)
136 zone->emer_mem = val64;
137 } else if (attr == &ttm_mem_swap)
138 zone->swap_limit = val64;
139 spin_unlock(&zone->glob->lock);
140
141 ttm_check_swapping(zone->glob);
142
143 return size;
144}
145
146static struct attribute *ttm_mem_zone_attrs[] = {
147 &ttm_mem_sys,
148 &ttm_mem_emer,
149 &ttm_mem_max,
150 &ttm_mem_swap,
151 &ttm_mem_used,
152 NULL
153};
154
155static struct sysfs_ops ttm_mem_zone_ops = {
156 .show = &ttm_mem_zone_show,
157 .store = &ttm_mem_zone_store
158};
159
160static struct kobj_type ttm_mem_zone_kobj_type = {
161 .release = &ttm_mem_zone_kobj_release,
162 .sysfs_ops = &ttm_mem_zone_ops,
163 .default_attrs = ttm_mem_zone_attrs,
164};
165
166static void ttm_mem_global_kobj_release(struct kobject *kobj)
167{
168 struct ttm_mem_global *glob =
169 container_of(kobj, struct ttm_mem_global, kobj);
170
171 kfree(glob);
172}
173
174static struct kobj_type ttm_mem_glob_kobj_type = {
175 .release = &ttm_mem_global_kobj_release,
176};
177
178static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob,
179 bool from_wq, uint64_t extra)
180{
181 unsigned int i;
182 struct ttm_mem_zone *zone;
183 uint64_t target;
184
185 for (i = 0; i < glob->num_zones; ++i) {
186 zone = glob->zones[i];
187
188 if (from_wq)
189 target = zone->swap_limit;
190 else if (capable(CAP_SYS_ADMIN))
191 target = zone->emer_mem;
192 else
193 target = zone->max_mem;
194
195 target = (extra > target) ? 0ULL : target;
196
197 if (zone->used_mem > target)
198 return true;
199 }
200 return false;
201}
202
38/** 203/**
39 * At this point we only support a single shrink callback. 204 * At this point we only support a single shrink callback.
40 * Extend this if needed, perhaps using a linked list of callbacks. 205 * Extend this if needed, perhaps using a linked list of callbacks.
@@ -42,34 +207,17 @@
42 * many threads may try to swap out at any given time. 207 * many threads may try to swap out at any given time.
43 */ 208 */
44 209
45static void ttm_shrink(struct ttm_mem_global *glob, bool from_workqueue, 210static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq,
46 uint64_t extra) 211 uint64_t extra)
47{ 212{
48 int ret; 213 int ret;
49 struct ttm_mem_shrink *shrink; 214 struct ttm_mem_shrink *shrink;
50 uint64_t target;
51 uint64_t total_target;
52 215
53 spin_lock(&glob->lock); 216 spin_lock(&glob->lock);
54 if (glob->shrink == NULL) 217 if (glob->shrink == NULL)
55 goto out; 218 goto out;
56 219
57 if (from_workqueue) { 220 while (ttm_zones_above_swap_target(glob, from_wq, extra)) {
58 target = glob->swap_limit;
59 total_target = glob->total_memory_swap_limit;
60 } else if (capable(CAP_SYS_ADMIN)) {
61 total_target = glob->emer_total_memory;
62 target = glob->emer_memory;
63 } else {
64 total_target = glob->max_total_memory;
65 target = glob->max_memory;
66 }
67
68 total_target = (extra >= total_target) ? 0 : total_target - extra;
69 target = (extra >= target) ? 0 : target - extra;
70
71 while (glob->used_memory > target ||
72 glob->used_total_memory > total_target) {
73 shrink = glob->shrink; 221 shrink = glob->shrink;
74 spin_unlock(&glob->lock); 222 spin_unlock(&glob->lock);
75 ret = shrink->do_shrink(shrink); 223 ret = shrink->do_shrink(shrink);
@@ -81,6 +229,8 @@ out:
81 spin_unlock(&glob->lock); 229 spin_unlock(&glob->lock);
82} 230}
83 231
232
233
84static void ttm_shrink_work(struct work_struct *work) 234static void ttm_shrink_work(struct work_struct *work)
85{ 235{
86 struct ttm_mem_global *glob = 236 struct ttm_mem_global *glob =
@@ -89,63 +239,198 @@ static void ttm_shrink_work(struct work_struct *work)
89 ttm_shrink(glob, true, 0ULL); 239 ttm_shrink(glob, true, 0ULL);
90} 240}
91 241
242static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
243 const struct sysinfo *si)
244{
245 struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
246 uint64_t mem;
247 int ret;
248
249 if (unlikely(!zone))
250 return -ENOMEM;
251
252 mem = si->totalram - si->totalhigh;
253 mem *= si->mem_unit;
254
255 zone->name = "kernel";
256 zone->zone_mem = mem;
257 zone->max_mem = mem >> 1;
258 zone->emer_mem = (mem >> 1) + (mem >> 2);
259 zone->swap_limit = zone->max_mem - (mem >> 3);
260 zone->used_mem = 0;
261 zone->glob = glob;
262 glob->zone_kernel = zone;
263 kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
264 ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
265 if (unlikely(ret != 0)) {
266 kobject_put(&zone->kobj);
267 return ret;
268 }
269 glob->zones[glob->num_zones++] = zone;
270 return 0;
271}
272
273#ifdef CONFIG_HIGHMEM
274static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
275 const struct sysinfo *si)
276{
277 struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
278 uint64_t mem;
279 int ret;
280
281 if (unlikely(!zone))
282 return -ENOMEM;
283
284 if (si->totalhigh == 0)
285 return 0;
286
287 mem = si->totalram;
288 mem *= si->mem_unit;
289
290 zone->name = "highmem";
291 zone->zone_mem = mem;
292 zone->max_mem = mem >> 1;
293 zone->emer_mem = (mem >> 1) + (mem >> 2);
294 zone->swap_limit = zone->max_mem - (mem >> 3);
295 zone->used_mem = 0;
296 zone->glob = glob;
297 glob->zone_highmem = zone;
298 kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
299 ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
300 if (unlikely(ret != 0)) {
301 kobject_put(&zone->kobj);
302 return ret;
303 }
304 glob->zones[glob->num_zones++] = zone;
305 return 0;
306}
307#else
308static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
309 const struct sysinfo *si)
310{
311 struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
312 uint64_t mem;
313 int ret;
314
315 if (unlikely(!zone))
316 return -ENOMEM;
317
318 mem = si->totalram;
319 mem *= si->mem_unit;
320
321 /**
322 * No special dma32 zone needed.
323 */
324
325 if (mem <= ((uint64_t) 1ULL << 32))
326 return 0;
327
328 /*
329 * Limit max dma32 memory to 4GB for now
330 * until we can figure out how big this
331 * zone really is.
332 */
333
334 mem = ((uint64_t) 1ULL << 32);
335 zone->name = "dma32";
336 zone->zone_mem = mem;
337 zone->max_mem = mem >> 1;
338 zone->emer_mem = (mem >> 1) + (mem >> 2);
339 zone->swap_limit = zone->max_mem - (mem >> 3);
340 zone->used_mem = 0;
341 zone->glob = glob;
342 glob->zone_dma32 = zone;
343 kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
344 ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
345 if (unlikely(ret != 0)) {
346 kobject_put(&zone->kobj);
347 return ret;
348 }
349 glob->zones[glob->num_zones++] = zone;
350 return 0;
351}
352#endif
353
92int ttm_mem_global_init(struct ttm_mem_global *glob) 354int ttm_mem_global_init(struct ttm_mem_global *glob)
93{ 355{
94 struct sysinfo si; 356 struct sysinfo si;
95 uint64_t mem; 357 int ret;
358 int i;
359 struct ttm_mem_zone *zone;
96 360
97 spin_lock_init(&glob->lock); 361 spin_lock_init(&glob->lock);
98 glob->swap_queue = create_singlethread_workqueue("ttm_swap"); 362 glob->swap_queue = create_singlethread_workqueue("ttm_swap");
99 INIT_WORK(&glob->work, ttm_shrink_work); 363 INIT_WORK(&glob->work, ttm_shrink_work);
100 init_waitqueue_head(&glob->queue); 364 init_waitqueue_head(&glob->queue);
365 kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type);
366 ret = kobject_add(&glob->kobj,
367 ttm_get_kobj(),
368 "memory_accounting");
369 if (unlikely(ret != 0)) {
370 kobject_put(&glob->kobj);
371 return ret;
372 }
101 373
102 si_meminfo(&si); 374 si_meminfo(&si);
103 375
104 mem = si.totalram - si.totalhigh; 376 ret = ttm_mem_init_kernel_zone(glob, &si);
105 mem *= si.mem_unit; 377 if (unlikely(ret != 0))
106 378 goto out_no_zone;
107 glob->max_memory = mem >> 1; 379#ifdef CONFIG_HIGHMEM
108 glob->emer_memory = (mem >> 1) + (mem >> 2); 380 ret = ttm_mem_init_highmem_zone(glob, &si);
109 glob->swap_limit = glob->max_memory - (mem >> 3); 381 if (unlikely(ret != 0))
110 glob->used_memory = 0; 382 goto out_no_zone;
111 glob->used_total_memory = 0; 383#else
112 glob->shrink = NULL; 384 ret = ttm_mem_init_dma32_zone(glob, &si);
113 385 if (unlikely(ret != 0))
114 mem = si.totalram; 386 goto out_no_zone;
115 mem *= si.mem_unit; 387#endif
116 388 for (i = 0; i < glob->num_zones; ++i) {
117 glob->max_total_memory = mem >> 1; 389 zone = glob->zones[i];
118 glob->emer_total_memory = (mem >> 1) + (mem >> 2); 390 printk(KERN_INFO TTM_PFX
119 391 "Zone %7s: Available graphics memory: %llu kiB.\n",
120 glob->total_memory_swap_limit = glob->max_total_memory - (mem >> 3); 392 zone->name, (unsigned long long) zone->max_mem >> 10);
121 393 }
122 printk(KERN_INFO TTM_PFX "TTM available graphics memory: %llu MiB\n",
123 glob->max_total_memory >> 20);
124 printk(KERN_INFO TTM_PFX "TTM available object memory: %llu MiB\n",
125 glob->max_memory >> 20);
126
127 return 0; 394 return 0;
395out_no_zone:
396 ttm_mem_global_release(glob);
397 return ret;
128} 398}
129EXPORT_SYMBOL(ttm_mem_global_init); 399EXPORT_SYMBOL(ttm_mem_global_init);
130 400
131void ttm_mem_global_release(struct ttm_mem_global *glob) 401void ttm_mem_global_release(struct ttm_mem_global *glob)
132{ 402{
133 printk(KERN_INFO TTM_PFX "Used total memory is %llu bytes.\n", 403 unsigned int i;
134 (unsigned long long)glob->used_total_memory); 404 struct ttm_mem_zone *zone;
405
135 flush_workqueue(glob->swap_queue); 406 flush_workqueue(glob->swap_queue);
136 destroy_workqueue(glob->swap_queue); 407 destroy_workqueue(glob->swap_queue);
137 glob->swap_queue = NULL; 408 glob->swap_queue = NULL;
409 for (i = 0; i < glob->num_zones; ++i) {
410 zone = glob->zones[i];
411 kobject_del(&zone->kobj);
412 kobject_put(&zone->kobj);
413 }
414 kobject_del(&glob->kobj);
415 kobject_put(&glob->kobj);
138} 416}
139EXPORT_SYMBOL(ttm_mem_global_release); 417EXPORT_SYMBOL(ttm_mem_global_release);
140 418
141static inline void ttm_check_swapping(struct ttm_mem_global *glob) 419static void ttm_check_swapping(struct ttm_mem_global *glob)
142{ 420{
143 bool needs_swapping; 421 bool needs_swapping = false;
422 unsigned int i;
423 struct ttm_mem_zone *zone;
144 424
145 spin_lock(&glob->lock); 425 spin_lock(&glob->lock);
146 needs_swapping = (glob->used_memory > glob->swap_limit || 426 for (i = 0; i < glob->num_zones; ++i) {
147 glob->used_total_memory > 427 zone = glob->zones[i];
148 glob->total_memory_swap_limit); 428 if (zone->used_mem > zone->swap_limit) {
429 needs_swapping = true;
430 break;
431 }
432 }
433
149 spin_unlock(&glob->lock); 434 spin_unlock(&glob->lock);
150 435
151 if (unlikely(needs_swapping)) 436 if (unlikely(needs_swapping))
@@ -153,44 +438,60 @@ static inline void ttm_check_swapping(struct ttm_mem_global *glob)
153 438
154} 439}
155 440
156void ttm_mem_global_free(struct ttm_mem_global *glob, 441static void ttm_mem_global_free_zone(struct ttm_mem_global *glob,
157 uint64_t amount, bool himem) 442 struct ttm_mem_zone *single_zone,
443 uint64_t amount)
158{ 444{
445 unsigned int i;
446 struct ttm_mem_zone *zone;
447
159 spin_lock(&glob->lock); 448 spin_lock(&glob->lock);
160 glob->used_total_memory -= amount; 449 for (i = 0; i < glob->num_zones; ++i) {
161 if (!himem) 450 zone = glob->zones[i];
162 glob->used_memory -= amount; 451 if (single_zone && zone != single_zone)
163 wake_up_all(&glob->queue); 452 continue;
453 zone->used_mem -= amount;
454 }
164 spin_unlock(&glob->lock); 455 spin_unlock(&glob->lock);
165} 456}
166 457
458void ttm_mem_global_free(struct ttm_mem_global *glob,
459 uint64_t amount)
460{
461 return ttm_mem_global_free_zone(glob, NULL, amount);
462}
463
167static int ttm_mem_global_reserve(struct ttm_mem_global *glob, 464static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
168 uint64_t amount, bool himem, bool reserve) 465 struct ttm_mem_zone *single_zone,
466 uint64_t amount, bool reserve)
169{ 467{
170 uint64_t limit; 468 uint64_t limit;
171 uint64_t lomem_limit;
172 int ret = -ENOMEM; 469 int ret = -ENOMEM;
470 unsigned int i;
471 struct ttm_mem_zone *zone;
173 472
174 spin_lock(&glob->lock); 473 spin_lock(&glob->lock);
474 for (i = 0; i < glob->num_zones; ++i) {
475 zone = glob->zones[i];
476 if (single_zone && zone != single_zone)
477 continue;
175 478
176 if (capable(CAP_SYS_ADMIN)) { 479 limit = (capable(CAP_SYS_ADMIN)) ?
177 limit = glob->emer_total_memory; 480 zone->emer_mem : zone->max_mem;
178 lomem_limit = glob->emer_memory;
179 } else {
180 limit = glob->max_total_memory;
181 lomem_limit = glob->max_memory;
182 }
183 481
184 if (unlikely(glob->used_total_memory + amount > limit)) 482 if (zone->used_mem > limit)
185 goto out_unlock; 483 goto out_unlock;
186 if (unlikely(!himem && glob->used_memory + amount > lomem_limit)) 484 }
187 goto out_unlock;
188 485
189 if (reserve) { 486 if (reserve) {
190 glob->used_total_memory += amount; 487 for (i = 0; i < glob->num_zones; ++i) {
191 if (!himem) 488 zone = glob->zones[i];
192 glob->used_memory += amount; 489 if (single_zone && zone != single_zone)
490 continue;
491 zone->used_mem += amount;
492 }
193 } 493 }
494
194 ret = 0; 495 ret = 0;
195out_unlock: 496out_unlock:
196 spin_unlock(&glob->lock); 497 spin_unlock(&glob->lock);
@@ -199,12 +500,17 @@ out_unlock:
199 return ret; 500 return ret;
200} 501}
201 502
202int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, 503
203 bool no_wait, bool interruptible, bool himem) 504static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
505 struct ttm_mem_zone *single_zone,
506 uint64_t memory,
507 bool no_wait, bool interruptible)
204{ 508{
205 int count = TTM_MEMORY_ALLOC_RETRIES; 509 int count = TTM_MEMORY_ALLOC_RETRIES;
206 510
207 while (unlikely(ttm_mem_global_reserve(glob, memory, himem, true) 511 while (unlikely(ttm_mem_global_reserve(glob,
512 single_zone,
513 memory, true)
208 != 0)) { 514 != 0)) {
209 if (no_wait) 515 if (no_wait)
210 return -ENOMEM; 516 return -ENOMEM;
@@ -216,6 +522,56 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
216 return 0; 522 return 0;
217} 523}
218 524
525int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
526 bool no_wait, bool interruptible)
527{
528 /**
529 * Normal allocations of kernel memory are registered in
530 * all zones.
531 */
532
533 return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
534 interruptible);
535}
536
537int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
538 struct page *page,
539 bool no_wait, bool interruptible)
540{
541
542 struct ttm_mem_zone *zone = NULL;
543
544 /**
545 * Page allocations may be registed in a single zone
546 * only if highmem or !dma32.
547 */
548
549#ifdef CONFIG_HIGHMEM
550 if (PageHighMem(page) && glob->zone_highmem != NULL)
551 zone = glob->zone_highmem;
552#else
553 if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
554 zone = glob->zone_kernel;
555#endif
556 return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait,
557 interruptible);
558}
559
560void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page)
561{
562 struct ttm_mem_zone *zone = NULL;
563
564#ifdef CONFIG_HIGHMEM
565 if (PageHighMem(page) && glob->zone_highmem != NULL)
566 zone = glob->zone_highmem;
567#else
568 if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
569 zone = glob->zone_kernel;
570#endif
571 ttm_mem_global_free_zone(glob, zone, PAGE_SIZE);
572}
573
574
219size_t ttm_round_pot(size_t size) 575size_t ttm_round_pot(size_t size)
220{ 576{
221 if ((size & (size - 1)) == 0) 577 if ((size & (size - 1)) == 0)
diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c
index 59ce8191d584..9a6edbfeaa9e 100644
--- a/drivers/gpu/drm/ttm/ttm_module.c
+++ b/drivers/gpu/drm/ttm/ttm_module.c
@@ -29,16 +29,72 @@
29 * Jerome Glisse 29 * Jerome Glisse
30 */ 30 */
31#include <linux/module.h> 31#include <linux/module.h>
32#include <ttm/ttm_module.h> 32#include <linux/device.h>
33#include <linux/sched.h>
34#include "ttm/ttm_module.h"
35#include "drm_sysfs.h"
36
37static DECLARE_WAIT_QUEUE_HEAD(exit_q);
38atomic_t device_released;
39
40static struct device_type ttm_drm_class_type = {
41 .name = "ttm",
42 /**
43 * Add pm ops here.
44 */
45};
46
47static void ttm_drm_class_device_release(struct device *dev)
48{
49 atomic_set(&device_released, 1);
50 wake_up_all(&exit_q);
51}
52
53static struct device ttm_drm_class_device = {
54 .type = &ttm_drm_class_type,
55 .release = &ttm_drm_class_device_release
56};
57
58struct kobject *ttm_get_kobj(void)
59{
60 struct kobject *kobj = &ttm_drm_class_device.kobj;
61 BUG_ON(kobj == NULL);
62 return kobj;
63}
33 64
34static int __init ttm_init(void) 65static int __init ttm_init(void)
35{ 66{
67 int ret;
68
69 ret = dev_set_name(&ttm_drm_class_device, "ttm");
70 if (unlikely(ret != 0))
71 return ret;
72
36 ttm_global_init(); 73 ttm_global_init();
74
75 atomic_set(&device_released, 0);
76 ret = drm_class_device_register(&ttm_drm_class_device);
77 if (unlikely(ret != 0))
78 goto out_no_dev_reg;
79
37 return 0; 80 return 0;
81out_no_dev_reg:
82 atomic_set(&device_released, 1);
83 wake_up_all(&exit_q);
84 ttm_global_release();
85 return ret;
38} 86}
39 87
40static void __exit ttm_exit(void) 88static void __exit ttm_exit(void)
41{ 89{
90 drm_class_device_unregister(&ttm_drm_class_device);
91
92 /**
93 * Refuse to unload until the TTM device is released.
94 * Not sure this is 100% needed.
95 */
96
97 wait_event(exit_q, atomic_read(&device_released) == 1);
42 ttm_global_release(); 98 ttm_global_release();
43} 99}
44 100
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index b8b6c4a5f983..a55ee1a56c16 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -34,76 +34,13 @@
34#include <linux/pagemap.h> 34#include <linux/pagemap.h>
35#include <linux/file.h> 35#include <linux/file.h>
36#include <linux/swap.h> 36#include <linux/swap.h>
37#include "drm_cache.h"
37#include "ttm/ttm_module.h" 38#include "ttm/ttm_module.h"
38#include "ttm/ttm_bo_driver.h" 39#include "ttm/ttm_bo_driver.h"
39#include "ttm/ttm_placement.h" 40#include "ttm/ttm_placement.h"
40 41
41static int ttm_tt_swapin(struct ttm_tt *ttm); 42static int ttm_tt_swapin(struct ttm_tt *ttm);
42 43
43#if defined(CONFIG_X86)
44static void ttm_tt_clflush_page(struct page *page)
45{
46 uint8_t *page_virtual;
47 unsigned int i;
48
49 if (unlikely(page == NULL))
50 return;
51
52 page_virtual = kmap_atomic(page, KM_USER0);
53
54 for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
55 clflush(page_virtual + i);
56
57 kunmap_atomic(page_virtual, KM_USER0);
58}
59
60static void ttm_tt_cache_flush_clflush(struct page *pages[],
61 unsigned long num_pages)
62{
63 unsigned long i;
64
65 mb();
66 for (i = 0; i < num_pages; ++i)
67 ttm_tt_clflush_page(*pages++);
68 mb();
69}
70#elif !defined(__powerpc__)
71static void ttm_tt_ipi_handler(void *null)
72{
73 ;
74}
75#endif
76
77void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages)
78{
79
80#if defined(CONFIG_X86)
81 if (cpu_has_clflush) {
82 ttm_tt_cache_flush_clflush(pages, num_pages);
83 return;
84 }
85#elif defined(__powerpc__)
86 unsigned long i;
87
88 for (i = 0; i < num_pages; ++i) {
89 struct page *page = pages[i];
90 void *page_virtual;
91
92 if (unlikely(page == NULL))
93 continue;
94
95 page_virtual = kmap_atomic(page, KM_USER0);
96 flush_dcache_range((unsigned long) page_virtual,
97 (unsigned long) page_virtual + PAGE_SIZE);
98 kunmap_atomic(page_virtual, KM_USER0);
99 }
100#else
101 if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0)
102 printk(KERN_ERR TTM_PFX
103 "Timed out waiting for drm cache flush.\n");
104#endif
105}
106
107/** 44/**
108 * Allocates storage for pointers to the pages that back the ttm. 45 * Allocates storage for pointers to the pages that back the ttm.
109 * 46 *
@@ -179,7 +116,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
179 set_page_dirty_lock(page); 116 set_page_dirty_lock(page);
180 117
181 ttm->pages[i] = NULL; 118 ttm->pages[i] = NULL;
182 ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, false); 119 ttm_mem_global_free(ttm->glob->mem_glob, PAGE_SIZE);
183 put_page(page); 120 put_page(page);
184 } 121 }
185 ttm->state = tt_unpopulated; 122 ttm->state = tt_unpopulated;
@@ -190,8 +127,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
190static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index) 127static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
191{ 128{
192 struct page *p; 129 struct page *p;
193 struct ttm_bo_device *bdev = ttm->bdev; 130 struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
194 struct ttm_mem_global *mem_glob = bdev->mem_glob;
195 int ret; 131 int ret;
196 132
197 while (NULL == (p = ttm->pages[index])) { 133 while (NULL == (p = ttm->pages[index])) {
@@ -200,21 +136,14 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
200 if (!p) 136 if (!p)
201 return NULL; 137 return NULL;
202 138
203 if (PageHighMem(p)) { 139 ret = ttm_mem_global_alloc_page(mem_glob, p, false, false);
204 ret = 140 if (unlikely(ret != 0))
205 ttm_mem_global_alloc(mem_glob, PAGE_SIZE, 141 goto out_err;
206 false, false, true); 142
207 if (unlikely(ret != 0)) 143 if (PageHighMem(p))
208 goto out_err;
209 ttm->pages[--ttm->first_himem_page] = p; 144 ttm->pages[--ttm->first_himem_page] = p;
210 } else { 145 else
211 ret =
212 ttm_mem_global_alloc(mem_glob, PAGE_SIZE,
213 false, false, false);
214 if (unlikely(ret != 0))
215 goto out_err;
216 ttm->pages[++ttm->last_lomem_page] = p; 146 ttm->pages[++ttm->last_lomem_page] = p;
217 }
218 } 147 }
219 return p; 148 return p;
220out_err: 149out_err:
@@ -310,7 +239,7 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm,
310 } 239 }
311 240
312 if (ttm->caching_state == tt_cached) 241 if (ttm->caching_state == tt_cached)
313 ttm_tt_cache_flush(ttm->pages, ttm->num_pages); 242 drm_clflush_pages(ttm->pages, ttm->num_pages);
314 243
315 for (i = 0; i < ttm->num_pages; ++i) { 244 for (i = 0; i < ttm->num_pages; ++i) {
316 cur_page = ttm->pages[i]; 245 cur_page = ttm->pages[i];
@@ -368,8 +297,8 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
368 printk(KERN_ERR TTM_PFX 297 printk(KERN_ERR TTM_PFX
369 "Erroneous page count. " 298 "Erroneous page count. "
370 "Leaking pages.\n"); 299 "Leaking pages.\n");
371 ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, 300 ttm_mem_global_free_page(ttm->glob->mem_glob,
372 PageHighMem(cur_page)); 301 cur_page);
373 __free_page(cur_page); 302 __free_page(cur_page);
374 } 303 }
375 } 304 }
@@ -414,7 +343,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
414 struct mm_struct *mm = tsk->mm; 343 struct mm_struct *mm = tsk->mm;
415 int ret; 344 int ret;
416 int write = (ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0; 345 int write = (ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0;
417 struct ttm_mem_global *mem_glob = ttm->bdev->mem_glob; 346 struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
418 347
419 BUG_ON(num_pages != ttm->num_pages); 348 BUG_ON(num_pages != ttm->num_pages);
420 BUG_ON((ttm->page_flags & TTM_PAGE_FLAG_USER) == 0); 349 BUG_ON((ttm->page_flags & TTM_PAGE_FLAG_USER) == 0);
@@ -424,7 +353,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
424 */ 353 */
425 354
426 ret = ttm_mem_global_alloc(mem_glob, num_pages * PAGE_SIZE, 355 ret = ttm_mem_global_alloc(mem_glob, num_pages * PAGE_SIZE,
427 false, false, false); 356 false, false);
428 if (unlikely(ret != 0)) 357 if (unlikely(ret != 0))
429 return ret; 358 return ret;
430 359
@@ -435,7 +364,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
435 364
436 if (ret != num_pages && write) { 365 if (ret != num_pages && write) {
437 ttm_tt_free_user_pages(ttm); 366 ttm_tt_free_user_pages(ttm);
438 ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE, false); 367 ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE);
439 return -ENOMEM; 368 return -ENOMEM;
440 } 369 }
441 370
@@ -459,8 +388,7 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
459 if (!ttm) 388 if (!ttm)
460 return NULL; 389 return NULL;
461 390
462 ttm->bdev = bdev; 391 ttm->glob = bdev->glob;
463
464 ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 392 ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
465 ttm->first_himem_page = ttm->num_pages; 393 ttm->first_himem_page = ttm->num_pages;
466 ttm->last_lomem_page = -1; 394 ttm->last_lomem_page = -1;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 4d1dc0cf1401..8b6ee247bfe4 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -852,14 +852,14 @@ static const struct file_operations hiddev_fops = {
852#endif 852#endif
853}; 853};
854 854
855static char *hiddev_nodename(struct device *dev) 855static char *hiddev_devnode(struct device *dev, mode_t *mode)
856{ 856{
857 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); 857 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
858} 858}
859 859
860static struct usb_class_driver hiddev_class = { 860static struct usb_class_driver hiddev_class = {
861 .name = "hiddev%d", 861 .name = "hiddev%d",
862 .nodename = hiddev_nodename, 862 .devnode = hiddev_devnode,
863 .fops = &hiddev_fops, 863 .fops = &hiddev_fops,
864 .minor_base = HIDDEV_MINOR_BASE, 864 .minor_base = HIDDEV_MINOR_BASE,
865}; 865};
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 0b486a63460d..4afba3ec2a61 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -609,13 +609,12 @@ static int __init i2c_adap_imx_init(void)
609{ 609{
610 return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe); 610 return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe);
611} 611}
612subsys_initcall(i2c_adap_imx_init);
612 613
613static void __exit i2c_adap_imx_exit(void) 614static void __exit i2c_adap_imx_exit(void)
614{ 615{
615 platform_driver_unregister(&i2c_imx_driver); 616 platform_driver_unregister(&i2c_imx_driver);
616} 617}
617
618module_init(i2c_adap_imx_init);
619module_exit(i2c_adap_imx_exit); 618module_exit(i2c_adap_imx_exit);
620 619
621MODULE_LICENSE("GPL"); 620MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index c3869d94ad42..bbab0e166630 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -293,13 +293,13 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
293 } 293 }
294} 294}
295 295
296static int 296static irqreturn_t
297mv64xxx_i2c_intr(int irq, void *dev_id) 297mv64xxx_i2c_intr(int irq, void *dev_id)
298{ 298{
299 struct mv64xxx_i2c_data *drv_data = dev_id; 299 struct mv64xxx_i2c_data *drv_data = dev_id;
300 unsigned long flags; 300 unsigned long flags;
301 u32 status; 301 u32 status;
302 int rc = IRQ_NONE; 302 irqreturn_t rc = IRQ_NONE;
303 303
304 spin_lock_irqsave(&drv_data->lock, flags); 304 spin_lock_irqsave(&drv_data->lock, flags);
305 while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) & 305 while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 851791d955f3..556539d617a4 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1265,14 +1265,14 @@ static struct device_type input_dev_type = {
1265 .uevent = input_dev_uevent, 1265 .uevent = input_dev_uevent,
1266}; 1266};
1267 1267
1268static char *input_nodename(struct device *dev) 1268static char *input_devnode(struct device *dev, mode_t *mode)
1269{ 1269{
1270 return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev)); 1270 return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev));
1271} 1271}
1272 1272
1273struct class input_class = { 1273struct class input_class = {
1274 .name = "input", 1274 .name = "input",
1275 .nodename = input_nodename, 1275 .devnode = input_devnode,
1276}; 1276};
1277EXPORT_SYMBOL_GPL(input_class); 1277EXPORT_SYMBOL_GPL(input_class);
1278 1278
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 8ff7e35c7069..f33ac27de643 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -408,33 +408,28 @@ static int if_write_room(struct tty_struct *tty)
408 return retval; 408 return retval;
409} 409}
410 410
411/* FIXME: This function does not have error returns */
412
413static int if_chars_in_buffer(struct tty_struct *tty) 411static int if_chars_in_buffer(struct tty_struct *tty)
414{ 412{
415 struct cardstate *cs; 413 struct cardstate *cs;
416 int retval = -ENODEV; 414 int retval = 0;
417 415
418 cs = (struct cardstate *) tty->driver_data; 416 cs = (struct cardstate *) tty->driver_data;
419 if (!cs) { 417 if (!cs) {
420 pr_err("%s: no cardstate\n", __func__); 418 pr_err("%s: no cardstate\n", __func__);
421 return -ENODEV; 419 return 0;
422 } 420 }
423 421
424 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); 422 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
425 423
426 if (mutex_lock_interruptible(&cs->mutex)) 424 mutex_lock(&cs->mutex);
427 return -ERESTARTSYS; // FIXME -EINTR?
428 425
429 if (!cs->connected) { 426 if (!cs->connected)
430 gig_dbg(DEBUG_IF, "not connected"); 427 gig_dbg(DEBUG_IF, "not connected");
431 retval = -ENODEV; 428 else if (!cs->open_count)
432 } else if (!cs->open_count)
433 dev_warn(cs->dev, "%s: device not opened\n", __func__); 429 dev_warn(cs->dev, "%s: device not opened\n", __func__);
434 else if (cs->mstate != MS_LOCKED) { 430 else if (cs->mstate != MS_LOCKED)
435 dev_warn(cs->dev, "can't write to unlocked device\n"); 431 dev_warn(cs->dev, "can't write to unlocked device\n");
436 retval = -EBUSY; 432 else
437 } else
438 retval = cs->ops->chars_in_buffer(cs); 433 retval = cs->ops->chars_in_buffer(cs);
439 434
440 mutex_unlock(&cs->mutex); 435 mutex_unlock(&cs->mutex);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 7f77f18fcafa..a67942931582 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = {
1532static struct miscdevice _dm_misc = { 1532static struct miscdevice _dm_misc = {
1533 .minor = MISC_DYNAMIC_MINOR, 1533 .minor = MISC_DYNAMIC_MINOR,
1534 .name = DM_NAME, 1534 .name = DM_NAME,
1535 .devnode = "mapper/control", 1535 .nodename = "mapper/control",
1536 .fops = &_ctl_fops 1536 .fops = &_ctl_fops
1537}; 1537};
1538 1538
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index fc76c30e24f1..155c93eb75da 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -210,7 +210,8 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
210 tda18271_i2c_gate_ctrl(fe, 0); 210 tda18271_i2c_gate_ctrl(fe, 0);
211 211
212 if (ret != 1) 212 if (ret != 1)
213 tda_err("ERROR: i2c_transfer returned: %d\n", ret); 213 tda_err("ERROR: idx = 0x%x, len = %d, "
214 "i2c_transfer returned: %d\n", idx, len, ret);
214 215
215 return (ret == 1 ? 0 : ret); 216 return (ret == 1 ? 0 : ret);
216} 217}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index bc4b004ba7db..64595112000d 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -36,6 +36,27 @@ static LIST_HEAD(hybrid_tuner_instance_list);
36 36
37/*---------------------------------------------------------------------*/ 37/*---------------------------------------------------------------------*/
38 38
39static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
40{
41 struct tda18271_priv *priv = fe->tuner_priv;
42
43 int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
44 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
45 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
46
47 if (tda_fail(ret))
48 goto fail;
49
50 tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
51 standby ? "standby" : "active",
52 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
53 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
54fail:
55 return ret;
56}
57
58/*---------------------------------------------------------------------*/
59
39static inline int charge_pump_source(struct dvb_frontend *fe, int force) 60static inline int charge_pump_source(struct dvb_frontend *fe, int force)
40{ 61{
41 struct tda18271_priv *priv = fe->tuner_priv; 62 struct tda18271_priv *priv = fe->tuner_priv;
@@ -271,7 +292,7 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
271 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); 292 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
272 293
273 /* calculate temperature compensation */ 294 /* calculate temperature compensation */
274 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal); 295 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
275 296
276 regs[R_EB14] = approx + rfcal_comp; 297 regs[R_EB14] = approx + rfcal_comp;
277 ret = tda18271_write_regs(fe, R_EB14, 1); 298 ret = tda18271_write_regs(fe, R_EB14, 1);
@@ -800,7 +821,7 @@ static int tda18271_init(struct dvb_frontend *fe)
800 821
801 mutex_lock(&priv->lock); 822 mutex_lock(&priv->lock);
802 823
803 /* power up */ 824 /* full power up */
804 ret = tda18271_set_standby_mode(fe, 0, 0, 0); 825 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
805 if (tda_fail(ret)) 826 if (tda_fail(ret))
806 goto fail; 827 goto fail;
@@ -818,6 +839,21 @@ fail:
818 return ret; 839 return ret;
819} 840}
820 841
842static int tda18271_sleep(struct dvb_frontend *fe)
843{
844 struct tda18271_priv *priv = fe->tuner_priv;
845 int ret;
846
847 mutex_lock(&priv->lock);
848
849 /* enter standby mode, with required output features enabled */
850 ret = tda18271_toggle_output(fe, 1);
851
852 mutex_unlock(&priv->lock);
853
854 return ret;
855}
856
821/* ------------------------------------------------------------------ */ 857/* ------------------------------------------------------------------ */
822 858
823static int tda18271_agc(struct dvb_frontend *fe) 859static int tda18271_agc(struct dvb_frontend *fe)
@@ -827,8 +863,9 @@ static int tda18271_agc(struct dvb_frontend *fe)
827 863
828 switch (priv->config) { 864 switch (priv->config) {
829 case 0: 865 case 0:
830 /* no LNA */ 866 /* no external agc configuration required */
831 tda_dbg("no agc configuration provided\n"); 867 if (tda18271_debug & DBG_ADV)
868 tda_dbg("no agc configuration provided\n");
832 break; 869 break;
833 case 3: 870 case 3:
834 /* switch with GPIO of saa713x */ 871 /* switch with GPIO of saa713x */
@@ -1010,22 +1047,6 @@ fail:
1010 return ret; 1047 return ret;
1011} 1048}
1012 1049
1013static int tda18271_sleep(struct dvb_frontend *fe)
1014{
1015 struct tda18271_priv *priv = fe->tuner_priv;
1016 int ret;
1017
1018 mutex_lock(&priv->lock);
1019
1020 /* standby mode w/ slave tuner output
1021 * & loop thru & xtal oscillator on */
1022 ret = tda18271_set_standby_mode(fe, 1, 0, 0);
1023
1024 mutex_unlock(&priv->lock);
1025
1026 return ret;
1027}
1028
1029static int tda18271_release(struct dvb_frontend *fe) 1050static int tda18271_release(struct dvb_frontend *fe)
1030{ 1051{
1031 struct tda18271_priv *priv = fe->tuner_priv; 1052 struct tda18271_priv *priv = fe->tuner_priv;
@@ -1199,6 +1220,9 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1199 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1220 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1200 priv->role = (cfg) ? cfg->role : TDA18271_MASTER; 1221 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1201 priv->config = (cfg) ? cfg->config : 0; 1222 priv->config = (cfg) ? cfg->config : 0;
1223 priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
1224 priv->output_opt = (cfg) ?
1225 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1202 1226
1203 /* tda18271_cal_on_startup == -1 when cal 1227 /* tda18271_cal_on_startup == -1 when cal
1204 * module option is unset */ 1228 * module option is unset */
@@ -1216,9 +1240,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1216 1240
1217 fe->tuner_priv = priv; 1241 fe->tuner_priv = priv;
1218 1242
1219 if (cfg)
1220 priv->small_i2c = cfg->small_i2c;
1221
1222 if (tda_fail(tda18271_get_id(fe))) 1243 if (tda_fail(tda18271_get_id(fe)))
1223 goto fail; 1244 goto fail;
1224 1245
@@ -1238,9 +1259,19 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1238 /* existing tuner instance */ 1259 /* existing tuner instance */
1239 fe->tuner_priv = priv; 1260 fe->tuner_priv = priv;
1240 1261
1241 /* allow dvb driver to override i2c gate setting */ 1262 /* allow dvb driver to override configuration settings */
1242 if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) 1263 if (cfg) {
1243 priv->gate = cfg->gate; 1264 if (cfg->gate != TDA18271_GATE_ANALOG)
1265 priv->gate = cfg->gate;
1266 if (cfg->role)
1267 priv->role = cfg->role;
1268 if (cfg->config)
1269 priv->config = cfg->config;
1270 if (cfg->small_i2c)
1271 priv->small_i2c = cfg->small_i2c;
1272 if (cfg->output_opt)
1273 priv->output_opt = cfg->output_opt;
1274 }
1244 break; 1275 break;
1245 } 1276 }
1246 1277
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index ab14ceb9e0ce..e21fdeff3ddf 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -962,10 +962,9 @@ struct tda18271_cid_target_map {
962static struct tda18271_cid_target_map tda18271_cid_target[] = { 962static struct tda18271_cid_target_map tda18271_cid_target[] = {
963 { .rfmax = 46000, .target = 0x04, .limit = 1800 }, 963 { .rfmax = 46000, .target = 0x04, .limit = 1800 },
964 { .rfmax = 52200, .target = 0x0a, .limit = 1500 }, 964 { .rfmax = 52200, .target = 0x0a, .limit = 1500 },
965 { .rfmax = 79100, .target = 0x01, .limit = 4000 }, 965 { .rfmax = 70100, .target = 0x01, .limit = 4000 },
966 { .rfmax = 136800, .target = 0x18, .limit = 4000 }, 966 { .rfmax = 136800, .target = 0x18, .limit = 4000 },
967 { .rfmax = 156700, .target = 0x18, .limit = 4000 }, 967 { .rfmax = 156700, .target = 0x18, .limit = 4000 },
968 { .rfmax = 156700, .target = 0x18, .limit = 4000 },
969 { .rfmax = 186250, .target = 0x0a, .limit = 4000 }, 968 { .rfmax = 186250, .target = 0x0a, .limit = 4000 },
970 { .rfmax = 230000, .target = 0x0a, .limit = 4000 }, 969 { .rfmax = 230000, .target = 0x0a, .limit = 4000 },
971 { .rfmax = 345000, .target = 0x18, .limit = 4000 }, 970 { .rfmax = 345000, .target = 0x18, .limit = 4000 },
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index e6a80ad09356..2bee229acd91 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -108,6 +108,7 @@ struct tda18271_priv {
108 enum tda18271_role role; 108 enum tda18271_role role;
109 enum tda18271_i2c_gate gate; 109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id; 110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt;
111 112
112 unsigned int config; /* interface to saa713x / tda829x */ 113 unsigned int config; /* interface to saa713x / tda829x */
113 unsigned int tm_rfcal; 114 unsigned int tm_rfcal;
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 71bac9593f1e..323f2912128d 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -67,6 +67,17 @@ enum tda18271_i2c_gate {
67 TDA18271_GATE_DIGITAL, 67 TDA18271_GATE_DIGITAL,
68}; 68};
69 69
70enum tda18271_output_options {
71 /* slave tuner output & loop thru & xtal oscillator always on */
72 TDA18271_OUTPUT_LT_XT_ON = 0,
73
74 /* slave tuner output loop thru off */
75 TDA18271_OUTPUT_LT_OFF = 1,
76
77 /* xtal oscillator off */
78 TDA18271_OUTPUT_XT_OFF = 2,
79};
80
70struct tda18271_config { 81struct tda18271_config {
71 /* override default if freq / std settings (optional) */ 82 /* override default if freq / std settings (optional) */
72 struct tda18271_std_map *std_map; 83 struct tda18271_std_map *std_map;
@@ -77,6 +88,9 @@ struct tda18271_config {
77 /* use i2c gate provided by analog or digital demod */ 88 /* use i2c gate provided by analog or digital demod */
78 enum tda18271_i2c_gate gate; 89 enum tda18271_i2c_gate gate;
79 90
91 /* output options that can be disabled */
92 enum tda18271_output_options output_opt;
93
80 /* force rf tracking filter calibration on startup */ 94 /* force rf tracking filter calibration on startup */
81 unsigned int rf_cal_on_startup:1; 95 unsigned int rf_cal_on_startup:1;
82 96
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 5c6ef1e23c94..2b876f3988c1 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1320,6 +1320,23 @@ static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
1320 }, 1320 },
1321}; 1321};
1322 1322
1323/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
1324
1325static struct tuner_range tuner_cu1216l_ranges[] = {
1326 { 16 * 160.25 /*MHz*/, 0xce, 0x01 },
1327 { 16 * 444.25 /*MHz*/, 0xce, 0x02 },
1328 { 16 * 999.99 , 0xce, 0x04 },
1329};
1330
1331static struct tuner_params tuner_philips_cu1216l_params[] = {
1332 {
1333 .type = TUNER_PARAM_TYPE_DIGITAL,
1334 .ranges = tuner_cu1216l_ranges,
1335 .count = ARRAY_SIZE(tuner_cu1216l_ranges),
1336 .iffreq = 16 * 36.125, /*MHz*/
1337 },
1338};
1339
1323/* --------------------------------------------------------------------- */ 1340/* --------------------------------------------------------------------- */
1324 1341
1325struct tunertype tuners[] = { 1342struct tunertype tuners[] = {
@@ -1778,6 +1795,16 @@ struct tunertype tuners[] = {
1778 .params = tuner_partsnic_pti_5nf05_params, 1795 .params = tuner_partsnic_pti_5nf05_params,
1779 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params), 1796 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
1780 }, 1797 },
1798 [TUNER_PHILIPS_CU1216L] = {
1799 .name = "Philips CU1216L",
1800 .params = tuner_philips_cu1216l_params,
1801 .count = ARRAY_SIZE(tuner_philips_cu1216l_params),
1802 .stepsize = 62500,
1803 },
1804 [TUNER_NXP_TDA18271] = {
1805 .name = "NXP TDA18271",
1806 /* see tda18271-fe.c for details */
1807 },
1781}; 1808};
1782EXPORT_SYMBOL(tuners); 1809EXPORT_SYMBOL(tuners);
1783 1810
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 1d0e4b1ef10c..35d0817126e9 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -68,6 +68,10 @@ comment "Supported FireWire (IEEE 1394) Adapters"
68 depends on DVB_CORE && IEEE1394 68 depends on DVB_CORE && IEEE1394
69source "drivers/media/dvb/firewire/Kconfig" 69source "drivers/media/dvb/firewire/Kconfig"
70 70
71comment "Supported Earthsoft PT1 Adapters"
72 depends on DVB_CORE && PCI && I2C
73source "drivers/media/dvb/pt1/Kconfig"
74
71comment "Supported DVB Frontends" 75comment "Supported DVB Frontends"
72 depends on DVB_CORE 76 depends on DVB_CORE
73source "drivers/media/dvb/frontends/Kconfig" 77source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 6092a5bb5a7d..16d262ddb45d 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/
6 6
7obj-$(CONFIG_DVB_FIREDTV) += firewire/ 7obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index d13ebcb0c6b6..ddf639ed2fd8 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -850,6 +850,49 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
850 return 0; 850 return 0;
851} 851}
852 852
853static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
854{
855 int i;
856
857 memset(&(fe->dtv_property_cache), 0,
858 sizeof(struct dtv_frontend_properties));
859
860 fe->dtv_property_cache.state = DTV_CLEAR;
861 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
862 fe->dtv_property_cache.inversion = INVERSION_AUTO;
863 fe->dtv_property_cache.fec_inner = FEC_AUTO;
864 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
865 fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
866 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
867 fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
868 fe->dtv_property_cache.symbol_rate = QAM_AUTO;
869 fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
870 fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
871
872 fe->dtv_property_cache.isdbt_partial_reception = -1;
873 fe->dtv_property_cache.isdbt_sb_mode = -1;
874 fe->dtv_property_cache.isdbt_sb_subchannel = -1;
875 fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
876 fe->dtv_property_cache.isdbt_sb_segment_count = -1;
877 fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
878 for (i = 0; i < 3; i++) {
879 fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
880 fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
881 fe->dtv_property_cache.layer[i].interleaving = -1;
882 fe->dtv_property_cache.layer[i].segment_count = -1;
883 }
884
885 return 0;
886}
887
888#define _DTV_CMD(n, s, b) \
889[n] = { \
890 .name = #n, \
891 .cmd = n, \
892 .set = s,\
893 .buffer = b \
894}
895
853static struct dtv_cmds_h dtv_cmds[] = { 896static struct dtv_cmds_h dtv_cmds[] = {
854 [DTV_TUNE] = { 897 [DTV_TUNE] = {
855 .name = "DTV_TUNE", 898 .name = "DTV_TUNE",
@@ -949,6 +992,47 @@ static struct dtv_cmds_h dtv_cmds[] = {
949 .cmd = DTV_TRANSMISSION_MODE, 992 .cmd = DTV_TRANSMISSION_MODE,
950 .set = 1, 993 .set = 1,
951 }, 994 },
995
996 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
997 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
998 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
999 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
1000 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
1001 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
1002 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
1003 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
1004 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
1005 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
1006 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
1007 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
1008 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
1009 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
1010 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
1011 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
1012 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
1013 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
1014
1015 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
1016 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
1017 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
1018 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
1019 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
1020 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
1021 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
1022 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
1023 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
1024 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
1025 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
1026 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
1027 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
1028 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
1029 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
1030 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
1031 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
1032 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
1033
1034 _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
1035
952 /* Get */ 1036 /* Get */
953 [DTV_DISEQC_SLAVE_REPLY] = { 1037 [DTV_DISEQC_SLAVE_REPLY] = {
954 .name = "DTV_DISEQC_SLAVE_REPLY", 1038 .name = "DTV_DISEQC_SLAVE_REPLY",
@@ -956,6 +1040,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
956 .set = 0, 1040 .set = 0,
957 .buffer = 1, 1041 .buffer = 1,
958 }, 1042 },
1043
959 [DTV_API_VERSION] = { 1044 [DTV_API_VERSION] = {
960 .name = "DTV_API_VERSION", 1045 .name = "DTV_API_VERSION",
961 .cmd = DTV_API_VERSION, 1046 .cmd = DTV_API_VERSION,
@@ -1165,14 +1250,21 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1165 if(c->delivery_system == SYS_ISDBT) { 1250 if(c->delivery_system == SYS_ISDBT) {
1166 /* Fake out a generic DVB-T request so we pass validation in the ioctl */ 1251 /* Fake out a generic DVB-T request so we pass validation in the ioctl */
1167 p->frequency = c->frequency; 1252 p->frequency = c->frequency;
1168 p->inversion = INVERSION_AUTO; 1253 p->inversion = c->inversion;
1169 p->u.ofdm.constellation = QAM_AUTO; 1254 p->u.ofdm.constellation = QAM_AUTO;
1170 p->u.ofdm.code_rate_HP = FEC_AUTO; 1255 p->u.ofdm.code_rate_HP = FEC_AUTO;
1171 p->u.ofdm.code_rate_LP = FEC_AUTO; 1256 p->u.ofdm.code_rate_LP = FEC_AUTO;
1172 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1173 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; 1257 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
1174 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; 1258 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
1175 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; 1259 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
1260 if (c->bandwidth_hz == 8000000)
1261 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1262 else if (c->bandwidth_hz == 7000000)
1263 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1264 else if (c->bandwidth_hz == 6000000)
1265 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1266 else
1267 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1176 } 1268 }
1177} 1269}
1178 1270
@@ -1274,6 +1366,65 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1274 case DTV_HIERARCHY: 1366 case DTV_HIERARCHY:
1275 tvp->u.data = fe->dtv_property_cache.hierarchy; 1367 tvp->u.data = fe->dtv_property_cache.hierarchy;
1276 break; 1368 break;
1369
1370 /* ISDB-T Support here */
1371 case DTV_ISDBT_PARTIAL_RECEPTION:
1372 tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
1373 break;
1374 case DTV_ISDBT_SOUND_BROADCASTING:
1375 tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
1376 break;
1377 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1378 tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
1379 break;
1380 case DTV_ISDBT_SB_SEGMENT_IDX:
1381 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
1382 break;
1383 case DTV_ISDBT_SB_SEGMENT_COUNT:
1384 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
1385 break;
1386 case DTV_ISDBT_LAYER_ENABLED:
1387 tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
1388 break;
1389 case DTV_ISDBT_LAYERA_FEC:
1390 tvp->u.data = fe->dtv_property_cache.layer[0].fec;
1391 break;
1392 case DTV_ISDBT_LAYERA_MODULATION:
1393 tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
1394 break;
1395 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1396 tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
1397 break;
1398 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1399 tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
1400 break;
1401 case DTV_ISDBT_LAYERB_FEC:
1402 tvp->u.data = fe->dtv_property_cache.layer[1].fec;
1403 break;
1404 case DTV_ISDBT_LAYERB_MODULATION:
1405 tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
1406 break;
1407 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1408 tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
1409 break;
1410 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1411 tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
1412 break;
1413 case DTV_ISDBT_LAYERC_FEC:
1414 tvp->u.data = fe->dtv_property_cache.layer[2].fec;
1415 break;
1416 case DTV_ISDBT_LAYERC_MODULATION:
1417 tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
1418 break;
1419 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1420 tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
1421 break;
1422 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1423 tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
1424 break;
1425 case DTV_ISDBS_TS_ID:
1426 tvp->u.data = fe->dtv_property_cache.isdbs_ts_id;
1427 break;
1277 default: 1428 default:
1278 r = -1; 1429 r = -1;
1279 } 1430 }
@@ -1302,10 +1453,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1302 /* Reset a cache of data specific to the frontend here. This does 1453 /* Reset a cache of data specific to the frontend here. This does
1303 * not effect hardware. 1454 * not effect hardware.
1304 */ 1455 */
1456 dvb_frontend_clear_cache(fe);
1305 dprintk("%s() Flushing property cache\n", __func__); 1457 dprintk("%s() Flushing property cache\n", __func__);
1306 memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
1307 fe->dtv_property_cache.state = tvp->cmd;
1308 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
1309 break; 1458 break;
1310 case DTV_TUNE: 1459 case DTV_TUNE:
1311 /* interpret the cache of data, build either a traditional frontend 1460 /* interpret the cache of data, build either a traditional frontend
@@ -1371,6 +1520,65 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1371 case DTV_HIERARCHY: 1520 case DTV_HIERARCHY:
1372 fe->dtv_property_cache.hierarchy = tvp->u.data; 1521 fe->dtv_property_cache.hierarchy = tvp->u.data;
1373 break; 1522 break;
1523
1524 /* ISDB-T Support here */
1525 case DTV_ISDBT_PARTIAL_RECEPTION:
1526 fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
1527 break;
1528 case DTV_ISDBT_SOUND_BROADCASTING:
1529 fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
1530 break;
1531 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1532 fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
1533 break;
1534 case DTV_ISDBT_SB_SEGMENT_IDX:
1535 fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
1536 break;
1537 case DTV_ISDBT_SB_SEGMENT_COUNT:
1538 fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
1539 break;
1540 case DTV_ISDBT_LAYER_ENABLED:
1541 fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
1542 break;
1543 case DTV_ISDBT_LAYERA_FEC:
1544 fe->dtv_property_cache.layer[0].fec = tvp->u.data;
1545 break;
1546 case DTV_ISDBT_LAYERA_MODULATION:
1547 fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
1548 break;
1549 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1550 fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
1551 break;
1552 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1553 fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
1554 break;
1555 case DTV_ISDBT_LAYERB_FEC:
1556 fe->dtv_property_cache.layer[1].fec = tvp->u.data;
1557 break;
1558 case DTV_ISDBT_LAYERB_MODULATION:
1559 fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
1560 break;
1561 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1562 fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
1563 break;
1564 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1565 fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
1566 break;
1567 case DTV_ISDBT_LAYERC_FEC:
1568 fe->dtv_property_cache.layer[2].fec = tvp->u.data;
1569 break;
1570 case DTV_ISDBT_LAYERC_MODULATION:
1571 fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
1572 break;
1573 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1574 fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
1575 break;
1576 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1577 fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
1578 break;
1579 case DTV_ISDBS_TS_ID:
1580 fe->dtv_property_cache.isdbs_ts_id = tvp->u.data;
1581 break;
1374 default: 1582 default:
1375 r = -1; 1583 r = -1;
1376 } 1584 }
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index e176da472d7a..810f07d63246 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -341,6 +341,23 @@ struct dtv_frontend_properties {
341 fe_rolloff_t rolloff; 341 fe_rolloff_t rolloff;
342 342
343 fe_delivery_system_t delivery_system; 343 fe_delivery_system_t delivery_system;
344
345 /* ISDB-T specifics */
346 u8 isdbt_partial_reception;
347 u8 isdbt_sb_mode;
348 u8 isdbt_sb_subchannel;
349 u32 isdbt_sb_segment_idx;
350 u32 isdbt_sb_segment_count;
351 u8 isdbt_layer_enabled;
352 struct {
353 u8 segment_count;
354 fe_code_rate_t fec;
355 fe_modulation_t modulation;
356 u8 interleaving;
357 } layer[3];
358
359 /* ISDB-T specifics */
360 u32 isdbs_ts_id;
344}; 361};
345 362
346struct dvb_frontend { 363struct dvb_frontend {
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 479dd05762a5..94159b90f733 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -447,7 +447,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
447 return 0; 447 return 0;
448} 448}
449 449
450static char *dvb_nodename(struct device *dev) 450static char *dvb_devnode(struct device *dev, mode_t *mode)
451{ 451{
452 struct dvb_device *dvbdev = dev_get_drvdata(dev); 452 struct dvb_device *dvbdev = dev_get_drvdata(dev);
453 453
@@ -478,7 +478,7 @@ static int __init init_dvbdev(void)
478 goto error; 478 goto error;
479 } 479 }
480 dvb_class->dev_uevent = dvb_uevent; 480 dvb_class->dev_uevent = dvb_uevent;
481 dvb_class->nodename = dvb_nodename; 481 dvb_class->devnode = dvb_devnode;
482 return 0; 482 return 0;
483 483
484error: 484error:
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 8b8bc04ee980..0e4b97fba384 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -71,6 +71,7 @@ config DVB_USB_DIB0700
71 depends on DVB_USB 71 depends on DVB_USB
72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE 72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE 73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE
74 select DVB_DIB8000 if !DVB_FE_CUSTOMISE
74 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE 75 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
75 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
76 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE 77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
@@ -87,7 +88,7 @@ config DVB_USB_DIB0700
87 Avermedia and other big and small companies. 88 Avermedia and other big and small companies.
88 89
89 For an up-to-date list of devices supported by this driver, have a look 90 For an up-to-date list of devices supported by this driver, have a look
90 on the Linux-DVB Wiki at www.linuxtv.org. 91 on the LinuxTV Wiki at www.linuxtv.org.
91 92
92 Say Y if you own such a device and want to use it. You should build it as 93 Say Y if you own such a device and want to use it. You should build it as
93 a module. 94 a module.
@@ -315,3 +316,9 @@ config DVB_USB_CE6230
315 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 316 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
316 help 317 help
317 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver 318 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
319
320config DVB_USB_FRIIO
321 tristate "Friio ISDB-T USB2.0 Receiver support"
322 depends on DVB_USB
323 help
324 Say Y here to support the Japanese DTV receiver Friio.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index f92734ed777a..85b83a43d55d 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -79,6 +79,9 @@ obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
79dvb-usb-ce6230-objs = ce6230.o 79dvb-usb-ce6230-objs = ce6230.o
80obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o 80obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
81 81
82dvb-usb-friio-objs = friio.o friio-fe.o
83obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
84
82EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 85EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
83# due to tuner-xc3028 86# due to tuner-xc3028
84EXTRA_CFLAGS += -Idrivers/media/common/tuners 87EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 99cdd0d101ca..cf042b309b46 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -61,10 +61,13 @@ static struct af9013_config af9015_af9013_config[] = {
61 61
62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) 62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
63{ 63{
64#define BUF_LEN 63
65#define REQ_HDR_LEN 8 /* send header size */
66#define ACK_HDR_LEN 2 /* rece header size */
64 int act_len, ret; 67 int act_len, ret;
65 u8 buf[64]; 68 u8 buf[BUF_LEN];
66 u8 write = 1; 69 u8 write = 1;
67 u8 msg_len = 8; 70 u8 msg_len = REQ_HDR_LEN;
68 static u8 seq; /* packet sequence number */ 71 static u8 seq; /* packet sequence number */
69 72
70 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0) 73 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
@@ -94,7 +97,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
94 break; 97 break;
95 case WRITE_MEMORY: 98 case WRITE_MEMORY:
96 if (((req->addr & 0xff00) == 0xff00) || 99 if (((req->addr & 0xff00) == 0xff00) ||
97 ((req->addr & 0xae00) == 0xae00)) 100 ((req->addr & 0xff00) == 0xae00))
98 buf[0] = WRITE_VIRTUAL_MEMORY; 101 buf[0] = WRITE_VIRTUAL_MEMORY;
99 case WRITE_VIRTUAL_MEMORY: 102 case WRITE_VIRTUAL_MEMORY:
100 case COPY_FIRMWARE: 103 case COPY_FIRMWARE:
@@ -107,17 +110,26 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
107 goto error_unlock; 110 goto error_unlock;
108 } 111 }
109 112
113 /* buffer overflow check */
114 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
115 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
116 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
117 ret = -EINVAL;
118 goto error_unlock;
119 }
120
110 /* write requested */ 121 /* write requested */
111 if (write) { 122 if (write) {
112 memcpy(&buf[8], req->data, req->data_len); 123 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
113 msg_len += req->data_len; 124 msg_len += req->data_len;
114 } 125 }
126
115 deb_xfer(">>> "); 127 deb_xfer(">>> ");
116 debug_dump(buf, msg_len, deb_xfer); 128 debug_dump(buf, msg_len, deb_xfer);
117 129
118 /* send req */ 130 /* send req */
119 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len, 131 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
120 &act_len, AF9015_USB_TIMEOUT); 132 &act_len, AF9015_USB_TIMEOUT);
121 if (ret) 133 if (ret)
122 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len); 134 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
123 else 135 else
@@ -130,10 +142,14 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
130 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) 142 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
131 goto exit_unlock; 143 goto exit_unlock;
132 144
133 /* receive ack and data if read req */ 145 /* write receives seq + status = 2 bytes
134 msg_len = 1 + 1 + req->data_len; /* seq + status + data len */ 146 read receives seq + status + data = 2 + N bytes */
147 msg_len = ACK_HDR_LEN;
148 if (!write)
149 msg_len += req->data_len;
150
135 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len, 151 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
136 &act_len, AF9015_USB_TIMEOUT); 152 &act_len, AF9015_USB_TIMEOUT);
137 if (ret) { 153 if (ret) {
138 err("recv bulk message failed:%d", ret); 154 err("recv bulk message failed:%d", ret);
139 ret = -1; 155 ret = -1;
@@ -159,7 +175,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
159 175
160 /* read request, copy returned data to return buf */ 176 /* read request, copy returned data to return buf */
161 if (!write) 177 if (!write)
162 memcpy(req->data, &buf[2], req->data_len); 178 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
163 179
164error_unlock: 180error_unlock:
165exit_unlock: 181exit_unlock:
@@ -369,12 +385,14 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
369 u8 packet_size; 385 u8 packet_size;
370 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed); 386 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
371 387
388 /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
389 We use smaller - about 1/4 from the original, 5 and 87. */
372#define TS_PACKET_SIZE 188 390#define TS_PACKET_SIZE 188
373 391
374#define TS_USB20_PACKET_COUNT 348 392#define TS_USB20_PACKET_COUNT 87
375#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) 393#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
376 394
377#define TS_USB11_PACKET_COUNT 21 395#define TS_USB11_PACKET_COUNT 5
378#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) 396#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
379 397
380#define TS_USB20_MAX_PACKET_SIZE 512 398#define TS_USB20_MAX_PACKET_SIZE 512
@@ -868,13 +886,13 @@ static int af9015_read_config(struct usb_device *udev)
868 /* USB1.1 set smaller buffersize and disable 2nd adapter */ 886 /* USB1.1 set smaller buffersize and disable 2nd adapter */
869 if (udev->speed == USB_SPEED_FULL) { 887 if (udev->speed == USB_SPEED_FULL) {
870 af9015_properties[i].adapter[0].stream.u.bulk.buffersize 888 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
871 = TS_USB11_MAX_PACKET_SIZE; 889 = TS_USB11_FRAME_SIZE;
872 /* disable 2nd adapter because we don't have 890 /* disable 2nd adapter because we don't have
873 PID-filters */ 891 PID-filters */
874 af9015_config.dual_mode = 0; 892 af9015_config.dual_mode = 0;
875 } else { 893 } else {
876 af9015_properties[i].adapter[0].stream.u.bulk.buffersize 894 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
877 = TS_USB20_MAX_PACKET_SIZE; 895 = TS_USB20_FRAME_SIZE;
878 } 896 }
879 } 897 }
880 898
@@ -1310,7 +1328,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1310 .u = { 1328 .u = {
1311 .bulk = { 1329 .bulk = {
1312 .buffersize = 1330 .buffersize =
1313 TS_USB20_MAX_PACKET_SIZE, 1331 TS_USB20_FRAME_SIZE,
1314 } 1332 }
1315 } 1333 }
1316 }, 1334 },
@@ -1416,7 +1434,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1416 .u = { 1434 .u = {
1417 .bulk = { 1435 .bulk = {
1418 .buffersize = 1436 .buffersize =
1419 TS_USB20_MAX_PACKET_SIZE, 1437 TS_USB20_FRAME_SIZE,
1420 } 1438 }
1421 } 1439 }
1422 }, 1440 },
@@ -1522,7 +1540,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1522 .u = { 1540 .u = {
1523 .bulk = { 1541 .bulk = {
1524 .buffersize = 1542 .buffersize =
1525 TS_USB20_MAX_PACKET_SIZE, 1543 TS_USB20_FRAME_SIZE,
1526 } 1544 }
1527 } 1545 }
1528 }, 1546 },
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 7381aff4dcf6..2ae7f648effe 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -203,11 +203,11 @@ static struct i2c_algorithm anysee_i2c_algo = {
203 203
204static int anysee_mt352_demod_init(struct dvb_frontend *fe) 204static int anysee_mt352_demod_init(struct dvb_frontend *fe)
205{ 205{
206 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; 206 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
207 static u8 reset [] = { RESET, 0x80 }; 207 static u8 reset[] = { RESET, 0x80 };
208 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; 208 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
209 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; 209 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
210 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; 210 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
211 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 211 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
212 212
213 mt352_write(fe, clock_config, sizeof(clock_config)); 213 mt352_write(fe, clock_config, sizeof(clock_config));
@@ -485,7 +485,7 @@ static int anysee_probe(struct usb_interface *intf,
485 return ret; 485 return ret;
486} 486}
487 487
488static struct usb_device_id anysee_table [] = { 488static struct usb_device_id anysee_table[] = {
489 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, 489 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
490 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, 490 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
491 { } /* Terminating entry */ 491 { } /* Terminating entry */
@@ -511,7 +511,7 @@ static struct dvb_usb_device_properties anysee_properties = {
511 .endpoint = 0x82, 511 .endpoint = 0x82,
512 .u = { 512 .u = {
513 .bulk = { 513 .bulk = {
514 .buffersize = 512, 514 .buffersize = (16*512),
515 } 515 }
516 } 516 }
517 }, 517 },
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 52badc00e673..0737c6377892 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -274,7 +274,7 @@ static struct dvb_usb_device_properties ce6230_properties = {
274 .endpoint = 0x82, 274 .endpoint = 0x82,
275 .u = { 275 .u = {
276 .bulk = { 276 .bulk = {
277 .buffersize = 512, 277 .buffersize = (16*512),
278 } 278 }
279 } 279 }
280 }, 280 },
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index d1d6f4491403..0b2812aa30a4 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -4,13 +4,14 @@
4 * under the terms of the GNU General Public License as published by the Free 4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2. 5 * Software Foundation, version 2.
6 * 6 *
7 * Copyright (C) 2005-7 DiBcom, SA 7 * Copyright (C) 2005-9 DiBcom, SA et al
8 */ 8 */
9#include "dib0700.h" 9#include "dib0700.h"
10 10
11#include "dib3000mc.h" 11#include "dib3000mc.h"
12#include "dib7000m.h" 12#include "dib7000m.h"
13#include "dib7000p.h" 13#include "dib7000p.h"
14#include "dib8000.h"
14#include "mt2060.h" 15#include "mt2060.h"
15#include "mt2266.h" 16#include "mt2266.h"
16#include "tuner-xc2028.h" 17#include "tuner-xc2028.h"
@@ -1098,11 +1099,13 @@ static struct dibx000_agc_config dib7070_agc_config = {
1098 1099
1099static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) 1100static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1100{ 1101{
1102 deb_info("reset: %d", onoff);
1101 return dib7000p_set_gpio(fe, 8, 0, !onoff); 1103 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1102} 1104}
1103 1105
1104static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) 1106static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1105{ 1107{
1108 deb_info("sleep: %d", onoff);
1106 return dib7000p_set_gpio(fe, 9, 0, onoff); 1109 return dib7000p_set_gpio(fe, 9, 0, onoff);
1107} 1110}
1108 1111
@@ -1112,16 +1115,26 @@ static struct dib0070_config dib7070p_dib0070_config[2] = {
1112 .reset = dib7070_tuner_reset, 1115 .reset = dib7070_tuner_reset,
1113 .sleep = dib7070_tuner_sleep, 1116 .sleep = dib7070_tuner_sleep,
1114 .clock_khz = 12000, 1117 .clock_khz = 12000,
1115 .clock_pad_drive = 4 1118 .clock_pad_drive = 4,
1119 .charge_pump = 2,
1116 }, { 1120 }, {
1117 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, 1121 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1118 .reset = dib7070_tuner_reset, 1122 .reset = dib7070_tuner_reset,
1119 .sleep = dib7070_tuner_sleep, 1123 .sleep = dib7070_tuner_sleep,
1120 .clock_khz = 12000, 1124 .clock_khz = 12000,
1121 1125 .charge_pump = 2,
1122 } 1126 }
1123}; 1127};
1124 1128
1129static struct dib0070_config dib7770p_dib0070_config = {
1130 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1131 .reset = dib7070_tuner_reset,
1132 .sleep = dib7070_tuner_sleep,
1133 .clock_khz = 12000,
1134 .clock_pad_drive = 0,
1135 .flip_chip = 1,
1136};
1137
1125static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1138static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1126{ 1139{
1127 struct dvb_usb_adapter *adap = fe->dvb->priv; 1140 struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -1139,6 +1152,45 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte
1139 return state->set_param_save(fe, fep); 1152 return state->set_param_save(fe, fep);
1140} 1153}
1141 1154
1155static int dib7770_set_param_override(struct dvb_frontend *fe,
1156 struct dvb_frontend_parameters *fep)
1157{
1158 struct dvb_usb_adapter *adap = fe->dvb->priv;
1159 struct dib0700_adapter_state *state = adap->priv;
1160
1161 u16 offset;
1162 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1163 switch (band) {
1164 case BAND_VHF:
1165 dib7000p_set_gpio(fe, 0, 0, 1);
1166 offset = 850;
1167 break;
1168 case BAND_UHF:
1169 default:
1170 dib7000p_set_gpio(fe, 0, 0, 0);
1171 offset = 250;
1172 break;
1173 }
1174 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1175 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1176 return state->set_param_save(fe, fep);
1177}
1178
1179static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
1180{
1181 struct dib0700_adapter_state *st = adap->priv;
1182 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
1183 DIBX000_I2C_INTERFACE_TUNER, 1);
1184
1185 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1186 &dib7770p_dib0070_config) == NULL)
1187 return -ENODEV;
1188
1189 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1190 adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
1191 return 0;
1192}
1193
1142static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) 1194static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1143{ 1195{
1144 struct dib0700_adapter_state *st = adap->priv; 1196 struct dib0700_adapter_state *st = adap->priv;
@@ -1217,6 +1269,306 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1217 return adap->fe == NULL ? -ENODEV : 0; 1269 return adap->fe == NULL ? -ENODEV : 0;
1218} 1270}
1219 1271
1272/* DIB807x generic */
1273static struct dibx000_agc_config dib807x_agc_config[2] = {
1274 {
1275 BAND_VHF,
1276 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1277 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1278 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1279 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1280 * P_agc_write=0 */
1281 (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1282 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1283 (0 << 0), /* setup*/
1284
1285 600, /* inv_gain*/
1286 10, /* time_stabiliz*/
1287
1288 0, /* alpha_level*/
1289 118, /* thlock*/
1290
1291 0, /* wbd_inv*/
1292 3530, /* wbd_ref*/
1293 1, /* wbd_sel*/
1294 5, /* wbd_alpha*/
1295
1296 65535, /* agc1_max*/
1297 0, /* agc1_min*/
1298
1299 65535, /* agc2_max*/
1300 0, /* agc2_min*/
1301
1302 0, /* agc1_pt1*/
1303 40, /* agc1_pt2*/
1304 183, /* agc1_pt3*/
1305 206, /* agc1_slope1*/
1306 255, /* agc1_slope2*/
1307 72, /* agc2_pt1*/
1308 152, /* agc2_pt2*/
1309 88, /* agc2_slope1*/
1310 90, /* agc2_slope2*/
1311
1312 17, /* alpha_mant*/
1313 27, /* alpha_exp*/
1314 23, /* beta_mant*/
1315 51, /* beta_exp*/
1316
1317 0, /* perform_agc_softsplit*/
1318 }, {
1319 BAND_UHF,
1320 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1321 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1322 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1323 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1324 * P_agc_write=0 */
1325 (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1326 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1327 (0 << 0), /* setup */
1328
1329 600, /* inv_gain*/
1330 10, /* time_stabiliz*/
1331
1332 0, /* alpha_level*/
1333 118, /* thlock*/
1334
1335 0, /* wbd_inv*/
1336 3530, /* wbd_ref*/
1337 1, /* wbd_sel*/
1338 5, /* wbd_alpha*/
1339
1340 65535, /* agc1_max*/
1341 0, /* agc1_min*/
1342
1343 65535, /* agc2_max*/
1344 0, /* agc2_min*/
1345
1346 0, /* agc1_pt1*/
1347 40, /* agc1_pt2*/
1348 183, /* agc1_pt3*/
1349 206, /* agc1_slope1*/
1350 255, /* agc1_slope2*/
1351 72, /* agc2_pt1*/
1352 152, /* agc2_pt2*/
1353 88, /* agc2_slope1*/
1354 90, /* agc2_slope2*/
1355
1356 17, /* alpha_mant*/
1357 27, /* alpha_exp*/
1358 23, /* beta_mant*/
1359 51, /* beta_exp*/
1360
1361 0, /* perform_agc_softsplit*/
1362 }
1363};
1364
1365static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1366 60000, 15000, /* internal, sampling*/
1367 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1368 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1369 ADClkSrc, modulo */
1370 (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1371 (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1372 18179755, /* timf*/
1373 12000000, /* xtal_hz*/
1374};
1375
1376static struct dib8000_config dib807x_dib8000_config[2] = {
1377 {
1378 .output_mpeg2_in_188_bytes = 1,
1379
1380 .agc_config_count = 2,
1381 .agc = dib807x_agc_config,
1382 .pll = &dib807x_bw_config_12_mhz,
1383 .tuner_is_baseband = 1,
1384
1385 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1386 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1387 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1388
1389 .hostbus_diversity = 1,
1390 .div_cfg = 1,
1391 .agc_control = &dib0070_ctrl_agc_filter,
1392 .output_mode = OUTMODE_MPEG2_FIFO,
1393 .drives = 0x2d98,
1394 }, {
1395 .output_mpeg2_in_188_bytes = 1,
1396
1397 .agc_config_count = 2,
1398 .agc = dib807x_agc_config,
1399 .pll = &dib807x_bw_config_12_mhz,
1400 .tuner_is_baseband = 1,
1401
1402 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1403 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1404 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1405
1406 .hostbus_diversity = 1,
1407 .agc_control = &dib0070_ctrl_agc_filter,
1408 .output_mode = OUTMODE_MPEG2_FIFO,
1409 .drives = 0x2d98,
1410 }
1411};
1412
1413static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
1414{
1415 return dib8000_set_gpio(fe, 5, 0, !onoff);
1416}
1417
1418static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
1419{
1420 return dib8000_set_gpio(fe, 0, 0, onoff);
1421}
1422
1423static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1424 { 240, 7},
1425 { 0xffff, 6},
1426};
1427
1428static struct dib0070_config dib807x_dib0070_config[2] = {
1429 {
1430 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1431 .reset = dib807x_tuner_reset,
1432 .sleep = dib807x_tuner_sleep,
1433 .clock_khz = 12000,
1434 .clock_pad_drive = 4,
1435 .vga_filter = 1,
1436 .force_crystal_mode = 1,
1437 .enable_third_order_filter = 1,
1438 .charge_pump = 0,
1439 .wbd_gain = dib8070_wbd_gain_cfg,
1440 .osc_buffer_state = 0,
1441 .freq_offset_khz_uhf = -100,
1442 .freq_offset_khz_vhf = -100,
1443 }, {
1444 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1445 .reset = dib807x_tuner_reset,
1446 .sleep = dib807x_tuner_sleep,
1447 .clock_khz = 12000,
1448 .clock_pad_drive = 2,
1449 .vga_filter = 1,
1450 .force_crystal_mode = 1,
1451 .enable_third_order_filter = 1,
1452 .charge_pump = 0,
1453 .wbd_gain = dib8070_wbd_gain_cfg,
1454 .osc_buffer_state = 0,
1455 .freq_offset_khz_uhf = -25,
1456 .freq_offset_khz_vhf = -25,
1457 }
1458};
1459
1460static int dib807x_set_param_override(struct dvb_frontend *fe,
1461 struct dvb_frontend_parameters *fep)
1462{
1463 struct dvb_usb_adapter *adap = fe->dvb->priv;
1464 struct dib0700_adapter_state *state = adap->priv;
1465
1466 u16 offset = dib0070_wbd_offset(fe);
1467 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1468 switch (band) {
1469 case BAND_VHF:
1470 offset += 750;
1471 break;
1472 case BAND_UHF: /* fall-thru wanted */
1473 default:
1474 offset += 250; break;
1475 }
1476 deb_info("WBD for DiB8000: %d\n", offset);
1477 dib8000_set_wbd_ref(fe, offset);
1478
1479 return state->set_param_save(fe, fep);
1480}
1481
1482static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1483{
1484 struct dib0700_adapter_state *st = adap->priv;
1485 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
1486 DIBX000_I2C_INTERFACE_TUNER, 1);
1487
1488 if (adap->id == 0) {
1489 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1490 &dib807x_dib0070_config[0]) == NULL)
1491 return -ENODEV;
1492 } else {
1493 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1494 &dib807x_dib0070_config[1]) == NULL)
1495 return -ENODEV;
1496 }
1497
1498 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1499 adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1500 return 0;
1501}
1502
1503
1504/* STK807x */
1505static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1506{
1507 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1508 msleep(10);
1509 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1510 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1511 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1512
1513 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1514
1515 dib0700_ctrl_clock(adap->dev, 72, 1);
1516
1517 msleep(10);
1518 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1519 msleep(10);
1520 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1521
1522 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1523 0x80);
1524
1525 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1526 &dib807x_dib8000_config[0]);
1527
1528 return adap->fe == NULL ? -ENODEV : 0;
1529}
1530
1531/* STK807xPVR */
1532static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1533{
1534 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1535 msleep(30);
1536 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1537 msleep(500);
1538 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1539 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1540 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1541
1542 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1543
1544 dib0700_ctrl_clock(adap->dev, 72, 1);
1545
1546 msleep(10);
1547 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1548 msleep(10);
1549 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1550
1551 /* initialize IC 0 */
1552 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
1553
1554 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1555 &dib807x_dib8000_config[0]);
1556
1557 return adap->fe == NULL ? -ENODEV : 0;
1558}
1559
1560static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1561{
1562 /* initialize IC 1 */
1563 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
1564
1565 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1566 &dib807x_dib8000_config[1]);
1567
1568 return adap->fe == NULL ? -ENODEV : 0;
1569}
1570
1571
1220/* STK7070PD */ 1572/* STK7070PD */
1221static struct dib7000p_config stk7070pd_dib7000p_config[2] = { 1573static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1222 { 1574 {
@@ -1500,7 +1852,15 @@ struct usb_device_id dib0700_usb_id_table[] = {
1500 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) }, 1852 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
1501 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) }, 1853 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
1502 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) }, 1854 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
1503 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) }, 1855/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
1856 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
1857 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
1858 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
1859 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
1860/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
1861 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
1862 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
1863 { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
1504 { 0 } /* Terminating entry */ 1864 { 0 } /* Terminating entry */
1505}; 1865};
1506MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1866MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1565,7 +1925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1565 { NULL }, 1925 { NULL },
1566 }, 1926 },
1567 { "Leadtek Winfast DTV Dongle (STK7700P based)", 1927 { "Leadtek Winfast DTV Dongle (STK7700P based)",
1568 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] }, 1928 { &dib0700_usb_id_table[8] },
1569 { NULL }, 1929 { NULL },
1570 }, 1930 },
1571 { "AVerMedia AVerTV DVB-T Express", 1931 { "AVerMedia AVerTV DVB-T Express",
@@ -1764,6 +2124,41 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1764 2124
1765 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2125 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1766 2126
2127 .num_adapters = 1,
2128 .adapter = {
2129 {
2130 .frontend_attach = stk7070p_frontend_attach,
2131 .tuner_attach = dib7070p_tuner_attach,
2132
2133 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2134
2135 .size_of_priv = sizeof(struct dib0700_adapter_state),
2136 },
2137 },
2138
2139 .num_device_descs = 3,
2140 .devices = {
2141 { "Pinnacle PCTV 73A",
2142 { &dib0700_usb_id_table[56], NULL },
2143 { NULL },
2144 },
2145 { "Pinnacle PCTV 73e SE",
2146 { &dib0700_usb_id_table[57], NULL },
2147 { NULL },
2148 },
2149 { "Pinnacle PCTV 282e",
2150 { &dib0700_usb_id_table[58], NULL },
2151 { NULL },
2152 },
2153 },
2154
2155 .rc_interval = DEFAULT_RC_INTERVAL,
2156 .rc_key_map = dib0700_rc_keys,
2157 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2158 .rc_query = dib0700_rc_query
2159
2160 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2161
1767 .num_adapters = 2, 2162 .num_adapters = 2,
1768 .adapter = { 2163 .adapter = {
1769 { 2164 {
@@ -1927,6 +2322,102 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1927 { NULL }, 2322 { NULL },
1928 }, 2323 },
1929 }, 2324 },
2325 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2326
2327 .num_adapters = 1,
2328 .adapter = {
2329 {
2330 .frontend_attach = stk7070p_frontend_attach,
2331 .tuner_attach = dib7770p_tuner_attach,
2332
2333 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2334
2335 .size_of_priv =
2336 sizeof(struct dib0700_adapter_state),
2337 },
2338 },
2339
2340 .num_device_descs = 2,
2341 .devices = {
2342 { "DiBcom STK7770P reference design",
2343 { &dib0700_usb_id_table[59], NULL },
2344 { NULL },
2345 },
2346 { "Terratec Cinergy T USB XXS (HD)",
2347 { &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
2348 { NULL },
2349 },
2350 },
2351 .rc_interval = DEFAULT_RC_INTERVAL,
2352 .rc_key_map = dib0700_rc_keys,
2353 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2354 .rc_query = dib0700_rc_query
2355 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2356 .num_adapters = 1,
2357 .adapter = {
2358 {
2359 .frontend_attach = stk807x_frontend_attach,
2360 .tuner_attach = dib807x_tuner_attach,
2361
2362 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2363
2364 .size_of_priv =
2365 sizeof(struct dib0700_adapter_state),
2366 },
2367 },
2368
2369 .num_device_descs = 2,
2370 .devices = {
2371 { "DiBcom STK807xP reference design",
2372 { &dib0700_usb_id_table[62], NULL },
2373 { NULL },
2374 },
2375 { "Prolink Pixelview SBTVD",
2376 { &dib0700_usb_id_table[63], NULL },
2377 { NULL },
2378 },
2379 },
2380
2381 .rc_interval = DEFAULT_RC_INTERVAL,
2382 .rc_key_map = dib0700_rc_keys,
2383 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2384 .rc_query = dib0700_rc_query
2385
2386 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2387 .num_adapters = 2,
2388 .adapter = {
2389 {
2390 .frontend_attach = stk807xpvr_frontend_attach0,
2391 .tuner_attach = dib807x_tuner_attach,
2392
2393 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2394
2395 .size_of_priv =
2396 sizeof(struct dib0700_adapter_state),
2397 },
2398 {
2399 .frontend_attach = stk807xpvr_frontend_attach1,
2400 .tuner_attach = dib807x_tuner_attach,
2401
2402 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
2403
2404 .size_of_priv =
2405 sizeof(struct dib0700_adapter_state),
2406 },
2407 },
2408
2409 .num_device_descs = 1,
2410 .devices = {
2411 { "DiBcom STK807xPVR reference design",
2412 { &dib0700_usb_id_table[61], NULL },
2413 { NULL },
2414 },
2415 },
2416
2417 .rc_interval = DEFAULT_RC_INTERVAL,
2418 .rc_key_map = dib0700_rc_keys,
2419 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2420 .rc_query = dib0700_rc_query
1930 }, 2421 },
1931}; 2422};
1932 2423
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 185a5069b10b..a548c14c1944 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -46,6 +46,7 @@
46#define USB_VID_MSI_2 0x1462 46#define USB_VID_MSI_2 0x1462
47#define USB_VID_OPERA1 0x695c 47#define USB_VID_OPERA1 0x695c
48#define USB_VID_PINNACLE 0x2304 48#define USB_VID_PINNACLE 0x2304
49#define USB_VID_PIXELVIEW 0x1554
49#define USB_VID_TECHNOTREND 0x0b48 50#define USB_VID_TECHNOTREND 0x0b48
50#define USB_VID_TERRATEC 0x0ccd 51#define USB_VID_TERRATEC 0x0ccd
51#define USB_VID_TELESTAR 0x10b9 52#define USB_VID_TELESTAR 0x10b9
@@ -59,6 +60,7 @@
59#define USB_VID_YUAN 0x1164 60#define USB_VID_YUAN 0x1164
60#define USB_VID_XTENSIONS 0x1ae7 61#define USB_VID_XTENSIONS 0x1ae7
61#define USB_VID_HUMAX_COEX 0x10b9 62#define USB_VID_HUMAX_COEX 0x10b9
63#define USB_VID_774 0x7a69
62 64
63/* Product IDs */ 65/* Product IDs */
64#define USB_PID_ADSTECH_USB2_COLD 0xa333 66#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -95,7 +97,10 @@
95#define USB_PID_DIBCOM_STK7700_U7000 0x7001 97#define USB_PID_DIBCOM_STK7700_U7000 0x7001
96#define USB_PID_DIBCOM_STK7070P 0x1ebc 98#define USB_PID_DIBCOM_STK7070P 0x1ebc
97#define USB_PID_DIBCOM_STK7070PD 0x1ebe 99#define USB_PID_DIBCOM_STK7070PD 0x1ebe
100#define USB_PID_DIBCOM_STK807XP 0x1f90
101#define USB_PID_DIBCOM_STK807XPVR 0x1f98
98#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 102#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
103#define USB_PID_DIBCOM_STK7770P 0x1e80
99#define USB_PID_DPOSH_M9206_COLD 0x9206 104#define USB_PID_DPOSH_M9206_COLD 0x9206
100#define USB_PID_DPOSH_M9206_WARM 0xa090 105#define USB_PID_DPOSH_M9206_WARM 0xa090
101#define USB_PID_UNIWILL_STK7700P 0x6003 106#define USB_PID_UNIWILL_STK7700P 0x6003
@@ -184,6 +189,7 @@
184#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 189#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
185#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 190#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
186#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 191#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
192#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
187#define USB_PID_TERRATEC_T3 0x10a0 193#define USB_PID_TERRATEC_T3 0x10a0
188#define USB_PID_TERRATEC_T5 0x10a1 194#define USB_PID_TERRATEC_T5 0x10a1
189#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e 195#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
@@ -195,6 +201,10 @@
195#define USB_PID_PINNACLE_PCTV73E 0x0237 201#define USB_PID_PINNACLE_PCTV73E 0x0237
196#define USB_PID_PINNACLE_PCTV801E 0x023a 202#define USB_PID_PINNACLE_PCTV801E 0x023a
197#define USB_PID_PINNACLE_PCTV801E_SE 0x023b 203#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
204#define USB_PID_PINNACLE_PCTV73A 0x0243
205#define USB_PID_PINNACLE_PCTV73ESE 0x0245
206#define USB_PID_PINNACLE_PCTV282E 0x0248
207#define USB_PID_PIXELVIEW_SBTVD 0x5010
198#define USB_PID_PCTV_200E 0x020e 208#define USB_PID_PCTV_200E 0x020e
199#define USB_PID_PCTV_400E 0x020f 209#define USB_PID_PCTV_400E 0x020f
200#define USB_PID_PCTV_450E 0x0222 210#define USB_PID_PCTV_450E 0x0222
@@ -265,5 +275,6 @@
265#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 275#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
266#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 276#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
267#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 277#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
278#define USB_PID_FRIIO_WHITE 0x0001
268 279
269#endif 280#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
new file mode 100644
index 000000000000..c4dfe25cf60d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -0,0 +1,483 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/slab.h>
16
17#include "friio.h"
18
19struct jdvbt90502_state {
20 struct i2c_adapter *i2c;
21 struct dvb_frontend frontend;
22 struct jdvbt90502_config config;
23};
24
25/* NOTE: TC90502 has 16bit register-address? */
26/* register 0x0100 is used for reading PLL status, so reg is u16 here */
27static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
28 const u16 reg, u8 *buf, const size_t count)
29{
30 int ret;
31 u8 wbuf[3];
32 struct i2c_msg msg[2];
33
34 wbuf[0] = reg & 0xFF;
35 wbuf[1] = 0;
36 wbuf[2] = reg >> 8;
37
38 msg[0].addr = state->config.demod_address;
39 msg[0].flags = 0;
40 msg[0].buf = wbuf;
41 msg[0].len = sizeof(wbuf);
42
43 msg[1].addr = msg[0].addr;
44 msg[1].flags = I2C_M_RD;
45 msg[1].buf = buf;
46 msg[1].len = count;
47
48 ret = i2c_transfer(state->i2c, msg, 2);
49 if (ret != 2) {
50 deb_fe(" reg read failed.\n");
51 return -EREMOTEIO;
52 }
53 return 0;
54}
55
56/* currently 16bit register-address is not used, so reg is u8 here */
57static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
58 const u8 reg, const u8 val)
59{
60 struct i2c_msg msg;
61 u8 wbuf[2];
62
63 wbuf[0] = reg;
64 wbuf[1] = val;
65
66 msg.addr = state->config.demod_address;
67 msg.flags = 0;
68 msg.buf = wbuf;
69 msg.len = sizeof(wbuf);
70
71 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
72 deb_fe(" reg write failed.");
73 return -EREMOTEIO;
74 }
75 return 0;
76}
77
78static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
79{
80 struct jdvbt90502_state *state = fe->demodulator_priv;
81 int err, i;
82 for (i = 0; i < len - 1; i++) {
83 err = jdvbt90502_single_reg_write(state,
84 buf[0] + i, buf[i + 1]);
85 if (err)
86 return err;
87 }
88
89 return 0;
90}
91
92/* read pll status byte via the demodulator's I2C register */
93/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
94static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
95{
96 int ret;
97
98 /* +1 for reading */
99 u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
100
101 *result = 0;
102
103 ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
104 pll_addr_byte);
105 if (ret)
106 goto error;
107
108 ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
109 if (ret)
110 goto error;
111
112 deb_fe("PLL read val:%02x\n", *result);
113 return 0;
114
115error:
116 deb_fe("%s:ret == %d\n", __func__, ret);
117 return -EREMOTEIO;
118}
119
120
121/* set pll frequency via the demodulator's I2C register */
122static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
123{
124 int ret;
125 int retry;
126 u8 res1;
127 u8 res2[9];
128
129 u8 pll_freq_cmd[PLL_CMD_LEN];
130 u8 pll_agc_cmd[PLL_CMD_LEN];
131 struct i2c_msg msg[2];
132 u32 f;
133
134 deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
135 state->frontend.ops.info.frequency_stepsize);
136 /* freq -> oscilator frequency conversion. */
137 /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
138 /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */
139 /* 1/7MHz for center freq shift */
140 f = freq / state->frontend.ops.info.frequency_stepsize;
141 f += 400;
142 pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
143 pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
144 pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
145 pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
146 pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
147 pll_freq_cmd[BANDSWITCH_BYTE] = 0x08; /* UHF band */
148
149 msg[0].addr = state->config.demod_address;
150 msg[0].flags = 0;
151 msg[0].buf = pll_freq_cmd;
152 msg[0].len = sizeof(pll_freq_cmd);
153
154 ret = i2c_transfer(state->i2c, &msg[0], 1);
155 if (ret != 1)
156 goto error;
157
158 udelay(50);
159
160 pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
161 pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
162 pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
163 pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
164 pll_agc_cmd[CONTROL_BYTE] = 0x9A; /* AGC_CTRL instead of BANDSWITCH */
165 pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
166 /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
167
168 msg[1].addr = msg[0].addr;
169 msg[1].flags = 0;
170 msg[1].buf = pll_agc_cmd;
171 msg[1].len = sizeof(pll_agc_cmd);
172
173 ret = i2c_transfer(state->i2c, &msg[1], 1);
174 if (ret != 1)
175 goto error;
176
177 /* I don't know what these cmds are for, */
178 /* but the USB log on a windows box contains them */
179 ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
180 ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
181 if (ret)
182 goto error;
183 udelay(100);
184
185 /* wait for the demod to be ready? */
186#define RETRY_COUNT 5
187 for (retry = 0; retry < RETRY_COUNT; retry++) {
188 ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
189 if (ret)
190 goto error;
191 /* if (res1 != 0x00) goto error; */
192 ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
193 if (ret)
194 goto error;
195 if (res2[0] >= 0xA7)
196 break;
197 msleep(100);
198 }
199 if (retry >= RETRY_COUNT) {
200 deb_fe("%s: FE does not get ready after freq setting.\n",
201 __func__);
202 return -EREMOTEIO;
203 }
204
205 return 0;
206error:
207 deb_fe("%s:ret == %d\n", __func__, ret);
208 return -EREMOTEIO;
209}
210
211static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
212{
213 u8 result;
214 int ret;
215
216 *state = FE_HAS_SIGNAL;
217
218 ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
219 if (ret) {
220 deb_fe("%s:ret == %d\n", __func__, ret);
221 return -EREMOTEIO;
222 }
223
224 *state = FE_HAS_SIGNAL
225 | FE_HAS_CARRIER
226 | FE_HAS_VITERBI
227 | FE_HAS_SYNC;
228
229 if (result & PLL_STATUS_LOCKED)
230 *state |= FE_HAS_LOCK;
231
232 return 0;
233}
234
235static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
236{
237 *ber = 0;
238 return 0;
239}
240
241static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
242 u16 *strength)
243{
244 int ret;
245 u8 rbuf[37];
246
247 *strength = 0;
248
249 /* status register (incl. signal strength) : 0x89 */
250 /* TODO: read just the necessary registers [0x8B..0x8D]? */
251 ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
252 rbuf, sizeof(rbuf));
253
254 if (ret) {
255 deb_fe("%s:ret == %d\n", __func__, ret);
256 return -EREMOTEIO;
257 }
258
259 /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
260 *strength = (rbuf[3] << 8) + rbuf[4];
261 if (rbuf[2])
262 *strength = 0xffff;
263
264 return 0;
265}
266
267static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
268{
269 *snr = 0x0101;
270 return 0;
271}
272
273static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
274{
275 *ucblocks = 0;
276 return 0;
277}
278
279static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe,
280 struct dvb_frontend_tune_settings *fs)
281{
282 fs->min_delay_ms = 500;
283 fs->step_size = 0;
284 fs->max_drift = 0;
285
286 return 0;
287}
288
289static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
290 struct dvb_frontend_parameters *p)
291{
292 p->inversion = INVERSION_AUTO;
293 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
294 p->u.ofdm.code_rate_HP = FEC_AUTO;
295 p->u.ofdm.code_rate_LP = FEC_AUTO;
296 p->u.ofdm.constellation = QAM_64;
297 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
298 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
299 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
300 return 0;
301}
302
303static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
304 struct dvb_frontend_parameters *p)
305{
306 /**
307 * NOTE: ignore all the paramters except frequency.
308 * others should be fixed to the proper value for ISDB-T,
309 * but don't check here.
310 */
311
312 struct jdvbt90502_state *state = fe->demodulator_priv;
313 int ret;
314
315 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
316
317 ret = jdvbt90502_pll_set_freq(state, p->frequency);
318 if (ret) {
319 deb_fe("%s:ret == %d\n", __func__, ret);
320 return -EREMOTEIO;
321 }
322
323 return 0;
324}
325
326static int jdvbt90502_sleep(struct dvb_frontend *fe)
327{
328 deb_fe("%s called.\n", __func__);
329 return 0;
330}
331
332
333/**
334 * (reg, val) commad list to initialize this module.
335 * captured on a Windows box.
336 */
337static u8 init_code[][2] = {
338 {0x01, 0x40},
339 {0x04, 0x38},
340 {0x05, 0x40},
341 {0x07, 0x40},
342 {0x0F, 0x4F},
343 {0x11, 0x21},
344 {0x12, 0x0B},
345 {0x13, 0x2F},
346 {0x14, 0x31},
347 {0x16, 0x02},
348 {0x21, 0xC4},
349 {0x22, 0x20},
350 {0x2C, 0x79},
351 {0x2D, 0x34},
352 {0x2F, 0x00},
353 {0x30, 0x28},
354 {0x31, 0x31},
355 {0x32, 0xDF},
356 {0x38, 0x01},
357 {0x39, 0x78},
358 {0x3B, 0x33},
359 {0x3C, 0x33},
360 {0x48, 0x90},
361 {0x51, 0x68},
362 {0x5E, 0x38},
363 {0x71, 0x00},
364 {0x72, 0x08},
365 {0x77, 0x00},
366 {0xC0, 0x21},
367 {0xC1, 0x10},
368 {0xE4, 0x1A},
369 {0xEA, 0x1F},
370 {0x77, 0x00},
371 {0x71, 0x00},
372 {0x71, 0x00},
373 {0x76, 0x0C},
374};
375
376const static int init_code_len = sizeof(init_code) / sizeof(u8[2]);
377
378static int jdvbt90502_init(struct dvb_frontend *fe)
379{
380 int i = -1;
381 int ret;
382 struct i2c_msg msg;
383
384 struct jdvbt90502_state *state = fe->demodulator_priv;
385
386 deb_fe("%s called.\n", __func__);
387
388 msg.addr = state->config.demod_address;
389 msg.flags = 0;
390 msg.len = 2;
391 for (i = 0; i < init_code_len; i++) {
392 msg.buf = init_code[i];
393 ret = i2c_transfer(state->i2c, &msg, 1);
394 if (ret != 1)
395 goto error;
396 }
397 msleep(100);
398
399 return 0;
400
401error:
402 deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
403 return -EREMOTEIO;
404}
405
406
407static void jdvbt90502_release(struct dvb_frontend *fe)
408{
409 struct jdvbt90502_state *state = fe->demodulator_priv;
410 kfree(state);
411}
412
413
414static struct dvb_frontend_ops jdvbt90502_ops;
415
416struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
417{
418 struct jdvbt90502_state *state = NULL;
419
420 deb_info("%s called.\n", __func__);
421
422 /* allocate memory for the internal state */
423 state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
424 if (state == NULL)
425 goto error;
426
427 /* setup the state */
428 state->i2c = &d->i2c_adap;
429 memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
430
431 /* create dvb_frontend */
432 memcpy(&state->frontend.ops, &jdvbt90502_ops,
433 sizeof(jdvbt90502_ops));
434 state->frontend.demodulator_priv = state;
435
436 if (jdvbt90502_init(&state->frontend) < 0)
437 goto error;
438
439 return &state->frontend;
440
441error:
442 kfree(state);
443 return NULL;
444}
445
446static struct dvb_frontend_ops jdvbt90502_ops = {
447
448 .info = {
449 .name = "Comtech JDVBT90502 ISDB-T",
450 .type = FE_OFDM,
451 .frequency_min = 473000000, /* UHF 13ch, center */
452 .frequency_max = 767142857, /* UHF 62ch, center */
453 .frequency_stepsize = JDVBT90502_PLL_CLK /
454 JDVBT90502_PLL_DIVIDER,
455 .frequency_tolerance = 0,
456
457 /* NOTE: this driver ignores all parameters but frequency. */
458 .caps = FE_CAN_INVERSION_AUTO |
459 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
460 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
461 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
462 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
463 FE_CAN_TRANSMISSION_MODE_AUTO |
464 FE_CAN_GUARD_INTERVAL_AUTO |
465 FE_CAN_HIERARCHY_AUTO,
466 },
467
468 .release = jdvbt90502_release,
469
470 .init = jdvbt90502_init,
471 .sleep = jdvbt90502_sleep,
472 .write = _jdvbt90502_write,
473
474 .set_frontend = jdvbt90502_set_frontend,
475 .get_frontend = jdvbt90502_get_frontend,
476 .get_tune_settings = jdvbt90502_get_tune_settings,
477
478 .read_status = jdvbt90502_read_status,
479 .read_ber = jdvbt90502_read_ber,
480 .read_signal_strength = jdvbt90502_read_signal_strength,
481 .read_snr = jdvbt90502_read_snr,
482 .read_ucblocks = jdvbt90502_read_ucblocks,
483};
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
new file mode 100644
index 000000000000..14a65b4aec07
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.c
@@ -0,0 +1,525 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include "friio.h"
14
15/* debug */
16int dvb_usb_friio_debug;
17module_param_named(debug, dvb_usb_friio_debug, int, 0644);
18MODULE_PARM_DESC(debug,
19 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
20 DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24/**
25 * Indirect I2C access to the PLL via FE.
26 * whole I2C protocol data to the PLL is sent via the FE's I2C register.
27 * This is done by a control msg to the FE with the I2C data accompanied, and
28 * a specific USB request number is assigned for that purpose.
29 *
30 * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
31 * TODO: refoctored, smarter i2c functions.
32 */
33static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
34 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
35{
36 u16 index = wbuf[0]; /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
37 u16 value = addr << (8 + 1);
38 int wo = (rbuf == NULL || rlen == 0); /* write only */
39 u8 req, type;
40
41 deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
42 wbuf[1], wbuf[0], wlen - 1);
43
44 if (wo && wlen >= 2) {
45 req = GL861_REQ_I2C_DATA_CTRL_WRITE;
46 type = GL861_WRITE;
47 udelay(20);
48 return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
49 req, type, value, index,
50 &wbuf[1], wlen - 1, 2000);
51 }
52
53 deb_xfer("not supported ctrl-msg, aborting.");
54 return -EINVAL;
55}
56
57/* normal I2C access (without extra data arguments).
58 * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
59 * or read from the register wbuf[0].
60 * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
61 */
62static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
63 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
64{
65 u16 index;
66 u16 value = addr << (8 + 1);
67 int wo = (rbuf == NULL || rlen == 0); /* write-only */
68 u8 req, type;
69 unsigned int pipe;
70
71 /* special case for the indirect I2C access to the PLL via FE, */
72 if (addr == friio_fe_config.demod_address &&
73 wbuf[0] == JDVBT90502_2ND_I2C_REG)
74 return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
75
76 if (wo) {
77 req = GL861_REQ_I2C_WRITE;
78 type = GL861_WRITE;
79 pipe = usb_sndctrlpipe(d->udev, 0);
80 } else { /* rw */
81 req = GL861_REQ_I2C_READ;
82 type = GL861_READ;
83 pipe = usb_rcvctrlpipe(d->udev, 0);
84 }
85
86 switch (wlen) {
87 case 1:
88 index = wbuf[0];
89 break;
90 case 2:
91 index = wbuf[0];
92 value = value + wbuf[1];
93 break;
94 case 3:
95 /* special case for 16bit register-address */
96 index = (wbuf[2] << 8) | wbuf[0];
97 value = value + wbuf[1];
98 break;
99 default:
100 deb_xfer("wlen = %x, aborting.", wlen);
101 return -EINVAL;
102 }
103 msleep(1);
104 return usb_control_msg(d->udev, pipe, req, type,
105 value, index, rbuf, rlen, 2000);
106}
107
108/* I2C */
109static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
110 int num)
111{
112 struct dvb_usb_device *d = i2c_get_adapdata(adap);
113 int i;
114
115
116 if (num > 2)
117 return -EINVAL;
118
119 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
120 return -EAGAIN;
121
122 for (i = 0; i < num; i++) {
123 /* write/read request */
124 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
125 if (gl861_i2c_msg(d, msg[i].addr,
126 msg[i].buf, msg[i].len,
127 msg[i + 1].buf, msg[i + 1].len) < 0)
128 break;
129 i++;
130 } else
131 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
132 msg[i].len, NULL, 0) < 0)
133 break;
134 }
135
136 mutex_unlock(&d->i2c_mutex);
137 return i;
138}
139
140static u32 gl861_i2c_func(struct i2c_adapter *adapter)
141{
142 return I2C_FUNC_I2C;
143}
144
145
146static int friio_ext_ctl(struct dvb_usb_adapter *adap,
147 u32 sat_color, int lnb_on)
148{
149 int i;
150 int ret;
151 struct i2c_msg msg;
152 u8 buf[2];
153 u32 mask;
154 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
155
156 msg.addr = 0x00;
157 msg.flags = 0;
158 msg.len = 2;
159 msg.buf = buf;
160
161 buf[0] = 0x00;
162
163 /* send 2bit header (&B10) */
164 buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
165 ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
166 buf[1] |= FRIIO_CTL_CLK;
167 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
168
169 buf[1] = lnb | FRIIO_CTL_STROBE;
170 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
171 buf[1] |= FRIIO_CTL_CLK;
172 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
173
174 /* send 32bit(satur, R, G, B) data in serial */
175 mask = 1 << 31;
176 for (i = 0; i < 32; i++) {
177 buf[1] = lnb | FRIIO_CTL_STROBE;
178 if (sat_color & mask)
179 buf[1] |= FRIIO_CTL_LED;
180 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
181 buf[1] |= FRIIO_CTL_CLK;
182 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
183 mask >>= 1;
184 }
185
186 /* set the strobe off */
187 buf[1] = lnb;
188 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
189 buf[1] |= FRIIO_CTL_CLK;
190 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
191
192 return (ret == 70);
193}
194
195
196static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
197
198/* TODO: move these init cmds to the FE's init routine? */
199static u8 streaming_init_cmds[][2] = {
200 {0x33, 0x08},
201 {0x37, 0x40},
202 {0x3A, 0x1F},
203 {0x3B, 0xFF},
204 {0x3C, 0x1F},
205 {0x3D, 0xFF},
206 {0x38, 0x00},
207 {0x35, 0x00},
208 {0x39, 0x00},
209 {0x36, 0x00},
210};
211static int cmdlen = sizeof(streaming_init_cmds) / 2;
212
213/*
214 * Command sequence in this init function is a replay
215 * of the captured USB commands from the Windows proprietary driver.
216 */
217static int friio_initialize(struct dvb_usb_device *d)
218{
219 int ret;
220 int i;
221 int retry = 0;
222 u8 rbuf[2];
223 u8 wbuf[3];
224
225 deb_info("%s called.\n", __func__);
226
227 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
228 /* because the i2c device is not set up yet. */
229 wbuf[0] = 0x11;
230 wbuf[1] = 0x02;
231 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
232 if (ret < 0)
233 goto error;
234 msleep(2);
235
236 wbuf[0] = 0x11;
237 wbuf[1] = 0x00;
238 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
239 if (ret < 0)
240 goto error;
241 msleep(1);
242
243 /* following msgs should be in the FE's init code? */
244 /* cmd sequence to identify the device type? (friio black/white) */
245 wbuf[0] = 0x03;
246 wbuf[1] = 0x80;
247 /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
248 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
249 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
250 0x1200, 0x0100, wbuf, 2, 2000);
251 if (ret < 0)
252 goto error;
253
254 msleep(2);
255 wbuf[0] = 0x00;
256 wbuf[2] = 0x01; /* reg.0x0100 */
257 wbuf[1] = 0x00;
258 ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
259 /* my Friio White returns 0xffff. */
260 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
261 goto error;
262
263 msleep(2);
264 wbuf[0] = 0x03;
265 wbuf[1] = 0x80;
266 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
267 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
268 0x9000, 0x0100, wbuf, 2, 2000);
269 if (ret < 0)
270 goto error;
271
272 msleep(2);
273 wbuf[0] = 0x00;
274 wbuf[2] = 0x01; /* reg.0x0100 */
275 wbuf[1] = 0x00;
276 ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
277 /* my Friio White returns 0xffff again. */
278 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
279 goto error;
280
281 msleep(1);
282
283restart:
284 /* ============ start DEMOD init cmds ================== */
285 /* read PLL status to clear the POR bit */
286 wbuf[0] = JDVBT90502_2ND_I2C_REG;
287 wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1; /* +1 for reading */
288 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
289 if (ret < 0)
290 goto error;
291
292 msleep(5);
293 /* note: DEMODULATOR has 16bit register-address. */
294 wbuf[0] = 0x00;
295 wbuf[2] = 0x01; /* reg addr: 0x0100 */
296 wbuf[1] = 0x00; /* val: not used */
297 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
298 if (ret < 0)
299 goto error;
300/*
301 msleep(1);
302 wbuf[0] = 0x80;
303 wbuf[1] = 0x00;
304 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
305 if (ret < 0)
306 goto error;
307 */
308 if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */
309 if (++retry > 3) {
310 deb_info("failed to get the correct"
311 " FE demod status:0x%02x\n", rbuf[0]);
312 goto error;
313 }
314 msleep(100);
315 goto restart;
316 }
317
318 /* TODO: check return value in rbuf */
319 /* =========== end DEMOD init cmds ===================== */
320 msleep(1);
321
322 wbuf[0] = 0x30;
323 wbuf[1] = 0x04;
324 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
325 if (ret < 0)
326 goto error;
327
328 msleep(2);
329 /* following 2 cmds unnecessary? */
330 wbuf[0] = 0x00;
331 wbuf[1] = 0x01;
332 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
333 if (ret < 0)
334 goto error;
335
336 wbuf[0] = 0x06;
337 wbuf[1] = 0x0F;
338 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
339 if (ret < 0)
340 goto error;
341
342 /* some streaming ctl cmds (maybe) */
343 msleep(10);
344 for (i = 0; i < cmdlen; i++) {
345 ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
346 NULL, 0);
347 if (ret < 0)
348 goto error;
349 msleep(1);
350 }
351 msleep(20);
352
353 /* change the LED color etc. */
354 ret = friio_streaming_ctrl(&d->adapter[0], 0);
355 if (ret < 0)
356 goto error;
357
358 return 0;
359
360error:
361 deb_info("%s:ret == %d\n", __func__, ret);
362 return -EIO;
363}
364
365/* Callbacks for DVB USB */
366
367static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
368{
369 int ret;
370
371 deb_info("%s called.(%d)\n", __func__, onoff);
372
373 /* set the LED color and saturation (and LNB on) */
374 if (onoff)
375 ret = friio_ext_ctl(adap, 0x6400ff64, 1);
376 else
377 ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
378
379 if (ret != 1) {
380 deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
381 return -EREMOTEIO;
382 }
383 return 0;
384}
385
386static int friio_frontend_attach(struct dvb_usb_adapter *adap)
387{
388 if (friio_initialize(adap->dev) < 0)
389 return -EIO;
390
391 adap->fe = jdvbt90502_attach(adap->dev);
392 if (adap->fe == NULL)
393 return -EIO;
394
395 return 0;
396}
397
398/* DVB USB Driver stuff */
399static struct dvb_usb_device_properties friio_properties;
400
401static int friio_probe(struct usb_interface *intf,
402 const struct usb_device_id *id)
403{
404 struct dvb_usb_device *d;
405 struct usb_host_interface *alt;
406 int ret;
407
408 if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
409 return -ENODEV;
410
411 alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
412 if (alt == NULL) {
413 deb_rc("not alt found!\n");
414 return -ENODEV;
415 }
416 ret = usb_set_interface(interface_to_usbdev(intf),
417 alt->desc.bInterfaceNumber,
418 alt->desc.bAlternateSetting);
419 if (ret != 0) {
420 deb_rc("failed to set alt-setting!\n");
421 return ret;
422 }
423
424 ret = dvb_usb_device_init(intf, &friio_properties,
425 THIS_MODULE, &d, adapter_nr);
426 if (ret == 0)
427 friio_streaming_ctrl(&d->adapter[0], 1);
428
429 return ret;
430}
431
432
433struct jdvbt90502_config friio_fe_config = {
434 .demod_address = FRIIO_DEMOD_ADDR,
435 .pll_address = FRIIO_PLL_ADDR,
436};
437
438static struct i2c_algorithm gl861_i2c_algo = {
439 .master_xfer = gl861_i2c_xfer,
440 .functionality = gl861_i2c_func,
441};
442
443static struct usb_device_id friio_table[] = {
444 { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
445 { } /* Terminating entry */
446};
447MODULE_DEVICE_TABLE(usb, friio_table);
448
449
450static struct dvb_usb_device_properties friio_properties = {
451 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
452 .usb_ctrl = DEVICE_SPECIFIC,
453
454 .size_of_priv = 0,
455
456 .num_adapters = 1,
457 .adapter = {
458 /* caps:0 => no pid filter, 188B TS packet */
459 /* GL861 has a HW pid filter, but no info available. */
460 {
461 .caps = 0,
462
463 .frontend_attach = friio_frontend_attach,
464 .streaming_ctrl = friio_streaming_ctrl,
465
466 .stream = {
467 .type = USB_BULK,
468 /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
469 .count = 8,
470 .endpoint = 0x01,
471 .u = {
472 /* GL861 has 6KB buf inside */
473 .bulk = {
474 .buffersize = 16384,
475 }
476 }
477 },
478 }
479 },
480 .i2c_algo = &gl861_i2c_algo,
481
482 .num_device_descs = 1,
483 .devices = {
484 {
485 .name = "774 Friio ISDB-T USB2.0",
486 .cold_ids = { NULL },
487 .warm_ids = { &friio_table[0], NULL },
488 },
489 }
490};
491
492static struct usb_driver friio_driver = {
493 .name = "dvb_usb_friio",
494 .probe = friio_probe,
495 .disconnect = dvb_usb_device_exit,
496 .id_table = friio_table,
497};
498
499
500/* module stuff */
501static int __init friio_module_init(void)
502{
503 int ret;
504
505 ret = usb_register(&friio_driver);
506 if (ret)
507 err("usb_register failed. Error number %d", ret);
508
509 return ret;
510}
511
512
513static void __exit friio_module_exit(void)
514{
515 /* deregister this driver from the USB subsystem */
516 usb_deregister(&friio_driver);
517}
518
519module_init(friio_module_init);
520module_exit(friio_module_exit);
521
522MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
523MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
524MODULE_VERSION("0.2");
525MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h
new file mode 100644
index 000000000000..af8d55e390fb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.h
@@ -0,0 +1,99 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#ifndef _DVB_USB_FRIIO_H_
14#define _DVB_USB_FRIIO_H_
15
16/**
17 * Friio Components
18 * USB hub: AU4254
19 * USB controller(+ TS dmx & streaming): GL861
20 * Frontend: comtech JDVBT-90502
21 * (tuner PLL: tua6034, I2C addr:(0xC0 >> 1))
22 * (OFDM demodulator: TC90502, I2C addr:(0x30 >> 1))
23 * LED x3 (+LNB) controll: PIC 16F676
24 * EEPROM: 24C08
25 *
26 * (USB smart card reader: AU9522)
27 *
28 */
29
30#define DVB_USB_LOG_PREFIX "friio"
31#include "dvb-usb.h"
32
33extern int dvb_usb_friio_debug;
34#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
35#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
36#define deb_rc(args...) dprintk(dvb_usb_friio_debug, 0x04, args)
37#define deb_fe(args...) dprintk(dvb_usb_friio_debug, 0x08, args)
38
39/* Vendor requests */
40#define GL861_WRITE 0x40
41#define GL861_READ 0xc0
42
43/* command bytes */
44#define GL861_REQ_I2C_WRITE 0x01
45#define GL861_REQ_I2C_READ 0x02
46/* For control msg with data argument */
47/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
48#define GL861_REQ_I2C_DATA_CTRL_WRITE 0x03
49
50#define GL861_ALTSETTING_COUNT 2
51#define FRIIO_BULK_ALTSETTING 0
52#define FRIIO_ISOC_ALTSETTING 1
53
54/* LED & LNB control via PIC. */
55/* basically, it's serial control with clock and strobe. */
56/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
57/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
58#define FRIIO_CTL_LNB (1 << 0)
59#define FRIIO_CTL_STROBE (1 << 1)
60#define FRIIO_CTL_CLK (1 << 2)
61#define FRIIO_CTL_LED (1 << 3)
62
63/* Front End related */
64
65#define FRIIO_DEMOD_ADDR (0x30 >> 1)
66#define FRIIO_PLL_ADDR (0xC0 >> 1)
67
68#define JDVBT90502_PLL_CLK 4000000
69#define JDVBT90502_PLL_DIVIDER 28
70
71#define JDVBT90502_2ND_I2C_REG 0xFE
72
73/* byte index for pll i2c command data structure*/
74/* see datasheet for tua6034 */
75#define DEMOD_REDIRECT_REG 0
76#define ADDRESS_BYTE 1
77#define DIVIDER_BYTE1 2
78#define DIVIDER_BYTE2 3
79#define CONTROL_BYTE 4
80#define BANDSWITCH_BYTE 5
81#define AGC_CTRL_BYTE 5
82#define PLL_CMD_LEN 6
83
84/* bit masks for PLL STATUS response */
85#define PLL_STATUS_POR_MODE 0x80 /* 1: Power on Reset (test) Mode */
86#define PLL_STATUS_LOCKED 0x40 /* 1: locked */
87#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
88#define PLL_STATUS_TESTMODE 0x07 /* digital output level (5 level) */
89 /* 0.15Vcc step 0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
90
91
92struct jdvbt90502_config {
93 u8 demod_address; /* i2c addr for demodulator IC */
94 u8 pll_address; /* PLL addr on the secondary i2c*/
95};
96extern struct jdvbt90502_config friio_fe_config;
97
98extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
99#endif
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index aec7a1943b66..ef9b7bed13ff 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -337,6 +337,8 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
337 int i, pass, ret = 0; 337 int i, pass, ret = 0;
338 338
339 buff = kmalloc(65536, GFP_KERNEL); 339 buff = kmalloc(65536, GFP_KERNEL);
340 if (buff == NULL)
341 return -ENOMEM;
340 342
341 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) 343 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
342 goto done; 344 goto done;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b794e860b4e2..d7c4837fa71c 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -484,6 +484,14 @@ config DVB_S921
484 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module. 484 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
485 Say Y when you want to support this frontend. 485 Say Y when you want to support this frontend.
486 486
487config DVB_DIB8000
488 tristate "DiBcom 8000MB/MC"
489 depends on DVB_CORE && I2C
490 default m if DVB_FE_CUSTOMISE
491 help
492 A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
493 Say Y when you want to support this frontend.
494
487comment "Digital terrestrial only tuners/PLL" 495comment "Digital terrestrial only tuners/PLL"
488 depends on DVB_CORE 496 depends on DVB_CORE
489 497
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3b49d37ab5fa..3523767e7a76 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
23obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o 23obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o 24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o 25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
26obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
26obj-$(CONFIG_DVB_MT312) += mt312.o 27obj-$(CONFIG_DVB_MT312) += mt312.o
27obj-$(CONFIG_DVB_VES1820) += ves1820.o 28obj-$(CONFIG_DVB_VES1820) += ves1820.o
28obj-$(CONFIG_DVB_VES1X93) += ves1x93.o 29obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 9e9a75576a1d..74981ee923c8 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -792,6 +792,11 @@ static int au8522_probe(struct i2c_client *client,
792 } 792 }
793 793
794 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); 794 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
795 if (demod_config == NULL) {
796 if (instance == 1)
797 kfree(state);
798 return -ENOMEM;
799 }
795 demod_config->demod_address = 0x8e >> 1; 800 demod_config->demod_address = 0x8e >> 1;
796 801
797 state->config = demod_config; 802 state->config = demod_config;
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index da92cbe1b8ea..2be17b93e0bd 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -1,12 +1,29 @@
1/* 1/*
2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. 2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
3 * 3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) 4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2. 8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * This code is more or less generated from another driver, please
23 * excuse some codingstyle oddities.
24 *
9 */ 25 */
26
10#include <linux/kernel.h> 27#include <linux/kernel.h>
11#include <linux/i2c.h> 28#include <linux/i2c.h>
12 29
@@ -19,27 +36,65 @@ static int debug;
19module_param(debug, int, 0644); 36module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 37MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
21 38
22#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0) 39#define dprintk(args...) do { \
40 if (debug) { \
41 printk(KERN_DEBUG "DiB0070: "); \
42 printk(args); \
43 printk("\n"); \
44 } \
45} while (0)
23 46
24#define DIB0070_P1D 0x00 47#define DIB0070_P1D 0x00
25#define DIB0070_P1F 0x01 48#define DIB0070_P1F 0x01
26#define DIB0070_P1G 0x03 49#define DIB0070_P1G 0x03
27#define DIB0070S_P1A 0x02 50#define DIB0070S_P1A 0x02
28 51
52enum frontend_tune_state {
53 CT_TUNER_START = 10,
54 CT_TUNER_STEP_0,
55 CT_TUNER_STEP_1,
56 CT_TUNER_STEP_2,
57 CT_TUNER_STEP_3,
58 CT_TUNER_STEP_4,
59 CT_TUNER_STEP_5,
60 CT_TUNER_STEP_6,
61 CT_TUNER_STEP_7,
62 CT_TUNER_STOP,
63};
64
65#define FE_CALLBACK_TIME_NEVER 0xffffffff
66
29struct dib0070_state { 67struct dib0070_state {
30 struct i2c_adapter *i2c; 68 struct i2c_adapter *i2c;
31 struct dvb_frontend *fe; 69 struct dvb_frontend *fe;
32 const struct dib0070_config *cfg; 70 const struct dib0070_config *cfg;
33 u16 wbd_ff_offset; 71 u16 wbd_ff_offset;
34 u8 revision; 72 u8 revision;
73
74 enum frontend_tune_state tune_state;
75 u32 current_rf;
76
77 /* for the captrim binary search */
78 s8 step;
79 u16 adc_diff;
80
81 s8 captrim;
82 s8 fcaptrim;
83 u16 lo4;
84
85 const struct dib0070_tuning *current_tune_table_index;
86 const struct dib0070_lna_match *lna_match;
87
88 u8 wbd_gain_current;
89 u16 wbd_offset_3_3[2];
35}; 90};
36 91
37static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) 92static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
38{ 93{
39 u8 b[2]; 94 u8 b[2];
40 struct i2c_msg msg[2] = { 95 struct i2c_msg msg[2] = {
41 { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 }, 96 {.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
42 { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, 97 {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
43 }; 98 };
44 if (i2c_transfer(state->i2c, msg, 2) != 2) { 99 if (i2c_transfer(state->i2c, msg, 2) != 2) {
45 printk(KERN_WARNING "DiB0070 I2C read failed\n"); 100 printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -51,7 +106,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
51static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) 106static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
52{ 107{
53 u8 b[3] = { reg, val >> 8, val & 0xff }; 108 u8 b[3] = { reg, val >> 8, val & 0xff };
54 struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; 109 struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
55 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 110 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
56 printk(KERN_WARNING "DiB0070 I2C write failed\n"); 111 printk(KERN_WARNING "DiB0070 I2C write failed\n");
57 return -EREMOTEIO; 112 return -EREMOTEIO;
@@ -59,55 +114,71 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
59 return 0; 114 return 0;
60} 115}
61 116
62#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0) 117#define HARD_RESET(state) do { \
118 state->cfg->sleep(state->fe, 0); \
119 if (state->cfg->reset) { \
120 state->cfg->reset(state->fe,1); msleep(10); \
121 state->cfg->reset(state->fe,0); msleep(10); \
122 } \
123} while (0)
63 124
64static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) 125static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
65{ 126{
66 struct dib0070_state *st = fe->tuner_priv; 127 struct dib0070_state *state = fe->tuner_priv;
67 u16 tmp = 0; 128 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
68 tmp = dib0070_read_reg(st, 0x02) & 0x3fff; 129
130 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
131 tmp |= (0 << 14);
132 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
133 tmp |= (1 << 14);
134 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
135 tmp |= (2 << 14);
136 else
137 tmp |= (3 << 14);
69 138
70 switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) { 139 dib0070_write_reg(state, 0x02, tmp);
71 case 8000: 140
72 tmp |= (0 << 14); 141 /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
73 break; 142 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
74 case 7000: 143 u16 value = dib0070_read_reg(state, 0x17);
75 tmp |= (1 << 14); 144
76 break; 145 dib0070_write_reg(state, 0x17, value & 0xfffc);
77 case 6000: 146 tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
78 tmp |= (2 << 14); 147 dib0070_write_reg(state, 0x01, tmp | (60 << 9));
79 break; 148
80 case 5000: 149 dib0070_write_reg(state, 0x17, value);
81 default:
82 tmp |= (3 << 14);
83 break;
84 } 150 }
85 dib0070_write_reg(st, 0x02, tmp);
86 return 0; 151 return 0;
87} 152}
88 153
89static void dib0070_captrim(struct dib0070_state *st, u16 LO4) 154static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
90{ 155{
91 int8_t captrim, fcaptrim, step_sign, step; 156 int8_t step_sign;
92 u16 adc, adc_diff = 3000; 157 u16 adc;
158 int ret = 0;
93 159
160 if (*tune_state == CT_TUNER_STEP_0) {
94 161
162 dib0070_write_reg(state, 0x0f, 0xed10);
163 dib0070_write_reg(state, 0x17, 0x0034);
95 164
96 dib0070_write_reg(st, 0x0f, 0xed10); 165 dib0070_write_reg(state, 0x18, 0x0032);
97 dib0070_write_reg(st, 0x17, 0x0034); 166 state->step = state->captrim = state->fcaptrim = 64;
167 state->adc_diff = 3000;
168 ret = 20;
98 169
99 dib0070_write_reg(st, 0x18, 0x0032); 170 *tune_state = CT_TUNER_STEP_1;
100 msleep(2); 171 } else if (*tune_state == CT_TUNER_STEP_1) {
172 state->step /= 2;
173 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
174 ret = 15;
101 175
102 step = captrim = fcaptrim = 64; 176 *tune_state = CT_TUNER_STEP_2;
177 } else if (*tune_state == CT_TUNER_STEP_2) {
103 178
104 do { 179 adc = dib0070_read_reg(state, 0x19);
105 step /= 2;
106 dib0070_write_reg(st, 0x14, LO4 | captrim);
107 msleep(1);
108 adc = dib0070_read_reg(st, 0x19);
109 180
110 dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024); 181 dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
111 182
112 if (adc >= 400) { 183 if (adc >= 400) {
113 adc -= 400; 184 adc -= 400;
@@ -117,379 +188,430 @@ static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
117 step_sign = 1; 188 step_sign = 1;
118 } 189 }
119 190
120 if (adc < adc_diff) { 191 if (adc < state->adc_diff) {
121 dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff); 192 dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
122 adc_diff = adc; 193 state->adc_diff = adc;
123 fcaptrim = captrim; 194 state->fcaptrim = state->captrim;
124 195
196 }
197 state->captrim += (step_sign * state->step);
125 198
199 if (state->step >= 1)
200 *tune_state = CT_TUNER_STEP_1;
201 else
202 *tune_state = CT_TUNER_STEP_3;
126 203
127 } 204 } else if (*tune_state == CT_TUNER_STEP_3) {
128 captrim += (step_sign * step); 205 dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
129 } while (step >= 1); 206 dib0070_write_reg(state, 0x18, 0x07ff);
207 *tune_state = CT_TUNER_STEP_4;
208 }
130 209
131 dib0070_write_reg(st, 0x14, LO4 | fcaptrim); 210 return ret;
132 dib0070_write_reg(st, 0x18, 0x07ff);
133} 211}
134 212
135#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 213static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
136#define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7)
137#define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12)
138#define LO4_SET_CTRIM(l, c) l |= (c) << 10
139static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
140{ 214{
141 struct dib0070_state *st = fe->tuner_priv; 215 struct dib0070_state *state = fe->tuner_priv;
142 u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf); 216 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
143 217 dprintk("CTRL_LO5: 0x%x", lo5);
144 u8 band = BAND_OF_FREQUENCY(freq), c; 218 return dib0070_write_reg(state, 0x15, lo5);
219}
145 220
146 /*******************VCO***********************************/ 221void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
147 u16 lo4 = 0; 222{
223 struct dib0070_state *state = fe->tuner_priv;
148 224
149 u8 REFDIV, PRESC = 2; 225 if (open) {
150 u32 FBDiv, Rest, FREF, VCOF_kHz; 226 dib0070_write_reg(state, 0x1b, 0xff00);
151 u16 Num, Den; 227 dib0070_write_reg(state, 0x1a, 0x0000);
152 /*******************FrontEnd******************************/ 228 } else {
153 u16 value = 0; 229 dib0070_write_reg(state, 0x1b, 0x4112);
230 if (state->cfg->vga_filter != 0) {
231 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
232 dprintk("vga filter register is set to %x", state->cfg->vga_filter);
233 } else
234 dib0070_write_reg(state, 0x1a, 0x0009);
235 }
236}
154 237
155 dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); 238EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
239struct dib0070_tuning {
240 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
241 u8 switch_trim;
242 u8 vco_band;
243 u8 hfdiv;
244 u8 vco_multi;
245 u8 presc;
246 u8 wbdmux;
247 u16 tuner_enable;
248};
156 249
250struct dib0070_lna_match {
251 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
252 u8 lna_band;
253};
157 254
158 dib0070_write_reg(st, 0x17, 0x30); 255static const struct dib0070_tuning dib0070s_tuning_table[] = {
256 {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */
257 {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
258 {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
259 {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */
260 {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
261 {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
262 {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */
263};
159 264
160 dib0070_set_bandwidth(fe, ch); /* c is used as HF */ 265static const struct dib0070_tuning dib0070_tuning_table[] = {
161 switch (st->revision) { 266 {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */
162 case DIB0070S_P1A: 267 {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */
163 switch (band) { 268 {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
164 case BAND_LBAND: 269 {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
165 LO4_SET_VCO_HFDIV(lo4, 1, 1); 270 {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */
166 c = 2; 271 {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
167 break; 272 {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
168 case BAND_SBAND: 273 {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */
169 LO4_SET_VCO_HFDIV(lo4, 0, 0); 274};
170 LO4_SET_CTRIM(lo4, 1);
171 c = 1;
172 break;
173 case BAND_UHF:
174 default:
175 if (freq < 570000) {
176 LO4_SET_VCO_HFDIV(lo4, 1, 3);
177 PRESC = 6; c = 6;
178 } else if (freq < 680000) {
179 LO4_SET_VCO_HFDIV(lo4, 0, 2);
180 c = 4;
181 } else {
182 LO4_SET_VCO_HFDIV(lo4, 1, 2);
183 c = 4;
184 }
185 break;
186 } break;
187
188 case DIB0070_P1G:
189 case DIB0070_P1F:
190 default:
191 switch (band) {
192 case BAND_FM:
193 LO4_SET_VCO_HFDIV(lo4, 0, 7);
194 c = 24;
195 break;
196 case BAND_LBAND:
197 LO4_SET_VCO_HFDIV(lo4, 1, 0);
198 c = 2;
199 break;
200 case BAND_VHF:
201 if (freq < 180000) {
202 LO4_SET_VCO_HFDIV(lo4, 0, 3);
203 c = 16;
204 } else if (freq < 190000) {
205 LO4_SET_VCO_HFDIV(lo4, 1, 3);
206 c = 16;
207 } else {
208 LO4_SET_VCO_HFDIV(lo4, 0, 6);
209 c = 12;
210 }
211 break;
212
213 case BAND_UHF:
214 default:
215 if (freq < 570000) {
216 LO4_SET_VCO_HFDIV(lo4, 1, 5);
217 c = 6;
218 } else if (freq < 700000) {
219 LO4_SET_VCO_HFDIV(lo4, 0, 1);
220 c = 4;
221 } else {
222 LO4_SET_VCO_HFDIV(lo4, 1, 1);
223 c = 4;
224 }
225 break;
226 }
227 break;
228 }
229 275
230 dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf); 276static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
231 dprintk( "VCO = %hd", (lo4 >> 11) & 0x3); 277 {180000, 0}, /* VHF */
278 {188000, 1},
279 {196400, 2},
280 {250000, 3},
281 {550000, 0}, /* UHF */
282 {590000, 1},
283 {666000, 3},
284 {864000, 5},
285 {1500000, 0}, /* LBAND or everything higher than UHF */
286 {1600000, 1},
287 {2000000, 3},
288 {0xffffffff, 7},
289};
232 290
291static const struct dib0070_lna_match dib0070_lna[] = {
292 {180000, 0}, /* VHF */
293 {188000, 1},
294 {196400, 2},
295 {250000, 3},
296 {550000, 2}, /* UHF */
297 {650000, 3},
298 {750000, 5},
299 {850000, 6},
300 {864000, 7},
301 {1500000, 0}, /* LBAND or everything higher than UHF */
302 {1600000, 1},
303 {2000000, 3},
304 {0xffffffff, 7},
305};
233 306
234 VCOF_kHz = (c * freq) * 2; 307#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
235 dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq); 308static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
309{
310 struct dib0070_state *state = fe->tuner_priv;
236 311
237 switch (band) { 312 const struct dib0070_tuning *tune;
238 case BAND_VHF: 313 const struct dib0070_lna_match *lna_match;
239 REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000);
240 break;
241 case BAND_FM:
242 REFDIV = (u8) ((st->cfg->clock_khz) / 1000);
243 break;
244 default:
245 REFDIV = (u8) ( st->cfg->clock_khz / 10000);
246 break;
247 }
248 FREF = st->cfg->clock_khz / REFDIV;
249 314
250 dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); 315 enum frontend_tune_state *tune_state = &state->tune_state;
316 int ret = 10; /* 1ms is the default delay most of the time */
251 317
318 u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
319 u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
252 320
321#ifdef CONFIG_SYS_ISDBT
322 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
323 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
324 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
325 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
326 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
327 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
328 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
329 freq += 850;
330#endif
331 if (state->current_rf != freq) {
253 332
254 switch (st->revision) { 333 switch (state->revision) {
255 case DIB0070S_P1A: 334 case DIB0070S_P1A:
256 FBDiv = (VCOF_kHz / PRESC / FREF); 335 tune = dib0070s_tuning_table;
257 Rest = (VCOF_kHz / PRESC) - FBDiv * FREF; 336 lna_match = dib0070_lna;
258 break; 337 break;
259
260 case DIB0070_P1G:
261 case DIB0070_P1F:
262 default: 338 default:
263 FBDiv = (freq / (FREF / 2)); 339 tune = dib0070_tuning_table;
264 Rest = 2 * freq - FBDiv * FREF; 340 if (state->cfg->flip_chip)
341 lna_match = dib0070_lna_flip_chip;
342 else
343 lna_match = dib0070_lna;
265 break; 344 break;
266 } 345 }
267 346 while (freq > tune->max_freq) /* find the right one */
268 347 tune++;
269 if (Rest < LPF) Rest = 0; 348 while (freq > lna_match->max_freq) /* find the right one */
270 else if (Rest < 2 * LPF) Rest = 2 * LPF; 349 lna_match++;
271 else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; }
272 else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF;
273 Rest = (Rest * 6528) / (FREF / 10);
274 dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
275
276 Num = 0;
277 Den = 1;
278 350
279 if (Rest > 0) { 351 state->current_tune_table_index = tune;
280 LO4_SET_SD(lo4, 1); 352 state->lna_match = lna_match;
281 Den = 255;
282 Num = (u16)Rest;
283 } 353 }
284 dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1);
285 354
355 if (*tune_state == CT_TUNER_START) {
356 dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
357 if (state->current_rf != freq) {
358 u8 REFDIV;
359 u32 FBDiv, Rest, FREF, VCOF_kHz;
360 u8 Den;
286 361
362 state->current_rf = freq;
363 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
287 364
288 dib0070_write_reg(st, 0x11, (u16)FBDiv); 365 dib0070_write_reg(state, 0x17, 0x30);
289 366
367 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
290 368
291 dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV); 369 switch (band) {
292 370 case BAND_VHF:
371 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
372 break;
373 case BAND_FM:
374 REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
375 break;
376 default:
377 REFDIV = (u8) (state->cfg->clock_khz / 10000);
378 break;
379 }
380 FREF = state->cfg->clock_khz / REFDIV;
381
382 switch (state->revision) {
383 case DIB0070S_P1A:
384 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
385 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
386 break;
387
388 case DIB0070_P1G:
389 case DIB0070_P1F:
390 default:
391 FBDiv = (freq / (FREF / 2));
392 Rest = 2 * freq - FBDiv * FREF;
393 break;
394 }
293 395
294 dib0070_write_reg(st, 0x13, Num); 396 if (Rest < LPF)
397 Rest = 0;
398 else if (Rest < 2 * LPF)
399 Rest = 2 * LPF;
400 else if (Rest > (FREF - LPF)) {
401 Rest = 0;
402 FBDiv += 1;
403 } else if (Rest > (FREF - 2 * LPF))
404 Rest = FREF - 2 * LPF;
405 Rest = (Rest * 6528) / (FREF / 10);
406
407 Den = 1;
408 if (Rest > 0) {
409 state->lo4 |= (1 << 14) | (1 << 12);
410 Den = 255;
411 }
295 412
413 dib0070_write_reg(state, 0x11, (u16) FBDiv);
414 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
415 dib0070_write_reg(state, 0x13, (u16) Rest);
296 416
297 value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001; 417 if (state->revision == DIB0070S_P1A) {
298 418
299 switch (band) { 419 if (band == BAND_SBAND) {
300 case BAND_UHF: value |= 0x4000 | 0x0800; break; 420 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
301 case BAND_LBAND: value |= 0x2000 | 0x0400; break; 421 dib0070_write_reg(state, 0x1d, 0xFFFF);
302 default: value |= 0x8000 | 0x1000; break; 422 } else
303 } 423 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
304 dib0070_write_reg(st, 0x20, value); 424 }
305 425
306 dib0070_captrim(st, lo4); 426 dib0070_write_reg(state, 0x20,
307 if (st->revision == DIB0070S_P1A) { 427 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
308 if (band == BAND_SBAND)
309 dib0070_write_reg(st, 0x15, 0x16e2);
310 else
311 dib0070_write_reg(st, 0x15, 0x56e5);
312 }
313 428
429 dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
430 dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
431 dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
432 dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
433 dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
434 dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
314 435
436 *tune_state = CT_TUNER_STEP_0;
437 } else { /* we are already tuned to this frequency - the configuration is correct */
438 ret = 50; /* wakeup time */
439 *tune_state = CT_TUNER_STEP_5;
440 }
441 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
442
443 ret = dib0070_captrim(state, tune_state);
444
445 } else if (*tune_state == CT_TUNER_STEP_4) {
446 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
447 if (tmp != NULL) {
448 while (freq / 1000 > tmp->freq) /* find the right one */
449 tmp++;
450 dib0070_write_reg(state, 0x0f,
451 (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
452 current_tune_table_index->
453 wbdmux << 0));
454 state->wbd_gain_current = tmp->wbd_gain_val;
455 } else {
456 dib0070_write_reg(state, 0x0f,
457 (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
458 wbdmux << 0));
459 state->wbd_gain_current = 6;
460 }
315 461
316 switch (band) { 462 dib0070_write_reg(state, 0x06, 0x3fff);
317 case BAND_UHF: value = 0x7c82; break; 463 dib0070_write_reg(state, 0x07,
318 case BAND_LBAND: value = 0x7c84; break; 464 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
319 default: value = 0x7c81; break; 465 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
320 } 466 dib0070_write_reg(state, 0x0d, 0x0d80);
321 dib0070_write_reg(st, 0x0f, value); 467
322 dib0070_write_reg(st, 0x06, 0x3fff); 468 dib0070_write_reg(state, 0x18, 0x07ff);
323 469 dib0070_write_reg(state, 0x17, 0x0033);
324 /* Front End */ 470
325 /* c == TUNE, value = SWITCH */ 471 *tune_state = CT_TUNER_STEP_5;
326 c = 0; 472 } else if (*tune_state == CT_TUNER_STEP_5) {
327 value = 0; 473 dib0070_set_bandwidth(fe, ch);
328 switch (band) { 474 *tune_state = CT_TUNER_STOP;
329 case BAND_FM: 475 } else {
330 c = 0; value = 1; 476 ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
331 break;
332
333 case BAND_VHF:
334 if (freq <= 180000) c = 0;
335 else if (freq <= 188200) c = 1;
336 else if (freq <= 196400) c = 2;
337 else c = 3;
338 value = 1;
339 break;
340
341 case BAND_LBAND:
342 if (freq <= 1500000) c = 0;
343 else if (freq <= 1600000) c = 1;
344 else c = 3;
345 break;
346
347 case BAND_SBAND:
348 c = 7;
349 dib0070_write_reg(st, 0x1d,0xFFFF);
350 break;
351
352 case BAND_UHF:
353 default:
354 if (st->cfg->flip_chip) {
355 if (freq <= 550000) c = 0;
356 else if (freq <= 590000) c = 1;
357 else if (freq <= 666000) c = 3;
358 else c = 5;
359 } else {
360 if (freq <= 550000) c = 2;
361 else if (freq <= 650000) c = 3;
362 else if (freq <= 750000) c = 5;
363 else if (freq <= 850000) c = 6;
364 else c = 7;
365 }
366 value = 2;
367 break;
368 } 477 }
478 return ret;
479}
369 480
370 /* default: LNA_MATCH=7, BIAS=3 */ 481static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
371 dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0)); 482{
372 dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127)); 483 struct dib0070_state *state = fe->tuner_priv;
373 dib0070_write_reg(st, 0x0d, 0x0d80); 484 uint32_t ret;
374 485
486 state->tune_state = CT_TUNER_START;
375 487
376 dib0070_write_reg(st, 0x18, 0x07ff); 488 do {
377 dib0070_write_reg(st, 0x17, 0x0033); 489 ret = dib0070_tune_digital(fe, p);
490 if (ret != FE_CALLBACK_TIME_NEVER)
491 msleep(ret / 10);
492 else
493 break;
494 } while (state->tune_state != CT_TUNER_STOP);
378 495
379 return 0; 496 return 0;
380} 497}
381 498
382static int dib0070_wakeup(struct dvb_frontend *fe) 499static int dib0070_wakeup(struct dvb_frontend *fe)
383{ 500{
384 struct dib0070_state *st = fe->tuner_priv; 501 struct dib0070_state *state = fe->tuner_priv;
385 if (st->cfg->sleep) 502 if (state->cfg->sleep)
386 st->cfg->sleep(fe, 0); 503 state->cfg->sleep(fe, 0);
387 return 0; 504 return 0;
388} 505}
389 506
390static int dib0070_sleep(struct dvb_frontend *fe) 507static int dib0070_sleep(struct dvb_frontend *fe)
391{ 508{
392 struct dib0070_state *st = fe->tuner_priv; 509 struct dib0070_state *state = fe->tuner_priv;
393 if (st->cfg->sleep) 510 if (state->cfg->sleep)
394 st->cfg->sleep(fe, 1); 511 state->cfg->sleep(fe, 1);
395 return 0; 512 return 0;
396} 513}
397 514
398static u16 dib0070_p1f_defaults[] = 515static const u16 dib0070_p1f_defaults[] = {
399
400{
401 7, 0x02, 516 7, 0x02,
402 0x0008, 517 0x0008,
403 0x0000, 518 0x0000,
404 0x0000, 519 0x0000,
405 0x0000, 520 0x0000,
406 0x0000, 521 0x0000,
407 0x0002, 522 0x0002,
408 0x0100, 523 0x0100,
409 524
410 3, 0x0d, 525 3, 0x0d,
411 0x0d80, 526 0x0d80,
412 0x0001, 527 0x0001,
413 0x0000, 528 0x0000,
414 529
415 4, 0x11, 530 4, 0x11,
416 0x0000, 531 0x0000,
417 0x0103, 532 0x0103,
418 0x0000, 533 0x0000,
419 0x0000, 534 0x0000,
420 535
421 3, 0x16, 536 3, 0x16,
422 0x0004 | 0x0040, 537 0x0004 | 0x0040,
423 0x0030, 538 0x0030,
424 0x07ff, 539 0x07ff,
425 540
426 6, 0x1b, 541 6, 0x1b,
427 0x4112, 542 0x4112,
428 0xff00, 543 0xff00,
429 0xc07f, 544 0xc07f,
430 0x0000, 545 0x0000,
431 0x0180, 546 0x0180,
432 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, 547 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
433 548
434 0, 549 0,
435}; 550};
436 551
437static void dib0070_wbd_calibration(struct dvb_frontend *fe) 552static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
438{ 553{
439 u16 wbd_offs; 554 u16 tuner_en = dib0070_read_reg(state, 0x20);
440 struct dib0070_state *state = fe->tuner_priv; 555 u16 offset;
441
442 if (state->cfg->sleep)
443 state->cfg->sleep(fe, 0);
444 556
445 dib0070_write_reg(state, 0x0f, 0x6d81); 557 dib0070_write_reg(state, 0x18, 0x07ff);
446 dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); 558 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
559 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
447 msleep(9); 560 msleep(9);
448 wbd_offs = dib0070_read_reg(state, 0x19); 561 offset = dib0070_read_reg(state, 0x19);
449 dib0070_write_reg(state, 0x20, 0); 562 dib0070_write_reg(state, 0x20, tuner_en);
450 state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); 563 return offset;
451 dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
452
453 if (state->cfg->sleep)
454 state->cfg->sleep(fe, 1);
455
456} 564}
457 565
458u16 dib0070_wbd_offset(struct dvb_frontend *fe) 566static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
459{ 567{
460 struct dib0070_state *st = fe->tuner_priv; 568 u8 gain;
461 return st->wbd_ff_offset; 569 for (gain = 6; gain < 8; gain++) {
570 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
571 dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
572 }
462} 573}
463 574
464EXPORT_SYMBOL(dib0070_wbd_offset); 575u16 dib0070_wbd_offset(struct dvb_frontend *fe)
465static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
466{ 576{
467 struct dib0070_state *state = fe->tuner_priv; 577 struct dib0070_state *state = fe->tuner_priv;
468 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); 578 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
469 dprintk( "CTRL_LO5: 0x%x", lo5); 579 u32 freq = fe->dtv_property_cache.frequency / 1000;
470 return dib0070_write_reg(state, 0x15, lo5); 580
581 if (tmp != NULL) {
582 while (freq / 1000 > tmp->freq) /* find the right one */
583 tmp++;
584 state->wbd_gain_current = tmp->wbd_gain_val;
585 } else
586 state->wbd_gain_current = 6;
587
588 return state->wbd_offset_3_3[state->wbd_gain_current - 6];
471} 589}
472 590
591EXPORT_SYMBOL(dib0070_wbd_offset);
592
473#define pgm_read_word(w) (*w) 593#define pgm_read_word(w) (*w)
474static int dib0070_reset(struct dib0070_state *state) 594static int dib0070_reset(struct dvb_frontend *fe)
475{ 595{
596 struct dib0070_state *state = fe->tuner_priv;
476 u16 l, r, *n; 597 u16 l, r, *n;
477 598
478 HARD_RESET(state); 599 HARD_RESET(state);
479 600
480
481#ifndef FORCE_SBAND_TUNER 601#ifndef FORCE_SBAND_TUNER
482 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) 602 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
483 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; 603 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
484 else 604 else
605#else
606#warning forcing SBAND
485#endif 607#endif
486 state->revision = DIB0070S_P1A; 608 state->revision = DIB0070S_P1A;
487 609
488 /* P1F or not */ 610 /* P1F or not */
489 dprintk( "Revision: %x", state->revision); 611 dprintk("Revision: %x", state->revision);
490 612
491 if (state->revision == DIB0070_P1D) { 613 if (state->revision == DIB0070_P1D) {
492 dprintk( "Error: this driver is not to be used meant for P1D or earlier"); 614 dprintk("Error: this driver is not to be used meant for P1D or earlier");
493 return -EINVAL; 615 return -EINVAL;
494 } 616 }
495 617
@@ -498,7 +620,7 @@ static int dib0070_reset(struct dib0070_state *state)
498 while (l) { 620 while (l) {
499 r = pgm_read_word(n++); 621 r = pgm_read_word(n++);
500 do { 622 do {
501 dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); 623 dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
502 r++; 624 r++;
503 } while (--l); 625 } while (--l);
504 l = pgm_read_word(n++); 626 l = pgm_read_word(n++);
@@ -514,24 +636,25 @@ static int dib0070_reset(struct dib0070_state *state)
514 r |= state->cfg->osc_buffer_state << 3; 636 r |= state->cfg->osc_buffer_state << 3;
515 637
516 dib0070_write_reg(state, 0x10, r); 638 dib0070_write_reg(state, 0x10, r);
517 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4)); 639 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
518 640
519 if (state->cfg->invert_iq) { 641 if (state->cfg->invert_iq) {
520 r = dib0070_read_reg(state, 0x02) & 0xffdf; 642 r = dib0070_read_reg(state, 0x02) & 0xffdf;
521 dib0070_write_reg(state, 0x02, r | (1 << 5)); 643 dib0070_write_reg(state, 0x02, r | (1 << 5));
522 } 644 }
523 645
524
525 if (state->revision == DIB0070S_P1A) 646 if (state->revision == DIB0070S_P1A)
526 dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1); 647 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
527 else 648 else
528 dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0); 649 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
529 650
530 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); 651 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
652
653 dib0070_wbd_offset_calibration(state);
654
531 return 0; 655 return 0;
532} 656}
533 657
534
535static int dib0070_release(struct dvb_frontend *fe) 658static int dib0070_release(struct dvb_frontend *fe)
536{ 659{
537 kfree(fe->tuner_priv); 660 kfree(fe->tuner_priv);
@@ -539,23 +662,24 @@ static int dib0070_release(struct dvb_frontend *fe)
539 return 0; 662 return 0;
540} 663}
541 664
542static struct dvb_tuner_ops dib0070_ops = { 665static const struct dvb_tuner_ops dib0070_ops = {
543 .info = { 666 .info = {
544 .name = "DiBcom DiB0070", 667 .name = "DiBcom DiB0070",
545 .frequency_min = 45000000, 668 .frequency_min = 45000000,
546 .frequency_max = 860000000, 669 .frequency_max = 860000000,
547 .frequency_step = 1000, 670 .frequency_step = 1000,
548 }, 671 },
549 .release = dib0070_release, 672 .release = dib0070_release,
550 673
551 .init = dib0070_wakeup, 674 .init = dib0070_wakeup,
552 .sleep = dib0070_sleep, 675 .sleep = dib0070_sleep,
553 .set_params = dib0070_tune_digital, 676 .set_params = dib0070_tune,
554// .get_frequency = dib0070_get_frequency, 677
555// .get_bandwidth = dib0070_get_bandwidth 678// .get_frequency = dib0070_get_frequency,
679// .get_bandwidth = dib0070_get_bandwidth
556}; 680};
557 681
558struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) 682struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
559{ 683{
560 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); 684 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
561 if (state == NULL) 685 if (state == NULL)
@@ -563,25 +687,24 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
563 687
564 state->cfg = cfg; 688 state->cfg = cfg;
565 state->i2c = i2c; 689 state->i2c = i2c;
566 state->fe = fe; 690 state->fe = fe;
567 fe->tuner_priv = state; 691 fe->tuner_priv = state;
568 692
569 if (dib0070_reset(state) != 0) 693 if (dib0070_reset(fe) != 0)
570 goto free_mem; 694 goto free_mem;
571 695
572 dib0070_wbd_calibration(fe);
573
574 printk(KERN_INFO "DiB0070: successfully identified\n"); 696 printk(KERN_INFO "DiB0070: successfully identified\n");
575 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); 697 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
576 698
577 fe->tuner_priv = state; 699 fe->tuner_priv = state;
578 return fe; 700 return fe;
579 701
580free_mem: 702 free_mem:
581 kfree(state); 703 kfree(state);
582 fe->tuner_priv = NULL; 704 fe->tuner_priv = NULL;
583 return NULL; 705 return NULL;
584} 706}
707
585EXPORT_SYMBOL(dib0070_attach); 708EXPORT_SYMBOL(dib0070_attach);
586 709
587MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 710MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 9670f5d20cfb..8a2e1e710adb 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -15,6 +15,11 @@ struct i2c_adapter;
15 15
16#define DEFAULT_DIB0070_I2C_ADDRESS 0x60 16#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
17 17
18struct dib0070_wbd_gain_cfg {
19 u16 freq;
20 u16 wbd_gain_val;
21};
22
18struct dib0070_config { 23struct dib0070_config {
19 u8 i2c_address; 24 u8 i2c_address;
20 25
@@ -26,26 +31,28 @@ struct dib0070_config {
26 int freq_offset_khz_uhf; 31 int freq_offset_khz_uhf;
27 int freq_offset_khz_vhf; 32 int freq_offset_khz_vhf;
28 33
29 u8 osc_buffer_state; /* 0= normal, 1= tri-state */ 34 u8 osc_buffer_state; /* 0= normal, 1= tri-state */
30 u32 clock_khz; 35 u32 clock_khz;
31 u8 clock_pad_drive; /* (Drive + 1) * 2mA */ 36 u8 clock_pad_drive; /* (Drive + 1) * 2mA */
32 37
33 u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */ 38 u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
34 39
35 u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */ 40 u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
36 41
37 u8 flip_chip; 42 u8 flip_chip;
43 u8 enable_third_order_filter;
44 u8 charge_pump;
45
46 const struct dib0070_wbd_gain_cfg *wbd_gain;
47
48 u8 vga_filter;
38}; 49};
39 50
40#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) 51#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 52extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
42 struct i2c_adapter *i2c,
43 struct dib0070_config *cfg);
44extern u16 dib0070_wbd_offset(struct dvb_frontend *); 53extern u16 dib0070_wbd_offset(struct dvb_frontend *);
45#else 54#else
46static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 55static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
47 struct i2c_adapter *i2c,
48 struct dib0070_config *cfg)
49{ 56{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL; 58 return NULL;
@@ -57,5 +64,6 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
57 return -ENODEV; 64 return -ENODEV;
58} 65}
59#endif 66#endif
67extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
60 68
61#endif 69#endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index fc96fbf03d6d..55ef6eeb0769 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/i2c.h> 11#include <linux/i2c.h>
12 12
13#include "dvb_math.h"
13#include "dvb_frontend.h" 14#include "dvb_frontend.h"
14 15
15#include "dib7000p.h" 16#include "dib7000p.h"
@@ -1217,7 +1218,37 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1217 1218
1218static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) 1219static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1219{ 1220{
1220 *snr = 0x0000; 1221 struct dib7000p_state *state = fe->demodulator_priv;
1222 u16 val;
1223 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1224 u32 result = 0;
1225
1226 val = dib7000p_read_word(state, 479);
1227 noise_mant = (val >> 4) & 0xff;
1228 noise_exp = ((val & 0xf) << 2);
1229 val = dib7000p_read_word(state, 480);
1230 noise_exp += ((val >> 14) & 0x3);
1231 if ((noise_exp & 0x20) != 0)
1232 noise_exp -= 0x40;
1233
1234 signal_mant = (val >> 6) & 0xFF;
1235 signal_exp = (val & 0x3F);
1236 if ((signal_exp & 0x20) != 0)
1237 signal_exp -= 0x40;
1238
1239 if (signal_mant != 0)
1240 result = intlog10(2) * 10 * signal_exp + 10 *
1241 intlog10(signal_mant);
1242 else
1243 result = intlog10(2) * 10 * signal_exp - 100;
1244
1245 if (noise_mant != 0)
1246 result -= intlog10(2) * 10 * noise_exp + 10 *
1247 intlog10(noise_mant);
1248 else
1249 result -= intlog10(2) * 10 * noise_exp - 100;
1250
1251 *snr = result / ((1 << 24) / 10);
1221 return 0; 1252 return 0;
1222} 1253}
1223 1254
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
new file mode 100644
index 000000000000..852c790d09d9
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -0,0 +1,2277 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3 *
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include "dvb_math.h"
13
14#include "dvb_frontend.h"
15
16#include "dib8000.h"
17
18#define LAYER_ALL -1
19#define LAYER_A 1
20#define LAYER_B 2
21#define LAYER_C 3
22
23#define FE_CALLBACK_TIME_NEVER 0xffffffff
24
25static int debug;
26module_param(debug, int, 0644);
27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
28
29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
30
31enum frontend_tune_state {
32 CT_AGC_START = 20,
33 CT_AGC_STEP_0,
34 CT_AGC_STEP_1,
35 CT_AGC_STEP_2,
36 CT_AGC_STEP_3,
37 CT_AGC_STEP_4,
38 CT_AGC_STOP,
39
40 CT_DEMOD_START = 30,
41};
42
43#define FE_STATUS_TUNE_FAILED 0
44
45struct i2c_device {
46 struct i2c_adapter *adap;
47 u8 addr;
48};
49
50struct dib8000_state {
51 struct dvb_frontend fe;
52 struct dib8000_config cfg;
53
54 struct i2c_device i2c;
55
56 struct dibx000_i2c_master i2c_master;
57
58 u16 wbd_ref;
59
60 u8 current_band;
61 u32 current_bandwidth;
62 struct dibx000_agc_config *current_agc;
63 u32 timf;
64 u32 timf_default;
65
66 u8 div_force_off:1;
67 u8 div_state:1;
68 u16 div_sync_wait;
69
70 u8 agc_state;
71 u8 differential_constellation;
72 u8 diversity_onoff;
73
74 s16 ber_monitored_layer;
75 u16 gpio_dir;
76 u16 gpio_val;
77
78 u16 revision;
79 u8 isdbt_cfg_loaded;
80 enum frontend_tune_state tune_state;
81 u32 status;
82};
83
84enum dib8000_power_mode {
85 DIB8000M_POWER_ALL = 0,
86 DIB8000M_POWER_INTERFACE_ONLY,
87};
88
89static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
90{
91 u8 wb[2] = { reg >> 8, reg & 0xff };
92 u8 rb[2];
93 struct i2c_msg msg[2] = {
94 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
95 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
96 };
97
98 if (i2c_transfer(i2c->adap, msg, 2) != 2)
99 dprintk("i2c read error on %d", reg);
100
101 return (rb[0] << 8) | rb[1];
102}
103
104static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
105{
106 return dib8000_i2c_read16(&state->i2c, reg);
107}
108
109static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
110{
111 u16 rw[2];
112
113 rw[0] = dib8000_read_word(state, reg + 0);
114 rw[1] = dib8000_read_word(state, reg + 1);
115
116 return ((rw[0] << 16) | (rw[1]));
117}
118
119static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
120{
121 u8 b[4] = {
122 (reg >> 8) & 0xff, reg & 0xff,
123 (val >> 8) & 0xff, val & 0xff,
124 };
125 struct i2c_msg msg = {
126 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
127 };
128 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
129}
130
131static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
132{
133 return dib8000_i2c_write16(&state->i2c, reg, val);
134}
135
136const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
137 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
138 (920 << 5) | 0x09
139};
140
141const int16_t coeff_2k_sb_1seg[8] = {
142 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
143};
144
145const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
146 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
147 (-931 << 5) | 0x0f
148};
149
150const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
151 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
152 (982 << 5) | 0x0c
153};
154
155const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
156 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
157 (-720 << 5) | 0x0d
158};
159
160const int16_t coeff_2k_sb_3seg[8] = {
161 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
162 (-610 << 5) | 0x0a
163};
164
165const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
166 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
167 (-922 << 5) | 0x0d
168};
169
170const int16_t coeff_4k_sb_1seg[8] = {
171 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
172 (-655 << 5) | 0x0a
173};
174
175const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
176 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
177 (-958 << 5) | 0x13
178};
179
180const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
181 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
182 (-568 << 5) | 0x0f
183};
184
185const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
186 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
187 (-848 << 5) | 0x13
188};
189
190const int16_t coeff_4k_sb_3seg[8] = {
191 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
192 (-869 << 5) | 0x13
193};
194
195const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
196 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
197 (-598 << 5) | 0x10
198};
199
200const int16_t coeff_8k_sb_1seg[8] = {
201 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
202 (585 << 5) | 0x0f
203};
204
205const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
206 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
207 (0 << 5) | 0x14
208};
209
210const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
211 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
212 (-877 << 5) | 0x15
213};
214
215const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
216 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
217 (-921 << 5) | 0x14
218};
219
220const int16_t coeff_8k_sb_3seg[8] = {
221 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
222 (690 << 5) | 0x14
223};
224
225const int16_t ana_fe_coeff_3seg[24] = {
226 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
227};
228
229const int16_t ana_fe_coeff_1seg[24] = {
230 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
231};
232
233const int16_t ana_fe_coeff_13seg[24] = {
234 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
235};
236
237static u16 fft_to_mode(struct dib8000_state *state)
238{
239 u16 mode;
240 switch (state->fe.dtv_property_cache.transmission_mode) {
241 case TRANSMISSION_MODE_2K:
242 mode = 1;
243 break;
244 case TRANSMISSION_MODE_4K:
245 mode = 2;
246 break;
247 default:
248 case TRANSMISSION_MODE_AUTO:
249 case TRANSMISSION_MODE_8K:
250 mode = 3;
251 break;
252 }
253 return mode;
254}
255
256static void dib8000_set_acquisition_mode(struct dib8000_state *state)
257{
258 u16 nud = dib8000_read_word(state, 298);
259 nud |= (1 << 3) | (1 << 0);
260 dprintk("acquisition mode activated");
261 dib8000_write_word(state, 298, nud);
262}
263
264static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
265{
266 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
267
268 outreg = 0;
269 fifo_threshold = 1792;
270 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
271
272 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode);
273
274 switch (mode) {
275 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
276 outreg = (1 << 10); /* 0x0400 */
277 break;
278 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
279 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
280 break;
281 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
282 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
283 break;
284 case OUTMODE_DIVERSITY:
285 if (state->cfg.hostbus_diversity) {
286 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
287 sram &= 0xfdff;
288 } else
289 sram |= 0x0c00;
290 break;
291 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
292 smo_mode |= (3 << 1);
293 fifo_threshold = 512;
294 outreg = (1 << 10) | (5 << 6);
295 break;
296 case OUTMODE_HIGH_Z: // disable
297 outreg = 0;
298 break;
299
300 case OUTMODE_ANALOG_ADC:
301 outreg = (1 << 10) | (3 << 6);
302 dib8000_set_acquisition_mode(state);
303 break;
304
305 default:
306 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
307 return -EINVAL;
308 }
309
310 if (state->cfg.output_mpeg2_in_188_bytes)
311 smo_mode |= (1 << 5);
312
313 dib8000_write_word(state, 299, smo_mode);
314 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
315 dib8000_write_word(state, 1286, outreg);
316 dib8000_write_word(state, 1291, sram);
317
318 return 0;
319}
320
321static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
322{
323 struct dib8000_state *state = fe->demodulator_priv;
324 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
325
326 if (!state->differential_constellation) {
327 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
328 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
329 } else {
330 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
331 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
332 }
333 state->diversity_onoff = onoff;
334
335 switch (onoff) {
336 case 0: /* only use the internal way - not the diversity input */
337 dib8000_write_word(state, 270, 1);
338 dib8000_write_word(state, 271, 0);
339 break;
340 case 1: /* both ways */
341 dib8000_write_word(state, 270, 6);
342 dib8000_write_word(state, 271, 6);
343 break;
344 case 2: /* only the diversity input */
345 dib8000_write_word(state, 270, 0);
346 dib8000_write_word(state, 271, 1);
347 break;
348 }
349 return 0;
350}
351
352static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
353{
354 /* by default everything is going to be powered off */
355 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
356 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
357
358 /* now, depending on the requested mode, we power on */
359 switch (mode) {
360 /* power up everything in the demod */
361 case DIB8000M_POWER_ALL:
362 reg_774 = 0x0000;
363 reg_775 = 0x0000;
364 reg_776 = 0x0000;
365 reg_900 &= 0xfffc;
366 reg_1280 &= 0x00ff;
367 break;
368 case DIB8000M_POWER_INTERFACE_ONLY:
369 reg_1280 &= 0x00ff;
370 break;
371 }
372
373 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
374 dib8000_write_word(state, 774, reg_774);
375 dib8000_write_word(state, 775, reg_775);
376 dib8000_write_word(state, 776, reg_776);
377 dib8000_write_word(state, 900, reg_900);
378 dib8000_write_word(state, 1280, reg_1280);
379}
380
381static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
382{
383 int ret = 0;
384 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
385
386 switch (no) {
387 case DIBX000_SLOW_ADC_ON:
388 reg_908 |= (1 << 1) | (1 << 0);
389 ret |= dib8000_write_word(state, 908, reg_908);
390 reg_908 &= ~(1 << 1);
391 break;
392
393 case DIBX000_SLOW_ADC_OFF:
394 reg_908 |= (1 << 1) | (1 << 0);
395 break;
396
397 case DIBX000_ADC_ON:
398 reg_907 &= 0x0fff;
399 reg_908 &= 0x0003;
400 break;
401
402 case DIBX000_ADC_OFF: // leave the VBG voltage on
403 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
404 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
405 break;
406
407 case DIBX000_VBG_ENABLE:
408 reg_907 &= ~(1 << 15);
409 break;
410
411 case DIBX000_VBG_DISABLE:
412 reg_907 |= (1 << 15);
413 break;
414
415 default:
416 break;
417 }
418
419 ret |= dib8000_write_word(state, 907, reg_907);
420 ret |= dib8000_write_word(state, 908, reg_908);
421
422 return ret;
423}
424
425static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
426{
427 u32 timf;
428
429 if (bw == 0)
430 bw = 6000;
431
432 if (state->timf == 0) {
433 dprintk("using default timf");
434 timf = state->timf_default;
435 } else {
436 dprintk("using updated timf");
437 timf = state->timf;
438 }
439
440 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
441 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
442
443 return 0;
444}
445
446static int dib8000_sad_calib(struct dib8000_state *state)
447{
448/* internal */
449 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
450 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
451
452 /* do the calibration */
453 dib8000_write_word(state, 923, (1 << 0));
454 dib8000_write_word(state, 923, (0 << 0));
455
456 msleep(1);
457 return 0;
458}
459
460int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
461{
462 struct dib8000_state *state = fe->demodulator_priv;
463 if (value > 4095)
464 value = 4095;
465 state->wbd_ref = value;
466 return dib8000_write_word(state, 106, value);
467}
468
469EXPORT_SYMBOL(dib8000_set_wbd_ref);
470static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
471{
472 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
473 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
474 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
475 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
476 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
477 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
478
479 dib8000_write_word(state, 922, bw->sad_cfg);
480}
481
482static void dib8000_reset_pll(struct dib8000_state *state)
483{
484 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
485 u16 clk_cfg1;
486
487 // clk_cfg0
488 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
489
490 // clk_cfg1
491 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
492 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
493
494 dib8000_write_word(state, 902, clk_cfg1);
495 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
496 dib8000_write_word(state, 902, clk_cfg1);
497
498 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
499
500 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
501 if (state->cfg.pll->ADClkSrc == 0)
502 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
503 else if (state->cfg.refclksel != 0)
504 dib8000_write_word(state, 904,
505 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
506 ADClkSrc << 7) | (0 << 1));
507 else
508 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
509
510 dib8000_reset_pll_common(state, pll);
511}
512
513static int dib8000_reset_gpio(struct dib8000_state *st)
514{
515 /* reset the GPIOs */
516 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
517 dib8000_write_word(st, 1030, st->cfg.gpio_val);
518
519 /* TODO 782 is P_gpio_od */
520
521 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
522
523 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
524 return 0;
525}
526
527static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
528{
529 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
530 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
531 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
532 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
533
534 st->cfg.gpio_val = dib8000_read_word(st, 1030);
535 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
536 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
537 dib8000_write_word(st, 1030, st->cfg.gpio_val);
538
539 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
540
541 return 0;
542}
543
544int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
545{
546 struct dib8000_state *state = fe->demodulator_priv;
547 return dib8000_cfg_gpio(state, num, dir, val);
548}
549
550EXPORT_SYMBOL(dib8000_set_gpio);
551static const u16 dib8000_defaults[] = {
552 /* auto search configuration - lock0 by default waiting
553 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
554 3, 7,
555 0x0004,
556 0x0400,
557 0x0814,
558
559 12, 11,
560 0x001b,
561 0x7740,
562 0x005b,
563 0x8d80,
564 0x01c9,
565 0xc380,
566 0x0000,
567 0x0080,
568 0x0000,
569 0x0090,
570 0x0001,
571 0xd4c0,
572
573 /*1, 32,
574 0x6680 // P_corm_thres Lock algorithms configuration */
575
576 11, 80, /* set ADC level to -16 */
577 (1 << 13) - 825 - 117,
578 (1 << 13) - 837 - 117,
579 (1 << 13) - 811 - 117,
580 (1 << 13) - 766 - 117,
581 (1 << 13) - 737 - 117,
582 (1 << 13) - 693 - 117,
583 (1 << 13) - 648 - 117,
584 (1 << 13) - 619 - 117,
585 (1 << 13) - 575 - 117,
586 (1 << 13) - 531 - 117,
587 (1 << 13) - 501 - 117,
588
589 4, 108,
590 0,
591 0,
592 0,
593 0,
594
595 1, 175,
596 0x0410,
597 1, 179,
598 8192, // P_fft_nb_to_cut
599
600 6, 181,
601 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
602 0x2800,
603 0x2800,
604 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
605 0x2800,
606 0x2800,
607
608 2, 193,
609 0x0666, // P_pha3_thres
610 0x0000, // P_cti_use_cpe, P_cti_use_prog
611
612 2, 205,
613 0x200f, // P_cspu_regul, P_cspu_win_cut
614 0x000f, // P_des_shift_work
615
616 5, 215,
617 0x023d, // P_adp_regul_cnt
618 0x00a4, // P_adp_noise_cnt
619 0x00a4, // P_adp_regul_ext
620 0x7ff0, // P_adp_noise_ext
621 0x3ccc, // P_adp_fil
622
623 1, 230,
624 0x0000, // P_2d_byp_ti_num
625
626 1, 263,
627 0x800, //P_equal_thres_wgn
628
629 1, 268,
630 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
631
632 1, 270,
633 0x0001, // P_div_lock0_wait
634 1, 285,
635 0x0020, //p_fec_
636 1, 299,
637 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
638
639 1, 338,
640 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
641 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1
642 (0 << 9) | // P_ctrl_pre_freq_inh=0
643 (3 << 5) | // P_ctrl_pre_freq_step=3
644 (1 << 0), // P_pre_freq_win_len=1
645
646 1, 903,
647 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
648
649 0,
650};
651
652static u16 dib8000_identify(struct i2c_device *client)
653{
654 u16 value;
655
656 //because of glitches sometimes
657 value = dib8000_i2c_read16(client, 896);
658
659 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
660 dprintk("wrong Vendor ID (read=0x%x)", value);
661 return 0;
662 }
663
664 value = dib8000_i2c_read16(client, 897);
665 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
666 dprintk("wrong Device ID (%x)", value);
667 return 0;
668 }
669
670 switch (value) {
671 case 0x8000:
672 dprintk("found DiB8000A");
673 break;
674 case 0x8001:
675 dprintk("found DiB8000B");
676 break;
677 case 0x8002:
678 dprintk("found DiB8000C");
679 break;
680 }
681 return value;
682}
683
684static int dib8000_reset(struct dvb_frontend *fe)
685{
686 struct dib8000_state *state = fe->demodulator_priv;
687
688 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
689
690 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
691 return -EINVAL;
692
693 if (state->revision == 0x8000)
694 dprintk("error : dib8000 MA not supported");
695
696 dibx000_reset_i2c_master(&state->i2c_master);
697
698 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
699
700 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
701 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
702
703 /* restart all parts */
704 dib8000_write_word(state, 770, 0xffff);
705 dib8000_write_word(state, 771, 0xffff);
706 dib8000_write_word(state, 772, 0xfffc);
707 dib8000_write_word(state, 898, 0x000c); // sad
708 dib8000_write_word(state, 1280, 0x004d);
709 dib8000_write_word(state, 1281, 0x000c);
710
711 dib8000_write_word(state, 770, 0x0000);
712 dib8000_write_word(state, 771, 0x0000);
713 dib8000_write_word(state, 772, 0x0000);
714 dib8000_write_word(state, 898, 0x0004); // sad
715 dib8000_write_word(state, 1280, 0x0000);
716 dib8000_write_word(state, 1281, 0x0000);
717
718 /* drives */
719 if (state->cfg.drives)
720 dib8000_write_word(state, 906, state->cfg.drives);
721 else {
722 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
723 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
724 }
725
726 dib8000_reset_pll(state);
727
728 if (dib8000_reset_gpio(state) != 0)
729 dprintk("GPIO reset was not successful.");
730
731 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
732 dprintk("OUTPUT_MODE could not be resetted.");
733
734 state->current_agc = NULL;
735
736 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
737 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
738 if (state->cfg.pll->ifreq == 0)
739 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
740 else
741 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
742
743 {
744 u16 l = 0, r;
745 const u16 *n;
746 n = dib8000_defaults;
747 l = *n++;
748 while (l) {
749 r = *n++;
750 do {
751 dib8000_write_word(state, r, *n++);
752 r++;
753 } while (--l);
754 l = *n++;
755 }
756 }
757 state->isdbt_cfg_loaded = 0;
758
759 //div_cfg override for special configs
760 if (state->cfg.div_cfg != 0)
761 dib8000_write_word(state, 903, state->cfg.div_cfg);
762
763 /* unforce divstr regardless whether i2c enumeration was done or not */
764 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
765
766 dib8000_set_bandwidth(state, 6000);
767
768 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
769 dib8000_sad_calib(state);
770 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
771
772 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
773
774 return 0;
775}
776
777static void dib8000_restart_agc(struct dib8000_state *state)
778{
779 // P_restart_iqc & P_restart_agc
780 dib8000_write_word(state, 770, 0x0a00);
781 dib8000_write_word(state, 770, 0x0000);
782}
783
784static int dib8000_update_lna(struct dib8000_state *state)
785{
786 u16 dyn_gain;
787
788 if (state->cfg.update_lna) {
789 // read dyn_gain here (because it is demod-dependent and not tuner)
790 dyn_gain = dib8000_read_word(state, 390);
791
792 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed
793 dib8000_restart_agc(state);
794 return 1;
795 }
796 }
797 return 0;
798}
799
800static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
801{
802 struct dibx000_agc_config *agc = NULL;
803 int i;
804 if (state->current_band == band && state->current_agc != NULL)
805 return 0;
806 state->current_band = band;
807
808 for (i = 0; i < state->cfg.agc_config_count; i++)
809 if (state->cfg.agc[i].band_caps & band) {
810 agc = &state->cfg.agc[i];
811 break;
812 }
813
814 if (agc == NULL) {
815 dprintk("no valid AGC configuration found for band 0x%02x", band);
816 return -EINVAL;
817 }
818
819 state->current_agc = agc;
820
821 /* AGC */
822 dib8000_write_word(state, 76, agc->setup);
823 dib8000_write_word(state, 77, agc->inv_gain);
824 dib8000_write_word(state, 78, agc->time_stabiliz);
825 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
826
827 // Demod AGC loop configuration
828 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
829 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
830
831 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
832 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
833
834 /* AGC continued */
835 if (state->wbd_ref != 0)
836 dib8000_write_word(state, 106, state->wbd_ref);
837 else // use default
838 dib8000_write_word(state, 106, agc->wbd_ref);
839 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
840 dib8000_write_word(state, 108, agc->agc1_max);
841 dib8000_write_word(state, 109, agc->agc1_min);
842 dib8000_write_word(state, 110, agc->agc2_max);
843 dib8000_write_word(state, 111, agc->agc2_min);
844 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
845 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
846 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
847 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
848
849 dib8000_write_word(state, 75, agc->agc1_pt3);
850 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
851
852 return 0;
853}
854
855static int dib8000_agc_soft_split(struct dib8000_state *state)
856{
857 u16 agc, split_offset;
858
859 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
860 return FE_CALLBACK_TIME_NEVER;
861
862 // n_agc_global
863 agc = dib8000_read_word(state, 390);
864
865 if (agc > state->current_agc->split.min_thres)
866 split_offset = state->current_agc->split.min;
867 else if (agc < state->current_agc->split.max_thres)
868 split_offset = state->current_agc->split.max;
869 else
870 split_offset = state->current_agc->split.max *
871 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
872
873 dprintk("AGC split_offset: %d", split_offset);
874
875 // P_agc_force_split and P_agc_split_offset
876 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
877 return 5000;
878}
879
880static int dib8000_agc_startup(struct dvb_frontend *fe)
881{
882 struct dib8000_state *state = fe->demodulator_priv;
883 enum frontend_tune_state *tune_state = &state->tune_state;
884
885 int ret = 0;
886
887 switch (*tune_state) {
888 case CT_AGC_START:
889 // set power-up level: interf+analog+AGC
890
891 dib8000_set_adc_state(state, DIBX000_ADC_ON);
892
893 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
894 *tune_state = CT_AGC_STOP;
895 state->status = FE_STATUS_TUNE_FAILED;
896 break;
897 }
898
899 ret = 70;
900 *tune_state = CT_AGC_STEP_0;
901 break;
902
903 case CT_AGC_STEP_0:
904 //AGC initialization
905 if (state->cfg.agc_control)
906 state->cfg.agc_control(&state->fe, 1);
907
908 dib8000_restart_agc(state);
909
910 // wait AGC rough lock time
911 ret = 50;
912 *tune_state = CT_AGC_STEP_1;
913 break;
914
915 case CT_AGC_STEP_1:
916 // wait AGC accurate lock time
917 ret = 70;
918
919 if (dib8000_update_lna(state))
920 // wait only AGC rough lock time
921 ret = 50;
922 else
923 *tune_state = CT_AGC_STEP_2;
924 break;
925
926 case CT_AGC_STEP_2:
927 dib8000_agc_soft_split(state);
928
929 if (state->cfg.agc_control)
930 state->cfg.agc_control(&state->fe, 0);
931
932 *tune_state = CT_AGC_STOP;
933 break;
934 default:
935 ret = dib8000_agc_soft_split(state);
936 break;
937 }
938 return ret;
939
940}
941
942static void dib8000_update_timf(struct dib8000_state *state)
943{
944 u32 timf = state->timf = dib8000_read32(state, 435);
945
946 dib8000_write_word(state, 29, (u16) (timf >> 16));
947 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
948 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
949}
950
951static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
952{
953 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
954 u8 guard, crate, constellation, timeI;
955 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
956 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
957 const s16 *ncoeff, *ana_fe;
958 u16 tmcc_pow = 0;
959 u16 coff_pow = 0x2800;
960 u16 init_prbs = 0xfff;
961 u16 ana_gain = 0;
962 u16 adc_target_16dB[11] = {
963 (1 << 13) - 825 - 117,
964 (1 << 13) - 837 - 117,
965 (1 << 13) - 811 - 117,
966 (1 << 13) - 766 - 117,
967 (1 << 13) - 737 - 117,
968 (1 << 13) - 693 - 117,
969 (1 << 13) - 648 - 117,
970 (1 << 13) - 619 - 117,
971 (1 << 13) - 575 - 117,
972 (1 << 13) - 531 - 117,
973 (1 << 13) - 501 - 117
974 };
975
976 if (state->ber_monitored_layer != LAYER_ALL)
977 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
978 else
979 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
980
981 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
982 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
983
984 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
985 //compute new dds_freq for the seg and adjust prbs
986 int seg_offset =
987 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
988 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
989 int clk = state->cfg.pll->internal;
990 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
991 int dds_offset = seg_offset * segtodds;
992 int new_dds, sub_channel;
993 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
994 dds_offset -= (int)(segtodds / 2);
995
996 if (state->cfg.pll->ifreq == 0) {
997 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
998 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
999 new_dds = dds_offset;
1000 } else
1001 new_dds = dds_offset;
1002
1003 // We shift tuning frequency if the wanted segment is :
1004 // - the segment of center frequency with an odd total number of segments
1005 // - the segment to the left of center frequency with an even total number of segments
1006 // - the segment to the right of center frequency with an even total number of segments
1007 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1008 &&
1009 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1010 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1011 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1012 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1013 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1014 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1015 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1016 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1017 )) {
1018 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1019 }
1020 } else {
1021 if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1022 new_dds = state->cfg.pll->ifreq - dds_offset;
1023 else
1024 new_dds = state->cfg.pll->ifreq + dds_offset;
1025 }
1026 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1027 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1028 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
1029 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1030 else // if even
1031 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1032 sub_channel -= 6;
1033
1034 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1035 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1036 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1037 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1038 } else {
1039 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1040 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1041 }
1042
1043 switch (state->fe.dtv_property_cache.transmission_mode) {
1044 case TRANSMISSION_MODE_2K:
1045 switch (sub_channel) {
1046 case -6:
1047 init_prbs = 0x0;
1048 break; // 41, 0, 1
1049 case -5:
1050 init_prbs = 0x423;
1051 break; // 02~04
1052 case -4:
1053 init_prbs = 0x9;
1054 break; // 05~07
1055 case -3:
1056 init_prbs = 0x5C7;
1057 break; // 08~10
1058 case -2:
1059 init_prbs = 0x7A6;
1060 break; // 11~13
1061 case -1:
1062 init_prbs = 0x3D8;
1063 break; // 14~16
1064 case 0:
1065 init_prbs = 0x527;
1066 break; // 17~19
1067 case 1:
1068 init_prbs = 0x7FF;
1069 break; // 20~22
1070 case 2:
1071 init_prbs = 0x79B;
1072 break; // 23~25
1073 case 3:
1074 init_prbs = 0x3D6;
1075 break; // 26~28
1076 case 4:
1077 init_prbs = 0x3A2;
1078 break; // 29~31
1079 case 5:
1080 init_prbs = 0x53B;
1081 break; // 32~34
1082 case 6:
1083 init_prbs = 0x2F4;
1084 break; // 35~37
1085 default:
1086 case 7:
1087 init_prbs = 0x213;
1088 break; // 38~40
1089 }
1090 break;
1091
1092 case TRANSMISSION_MODE_4K:
1093 switch (sub_channel) {
1094 case -6:
1095 init_prbs = 0x0;
1096 break; // 41, 0, 1
1097 case -5:
1098 init_prbs = 0x208;
1099 break; // 02~04
1100 case -4:
1101 init_prbs = 0xC3;
1102 break; // 05~07
1103 case -3:
1104 init_prbs = 0x7B9;
1105 break; // 08~10
1106 case -2:
1107 init_prbs = 0x423;
1108 break; // 11~13
1109 case -1:
1110 init_prbs = 0x5C7;
1111 break; // 14~16
1112 case 0:
1113 init_prbs = 0x3D8;
1114 break; // 17~19
1115 case 1:
1116 init_prbs = 0x7FF;
1117 break; // 20~22
1118 case 2:
1119 init_prbs = 0x3D6;
1120 break; // 23~25
1121 case 3:
1122 init_prbs = 0x53B;
1123 break; // 26~28
1124 case 4:
1125 init_prbs = 0x213;
1126 break; // 29~31
1127 case 5:
1128 init_prbs = 0x29;
1129 break; // 32~34
1130 case 6:
1131 init_prbs = 0xD0;
1132 break; // 35~37
1133 default:
1134 case 7:
1135 init_prbs = 0x48E;
1136 break; // 38~40
1137 }
1138 break;
1139
1140 default:
1141 case TRANSMISSION_MODE_8K:
1142 switch (sub_channel) {
1143 case -6:
1144 init_prbs = 0x0;
1145 break; // 41, 0, 1
1146 case -5:
1147 init_prbs = 0x740;
1148 break; // 02~04
1149 case -4:
1150 init_prbs = 0x069;
1151 break; // 05~07
1152 case -3:
1153 init_prbs = 0x7DD;
1154 break; // 08~10
1155 case -2:
1156 init_prbs = 0x208;
1157 break; // 11~13
1158 case -1:
1159 init_prbs = 0x7B9;
1160 break; // 14~16
1161 case 0:
1162 init_prbs = 0x5C7;
1163 break; // 17~19
1164 case 1:
1165 init_prbs = 0x7FF;
1166 break; // 20~22
1167 case 2:
1168 init_prbs = 0x53B;
1169 break; // 23~25
1170 case 3:
1171 init_prbs = 0x29;
1172 break; // 26~28
1173 case 4:
1174 init_prbs = 0x48E;
1175 break; // 29~31
1176 case 5:
1177 init_prbs = 0x4C4;
1178 break; // 32~34
1179 case 6:
1180 init_prbs = 0x367;
1181 break; // 33~37
1182 default:
1183 case 7:
1184 init_prbs = 0x684;
1185 break; // 38~40
1186 }
1187 break;
1188 }
1189 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
1190 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1191 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1192 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1193 }
1194 /*P_mode == ?? */
1195 dib8000_write_word(state, 10, (seq << 4));
1196 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1197
1198 switch (state->fe.dtv_property_cache.guard_interval) {
1199 case GUARD_INTERVAL_1_32:
1200 guard = 0;
1201 break;
1202 case GUARD_INTERVAL_1_16:
1203 guard = 1;
1204 break;
1205 case GUARD_INTERVAL_1_8:
1206 guard = 2;
1207 break;
1208 case GUARD_INTERVAL_1_4:
1209 default:
1210 guard = 3;
1211 break;
1212 }
1213
1214 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1215
1216 max_constellation = DQPSK;
1217 for (i = 0; i < 3; i++) {
1218 switch (state->fe.dtv_property_cache.layer[i].modulation) {
1219 case DQPSK:
1220 constellation = 0;
1221 break;
1222 case QPSK:
1223 constellation = 1;
1224 break;
1225 case QAM_16:
1226 constellation = 2;
1227 break;
1228 case QAM_64:
1229 default:
1230 constellation = 3;
1231 break;
1232 }
1233
1234 switch (state->fe.dtv_property_cache.layer[i].fec) {
1235 case FEC_1_2:
1236 crate = 1;
1237 break;
1238 case FEC_2_3:
1239 crate = 2;
1240 break;
1241 case FEC_3_4:
1242 crate = 3;
1243 break;
1244 case FEC_5_6:
1245 crate = 5;
1246 break;
1247 case FEC_7_8:
1248 default:
1249 crate = 7;
1250 break;
1251 }
1252
1253 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1254 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1255 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1256 )
1257 timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1258 else
1259 timeI = 0;
1260 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1261 (crate << 3) | timeI);
1262 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1263 switch (max_constellation) {
1264 case DQPSK:
1265 case QPSK:
1266 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1267 state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1268 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1269 break;
1270 case QAM_16:
1271 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1272 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1273 break;
1274 }
1275 }
1276 }
1277
1278 mode = fft_to_mode(state);
1279
1280 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1281
1282 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1283 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1284 isdbt_sb_mode & 1) << 4));
1285
1286 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1287
1288 /* signal optimization parameter */
1289
1290 if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1291 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1292 for (i = 1; i < 3; i++)
1293 nbseg_diff +=
1294 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1295 for (i = 0; i < nbseg_diff; i++)
1296 seg_diff_mask |= 1 << permu_seg[i + 1];
1297 } else {
1298 for (i = 0; i < 3; i++)
1299 nbseg_diff +=
1300 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1301 for (i = 0; i < nbseg_diff; i++)
1302 seg_diff_mask |= 1 << permu_seg[i];
1303 }
1304 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1305
1306 state->differential_constellation = (seg_diff_mask != 0);
1307 dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1308
1309 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1310 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1311 seg_mask13 = 0x00E0;
1312 else // 1-segment
1313 seg_mask13 = 0x0040;
1314 } else
1315 seg_mask13 = 0x1fff;
1316
1317 // WRITE: Mode & Diff mask
1318 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1319
1320 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1321 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1322 else
1323 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1324
1325 // ---- SMALL ----
1326 // P_small_seg_diff
1327 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1328
1329 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1330
1331/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1332 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1333
1334 // ---- SMALL ----
1335 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1336 switch (state->fe.dtv_property_cache.transmission_mode) {
1337 case TRANSMISSION_MODE_2K:
1338 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1339 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1340 ncoeff = coeff_2k_sb_1seg_dqpsk;
1341 else // QPSK or QAM
1342 ncoeff = coeff_2k_sb_1seg;
1343 } else { // 3-segments
1344 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1345 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1346 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1347 else // QPSK or QAM on external segments
1348 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1349 } else { // QPSK or QAM on central segment
1350 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1351 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1352 else // QPSK or QAM on external segments
1353 ncoeff = coeff_2k_sb_3seg;
1354 }
1355 }
1356 break;
1357
1358 case TRANSMISSION_MODE_4K:
1359 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1360 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1361 ncoeff = coeff_4k_sb_1seg_dqpsk;
1362 else // QPSK or QAM
1363 ncoeff = coeff_4k_sb_1seg;
1364 } else { // 3-segments
1365 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1366 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1367 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1368 } else { // QPSK or QAM on external segments
1369 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1370 }
1371 } else { // QPSK or QAM on central segment
1372 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1373 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1374 } else // QPSK or QAM on external segments
1375 ncoeff = coeff_4k_sb_3seg;
1376 }
1377 }
1378 break;
1379
1380 case TRANSMISSION_MODE_AUTO:
1381 case TRANSMISSION_MODE_8K:
1382 default:
1383 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1384 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1385 ncoeff = coeff_8k_sb_1seg_dqpsk;
1386 else // QPSK or QAM
1387 ncoeff = coeff_8k_sb_1seg;
1388 } else { // 3-segments
1389 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1390 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1391 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1392 } else { // QPSK or QAM on external segments
1393 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1394 }
1395 } else { // QPSK or QAM on central segment
1396 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1397 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1398 } else // QPSK or QAM on external segments
1399 ncoeff = coeff_8k_sb_3seg;
1400 }
1401 }
1402 break;
1403 }
1404 }
1405 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1406 for (i = 0; i < 8; i++)
1407 dib8000_write_word(state, 343 + i, ncoeff[i]);
1408
1409 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1410 dib8000_write_word(state, 351,
1411 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1412
1413 // ---- COFF ----
1414 // Carloff, the most robust
1415 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
1416
1417 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1418 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1419 dib8000_write_word(state, 187,
1420 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1421 | 0x3);
1422
1423/* // P_small_coef_ext_enable = 1 */
1424/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1425
1426 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1427
1428 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1429 if (mode == 3)
1430 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1431 else
1432 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1433 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1434 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1435 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1436 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1437 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1438 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1439 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1440
1441 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1442 dib8000_write_word(state, 181, 300);
1443 dib8000_write_word(state, 182, 150);
1444 dib8000_write_word(state, 183, 80);
1445 dib8000_write_word(state, 184, 300);
1446 dib8000_write_word(state, 185, 150);
1447 dib8000_write_word(state, 186, 80);
1448 } else { // Sound Broadcasting mode 3 seg
1449 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1450 /* if (mode == 3) */
1451 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1452 /* else */
1453 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1454 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1455
1456 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1457 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1458 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1459 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1460 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1461 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1462 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1463
1464 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1465 dib8000_write_word(state, 181, 350);
1466 dib8000_write_word(state, 182, 300);
1467 dib8000_write_word(state, 183, 250);
1468 dib8000_write_word(state, 184, 350);
1469 dib8000_write_word(state, 185, 300);
1470 dib8000_write_word(state, 186, 250);
1471 }
1472
1473 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1474 dib8000_write_word(state, 180, (16 << 6) | 9);
1475 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1476 coff_pow = 0x2800;
1477 for (i = 0; i < 6; i++)
1478 dib8000_write_word(state, 181 + i, coff_pow);
1479
1480 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1481 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1482 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1483
1484 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1485 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1486 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1487 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1488 }
1489 // ---- FFT ----
1490 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
1491 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1492 else
1493 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1494
1495 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1496 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1497 */
1498 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1499 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1500
1501 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1502 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1503 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1504 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1505 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1506 else
1507 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1508 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1509 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1510 if (!autosearching)
1511 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1512 else
1513 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1514 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1515
1516 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1517
1518 /* offset loop parameters */
1519 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1520 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1521 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1522 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1523
1524 else // Sound Broadcasting mode 3 seg
1525 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1526 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1527 } else
1528 // TODO in 13 seg, timf_alpha can always be the same or not ?
1529 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1530 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1531
1532 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1533 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1534 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1535 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1536
1537 else // Sound Broadcasting mode 3 seg
1538 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1539 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1540 } else
1541 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1542 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1543
1544 /* P_dvsy_sync_wait - reuse mode */
1545 switch (state->fe.dtv_property_cache.transmission_mode) {
1546 case TRANSMISSION_MODE_8K:
1547 mode = 256;
1548 break;
1549 case TRANSMISSION_MODE_4K:
1550 mode = 128;
1551 break;
1552 default:
1553 case TRANSMISSION_MODE_2K:
1554 mode = 64;
1555 break;
1556 }
1557 if (state->cfg.diversity_delay == 0)
1558 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1559 else
1560 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1561 mode <<= 4;
1562 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1563
1564 /* channel estimation fine configuration */
1565 switch (max_constellation) {
1566 case QAM_64:
1567 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1568 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1569 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1570 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1571 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1572 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1573 break;
1574 case QAM_16:
1575 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1576 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1577 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1578 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1579 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1580 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1581 break;
1582 default:
1583 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1584 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1585 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1586 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1587 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1588 break;
1589 }
1590 for (mode = 0; mode < 4; mode++)
1591 dib8000_write_word(state, 215 + mode, coeff[mode]);
1592
1593 // update ana_gain depending on max constellation
1594 dib8000_write_word(state, 116, ana_gain);
1595 // update ADC target depending on ana_gain
1596 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1597 for (i = 0; i < 10; i++)
1598 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1599 } else { // set -22dB ADC target for ana_gain=0
1600 for (i = 0; i < 10; i++)
1601 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1602 }
1603
1604 // ---- ANA_FE ----
1605 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1606 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1607 ana_fe = ana_fe_coeff_3seg;
1608 else // 1-segment
1609 ana_fe = ana_fe_coeff_1seg;
1610 } else
1611 ana_fe = ana_fe_coeff_13seg;
1612
1613 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1614 for (mode = 0; mode < 24; mode++)
1615 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1616
1617 // ---- CHAN_BLK ----
1618 for (i = 0; i < 13; i++) {
1619 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1620 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1621 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1622 }
1623 }
1624 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1625 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1626 // "P_cspu_left_edge" not used => do not care
1627 // "P_cspu_right_edge" not used => do not care
1628
1629 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1630 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1631 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1632 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
1633 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1634 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1635 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1636 }
1637 } else if (state->isdbt_cfg_loaded == 0) {
1638 dib8000_write_word(state, 228, 0); // default value
1639 dib8000_write_word(state, 265, 31); // default value
1640 dib8000_write_word(state, 205, 0x200f); // init value
1641 }
1642 // ---- TMCC ----
1643 for (i = 0; i < 3; i++)
1644 tmcc_pow +=
1645 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1646 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1647 // Threshold is set at 1/4 of max power.
1648 tmcc_pow *= (1 << (9 - 2));
1649
1650 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1651 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1652 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1653 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1654 // ---- PHA3 ----
1655
1656 if (state->isdbt_cfg_loaded == 0)
1657 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1658
1659 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1660 state->isdbt_cfg_loaded = 0;
1661 else
1662 state->isdbt_cfg_loaded = 1;
1663
1664}
1665
1666static int dib8000_autosearch_start(struct dvb_frontend *fe)
1667{
1668 u8 factor;
1669 u32 value;
1670 struct dib8000_state *state = fe->demodulator_priv;
1671
1672 int slist = 0;
1673
1674 state->fe.dtv_property_cache.inversion = 0;
1675 if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1676 state->fe.dtv_property_cache.layer[0].segment_count = 13;
1677 state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1678 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1679 state->fe.dtv_property_cache.layer[0].interleaving = 0;
1680
1681 //choose the right list, in sb, always do everything
1682 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1683 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1684 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1685 slist = 7;
1686 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1687 } else {
1688 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1689 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1690 slist = 7;
1691 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1692 } else
1693 slist = 3;
1694 } else {
1695 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1696 slist = 2;
1697 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1698 } else
1699 slist = 0;
1700 }
1701
1702 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1703 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1704 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1705 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1706
1707 dprintk("using list for autosearch : %d", slist);
1708 dib8000_set_channel(state, (unsigned char)slist, 1);
1709 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1710
1711 factor = 1;
1712
1713 //set lock_mask values
1714 dib8000_write_word(state, 6, 0x4);
1715 dib8000_write_word(state, 7, 0x8);
1716 dib8000_write_word(state, 8, 0x1000);
1717
1718 //set lock_mask wait time values
1719 value = 50 * state->cfg.pll->internal * factor;
1720 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1721 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1722 value = 100 * state->cfg.pll->internal * factor;
1723 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1724 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1725 value = 1000 * state->cfg.pll->internal * factor;
1726 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1727 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1728
1729 value = dib8000_read_word(state, 0);
1730 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1731 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1732 dib8000_write_word(state, 0, (u16) value);
1733
1734 }
1735
1736 return 0;
1737}
1738
1739static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1740{
1741 struct dib8000_state *state = fe->demodulator_priv;
1742 u16 irq_pending = dib8000_read_word(state, 1284);
1743
1744 if (irq_pending & 0x1) { // failed
1745 dprintk("dib8000_autosearch_irq failed");
1746 return 1;
1747 }
1748
1749 if (irq_pending & 0x2) { // succeeded
1750 dprintk("dib8000_autosearch_irq succeeded");
1751 return 2;
1752 }
1753
1754 return 0; // still pending
1755}
1756
1757static int dib8000_tune(struct dvb_frontend *fe)
1758{
1759 struct dib8000_state *state = fe->demodulator_priv;
1760 int ret = 0;
1761 u16 value, mode = fft_to_mode(state);
1762
1763 // we are already tuned - just resuming from suspend
1764 if (state == NULL)
1765 return -EINVAL;
1766
1767 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1768 dib8000_set_channel(state, 0, 0);
1769
1770 // restart demod
1771 ret |= dib8000_write_word(state, 770, 0x4000);
1772 ret |= dib8000_write_word(state, 770, 0x0000);
1773 msleep(45);
1774
1775 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1776 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1777
1778 // never achieved a lock before - wait for timfreq to update
1779 if (state->timf == 0) {
1780 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1781 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1782 msleep(300);
1783 else // Sound Broadcasting mode 3 seg
1784 msleep(500);
1785 } else // 13 seg
1786 msleep(200);
1787 }
1788 //dump_reg(state);
1789 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1790 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1791
1792 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1793 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1794 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1795
1796 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1797 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1798
1799 } else { // Sound Broadcasting mode 3 seg
1800
1801 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1802 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1803
1804 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1805 }
1806
1807 } else { // 13 seg
1808 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1809 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1810
1811 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1812
1813 }
1814
1815 // we achieved a coff_cpil_lock - it's time to update the timf
1816 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1817 dib8000_update_timf(state);
1818
1819 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1820 dib8000_write_word(state, 6, 0x200);
1821
1822 if (state->revision == 0x8002) {
1823 value = dib8000_read_word(state, 903);
1824 dib8000_write_word(state, 903, value & ~(1 << 3));
1825 msleep(1);
1826 dib8000_write_word(state, 903, value | (1 << 3));
1827 }
1828
1829 return ret;
1830}
1831
1832static int dib8000_wakeup(struct dvb_frontend *fe)
1833{
1834 struct dib8000_state *state = fe->demodulator_priv;
1835
1836 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1837 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1838 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1839 dprintk("could not start Slow ADC");
1840
1841 return 0;
1842}
1843
1844static int dib8000_sleep(struct dvb_frontend *fe)
1845{
1846 struct dib8000_state *st = fe->demodulator_priv;
1847 if (1) {
1848 dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1849 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1850 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1851 } else {
1852
1853 return 0;
1854 }
1855}
1856
1857static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1858{
1859 struct dib8000_state *state = fe->demodulator_priv;
1860 u16 i, val = 0;
1861
1862 fe->dtv_property_cache.bandwidth_hz = 6000000;
1863
1864 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1865
1866 val = dib8000_read_word(state, 570);
1867 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1868 switch ((val & 0x30) >> 4) {
1869 case 1:
1870 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1871 break;
1872 case 3:
1873 default:
1874 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1875 break;
1876 }
1877
1878 switch (val & 0x3) {
1879 case 0:
1880 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1881 dprintk("dib8000_get_frontend GI = 1/32 ");
1882 break;
1883 case 1:
1884 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1885 dprintk("dib8000_get_frontend GI = 1/16 ");
1886 break;
1887 case 2:
1888 dprintk("dib8000_get_frontend GI = 1/8 ");
1889 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1890 break;
1891 case 3:
1892 dprintk("dib8000_get_frontend GI = 1/4 ");
1893 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1894 break;
1895 }
1896
1897 val = dib8000_read_word(state, 505);
1898 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1899 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1900
1901 for (i = 0; i < 3; i++) {
1902 val = dib8000_read_word(state, 493 + i);
1903 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1904 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1905
1906 val = dib8000_read_word(state, 499 + i);
1907 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1908 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1909
1910 val = dib8000_read_word(state, 481 + i);
1911 switch (val & 0x7) {
1912 case 1:
1913 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1914 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1915 break;
1916 case 2:
1917 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1918 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1919 break;
1920 case 3:
1921 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1922 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1923 break;
1924 case 5:
1925 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1926 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1927 break;
1928 default:
1929 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1930 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1931 break;
1932 }
1933
1934 val = dib8000_read_word(state, 487 + i);
1935 switch (val & 0x3) {
1936 case 0:
1937 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1938 fe->dtv_property_cache.layer[i].modulation = DQPSK;
1939 break;
1940 case 1:
1941 fe->dtv_property_cache.layer[i].modulation = QPSK;
1942 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1943 break;
1944 case 2:
1945 fe->dtv_property_cache.layer[i].modulation = QAM_16;
1946 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1947 break;
1948 case 3:
1949 default:
1950 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1951 fe->dtv_property_cache.layer[i].modulation = QAM_64;
1952 break;
1953 }
1954 }
1955 return 0;
1956}
1957
1958static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1959{
1960 struct dib8000_state *state = fe->demodulator_priv;
1961 int time, ret;
1962
1963 dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
1964
1965 if (fe->ops.tuner_ops.set_params)
1966 fe->ops.tuner_ops.set_params(fe, fep);
1967
1968 /* start up the AGC */
1969 state->tune_state = CT_AGC_START;
1970 do {
1971 time = dib8000_agc_startup(fe);
1972 if (time != FE_CALLBACK_TIME_NEVER)
1973 msleep(time / 10);
1974 else
1975 break;
1976 } while (state->tune_state != CT_AGC_STOP);
1977
1978 if (state->fe.dtv_property_cache.frequency == 0) {
1979 dprintk("dib8000: must at least specify frequency ");
1980 return 0;
1981 }
1982
1983 if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
1984 dprintk("dib8000: no bandwidth specified, set to default ");
1985 state->fe.dtv_property_cache.bandwidth_hz = 6000000;
1986 }
1987
1988 state->tune_state = CT_DEMOD_START;
1989
1990 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
1991 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
1992 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
1993 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
1994 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
1995 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
1996 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
1997 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
1998 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
1999 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2000 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2001 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2002 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2003 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2004 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2005 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2006 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2007 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2008 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2009 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2010 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2011 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2012 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2013 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2014 int i = 800, found;
2015
2016 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2017 dib8000_autosearch_start(fe);
2018 do {
2019 msleep(10);
2020 found = dib8000_autosearch_irq(fe);
2021 } while (found == 0 && i--);
2022
2023 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2024
2025 if (found == 0 || found == 1)
2026 return 0; // no channel found
2027
2028 dib8000_get_frontend(fe, fep);
2029 }
2030
2031 ret = dib8000_tune(fe);
2032
2033 /* make this a config parameter */
2034 dib8000_set_output_mode(state, state->cfg.output_mode);
2035
2036 return ret;
2037}
2038
2039static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2040{
2041 struct dib8000_state *state = fe->demodulator_priv;
2042 u16 lock = dib8000_read_word(state, 568);
2043
2044 *stat = 0;
2045
2046 if ((lock >> 14) & 1) // AGC
2047 *stat |= FE_HAS_SIGNAL;
2048
2049 if ((lock >> 8) & 1) // Equal
2050 *stat |= FE_HAS_CARRIER;
2051
2052 if ((lock >> 3) & 1) // TMCC_SYNC
2053 *stat |= FE_HAS_SYNC;
2054
2055 if ((lock >> 5) & 7) // FEC MPEG
2056 *stat |= FE_HAS_LOCK;
2057
2058 lock = dib8000_read_word(state, 554); // Viterbi Layer A
2059 if (lock & 0x01)
2060 *stat |= FE_HAS_VITERBI;
2061
2062 lock = dib8000_read_word(state, 555); // Viterbi Layer B
2063 if (lock & 0x01)
2064 *stat |= FE_HAS_VITERBI;
2065
2066 lock = dib8000_read_word(state, 556); // Viterbi Layer C
2067 if (lock & 0x01)
2068 *stat |= FE_HAS_VITERBI;
2069
2070 return 0;
2071}
2072
2073static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2074{
2075 struct dib8000_state *state = fe->demodulator_priv;
2076 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2077 return 0;
2078}
2079
2080static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2081{
2082 struct dib8000_state *state = fe->demodulator_priv;
2083 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2084 return 0;
2085}
2086
2087static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2088{
2089 struct dib8000_state *state = fe->demodulator_priv;
2090 u16 val = dib8000_read_word(state, 390);
2091 *strength = 65535 - val;
2092 return 0;
2093}
2094
2095static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2096{
2097 struct dib8000_state *state = fe->demodulator_priv;
2098 u16 val;
2099 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2100 u32 result = 0;
2101
2102 val = dib8000_read_word(state, 542);
2103 noise_mant = (val >> 6) & 0xff;
2104 noise_exp = (val & 0x3f);
2105
2106 val = dib8000_read_word(state, 543);
2107 signal_mant = (val >> 6) & 0xff;
2108 signal_exp = (val & 0x3f);
2109
2110 if ((noise_exp & 0x20) != 0)
2111 noise_exp -= 0x40;
2112 if ((signal_exp & 0x20) != 0)
2113 signal_exp -= 0x40;
2114
2115 if (signal_mant != 0)
2116 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2117 else
2118 result = intlog10(2) * 10 * signal_exp - 100;
2119 if (noise_mant != 0)
2120 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2121 else
2122 result -= intlog10(2) * 10 * noise_exp - 100;
2123
2124 *snr = result / (1 << 24);
2125 return 0;
2126}
2127
2128int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2129{
2130 int k = 0;
2131 u8 new_addr = 0;
2132 struct i2c_device client = {.adap = host };
2133
2134 for (k = no_of_demods - 1; k >= 0; k--) {
2135 /* designated i2c address */
2136 new_addr = first_addr + (k << 1);
2137
2138 client.addr = new_addr;
2139 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2140 if (dib8000_identify(&client) == 0) {
2141 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2142 client.addr = default_addr;
2143 if (dib8000_identify(&client) == 0) {
2144 dprintk("#%d: not identified", k);
2145 return -EINVAL;
2146 }
2147 }
2148
2149 /* start diversity to pull_down div_str - just for i2c-enumeration */
2150 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2151
2152 /* set new i2c address and force divstart */
2153 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2154 client.addr = new_addr;
2155 dib8000_identify(&client);
2156
2157 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2158 }
2159
2160 for (k = 0; k < no_of_demods; k++) {
2161 new_addr = first_addr | (k << 1);
2162 client.addr = new_addr;
2163
2164 // unforce divstr
2165 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2166
2167 /* deactivate div - it was just for i2c-enumeration */
2168 dib8000_i2c_write16(&client, 1286, 0);
2169 }
2170
2171 return 0;
2172}
2173
2174EXPORT_SYMBOL(dib8000_i2c_enumeration);
2175static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2176{
2177 tune->min_delay_ms = 1000;
2178 tune->step_size = 0;
2179 tune->max_drift = 0;
2180 return 0;
2181}
2182
2183static void dib8000_release(struct dvb_frontend *fe)
2184{
2185 struct dib8000_state *st = fe->demodulator_priv;
2186 dibx000_exit_i2c_master(&st->i2c_master);
2187 kfree(st);
2188}
2189
2190struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2191{
2192 struct dib8000_state *st = fe->demodulator_priv;
2193 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2194}
2195
2196EXPORT_SYMBOL(dib8000_get_i2c_master);
2197
2198static const struct dvb_frontend_ops dib8000_ops = {
2199 .info = {
2200 .name = "DiBcom 8000 ISDB-T",
2201 .type = FE_OFDM,
2202 .frequency_min = 44250000,
2203 .frequency_max = 867250000,
2204 .frequency_stepsize = 62500,
2205 .caps = FE_CAN_INVERSION_AUTO |
2206 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2207 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2208 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2209 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2210 },
2211
2212 .release = dib8000_release,
2213
2214 .init = dib8000_wakeup,
2215 .sleep = dib8000_sleep,
2216
2217 .set_frontend = dib8000_set_frontend,
2218 .get_tune_settings = dib8000_fe_get_tune_settings,
2219 .get_frontend = dib8000_get_frontend,
2220
2221 .read_status = dib8000_read_status,
2222 .read_ber = dib8000_read_ber,
2223 .read_signal_strength = dib8000_read_signal_strength,
2224 .read_snr = dib8000_read_snr,
2225 .read_ucblocks = dib8000_read_unc_blocks,
2226};
2227
2228struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2229{
2230 struct dvb_frontend *fe;
2231 struct dib8000_state *state;
2232
2233 dprintk("dib8000_attach");
2234
2235 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2236 if (state == NULL)
2237 return NULL;
2238
2239 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2240 state->i2c.adap = i2c_adap;
2241 state->i2c.addr = i2c_addr;
2242 state->gpio_val = cfg->gpio_val;
2243 state->gpio_dir = cfg->gpio_dir;
2244
2245 /* Ensure the output mode remains at the previous default if it's
2246 * not specifically set by the caller.
2247 */
2248 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2249 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2250
2251 fe = &state->fe;
2252 fe->demodulator_priv = state;
2253 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2254
2255 state->timf_default = cfg->pll->timf;
2256
2257 if (dib8000_identify(&state->i2c) == 0)
2258 goto error;
2259
2260 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2261
2262 dib8000_reset(fe);
2263
2264 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2265
2266 return fe;
2267
2268 error:
2269 kfree(state);
2270 return NULL;
2271}
2272
2273EXPORT_SYMBOL(dib8000_attach);
2274
2275MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2276MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2277MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
new file mode 100644
index 000000000000..a86de340dd54
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -0,0 +1,79 @@
1#ifndef DIB8000_H
2#define DIB8000_H
3
4#include "dibx000_common.h"
5
6struct dib8000_config {
7 u8 output_mpeg2_in_188_bytes;
8 u8 hostbus_diversity;
9 u8 tuner_is_baseband;
10 int (*update_lna) (struct dvb_frontend *, u16 agc_global);
11
12 u8 agc_config_count;
13 struct dibx000_agc_config *agc;
14 struct dibx000_bandwidth_config *pll;
15
16#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
17 u16 gpio_dir;
18#define DIB8000_GPIO_DEFAULT_VALUES 0x0000
19 u16 gpio_val;
20#define DIB8000_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
21#define DIB8000_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
22#define DIB8000_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
23#define DIB8000_GPIO_PWM_POS3(v) (v & 0xf)
24#define DIB8000_GPIO_DEFAULT_PWM_POS 0xffff
25 u16 gpio_pwm_pos;
26 u16 pwm_freq_div;
27
28 void (*agc_control) (struct dvb_frontend *, u8 before);
29
30 u16 drives;
31 u16 diversity_delay;
32 u8 div_cfg;
33 u8 output_mode;
34 u8 refclksel;
35};
36
37#define DEFAULT_DIB8000_I2C_ADDRESS 18
38
39#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
40extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
41extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
42
43extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
44
45extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
46extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
47#else
48static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53
54static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59
60int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63 return -ENODEV;
64}
65
66int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
67{
68 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
69 return -ENODEV;
70}
71
72int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
73{
74 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
75 return -ENODEV;
76}
77#endif
78
79#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 315e09e95b0c..4efca30d2127 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -15,29 +15,31 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
15 (val >> 8) & 0xff, val & 0xff, 15 (val >> 8) & 0xff, val & 0xff,
16 }; 16 };
17 struct i2c_msg msg = { 17 struct i2c_msg msg = {
18 .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4 18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
19 }; 19 };
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21} 21}
22 22
23 23
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) 24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
25 enum dibx000_i2c_interface intf)
25{ 26{
26 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { 27 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
27 dprintk("selecting interface: %d\n",intf); 28 dprintk("selecting interface: %d\n", intf);
28 mst->selected_interface = intf; 29 mst->selected_interface = intf;
29 return dibx000_write_word(mst, mst->base_reg + 4, intf); 30 return dibx000_write_word(mst, mst->base_reg + 4, intf);
30 } 31 }
31 return 0; 32 return 0;
32} 33}
33 34
34static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff) 35static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
36 u8 addr, int onoff)
35{ 37{
36 u16 val; 38 u16 val;
37 39
38 40
39 if (onoff) 41 if (onoff)
40 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open 42 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
41 else 43 else
42 val = 1 << 7; 44 val = 1 << 7;
43 45
@@ -45,7 +47,7 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 ad
45 val <<= 1; 47 val <<= 1;
46 48
47 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff); 49 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
48 tx[1] = ( (mst->base_reg + 1) & 0xff); 50 tx[1] = ((mst->base_reg + 1) & 0xff);
49 tx[2] = val >> 8; 51 tx[2] = val >> 8;
50 tx[3] = val & 0xff; 52 tx[3] = val & 0xff;
51 53
@@ -57,59 +59,78 @@ static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
57 return I2C_FUNC_I2C; 59 return I2C_FUNC_I2C;
58} 60}
59 61
60static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 62static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
63 struct i2c_msg msg[], int num)
61{ 64{
62 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 65 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
63 struct i2c_msg m[2 + num]; 66 struct i2c_msg m[2 + num];
64 u8 tx_open[4], tx_close[4]; 67 u8 tx_open[4], tx_close[4];
65 68
66 memset(m,0, sizeof(struct i2c_msg) * (2 + num)); 69 memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
67 70
68 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); 71 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
69 72
70 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 73 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
71 m[0].addr = mst->i2c_addr; 74 m[0].addr = mst->i2c_addr;
72 m[0].buf = tx_open; 75 m[0].buf = tx_open;
73 m[0].len = 4; 76 m[0].len = 4;
74 77
75 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 78 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
76 79
77 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 80 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
78 m[num+1].addr = mst->i2c_addr; 81 m[num + 1].addr = mst->i2c_addr;
79 m[num+1].buf = tx_close; 82 m[num + 1].buf = tx_close;
80 m[num+1].len = 4; 83 m[num + 1].len = 4;
81 84
82 return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO; 85 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
83} 86}
84 87
85static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { 88static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
86 .master_xfer = dibx000_i2c_gated_tuner_xfer, 89 .master_xfer = dibx000_i2c_gated_tuner_xfer,
87 .functionality = dibx000_i2c_func, 90 .functionality = dibx000_i2c_func,
88}; 91};
89 92
90struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating) 93struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
94 enum dibx000_i2c_interface intf,
95 int gating)
91{ 96{
92 struct i2c_adapter *i2c = NULL; 97 struct i2c_adapter *i2c = NULL;
93 98
94 switch (intf) { 99 switch (intf) {
95 case DIBX000_I2C_INTERFACE_TUNER: 100 case DIBX000_I2C_INTERFACE_TUNER:
96 if (gating) 101 if (gating)
97 i2c = &mst->gated_tuner_i2c_adap; 102 i2c = &mst->gated_tuner_i2c_adap;
98 break; 103 break;
99 default: 104 default:
100 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); 105 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
101 break; 106 break;
102 } 107 }
103 108
104 return i2c; 109 return i2c;
105} 110}
111
106EXPORT_SYMBOL(dibx000_get_i2c_adapter); 112EXPORT_SYMBOL(dibx000_get_i2c_adapter);
107 113
108static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst) 114void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
115{
116 /* initialize the i2c-master by closing the gate */
117 u8 tx[4];
118 struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
119
120 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
121 i2c_transfer(mst->i2c_adap, &m, 1);
122 mst->selected_interface = 0xff; // the first time force a select of the I2C
123 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
124}
125
126EXPORT_SYMBOL(dibx000_reset_i2c_master);
127
128static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
129 struct i2c_algorithm *algo, const char *name,
130 struct dibx000_i2c_master *mst)
109{ 131{
110 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); 132 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
111 i2c_adap->class = I2C_CLASS_TV_DIGITAL, 133 i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
112 i2c_adap->algo = algo;
113 i2c_adap->algo_data = NULL; 134 i2c_adap->algo_data = NULL;
114 i2c_set_adapdata(i2c_adap, mst); 135 i2c_set_adapdata(i2c_adap, mst);
115 if (i2c_add_adapter(i2c_adap) < 0) 136 if (i2c_add_adapter(i2c_adap) < 0)
@@ -117,34 +138,40 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *
117 return 0; 138 return 0;
118} 139}
119 140
120int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr) 141int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
142 struct i2c_adapter *i2c_adap, u8 i2c_addr)
121{ 143{
122 u8 tx[4]; 144 u8 tx[4];
123 struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 }; 145 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
124 146
125 mst->device_rev = device_rev; 147 mst->device_rev = device_rev;
126 mst->i2c_adap = i2c_adap; 148 mst->i2c_adap = i2c_adap;
127 mst->i2c_addr = i2c_addr >> 1; 149 mst->i2c_addr = i2c_addr >> 1;
128 150
129 if (device_rev == DIB7000P) 151 if (device_rev == DIB7000P || device_rev == DIB8000)
130 mst->base_reg = 1024; 152 mst->base_reg = 1024;
131 else 153 else
132 mst->base_reg = 768; 154 mst->base_reg = 768;
133 155
134 if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0) 156 if (i2c_adapter_init
135 printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n"); 157 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
158 "DiBX000 tuner I2C bus", mst) != 0)
159 printk(KERN_ERR
160 "DiBX000: could not initialize the tuner i2c_adapter\n");
136 161
137 /* initialize the i2c-master by closing the gate */ 162 /* initialize the i2c-master by closing the gate */
138 dibx000_i2c_gate_ctrl(mst, tx, 0, 0); 163 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
139 164
140 return i2c_transfer(i2c_adap, &m, 1) == 1; 165 return i2c_transfer(i2c_adap, &m, 1) == 1;
141} 166}
167
142EXPORT_SYMBOL(dibx000_init_i2c_master); 168EXPORT_SYMBOL(dibx000_init_i2c_master);
143 169
144void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) 170void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
145{ 171{
146 i2c_del_adapter(&mst->gated_tuner_i2c_adap); 172 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
147} 173}
174
148EXPORT_SYMBOL(dibx000_exit_i2c_master); 175EXPORT_SYMBOL(dibx000_exit_i2c_master);
149 176
150MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 177MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 84e4d5362922..5be10eca07c0 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -2,7 +2,7 @@
2#define DIBX000_COMMON_H 2#define DIBX000_COMMON_H
3 3
4enum dibx000_i2c_interface { 4enum dibx000_i2c_interface {
5 DIBX000_I2C_INTERFACE_TUNER = 0, 5 DIBX000_I2C_INTERFACE_TUNER = 0,
6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1, 6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2 7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
8}; 8};
@@ -12,22 +12,29 @@ struct dibx000_i2c_master {
12#define DIB7000 2 12#define DIB7000 2
13#define DIB7000P 11 13#define DIB7000P 11
14#define DIB7000MC 12 14#define DIB7000MC 12
15#define DIB8000 13
15 u16 device_rev; 16 u16 device_rev;
16 17
17 enum dibx000_i2c_interface selected_interface; 18 enum dibx000_i2c_interface selected_interface;
18 19
19// struct i2c_adapter tuner_i2c_adap; 20// struct i2c_adapter tuner_i2c_adap;
20 struct i2c_adapter gated_tuner_i2c_adap; 21 struct i2c_adapter gated_tuner_i2c_adap;
21 22
22 struct i2c_adapter *i2c_adap; 23 struct i2c_adapter *i2c_adap;
23 u8 i2c_addr; 24 u8 i2c_addr;
24 25
25 u16 base_reg; 26 u16 base_reg;
26}; 27};
27 28
28extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr); 29extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
29extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating); 30 u16 device_rev, struct i2c_adapter *i2c_adap,
31 u8 i2c_addr);
32extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
33 *mst,
34 enum dibx000_i2c_interface
35 intf, int gating);
30extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); 36extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
37extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
31 38
32#define BAND_LBAND 0x01 39#define BAND_LBAND 0x01
33#define BAND_UHF 0x02 40#define BAND_UHF 0x02
@@ -41,18 +48,18 @@ extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
41 (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) 48 (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
42 49
43struct dibx000_agc_config { 50struct dibx000_agc_config {
44 /* defines the capabilities of this AGC-setting - using the BAND_-defines*/ 51 /* defines the capabilities of this AGC-setting - using the BAND_-defines */
45 u8 band_caps; 52 u8 band_caps;
46 53
47 u16 setup; 54 u16 setup;
48 55
49 u16 inv_gain; 56 u16 inv_gain;
50 u16 time_stabiliz; 57 u16 time_stabiliz;
51 58
52 u8 alpha_level; 59 u8 alpha_level;
53 u16 thlock; 60 u16 thlock;
54 61
55 u8 wbd_inv; 62 u8 wbd_inv;
56 u16 wbd_ref; 63 u16 wbd_ref;
57 u8 wbd_sel; 64 u8 wbd_sel;
58 u8 wbd_alpha; 65 u8 wbd_alpha;
@@ -92,8 +99,8 @@ struct dibx000_agc_config {
92}; 99};
93 100
94struct dibx000_bandwidth_config { 101struct dibx000_bandwidth_config {
95 u32 internal; 102 u32 internal;
96 u32 sampling; 103 u32 sampling;
97 104
98 u8 pll_prediv; 105 u8 pll_prediv;
99 u8 pll_ratio; 106 u8 pll_ratio;
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index eb72a9866c93..e334b5d4e578 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,6 +363,8 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
363 363
364 struct lgdt3304_state *state; 364 struct lgdt3304_state *state;
365 state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); 365 state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
366 if (state == NULL)
367 return NULL;
366 state->addr = config->i2c_address; 368 state->addr = config->i2c_address;
367 state->i2c = i2c; 369 state->i2c = i2c;
368 370
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 3f5a0e1dfdf5..3156b64cfc96 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,6 +169,8 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
169 169
170 struct s921_state *state; 170 struct s921_state *state;
171 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); 171 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
172 if (state == NULL)
173 return NULL;
172 174
173 state->addr = config->i2c_address; 175 state->addr = config->i2c_address;
174 state->i2c = i2c; 176 state->i2c = i2c;
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/dvb/pt1/Kconfig
new file mode 100644
index 000000000000..24501d5bf70d
--- /dev/null
+++ b/drivers/media/dvb/pt1/Kconfig
@@ -0,0 +1,12 @@
1config DVB_PT1
2 tristate "PT1 cards"
3 depends on DVB_CORE && PCI && I2C
4 help
5 Support for Earthsoft PT1 PCI cards.
6
7 Since these cards have no MPEG decoder onboard, they transmit
8 only compressed MPEG data over the PCI bus, so you need
9 an external software decoder to watch TV on your computer.
10
11 Say Y or M if you own such a device and want to use it.
12
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile
new file mode 100644
index 000000000000..a66da17bbe31
--- /dev/null
+++ b/drivers/media/dvb/pt1/Makefile
@@ -0,0 +1,5 @@
1earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
2
3obj-$(CONFIG_DVB_PT1) += earth-pt1.o
4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
new file mode 100644
index 000000000000..8ffbcecad931
--- /dev/null
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -0,0 +1,1056 @@
1/*
2 * driver for Earthsoft PT1
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/kthread.h>
28#include <linux/freezer.h>
29
30#include "dvbdev.h"
31#include "dvb_demux.h"
32#include "dmxdev.h"
33#include "dvb_net.h"
34#include "dvb_frontend.h"
35
36#include "va1j5jf8007t.h"
37#include "va1j5jf8007s.h"
38
39#define DRIVER_NAME "earth-pt1"
40
41#define PT1_PAGE_SHIFT 12
42#define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT)
43#define PT1_NR_UPACKETS 1024
44#define PT1_NR_BUFS 511
45
46struct pt1_buffer_page {
47 __le32 upackets[PT1_NR_UPACKETS];
48};
49
50struct pt1_table_page {
51 __le32 next_pfn;
52 __le32 buf_pfns[PT1_NR_BUFS];
53};
54
55struct pt1_buffer {
56 struct pt1_buffer_page *page;
57 dma_addr_t addr;
58};
59
60struct pt1_table {
61 struct pt1_table_page *page;
62 dma_addr_t addr;
63 struct pt1_buffer bufs[PT1_NR_BUFS];
64};
65
66#define PT1_NR_ADAPS 4
67
68struct pt1_adapter;
69
70struct pt1 {
71 struct pci_dev *pdev;
72 void __iomem *regs;
73 struct i2c_adapter i2c_adap;
74 int i2c_running;
75 struct pt1_adapter *adaps[PT1_NR_ADAPS];
76 struct pt1_table *tables;
77 struct task_struct *kthread;
78};
79
80struct pt1_adapter {
81 struct pt1 *pt1;
82 int index;
83
84 u8 *buf;
85 int upacket_count;
86 int packet_count;
87
88 struct dvb_adapter adap;
89 struct dvb_demux demux;
90 int users;
91 struct dmxdev dmxdev;
92 struct dvb_net net;
93 struct dvb_frontend *fe;
94 int (*orig_set_voltage)(struct dvb_frontend *fe,
95 fe_sec_voltage_t voltage);
96};
97
98#define pt1_printk(level, pt1, format, arg...) \
99 dev_printk(level, &(pt1)->pdev->dev, format, ##arg)
100
101static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
102{
103 writel(data, pt1->regs + reg * 4);
104}
105
106static u32 pt1_read_reg(struct pt1 *pt1, int reg)
107{
108 return readl(pt1->regs + reg * 4);
109}
110
111static int pt1_nr_tables = 64;
112module_param_named(nr_tables, pt1_nr_tables, int, 0);
113
114static void pt1_increment_table_count(struct pt1 *pt1)
115{
116 pt1_write_reg(pt1, 0, 0x00000020);
117}
118
119static void pt1_init_table_count(struct pt1 *pt1)
120{
121 pt1_write_reg(pt1, 0, 0x00000010);
122}
123
124static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn)
125{
126 pt1_write_reg(pt1, 5, first_pfn);
127 pt1_write_reg(pt1, 0, 0x0c000040);
128}
129
130static void pt1_unregister_tables(struct pt1 *pt1)
131{
132 pt1_write_reg(pt1, 0, 0x08080000);
133}
134
135static int pt1_sync(struct pt1 *pt1)
136{
137 int i;
138 for (i = 0; i < 57; i++) {
139 if (pt1_read_reg(pt1, 0) & 0x20000000)
140 return 0;
141 pt1_write_reg(pt1, 0, 0x00000008);
142 }
143 pt1_printk(KERN_ERR, pt1, "could not sync\n");
144 return -EIO;
145}
146
147static u64 pt1_identify(struct pt1 *pt1)
148{
149 int i;
150 u64 id;
151 id = 0;
152 for (i = 0; i < 57; i++) {
153 id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i;
154 pt1_write_reg(pt1, 0, 0x00000008);
155 }
156 return id;
157}
158
159static int pt1_unlock(struct pt1 *pt1)
160{
161 int i;
162 pt1_write_reg(pt1, 0, 0x00000008);
163 for (i = 0; i < 3; i++) {
164 if (pt1_read_reg(pt1, 0) & 0x80000000)
165 return 0;
166 schedule_timeout_uninterruptible((HZ + 999) / 1000);
167 }
168 pt1_printk(KERN_ERR, pt1, "could not unlock\n");
169 return -EIO;
170}
171
172static int pt1_reset_pci(struct pt1 *pt1)
173{
174 int i;
175 pt1_write_reg(pt1, 0, 0x01010000);
176 pt1_write_reg(pt1, 0, 0x01000000);
177 for (i = 0; i < 10; i++) {
178 if (pt1_read_reg(pt1, 0) & 0x00000001)
179 return 0;
180 schedule_timeout_uninterruptible((HZ + 999) / 1000);
181 }
182 pt1_printk(KERN_ERR, pt1, "could not reset PCI\n");
183 return -EIO;
184}
185
186static int pt1_reset_ram(struct pt1 *pt1)
187{
188 int i;
189 pt1_write_reg(pt1, 0, 0x02020000);
190 pt1_write_reg(pt1, 0, 0x02000000);
191 for (i = 0; i < 10; i++) {
192 if (pt1_read_reg(pt1, 0) & 0x00000002)
193 return 0;
194 schedule_timeout_uninterruptible((HZ + 999) / 1000);
195 }
196 pt1_printk(KERN_ERR, pt1, "could not reset RAM\n");
197 return -EIO;
198}
199
200static int pt1_do_enable_ram(struct pt1 *pt1)
201{
202 int i, j;
203 u32 status;
204 status = pt1_read_reg(pt1, 0) & 0x00000004;
205 pt1_write_reg(pt1, 0, 0x00000002);
206 for (i = 0; i < 10; i++) {
207 for (j = 0; j < 1024; j++) {
208 if ((pt1_read_reg(pt1, 0) & 0x00000004) != status)
209 return 0;
210 }
211 schedule_timeout_uninterruptible((HZ + 999) / 1000);
212 }
213 pt1_printk(KERN_ERR, pt1, "could not enable RAM\n");
214 return -EIO;
215}
216
217static int pt1_enable_ram(struct pt1 *pt1)
218{
219 int i, ret;
220 schedule_timeout_uninterruptible((HZ + 999) / 1000);
221 for (i = 0; i < 10; i++) {
222 ret = pt1_do_enable_ram(pt1);
223 if (ret < 0)
224 return ret;
225 }
226 return 0;
227}
228
229static void pt1_disable_ram(struct pt1 *pt1)
230{
231 pt1_write_reg(pt1, 0, 0x0b0b0000);
232}
233
234static void pt1_set_stream(struct pt1 *pt1, int index, int enabled)
235{
236 pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index);
237}
238
239static void pt1_init_streams(struct pt1 *pt1)
240{
241 int i;
242 for (i = 0; i < PT1_NR_ADAPS; i++)
243 pt1_set_stream(pt1, i, 0);
244}
245
246static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
247{
248 u32 upacket;
249 int i;
250 int index;
251 struct pt1_adapter *adap;
252 int offset;
253 u8 *buf;
254
255 if (!page->upackets[PT1_NR_UPACKETS - 1])
256 return 0;
257
258 for (i = 0; i < PT1_NR_UPACKETS; i++) {
259 upacket = le32_to_cpu(page->upackets[i]);
260 index = (upacket >> 29) - 1;
261 if (index < 0 || index >= PT1_NR_ADAPS)
262 continue;
263
264 adap = pt1->adaps[index];
265 if (upacket >> 25 & 1)
266 adap->upacket_count = 0;
267 else if (!adap->upacket_count)
268 continue;
269
270 buf = adap->buf;
271 offset = adap->packet_count * 188 + adap->upacket_count * 3;
272 buf[offset] = upacket >> 16;
273 buf[offset + 1] = upacket >> 8;
274 if (adap->upacket_count != 62)
275 buf[offset + 2] = upacket;
276
277 if (++adap->upacket_count >= 63) {
278 adap->upacket_count = 0;
279 if (++adap->packet_count >= 21) {
280 dvb_dmx_swfilter_packets(&adap->demux, buf, 21);
281 adap->packet_count = 0;
282 }
283 }
284 }
285
286 page->upackets[PT1_NR_UPACKETS - 1] = 0;
287 return 1;
288}
289
290static int pt1_thread(void *data)
291{
292 struct pt1 *pt1;
293 int table_index;
294 int buf_index;
295 struct pt1_buffer_page *page;
296
297 pt1 = data;
298 set_freezable();
299
300 table_index = 0;
301 buf_index = 0;
302
303 while (!kthread_should_stop()) {
304 try_to_freeze();
305
306 page = pt1->tables[table_index].bufs[buf_index].page;
307 if (!pt1_filter(pt1, page)) {
308 schedule_timeout_interruptible((HZ + 999) / 1000);
309 continue;
310 }
311
312 if (++buf_index >= PT1_NR_BUFS) {
313 pt1_increment_table_count(pt1);
314 buf_index = 0;
315 if (++table_index >= pt1_nr_tables)
316 table_index = 0;
317 }
318 }
319
320 return 0;
321}
322
323static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr)
324{
325 dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr);
326}
327
328static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp)
329{
330 void *page;
331 dma_addr_t addr;
332
333 page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr,
334 GFP_KERNEL);
335 if (page == NULL)
336 return NULL;
337
338 BUG_ON(addr & (PT1_PAGE_SIZE - 1));
339 BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1);
340
341 *addrp = addr;
342 *pfnp = addr >> PT1_PAGE_SHIFT;
343 return page;
344}
345
346static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf)
347{
348 pt1_free_page(pt1, buf->page, buf->addr);
349}
350
351static int
352pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf, u32 *pfnp)
353{
354 struct pt1_buffer_page *page;
355 dma_addr_t addr;
356
357 page = pt1_alloc_page(pt1, &addr, pfnp);
358 if (page == NULL)
359 return -ENOMEM;
360
361 page->upackets[PT1_NR_UPACKETS - 1] = 0;
362
363 buf->page = page;
364 buf->addr = addr;
365 return 0;
366}
367
368static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table)
369{
370 int i;
371
372 for (i = 0; i < PT1_NR_BUFS; i++)
373 pt1_cleanup_buffer(pt1, &table->bufs[i]);
374
375 pt1_free_page(pt1, table->page, table->addr);
376}
377
378static int
379pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp)
380{
381 struct pt1_table_page *page;
382 dma_addr_t addr;
383 int i, ret;
384 u32 buf_pfn;
385
386 page = pt1_alloc_page(pt1, &addr, pfnp);
387 if (page == NULL)
388 return -ENOMEM;
389
390 for (i = 0; i < PT1_NR_BUFS; i++) {
391 ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn);
392 if (ret < 0)
393 goto err;
394
395 page->buf_pfns[i] = cpu_to_le32(buf_pfn);
396 }
397
398 pt1_increment_table_count(pt1);
399 table->page = page;
400 table->addr = addr;
401 return 0;
402
403err:
404 while (i--)
405 pt1_cleanup_buffer(pt1, &table->bufs[i]);
406
407 pt1_free_page(pt1, page, addr);
408 return ret;
409}
410
411static void pt1_cleanup_tables(struct pt1 *pt1)
412{
413 struct pt1_table *tables;
414 int i;
415
416 tables = pt1->tables;
417 pt1_unregister_tables(pt1);
418
419 for (i = 0; i < pt1_nr_tables; i++)
420 pt1_cleanup_table(pt1, &tables[i]);
421
422 vfree(tables);
423}
424
425static int pt1_init_tables(struct pt1 *pt1)
426{
427 struct pt1_table *tables;
428 int i, ret;
429 u32 first_pfn, pfn;
430
431 tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
432 if (tables == NULL)
433 return -ENOMEM;
434
435 pt1_init_table_count(pt1);
436
437 i = 0;
438 if (pt1_nr_tables) {
439 ret = pt1_init_table(pt1, &tables[0], &first_pfn);
440 if (ret)
441 goto err;
442 i++;
443 }
444
445 while (i < pt1_nr_tables) {
446 ret = pt1_init_table(pt1, &tables[i], &pfn);
447 if (ret)
448 goto err;
449 tables[i - 1].page->next_pfn = cpu_to_le32(pfn);
450 i++;
451 }
452
453 tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn);
454
455 pt1_register_tables(pt1, first_pfn);
456 pt1->tables = tables;
457 return 0;
458
459err:
460 while (i--)
461 pt1_cleanup_table(pt1, &tables[i]);
462
463 vfree(tables);
464 return ret;
465}
466
467static int pt1_start_feed(struct dvb_demux_feed *feed)
468{
469 struct pt1_adapter *adap;
470 adap = container_of(feed->demux, struct pt1_adapter, demux);
471 if (!adap->users++)
472 pt1_set_stream(adap->pt1, adap->index, 1);
473 return 0;
474}
475
476static int pt1_stop_feed(struct dvb_demux_feed *feed)
477{
478 struct pt1_adapter *adap;
479 adap = container_of(feed->demux, struct pt1_adapter, demux);
480 if (!--adap->users)
481 pt1_set_stream(adap->pt1, adap->index, 0);
482 return 0;
483}
484
485static void
486pt1_set_power(struct pt1 *pt1, int power, int lnb, int reset)
487{
488 pt1_write_reg(pt1, 1, power | lnb << 1 | !reset << 3);
489}
490
491static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
492{
493 struct pt1_adapter *adap;
494 int lnb;
495
496 adap = container_of(fe->dvb, struct pt1_adapter, adap);
497
498 switch (voltage) {
499 case SEC_VOLTAGE_13: /* actually 11V */
500 lnb = 2;
501 break;
502 case SEC_VOLTAGE_18: /* actually 15V */
503 lnb = 3;
504 break;
505 case SEC_VOLTAGE_OFF:
506 lnb = 0;
507 break;
508 default:
509 return -EINVAL;
510 }
511
512 pt1_set_power(adap->pt1, 1, lnb, 0);
513
514 if (adap->orig_set_voltage)
515 return adap->orig_set_voltage(fe, voltage);
516 else
517 return 0;
518}
519
520static void pt1_free_adapter(struct pt1_adapter *adap)
521{
522 dvb_unregister_frontend(adap->fe);
523 dvb_net_release(&adap->net);
524 adap->demux.dmx.close(&adap->demux.dmx);
525 dvb_dmxdev_release(&adap->dmxdev);
526 dvb_dmx_release(&adap->demux);
527 dvb_unregister_adapter(&adap->adap);
528 free_page((unsigned long)adap->buf);
529 kfree(adap);
530}
531
532DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
533
534static struct pt1_adapter *
535pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe)
536{
537 struct pt1_adapter *adap;
538 void *buf;
539 struct dvb_adapter *dvb_adap;
540 struct dvb_demux *demux;
541 struct dmxdev *dmxdev;
542 int ret;
543
544 adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL);
545 if (!adap) {
546 ret = -ENOMEM;
547 goto err;
548 }
549
550 adap->pt1 = pt1;
551
552 adap->orig_set_voltage = fe->ops.set_voltage;
553 fe->ops.set_voltage = pt1_set_voltage;
554
555 buf = (u8 *)__get_free_page(GFP_KERNEL);
556 if (!buf) {
557 ret = -ENOMEM;
558 goto err_kfree;
559 }
560
561 adap->buf = buf;
562 adap->upacket_count = 0;
563 adap->packet_count = 0;
564
565 dvb_adap = &adap->adap;
566 dvb_adap->priv = adap;
567 ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE,
568 &pt1->pdev->dev, adapter_nr);
569 if (ret < 0)
570 goto err_free_page;
571
572 demux = &adap->demux;
573 demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
574 demux->priv = adap;
575 demux->feednum = 256;
576 demux->filternum = 256;
577 demux->start_feed = pt1_start_feed;
578 demux->stop_feed = pt1_stop_feed;
579 demux->write_to_decoder = NULL;
580 ret = dvb_dmx_init(demux);
581 if (ret < 0)
582 goto err_unregister_adapter;
583
584 dmxdev = &adap->dmxdev;
585 dmxdev->filternum = 256;
586 dmxdev->demux = &demux->dmx;
587 dmxdev->capabilities = 0;
588 ret = dvb_dmxdev_init(dmxdev, dvb_adap);
589 if (ret < 0)
590 goto err_dmx_release;
591
592 dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
593
594 ret = dvb_register_frontend(dvb_adap, fe);
595 if (ret < 0)
596 goto err_net_release;
597 adap->fe = fe;
598
599 return adap;
600
601err_net_release:
602 dvb_net_release(&adap->net);
603 adap->demux.dmx.close(&adap->demux.dmx);
604 dvb_dmxdev_release(&adap->dmxdev);
605err_dmx_release:
606 dvb_dmx_release(demux);
607err_unregister_adapter:
608 dvb_unregister_adapter(dvb_adap);
609err_free_page:
610 free_page((unsigned long)buf);
611err_kfree:
612 kfree(adap);
613err:
614 return ERR_PTR(ret);
615}
616
617static void pt1_cleanup_adapters(struct pt1 *pt1)
618{
619 int i;
620 for (i = 0; i < PT1_NR_ADAPS; i++)
621 pt1_free_adapter(pt1->adaps[i]);
622}
623
624struct pt1_config {
625 struct va1j5jf8007s_config va1j5jf8007s_config;
626 struct va1j5jf8007t_config va1j5jf8007t_config;
627};
628
629static const struct pt1_config pt1_configs[2] = {
630 {
631 { .demod_address = 0x1b },
632 { .demod_address = 0x1a },
633 }, {
634 { .demod_address = 0x19 },
635 { .demod_address = 0x18 },
636 },
637};
638
639static int pt1_init_adapters(struct pt1 *pt1)
640{
641 int i, j;
642 struct i2c_adapter *i2c_adap;
643 const struct pt1_config *config;
644 struct dvb_frontend *fe[4];
645 struct pt1_adapter *adap;
646 int ret;
647
648 i = 0;
649 j = 0;
650
651 i2c_adap = &pt1->i2c_adap;
652 do {
653 config = &pt1_configs[i / 2];
654
655 fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
656 i2c_adap);
657 if (!fe[i]) {
658 ret = -ENODEV; /* This does not sound nice... */
659 goto err;
660 }
661 i++;
662
663 fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config,
664 i2c_adap);
665 if (!fe[i]) {
666 ret = -ENODEV;
667 goto err;
668 }
669 i++;
670
671 ret = va1j5jf8007s_prepare(fe[i - 2]);
672 if (ret < 0)
673 goto err;
674
675 ret = va1j5jf8007t_prepare(fe[i - 1]);
676 if (ret < 0)
677 goto err;
678
679 } while (i < 4);
680
681 do {
682 adap = pt1_alloc_adapter(pt1, fe[j]);
683 if (IS_ERR(adap))
684 goto err;
685 adap->index = j;
686 pt1->adaps[j] = adap;
687 } while (++j < 4);
688
689 return 0;
690
691err:
692 while (i-- > j)
693 fe[i]->ops.release(fe[i]);
694
695 while (j--)
696 pt1_free_adapter(pt1->adaps[j]);
697
698 return ret;
699}
700
701static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable,
702 int clock, int data, int next_addr)
703{
704 pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 |
705 !clock << 11 | !data << 10 | next_addr);
706}
707
708static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data)
709{
710 pt1_i2c_emit(pt1, addr, 1, 0, 0, data, addr + 1);
711 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2);
712 pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3);
713 *addrp = addr + 3;
714}
715
716static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp)
717{
718 pt1_i2c_emit(pt1, addr, 1, 0, 0, 1, addr + 1);
719 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2);
720 pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3);
721 pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4);
722 *addrp = addr + 4;
723}
724
725static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data)
726{
727 int i;
728 for (i = 0; i < 8; i++)
729 pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1);
730 pt1_i2c_write_bit(pt1, addr, &addr, 1);
731 *addrp = addr;
732}
733
734static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last)
735{
736 int i;
737 for (i = 0; i < 8; i++)
738 pt1_i2c_read_bit(pt1, addr, &addr);
739 pt1_i2c_write_bit(pt1, addr, &addr, last);
740 *addrp = addr;
741}
742
743static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp)
744{
745 pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1);
746 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
747 pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3);
748 *addrp = addr + 3;
749}
750
751static void
752pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
753{
754 int i;
755 pt1_i2c_prepare(pt1, addr, &addr);
756 pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1);
757 for (i = 0; i < msg->len; i++)
758 pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]);
759 *addrp = addr;
760}
761
762static void
763pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
764{
765 int i;
766 pt1_i2c_prepare(pt1, addr, &addr);
767 pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1);
768 for (i = 0; i < msg->len; i++)
769 pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1);
770 *addrp = addr;
771}
772
773static int pt1_i2c_end(struct pt1 *pt1, int addr)
774{
775 pt1_i2c_emit(pt1, addr, 1, 0, 0, 0, addr + 1);
776 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
777 pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0);
778
779 pt1_write_reg(pt1, 0, 0x00000004);
780 do {
781 if (signal_pending(current))
782 return -EINTR;
783 schedule_timeout_interruptible((HZ + 999) / 1000);
784 } while (pt1_read_reg(pt1, 0) & 0x00000080);
785 return 0;
786}
787
788static void pt1_i2c_begin(struct pt1 *pt1, int *addrp)
789{
790 int addr;
791 addr = 0;
792
793 pt1_i2c_emit(pt1, addr, 0, 0, 1, 1, addr /* itself */);
794 addr = addr + 1;
795
796 if (!pt1->i2c_running) {
797 pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1);
798 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
799 addr = addr + 2;
800 pt1->i2c_running = 1;
801 }
802 *addrp = addr;
803}
804
805static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
806{
807 struct pt1 *pt1;
808 int i;
809 struct i2c_msg *msg, *next_msg;
810 int addr, ret;
811 u16 len;
812 u32 word;
813
814 pt1 = i2c_get_adapdata(adap);
815
816 for (i = 0; i < num; i++) {
817 msg = &msgs[i];
818 if (msg->flags & I2C_M_RD)
819 return -ENOTSUPP;
820
821 if (i + 1 < num)
822 next_msg = &msgs[i + 1];
823 else
824 next_msg = NULL;
825
826 if (next_msg && next_msg->flags & I2C_M_RD) {
827 i++;
828
829 len = next_msg->len;
830 if (len > 4)
831 return -ENOTSUPP;
832
833 pt1_i2c_begin(pt1, &addr);
834 pt1_i2c_write_msg(pt1, addr, &addr, msg);
835 pt1_i2c_read_msg(pt1, addr, &addr, next_msg);
836 ret = pt1_i2c_end(pt1, addr);
837 if (ret < 0)
838 return ret;
839
840 word = pt1_read_reg(pt1, 2);
841 while (len--) {
842 next_msg->buf[len] = word;
843 word >>= 8;
844 }
845 } else {
846 pt1_i2c_begin(pt1, &addr);
847 pt1_i2c_write_msg(pt1, addr, &addr, msg);
848 ret = pt1_i2c_end(pt1, addr);
849 if (ret < 0)
850 return ret;
851 }
852 }
853
854 return num;
855}
856
857static u32 pt1_i2c_func(struct i2c_adapter *adap)
858{
859 return I2C_FUNC_I2C;
860}
861
862static const struct i2c_algorithm pt1_i2c_algo = {
863 .master_xfer = pt1_i2c_xfer,
864 .functionality = pt1_i2c_func,
865};
866
867static void pt1_i2c_wait(struct pt1 *pt1)
868{
869 int i;
870 for (i = 0; i < 128; i++)
871 pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0);
872}
873
874static void pt1_i2c_init(struct pt1 *pt1)
875{
876 int i;
877 for (i = 0; i < 1024; i++)
878 pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
879}
880
881static void __devexit pt1_remove(struct pci_dev *pdev)
882{
883 struct pt1 *pt1;
884 void __iomem *regs;
885
886 pt1 = pci_get_drvdata(pdev);
887 regs = pt1->regs;
888
889 kthread_stop(pt1->kthread);
890 pt1_cleanup_tables(pt1);
891 pt1_cleanup_adapters(pt1);
892 pt1_disable_ram(pt1);
893 pt1_set_power(pt1, 0, 0, 1);
894 i2c_del_adapter(&pt1->i2c_adap);
895 pci_set_drvdata(pdev, NULL);
896 kfree(pt1);
897 pci_iounmap(pdev, regs);
898 pci_release_regions(pdev);
899 pci_disable_device(pdev);
900}
901
902static int __devinit
903pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
904{
905 int ret;
906 void __iomem *regs;
907 struct pt1 *pt1;
908 struct i2c_adapter *i2c_adap;
909 struct task_struct *kthread;
910
911 ret = pci_enable_device(pdev);
912 if (ret < 0)
913 goto err;
914
915 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
916 if (ret < 0)
917 goto err_pci_disable_device;
918
919 pci_set_master(pdev);
920
921 ret = pci_request_regions(pdev, DRIVER_NAME);
922 if (ret < 0)
923 goto err_pci_disable_device;
924
925 regs = pci_iomap(pdev, 0, 0);
926 if (!regs) {
927 ret = -EIO;
928 goto err_pci_release_regions;
929 }
930
931 pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL);
932 if (!pt1) {
933 ret = -ENOMEM;
934 goto err_pci_iounmap;
935 }
936
937 pt1->pdev = pdev;
938 pt1->regs = regs;
939 pci_set_drvdata(pdev, pt1);
940
941 i2c_adap = &pt1->i2c_adap;
942 i2c_adap->class = I2C_CLASS_TV_DIGITAL;
943 i2c_adap->algo = &pt1_i2c_algo;
944 i2c_adap->algo_data = NULL;
945 i2c_adap->dev.parent = &pdev->dev;
946 i2c_set_adapdata(i2c_adap, pt1);
947 ret = i2c_add_adapter(i2c_adap);
948 if (ret < 0)
949 goto err_kfree;
950
951 pt1_set_power(pt1, 0, 0, 1);
952
953 pt1_i2c_init(pt1);
954 pt1_i2c_wait(pt1);
955
956 ret = pt1_sync(pt1);
957 if (ret < 0)
958 goto err_i2c_del_adapter;
959
960 pt1_identify(pt1);
961
962 ret = pt1_unlock(pt1);
963 if (ret < 0)
964 goto err_i2c_del_adapter;
965
966 ret = pt1_reset_pci(pt1);
967 if (ret < 0)
968 goto err_i2c_del_adapter;
969
970 ret = pt1_reset_ram(pt1);
971 if (ret < 0)
972 goto err_i2c_del_adapter;
973
974 ret = pt1_enable_ram(pt1);
975 if (ret < 0)
976 goto err_i2c_del_adapter;
977
978 pt1_init_streams(pt1);
979
980 pt1_set_power(pt1, 1, 0, 1);
981 schedule_timeout_uninterruptible((HZ + 49) / 50);
982
983 pt1_set_power(pt1, 1, 0, 0);
984 schedule_timeout_uninterruptible((HZ + 999) / 1000);
985
986 ret = pt1_init_adapters(pt1);
987 if (ret < 0)
988 goto err_pt1_disable_ram;
989
990 ret = pt1_init_tables(pt1);
991 if (ret < 0)
992 goto err_pt1_cleanup_adapters;
993
994 kthread = kthread_run(pt1_thread, pt1, "pt1");
995 if (IS_ERR(kthread)) {
996 ret = PTR_ERR(kthread);
997 goto err_pt1_cleanup_tables;
998 }
999
1000 pt1->kthread = kthread;
1001 return 0;
1002
1003err_pt1_cleanup_tables:
1004 pt1_cleanup_tables(pt1);
1005err_pt1_cleanup_adapters:
1006 pt1_cleanup_adapters(pt1);
1007err_pt1_disable_ram:
1008 pt1_disable_ram(pt1);
1009 pt1_set_power(pt1, 0, 0, 1);
1010err_i2c_del_adapter:
1011 i2c_del_adapter(i2c_adap);
1012err_kfree:
1013 pci_set_drvdata(pdev, NULL);
1014 kfree(pt1);
1015err_pci_iounmap:
1016 pci_iounmap(pdev, regs);
1017err_pci_release_regions:
1018 pci_release_regions(pdev);
1019err_pci_disable_device:
1020 pci_disable_device(pdev);
1021err:
1022 return ret;
1023
1024}
1025
1026static struct pci_device_id pt1_id_table[] = {
1027 { PCI_DEVICE(0x10ee, 0x211a) },
1028 { },
1029};
1030MODULE_DEVICE_TABLE(pci, pt1_id_table);
1031
1032static struct pci_driver pt1_driver = {
1033 .name = DRIVER_NAME,
1034 .probe = pt1_probe,
1035 .remove = __devexit_p(pt1_remove),
1036 .id_table = pt1_id_table,
1037};
1038
1039
1040static int __init pt1_init(void)
1041{
1042 return pci_register_driver(&pt1_driver);
1043}
1044
1045
1046static void __exit pt1_cleanup(void)
1047{
1048 pci_unregister_driver(&pt1_driver);
1049}
1050
1051module_init(pt1_init);
1052module_exit(pt1_cleanup);
1053
1054MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
1055MODULE_DESCRIPTION("Earthsoft PT1 Driver");
1056MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
new file mode 100644
index 000000000000..2db940f8635f
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -0,0 +1,658 @@
1/*
2 * ISDB-S driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29#include "va1j5jf8007s.h"
30
31enum va1j5jf8007s_tune_state {
32 VA1J5JF8007S_IDLE,
33 VA1J5JF8007S_SET_FREQUENCY_1,
34 VA1J5JF8007S_SET_FREQUENCY_2,
35 VA1J5JF8007S_SET_FREQUENCY_3,
36 VA1J5JF8007S_CHECK_FREQUENCY,
37 VA1J5JF8007S_SET_MODULATION,
38 VA1J5JF8007S_CHECK_MODULATION,
39 VA1J5JF8007S_SET_TS_ID,
40 VA1J5JF8007S_CHECK_TS_ID,
41 VA1J5JF8007S_TRACK,
42};
43
44struct va1j5jf8007s_state {
45 const struct va1j5jf8007s_config *config;
46 struct i2c_adapter *adap;
47 struct dvb_frontend fe;
48 enum va1j5jf8007s_tune_state tune_state;
49};
50
51static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
52{
53 return DVBFE_ALGO_HW;
54}
55
56static int
57va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
58{
59 struct va1j5jf8007s_state *state;
60
61 state = fe->demodulator_priv;
62
63 switch (state->tune_state) {
64 case VA1J5JF8007S_IDLE:
65 case VA1J5JF8007S_SET_FREQUENCY_1:
66 case VA1J5JF8007S_SET_FREQUENCY_2:
67 case VA1J5JF8007S_SET_FREQUENCY_3:
68 case VA1J5JF8007S_CHECK_FREQUENCY:
69 *status = 0;
70 return 0;
71
72
73 case VA1J5JF8007S_SET_MODULATION:
74 case VA1J5JF8007S_CHECK_MODULATION:
75 *status |= FE_HAS_SIGNAL;
76 return 0;
77
78 case VA1J5JF8007S_SET_TS_ID:
79 case VA1J5JF8007S_CHECK_TS_ID:
80 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
81 return 0;
82
83 case VA1J5JF8007S_TRACK:
84 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
85 return 0;
86 }
87
88 BUG();
89}
90
91struct va1j5jf8007s_cb_map {
92 u32 frequency;
93 u8 cb;
94};
95
96static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
97 { 986000, 0xb2 },
98 { 1072000, 0xd2 },
99 { 1154000, 0xe2 },
100 { 1291000, 0x20 },
101 { 1447000, 0x40 },
102 { 1615000, 0x60 },
103 { 1791000, 0x80 },
104 { 1972000, 0xa0 },
105};
106
107static u8 va1j5jf8007s_lookup_cb(u32 frequency)
108{
109 int i;
110 const struct va1j5jf8007s_cb_map *map;
111
112 for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
113 map = &va1j5jf8007s_cb_maps[i];
114 if (frequency < map->frequency)
115 return map->cb;
116 }
117 return 0xc0;
118}
119
120static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
121{
122 u32 frequency;
123 u16 word;
124 u8 buf[6];
125 struct i2c_msg msg;
126
127 frequency = state->fe.dtv_property_cache.frequency;
128
129 word = (frequency + 500) / 1000;
130 if (frequency < 1072000)
131 word = (word << 1 & ~0x1f) | (word & 0x0f);
132
133 buf[0] = 0xfe;
134 buf[1] = 0xc0;
135 buf[2] = 0x40 | word >> 8;
136 buf[3] = word;
137 buf[4] = 0xe0;
138 buf[5] = va1j5jf8007s_lookup_cb(frequency);
139
140 msg.addr = state->config->demod_address;
141 msg.flags = 0;
142 msg.len = sizeof(buf);
143 msg.buf = buf;
144
145 if (i2c_transfer(state->adap, &msg, 1) != 1)
146 return -EREMOTEIO;
147
148 return 0;
149}
150
151static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
152{
153 u8 buf[3];
154 struct i2c_msg msg;
155
156 buf[0] = 0xfe;
157 buf[1] = 0xc0;
158 buf[2] = 0xe4;
159
160 msg.addr = state->config->demod_address;
161 msg.flags = 0;
162 msg.len = sizeof(buf);
163 msg.buf = buf;
164
165 if (i2c_transfer(state->adap, &msg, 1) != 1)
166 return -EREMOTEIO;
167
168 return 0;
169}
170
171static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
172{
173 u32 frequency;
174 u8 buf[4];
175 struct i2c_msg msg;
176
177 frequency = state->fe.dtv_property_cache.frequency;
178
179 buf[0] = 0xfe;
180 buf[1] = 0xc0;
181 buf[2] = 0xf4;
182 buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
183
184 msg.addr = state->config->demod_address;
185 msg.flags = 0;
186 msg.len = sizeof(buf);
187 msg.buf = buf;
188
189 if (i2c_transfer(state->adap, &msg, 1) != 1)
190 return -EREMOTEIO;
191
192 return 0;
193}
194
195static int
196va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
197{
198 u8 addr;
199 u8 write_buf[2], read_buf[1];
200 struct i2c_msg msgs[2];
201
202 addr = state->config->demod_address;
203
204 write_buf[0] = 0xfe;
205 write_buf[1] = 0xc1;
206
207 msgs[0].addr = addr;
208 msgs[0].flags = 0;
209 msgs[0].len = sizeof(write_buf);
210 msgs[0].buf = write_buf;
211
212 msgs[1].addr = addr;
213 msgs[1].flags = I2C_M_RD;
214 msgs[1].len = sizeof(read_buf);
215 msgs[1].buf = read_buf;
216
217 if (i2c_transfer(state->adap, msgs, 2) != 2)
218 return -EREMOTEIO;
219
220 *lock = read_buf[0] & 0x40;
221 return 0;
222}
223
224static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
225{
226 u8 buf[2];
227 struct i2c_msg msg;
228
229 buf[0] = 0x03;
230 buf[1] = 0x01;
231
232 msg.addr = state->config->demod_address;
233 msg.flags = 0;
234 msg.len = sizeof(buf);
235 msg.buf = buf;
236
237 if (i2c_transfer(state->adap, &msg, 1) != 1)
238 return -EREMOTEIO;
239
240 return 0;
241}
242
243static int
244va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
245{
246 u8 addr;
247 u8 write_buf[1], read_buf[1];
248 struct i2c_msg msgs[2];
249
250 addr = state->config->demod_address;
251
252 write_buf[0] = 0xc3;
253
254 msgs[0].addr = addr;
255 msgs[0].flags = 0;
256 msgs[0].len = sizeof(write_buf);
257 msgs[0].buf = write_buf;
258
259 msgs[1].addr = addr;
260 msgs[1].flags = I2C_M_RD;
261 msgs[1].len = sizeof(read_buf);
262 msgs[1].buf = read_buf;
263
264 if (i2c_transfer(state->adap, msgs, 2) != 2)
265 return -EREMOTEIO;
266
267 *lock = !(read_buf[0] & 0x10);
268 return 0;
269}
270
271static int
272va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
273{
274 u32 ts_id;
275 u8 buf[3];
276 struct i2c_msg msg;
277
278 ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
279 if (!ts_id)
280 return 0;
281
282 buf[0] = 0x8f;
283 buf[1] = ts_id >> 8;
284 buf[2] = ts_id;
285
286 msg.addr = state->config->demod_address;
287 msg.flags = 0;
288 msg.len = sizeof(buf);
289 msg.buf = buf;
290
291 if (i2c_transfer(state->adap, &msg, 1) != 1)
292 return -EREMOTEIO;
293
294 return 0;
295}
296
297static int
298va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
299{
300 u8 addr;
301 u8 write_buf[1], read_buf[2];
302 struct i2c_msg msgs[2];
303 u32 ts_id;
304
305 ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
306 if (!ts_id) {
307 *lock = 1;
308 return 0;
309 }
310
311 addr = state->config->demod_address;
312
313 write_buf[0] = 0xe6;
314
315 msgs[0].addr = addr;
316 msgs[0].flags = 0;
317 msgs[0].len = sizeof(write_buf);
318 msgs[0].buf = write_buf;
319
320 msgs[1].addr = addr;
321 msgs[1].flags = I2C_M_RD;
322 msgs[1].len = sizeof(read_buf);
323 msgs[1].buf = read_buf;
324
325 if (i2c_transfer(state->adap, msgs, 2) != 2)
326 return -EREMOTEIO;
327
328 *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
329 return 0;
330}
331
332static int
333va1j5jf8007s_tune(struct dvb_frontend *fe,
334 struct dvb_frontend_parameters *params,
335 unsigned int mode_flags, unsigned int *delay,
336 fe_status_t *status)
337{
338 struct va1j5jf8007s_state *state;
339 int ret;
340 int lock;
341
342 state = fe->demodulator_priv;
343
344 if (params != NULL)
345 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
346
347 switch (state->tune_state) {
348 case VA1J5JF8007S_IDLE:
349 *delay = 3 * HZ;
350 *status = 0;
351 return 0;
352
353 case VA1J5JF8007S_SET_FREQUENCY_1:
354 ret = va1j5jf8007s_set_frequency_1(state);
355 if (ret < 0)
356 return ret;
357
358 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
359 *delay = 0;
360 *status = 0;
361 return 0;
362
363 case VA1J5JF8007S_SET_FREQUENCY_2:
364 ret = va1j5jf8007s_set_frequency_2(state);
365 if (ret < 0)
366 return ret;
367
368 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
369 *delay = (HZ + 99) / 100;
370 *status = 0;
371 return 0;
372
373 case VA1J5JF8007S_SET_FREQUENCY_3:
374 ret = va1j5jf8007s_set_frequency_3(state);
375 if (ret < 0)
376 return ret;
377
378 state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
379 *delay = 0;
380 *status = 0;
381 return 0;
382
383 case VA1J5JF8007S_CHECK_FREQUENCY:
384 ret = va1j5jf8007s_check_frequency(state, &lock);
385 if (ret < 0)
386 return ret;
387
388 if (!lock) {
389 *delay = (HZ + 999) / 1000;
390 *status = 0;
391 return 0;
392 }
393
394 state->tune_state = VA1J5JF8007S_SET_MODULATION;
395 *delay = 0;
396 *status = FE_HAS_SIGNAL;
397 return 0;
398
399 case VA1J5JF8007S_SET_MODULATION:
400 ret = va1j5jf8007s_set_modulation(state);
401 if (ret < 0)
402 return ret;
403
404 state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
405 *delay = 0;
406 *status = FE_HAS_SIGNAL;
407 return 0;
408
409 case VA1J5JF8007S_CHECK_MODULATION:
410 ret = va1j5jf8007s_check_modulation(state, &lock);
411 if (ret < 0)
412 return ret;
413
414 if (!lock) {
415 *delay = (HZ + 49) / 50;
416 *status = FE_HAS_SIGNAL;
417 return 0;
418 }
419
420 state->tune_state = VA1J5JF8007S_SET_TS_ID;
421 *delay = 0;
422 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
423 return 0;
424
425 case VA1J5JF8007S_SET_TS_ID:
426 ret = va1j5jf8007s_set_ts_id(state);
427 if (ret < 0)
428 return ret;
429
430 state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
431 return 0;
432
433 case VA1J5JF8007S_CHECK_TS_ID:
434 ret = va1j5jf8007s_check_ts_id(state, &lock);
435 if (ret < 0)
436 return ret;
437
438 if (!lock) {
439 *delay = (HZ + 99) / 100;
440 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
441 return 0;
442 }
443
444 state->tune_state = VA1J5JF8007S_TRACK;
445 /* fall through */
446
447 case VA1J5JF8007S_TRACK:
448 *delay = 3 * HZ;
449 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
450 return 0;
451 }
452
453 BUG();
454}
455
456static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
457{
458 u8 buf[4];
459 struct i2c_msg msg;
460
461 buf[0] = 0xfe;
462 buf[1] = 0xc0;
463 buf[2] = 0xf0;
464 buf[3] = 0x04;
465
466 msg.addr = state->config->demod_address;
467 msg.flags = 0;
468 msg.len = sizeof(buf);
469 msg.buf = buf;
470
471 if (i2c_transfer(state->adap, &msg, 1) != 1)
472 return -EREMOTEIO;
473
474 return 0;
475}
476
477static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
478{
479 u8 buf[2];
480 struct i2c_msg msg;
481
482 buf[0] = 0x17;
483 buf[1] = sleep ? 0x01 : 0x00;
484
485 msg.addr = state->config->demod_address;
486 msg.flags = 0;
487 msg.len = sizeof(buf);
488 msg.buf = buf;
489
490 if (i2c_transfer(state->adap, &msg, 1) != 1)
491 return -EREMOTEIO;
492
493 return 0;
494}
495
496static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
497{
498 struct va1j5jf8007s_state *state;
499 int ret;
500
501 state = fe->demodulator_priv;
502
503 ret = va1j5jf8007s_init_frequency(state);
504 if (ret < 0)
505 return ret;
506
507 return va1j5jf8007s_set_sleep(state, 1);
508}
509
510static int va1j5jf8007s_init(struct dvb_frontend *fe)
511{
512 struct va1j5jf8007s_state *state;
513
514 state = fe->demodulator_priv;
515 state->tune_state = VA1J5JF8007S_IDLE;
516
517 return va1j5jf8007s_set_sleep(state, 0);
518}
519
520static void va1j5jf8007s_release(struct dvb_frontend *fe)
521{
522 struct va1j5jf8007s_state *state;
523 state = fe->demodulator_priv;
524 kfree(state);
525}
526
527static struct dvb_frontend_ops va1j5jf8007s_ops = {
528 .info = {
529 .name = "VA1J5JF8007 ISDB-S",
530 .type = FE_QPSK,
531 .frequency_min = 950000,
532 .frequency_max = 2150000,
533 .frequency_stepsize = 1000,
534 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
535 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
536 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
537 },
538
539 .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
540 .read_status = va1j5jf8007s_read_status,
541 .tune = va1j5jf8007s_tune,
542 .sleep = va1j5jf8007s_sleep,
543 .init = va1j5jf8007s_init,
544 .release = va1j5jf8007s_release,
545};
546
547static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
548{
549 u8 addr;
550 u8 write_buf[1], read_buf[1];
551 struct i2c_msg msgs[2];
552
553 addr = state->config->demod_address;
554
555 write_buf[0] = 0x07;
556
557 msgs[0].addr = addr;
558 msgs[0].flags = 0;
559 msgs[0].len = sizeof(write_buf);
560 msgs[0].buf = write_buf;
561
562 msgs[1].addr = addr;
563 msgs[1].flags = I2C_M_RD;
564 msgs[1].len = sizeof(read_buf);
565 msgs[1].buf = read_buf;
566
567 if (i2c_transfer(state->adap, msgs, 2) != 2)
568 return -EREMOTEIO;
569
570 if (read_buf[0] != 0x41)
571 return -EIO;
572
573 return 0;
574}
575
576static const u8 va1j5jf8007s_prepare_bufs[][2] = {
577 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
578 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
579 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
580 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
581};
582
583static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
584{
585 u8 addr;
586 u8 buf[2];
587 struct i2c_msg msg;
588 int i;
589
590 addr = state->config->demod_address;
591
592 msg.addr = addr;
593 msg.flags = 0;
594 msg.len = 2;
595 msg.buf = buf;
596 for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_prepare_bufs); i++) {
597 memcpy(buf, va1j5jf8007s_prepare_bufs[i], sizeof(buf));
598 if (i2c_transfer(state->adap, &msg, 1) != 1)
599 return -EREMOTEIO;
600 }
601
602 return 0;
603}
604
605/* must be called after va1j5jf8007t_attach */
606int va1j5jf8007s_prepare(struct dvb_frontend *fe)
607{
608 struct va1j5jf8007s_state *state;
609 int ret;
610
611 state = fe->demodulator_priv;
612
613 ret = va1j5jf8007s_prepare_1(state);
614 if (ret < 0)
615 return ret;
616
617 ret = va1j5jf8007s_prepare_2(state);
618 if (ret < 0)
619 return ret;
620
621 return va1j5jf8007s_init_frequency(state);
622}
623
624struct dvb_frontend *
625va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
626 struct i2c_adapter *adap)
627{
628 struct va1j5jf8007s_state *state;
629 struct dvb_frontend *fe;
630 u8 buf[2];
631 struct i2c_msg msg;
632
633 state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
634 if (!state)
635 return NULL;
636
637 state->config = config;
638 state->adap = adap;
639
640 fe = &state->fe;
641 memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
642 fe->demodulator_priv = state;
643
644 buf[0] = 0x01;
645 buf[1] = 0x80;
646
647 msg.addr = state->config->demod_address;
648 msg.flags = 0;
649 msg.len = sizeof(buf);
650 msg.buf = buf;
651
652 if (i2c_transfer(state->adap, &msg, 1) != 1) {
653 kfree(state);
654 return NULL;
655 }
656
657 return fe;
658}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h
new file mode 100644
index 000000000000..aa228a816353
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.h
@@ -0,0 +1,40 @@
1/*
2 * ISDB-S driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef VA1J5JF8007S_H
25#define VA1J5JF8007S_H
26
27struct va1j5jf8007s_config {
28 u8 demod_address;
29};
30
31struct i2c_adapter;
32
33struct dvb_frontend *
34va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
35 struct i2c_adapter *adap);
36
37/* must be called after va1j5jf8007t_attach */
38int va1j5jf8007s_prepare(struct dvb_frontend *fe);
39
40#endif
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
new file mode 100644
index 000000000000..71117f4ca7e6
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -0,0 +1,468 @@
1/*
2 * ISDB-T driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29#include "dvb_math.h"
30#include "va1j5jf8007t.h"
31
32enum va1j5jf8007t_tune_state {
33 VA1J5JF8007T_IDLE,
34 VA1J5JF8007T_SET_FREQUENCY,
35 VA1J5JF8007T_CHECK_FREQUENCY,
36 VA1J5JF8007T_SET_MODULATION,
37 VA1J5JF8007T_CHECK_MODULATION,
38 VA1J5JF8007T_TRACK,
39 VA1J5JF8007T_ABORT,
40};
41
42struct va1j5jf8007t_state {
43 const struct va1j5jf8007t_config *config;
44 struct i2c_adapter *adap;
45 struct dvb_frontend fe;
46 enum va1j5jf8007t_tune_state tune_state;
47};
48
49static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
50{
51 return DVBFE_ALGO_HW;
52}
53
54static int
55va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
56{
57 struct va1j5jf8007t_state *state;
58
59 state = fe->demodulator_priv;
60
61 switch (state->tune_state) {
62 case VA1J5JF8007T_IDLE:
63 case VA1J5JF8007T_SET_FREQUENCY:
64 case VA1J5JF8007T_CHECK_FREQUENCY:
65 *status = 0;
66 return 0;
67
68
69 case VA1J5JF8007T_SET_MODULATION:
70 case VA1J5JF8007T_CHECK_MODULATION:
71 case VA1J5JF8007T_ABORT:
72 *status |= FE_HAS_SIGNAL;
73 return 0;
74
75 case VA1J5JF8007T_TRACK:
76 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
77 return 0;
78 }
79
80 BUG();
81}
82
83struct va1j5jf8007t_cb_map {
84 u32 frequency;
85 u8 cb;
86};
87
88static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
89 { 90000000, 0x80 },
90 { 140000000, 0x81 },
91 { 170000000, 0xa1 },
92 { 220000000, 0x62 },
93 { 330000000, 0xa2 },
94 { 402000000, 0xe2 },
95 { 450000000, 0x64 },
96 { 550000000, 0x84 },
97 { 600000000, 0xa4 },
98 { 700000000, 0xc4 },
99};
100
101static u8 va1j5jf8007t_lookup_cb(u32 frequency)
102{
103 int i;
104 const struct va1j5jf8007t_cb_map *map;
105
106 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
107 map = &va1j5jf8007t_cb_maps[i];
108 if (frequency < map->frequency)
109 return map->cb;
110 }
111 return 0xe4;
112}
113
114static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
115{
116 u32 frequency;
117 u16 word;
118 u8 buf[6];
119 struct i2c_msg msg;
120
121 frequency = state->fe.dtv_property_cache.frequency;
122
123 word = (frequency + 71428) / 142857 + 399;
124 buf[0] = 0xfe;
125 buf[1] = 0xc2;
126 buf[2] = word >> 8;
127 buf[3] = word;
128 buf[4] = 0x80;
129 buf[5] = va1j5jf8007t_lookup_cb(frequency);
130
131 msg.addr = state->config->demod_address;
132 msg.flags = 0;
133 msg.len = sizeof(buf);
134 msg.buf = buf;
135
136 if (i2c_transfer(state->adap, &msg, 1) != 1)
137 return -EREMOTEIO;
138
139 return 0;
140}
141
142static int
143va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
144{
145 u8 addr;
146 u8 write_buf[2], read_buf[1];
147 struct i2c_msg msgs[2];
148
149 addr = state->config->demod_address;
150
151 write_buf[0] = 0xfe;
152 write_buf[1] = 0xc3;
153
154 msgs[0].addr = addr;
155 msgs[0].flags = 0;
156 msgs[0].len = sizeof(write_buf);
157 msgs[0].buf = write_buf;
158
159 msgs[1].addr = addr;
160 msgs[1].flags = I2C_M_RD;
161 msgs[1].len = sizeof(read_buf);
162 msgs[1].buf = read_buf;
163
164 if (i2c_transfer(state->adap, msgs, 2) != 2)
165 return -EREMOTEIO;
166
167 *lock = read_buf[0] & 0x40;
168 return 0;
169}
170
171static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
172{
173 u8 buf[2];
174 struct i2c_msg msg;
175
176 buf[0] = 0x01;
177 buf[1] = 0x40;
178
179 msg.addr = state->config->demod_address;
180 msg.flags = 0;
181 msg.len = sizeof(buf);
182 msg.buf = buf;
183
184 if (i2c_transfer(state->adap, &msg, 1) != 1)
185 return -EREMOTEIO;
186
187 return 0;
188}
189
190static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
191 int *lock, int *retry)
192{
193 u8 addr;
194 u8 write_buf[1], read_buf[1];
195 struct i2c_msg msgs[2];
196
197 addr = state->config->demod_address;
198
199 write_buf[0] = 0x80;
200
201 msgs[0].addr = addr;
202 msgs[0].flags = 0;
203 msgs[0].len = sizeof(write_buf);
204 msgs[0].buf = write_buf;
205
206 msgs[1].addr = addr;
207 msgs[1].flags = I2C_M_RD;
208 msgs[1].len = sizeof(read_buf);
209 msgs[1].buf = read_buf;
210
211 if (i2c_transfer(state->adap, msgs, 2) != 2)
212 return -EREMOTEIO;
213
214 *lock = !(read_buf[0] & 0x10);
215 *retry = read_buf[0] & 0x80;
216 return 0;
217}
218
219static int
220va1j5jf8007t_tune(struct dvb_frontend *fe,
221 struct dvb_frontend_parameters *params,
222 unsigned int mode_flags, unsigned int *delay,
223 fe_status_t *status)
224{
225 struct va1j5jf8007t_state *state;
226 int ret;
227 int lock, retry;
228
229 state = fe->demodulator_priv;
230
231 if (params != NULL)
232 state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
233
234 switch (state->tune_state) {
235 case VA1J5JF8007T_IDLE:
236 *delay = 3 * HZ;
237 *status = 0;
238 return 0;
239
240 case VA1J5JF8007T_SET_FREQUENCY:
241 ret = va1j5jf8007t_set_frequency(state);
242 if (ret < 0)
243 return ret;
244
245 state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
246 *delay = 0;
247 *status = 0;
248 return 0;
249
250 case VA1J5JF8007T_CHECK_FREQUENCY:
251 ret = va1j5jf8007t_check_frequency(state, &lock);
252 if (ret < 0)
253 return ret;
254
255 if (!lock) {
256 *delay = (HZ + 999) / 1000;
257 *status = 0;
258 return 0;
259 }
260
261 state->tune_state = VA1J5JF8007T_SET_MODULATION;
262 *delay = 0;
263 *status = FE_HAS_SIGNAL;
264 return 0;
265
266 case VA1J5JF8007T_SET_MODULATION:
267 ret = va1j5jf8007t_set_modulation(state);
268 if (ret < 0)
269 return ret;
270
271 state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
272 *delay = 0;
273 *status = FE_HAS_SIGNAL;
274 return 0;
275
276 case VA1J5JF8007T_CHECK_MODULATION:
277 ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
278 if (ret < 0)
279 return ret;
280
281 if (!lock) {
282 if (!retry) {
283 state->tune_state = VA1J5JF8007T_ABORT;
284 *delay = 3 * HZ;
285 *status = FE_HAS_SIGNAL;
286 return 0;
287 }
288 *delay = (HZ + 999) / 1000;
289 *status = FE_HAS_SIGNAL;
290 return 0;
291 }
292
293 state->tune_state = VA1J5JF8007T_TRACK;
294 /* fall through */
295
296 case VA1J5JF8007T_TRACK:
297 *delay = 3 * HZ;
298 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
299 return 0;
300
301 case VA1J5JF8007T_ABORT:
302 *delay = 3 * HZ;
303 *status = FE_HAS_SIGNAL;
304 return 0;
305 }
306
307 BUG();
308}
309
310static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
311{
312 u8 buf[7];
313 struct i2c_msg msg;
314
315 buf[0] = 0xfe;
316 buf[1] = 0xc2;
317 buf[2] = 0x01;
318 buf[3] = 0x8f;
319 buf[4] = 0xc1;
320 buf[5] = 0x80;
321 buf[6] = 0x80;
322
323 msg.addr = state->config->demod_address;
324 msg.flags = 0;
325 msg.len = sizeof(buf);
326 msg.buf = buf;
327
328 if (i2c_transfer(state->adap, &msg, 1) != 1)
329 return -EREMOTEIO;
330
331 return 0;
332}
333
334static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
335{
336 u8 buf[2];
337 struct i2c_msg msg;
338
339 buf[0] = 0x03;
340 buf[1] = sleep ? 0x90 : 0x80;
341
342 msg.addr = state->config->demod_address;
343 msg.flags = 0;
344 msg.len = sizeof(buf);
345 msg.buf = buf;
346
347 if (i2c_transfer(state->adap, &msg, 1) != 1)
348 return -EREMOTEIO;
349
350 return 0;
351}
352
353static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
354{
355 struct va1j5jf8007t_state *state;
356 int ret;
357
358 state = fe->demodulator_priv;
359
360 ret = va1j5jf8007t_init_frequency(state);
361 if (ret < 0)
362 return ret;
363
364 return va1j5jf8007t_set_sleep(state, 1);
365}
366
367static int va1j5jf8007t_init(struct dvb_frontend *fe)
368{
369 struct va1j5jf8007t_state *state;
370
371 state = fe->demodulator_priv;
372 state->tune_state = VA1J5JF8007T_IDLE;
373
374 return va1j5jf8007t_set_sleep(state, 0);
375}
376
377static void va1j5jf8007t_release(struct dvb_frontend *fe)
378{
379 struct va1j5jf8007t_state *state;
380 state = fe->demodulator_priv;
381 kfree(state);
382}
383
384static struct dvb_frontend_ops va1j5jf8007t_ops = {
385 .info = {
386 .name = "VA1J5JF8007 ISDB-T",
387 .type = FE_OFDM,
388 .frequency_min = 90000000,
389 .frequency_max = 770000000,
390 .frequency_stepsize = 142857,
391 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
392 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
393 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
394 },
395
396 .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
397 .read_status = va1j5jf8007t_read_status,
398 .tune = va1j5jf8007t_tune,
399 .sleep = va1j5jf8007t_sleep,
400 .init = va1j5jf8007t_init,
401 .release = va1j5jf8007t_release,
402};
403
404static const u8 va1j5jf8007t_prepare_bufs[][2] = {
405 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
406 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
407 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
408 {0xef, 0x01}
409};
410
411int va1j5jf8007t_prepare(struct dvb_frontend *fe)
412{
413 struct va1j5jf8007t_state *state;
414 u8 buf[2];
415 struct i2c_msg msg;
416 int i;
417
418 state = fe->demodulator_priv;
419
420 msg.addr = state->config->demod_address;
421 msg.flags = 0;
422 msg.len = sizeof(buf);
423 msg.buf = buf;
424
425 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) {
426 memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf));
427 if (i2c_transfer(state->adap, &msg, 1) != 1)
428 return -EREMOTEIO;
429 }
430
431 return va1j5jf8007t_init_frequency(state);
432}
433
434struct dvb_frontend *
435va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
436 struct i2c_adapter *adap)
437{
438 struct va1j5jf8007t_state *state;
439 struct dvb_frontend *fe;
440 u8 buf[2];
441 struct i2c_msg msg;
442
443 state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
444 if (!state)
445 return NULL;
446
447 state->config = config;
448 state->adap = adap;
449
450 fe = &state->fe;
451 memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
452 fe->demodulator_priv = state;
453
454 buf[0] = 0x01;
455 buf[1] = 0x80;
456
457 msg.addr = state->config->demod_address;
458 msg.flags = 0;
459 msg.len = sizeof(buf);
460 msg.buf = buf;
461
462 if (i2c_transfer(state->adap, &msg, 1) != 1) {
463 kfree(state);
464 return NULL;
465 }
466
467 return fe;
468}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h
new file mode 100644
index 000000000000..ed49906f7769
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.h
@@ -0,0 +1,40 @@
1/*
2 * ISDB-T driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef VA1J5JF8007T_H
25#define VA1J5JF8007T_H
26
27struct va1j5jf8007t_config {
28 u8 demod_address;
29};
30
31struct i2c_adapter;
32
33struct dvb_frontend *
34va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
35 struct i2c_adapter *adap);
36
37/* must be called after va1j5jf8007s_attach */
38int va1j5jf8007t_prepare(struct dvb_frontend *fe);
39
40#endif
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 25a36ad60c5e..a87a477c87f2 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -346,7 +346,7 @@ config RADIO_SI4713
346 ---help--- 346 ---help---
347 Say Y here if you want support to Si4713 FM Radio Transmitter. 347 Say Y here if you want support to Si4713 FM Radio Transmitter.
348 This device can transmit audio through FM. It can transmit 348 This device can transmit audio through FM. It can transmit
349 EDS and EBDS signals as well. This module is the v4l2 radio 349 RDS and RBDS signals as well. This module is the v4l2 radio
350 interface for the i2c driver of this device. 350 interface for the i2c driver of this device.
351 351
352 To compile this driver as a module, choose M here: the 352 To compile this driver as a module, choose M here: the
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 65c14b704586..170bbe554787 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -24,7 +24,6 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/version.h>
28#include <linux/platform_device.h> 27#include <linux/platform_device.h>
29#include <linux/i2c.h> 28#include <linux/i2c.h>
30#include <linux/videodev2.h> 29#include <linux/videodev2.h>
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 1d758525d236..e6186b338a12 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -265,6 +265,15 @@ config VIDEO_SAA6588
265 265
266comment "Video decoders" 266comment "Video decoders"
267 267
268config VIDEO_ADV7180
269 tristate "Analog Devices ADV7180 decoder"
270 depends on VIDEO_V4L2 && I2C
271 ---help---
272 Support for the Analog Devices ADV7180 video decoder.
273
274 To compile this driver as a module, choose M here: the
275 module will be called adv7180.
276
268config VIDEO_BT819 277config VIDEO_BT819
269 tristate "BT819A VideoStream decoder" 278 tristate "BT819A VideoStream decoder"
270 depends on VIDEO_V4L2 && I2C 279 depends on VIDEO_V4L2 && I2C
@@ -493,6 +502,39 @@ config VIDEO_UPD64083
493 502
494endmenu # encoder / decoder chips 503endmenu # encoder / decoder chips
495 504
505config DISPLAY_DAVINCI_DM646X_EVM
506 tristate "DM646x EVM Video Display"
507 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
508 select VIDEOBUF_DMA_CONTIG
509 select VIDEO_DAVINCI_VPIF
510 select VIDEO_ADV7343
511 select VIDEO_THS7303
512 help
513 Support for DM6467 based display device.
514
515 To compile this driver as a module, choose M here: the
516 module will be called vpif_display.
517
518config CAPTURE_DAVINCI_DM646X_EVM
519 tristate "DM646x EVM Video Capture"
520 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
521 select VIDEOBUF_DMA_CONTIG
522 select VIDEO_DAVINCI_VPIF
523 help
524 Support for DM6467 based capture device.
525
526 To compile this driver as a module, choose M here: the
527 module will be called vpif_capture.
528
529config VIDEO_DAVINCI_VPIF
530 tristate "DaVinci VPIF Driver"
531 depends on DISPLAY_DAVINCI_DM646X_EVM
532 help
533 Support for DaVinci VPIF Driver.
534
535 To compile this driver as a module, choose M here: the
536 module will be called vpif.
537
496config VIDEO_VIVI 538config VIDEO_VIVI
497 tristate "Virtual Video Driver" 539 tristate "Virtual Video Driver"
498 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 540 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
@@ -505,6 +547,55 @@ config VIDEO_VIVI
505 Say Y here if you want to test video apps or debug V4L devices. 547 Say Y here if you want to test video apps or debug V4L devices.
506 In doubt, say N. 548 In doubt, say N.
507 549
550config VIDEO_VPSS_SYSTEM
551 tristate "VPSS System module driver"
552 depends on ARCH_DAVINCI
553 help
554 Support for vpss system module for video driver
555 default y
556
557config VIDEO_VPFE_CAPTURE
558 tristate "VPFE Video Capture Driver"
559 depends on VIDEO_V4L2 && ARCH_DAVINCI
560 select VIDEOBUF_DMA_CONTIG
561 help
562 Support for DMXXXX VPFE based frame grabber. This is the
563 common V4L2 module for following DMXXX SoCs from Texas
564 Instruments:- DM6446 & DM355.
565
566 To compile this driver as a module, choose M here: the
567 module will be called vpfe-capture.
568
569config VIDEO_DM6446_CCDC
570 tristate "DM6446 CCDC HW module"
571 depends on ARCH_DAVINCI_DM644x && VIDEO_VPFE_CAPTURE
572 select VIDEO_VPSS_SYSTEM
573 default y
574 help
575 Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
576 with decoder modules such as TVP5146 over BT656 or
577 sensor module such as MT9T001 over a raw interface. This
578 module configures the interface and CCDC/ISIF to do
579 video frame capture from slave decoders.
580
581 To compile this driver as a module, choose M here: the
582 module will be called vpfe.
583
584config VIDEO_DM355_CCDC
585 tristate "DM355 CCDC HW module"
586 depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
587 select VIDEO_VPSS_SYSTEM
588 default y
589 help
590 Enables DM355 CCD hw module. DM355 CCDC hw interfaces
591 with decoder modules such as TVP5146 over BT656 or
592 sensor module such as MT9T001 over a raw interface. This
593 module configures the interface and CCDC/ISIF to do
594 video frame capture from a slave decoders
595
596 To compile this driver as a module, choose M here: the
597 module will be called vpfe.
598
508source "drivers/media/video/bt8xx/Kconfig" 599source "drivers/media/video/bt8xx/Kconfig"
509 600
510config VIDEO_PMS 601config VIDEO_PMS
@@ -690,6 +781,8 @@ source "drivers/media/video/ivtv/Kconfig"
690 781
691source "drivers/media/video/cx18/Kconfig" 782source "drivers/media/video/cx18/Kconfig"
692 783
784source "drivers/media/video/saa7164/Kconfig"
785
693config VIDEO_M32R_AR 786config VIDEO_M32R_AR
694 tristate "AR devices" 787 tristate "AR devices"
695 depends on M32R && VIDEO_V4L1 788 depends on M32R && VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 9f2e3214a482..e541932a789b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
45obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o 45obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
46obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 46obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
47obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 47obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
48obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
48obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o 49obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
49obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o 50obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
50obj-$(CONFIG_VIDEO_BT819) += bt819.o 51obj-$(CONFIG_VIDEO_BT819) += bt819.o
@@ -154,12 +155,17 @@ obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
154obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 155obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
155obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 156obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
156 157
158obj-$(CONFIG_ARCH_DAVINCI) += davinci/
159
157obj-$(CONFIG_VIDEO_AU0828) += au0828/ 160obj-$(CONFIG_VIDEO_AU0828) += au0828/
158 161
159obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ 162obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
163obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
160 164
161obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o 165obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
162 166
167obj-$(CONFIG_ARCH_DAVINCI) += davinci/
168
163EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 169EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
164EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 170EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
165EXTRA_CFLAGS += -Idrivers/media/common/tuners 171EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
new file mode 100644
index 000000000000..1b3cbd02a7fd
--- /dev/null
+++ b/drivers/media/video/adv7180.c
@@ -0,0 +1,202 @@
1/*
2 * adv7180.c Analog Devices ADV7180 video decoder driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/i2c.h>
25#include <linux/i2c-id.h>
26#include <media/v4l2-ioctl.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-chip-ident.h>
30
31#define DRIVER_NAME "adv7180"
32
33#define ADV7180_INPUT_CONTROL_REG 0x00
34#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM 0x00
35#define ADV7180_AUTODETECT_ENABLE_REG 0x07
36#define ADV7180_AUTODETECT_DEFAULT 0x7f
37
38
39#define ADV7180_STATUS1_REG 0x10
40#define ADV7180_STATUS1_AUTOD_MASK 0x70
41#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
42#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
43#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
44#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
45#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
46#define ADV7180_STATUS1_AUTOD_SECAM 0x50
47#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
48#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
49
50#define ADV7180_IDENT_REG 0x11
51#define ADV7180_ID_7180 0x18
52
53
54struct adv7180_state {
55 struct v4l2_subdev sd;
56};
57
58static v4l2_std_id determine_norm(struct i2c_client *client)
59{
60 u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
61
62 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
63 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
64 return V4L2_STD_NTSC_M_JP;
65 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
66 return V4L2_STD_NTSC_443;
67 case ADV7180_STATUS1_AUTOD_PAL_M:
68 return V4L2_STD_PAL_M;
69 case ADV7180_STATUS1_AUTOD_PAL_60:
70 return V4L2_STD_PAL_60;
71 case ADV7180_STATUS1_AUTOD_PAL_B_G:
72 return V4L2_STD_PAL;
73 case ADV7180_STATUS1_AUTOD_SECAM:
74 return V4L2_STD_SECAM;
75 case ADV7180_STATUS1_AUTOD_PAL_COMB:
76 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
77 case ADV7180_STATUS1_AUTOD_SECAM_525:
78 return V4L2_STD_SECAM;
79 default:
80 return V4L2_STD_UNKNOWN;
81 }
82}
83
84static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
85{
86 return container_of(sd, struct adv7180_state, sd);
87}
88
89static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
90{
91 struct i2c_client *client = v4l2_get_subdevdata(sd);
92
93 *std = determine_norm(client);
94 return 0;
95}
96
97static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
98 struct v4l2_dbg_chip_ident *chip)
99{
100 struct i2c_client *client = v4l2_get_subdevdata(sd);
101
102 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
103}
104
105static const struct v4l2_subdev_video_ops adv7180_video_ops = {
106 .querystd = adv7180_querystd,
107};
108
109static const struct v4l2_subdev_core_ops adv7180_core_ops = {
110 .g_chip_ident = adv7180_g_chip_ident,
111};
112
113static const struct v4l2_subdev_ops adv7180_ops = {
114 .core = &adv7180_core_ops,
115 .video = &adv7180_video_ops,
116};
117
118/*
119 * Generic i2c probe
120 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
121 */
122
123static int adv7180_probe(struct i2c_client *client,
124 const struct i2c_device_id *id)
125{
126 struct adv7180_state *state;
127 struct v4l2_subdev *sd;
128 int ret;
129
130 /* Check if the adapter supports the needed features */
131 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
132 return -EIO;
133
134 v4l_info(client, "chip found @ 0x%02x (%s)\n",
135 client->addr << 1, client->adapter->name);
136
137 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
138 if (state == NULL)
139 return -ENOMEM;
140 sd = &state->sd;
141 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
142
143 /* Initialize adv7180 */
144 /* enable autodetection */
145 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
146 ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM);
147 if (ret > 0)
148 ret = i2c_smbus_write_byte_data(client,
149 ADV7180_AUTODETECT_ENABLE_REG,
150 ADV7180_AUTODETECT_DEFAULT);
151 if (ret < 0) {
152 printk(KERN_ERR DRIVER_NAME
153 ": Failed to communicate to chip: %d\n", ret);
154 return ret;
155 }
156
157 return 0;
158}
159
160static int adv7180_remove(struct i2c_client *client)
161{
162 struct v4l2_subdev *sd = i2c_get_clientdata(client);
163
164 v4l2_device_unregister_subdev(sd);
165 kfree(to_state(sd));
166 return 0;
167}
168
169static const struct i2c_device_id adv7180_id[] = {
170 {DRIVER_NAME, 0},
171 {},
172};
173
174MODULE_DEVICE_TABLE(i2c, adv7180_id);
175
176static struct i2c_driver adv7180_driver = {
177 .driver = {
178 .owner = THIS_MODULE,
179 .name = DRIVER_NAME,
180 },
181 .probe = adv7180_probe,
182 .remove = adv7180_remove,
183 .id_table = adv7180_id,
184};
185
186static __init int adv7180_init(void)
187{
188 return i2c_add_driver(&adv7180_driver);
189}
190
191static __exit void adv7180_exit(void)
192{
193 i2c_del_driver(&adv7180_driver);
194}
195
196module_init(adv7180_init);
197module_exit(adv7180_exit);
198
199MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
200MODULE_AUTHOR("Mocean Laboratories");
201MODULE_LICENSE("GPL v2");
202
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 30f5caf5dda5..df26f2fe44eb 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -24,7 +24,6 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/version.h>
28 27
29#include <media/adv7343.h> 28#include <media/adv7343.h>
30#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 830c4a933f63..57dd9195daf5 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
212 be abstracted out if we ever need to support a different 212 be abstracted out if we ever need to support a different
213 demod) */ 213 demod) */
214 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 214 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
215 "au8522", "au8522", 0x8e >> 1); 215 "au8522", "au8522", 0x8e >> 1, NULL);
216 if (sd == NULL) 216 if (sd == NULL)
217 printk(KERN_ERR "analog subdev registration failed\n"); 217 printk(KERN_ERR "analog subdev registration failed\n");
218 } 218 }
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
221 if (dev->board.tuner_type != TUNER_ABSENT) { 221 if (dev->board.tuner_type != TUNER_ABSENT) {
222 /* Load the tuner module, which does the attach */ 222 /* Load the tuner module, which does the attach */
223 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 223 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
224 "tuner", "tuner", dev->board.tuner_addr); 224 "tuner", "tuner", dev->board.tuner_addr, NULL);
225 if (sd == NULL) 225 if (sd == NULL)
226 printk(KERN_ERR "tuner subdev registration fail\n"); 226 printk(KERN_ERR "tuner subdev registration fail\n");
227 227
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index b42251fa96ba..12279f6d9bc4 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3524,8 +3524,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
3524 }; 3524 };
3525 struct v4l2_subdev *sd; 3525 struct v4l2_subdev *sd;
3526 3526
3527 sd = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3527 sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3528 &btv->c.i2c_adap, "saa6588", "saa6588", addrs); 3528 &btv->c.i2c_adap, "saa6588", "saa6588", 0, addrs);
3529 btv->has_saa6588 = (sd != NULL); 3529 btv->has_saa6588 = (sd != NULL);
3530 } 3530 }
3531 3531
@@ -3549,8 +3549,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
3549 I2C_CLIENT_END 3549 I2C_CLIENT_END
3550 }; 3550 };
3551 3551
3552 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3552 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3553 &btv->c.i2c_adap, "msp3400", "msp3400", addrs); 3553 &btv->c.i2c_adap, "msp3400", "msp3400", 0, addrs);
3554 if (btv->sd_msp34xx) 3554 if (btv->sd_msp34xx)
3555 return; 3555 return;
3556 goto no_audio; 3556 goto no_audio;
@@ -3563,16 +3563,16 @@ void __devinit bttv_init_card2(struct bttv *btv)
3563 I2C_CLIENT_END 3563 I2C_CLIENT_END
3564 }; 3564 };
3565 3565
3566 if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3566 if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3567 &btv->c.i2c_adap, "tda7432", "tda7432", addrs)) 3567 &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
3568 return; 3568 return;
3569 goto no_audio; 3569 goto no_audio;
3570 } 3570 }
3571 3571
3572 case 3: { 3572 case 3: {
3573 /* The user specified that we should probe for tvaudio */ 3573 /* The user specified that we should probe for tvaudio */
3574 btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3574 btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3575 &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs()); 3575 &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
3576 if (btv->sd_tvaudio) 3576 if (btv->sd_tvaudio)
3577 return; 3577 return;
3578 goto no_audio; 3578 goto no_audio;
@@ -3591,13 +3591,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
3591 it really is a msp3400, so it will return NULL when the device 3591 it really is a msp3400, so it will return NULL when the device
3592 found is really something else (e.g. a tea6300). */ 3592 found is really something else (e.g. a tea6300). */
3593 if (!bttv_tvcards[btv->c.type].no_msp34xx) { 3593 if (!bttv_tvcards[btv->c.type].no_msp34xx) {
3594 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev, 3594 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3595 &btv->c.i2c_adap, "msp3400", "msp3400", 3595 &btv->c.i2c_adap, "msp3400", "msp3400",
3596 I2C_ADDR_MSP3400 >> 1); 3596 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
3597 } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { 3597 } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
3598 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev, 3598 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3599 &btv->c.i2c_adap, "msp3400", "msp3400", 3599 &btv->c.i2c_adap, "msp3400", "msp3400",
3600 I2C_ADDR_MSP3400_ALT >> 1); 3600 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
3601 } 3601 }
3602 3602
3603 /* If we found a msp34xx, then we're done. */ 3603 /* If we found a msp34xx, then we're done. */
@@ -3611,14 +3611,14 @@ void __devinit bttv_init_card2(struct bttv *btv)
3611 I2C_CLIENT_END 3611 I2C_CLIENT_END
3612 }; 3612 };
3613 3613
3614 if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3614 if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3615 &btv->c.i2c_adap, "tda7432", "tda7432", addrs)) 3615 &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
3616 return; 3616 return;
3617 } 3617 }
3618 3618
3619 /* Now see if we can find one of the tvaudio devices. */ 3619 /* Now see if we can find one of the tvaudio devices. */
3620 btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3620 btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3621 &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs()); 3621 &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
3622 if (btv->sd_tvaudio) 3622 if (btv->sd_tvaudio)
3623 return; 3623 return;
3624 3624
@@ -3641,15 +3641,15 @@ void __devinit bttv_init_tuner(struct bttv *btv)
3641 3641
3642 /* Load tuner module before issuing tuner config call! */ 3642 /* Load tuner module before issuing tuner config call! */
3643 if (bttv_tvcards[btv->c.type].has_radio) 3643 if (bttv_tvcards[btv->c.type].has_radio)
3644 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3644 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3645 &btv->c.i2c_adap, "tuner", "tuner", 3645 &btv->c.i2c_adap, "tuner", "tuner",
3646 v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3646 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
3647 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3647 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3648 &btv->c.i2c_adap, "tuner", "tuner", 3648 &btv->c.i2c_adap, "tuner", "tuner",
3649 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3649 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
3650 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3650 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3651 &btv->c.i2c_adap, "tuner", "tuner", 3651 &btv->c.i2c_adap, "tuner", "tuner",
3652 v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3652 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
3653 3653
3654 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3654 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3655 tun_setup.type = btv->tuner_type; 3655 tun_setup.type = btv->tuner_type;
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 9c149a781294..657c481d255c 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1955,7 +1955,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1955 1955
1956 cam->sensor_addr = 0x42; 1956 cam->sensor_addr = 0x42;
1957 cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter, 1957 cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
1958 "ov7670", "ov7670", cam->sensor_addr); 1958 "ov7670", "ov7670", cam->sensor_addr, NULL);
1959 if (cam->sensor == NULL) { 1959 if (cam->sensor == NULL) {
1960 ret = -ENODEV; 1960 ret = -ENODEV;
1961 goto out_smbus; 1961 goto out_smbus;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index dd0224f328ad..6dd51e27582c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -231,7 +231,7 @@ MODULE_PARM_DESC(enc_pcm_bufs,
231 "Number of encoder PCM buffers\n" 231 "Number of encoder PCM buffers\n"
232 "\t\t\tDefault is computed from other enc_pcm_* parameters"); 232 "\t\t\tDefault is computed from other enc_pcm_* parameters");
233 233
234MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); 234MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card");
235 235
236MODULE_AUTHOR("Hans Verkuil"); 236MODULE_AUTHOR("Hans Verkuil");
237MODULE_DESCRIPTION("CX23418 driver"); 237MODULE_DESCRIPTION("CX23418 driver");
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index da395fef50df..2477461e84d7 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -116,7 +116,7 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
116 /* Our default information for ir-kbd-i2c.c to use */ 116 /* Our default information for ir-kbd-i2c.c to use */
117 switch (hw) { 117 switch (hw) {
118 case CX18_HW_Z8F0811_IR_RX_HAUP: 118 case CX18_HW_Z8F0811_IR_RX_HAUP:
119 info.platform_data = &z8f0811_ir_init_data; 119 info.platform_data = (void *) &z8f0811_ir_init_data;
120 break; 120 break;
121 default: 121 default:
122 break; 122 break;
@@ -139,16 +139,16 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
139 139
140 if (hw == CX18_HW_TUNER) { 140 if (hw == CX18_HW_TUNER) {
141 /* special tuner group handling */ 141 /* special tuner group handling */
142 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 142 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
143 adap, mod, type, cx->card_i2c->radio); 143 adap, mod, type, 0, cx->card_i2c->radio);
144 if (sd != NULL) 144 if (sd != NULL)
145 sd->grp_id = hw; 145 sd->grp_id = hw;
146 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 146 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
147 adap, mod, type, cx->card_i2c->demod); 147 adap, mod, type, 0, cx->card_i2c->demod);
148 if (sd != NULL) 148 if (sd != NULL)
149 sd->grp_id = hw; 149 sd->grp_id = hw;
150 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 150 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
151 adap, mod, type, cx->card_i2c->tv); 151 adap, mod, type, 0, cx->card_i2c->tv);
152 if (sd != NULL) 152 if (sd != NULL)
153 sd->grp_id = hw; 153 sd->grp_id = hw;
154 return sd != NULL ? 0 : -1; 154 return sd != NULL ? 0 : -1;
@@ -162,7 +162,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
162 return -1; 162 return -1;
163 163
164 /* It's an I2C device other than an analog tuner or IR chip */ 164 /* It's an I2C device other than an analog tuner or IR chip */
165 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); 165 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx], NULL);
166 if (sd != NULL) 166 if (sd != NULL)
167 sd->grp_id = hw; 167 sd->grp_id = hw;
168 return sd != NULL ? 0 : -1; 168 return sd != NULL ? 0 : -1;
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 54d248e16d85..7df513a2dba8 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -245,9 +245,9 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
245 video_set_drvdata(s->video_dev, s); 245 video_set_drvdata(s->video_dev, s);
246 246
247 /* Register device. First try the desired minor, then any free one. */ 247 /* Register device. First try the desired minor, then any free one. */
248 ret = video_register_device(s->video_dev, vfl_type, num); 248 ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
249 if (ret < 0) { 249 if (ret < 0) {
250 CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", 250 CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
251 s->name, num); 251 s->name, num);
252 video_device_release(s->video_dev); 252 video_device_release(s->video_dev);
253 s->video_dev = NULL; 253 s->video_dev = NULL;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 63d2239fd324..319c459459e0 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -313,7 +313,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
313 if (dev->board.decoder == CX231XX_AVDECODER) { 313 if (dev->board.decoder == CX231XX_AVDECODER) {
314 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 314 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
315 &dev->i2c_bus[0].i2c_adap, 315 &dev->i2c_bus[0].i2c_adap,
316 "cx25840", "cx25840", 0x88 >> 1); 316 "cx25840", "cx25840", 0x88 >> 1, NULL);
317 if (dev->sd_cx25840 == NULL) 317 if (dev->sd_cx25840 == NULL)
318 cx231xx_info("cx25840 subdev registration failure\n"); 318 cx231xx_info("cx25840 subdev registration failure\n");
319 cx25840_call(dev, core, load_fw); 319 cx25840_call(dev, core, load_fw);
@@ -323,7 +323,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
323 if (dev->board.tuner_type != TUNER_ABSENT) { 323 if (dev->board.tuner_type != TUNER_ABSENT) {
324 dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, 324 dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
325 &dev->i2c_bus[1].i2c_adap, 325 &dev->i2c_bus[1].i2c_adap,
326 "tuner", "tuner", 0xc2 >> 1); 326 "tuner", "tuner", 0xc2 >> 1, NULL);
327 if (dev->sd_tuner == NULL) 327 if (dev->sd_tuner == NULL)
328 cx231xx_info("tuner subdev registration failure\n"); 328 cx231xx_info("tuner subdev registration failure\n");
329 329
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 0316257b7345..c04222ffb286 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -75,7 +75,6 @@ struct netup_ci_state {
75 void *priv; 75 void *priv;
76}; 76};
77 77
78struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
79 78
80int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, 79int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
81 u8 *buf, int len) 80 u8 *buf, int len)
@@ -183,10 +182,11 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
183 if (ret != 0) 182 if (ret != 0)
184 return ret; 183 return ret;
185 184
186 mutex_lock(&gpio_mutex); 185 mutex_lock(&dev->gpio_lock);
187 186
188 /* write addr */ 187 /* write addr */
189 cx_write(MC417_OEN, NETUP_EN_ALL); 188 cx_write(MC417_OEN, NETUP_EN_ALL);
189 msleep(2);
190 cx_write(MC417_RWD, NETUP_CTRL_OFF | 190 cx_write(MC417_RWD, NETUP_CTRL_OFF |
191 NETUP_ADLO | (0xff & addr)); 191 NETUP_ADLO | (0xff & addr));
192 cx_clear(MC417_RWD, NETUP_ADLO); 192 cx_clear(MC417_RWD, NETUP_ADLO);
@@ -194,9 +194,10 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
194 NETUP_ADHI | (0xff & (addr >> 8))); 194 NETUP_ADHI | (0xff & (addr >> 8)));
195 cx_clear(MC417_RWD, NETUP_ADHI); 195 cx_clear(MC417_RWD, NETUP_ADHI);
196 196
197 if (read) /* data in */ 197 if (read) { /* data in */
198 cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); 198 cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
199 else /* data out */ 199 msleep(2);
200 } else /* data out */
200 cx_write(MC417_RWD, NETUP_CTRL_OFF | data); 201 cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
201 202
202 /* choose chip */ 203 /* choose chip */
@@ -206,7 +207,7 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
206 cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR); 207 cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
207 mem = netup_ci_get_mem(dev); 208 mem = netup_ci_get_mem(dev);
208 209
209 mutex_unlock(&gpio_mutex); 210 mutex_unlock(&dev->gpio_lock);
210 211
211 if (!read) 212 if (!read)
212 if (mem < 0) 213 if (mem < 0)
@@ -403,7 +404,6 @@ int netup_ci_init(struct cx23885_tsport *port)
403 switch (port->nr) { 404 switch (port->nr) {
404 case 1: 405 case 1:
405 state->ci_i2c_addr = 0x40; 406 state->ci_i2c_addr = 0x40;
406 mutex_init(&gpio_mutex);
407 break; 407 break;
408 case 2: 408 case 2:
409 state->ci_i2c_addr = 0x41; 409 state->ci_i2c_addr = 0x41;
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 3143d85ef31d..bfdf79f1033c 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -210,6 +210,10 @@ struct cx23885_board cx23885_boards[] = {
210 .portb = CX23885_MPEG_ENCODER, 210 .portb = CX23885_MPEG_ENCODER,
211 .portc = CX23885_MPEG_DVB, 211 .portc = CX23885_MPEG_DVB,
212 }, 212 },
213 [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
214 .name = "Compro VideoMate E800",
215 .portc = CX23885_MPEG_DVB,
216 },
213}; 217};
214const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 218const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
215 219
@@ -341,6 +345,10 @@ struct cx23885_subid cx23885_subids[] = {
341 .subvendor = 0x0070, 345 .subvendor = 0x0070,
342 .subdevice = 0x8541, 346 .subdevice = 0x8541,
343 .card = CX23885_BOARD_HAUPPAUGE_HVR1850, 347 .card = CX23885_BOARD_HAUPPAUGE_HVR1850,
348 }, {
349 .subvendor = 0x1858,
350 .subdevice = 0xe800,
351 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
344 }, 352 },
345}; 353};
346const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 354const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -536,6 +544,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
536 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 544 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
537 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 545 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
538 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 546 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
547 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
539 /* Tuner Reset Command */ 548 /* Tuner Reset Command */
540 bitmask = 0x04; 549 bitmask = 0x04;
541 break; 550 break;
@@ -687,6 +696,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
687 break; 696 break;
688 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 697 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
689 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 698 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
699 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
690 /* GPIO-2 xc3028 tuner reset */ 700 /* GPIO-2 xc3028 tuner reset */
691 701
692 /* The following GPIO's are on the internal AVCore (cx25840) */ 702 /* The following GPIO's are on the internal AVCore (cx25840) */
@@ -911,6 +921,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
911 case CX23885_BOARD_HAUPPAUGE_HVR1255: 921 case CX23885_BOARD_HAUPPAUGE_HVR1255:
912 case CX23885_BOARD_HAUPPAUGE_HVR1210: 922 case CX23885_BOARD_HAUPPAUGE_HVR1210:
913 case CX23885_BOARD_HAUPPAUGE_HVR1850: 923 case CX23885_BOARD_HAUPPAUGE_HVR1850:
924 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
914 default: 925 default:
915 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 926 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
916 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 927 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -927,9 +938,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
927 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 938 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
928 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 939 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
929 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 940 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
941 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
930 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 942 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
931 &dev->i2c_bus[2].i2c_adap, 943 &dev->i2c_bus[2].i2c_adap,
932 "cx25840", "cx25840", 0x88 >> 1); 944 "cx25840", "cx25840", 0x88 >> 1, NULL);
933 v4l2_subdev_call(dev->sd_cx25840, core, load_fw); 945 v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
934 break; 946 break;
935 } 947 }
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 40d438d7234d..c31284ba19dd 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -758,6 +758,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
758 int i; 758 int i;
759 759
760 mutex_init(&dev->lock); 760 mutex_init(&dev->lock);
761 mutex_init(&dev->gpio_lock);
761 762
762 atomic_inc(&dev->refcount); 763 atomic_inc(&dev->refcount);
763 764
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 022fad798fc2..45e13ee66dc7 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -255,15 +255,18 @@ static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
255static struct tda18271_config hauppauge_tda18271_config = { 255static struct tda18271_config hauppauge_tda18271_config = {
256 .std_map = &hauppauge_tda18271_std_map, 256 .std_map = &hauppauge_tda18271_std_map,
257 .gate = TDA18271_GATE_ANALOG, 257 .gate = TDA18271_GATE_ANALOG,
258 .output_opt = TDA18271_OUTPUT_LT_OFF,
258}; 259};
259 260
260static struct tda18271_config hauppauge_hvr1200_tuner_config = { 261static struct tda18271_config hauppauge_hvr1200_tuner_config = {
261 .std_map = &hauppauge_hvr1200_tda18271_std_map, 262 .std_map = &hauppauge_hvr1200_tda18271_std_map,
262 .gate = TDA18271_GATE_ANALOG, 263 .gate = TDA18271_GATE_ANALOG,
264 .output_opt = TDA18271_OUTPUT_LT_OFF,
263}; 265};
264 266
265static struct tda18271_config hauppauge_hvr1210_tuner_config = { 267static struct tda18271_config hauppauge_hvr1210_tuner_config = {
266 .gate = TDA18271_GATE_DIGITAL, 268 .gate = TDA18271_GATE_DIGITAL,
269 .output_opt = TDA18271_OUTPUT_LT_OFF,
267}; 270};
268 271
269static struct tda18271_std_map hauppauge_hvr127x_std_map = { 272static struct tda18271_std_map hauppauge_hvr127x_std_map = {
@@ -275,6 +278,7 @@ static struct tda18271_std_map hauppauge_hvr127x_std_map = {
275 278
276static struct tda18271_config hauppauge_hvr127x_config = { 279static struct tda18271_config hauppauge_hvr127x_config = {
277 .std_map = &hauppauge_hvr127x_std_map, 280 .std_map = &hauppauge_hvr127x_std_map,
281 .output_opt = TDA18271_OUTPUT_LT_OFF,
278}; 282};
279 283
280static struct lgdt3305_config hauppauge_lgdt3305_config = { 284static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -743,6 +747,7 @@ static int dvb_register(struct cx23885_tsport *port)
743 } 747 }
744 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 748 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
745 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 749 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
750 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
746 i2c_bus = &dev->i2c_bus[0]; 751 i2c_bus = &dev->i2c_bus[0];
747 752
748 fe0->dvb.frontend = dvb_attach(zl10353_attach, 753 fe0->dvb.frontend = dvb_attach(zl10353_attach,
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 5d6093336300..654cc253cd50 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1521,11 +1521,11 @@ int cx23885_video_register(struct cx23885_dev *dev)
1521 if (dev->tuner_addr) 1521 if (dev->tuner_addr)
1522 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1522 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1523 &dev->i2c_bus[1].i2c_adap, 1523 &dev->i2c_bus[1].i2c_adap,
1524 "tuner", "tuner", dev->tuner_addr); 1524 "tuner", "tuner", dev->tuner_addr, NULL);
1525 else 1525 else
1526 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 1526 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1527 &dev->i2c_bus[1].i2c_adap, 1527 &dev->i2c_bus[1].i2c_adap,
1528 "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV)); 1528 "tuner", "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
1529 if (sd) { 1529 if (sd) {
1530 struct tuner_setup tun_setup; 1530 struct tuner_setup tun_setup;
1531 1531
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 86f26947bb78..cc7a165561ff 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -78,6 +78,7 @@
78#define CX23885_BOARD_MYGICA_X8506 22 78#define CX23885_BOARD_MYGICA_X8506 22
79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24 80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
81 82
82#define GPIO_0 0x00000001 83#define GPIO_0 0x00000001
83#define GPIO_1 0x00000002 84#define GPIO_1 0x00000002
@@ -325,6 +326,7 @@ struct cx23885_dev {
325 326
326 int nr; 327 int nr;
327 struct mutex lock; 328 struct mutex lock;
329 struct mutex gpio_lock;
328 330
329 /* board details */ 331 /* board details */
330 unsigned int board; 332 unsigned int board;
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
index 042bbbbd48f8..98a48f500684 100644
--- a/drivers/media/video/cx23885/netup-eeprom.c
+++ b/drivers/media/video/cx23885/netup-eeprom.c
@@ -97,11 +97,11 @@ void netup_get_card_info(struct i2c_adapter *i2c_adap,
97{ 97{
98 int i, j; 98 int i, j;
99 99
100 cinfo->rev = netup_eeprom_read(i2c_adap, 13); 100 cinfo->rev = netup_eeprom_read(i2c_adap, 63);
101 101
102 for (i = 0, j = 0; i < 6; i++, j++) 102 for (i = 64, j = 0; i < 70; i++, j++)
103 cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i); 103 cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i);
104 104
105 for (i = 6, j = 0; i < 12; i++, j++) 105 for (i = 70, j = 0; i < 76; i++, j++)
106 cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i); 106 cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i);
107}; 107};
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index e5f07fbd5a35..33be6369871a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -3439,20 +3439,20 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3439 The radio_type is sometimes missing, or set to UNSET but 3439 The radio_type is sometimes missing, or set to UNSET but
3440 later code configures a tea5767. 3440 later code configures a tea5767.
3441 */ 3441 */
3442 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap, 3442 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3443 "tuner", "tuner", 3443 "tuner", "tuner",
3444 v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3444 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
3445 if (has_demod) 3445 if (has_demod)
3446 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, 3446 v4l2_i2c_new_subdev(&core->v4l2_dev,
3447 &core->i2c_adap, "tuner", "tuner", 3447 &core->i2c_adap, "tuner", "tuner",
3448 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3448 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
3449 if (core->board.tuner_addr == ADDR_UNSET) { 3449 if (core->board.tuner_addr == ADDR_UNSET) {
3450 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, 3450 v4l2_i2c_new_subdev(&core->v4l2_dev,
3451 &core->i2c_adap, "tuner", "tuner", 3451 &core->i2c_adap, "tuner", "tuner",
3452 has_demod ? tv_addrs + 4 : tv_addrs); 3452 0, has_demod ? tv_addrs + 4 : tv_addrs);
3453 } else { 3453 } else {
3454 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 3454 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3455 "tuner", "tuner", core->board.tuner_addr); 3455 "tuner", "tuner", core->board.tuner_addr, NULL);
3456 } 3456 }
3457 } 3457 }
3458 3458
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 2bb54c3ef5cd..81d2b5dea18e 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1881,14 +1881,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1881 1881
1882 if (core->board.audio_chip == V4L2_IDENT_WM8775) 1882 if (core->board.audio_chip == V4L2_IDENT_WM8775)
1883 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 1883 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
1884 "wm8775", "wm8775", 0x36 >> 1); 1884 "wm8775", "wm8775", 0x36 >> 1, NULL);
1885 1885
1886 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { 1886 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
1887 /* This probes for a tda9874 as is used on some 1887 /* This probes for a tda9874 as is used on some
1888 Pixelview Ultra boards. */ 1888 Pixelview Ultra boards. */
1889 v4l2_i2c_new_probed_subdev_addr(&core->v4l2_dev, 1889 v4l2_i2c_new_subdev(&core->v4l2_dev,
1890 &core->i2c_adap, 1890 &core->i2c_adap,
1891 "tvaudio", "tvaudio", 0xb0 >> 1); 1891 "tvaudio", "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
1892 } 1892 }
1893 1893
1894 switch (core->boardnr) { 1894 switch (core->boardnr) {
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 0664d111085f..ee43876adb06 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -748,14 +748,14 @@ static const struct file_operations dabusb_fops =
748 .release = dabusb_release, 748 .release = dabusb_release,
749}; 749};
750 750
751static char *dabusb_nodename(struct device *dev) 751static char *dabusb_devnode(struct device *dev, mode_t *mode)
752{ 752{
753 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); 753 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
754} 754}
755 755
756static struct usb_class_driver dabusb_class = { 756static struct usb_class_driver dabusb_class = {
757 .name = "dabusb%d", 757 .name = "dabusb%d",
758 .nodename = dabusb_nodename, 758 .devnode = dabusb_devnode,
759 .fops = &dabusb_fops, 759 .fops = &dabusb_fops,
760 .minor_base = DABUSB_MINOR, 760 .minor_base = DABUSB_MINOR,
761}; 761};
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
new file mode 100644
index 000000000000..1a8b8f3f182e
--- /dev/null
+++ b/drivers/media/video/davinci/Makefile
@@ -0,0 +1,17 @@
1#
2# Makefile for the davinci video device drivers.
3#
4
5# VPIF
6obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
7
8#DM646x EVM Display driver
9obj-$(CONFIG_DISPLAY_DAVINCI_DM646X_EVM) += vpif_display.o
10#DM646x EVM Capture driver
11obj-$(CONFIG_CAPTURE_DAVINCI_DM646X_EVM) += vpif_capture.o
12
13# Capture: DM6446 and DM355
14obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/video/davinci/ccdc_hw_device.h
new file mode 100644
index 000000000000..86b9b3518965
--- /dev/null
+++ b/drivers/media/video/davinci/ccdc_hw_device.h
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * ccdc device API
19 */
20#ifndef _CCDC_HW_DEVICE_H
21#define _CCDC_HW_DEVICE_H
22
23#ifdef __KERNEL__
24#include <linux/videodev2.h>
25#include <linux/device.h>
26#include <media/davinci/vpfe_types.h>
27#include <media/davinci/ccdc_types.h>
28
29/*
30 * ccdc hw operations
31 */
32struct ccdc_hw_ops {
33 /* Pointer to initialize function to initialize ccdc device */
34 int (*open) (struct device *dev);
35 /* Pointer to deinitialize function */
36 int (*close) (struct device *dev);
37 /* set ccdc base address */
38 void (*set_ccdc_base)(void *base, int size);
39 /* Pointer to function to enable or disable ccdc */
40 void (*enable) (int en);
41 /* reset sbl. only for 6446 */
42 void (*reset) (void);
43 /* enable output to sdram */
44 void (*enable_out_to_sdram) (int en);
45 /* Pointer to function to set hw parameters */
46 int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
47 /* get interface parameters */
48 int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
49 /*
50 * Pointer to function to set parameters. Used
51 * for implementing VPFE_S_CCDC_PARAMS
52 */
53 int (*set_params) (void *params);
54 /*
55 * Pointer to function to get parameter. Used
56 * for implementing VPFE_G_CCDC_PARAMS
57 */
58 int (*get_params) (void *params);
59 /* Pointer to function to configure ccdc */
60 int (*configure) (void);
61
62 /* Pointer to function to set buffer type */
63 int (*set_buftype) (enum ccdc_buftype buf_type);
64 /* Pointer to function to get buffer type */
65 enum ccdc_buftype (*get_buftype) (void);
66 /* Pointer to function to set frame format */
67 int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
68 /* Pointer to function to get frame format */
69 enum ccdc_frmfmt (*get_frame_format) (void);
70 /* enumerate hw pix formats */
71 int (*enum_pix)(u32 *hw_pix, int i);
72 /* Pointer to function to set buffer type */
73 u32 (*get_pixel_format) (void);
74 /* Pointer to function to get pixel format. */
75 int (*set_pixel_format) (u32 pixfmt);
76 /* Pointer to function to set image window */
77 int (*set_image_window) (struct v4l2_rect *win);
78 /* Pointer to function to set image window */
79 void (*get_image_window) (struct v4l2_rect *win);
80 /* Pointer to function to get line length */
81 unsigned int (*get_line_length) (void);
82
83 /* Query CCDC control IDs */
84 int (*queryctrl)(struct v4l2_queryctrl *qctrl);
85 /* Set CCDC control */
86 int (*set_control)(struct v4l2_control *ctrl);
87 /* Get CCDC control */
88 int (*get_control)(struct v4l2_control *ctrl);
89
90 /* Pointer to function to set frame buffer address */
91 void (*setfbaddr) (unsigned long addr);
92 /* Pointer to function to get field id */
93 int (*getfid) (void);
94};
95
96struct ccdc_hw_device {
97 /* ccdc device name */
98 char name[32];
99 /* module owner */
100 struct module *owner;
101 /* hw ops */
102 struct ccdc_hw_ops hw_ops;
103};
104
105/* Used by CCDC module to register & unregister with vpfe capture driver */
106int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
107void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
108
109#endif
110#endif
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
new file mode 100644
index 000000000000..4629cabe3f28
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -0,0 +1,978 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM355
19 * ------------------------------
20 *
21 * This module is for configuring DM355 CCD controller of VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application include dm355_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters
30 *
31 * TODO: 1) Raw bayer parameter settings and bayer capture
32 * 2) Split module parameter structure to module specific ioctl structs
33 * 3) add support for lense shading correction
34 * 4) investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <media/davinci/dm355_ccdc.h>
41#include <media/davinci/vpss.h>
42#include "dm355_ccdc_regs.h"
43#include "ccdc_hw_device.h"
44
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM355");
47MODULE_AUTHOR("Texas Instruments");
48
49static struct device *dev;
50
51/* Object for CCDC raw mode */
52static struct ccdc_params_raw ccdc_hw_params_raw = {
53 .pix_fmt = CCDC_PIXFMT_RAW,
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
55 .win = CCDC_WIN_VGA,
56 .fid_pol = VPFE_PINPOL_POSITIVE,
57 .vd_pol = VPFE_PINPOL_POSITIVE,
58 .hd_pol = VPFE_PINPOL_POSITIVE,
59 .gain = {
60 .r_ye = 256,
61 .gb_g = 256,
62 .gr_cy = 256,
63 .b_mg = 256
64 },
65 .config_params = {
66 .datasft = 2,
67 .data_sz = CCDC_DATA_10BITS,
68 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
69 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
70 .alaw = {
71 .gama_wd = 2,
72 },
73 .blk_clamp = {
74 .sample_pixel = 1,
75 .dc_sub = 25
76 },
77 .col_pat_field0 = {
78 .olop = CCDC_GREEN_BLUE,
79 .olep = CCDC_BLUE,
80 .elop = CCDC_RED,
81 .elep = CCDC_GREEN_RED
82 },
83 .col_pat_field1 = {
84 .olop = CCDC_GREEN_BLUE,
85 .olep = CCDC_BLUE,
86 .elop = CCDC_RED,
87 .elep = CCDC_GREEN_RED
88 },
89 },
90};
91
92
93/* Object for CCDC ycbcr mode */
94static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
95 .win = CCDC_WIN_PAL,
96 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
97 .frm_fmt = CCDC_FRMFMT_INTERLACED,
98 .fid_pol = VPFE_PINPOL_POSITIVE,
99 .vd_pol = VPFE_PINPOL_POSITIVE,
100 .hd_pol = VPFE_PINPOL_POSITIVE,
101 .bt656_enable = 1,
102 .pix_order = CCDC_PIXORDER_CBYCRY,
103 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
104};
105
106static enum vpfe_hw_if_type ccdc_if_type;
107static void *__iomem ccdc_base_addr;
108static int ccdc_addr_size;
109
110/* Raw Bayer formats */
111static u32 ccdc_raw_bayer_pix_formats[] =
112 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
113
114/* Raw YUV formats */
115static u32 ccdc_raw_yuv_pix_formats[] =
116 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
117
118/* register access routines */
119static inline u32 regr(u32 offset)
120{
121 return __raw_readl(ccdc_base_addr + offset);
122}
123
124static inline void regw(u32 val, u32 offset)
125{
126 __raw_writel(val, ccdc_base_addr + offset);
127}
128
129static void ccdc_set_ccdc_base(void *addr, int size)
130{
131 ccdc_base_addr = addr;
132 ccdc_addr_size = size;
133}
134
135static void ccdc_enable(int en)
136{
137 unsigned int temp;
138 temp = regr(SYNCEN);
139 temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
140 temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
141 regw(temp, SYNCEN);
142}
143
144static void ccdc_enable_output_to_sdram(int en)
145{
146 unsigned int temp;
147 temp = regr(SYNCEN);
148 temp &= (~(CCDC_SYNCEN_WEN_MASK));
149 temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
150 regw(temp, SYNCEN);
151}
152
153static void ccdc_config_gain_offset(void)
154{
155 /* configure gain */
156 regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN);
157 regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN);
158 regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN);
159 regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN);
160 /* configure offset */
161 regw(ccdc_hw_params_raw.ccdc_offset, OFFSET);
162}
163
164/*
165 * ccdc_restore_defaults()
166 * This function restore power on defaults in the ccdc registers
167 */
168static int ccdc_restore_defaults(void)
169{
170 int i;
171
172 dev_dbg(dev, "\nstarting ccdc_restore_defaults...");
173 /* set all registers to zero */
174 for (i = 0; i <= CCDC_REG_LAST; i += 4)
175 regw(0, i);
176
177 /* now override the values with power on defaults in registers */
178 regw(MODESET_DEFAULT, MODESET);
179 /* no culling support */
180 regw(CULH_DEFAULT, CULH);
181 regw(CULV_DEFAULT, CULV);
182 /* Set default Gain and Offset */
183 ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT;
184 ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT;
185 ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT;
186 ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT;
187 ccdc_config_gain_offset();
188 regw(OUTCLIP_DEFAULT, OUTCLIP);
189 regw(LSCCFG2_DEFAULT, LSCCFG2);
190 /* select ccdc input */
191 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
192 dev_dbg(dev, "\ncouldn't select ccdc input source");
193 return -EFAULT;
194 }
195 /* select ccdc clock */
196 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
197 dev_dbg(dev, "\ncouldn't enable ccdc clock");
198 return -EFAULT;
199 }
200 dev_dbg(dev, "\nEnd of ccdc_restore_defaults...");
201 return 0;
202}
203
204static int ccdc_open(struct device *device)
205{
206 dev = device;
207 return ccdc_restore_defaults();
208}
209
210static int ccdc_close(struct device *device)
211{
212 /* disable clock */
213 vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
214 /* do nothing for now */
215 return 0;
216}
217/*
218 * ccdc_setwin()
219 * This function will configure the window size to
220 * be capture in CCDC reg.
221 */
222static void ccdc_setwin(struct v4l2_rect *image_win,
223 enum ccdc_frmfmt frm_fmt, int ppc)
224{
225 int horz_start, horz_nr_pixels;
226 int vert_start, vert_nr_lines;
227 int mid_img = 0;
228
229 dev_dbg(dev, "\nStarting ccdc_setwin...");
230
231 /*
232 * ppc - per pixel count. indicates how many pixels per cell
233 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
234 * raw capture this is 1
235 */
236 horz_start = image_win->left << (ppc - 1);
237 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
238
239 /* Writing the horizontal info into the registers */
240 regw(horz_start, SPH);
241 regw(horz_nr_pixels, NPH);
242 vert_start = image_win->top;
243
244 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
245 vert_nr_lines = (image_win->height >> 1) - 1;
246 vert_start >>= 1;
247 /* Since first line doesn't have any data */
248 vert_start += 1;
249 /* configure VDINT0 and VDINT1 */
250 regw(vert_start, VDINT0);
251 } else {
252 /* Since first line doesn't have any data */
253 vert_start += 1;
254 vert_nr_lines = image_win->height - 1;
255 /* configure VDINT0 and VDINT1 */
256 mid_img = vert_start + (image_win->height / 2);
257 regw(vert_start, VDINT0);
258 regw(mid_img, VDINT1);
259 }
260 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
261 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
262 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
263 dev_dbg(dev, "\nEnd of ccdc_setwin...");
264}
265
266static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
267{
268 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
269 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
270 dev_dbg(dev, "Invalid value of data shift\n");
271 return -EINVAL;
272 }
273
274 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
275 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
276 dev_dbg(dev, "Invalid value of median filter1\n");
277 return -EINVAL;
278 }
279
280 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
281 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
282 dev_dbg(dev, "Invalid value of median filter2\n");
283 return -EINVAL;
284 }
285
286 if ((ccdcparam->med_filt_thres < 0) ||
287 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
288 dev_dbg(dev, "Invalid value of median filter thresold\n");
289 return -EINVAL;
290 }
291
292 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
293 ccdcparam->data_sz > CCDC_DATA_8BITS) {
294 dev_dbg(dev, "Invalid value of data size\n");
295 return -EINVAL;
296 }
297
298 if (ccdcparam->alaw.enable) {
299 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
300 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
301 dev_dbg(dev, "Invalid value of ALAW\n");
302 return -EINVAL;
303 }
304 }
305
306 if (ccdcparam->blk_clamp.b_clamp_enable) {
307 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
308 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
309 dev_dbg(dev, "Invalid value of sample pixel\n");
310 return -EINVAL;
311 }
312 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
313 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
314 dev_dbg(dev, "Invalid value of sample lines\n");
315 return -EINVAL;
316 }
317 }
318 return 0;
319}
320
321/* Parameter operations */
322static int ccdc_set_params(void __user *params)
323{
324 struct ccdc_config_params_raw ccdc_raw_params;
325 int x;
326
327 /* only raw module parameters can be set through the IOCTL */
328 if (ccdc_if_type != VPFE_RAW_BAYER)
329 return -EINVAL;
330
331 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
332 if (x) {
333 dev_dbg(dev, "ccdc_set_params: error in copying ccdc"
334 "params, %d\n", x);
335 return -EFAULT;
336 }
337
338 if (!validate_ccdc_param(&ccdc_raw_params)) {
339 memcpy(&ccdc_hw_params_raw.config_params,
340 &ccdc_raw_params,
341 sizeof(ccdc_raw_params));
342 return 0;
343 }
344 return -EINVAL;
345}
346
347/* This function will configure CCDC for YCbCr video capture */
348static void ccdc_config_ycbcr(void)
349{
350 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
351 u32 temp;
352
353 /* first set the CCDC power on defaults values in all registers */
354 dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
355 ccdc_restore_defaults();
356
357 /* configure pixel format & video frame format */
358 temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
359 CCDC_INPUT_MODE_SHIFT) |
360 ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
361 CCDC_FRM_FMT_SHIFT));
362
363 /* setup BT.656 sync mode */
364 if (params->bt656_enable) {
365 regw(CCDC_REC656IF_BT656_EN, REC656IF);
366 /*
367 * configure the FID, VD, HD pin polarity fld,hd pol positive,
368 * vd negative, 8-bit pack mode
369 */
370 temp |= CCDC_VD_POL_NEGATIVE;
371 } else { /* y/c external sync mode */
372 temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
373 CCDC_FID_POL_SHIFT) |
374 ((params->hd_pol & CCDC_HD_POL_MASK) <<
375 CCDC_HD_POL_SHIFT) |
376 ((params->vd_pol & CCDC_VD_POL_MASK) <<
377 CCDC_VD_POL_SHIFT));
378 }
379
380 /* pack the data to 8-bit */
381 temp |= CCDC_DATA_PACK_ENABLE;
382
383 regw(temp, MODESET);
384
385 /* configure video window */
386 ccdc_setwin(&params->win, params->frm_fmt, 2);
387
388 /* configure the order of y cb cr in SD-RAM */
389 temp = (params->pix_order << CCDC_Y8POS_SHIFT);
390 temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
391 regw(temp, CCDCFG);
392
393 /*
394 * configure the horizontal line offset. This is done by rounding up
395 * width to a multiple of 16 pixels and multiply by two to account for
396 * y:cb:cr 4:2:2 data
397 */
398 regw(((params->win.width * 2 + 31) >> 5), HSIZE);
399
400 /* configure the memory line offset */
401 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
402 /* two fields are interleaved in memory */
403 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
404 }
405
406 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
407}
408
409/*
410 * ccdc_config_black_clamp()
411 * configure parameters for Optical Black Clamp
412 */
413static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
414{
415 u32 val;
416
417 if (!bclamp->b_clamp_enable) {
418 /* configure DCSub */
419 regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
420 regw(0x0000, CLAMP);
421 return;
422 }
423 /* Enable the Black clamping, set sample lines and pixels */
424 val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
425 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
426 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
427 regw(val, CLAMP);
428
429 /* If Black clamping is enable then make dcsub 0 */
430 val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
431 << CCDC_NUM_LINE_CALC_SHIFT;
432 regw(val, DCSUB);
433}
434
435/*
436 * ccdc_config_black_compense()
437 * configure parameters for Black Compensation
438 */
439static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
440{
441 u32 val;
442
443 val = (bcomp->b & CCDC_BLK_COMP_MASK) |
444 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
445 CCDC_BLK_COMP_GB_COMP_SHIFT);
446 regw(val, BLKCMP1);
447
448 val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
449 CCDC_BLK_COMP_GR_COMP_SHIFT) |
450 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
451 CCDC_BLK_COMP_R_COMP_SHIFT);
452 regw(val, BLKCMP0);
453}
454
455/*
456 * ccdc_write_dfc_entry()
457 * write an entry in the dfc table.
458 */
459int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
460{
461/* TODO This is to be re-visited and adjusted */
462#define DFC_WRITE_WAIT_COUNT 1000
463 u32 val, count = DFC_WRITE_WAIT_COUNT;
464
465 regw(dfc->dft_corr_vert[index], DFCMEM0);
466 regw(dfc->dft_corr_horz[index], DFCMEM1);
467 regw(dfc->dft_corr_sub1[index], DFCMEM2);
468 regw(dfc->dft_corr_sub2[index], DFCMEM3);
469 regw(dfc->dft_corr_sub3[index], DFCMEM4);
470 /* set WR bit to write */
471 val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
472 regw(val, DFCMEMCTL);
473
474 /*
475 * Assume, it is very short. If we get an error, we need to
476 * adjust this value
477 */
478 while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
479 count--;
480 /*
481 * TODO We expect the count to be non-zero to be successful. Adjust
482 * the count if write requires more time
483 */
484
485 if (count) {
486 dev_err(dev, "defect table write timeout !!!\n");
487 return -1;
488 }
489 return 0;
490}
491
492/*
493 * ccdc_config_vdfc()
494 * configure parameters for Vertical Defect Correction
495 */
496static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
497{
498 u32 val;
499 int i;
500
501 /* Configure General Defect Correction. The table used is from IPIPE */
502 val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
503
504 /* Configure Vertical Defect Correction if needed */
505 if (!dfc->ver_dft_en) {
506 /* Enable only General Defect Correction */
507 regw(val, DFCCTL);
508 return 0;
509 }
510
511 if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
512 return -EINVAL;
513
514 val |= CCDC_DFCCTL_VDFC_DISABLE;
515 val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
516 CCDC_DFCCTL_VDFCSL_SHIFT;
517 val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
518 CCDC_DFCCTL_VDFCUDA_SHIFT;
519 val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
520 CCDC_DFCCTL_VDFLSFT_SHIFT;
521 regw(val , DFCCTL);
522
523 /* clear address ptr to offset 0 */
524 val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
525
526 /* write defect table entries */
527 for (i = 0; i < dfc->table_size; i++) {
528 /* increment address for non zero index */
529 if (i != 0)
530 val = CCDC_DFCMEMCTL_INC_ADDR;
531 regw(val, DFCMEMCTL);
532 if (ccdc_write_dfc_entry(i, dfc) < 0)
533 return -EFAULT;
534 }
535
536 /* update saturation level and enable dfc */
537 regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
538 val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
539 CCDC_DFCCTL_VDFCEN_SHIFT);
540 regw(val, DFCCTL);
541 return 0;
542}
543
544/*
545 * ccdc_config_csc()
546 * configure parameters for color space conversion
547 * Each register CSCM0-7 has two values in S8Q5 format.
548 */
549static void ccdc_config_csc(struct ccdc_csc *csc)
550{
551 u32 val1, val2;
552 int i;
553
554 if (!csc->enable)
555 return;
556
557 /* Enable the CSC sub-module */
558 regw(CCDC_CSC_ENABLE, CSCCTL);
559
560 /* Converting the co-eff as per the format of the register */
561 for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
562 if ((i % 2) == 0) {
563 /* CSCM - LSB */
564 val1 = (csc->coeff[i].integer &
565 CCDC_CSC_COEF_INTEG_MASK)
566 << CCDC_CSC_COEF_INTEG_SHIFT;
567 /*
568 * convert decimal part to binary. Use 2 decimal
569 * precision, user values range from .00 - 0.99
570 */
571 val1 |= (((csc->coeff[i].decimal &
572 CCDC_CSC_COEF_DECIMAL_MASK) *
573 CCDC_CSC_DEC_MAX) / 100);
574 } else {
575
576 /* CSCM - MSB */
577 val2 = (csc->coeff[i].integer &
578 CCDC_CSC_COEF_INTEG_MASK)
579 << CCDC_CSC_COEF_INTEG_SHIFT;
580 val2 |= (((csc->coeff[i].decimal &
581 CCDC_CSC_COEF_DECIMAL_MASK) *
582 CCDC_CSC_DEC_MAX) / 100);
583 val2 <<= CCDC_CSCM_MSB_SHIFT;
584 val2 |= val1;
585 regw(val2, (CSCM0 + ((i - 1) << 1)));
586 }
587 }
588}
589
590/*
591 * ccdc_config_color_patterns()
592 * configure parameters for color patterns
593 */
594static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
595 struct ccdc_col_pat *pat1)
596{
597 u32 val;
598
599 val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
600 (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
601 (pat1->elop << 12) | (pat1->elep << 14));
602 regw(val, COLPTN);
603}
604
605/* This function will configure CCDC for Raw mode image capture */
606static int ccdc_config_raw(void)
607{
608 struct ccdc_params_raw *params = &ccdc_hw_params_raw;
609 struct ccdc_config_params_raw *config_params =
610 &ccdc_hw_params_raw.config_params;
611 unsigned int val;
612
613 dev_dbg(dev, "\nStarting ccdc_config_raw...");
614
615 /* restore power on defaults to register */
616 ccdc_restore_defaults();
617
618 /* CCDCFG register:
619 * set CCD Not to swap input since input is RAW data
620 * set FID detection function to Latch at V-Sync
621 * set WENLOG - ccdc valid area to AND
622 * set TRGSEL to WENBIT
623 * set EXTRG to DISABLE
624 * disable latching function on VSYNC - shadowed registers
625 */
626 regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
627 CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
628 CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
629
630 /*
631 * Set VDHD direction to input, input type to raw input
632 * normal data polarity, do not use external WEN
633 */
634 val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
635 CCDC_EXWEN_DISABLE);
636
637 /*
638 * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
639 * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
640 * frame format(progressive or interlace), & pixel format (Input mode)
641 */
642 val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
643 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
644 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
645 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
646 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
647
648 /* set pack for alaw compression */
649 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
650 config_params->alaw.enable)
651 val |= CCDC_DATA_PACK_ENABLE;
652
653 /* Configure for LPF */
654 if (config_params->lpf_enable)
655 val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
656 CCDC_LPF_SHIFT;
657
658 /* Configure the data shift */
659 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
660 CCDC_DATASFT_SHIFT;
661 regw(val , MODESET);
662 dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val);
663
664 /* Configure the Median Filter threshold */
665 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
666
667 /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
668 val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
669 CCDC_CFA_MOSAIC;
670
671 /* Enable and configure aLaw register if needed */
672 if (config_params->alaw.enable) {
673 val |= (CCDC_ALAW_ENABLE |
674 ((config_params->alaw.gama_wd &
675 CCDC_ALAW_GAMA_WD_MASK) <<
676 CCDC_GAMMAWD_INPUT_SHIFT));
677 }
678
679 /* Configure Median filter1 & filter2 */
680 val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
681 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
682
683 regw(val, GAMMAWD);
684 dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val);
685
686 /* configure video window */
687 ccdc_setwin(&params->win, params->frm_fmt, 1);
688
689 /* Optical Clamp Averaging */
690 ccdc_config_black_clamp(&config_params->blk_clamp);
691
692 /* Black level compensation */
693 ccdc_config_black_compense(&config_params->blk_comp);
694
695 /* Vertical Defect Correction if needed */
696 if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
697 return -EFAULT;
698
699 /* color space conversion */
700 ccdc_config_csc(&config_params->csc);
701
702 /* color pattern */
703 ccdc_config_color_patterns(&config_params->col_pat_field0,
704 &config_params->col_pat_field1);
705
706 /* Configure the Gain & offset control */
707 ccdc_config_gain_offset();
708
709 dev_dbg(dev, "\nWriting %x to COLPTN...\n", val);
710
711 /* Configure DATAOFST register */
712 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
713 CCDC_DATAOFST_H_SHIFT;
714 val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
715 CCDC_DATAOFST_V_SHIFT;
716 regw(val, DATAOFST);
717
718 /* configuring HSIZE register */
719 val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
720 CCDC_HSIZE_FLIP_SHIFT;
721
722 /* If pack 8 is enable then 1 pixel will take 1 byte */
723 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
724 config_params->alaw.enable) {
725 val |= (((params->win.width) + 31) >> 5) &
726 CCDC_HSIZE_VAL_MASK;
727
728 /* adjust to multiple of 32 */
729 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
730 (((params->win.width) + 31) >> 5) &
731 CCDC_HSIZE_VAL_MASK);
732 } else {
733 /* else one pixel will take 2 byte */
734 val |= (((params->win.width * 2) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK;
736
737 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
738 (((params->win.width * 2) + 31) >> 5) &
739 CCDC_HSIZE_VAL_MASK);
740 }
741 regw(val, HSIZE);
742
743 /* Configure SDOFST register */
744 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
745 if (params->image_invert_enable) {
746 /* For interlace inverse mode */
747 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
748 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
749 CCDC_SDOFST_INTERLACE_INVERSE);
750 } else {
751 /* For interlace non inverse mode */
752 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
753 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
754 CCDC_SDOFST_INTERLACE_NORMAL);
755 }
756 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
757 if (params->image_invert_enable) {
758 /* For progessive inverse mode */
759 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
760 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
761 CCDC_SDOFST_PROGRESSIVE_INVERSE);
762 } else {
763 /* For progessive non inverse mode */
764 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
765 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
766 CCDC_SDOFST_PROGRESSIVE_NORMAL);
767 }
768 }
769 dev_dbg(dev, "\nend of ccdc_config_raw...");
770 return 0;
771}
772
773static int ccdc_configure(void)
774{
775 if (ccdc_if_type == VPFE_RAW_BAYER)
776 return ccdc_config_raw();
777 else
778 ccdc_config_ycbcr();
779 return 0;
780}
781
782static int ccdc_set_buftype(enum ccdc_buftype buf_type)
783{
784 if (ccdc_if_type == VPFE_RAW_BAYER)
785 ccdc_hw_params_raw.buf_type = buf_type;
786 else
787 ccdc_hw_params_ycbcr.buf_type = buf_type;
788 return 0;
789}
790static enum ccdc_buftype ccdc_get_buftype(void)
791{
792 if (ccdc_if_type == VPFE_RAW_BAYER)
793 return ccdc_hw_params_raw.buf_type;
794 return ccdc_hw_params_ycbcr.buf_type;
795}
796
797static int ccdc_enum_pix(u32 *pix, int i)
798{
799 int ret = -EINVAL;
800 if (ccdc_if_type == VPFE_RAW_BAYER) {
801 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
802 *pix = ccdc_raw_bayer_pix_formats[i];
803 ret = 0;
804 }
805 } else {
806 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
807 *pix = ccdc_raw_yuv_pix_formats[i];
808 ret = 0;
809 }
810 }
811 return ret;
812}
813
814static int ccdc_set_pixel_format(u32 pixfmt)
815{
816 struct ccdc_a_law *alaw =
817 &ccdc_hw_params_raw.config_params.alaw;
818
819 if (ccdc_if_type == VPFE_RAW_BAYER) {
820 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
821 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
822 alaw->enable = 1;
823 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
824 return -EINVAL;
825 } else {
826 if (pixfmt == V4L2_PIX_FMT_YUYV)
827 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
828 else if (pixfmt == V4L2_PIX_FMT_UYVY)
829 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
830 else
831 return -EINVAL;
832 }
833 return 0;
834}
835static u32 ccdc_get_pixel_format(void)
836{
837 struct ccdc_a_law *alaw =
838 &ccdc_hw_params_raw.config_params.alaw;
839 u32 pixfmt;
840
841 if (ccdc_if_type == VPFE_RAW_BAYER)
842 if (alaw->enable)
843 pixfmt = V4L2_PIX_FMT_SBGGR8;
844 else
845 pixfmt = V4L2_PIX_FMT_SBGGR16;
846 else {
847 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
848 pixfmt = V4L2_PIX_FMT_YUYV;
849 else
850 pixfmt = V4L2_PIX_FMT_UYVY;
851 }
852 return pixfmt;
853}
854static int ccdc_set_image_window(struct v4l2_rect *win)
855{
856 if (ccdc_if_type == VPFE_RAW_BAYER)
857 ccdc_hw_params_raw.win = *win;
858 else
859 ccdc_hw_params_ycbcr.win = *win;
860 return 0;
861}
862
863static void ccdc_get_image_window(struct v4l2_rect *win)
864{
865 if (ccdc_if_type == VPFE_RAW_BAYER)
866 *win = ccdc_hw_params_raw.win;
867 else
868 *win = ccdc_hw_params_ycbcr.win;
869}
870
871static unsigned int ccdc_get_line_length(void)
872{
873 struct ccdc_config_params_raw *config_params =
874 &ccdc_hw_params_raw.config_params;
875 unsigned int len;
876
877 if (ccdc_if_type == VPFE_RAW_BAYER) {
878 if ((config_params->alaw.enable) ||
879 (config_params->data_sz == CCDC_DATA_8BITS))
880 len = ccdc_hw_params_raw.win.width;
881 else
882 len = ccdc_hw_params_raw.win.width * 2;
883 } else
884 len = ccdc_hw_params_ycbcr.win.width * 2;
885 return ALIGN(len, 32);
886}
887
888static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
889{
890 if (ccdc_if_type == VPFE_RAW_BAYER)
891 ccdc_hw_params_raw.frm_fmt = frm_fmt;
892 else
893 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
894 return 0;
895}
896
897static enum ccdc_frmfmt ccdc_get_frame_format(void)
898{
899 if (ccdc_if_type == VPFE_RAW_BAYER)
900 return ccdc_hw_params_raw.frm_fmt;
901 else
902 return ccdc_hw_params_ycbcr.frm_fmt;
903}
904
905static int ccdc_getfid(void)
906{
907 return (regr(MODESET) >> 15) & 1;
908}
909
910/* misc operations */
911static inline void ccdc_setfbaddr(unsigned long addr)
912{
913 regw((addr >> 21) & 0x007f, STADRH);
914 regw((addr >> 5) & 0x0ffff, STADRL);
915}
916
917static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
918{
919 ccdc_if_type = params->if_type;
920
921 switch (params->if_type) {
922 case VPFE_BT656:
923 case VPFE_YCBCR_SYNC_16:
924 case VPFE_YCBCR_SYNC_8:
925 ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
926 ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
927 break;
928 default:
929 /* TODO add support for raw bayer here */
930 return -EINVAL;
931 }
932 return 0;
933}
934
935static struct ccdc_hw_device ccdc_hw_dev = {
936 .name = "DM355 CCDC",
937 .owner = THIS_MODULE,
938 .hw_ops = {
939 .open = ccdc_open,
940 .close = ccdc_close,
941 .set_ccdc_base = ccdc_set_ccdc_base,
942 .enable = ccdc_enable,
943 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
944 .set_hw_if_params = ccdc_set_hw_if_params,
945 .set_params = ccdc_set_params,
946 .configure = ccdc_configure,
947 .set_buftype = ccdc_set_buftype,
948 .get_buftype = ccdc_get_buftype,
949 .enum_pix = ccdc_enum_pix,
950 .set_pixel_format = ccdc_set_pixel_format,
951 .get_pixel_format = ccdc_get_pixel_format,
952 .set_frame_format = ccdc_set_frame_format,
953 .get_frame_format = ccdc_get_frame_format,
954 .set_image_window = ccdc_set_image_window,
955 .get_image_window = ccdc_get_image_window,
956 .get_line_length = ccdc_get_line_length,
957 .setfbaddr = ccdc_setfbaddr,
958 .getfid = ccdc_getfid,
959 },
960};
961
962static int dm355_ccdc_init(void)
963{
964 printk(KERN_NOTICE "dm355_ccdc_init\n");
965 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
966 return -1;
967 printk(KERN_NOTICE "%s is registered with vpfe.\n",
968 ccdc_hw_dev.name);
969 return 0;
970}
971
972static void dm355_ccdc_exit(void)
973{
974 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
975}
976
977module_init(dm355_ccdc_init);
978module_exit(dm355_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h
new file mode 100644
index 000000000000..d6d2ef0533b5
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc_regs.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM355_CCDC_REGS_H
19#define _DM355_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define SYNCEN 0x00
25#define MODESET 0x04
26#define HDWIDTH 0x08
27#define VDWIDTH 0x0c
28#define PPLN 0x10
29#define LPFR 0x14
30#define SPH 0x18
31#define NPH 0x1c
32#define SLV0 0x20
33#define SLV1 0x24
34#define NLV 0x28
35#define CULH 0x2c
36#define CULV 0x30
37#define HSIZE 0x34
38#define SDOFST 0x38
39#define STADRH 0x3c
40#define STADRL 0x40
41#define CLAMP 0x44
42#define DCSUB 0x48
43#define COLPTN 0x4c
44#define BLKCMP0 0x50
45#define BLKCMP1 0x54
46#define MEDFILT 0x58
47#define RYEGAIN 0x5c
48#define GRCYGAIN 0x60
49#define GBGGAIN 0x64
50#define BMGGAIN 0x68
51#define OFFSET 0x6c
52#define OUTCLIP 0x70
53#define VDINT0 0x74
54#define VDINT1 0x78
55#define RSV0 0x7c
56#define GAMMAWD 0x80
57#define REC656IF 0x84
58#define CCDCFG 0x88
59#define FMTCFG 0x8c
60#define FMTPLEN 0x90
61#define FMTSPH 0x94
62#define FMTLNH 0x98
63#define FMTSLV 0x9c
64#define FMTLNV 0xa0
65#define FMTRLEN 0xa4
66#define FMTHCNT 0xa8
67#define FMT_ADDR_PTR_B 0xac
68#define FMT_ADDR_PTR(i) (FMT_ADDR_PTR_B + (i * 4))
69#define FMTPGM_VF0 0xcc
70#define FMTPGM_VF1 0xd0
71#define FMTPGM_AP0 0xd4
72#define FMTPGM_AP1 0xd8
73#define FMTPGM_AP2 0xdc
74#define FMTPGM_AP3 0xe0
75#define FMTPGM_AP4 0xe4
76#define FMTPGM_AP5 0xe8
77#define FMTPGM_AP6 0xec
78#define FMTPGM_AP7 0xf0
79#define LSCCFG1 0xf4
80#define LSCCFG2 0xf8
81#define LSCH0 0xfc
82#define LSCV0 0x100
83#define LSCKH 0x104
84#define LSCKV 0x108
85#define LSCMEMCTL 0x10c
86#define LSCMEMD 0x110
87#define LSCMEMQ 0x114
88#define DFCCTL 0x118
89#define DFCVSAT 0x11c
90#define DFCMEMCTL 0x120
91#define DFCMEM0 0x124
92#define DFCMEM1 0x128
93#define DFCMEM2 0x12c
94#define DFCMEM3 0x130
95#define DFCMEM4 0x134
96#define CSCCTL 0x138
97#define CSCM0 0x13c
98#define CSCM1 0x140
99#define CSCM2 0x144
100#define CSCM3 0x148
101#define CSCM4 0x14c
102#define CSCM5 0x150
103#define CSCM6 0x154
104#define CSCM7 0x158
105#define DATAOFST 0x15c
106#define CCDC_REG_LAST DATAOFST
107/**************************************************************
108* Define for various register bit mask and shifts for CCDC
109*
110**************************************************************/
111#define CCDC_RAW_IP_MODE 0
112#define CCDC_VDHDOUT_INPUT 0
113#define CCDC_YCINSWP_RAW (0 << 4)
114#define CCDC_EXWEN_DISABLE 0
115#define CCDC_DATAPOL_NORMAL 0
116#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0
117#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6)
118#define CCDC_CCDCFG_WENLOG_AND 0
119#define CCDC_CCDCFG_TRGSEL_WEN 0
120#define CCDC_CCDCFG_EXTRG_DISABLE 0
121#define CCDC_CFA_MOSAIC 0
122#define CCDC_Y8POS_SHIFT 11
123
124#define CCDC_VDC_DFCVSAT_MASK 0x3fff
125#define CCDC_DATAOFST_MASK 0x0ff
126#define CCDC_DATAOFST_H_SHIFT 0
127#define CCDC_DATAOFST_V_SHIFT 8
128#define CCDC_GAMMAWD_CFA_MASK 1
129#define CCDC_GAMMAWD_CFA_SHIFT 5
130#define CCDC_GAMMAWD_INPUT_SHIFT 2
131#define CCDC_FID_POL_MASK 1
132#define CCDC_FID_POL_SHIFT 4
133#define CCDC_HD_POL_MASK 1
134#define CCDC_HD_POL_SHIFT 3
135#define CCDC_VD_POL_MASK 1
136#define CCDC_VD_POL_SHIFT 2
137#define CCDC_VD_POL_NEGATIVE (1 << 2)
138#define CCDC_FRM_FMT_MASK 1
139#define CCDC_FRM_FMT_SHIFT 7
140#define CCDC_DATA_SZ_MASK 7
141#define CCDC_DATA_SZ_SHIFT 8
142#define CCDC_VDHDOUT_MASK 1
143#define CCDC_VDHDOUT_SHIFT 0
144#define CCDC_EXWEN_MASK 1
145#define CCDC_EXWEN_SHIFT 5
146#define CCDC_INPUT_MODE_MASK 3
147#define CCDC_INPUT_MODE_SHIFT 12
148#define CCDC_PIX_FMT_MASK 3
149#define CCDC_PIX_FMT_SHIFT 12
150#define CCDC_DATAPOL_MASK 1
151#define CCDC_DATAPOL_SHIFT 6
152#define CCDC_WEN_ENABLE (1 << 1)
153#define CCDC_VDHDEN_ENABLE (1 << 16)
154#define CCDC_LPF_ENABLE (1 << 14)
155#define CCDC_ALAW_ENABLE 1
156#define CCDC_ALAW_GAMA_WD_MASK 7
157#define CCDC_REC656IF_BT656_EN 3
158
159#define CCDC_FMTCFG_FMTMODE_MASK 3
160#define CCDC_FMTCFG_FMTMODE_SHIFT 1
161#define CCDC_FMTCFG_LNUM_MASK 3
162#define CCDC_FMTCFG_LNUM_SHIFT 4
163#define CCDC_FMTCFG_ADDRINC_MASK 7
164#define CCDC_FMTCFG_ADDRINC_SHIFT 8
165
166#define CCDC_CCDCFG_FIDMD_SHIFT 6
167#define CCDC_CCDCFG_WENLOG_SHIFT 8
168#define CCDC_CCDCFG_TRGSEL_SHIFT 9
169#define CCDC_CCDCFG_EXTRG_SHIFT 10
170#define CCDC_CCDCFG_MSBINVI_SHIFT 13
171
172#define CCDC_HSIZE_FLIP_SHIFT 12
173#define CCDC_HSIZE_FLIP_MASK 1
174#define CCDC_HSIZE_VAL_MASK 0xFFF
175#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
176#define CCDC_SDOFST_INTERLACE_INVERSE 0x4B6D
177#define CCDC_SDOFST_INTERLACE_NORMAL 0x0B6D
178#define CCDC_SDOFST_PROGRESSIVE_INVERSE 0x4000
179#define CCDC_SDOFST_PROGRESSIVE_NORMAL 0
180#define CCDC_START_PX_HOR_MASK 0x7FFF
181#define CCDC_NUM_PX_HOR_MASK 0x7FFF
182#define CCDC_START_VER_ONE_MASK 0x7FFF
183#define CCDC_START_VER_TWO_MASK 0x7FFF
184#define CCDC_NUM_LINES_VER 0x7FFF
185
186#define CCDC_BLK_CLAMP_ENABLE (1 << 15)
187#define CCDC_BLK_SGAIN_MASK 0x1F
188#define CCDC_BLK_ST_PXL_MASK 0x1FFF
189#define CCDC_BLK_SAMPLE_LN_MASK 3
190#define CCDC_BLK_SAMPLE_LN_SHIFT 13
191
192#define CCDC_NUM_LINE_CALC_MASK 3
193#define CCDC_NUM_LINE_CALC_SHIFT 14
194
195#define CCDC_BLK_DC_SUB_MASK 0x3FFF
196#define CCDC_BLK_COMP_MASK 0xFF
197#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
198#define CCDC_BLK_COMP_GR_COMP_SHIFT 0
199#define CCDC_BLK_COMP_R_COMP_SHIFT 8
200#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
201#define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15)
202#define CCDC_FPC_ENABLE (1 << 15)
203#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
204#define CCDC_DATA_PACK_ENABLE (1 << 11)
205#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
206#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
207#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
208#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
209#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
210#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
211#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
212#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
213#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
214#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
215#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
216
217#define CCDC_CSC_COEF_INTEG_MASK 7
218#define CCDC_CSC_COEF_DECIMAL_MASK 0x1f
219#define CCDC_CSC_COEF_INTEG_SHIFT 5
220#define CCDC_CSCM_MSB_SHIFT 8
221#define CCDC_CSC_ENABLE 1
222#define CCDC_CSC_DEC_MAX 32
223
224#define CCDC_MFILT1_SHIFT 10
225#define CCDC_MFILT2_SHIFT 8
226#define CCDC_MED_FILT_THRESH 0x3FFF
227#define CCDC_LPF_MASK 1
228#define CCDC_LPF_SHIFT 14
229#define CCDC_OFFSET_MASK 0x3FF
230#define CCDC_DATASFT_MASK 7
231#define CCDC_DATASFT_SHIFT 8
232
233#define CCDC_DF_ENABLE 1
234
235#define CCDC_FMTPLEN_P0_MASK 0xF
236#define CCDC_FMTPLEN_P1_MASK 0xF
237#define CCDC_FMTPLEN_P2_MASK 7
238#define CCDC_FMTPLEN_P3_MASK 7
239#define CCDC_FMTPLEN_P0_SHIFT 0
240#define CCDC_FMTPLEN_P1_SHIFT 4
241#define CCDC_FMTPLEN_P2_SHIFT 8
242#define CCDC_FMTPLEN_P3_SHIFT 12
243
244#define CCDC_FMTSPH_MASK 0x1FFF
245#define CCDC_FMTLNH_MASK 0x1FFF
246#define CCDC_FMTSLV_MASK 0x1FFF
247#define CCDC_FMTLNV_MASK 0x7FFF
248#define CCDC_FMTRLEN_MASK 0x1FFF
249#define CCDC_FMTHCNT_MASK 0x1FFF
250
251#define CCDC_ADP_INIT_MASK 0x1FFF
252#define CCDC_ADP_LINE_SHIFT 13
253#define CCDC_ADP_LINE_MASK 3
254#define CCDC_FMTPGN_APTR_MASK 7
255
256#define CCDC_DFCCTL_GDFCEN_MASK 1
257#define CCDC_DFCCTL_VDFCEN_MASK 1
258#define CCDC_DFCCTL_VDFC_DISABLE (0 << 4)
259#define CCDC_DFCCTL_VDFCEN_SHIFT 4
260#define CCDC_DFCCTL_VDFCSL_MASK 3
261#define CCDC_DFCCTL_VDFCSL_SHIFT 5
262#define CCDC_DFCCTL_VDFCUDA_MASK 1
263#define CCDC_DFCCTL_VDFCUDA_SHIFT 7
264#define CCDC_DFCCTL_VDFLSFT_MASK 3
265#define CCDC_DFCCTL_VDFLSFT_SHIFT 8
266#define CCDC_DFCMEMCTL_DFCMARST_MASK 1
267#define CCDC_DFCMEMCTL_DFCMARST_SHIFT 2
268#define CCDC_DFCMEMCTL_DFCMWR_MASK 1
269#define CCDC_DFCMEMCTL_DFCMWR_SHIFT 0
270#define CCDC_DFCMEMCTL_INC_ADDR (0 << 2)
271
272#define CCDC_LSCCFG_GFTSF_MASK 7
273#define CCDC_LSCCFG_GFTSF_SHIFT 1
274#define CCDC_LSCCFG_GFTINV_MASK 0xf
275#define CCDC_LSCCFG_GFTINV_SHIFT 4
276#define CCDC_LSC_GFTABLE_SEL_MASK 3
277#define CCDC_LSC_GFTABLE_EPEL_SHIFT 8
278#define CCDC_LSC_GFTABLE_OPEL_SHIFT 10
279#define CCDC_LSC_GFTABLE_EPOL_SHIFT 12
280#define CCDC_LSC_GFTABLE_OPOL_SHIFT 14
281#define CCDC_LSC_GFMODE_MASK 3
282#define CCDC_LSC_GFMODE_SHIFT 4
283#define CCDC_LSC_DISABLE 0
284#define CCDC_LSC_ENABLE 1
285#define CCDC_LSC_TABLE1_SLC 0
286#define CCDC_LSC_TABLE2_SLC 1
287#define CCDC_LSC_TABLE3_SLC 2
288#define CCDC_LSC_MEMADDR_RESET (1 << 2)
289#define CCDC_LSC_MEMADDR_INCR (0 << 2)
290#define CCDC_LSC_FRAC_MASK_T1 0xFF
291#define CCDC_LSC_INT_MASK 3
292#define CCDC_LSC_FRAC_MASK 0x3FFF
293#define CCDC_LSC_CENTRE_MASK 0x3FFF
294#define CCDC_LSC_COEF_MASK 0xff
295#define CCDC_LSC_COEFL_SHIFT 0
296#define CCDC_LSC_COEFU_SHIFT 8
297#define CCDC_GAIN_MASK 0x7FF
298#define CCDC_SYNCEN_VDHDEN_MASK (1 << 0)
299#define CCDC_SYNCEN_WEN_MASK (1 << 1)
300#define CCDC_SYNCEN_WEN_SHIFT 1
301
302/* Power on Defaults in hardware */
303#define MODESET_DEFAULT 0x200
304#define CULH_DEFAULT 0xFFFF
305#define CULV_DEFAULT 0xFF
306#define GAIN_DEFAULT 256
307#define OUTCLIP_DEFAULT 0x3FFF
308#define LSCCFG2_DEFAULT 0xE
309
310#endif
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
new file mode 100644
index 000000000000..2f19a919f477
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -0,0 +1,878 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM6446
19 * ------------------------------
20 *
21 * This module is for configuring CCD controller of DM6446 VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters. This file is named DM644x so that other
30 * variants such DM6443 may be supported using the same module.
31 *
32 * TODO: Test Raw bayer parameter settings and bayer capture
33 * Split module parameter structure to module specific ioctl structs
34 * investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <media/davinci/dm644x_ccdc.h>
41#include <media/davinci/vpss.h>
42#include "dm644x_ccdc_regs.h"
43#include "ccdc_hw_device.h"
44
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM6446");
47MODULE_AUTHOR("Texas Instruments");
48
49static struct device *dev;
50
51/* Object for CCDC raw mode */
52static struct ccdc_params_raw ccdc_hw_params_raw = {
53 .pix_fmt = CCDC_PIXFMT_RAW,
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
55 .win = CCDC_WIN_VGA,
56 .fid_pol = VPFE_PINPOL_POSITIVE,
57 .vd_pol = VPFE_PINPOL_POSITIVE,
58 .hd_pol = VPFE_PINPOL_POSITIVE,
59 .config_params = {
60 .data_sz = CCDC_DATA_10BITS,
61 },
62};
63
64/* Object for CCDC ycbcr mode */
65static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
66 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
67 .frm_fmt = CCDC_FRMFMT_INTERLACED,
68 .win = CCDC_WIN_PAL,
69 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .hd_pol = VPFE_PINPOL_POSITIVE,
72 .bt656_enable = 1,
73 .pix_order = CCDC_PIXORDER_CBYCRY,
74 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
75};
76
77#define CCDC_MAX_RAW_YUV_FORMATS 2
78
79/* Raw Bayer formats */
80static u32 ccdc_raw_bayer_pix_formats[] =
81 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
82
83/* Raw YUV formats */
84static u32 ccdc_raw_yuv_pix_formats[] =
85 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
86
87static void *__iomem ccdc_base_addr;
88static int ccdc_addr_size;
89static enum vpfe_hw_if_type ccdc_if_type;
90
91/* register access routines */
92static inline u32 regr(u32 offset)
93{
94 return __raw_readl(ccdc_base_addr + offset);
95}
96
97static inline void regw(u32 val, u32 offset)
98{
99 __raw_writel(val, ccdc_base_addr + offset);
100}
101
102static void ccdc_set_ccdc_base(void *addr, int size)
103{
104 ccdc_base_addr = addr;
105 ccdc_addr_size = size;
106}
107
108static void ccdc_enable(int flag)
109{
110 regw(flag, CCDC_PCR);
111}
112
113static void ccdc_enable_vport(int flag)
114{
115 if (flag)
116 /* enable video port */
117 regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
118 else
119 regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
120}
121
122/*
123 * ccdc_setwin()
124 * This function will configure the window size
125 * to be capture in CCDC reg
126 */
127void ccdc_setwin(struct v4l2_rect *image_win,
128 enum ccdc_frmfmt frm_fmt,
129 int ppc)
130{
131 int horz_start, horz_nr_pixels;
132 int vert_start, vert_nr_lines;
133 int val = 0, mid_img = 0;
134
135 dev_dbg(dev, "\nStarting ccdc_setwin...");
136 /*
137 * ppc - per pixel count. indicates how many pixels per cell
138 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
139 * raw capture this is 1
140 */
141 horz_start = image_win->left << (ppc - 1);
142 horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
143 regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
144 CCDC_HORZ_INFO);
145
146 vert_start = image_win->top;
147
148 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
149 vert_nr_lines = (image_win->height >> 1) - 1;
150 vert_start >>= 1;
151 /* Since first line doesn't have any data */
152 vert_start += 1;
153 /* configure VDINT0 */
154 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
155 regw(val, CCDC_VDINT);
156
157 } else {
158 /* Since first line doesn't have any data */
159 vert_start += 1;
160 vert_nr_lines = image_win->height - 1;
161 /*
162 * configure VDINT0 and VDINT1. VDINT1 will be at half
163 * of image height
164 */
165 mid_img = vert_start + (image_win->height / 2);
166 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
167 (mid_img & CCDC_VDINT_VDINT1_MASK);
168 regw(val, CCDC_VDINT);
169
170 }
171 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
172 CCDC_VERT_START);
173 regw(vert_nr_lines, CCDC_VERT_LINES);
174 dev_dbg(dev, "\nEnd of ccdc_setwin...");
175}
176
177static void ccdc_readregs(void)
178{
179 unsigned int val = 0;
180
181 val = regr(CCDC_ALAW);
182 dev_notice(dev, "\nReading 0x%x to ALAW...\n", val);
183 val = regr(CCDC_CLAMP);
184 dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val);
185 val = regr(CCDC_DCSUB);
186 dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val);
187 val = regr(CCDC_BLKCMP);
188 dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val);
189 val = regr(CCDC_FPC_ADDR);
190 dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val);
191 val = regr(CCDC_FPC);
192 dev_notice(dev, "\nReading 0x%x to FPC...\n", val);
193 val = regr(CCDC_FMTCFG);
194 dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val);
195 val = regr(CCDC_COLPTN);
196 dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val);
197 val = regr(CCDC_FMT_HORZ);
198 dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val);
199 val = regr(CCDC_FMT_VERT);
200 dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val);
201 val = regr(CCDC_HSIZE_OFF);
202 dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
203 val = regr(CCDC_SDOFST);
204 dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val);
205 val = regr(CCDC_VP_OUT);
206 dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val);
207 val = regr(CCDC_SYN_MODE);
208 dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val);
209 val = regr(CCDC_HORZ_INFO);
210 dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val);
211 val = regr(CCDC_VERT_START);
212 dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val);
213 val = regr(CCDC_VERT_LINES);
214 dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val);
215}
216
217static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
218{
219 if (ccdcparam->alaw.enable) {
220 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
221 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
222 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
223 dev_dbg(dev, "\nInvalid data line select");
224 return -1;
225 }
226 }
227 return 0;
228}
229
230static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
231{
232 struct ccdc_config_params_raw *config_params =
233 &ccdc_hw_params_raw.config_params;
234 unsigned int *fpc_virtaddr = NULL;
235 unsigned int *fpc_physaddr = NULL;
236
237 memcpy(config_params, raw_params, sizeof(*raw_params));
238 /*
239 * allocate memory for fault pixel table and copy the user
240 * values to the table
241 */
242 if (!config_params->fault_pxl.enable)
243 return 0;
244
245 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
246 fpc_virtaddr = (unsigned int *)phys_to_virt(
247 (unsigned long)fpc_physaddr);
248 /*
249 * Allocate memory for FPC table if current
250 * FPC table buffer is not big enough to
251 * accomodate FPC Number requested
252 */
253 if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
254 if (fpc_physaddr != NULL) {
255 free_pages((unsigned long)fpc_physaddr,
256 get_order
257 (config_params->fault_pxl.fp_num *
258 FP_NUM_BYTES));
259 }
260
261 /* Allocate memory for FPC table */
262 fpc_virtaddr =
263 (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
264 get_order(raw_params->
265 fault_pxl.fp_num *
266 FP_NUM_BYTES));
267
268 if (fpc_virtaddr == NULL) {
269 dev_dbg(dev,
270 "\nUnable to allocate memory for FPC");
271 return -EFAULT;
272 }
273 fpc_physaddr =
274 (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
275 }
276
277 /* Copy number of fault pixels and FPC table */
278 config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
279 if (copy_from_user(fpc_virtaddr,
280 (void __user *)raw_params->fault_pxl.fpc_table_addr,
281 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
282 dev_dbg(dev, "\n copy_from_user failed");
283 return -EFAULT;
284 }
285 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
286 return 0;
287}
288
289static int ccdc_close(struct device *dev)
290{
291 struct ccdc_config_params_raw *config_params =
292 &ccdc_hw_params_raw.config_params;
293 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
294
295 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
296
297 if (fpc_physaddr != NULL) {
298 fpc_virtaddr = (unsigned int *)
299 phys_to_virt((unsigned long)fpc_physaddr);
300 free_pages((unsigned long)fpc_virtaddr,
301 get_order(config_params->fault_pxl.fp_num *
302 FP_NUM_BYTES));
303 }
304 return 0;
305}
306
307/*
308 * ccdc_restore_defaults()
309 * This function will write defaults to all CCDC registers
310 */
311static void ccdc_restore_defaults(void)
312{
313 int i;
314
315 /* disable CCDC */
316 ccdc_enable(0);
317 /* set all registers to default value */
318 for (i = 4; i <= 0x94; i += 4)
319 regw(0, i);
320 regw(CCDC_NO_CULLING, CCDC_CULLING);
321 regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
322}
323
324static int ccdc_open(struct device *device)
325{
326 dev = device;
327 ccdc_restore_defaults();
328 if (ccdc_if_type == VPFE_RAW_BAYER)
329 ccdc_enable_vport(1);
330 return 0;
331}
332
333static void ccdc_sbl_reset(void)
334{
335 vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
336}
337
338/* Parameter operations */
339static int ccdc_set_params(void __user *params)
340{
341 struct ccdc_config_params_raw ccdc_raw_params;
342 int x;
343
344 if (ccdc_if_type != VPFE_RAW_BAYER)
345 return -EINVAL;
346
347 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
348 if (x) {
349 dev_dbg(dev, "ccdc_set_params: error in copying"
350 "ccdc params, %d\n", x);
351 return -EFAULT;
352 }
353
354 if (!validate_ccdc_param(&ccdc_raw_params)) {
355 if (!ccdc_update_raw_params(&ccdc_raw_params))
356 return 0;
357 }
358 return -EINVAL;
359}
360
361/*
362 * ccdc_config_ycbcr()
363 * This function will configure CCDC for YCbCr video capture
364 */
365void ccdc_config_ycbcr(void)
366{
367 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
368 u32 syn_mode;
369
370 dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
371 /*
372 * first restore the CCDC registers to default values
373 * This is important since we assume default values to be set in
374 * a lot of registers that we didn't touch
375 */
376 ccdc_restore_defaults();
377
378 /*
379 * configure pixel format, frame format, configure video frame
380 * format, enable output to SDRAM, enable internal timing generator
381 * and 8bit pack mode
382 */
383 syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
384 CCDC_SYN_MODE_INPMOD_SHIFT) |
385 ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
386 CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
387 CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
388
389 /* setup BT.656 sync mode */
390 if (params->bt656_enable) {
391 regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
392
393 /*
394 * configure the FID, VD, HD pin polarity,
395 * fld,hd pol positive, vd negative, 8-bit data
396 */
397 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS;
398 } else {
399 /* y/c external sync mode */
400 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
401 CCDC_FID_POL_SHIFT) |
402 ((params->hd_pol & CCDC_HD_POL_MASK) <<
403 CCDC_HD_POL_SHIFT) |
404 ((params->vd_pol & CCDC_VD_POL_MASK) <<
405 CCDC_VD_POL_SHIFT));
406 }
407 regw(syn_mode, CCDC_SYN_MODE);
408
409 /* configure video window */
410 ccdc_setwin(&params->win, params->frm_fmt, 2);
411
412 /*
413 * configure the order of y cb cr in SDRAM, and disable latch
414 * internal register on vsync
415 */
416 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
417 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
418
419 /*
420 * configure the horizontal line offset. This should be a
421 * on 32 byte bondary. So clear LSB 5 bits
422 */
423 regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF);
424
425 /* configure the memory line offset */
426 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
427 /* two fields are interleaved in memory */
428 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
429
430 ccdc_sbl_reset();
431 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
432 ccdc_readregs();
433}
434
435static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
436{
437 u32 val;
438
439 if (!bclamp->enable) {
440 /* configure DCSub */
441 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
442 regw(val, CCDC_DCSUB);
443 dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
444 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
445 dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
446 return;
447 }
448 /*
449 * Configure gain, Start pixel, No of line to be avg,
450 * No of pixel/line to be avg, & Enable the Black clamping
451 */
452 val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
453 ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
454 CCDC_BLK_ST_PXL_SHIFT) |
455 ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
456 CCDC_BLK_SAMPLE_LINE_SHIFT) |
457 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
458 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
459 regw(val, CCDC_CLAMP);
460 dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
461 /* If Black clamping is enable then make dcsub 0 */
462 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
463 dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
464}
465
466static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
467{
468 u32 val;
469
470 val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
471 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
472 CCDC_BLK_COMP_GB_COMP_SHIFT) |
473 ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
474 CCDC_BLK_COMP_GR_COMP_SHIFT) |
475 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
476 CCDC_BLK_COMP_R_COMP_SHIFT));
477 regw(val, CCDC_BLKCMP);
478}
479
480static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
481{
482 u32 val;
483
484 /* Initially disable FPC */
485 val = CCDC_FPC_DISABLE;
486 regw(val, CCDC_FPC);
487
488 if (!fpc->enable)
489 return;
490
491 /* Configure Fault pixel if needed */
492 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
493 dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n",
494 (fpc->fpc_table_addr));
495 /* Write the FPC params with FPC disable */
496 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
497 regw(val, CCDC_FPC);
498
499 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
500 /* read the FPC register */
501 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
502 regw(val, CCDC_FPC);
503 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
504}
505
506/*
507 * ccdc_config_raw()
508 * This function will configure CCDC for Raw capture mode
509 */
510void ccdc_config_raw(void)
511{
512 struct ccdc_params_raw *params = &ccdc_hw_params_raw;
513 struct ccdc_config_params_raw *config_params =
514 &ccdc_hw_params_raw.config_params;
515 unsigned int syn_mode = 0;
516 unsigned int val;
517
518 dev_dbg(dev, "\nStarting ccdc_config_raw...");
519
520 /* Reset CCDC */
521 ccdc_restore_defaults();
522
523 /* Disable latching function registers on VSYNC */
524 regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
525
526 /*
527 * Configure the vertical sync polarity(SYN_MODE.VDPOL),
528 * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
529 * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
530 * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
531 * SDRAM, enable internal timing generator
532 */
533 syn_mode =
534 (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
535 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
536 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
537 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
538 ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
539 CCDC_DATA_SZ_SHIFT) |
540 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
541 CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
542
543 /* Enable and configure aLaw register if needed */
544 if (config_params->alaw.enable) {
545 val = ((config_params->alaw.gama_wd &
546 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
547 regw(val, CCDC_ALAW);
548 dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val);
549 }
550
551 /* Configure video window */
552 ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
553
554 /* Configure Black Clamp */
555 ccdc_config_black_clamp(&config_params->blk_clamp);
556
557 /* Configure Black level compensation */
558 ccdc_config_black_compense(&config_params->blk_comp);
559
560 /* Configure Fault Pixel Correction */
561 ccdc_config_fpc(&config_params->fault_pxl);
562
563 /* If data size is 8 bit then pack the data */
564 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
565 config_params->alaw.enable)
566 syn_mode |= CCDC_DATA_PACK_ENABLE;
567
568#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
569 /* enable video port */
570 val = CCDC_ENABLE_VIDEO_PORT;
571#else
572 /* disable video port */
573 val = CCDC_DISABLE_VIDEO_PORT;
574#endif
575
576 if (config_params->data_sz == CCDC_DATA_8BITS)
577 val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
578 << CCDC_FMTCFG_VPIN_SHIFT;
579 else
580 val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
581 << CCDC_FMTCFG_VPIN_SHIFT;
582 /* Write value in FMTCFG */
583 regw(val, CCDC_FMTCFG);
584
585 dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val);
586 /* Configure the color pattern according to mt9t001 sensor */
587 regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
588
589 dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
590 /*
591 * Configure Data formatter(Video port) pixel selection
592 * (FMT_HORZ, FMT_VERT)
593 */
594 val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
595 CCDC_FMT_HORZ_FMTSPH_SHIFT) |
596 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
597 regw(val, CCDC_FMT_HORZ);
598
599 dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
600 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
601 << CCDC_FMT_VERT_FMTSLV_SHIFT;
602 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
603 val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
604 else
605 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
606
607 dev_dbg(dev, "\nparams->win.height 0x%x ...\n",
608 params->win.height);
609 regw(val, CCDC_FMT_VERT);
610
611 dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val);
612
613 dev_dbg(dev, "\nbelow regw(val, FMT_VERT)...");
614
615 /*
616 * Configure Horizontal offset register. If pack 8 is enabled then
617 * 1 pixel will take 1 byte
618 */
619 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
620 config_params->alaw.enable)
621 regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
622 CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
623 else
624 /* else one pixel will take 2 byte */
625 regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
626 CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
627 CCDC_HSIZE_OFF);
628
629 /* Set value for SDOFST */
630 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
631 if (params->image_invert_enable) {
632 /* For intelace inverse mode */
633 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
634 dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
635 }
636
637 else {
638 /* For intelace non inverse mode */
639 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
640 dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n");
641 }
642 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
643 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
644 dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
645 }
646
647 /*
648 * Configure video port pixel selection (VPOUT)
649 * Here -1 is to make the height value less than FMT_VERT.FMTLNV
650 */
651 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
652 val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
653 << CCDC_VP_OUT_VERT_NUM_SHIFT;
654 else
655 val =
656 ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
657 1) & CCDC_VP_OUT_VERT_NUM_MASK)) <<
658 CCDC_VP_OUT_VERT_NUM_SHIFT;
659
660 val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
661 << CCDC_VP_OUT_HORZ_NUM_SHIFT;
662 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
663 regw(val, CCDC_VP_OUT);
664
665 dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val);
666 regw(syn_mode, CCDC_SYN_MODE);
667 dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
668
669 ccdc_sbl_reset();
670 dev_dbg(dev, "\nend of ccdc_config_raw...");
671 ccdc_readregs();
672}
673
674static int ccdc_configure(void)
675{
676 if (ccdc_if_type == VPFE_RAW_BAYER)
677 ccdc_config_raw();
678 else
679 ccdc_config_ycbcr();
680 return 0;
681}
682
683static int ccdc_set_buftype(enum ccdc_buftype buf_type)
684{
685 if (ccdc_if_type == VPFE_RAW_BAYER)
686 ccdc_hw_params_raw.buf_type = buf_type;
687 else
688 ccdc_hw_params_ycbcr.buf_type = buf_type;
689 return 0;
690}
691
692static enum ccdc_buftype ccdc_get_buftype(void)
693{
694 if (ccdc_if_type == VPFE_RAW_BAYER)
695 return ccdc_hw_params_raw.buf_type;
696 return ccdc_hw_params_ycbcr.buf_type;
697}
698
699static int ccdc_enum_pix(u32 *pix, int i)
700{
701 int ret = -EINVAL;
702 if (ccdc_if_type == VPFE_RAW_BAYER) {
703 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
704 *pix = ccdc_raw_bayer_pix_formats[i];
705 ret = 0;
706 }
707 } else {
708 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
709 *pix = ccdc_raw_yuv_pix_formats[i];
710 ret = 0;
711 }
712 }
713 return ret;
714}
715
716static int ccdc_set_pixel_format(u32 pixfmt)
717{
718 if (ccdc_if_type == VPFE_RAW_BAYER) {
719 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
720 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
721 ccdc_hw_params_raw.config_params.alaw.enable = 1;
722 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
723 return -EINVAL;
724 } else {
725 if (pixfmt == V4L2_PIX_FMT_YUYV)
726 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
727 else if (pixfmt == V4L2_PIX_FMT_UYVY)
728 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
729 else
730 return -EINVAL;
731 }
732 return 0;
733}
734
735static u32 ccdc_get_pixel_format(void)
736{
737 struct ccdc_a_law *alaw =
738 &ccdc_hw_params_raw.config_params.alaw;
739 u32 pixfmt;
740
741 if (ccdc_if_type == VPFE_RAW_BAYER)
742 if (alaw->enable)
743 pixfmt = V4L2_PIX_FMT_SBGGR8;
744 else
745 pixfmt = V4L2_PIX_FMT_SBGGR16;
746 else {
747 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
748 pixfmt = V4L2_PIX_FMT_YUYV;
749 else
750 pixfmt = V4L2_PIX_FMT_UYVY;
751 }
752 return pixfmt;
753}
754
755static int ccdc_set_image_window(struct v4l2_rect *win)
756{
757 if (ccdc_if_type == VPFE_RAW_BAYER)
758 ccdc_hw_params_raw.win = *win;
759 else
760 ccdc_hw_params_ycbcr.win = *win;
761 return 0;
762}
763
764static void ccdc_get_image_window(struct v4l2_rect *win)
765{
766 if (ccdc_if_type == VPFE_RAW_BAYER)
767 *win = ccdc_hw_params_raw.win;
768 else
769 *win = ccdc_hw_params_ycbcr.win;
770}
771
772static unsigned int ccdc_get_line_length(void)
773{
774 struct ccdc_config_params_raw *config_params =
775 &ccdc_hw_params_raw.config_params;
776 unsigned int len;
777
778 if (ccdc_if_type == VPFE_RAW_BAYER) {
779 if ((config_params->alaw.enable) ||
780 (config_params->data_sz == CCDC_DATA_8BITS))
781 len = ccdc_hw_params_raw.win.width;
782 else
783 len = ccdc_hw_params_raw.win.width * 2;
784 } else
785 len = ccdc_hw_params_ycbcr.win.width * 2;
786 return ALIGN(len, 32);
787}
788
789static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
790{
791 if (ccdc_if_type == VPFE_RAW_BAYER)
792 ccdc_hw_params_raw.frm_fmt = frm_fmt;
793 else
794 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
795 return 0;
796}
797
798static enum ccdc_frmfmt ccdc_get_frame_format(void)
799{
800 if (ccdc_if_type == VPFE_RAW_BAYER)
801 return ccdc_hw_params_raw.frm_fmt;
802 else
803 return ccdc_hw_params_ycbcr.frm_fmt;
804}
805
806static int ccdc_getfid(void)
807{
808 return (regr(CCDC_SYN_MODE) >> 15) & 1;
809}
810
811/* misc operations */
812static inline void ccdc_setfbaddr(unsigned long addr)
813{
814 regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
815}
816
817static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
818{
819 ccdc_if_type = params->if_type;
820
821 switch (params->if_type) {
822 case VPFE_BT656:
823 case VPFE_YCBCR_SYNC_16:
824 case VPFE_YCBCR_SYNC_8:
825 ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
826 ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
827 break;
828 default:
829 /* TODO add support for raw bayer here */
830 return -EINVAL;
831 }
832 return 0;
833}
834
835static struct ccdc_hw_device ccdc_hw_dev = {
836 .name = "DM6446 CCDC",
837 .owner = THIS_MODULE,
838 .hw_ops = {
839 .open = ccdc_open,
840 .close = ccdc_close,
841 .set_ccdc_base = ccdc_set_ccdc_base,
842 .reset = ccdc_sbl_reset,
843 .enable = ccdc_enable,
844 .set_hw_if_params = ccdc_set_hw_if_params,
845 .set_params = ccdc_set_params,
846 .configure = ccdc_configure,
847 .set_buftype = ccdc_set_buftype,
848 .get_buftype = ccdc_get_buftype,
849 .enum_pix = ccdc_enum_pix,
850 .set_pixel_format = ccdc_set_pixel_format,
851 .get_pixel_format = ccdc_get_pixel_format,
852 .set_frame_format = ccdc_set_frame_format,
853 .get_frame_format = ccdc_get_frame_format,
854 .set_image_window = ccdc_set_image_window,
855 .get_image_window = ccdc_get_image_window,
856 .get_line_length = ccdc_get_line_length,
857 .setfbaddr = ccdc_setfbaddr,
858 .getfid = ccdc_getfid,
859 },
860};
861
862static int dm644x_ccdc_init(void)
863{
864 printk(KERN_NOTICE "dm644x_ccdc_init\n");
865 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
866 return -1;
867 printk(KERN_NOTICE "%s is registered with vpfe.\n",
868 ccdc_hw_dev.name);
869 return 0;
870}
871
872static void dm644x_ccdc_exit(void)
873{
874 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
875}
876
877module_init(dm644x_ccdc_init);
878module_exit(dm644x_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
new file mode 100644
index 000000000000..6e5d05324466
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc_regs.h
@@ -0,0 +1,145 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM644X_CCDC_REGS_H
19#define _DM644X_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define CCDC_PID 0x0
25#define CCDC_PCR 0x4
26#define CCDC_SYN_MODE 0x8
27#define CCDC_HD_VD_WID 0xc
28#define CCDC_PIX_LINES 0x10
29#define CCDC_HORZ_INFO 0x14
30#define CCDC_VERT_START 0x18
31#define CCDC_VERT_LINES 0x1c
32#define CCDC_CULLING 0x20
33#define CCDC_HSIZE_OFF 0x24
34#define CCDC_SDOFST 0x28
35#define CCDC_SDR_ADDR 0x2c
36#define CCDC_CLAMP 0x30
37#define CCDC_DCSUB 0x34
38#define CCDC_COLPTN 0x38
39#define CCDC_BLKCMP 0x3c
40#define CCDC_FPC 0x40
41#define CCDC_FPC_ADDR 0x44
42#define CCDC_VDINT 0x48
43#define CCDC_ALAW 0x4c
44#define CCDC_REC656IF 0x50
45#define CCDC_CCDCFG 0x54
46#define CCDC_FMTCFG 0x58
47#define CCDC_FMT_HORZ 0x5c
48#define CCDC_FMT_VERT 0x60
49#define CCDC_FMT_ADDR0 0x64
50#define CCDC_FMT_ADDR1 0x68
51#define CCDC_FMT_ADDR2 0x6c
52#define CCDC_FMT_ADDR3 0x70
53#define CCDC_FMT_ADDR4 0x74
54#define CCDC_FMT_ADDR5 0x78
55#define CCDC_FMT_ADDR6 0x7c
56#define CCDC_FMT_ADDR7 0x80
57#define CCDC_PRGEVEN_0 0x84
58#define CCDC_PRGEVEN_1 0x88
59#define CCDC_PRGODD_0 0x8c
60#define CCDC_PRGODD_1 0x90
61#define CCDC_VP_OUT 0x94
62
63
64/***************************************************************
65* Define for various register bit mask and shifts for CCDC
66****************************************************************/
67#define CCDC_FID_POL_MASK 1
68#define CCDC_FID_POL_SHIFT 4
69#define CCDC_HD_POL_MASK 1
70#define CCDC_HD_POL_SHIFT 3
71#define CCDC_VD_POL_MASK 1
72#define CCDC_VD_POL_SHIFT 2
73#define CCDC_HSIZE_OFF_MASK 0xffffffe0
74#define CCDC_32BYTE_ALIGN_VAL 31
75#define CCDC_FRM_FMT_MASK 0x1
76#define CCDC_FRM_FMT_SHIFT 7
77#define CCDC_DATA_SZ_MASK 7
78#define CCDC_DATA_SZ_SHIFT 8
79#define CCDC_PIX_FMT_MASK 3
80#define CCDC_PIX_FMT_SHIFT 12
81#define CCDC_VP2SDR_DISABLE 0xFFFBFFFF
82#define CCDC_WEN_ENABLE (1 << 17)
83#define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF
84#define CCDC_VDHDEN_ENABLE (1 << 16)
85#define CCDC_LPF_ENABLE (1 << 14)
86#define CCDC_ALAW_ENABLE (1 << 3)
87#define CCDC_ALAW_GAMA_WD_MASK 7
88#define CCDC_BLK_CLAMP_ENABLE (1 << 31)
89#define CCDC_BLK_SGAIN_MASK 0x1F
90#define CCDC_BLK_ST_PXL_MASK 0x7FFF
91#define CCDC_BLK_ST_PXL_SHIFT 10
92#define CCDC_BLK_SAMPLE_LN_MASK 7
93#define CCDC_BLK_SAMPLE_LN_SHIFT 28
94#define CCDC_BLK_SAMPLE_LINE_MASK 7
95#define CCDC_BLK_SAMPLE_LINE_SHIFT 25
96#define CCDC_BLK_DC_SUB_MASK 0x03FFF
97#define CCDC_BLK_COMP_MASK 0xFF
98#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
99#define CCDC_BLK_COMP_GR_COMP_SHIFT 16
100#define CCDC_BLK_COMP_R_COMP_SHIFT 24
101#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
102#define CCDC_FPC_ENABLE (1 << 15)
103#define CCDC_FPC_DISABLE 0
104#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
105#define CCDC_DATA_PACK_ENABLE (1 << 11)
106#define CCDC_FMTCFG_VPIN_MASK 7
107#define CCDC_FMTCFG_VPIN_SHIFT 12
108#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
109#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
110#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
111#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
112#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
113#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
114#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
115#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
116#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
117#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
118#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
119#define CCDC_HORZ_INFO_SPH_SHIFT 16
120#define CCDC_VERT_START_SLV0_SHIFT 16
121#define CCDC_VDINT_VDINT0_SHIFT 16
122#define CCDC_VDINT_VDINT1_MASK 0xFFFF
123#define CCDC_PPC_RAW 1
124#define CCDC_DCSUB_DEFAULT_VAL 0
125#define CCDC_CLAMP_DEFAULT_VAL 0
126#define CCDC_ENABLE_VIDEO_PORT 0x8000
127#define CCDC_DISABLE_VIDEO_PORT 0
128#define CCDC_COLPTN_VAL 0xBB11BB11
129#define CCDC_TWO_BYTES_PER_PIXEL 2
130#define CCDC_INTERLACED_IMAGE_INVERT 0x4B6D
131#define CCDC_INTERLACED_NO_IMAGE_INVERT 0x0249
132#define CCDC_PROGRESSIVE_IMAGE_INVERT 0x4000
133#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT 0
134#define CCDC_INTERLACED_HEIGHT_SHIFT 1
135#define CCDC_SYN_MODE_INPMOD_SHIFT 12
136#define CCDC_SYN_MODE_INPMOD_MASK 3
137#define CCDC_SYN_MODE_8BITS (7 << 8)
138#define CCDC_SYN_FLDMODE_MASK 1
139#define CCDC_SYN_FLDMODE_SHIFT 7
140#define CCDC_REC656IF_BT656_EN 3
141#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
142#define CCDC_CCDCFG_Y8POS_SHIFT 11
143#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
144#define CCDC_NO_CULLING 0xffff00ff
145#endif
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
new file mode 100644
index 000000000000..402ce43ef38e
--- /dev/null
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -0,0 +1,2124 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Driver name : VPFE Capture driver
19 * VPFE Capture driver allows applications to capture and stream video
20 * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
21 * TVP5146 or Raw Bayer RGB image data from an image sensor
22 * such as Microns' MT9T001, MT9T031 etc.
23 *
24 * These SoCs have, in common, a Video Processing Subsystem (VPSS) that
25 * consists of a Video Processing Front End (VPFE) for capturing
26 * video/raw image data and Video Processing Back End (VPBE) for displaying
27 * YUV data through an in-built analog encoder or Digital LCD port. This
28 * driver is for capture through VPFE. A typical EVM using these SoCs have
29 * following high level configuration.
30 *
31 *
32 * decoder(TVP5146/ YUV/
33 * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
34 * data input | |
35 * V |
36 * SDRAM |
37 * V
38 * Image Processor
39 * |
40 * V
41 * SDRAM
42 * The data flow happens from a decoder connected to the VPFE over a
43 * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
44 * and to the input of VPFE through an optional MUX (if more inputs are
45 * to be interfaced on the EVM). The input data is first passed through
46 * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
47 * does very little or no processing on YUV data and does pre-process Raw
48 * Bayer RGB data through modules such as Defect Pixel Correction (DFC)
49 * Color Space Conversion (CSC), data gain/offset etc. After this, data
50 * can be written to SDRAM or can be connected to the image processing
51 * block such as IPIPE (on DM355 only).
52 *
53 * Features supported
54 * - MMAP IO
55 * - Capture using TVP5146 over BT.656
56 * - support for interfacing decoders using sub device model
57 * - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
58 * data capture to SDRAM.
59 * TODO list
60 * - Support multiple REQBUF after open
61 * - Support for de-allocating buffers through REQBUF
62 * - Support for Raw Bayer RGB capture
63 * - Support for chaining Image Processor
64 * - Support for static allocation of buffers
65 * - Support for USERPTR IO
66 * - Support for STREAMON before QBUF
67 * - Support for control ioctls
68 */
69#include <linux/module.h>
70#include <linux/init.h>
71#include <linux/platform_device.h>
72#include <linux/interrupt.h>
73#include <linux/version.h>
74#include <media/v4l2-common.h>
75#include <linux/io.h>
76#include <media/davinci/vpfe_capture.h>
77#include "ccdc_hw_device.h"
78
79static int debug;
80static u32 numbuffers = 3;
81static u32 bufsize = (720 * 576 * 2);
82
83module_param(numbuffers, uint, S_IRUGO);
84module_param(bufsize, uint, S_IRUGO);
85module_param(debug, int, 0644);
86
87MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
88MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
89MODULE_PARM_DESC(debug, "Debug level 0-1");
90
91MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
92MODULE_LICENSE("GPL");
93MODULE_AUTHOR("Texas Instruments");
94
95/* standard information */
96struct vpfe_standard {
97 v4l2_std_id std_id;
98 unsigned int width;
99 unsigned int height;
100 struct v4l2_fract pixelaspect;
101 /* 0 - progressive, 1 - interlaced */
102 int frame_format;
103};
104
105/* ccdc configuration */
106struct ccdc_config {
107 /* This make sure vpfe is probed and ready to go */
108 int vpfe_probed;
109 /* name of ccdc device */
110 char name[32];
111 /* for storing mem maps for CCDC */
112 int ccdc_addr_size;
113 void *__iomem ccdc_addr;
114};
115
116/* data structures */
117static struct vpfe_config_params config_params = {
118 .min_numbuffers = 3,
119 .numbuffers = 3,
120 .min_bufsize = 720 * 480 * 2,
121 .device_bufsize = 720 * 576 * 2,
122};
123
124/* ccdc device registered */
125static struct ccdc_hw_device *ccdc_dev;
126/* lock for accessing ccdc information */
127static DEFINE_MUTEX(ccdc_lock);
128/* ccdc configuration */
129static struct ccdc_config *ccdc_cfg;
130
131const struct vpfe_standard vpfe_standards[] = {
132 {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
133 {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
134};
135
136/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
137static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
138 {
139 .fmtdesc = {
140 .index = 0,
141 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
142 .description = "Bayer GrRBGb 8bit A-Law compr.",
143 .pixelformat = V4L2_PIX_FMT_SBGGR8,
144 },
145 .bpp = 1,
146 },
147 {
148 .fmtdesc = {
149 .index = 1,
150 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
151 .description = "Bayer GrRBGb - 16bit",
152 .pixelformat = V4L2_PIX_FMT_SBGGR16,
153 },
154 .bpp = 2,
155 },
156 {
157 .fmtdesc = {
158 .index = 2,
159 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
160 .description = "Bayer GrRBGb 8bit DPCM compr.",
161 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
162 },
163 .bpp = 1,
164 },
165 {
166 .fmtdesc = {
167 .index = 3,
168 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
169 .description = "YCbCr 4:2:2 Interleaved UYVY",
170 .pixelformat = V4L2_PIX_FMT_UYVY,
171 },
172 .bpp = 2,
173 },
174 {
175 .fmtdesc = {
176 .index = 4,
177 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
178 .description = "YCbCr 4:2:2 Interleaved YUYV",
179 .pixelformat = V4L2_PIX_FMT_YUYV,
180 },
181 .bpp = 2,
182 },
183 {
184 .fmtdesc = {
185 .index = 5,
186 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
187 .description = "Y/CbCr 4:2:0 - Semi planar",
188 .pixelformat = V4L2_PIX_FMT_NV12,
189 },
190 .bpp = 1,
191 },
192};
193
194/*
195 * vpfe_lookup_pix_format()
196 * lookup an entry in the vpfe pix format table based on pix_format
197 */
198static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
199{
200 int i;
201
202 for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
203 if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
204 return &vpfe_pix_fmts[i];
205 }
206 return NULL;
207}
208
209/*
210 * vpfe_register_ccdc_device. CCDC module calls this to
211 * register with vpfe capture
212 */
213int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
214{
215 int ret = 0;
216 printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
217
218 BUG_ON(!dev->hw_ops.open);
219 BUG_ON(!dev->hw_ops.enable);
220 BUG_ON(!dev->hw_ops.set_hw_if_params);
221 BUG_ON(!dev->hw_ops.configure);
222 BUG_ON(!dev->hw_ops.set_buftype);
223 BUG_ON(!dev->hw_ops.get_buftype);
224 BUG_ON(!dev->hw_ops.enum_pix);
225 BUG_ON(!dev->hw_ops.set_frame_format);
226 BUG_ON(!dev->hw_ops.get_frame_format);
227 BUG_ON(!dev->hw_ops.get_pixel_format);
228 BUG_ON(!dev->hw_ops.set_pixel_format);
229 BUG_ON(!dev->hw_ops.set_params);
230 BUG_ON(!dev->hw_ops.set_image_window);
231 BUG_ON(!dev->hw_ops.get_image_window);
232 BUG_ON(!dev->hw_ops.get_line_length);
233 BUG_ON(!dev->hw_ops.setfbaddr);
234 BUG_ON(!dev->hw_ops.getfid);
235
236 mutex_lock(&ccdc_lock);
237 if (NULL == ccdc_cfg) {
238 /*
239 * TODO. Will this ever happen? if so, we need to fix it.
240 * Proabably we need to add the request to a linked list and
241 * walk through it during vpfe probe
242 */
243 printk(KERN_ERR "vpfe capture not initialized\n");
244 ret = -1;
245 goto unlock;
246 }
247
248 if (strcmp(dev->name, ccdc_cfg->name)) {
249 /* ignore this ccdc */
250 ret = -1;
251 goto unlock;
252 }
253
254 if (ccdc_dev) {
255 printk(KERN_ERR "ccdc already registered\n");
256 ret = -1;
257 goto unlock;
258 }
259
260 ccdc_dev = dev;
261 dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
262 ccdc_cfg->ccdc_addr_size);
263unlock:
264 mutex_unlock(&ccdc_lock);
265 return ret;
266}
267EXPORT_SYMBOL(vpfe_register_ccdc_device);
268
269/*
270 * vpfe_unregister_ccdc_device. CCDC module calls this to
271 * unregister with vpfe capture
272 */
273void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
274{
275 if (NULL == dev) {
276 printk(KERN_ERR "invalid ccdc device ptr\n");
277 return;
278 }
279
280 printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
281 dev->name);
282
283 if (strcmp(dev->name, ccdc_cfg->name)) {
284 /* ignore this ccdc */
285 return;
286 }
287
288 mutex_lock(&ccdc_lock);
289 ccdc_dev = NULL;
290 mutex_unlock(&ccdc_lock);
291 return;
292}
293EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
294
295/*
296 * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
297 */
298static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
299 struct v4l2_format *f)
300{
301 struct v4l2_rect image_win;
302 enum ccdc_buftype buf_type;
303 enum ccdc_frmfmt frm_fmt;
304
305 memset(f, 0, sizeof(*f));
306 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
307 ccdc_dev->hw_ops.get_image_window(&image_win);
308 f->fmt.pix.width = image_win.width;
309 f->fmt.pix.height = image_win.height;
310 f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
311 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
312 f->fmt.pix.height;
313 buf_type = ccdc_dev->hw_ops.get_buftype();
314 f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
315 frm_fmt = ccdc_dev->hw_ops.get_frame_format();
316 if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
317 f->fmt.pix.field = V4L2_FIELD_NONE;
318 else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
319 if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
320 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
321 else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
322 f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
323 else {
324 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
325 return -EINVAL;
326 }
327 } else {
328 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
329 return -EINVAL;
330 }
331 return 0;
332}
333
334/*
335 * vpfe_config_ccdc_image_format()
336 * For a pix format, configure ccdc to setup the capture
337 */
338static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
339{
340 enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
341 int ret = 0;
342
343 if (ccdc_dev->hw_ops.set_pixel_format(
344 vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
345 v4l2_err(&vpfe_dev->v4l2_dev,
346 "couldn't set pix format in ccdc\n");
347 return -EINVAL;
348 }
349 /* configure the image window */
350 ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
351
352 switch (vpfe_dev->fmt.fmt.pix.field) {
353 case V4L2_FIELD_INTERLACED:
354 /* do nothing, since it is default */
355 ret = ccdc_dev->hw_ops.set_buftype(
356 CCDC_BUFTYPE_FLD_INTERLEAVED);
357 break;
358 case V4L2_FIELD_NONE:
359 frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
360 /* buffer type only applicable for interlaced scan */
361 break;
362 case V4L2_FIELD_SEQ_TB:
363 ret = ccdc_dev->hw_ops.set_buftype(
364 CCDC_BUFTYPE_FLD_SEPARATED);
365 break;
366 default:
367 return -EINVAL;
368 }
369
370 /* set the frame format */
371 if (!ret)
372 ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
373 return ret;
374}
375/*
376 * vpfe_config_image_format()
377 * For a given standard, this functions sets up the default
378 * pix format & crop values in the vpfe device and ccdc. It first
379 * starts with defaults based values from the standard table.
380 * It then checks if sub device support g_fmt and then override the
381 * values based on that.Sets crop values to match with scan resolution
382 * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
383 * values in ccdc
384 */
385static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
386 const v4l2_std_id *std_id)
387{
388 struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
389 int i, ret = 0;
390
391 for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
392 if (vpfe_standards[i].std_id & *std_id) {
393 vpfe_dev->std_info.active_pixels =
394 vpfe_standards[i].width;
395 vpfe_dev->std_info.active_lines =
396 vpfe_standards[i].height;
397 vpfe_dev->std_info.frame_format =
398 vpfe_standards[i].frame_format;
399 vpfe_dev->std_index = i;
400 break;
401 }
402 }
403
404 if (i == ARRAY_SIZE(vpfe_standards)) {
405 v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
406 return -EINVAL;
407 }
408
409 vpfe_dev->crop.top = 0;
410 vpfe_dev->crop.left = 0;
411 vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
412 vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
413 vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width;
414 vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height;
415
416 /* first field and frame format based on standard frame format */
417 if (vpfe_dev->std_info.frame_format) {
418 vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
419 /* assume V4L2_PIX_FMT_UYVY as default */
420 vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
421 } else {
422 vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE;
423 /* assume V4L2_PIX_FMT_SBGGR8 */
424 vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
425 }
426
427 /* if sub device supports g_fmt, override the defaults */
428 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
429 sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt);
430
431 if (ret && ret != -ENOIOCTLCMD) {
432 v4l2_err(&vpfe_dev->v4l2_dev,
433 "error in getting g_fmt from sub device\n");
434 return ret;
435 }
436
437 /* Sets the values in CCDC */
438 ret = vpfe_config_ccdc_image_format(vpfe_dev);
439 if (ret)
440 return ret;
441
442 /* Update the values of sizeimage and bytesperline */
443 if (!ret) {
444 vpfe_dev->fmt.fmt.pix.bytesperline =
445 ccdc_dev->hw_ops.get_line_length();
446 vpfe_dev->fmt.fmt.pix.sizeimage =
447 vpfe_dev->fmt.fmt.pix.bytesperline *
448 vpfe_dev->fmt.fmt.pix.height;
449 }
450 return ret;
451}
452
453static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
454{
455 int ret = 0;
456
457 /* set first input of current subdevice as the current input */
458 vpfe_dev->current_input = 0;
459
460 /* set default standard */
461 vpfe_dev->std_index = 0;
462
463 /* Configure the default format information */
464 ret = vpfe_config_image_format(vpfe_dev,
465 &vpfe_standards[vpfe_dev->std_index].std_id);
466 if (ret)
467 return ret;
468
469 /* now open the ccdc device to initialize it */
470 mutex_lock(&ccdc_lock);
471 if (NULL == ccdc_dev) {
472 v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
473 ret = -ENODEV;
474 goto unlock;
475 }
476
477 if (!try_module_get(ccdc_dev->owner)) {
478 v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
479 ret = -ENODEV;
480 goto unlock;
481 }
482 ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
483 if (!ret)
484 vpfe_dev->initialized = 1;
485unlock:
486 mutex_unlock(&ccdc_lock);
487 return ret;
488}
489
490/*
491 * vpfe_open : It creates object of file handle structure and
492 * stores it in private_data member of filepointer
493 */
494static int vpfe_open(struct file *file)
495{
496 struct vpfe_device *vpfe_dev = video_drvdata(file);
497 struct vpfe_fh *fh;
498
499 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
500
501 if (!vpfe_dev->cfg->num_subdevs) {
502 v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
503 return -ENODEV;
504 }
505
506 /* Allocate memory for the file handle object */
507 fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
508 if (NULL == fh) {
509 v4l2_err(&vpfe_dev->v4l2_dev,
510 "unable to allocate memory for file handle object\n");
511 return -ENOMEM;
512 }
513 /* store pointer to fh in private_data member of file */
514 file->private_data = fh;
515 fh->vpfe_dev = vpfe_dev;
516 mutex_lock(&vpfe_dev->lock);
517 /* If decoder is not initialized. initialize it */
518 if (!vpfe_dev->initialized) {
519 if (vpfe_initialize_device(vpfe_dev)) {
520 mutex_unlock(&vpfe_dev->lock);
521 return -ENODEV;
522 }
523 }
524 /* Increment device usrs counter */
525 vpfe_dev->usrs++;
526 /* Set io_allowed member to false */
527 fh->io_allowed = 0;
528 /* Initialize priority of this instance to default priority */
529 fh->prio = V4L2_PRIORITY_UNSET;
530 v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
531 mutex_unlock(&vpfe_dev->lock);
532 return 0;
533}
534
535static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
536{
537 unsigned long addr;
538
539 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
540 struct videobuf_buffer, queue);
541 list_del(&vpfe_dev->next_frm->queue);
542 vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
543 addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
544 ccdc_dev->hw_ops.setfbaddr(addr);
545}
546
547static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
548{
549 struct timeval timevalue;
550
551 do_gettimeofday(&timevalue);
552 vpfe_dev->cur_frm->ts = timevalue;
553 vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
554 vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
555 wake_up_interruptible(&vpfe_dev->cur_frm->done);
556 vpfe_dev->cur_frm = vpfe_dev->next_frm;
557}
558
559/* ISR for VINT0*/
560static irqreturn_t vpfe_isr(int irq, void *dev_id)
561{
562 struct vpfe_device *vpfe_dev = dev_id;
563 enum v4l2_field field;
564 unsigned long addr;
565 int fid;
566
567 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
568 field = vpfe_dev->fmt.fmt.pix.field;
569
570 /* if streaming not started, don't do anything */
571 if (!vpfe_dev->started)
572 return IRQ_HANDLED;
573
574 /* only for 6446 this will be applicable */
575 if (NULL != ccdc_dev->hw_ops.reset)
576 ccdc_dev->hw_ops.reset();
577
578 if (field == V4L2_FIELD_NONE) {
579 /* handle progressive frame capture */
580 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
581 "frame format is progressive...\n");
582 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
583 vpfe_process_buffer_complete(vpfe_dev);
584 return IRQ_HANDLED;
585 }
586
587 /* interlaced or TB capture check which field we are in hardware */
588 fid = ccdc_dev->hw_ops.getfid();
589
590 /* switch the software maintained field id */
591 vpfe_dev->field_id ^= 1;
592 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
593 fid, vpfe_dev->field_id);
594 if (fid == vpfe_dev->field_id) {
595 /* we are in-sync here,continue */
596 if (fid == 0) {
597 /*
598 * One frame is just being captured. If the next frame
599 * is available, release the current frame and move on
600 */
601 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
602 vpfe_process_buffer_complete(vpfe_dev);
603 /*
604 * based on whether the two fields are stored
605 * interleavely or separately in memory, reconfigure
606 * the CCDC memory address
607 */
608 if (field == V4L2_FIELD_SEQ_TB) {
609 addr =
610 videobuf_to_dma_contig(vpfe_dev->cur_frm);
611 addr += vpfe_dev->field_off;
612 ccdc_dev->hw_ops.setfbaddr(addr);
613 }
614 return IRQ_HANDLED;
615 }
616 /*
617 * if one field is just being captured configure
618 * the next frame get the next frame from the empty
619 * queue if no frame is available hold on to the
620 * current buffer
621 */
622 spin_lock(&vpfe_dev->dma_queue_lock);
623 if (!list_empty(&vpfe_dev->dma_queue) &&
624 vpfe_dev->cur_frm == vpfe_dev->next_frm)
625 vpfe_schedule_next_buffer(vpfe_dev);
626 spin_unlock(&vpfe_dev->dma_queue_lock);
627 } else if (fid == 0) {
628 /*
629 * out of sync. Recover from any hardware out-of-sync.
630 * May loose one frame
631 */
632 vpfe_dev->field_id = fid;
633 }
634 return IRQ_HANDLED;
635}
636
637/* vdint1_isr - isr handler for VINT1 interrupt */
638static irqreturn_t vdint1_isr(int irq, void *dev_id)
639{
640 struct vpfe_device *vpfe_dev = dev_id;
641
642 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
643
644 /* if streaming not started, don't do anything */
645 if (!vpfe_dev->started)
646 return IRQ_HANDLED;
647
648 spin_lock(&vpfe_dev->dma_queue_lock);
649 if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
650 !list_empty(&vpfe_dev->dma_queue) &&
651 vpfe_dev->cur_frm == vpfe_dev->next_frm)
652 vpfe_schedule_next_buffer(vpfe_dev);
653 spin_unlock(&vpfe_dev->dma_queue_lock);
654 return IRQ_HANDLED;
655}
656
657static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
658{
659 enum ccdc_frmfmt frame_format;
660
661 frame_format = ccdc_dev->hw_ops.get_frame_format();
662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
663 free_irq(IRQ_VDINT1, vpfe_dev);
664}
665
666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
667{
668 enum ccdc_frmfmt frame_format;
669
670 frame_format = ccdc_dev->hw_ops.get_frame_format();
671 if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
672 return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
673 IRQF_DISABLED, "vpfe_capture1",
674 vpfe_dev);
675 }
676 return 0;
677}
678
679/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
680static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
681{
682 vpfe_dev->started = 0;
683 ccdc_dev->hw_ops.enable(0);
684 if (ccdc_dev->hw_ops.enable_out_to_sdram)
685 ccdc_dev->hw_ops.enable_out_to_sdram(0);
686}
687
688/*
689 * vpfe_release : This function deletes buffer queue, frees the
690 * buffers and the vpfe file handle
691 */
692static int vpfe_release(struct file *file)
693{
694 struct vpfe_device *vpfe_dev = video_drvdata(file);
695 struct vpfe_fh *fh = file->private_data;
696 struct vpfe_subdev_info *sdinfo;
697 int ret;
698
699 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
700
701 /* Get the device lock */
702 mutex_lock(&vpfe_dev->lock);
703 /* if this instance is doing IO */
704 if (fh->io_allowed) {
705 if (vpfe_dev->started) {
706 sdinfo = vpfe_dev->current_subdev;
707 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
708 sdinfo->grp_id,
709 video, s_stream, 0);
710 if (ret && (ret != -ENOIOCTLCMD))
711 v4l2_err(&vpfe_dev->v4l2_dev,
712 "stream off failed in subdev\n");
713 vpfe_stop_ccdc_capture(vpfe_dev);
714 vpfe_detach_irq(vpfe_dev);
715 videobuf_streamoff(&vpfe_dev->buffer_queue);
716 }
717 vpfe_dev->io_usrs = 0;
718 vpfe_dev->numbuffers = config_params.numbuffers;
719 }
720
721 /* Decrement device usrs counter */
722 vpfe_dev->usrs--;
723 /* Close the priority */
724 v4l2_prio_close(&vpfe_dev->prio, &fh->prio);
725 /* If this is the last file handle */
726 if (!vpfe_dev->usrs) {
727 vpfe_dev->initialized = 0;
728 if (ccdc_dev->hw_ops.close)
729 ccdc_dev->hw_ops.close(vpfe_dev->pdev);
730 module_put(ccdc_dev->owner);
731 }
732 mutex_unlock(&vpfe_dev->lock);
733 file->private_data = NULL;
734 /* Free memory allocated to file handle object */
735 kfree(fh);
736 return 0;
737}
738
739/*
740 * vpfe_mmap : It is used to map kernel space buffers
741 * into user spaces
742 */
743static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
744{
745 /* Get the device object and file handle object */
746 struct vpfe_device *vpfe_dev = video_drvdata(file);
747
748 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
749
750 return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
751}
752
753/*
754 * vpfe_poll: It is used for select/poll system call
755 */
756static unsigned int vpfe_poll(struct file *file, poll_table *wait)
757{
758 struct vpfe_device *vpfe_dev = video_drvdata(file);
759
760 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
761
762 if (vpfe_dev->started)
763 return videobuf_poll_stream(file,
764 &vpfe_dev->buffer_queue, wait);
765 return 0;
766}
767
768/* vpfe capture driver file operations */
769static const struct v4l2_file_operations vpfe_fops = {
770 .owner = THIS_MODULE,
771 .open = vpfe_open,
772 .release = vpfe_release,
773 .unlocked_ioctl = video_ioctl2,
774 .mmap = vpfe_mmap,
775 .poll = vpfe_poll
776};
777
778/*
779 * vpfe_check_format()
780 * This function adjust the input pixel format as per hardware
781 * capabilities and update the same in pixfmt.
782 * Following algorithm used :-
783 *
784 * If given pixformat is not in the vpfe list of pix formats or not
785 * supported by the hardware, current value of pixformat in the device
786 * is used
787 * If given field is not supported, then current field is used. If field
788 * is different from current, then it is matched with that from sub device.
789 * Minimum height is 2 lines for interlaced or tb field and 1 line for
790 * progressive. Maximum height is clamped to active active lines of scan
791 * Minimum width is 32 bytes in memory and width is clamped to active
792 * pixels of scan.
793 * bytesperline is a multiple of 32.
794 */
795static const struct vpfe_pixel_format *
796 vpfe_check_format(struct vpfe_device *vpfe_dev,
797 struct v4l2_pix_format *pixfmt)
798{
799 u32 min_height = 1, min_width = 32, max_width, max_height;
800 const struct vpfe_pixel_format *vpfe_pix_fmt;
801 u32 pix;
802 int temp, found;
803
804 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
805 if (NULL == vpfe_pix_fmt) {
806 /*
807 * use current pixel format in the vpfe device. We
808 * will find this pix format in the table
809 */
810 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
811 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
812 }
813
814 /* check if hw supports it */
815 temp = 0;
816 found = 0;
817 while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
818 if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
819 found = 1;
820 break;
821 }
822 temp++;
823 }
824
825 if (!found) {
826 /* use current pixel format */
827 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
828 /*
829 * Since this is currently used in the vpfe device, we
830 * will find this pix format in the table
831 */
832 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
833 }
834
835 /* check what field format is supported */
836 if (pixfmt->field == V4L2_FIELD_ANY) {
837 /* if field is any, use current value as default */
838 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
839 }
840
841 /*
842 * if field is not same as current field in the vpfe device
843 * try matching the field with the sub device field
844 */
845 if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
846 /*
847 * If field value is not in the supported fields, use current
848 * field used in the device as default
849 */
850 switch (pixfmt->field) {
851 case V4L2_FIELD_INTERLACED:
852 case V4L2_FIELD_SEQ_TB:
853 /* if sub device is supporting progressive, use that */
854 if (!vpfe_dev->std_info.frame_format)
855 pixfmt->field = V4L2_FIELD_NONE;
856 break;
857 case V4L2_FIELD_NONE:
858 if (vpfe_dev->std_info.frame_format)
859 pixfmt->field = V4L2_FIELD_INTERLACED;
860 break;
861
862 default:
863 /* use current field as default */
864 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
865 break;
866 }
867 }
868
869 /* Now adjust image resolutions supported */
870 if (pixfmt->field == V4L2_FIELD_INTERLACED ||
871 pixfmt->field == V4L2_FIELD_SEQ_TB)
872 min_height = 2;
873
874 max_width = vpfe_dev->std_info.active_pixels;
875 max_height = vpfe_dev->std_info.active_lines;
876 min_width /= vpfe_pix_fmt->bpp;
877
878 v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
879 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
880
881 pixfmt->width = clamp((pixfmt->width), min_width, max_width);
882 pixfmt->height = clamp((pixfmt->height), min_height, max_height);
883
884 /* If interlaced, adjust height to be a multiple of 2 */
885 if (pixfmt->field == V4L2_FIELD_INTERLACED)
886 pixfmt->height &= (~1);
887 /*
888 * recalculate bytesperline and sizeimage since width
889 * and height might have changed
890 */
891 pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
892 & ~31);
893 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
894 pixfmt->sizeimage =
895 pixfmt->bytesperline * pixfmt->height +
896 ((pixfmt->bytesperline * pixfmt->height) >> 1);
897 else
898 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
899
900 v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height ="
901 " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
902 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
903 pixfmt->bytesperline, pixfmt->sizeimage);
904 return vpfe_pix_fmt;
905}
906
907static int vpfe_querycap(struct file *file, void *priv,
908 struct v4l2_capability *cap)
909{
910 struct vpfe_device *vpfe_dev = video_drvdata(file);
911
912 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
913
914 cap->version = VPFE_CAPTURE_VERSION_CODE;
915 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
916 strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
917 strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
918 strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
919 return 0;
920}
921
922static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
923 struct v4l2_format *fmt)
924{
925 struct vpfe_device *vpfe_dev = video_drvdata(file);
926 int ret = 0;
927
928 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
929 /* Fill in the information about format */
930 *fmt = vpfe_dev->fmt;
931 return ret;
932}
933
934static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv,
935 struct v4l2_fmtdesc *fmt)
936{
937 struct vpfe_device *vpfe_dev = video_drvdata(file);
938 const struct vpfe_pixel_format *pix_fmt;
939 int temp_index;
940 u32 pix;
941
942 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
943
944 if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
945 return -EINVAL;
946
947 /* Fill in the information about format */
948 pix_fmt = vpfe_lookup_pix_format(pix);
949 if (NULL != pix_fmt) {
950 temp_index = fmt->index;
951 *fmt = pix_fmt->fmtdesc;
952 fmt->index = temp_index;
953 return 0;
954 }
955 return -EINVAL;
956}
957
958static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
959 struct v4l2_format *fmt)
960{
961 struct vpfe_device *vpfe_dev = video_drvdata(file);
962 const struct vpfe_pixel_format *pix_fmts;
963 int ret = 0;
964
965 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
966
967 /* If streaming is started, return error */
968 if (vpfe_dev->started) {
969 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
970 return -EBUSY;
971 }
972
973 /* Check for valid frame format */
974 pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
975
976 if (NULL == pix_fmts)
977 return -EINVAL;
978
979 /* store the pixel format in the device object */
980 ret = mutex_lock_interruptible(&vpfe_dev->lock);
981 if (ret)
982 return ret;
983
984 /* First detach any IRQ if currently attached */
985 vpfe_detach_irq(vpfe_dev);
986 vpfe_dev->fmt = *fmt;
987 /* set image capture parameters in the ccdc */
988 ret = vpfe_config_ccdc_image_format(vpfe_dev);
989 mutex_unlock(&vpfe_dev->lock);
990 return ret;
991}
992
993static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
994 struct v4l2_format *f)
995{
996 struct vpfe_device *vpfe_dev = video_drvdata(file);
997 const struct vpfe_pixel_format *pix_fmts;
998
999 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
1000
1001 pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
1002 if (NULL == pix_fmts)
1003 return -EINVAL;
1004 return 0;
1005}
1006
1007/*
1008 * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
1009 * given app input index
1010 */
1011static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
1012 int *subdev_index,
1013 int *subdev_input_index,
1014 int app_input_index)
1015{
1016 struct vpfe_config *cfg = vpfe_dev->cfg;
1017 struct vpfe_subdev_info *sdinfo;
1018 int i, j = 0;
1019
1020 for (i = 0; i < cfg->num_subdevs; i++) {
1021 sdinfo = &cfg->sub_devs[i];
1022 if (app_input_index < (j + sdinfo->num_inputs)) {
1023 *subdev_index = i;
1024 *subdev_input_index = app_input_index - j;
1025 return 0;
1026 }
1027 j += sdinfo->num_inputs;
1028 }
1029 return -EINVAL;
1030}
1031
1032/*
1033 * vpfe_get_app_input - Get app input index for a given subdev input index
1034 * driver stores the input index of the current sub device and translate it
1035 * when application request the current input
1036 */
1037static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
1038 int *app_input_index)
1039{
1040 struct vpfe_config *cfg = vpfe_dev->cfg;
1041 struct vpfe_subdev_info *sdinfo;
1042 int i, j = 0;
1043
1044 for (i = 0; i < cfg->num_subdevs; i++) {
1045 sdinfo = &cfg->sub_devs[i];
1046 if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
1047 if (vpfe_dev->current_input >= sdinfo->num_inputs)
1048 return -1;
1049 *app_input_index = j + vpfe_dev->current_input;
1050 return 0;
1051 }
1052 j += sdinfo->num_inputs;
1053 }
1054 return -EINVAL;
1055}
1056
1057static int vpfe_enum_input(struct file *file, void *priv,
1058 struct v4l2_input *inp)
1059{
1060 struct vpfe_device *vpfe_dev = video_drvdata(file);
1061 struct vpfe_subdev_info *sdinfo;
1062 int subdev, index ;
1063
1064 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
1065
1066 if (vpfe_get_subdev_input_index(vpfe_dev,
1067 &subdev,
1068 &index,
1069 inp->index) < 0) {
1070 v4l2_err(&vpfe_dev->v4l2_dev, "input information not found"
1071 " for the subdev\n");
1072 return -EINVAL;
1073 }
1074 sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
1075 memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input));
1076 return 0;
1077}
1078
1079static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
1080{
1081 struct vpfe_device *vpfe_dev = video_drvdata(file);
1082
1083 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
1084
1085 return vpfe_get_app_input_index(vpfe_dev, index);
1086}
1087
1088
1089static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
1090{
1091 struct vpfe_device *vpfe_dev = video_drvdata(file);
1092 struct vpfe_subdev_info *sdinfo;
1093 int subdev_index, inp_index;
1094 struct vpfe_route *route;
1095 u32 input = 0, output = 0;
1096 int ret = -EINVAL;
1097
1098 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
1099
1100 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1101 if (ret)
1102 return ret;
1103
1104 /*
1105 * If streaming is started return device busy
1106 * error
1107 */
1108 if (vpfe_dev->started) {
1109 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
1110 ret = -EBUSY;
1111 goto unlock_out;
1112 }
1113
1114 if (vpfe_get_subdev_input_index(vpfe_dev,
1115 &subdev_index,
1116 &inp_index,
1117 index) < 0) {
1118 v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
1119 goto unlock_out;
1120 }
1121
1122 sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
1123 route = &sdinfo->routes[inp_index];
1124 if (route && sdinfo->can_route) {
1125 input = route->input;
1126 output = route->output;
1127 }
1128
1129 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1130 video, s_routing, input, output, 0);
1131
1132 if (ret) {
1133 v4l2_err(&vpfe_dev->v4l2_dev,
1134 "vpfe_doioctl:error in setting input in decoder\n");
1135 ret = -EINVAL;
1136 goto unlock_out;
1137 }
1138 vpfe_dev->current_subdev = sdinfo;
1139 vpfe_dev->current_input = index;
1140 vpfe_dev->std_index = 0;
1141
1142 /* set the bus/interface parameter for the sub device in ccdc */
1143 ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
1144 if (ret)
1145 goto unlock_out;
1146
1147 /* set the default image parameters in the device */
1148 ret = vpfe_config_image_format(vpfe_dev,
1149 &vpfe_standards[vpfe_dev->std_index].std_id);
1150unlock_out:
1151 mutex_unlock(&vpfe_dev->lock);
1152 return ret;
1153}
1154
1155static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1156{
1157 struct vpfe_device *vpfe_dev = video_drvdata(file);
1158 struct vpfe_subdev_info *sdinfo;
1159 int ret = 0;
1160
1161 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
1162
1163 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1164 sdinfo = vpfe_dev->current_subdev;
1165 if (ret)
1166 return ret;
1167 /* Call querystd function of decoder device */
1168 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1169 video, querystd, std_id);
1170 mutex_unlock(&vpfe_dev->lock);
1171 return ret;
1172}
1173
1174static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1175{
1176 struct vpfe_device *vpfe_dev = video_drvdata(file);
1177 struct vpfe_subdev_info *sdinfo;
1178 int ret = 0;
1179
1180 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
1181
1182 /* Call decoder driver function to set the standard */
1183 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1184 if (ret)
1185 return ret;
1186
1187 sdinfo = vpfe_dev->current_subdev;
1188 /* If streaming is started, return device busy error */
1189 if (vpfe_dev->started) {
1190 v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
1191 ret = -EBUSY;
1192 goto unlock_out;
1193 }
1194
1195 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1196 core, s_std, *std_id);
1197 if (ret < 0) {
1198 v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
1199 goto unlock_out;
1200 }
1201 ret = vpfe_config_image_format(vpfe_dev, std_id);
1202
1203unlock_out:
1204 mutex_unlock(&vpfe_dev->lock);
1205 return ret;
1206}
1207
1208static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
1209{
1210 struct vpfe_device *vpfe_dev = video_drvdata(file);
1211
1212 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
1213
1214 *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
1215 return 0;
1216}
1217/*
1218 * Videobuf operations
1219 */
1220static int vpfe_videobuf_setup(struct videobuf_queue *vq,
1221 unsigned int *count,
1222 unsigned int *size)
1223{
1224 struct vpfe_fh *fh = vq->priv_data;
1225 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1226
1227 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
1228 *size = config_params.device_bufsize;
1229
1230 if (*count < config_params.min_numbuffers)
1231 *count = config_params.min_numbuffers;
1232 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1233 "count=%d, size=%d\n", *count, *size);
1234 return 0;
1235}
1236
1237static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
1238 struct videobuf_buffer *vb,
1239 enum v4l2_field field)
1240{
1241 struct vpfe_fh *fh = vq->priv_data;
1242 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1243
1244 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
1245
1246 /* If buffer is not initialized, initialize it */
1247 if (VIDEOBUF_NEEDS_INIT == vb->state) {
1248 vb->width = vpfe_dev->fmt.fmt.pix.width;
1249 vb->height = vpfe_dev->fmt.fmt.pix.height;
1250 vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
1251 vb->field = field;
1252 }
1253 vb->state = VIDEOBUF_PREPARED;
1254 return 0;
1255}
1256
1257static void vpfe_videobuf_queue(struct videobuf_queue *vq,
1258 struct videobuf_buffer *vb)
1259{
1260 /* Get the file handle object and device object */
1261 struct vpfe_fh *fh = vq->priv_data;
1262 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1263 unsigned long flags;
1264
1265 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
1266
1267 /* add the buffer to the DMA queue */
1268 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1269 list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
1270 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1271
1272 /* Change state of the buffer */
1273 vb->state = VIDEOBUF_QUEUED;
1274}
1275
1276static void vpfe_videobuf_release(struct videobuf_queue *vq,
1277 struct videobuf_buffer *vb)
1278{
1279 struct vpfe_fh *fh = vq->priv_data;
1280 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1281 unsigned long flags;
1282
1283 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
1284
1285 /*
1286 * We need to flush the buffer from the dma queue since
1287 * they are de-allocated
1288 */
1289 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1290 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1291 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1292 videobuf_dma_contig_free(vq, vb);
1293 vb->state = VIDEOBUF_NEEDS_INIT;
1294}
1295
1296static struct videobuf_queue_ops vpfe_videobuf_qops = {
1297 .buf_setup = vpfe_videobuf_setup,
1298 .buf_prepare = vpfe_videobuf_prepare,
1299 .buf_queue = vpfe_videobuf_queue,
1300 .buf_release = vpfe_videobuf_release,
1301};
1302
1303/*
1304 * vpfe_reqbufs. currently support REQBUF only once opening
1305 * the device.
1306 */
1307static int vpfe_reqbufs(struct file *file, void *priv,
1308 struct v4l2_requestbuffers *req_buf)
1309{
1310 struct vpfe_device *vpfe_dev = video_drvdata(file);
1311 struct vpfe_fh *fh = file->private_data;
1312 int ret = 0;
1313
1314 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
1315
1316 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
1317 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
1318 return -EINVAL;
1319 }
1320
1321 if (V4L2_MEMORY_USERPTR == req_buf->memory) {
1322 /* we don't support user ptr IO */
1323 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
1324 " USERPTR IO not supported\n");
1325 return -EINVAL;
1326 }
1327
1328 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1329 if (ret)
1330 return ret;
1331
1332 if (vpfe_dev->io_usrs != 0) {
1333 v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
1334 ret = -EBUSY;
1335 goto unlock_out;
1336 }
1337
1338 vpfe_dev->memory = req_buf->memory;
1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
1340 &vpfe_videobuf_qops,
1341 NULL,
1342 &vpfe_dev->irqlock,
1343 req_buf->type,
1344 vpfe_dev->fmt.fmt.pix.field,
1345 sizeof(struct videobuf_buffer),
1346 fh);
1347
1348 fh->io_allowed = 1;
1349 vpfe_dev->io_usrs = 1;
1350 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1351 ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
1352unlock_out:
1353 mutex_unlock(&vpfe_dev->lock);
1354 return ret;
1355}
1356
1357static int vpfe_querybuf(struct file *file, void *priv,
1358 struct v4l2_buffer *buf)
1359{
1360 struct vpfe_device *vpfe_dev = video_drvdata(file);
1361
1362 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
1363
1364 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1365 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1366 return -EINVAL;
1367 }
1368
1369 if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
1370 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
1371 return -EINVAL;
1372 }
1373 /* Call videobuf_querybuf to get information */
1374 return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
1375}
1376
1377static int vpfe_qbuf(struct file *file, void *priv,
1378 struct v4l2_buffer *p)
1379{
1380 struct vpfe_device *vpfe_dev = video_drvdata(file);
1381 struct vpfe_fh *fh = file->private_data;
1382
1383 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
1384
1385 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
1386 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1387 return -EINVAL;
1388 }
1389
1390 /*
1391 * If this file handle is not allowed to do IO,
1392 * return error
1393 */
1394 if (!fh->io_allowed) {
1395 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1396 return -EACCES;
1397 }
1398 return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
1399}
1400
1401static int vpfe_dqbuf(struct file *file, void *priv,
1402 struct v4l2_buffer *buf)
1403{
1404 struct vpfe_device *vpfe_dev = video_drvdata(file);
1405
1406 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
1407
1408 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1409 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1410 return -EINVAL;
1411 }
1412 return videobuf_dqbuf(&vpfe_dev->buffer_queue,
1413 buf, file->f_flags & O_NONBLOCK);
1414}
1415
1416/*
1417 * vpfe_calculate_offsets : This function calculates buffers offset
1418 * for top and bottom field
1419 */
1420static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
1421{
1422 struct v4l2_rect image_win;
1423
1424 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
1425
1426 ccdc_dev->hw_ops.get_image_window(&image_win);
1427 vpfe_dev->field_off = image_win.height * image_win.width;
1428}
1429
1430/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
1431static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
1432{
1433 ccdc_dev->hw_ops.enable(1);
1434 if (ccdc_dev->hw_ops.enable_out_to_sdram)
1435 ccdc_dev->hw_ops.enable_out_to_sdram(1);
1436 vpfe_dev->started = 1;
1437}
1438
1439/*
1440 * vpfe_streamon. Assume the DMA queue is not empty.
1441 * application is expected to call QBUF before calling
1442 * this ioctl. If not, driver returns error
1443 */
1444static int vpfe_streamon(struct file *file, void *priv,
1445 enum v4l2_buf_type buf_type)
1446{
1447 struct vpfe_device *vpfe_dev = video_drvdata(file);
1448 struct vpfe_fh *fh = file->private_data;
1449 struct vpfe_subdev_info *sdinfo;
1450 unsigned long addr;
1451 int ret = 0;
1452
1453 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
1454
1455 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1456 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1457 return -EINVAL;
1458 }
1459
1460 /* If file handle is not allowed IO, return error */
1461 if (!fh->io_allowed) {
1462 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1463 return -EACCES;
1464 }
1465
1466 sdinfo = vpfe_dev->current_subdev;
1467 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1468 video, s_stream, 1);
1469
1470 if (ret && (ret != -ENOIOCTLCMD)) {
1471 v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
1472 return -EINVAL;
1473 }
1474
1475 /* If buffer queue is empty, return error */
1476 if (list_empty(&vpfe_dev->buffer_queue.stream)) {
1477 v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
1478 return -EIO;
1479 }
1480
1481 /* Call videobuf_streamon to start streaming * in videobuf */
1482 ret = videobuf_streamon(&vpfe_dev->buffer_queue);
1483 if (ret)
1484 return ret;
1485
1486
1487 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1488 if (ret)
1489 goto streamoff;
1490 /* Get the next frame from the buffer queue */
1491 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
1492 struct videobuf_buffer, queue);
1493 vpfe_dev->cur_frm = vpfe_dev->next_frm;
1494 /* Remove buffer from the buffer queue */
1495 list_del(&vpfe_dev->cur_frm->queue);
1496 /* Mark state of the current frame to active */
1497 vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
1498 /* Initialize field_id and started member */
1499 vpfe_dev->field_id = 0;
1500 addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
1501
1502 /* Calculate field offset */
1503 vpfe_calculate_offsets(vpfe_dev);
1504
1505 if (vpfe_attach_irq(vpfe_dev) < 0) {
1506 v4l2_err(&vpfe_dev->v4l2_dev,
1507 "Error in attaching interrupt handle\n");
1508 ret = -EFAULT;
1509 goto unlock_out;
1510 }
1511 if (ccdc_dev->hw_ops.configure() < 0) {
1512 v4l2_err(&vpfe_dev->v4l2_dev,
1513 "Error in configuring ccdc\n");
1514 ret = -EINVAL;
1515 goto unlock_out;
1516 }
1517 ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
1518 vpfe_start_ccdc_capture(vpfe_dev);
1519 mutex_unlock(&vpfe_dev->lock);
1520 return ret;
1521unlock_out:
1522 mutex_unlock(&vpfe_dev->lock);
1523streamoff:
1524 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1525 return ret;
1526}
1527
1528static int vpfe_streamoff(struct file *file, void *priv,
1529 enum v4l2_buf_type buf_type)
1530{
1531 struct vpfe_device *vpfe_dev = video_drvdata(file);
1532 struct vpfe_fh *fh = file->private_data;
1533 struct vpfe_subdev_info *sdinfo;
1534 int ret = 0;
1535
1536 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
1537
1538 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1539 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1540 return -EINVAL;
1541 }
1542
1543 /* If io is allowed for this file handle, return error */
1544 if (!fh->io_allowed) {
1545 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1546 return -EACCES;
1547 }
1548
1549 /* If streaming is not started, return error */
1550 if (!vpfe_dev->started) {
1551 v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
1552 return -EINVAL;
1553 }
1554
1555 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1556 if (ret)
1557 return ret;
1558
1559 vpfe_stop_ccdc_capture(vpfe_dev);
1560 vpfe_detach_irq(vpfe_dev);
1561
1562 sdinfo = vpfe_dev->current_subdev;
1563 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1564 video, s_stream, 0);
1565
1566 if (ret && (ret != -ENOIOCTLCMD))
1567 v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
1568 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1569 mutex_unlock(&vpfe_dev->lock);
1570 return ret;
1571}
1572
1573static int vpfe_cropcap(struct file *file, void *priv,
1574 struct v4l2_cropcap *crop)
1575{
1576 struct vpfe_device *vpfe_dev = video_drvdata(file);
1577
1578 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
1579
1580 if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards))
1581 return -EINVAL;
1582
1583 memset(crop, 0, sizeof(struct v4l2_cropcap));
1584 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1585 crop->bounds.width = crop->defrect.width =
1586 vpfe_standards[vpfe_dev->std_index].width;
1587 crop->bounds.height = crop->defrect.height =
1588 vpfe_standards[vpfe_dev->std_index].height;
1589 crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect;
1590 return 0;
1591}
1592
1593static int vpfe_g_crop(struct file *file, void *priv,
1594 struct v4l2_crop *crop)
1595{
1596 struct vpfe_device *vpfe_dev = video_drvdata(file);
1597
1598 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n");
1599
1600 crop->c = vpfe_dev->crop;
1601 return 0;
1602}
1603
1604static int vpfe_s_crop(struct file *file, void *priv,
1605 struct v4l2_crop *crop)
1606{
1607 struct vpfe_device *vpfe_dev = video_drvdata(file);
1608 int ret = 0;
1609
1610 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
1611
1612 if (vpfe_dev->started) {
1613 /* make sure streaming is not started */
1614 v4l2_err(&vpfe_dev->v4l2_dev,
1615 "Cannot change crop when streaming is ON\n");
1616 return -EBUSY;
1617 }
1618
1619 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1620 if (ret)
1621 return ret;
1622
1623 if (crop->c.top < 0 || crop->c.left < 0) {
1624 v4l2_err(&vpfe_dev->v4l2_dev,
1625 "doesn't support negative values for top & left\n");
1626 ret = -EINVAL;
1627 goto unlock_out;
1628 }
1629
1630 /* adjust the width to 16 pixel boundry */
1631 crop->c.width = ((crop->c.width + 15) & ~0xf);
1632
1633 /* make sure parameters are valid */
1634 if ((crop->c.left + crop->c.width >
1635 vpfe_dev->std_info.active_pixels) ||
1636 (crop->c.top + crop->c.height >
1637 vpfe_dev->std_info.active_lines)) {
1638 v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
1639 ret = -EINVAL;
1640 goto unlock_out;
1641 }
1642 ccdc_dev->hw_ops.set_image_window(&crop->c);
1643 vpfe_dev->fmt.fmt.pix.width = crop->c.width;
1644 vpfe_dev->fmt.fmt.pix.height = crop->c.height;
1645 vpfe_dev->fmt.fmt.pix.bytesperline =
1646 ccdc_dev->hw_ops.get_line_length();
1647 vpfe_dev->fmt.fmt.pix.sizeimage =
1648 vpfe_dev->fmt.fmt.pix.bytesperline *
1649 vpfe_dev->fmt.fmt.pix.height;
1650 vpfe_dev->crop = crop->c;
1651unlock_out:
1652 mutex_unlock(&vpfe_dev->lock);
1653 return ret;
1654}
1655
1656
1657static long vpfe_param_handler(struct file *file, void *priv,
1658 int cmd, void *param)
1659{
1660 struct vpfe_device *vpfe_dev = video_drvdata(file);
1661 int ret = 0;
1662
1663 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
1664
1665 if (vpfe_dev->started) {
1666 /* only allowed if streaming is not started */
1667 v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
1668 return -EBUSY;
1669 }
1670
1671 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1672 if (ret)
1673 return ret;
1674
1675 switch (cmd) {
1676 case VPFE_CMD_S_CCDC_RAW_PARAMS:
1677 v4l2_warn(&vpfe_dev->v4l2_dev,
1678 "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
1679 ret = ccdc_dev->hw_ops.set_params(param);
1680 if (ret) {
1681 v4l2_err(&vpfe_dev->v4l2_dev,
1682 "Error in setting parameters in CCDC\n");
1683 goto unlock_out;
1684 }
1685 if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
1686 v4l2_err(&vpfe_dev->v4l2_dev,
1687 "Invalid image format at CCDC\n");
1688 goto unlock_out;
1689 }
1690 break;
1691 default:
1692 ret = -EINVAL;
1693 }
1694unlock_out:
1695 mutex_unlock(&vpfe_dev->lock);
1696 return ret;
1697}
1698
1699
1700/* vpfe capture ioctl operations */
1701static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
1702 .vidioc_querycap = vpfe_querycap,
1703 .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap,
1704 .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
1705 .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap,
1706 .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap,
1707 .vidioc_enum_input = vpfe_enum_input,
1708 .vidioc_g_input = vpfe_g_input,
1709 .vidioc_s_input = vpfe_s_input,
1710 .vidioc_querystd = vpfe_querystd,
1711 .vidioc_s_std = vpfe_s_std,
1712 .vidioc_g_std = vpfe_g_std,
1713 .vidioc_reqbufs = vpfe_reqbufs,
1714 .vidioc_querybuf = vpfe_querybuf,
1715 .vidioc_qbuf = vpfe_qbuf,
1716 .vidioc_dqbuf = vpfe_dqbuf,
1717 .vidioc_streamon = vpfe_streamon,
1718 .vidioc_streamoff = vpfe_streamoff,
1719 .vidioc_cropcap = vpfe_cropcap,
1720 .vidioc_g_crop = vpfe_g_crop,
1721 .vidioc_s_crop = vpfe_s_crop,
1722 .vidioc_default = vpfe_param_handler,
1723};
1724
1725static struct vpfe_device *vpfe_initialize(void)
1726{
1727 struct vpfe_device *vpfe_dev;
1728
1729 /* Default number of buffers should be 3 */
1730 if ((numbuffers > 0) &&
1731 (numbuffers < config_params.min_numbuffers))
1732 numbuffers = config_params.min_numbuffers;
1733
1734 /*
1735 * Set buffer size to min buffers size if invalid buffer size is
1736 * given
1737 */
1738 if (bufsize < config_params.min_bufsize)
1739 bufsize = config_params.min_bufsize;
1740
1741 config_params.numbuffers = numbuffers;
1742
1743 if (numbuffers)
1744 config_params.device_bufsize = bufsize;
1745
1746 /* Allocate memory for device objects */
1747 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
1748
1749 return vpfe_dev;
1750}
1751
1752static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
1753{
1754 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1755
1756 clk_disable(vpfe_cfg->vpssclk);
1757 clk_put(vpfe_cfg->vpssclk);
1758 clk_disable(vpfe_cfg->slaveclk);
1759 clk_put(vpfe_cfg->slaveclk);
1760 v4l2_info(vpfe_dev->pdev->driver,
1761 "vpfe vpss master & slave clocks disabled\n");
1762}
1763
1764static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
1765{
1766 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1767 int ret = -ENOENT;
1768
1769 vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
1770 if (NULL == vpfe_cfg->vpssclk) {
1771 v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
1772 "vpss_master\n");
1773 return ret;
1774 }
1775
1776 if (clk_enable(vpfe_cfg->vpssclk)) {
1777 v4l2_err(vpfe_dev->pdev->driver,
1778 "vpfe vpss master clock not enabled\n");
1779 goto out;
1780 }
1781 v4l2_info(vpfe_dev->pdev->driver,
1782 "vpfe vpss master clock enabled\n");
1783
1784 vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
1785 if (NULL == vpfe_cfg->slaveclk) {
1786 v4l2_err(vpfe_dev->pdev->driver,
1787 "No clock defined for vpss slave\n");
1788 goto out;
1789 }
1790
1791 if (clk_enable(vpfe_cfg->slaveclk)) {
1792 v4l2_err(vpfe_dev->pdev->driver,
1793 "vpfe vpss slave clock not enabled\n");
1794 goto out;
1795 }
1796 v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
1797 return 0;
1798out:
1799 if (vpfe_cfg->vpssclk)
1800 clk_put(vpfe_cfg->vpssclk);
1801 if (vpfe_cfg->slaveclk)
1802 clk_put(vpfe_cfg->slaveclk);
1803
1804 return -1;
1805}
1806
1807/*
1808 * vpfe_probe : This function creates device entries by register
1809 * itself to the V4L2 driver and initializes fields of each
1810 * device objects
1811 */
1812static __init int vpfe_probe(struct platform_device *pdev)
1813{
1814 struct vpfe_subdev_info *sdinfo;
1815 struct vpfe_config *vpfe_cfg;
1816 struct resource *res1;
1817 struct vpfe_device *vpfe_dev;
1818 struct i2c_adapter *i2c_adap;
1819 struct video_device *vfd;
1820 int ret = -ENOMEM, i, j;
1821 int num_subdevs = 0;
1822
1823 /* Get the pointer to the device object */
1824 vpfe_dev = vpfe_initialize();
1825
1826 if (!vpfe_dev) {
1827 v4l2_err(pdev->dev.driver,
1828 "Failed to allocate memory for vpfe_dev\n");
1829 return ret;
1830 }
1831
1832 vpfe_dev->pdev = &pdev->dev;
1833
1834 if (NULL == pdev->dev.platform_data) {
1835 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
1836 ret = -ENOENT;
1837 goto probe_free_dev_mem;
1838 }
1839
1840 vpfe_cfg = pdev->dev.platform_data;
1841 vpfe_dev->cfg = vpfe_cfg;
1842 if (NULL == vpfe_cfg->ccdc ||
1843 NULL == vpfe_cfg->card_name ||
1844 NULL == vpfe_cfg->sub_devs) {
1845 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
1846 ret = -ENOENT;
1847 goto probe_free_dev_mem;
1848 }
1849
1850 /* enable vpss clocks */
1851 ret = vpfe_enable_clock(vpfe_dev);
1852 if (ret)
1853 goto probe_free_dev_mem;
1854
1855 mutex_lock(&ccdc_lock);
1856 /* Allocate memory for ccdc configuration */
1857 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1858 if (NULL == ccdc_cfg) {
1859 v4l2_err(pdev->dev.driver,
1860 "Memory allocation failed for ccdc_cfg\n");
1861 goto probe_disable_clock;
1862 }
1863
1864 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
1865 /* Get VINT0 irq resource */
1866 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1867 if (!res1) {
1868 v4l2_err(pdev->dev.driver,
1869 "Unable to get interrupt for VINT0\n");
1870 ret = -ENOENT;
1871 goto probe_disable_clock;
1872 }
1873 vpfe_dev->ccdc_irq0 = res1->start;
1874
1875 /* Get VINT1 irq resource */
1876 res1 = platform_get_resource(pdev,
1877 IORESOURCE_IRQ, 1);
1878 if (!res1) {
1879 v4l2_err(pdev->dev.driver,
1880 "Unable to get interrupt for VINT1\n");
1881 ret = -ENOENT;
1882 goto probe_disable_clock;
1883 }
1884 vpfe_dev->ccdc_irq1 = res1->start;
1885
1886 /* Get address base of CCDC */
1887 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1888 if (!res1) {
1889 v4l2_err(pdev->dev.driver,
1890 "Unable to get register address map\n");
1891 ret = -ENOENT;
1892 goto probe_disable_clock;
1893 }
1894
1895 ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
1896 if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
1897 pdev->dev.driver->name)) {
1898 v4l2_err(pdev->dev.driver,
1899 "Failed request_mem_region for ccdc base\n");
1900 ret = -ENXIO;
1901 goto probe_disable_clock;
1902 }
1903 ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
1904 ccdc_cfg->ccdc_addr_size);
1905 if (!ccdc_cfg->ccdc_addr) {
1906 v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
1907 ret = -ENXIO;
1908 goto probe_out_release_mem1;
1909 }
1910
1911 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
1912 "vpfe_capture0", vpfe_dev);
1913
1914 if (0 != ret) {
1915 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
1916 goto probe_out_unmap1;
1917 }
1918
1919 /* Allocate memory for video device */
1920 vfd = video_device_alloc();
1921 if (NULL == vfd) {
1922 ret = -ENOMEM;
1923 v4l2_err(pdev->dev.driver,
1924 "Unable to alloc video device\n");
1925 goto probe_out_release_irq;
1926 }
1927
1928 /* Initialize field of video device */
1929 vfd->release = video_device_release;
1930 vfd->fops = &vpfe_fops;
1931 vfd->ioctl_ops = &vpfe_ioctl_ops;
1932 vfd->minor = -1;
1933 vfd->tvnorms = 0;
1934 vfd->current_norm = V4L2_STD_PAL;
1935 vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
1936 snprintf(vfd->name, sizeof(vfd->name),
1937 "%s_V%d.%d.%d",
1938 CAPTURE_DRV_NAME,
1939 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
1940 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
1941 (VPFE_CAPTURE_VERSION_CODE) & 0xff);
1942 /* Set video_dev to the video device */
1943 vpfe_dev->video_dev = vfd;
1944
1945 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
1946 if (ret) {
1947 v4l2_err(pdev->dev.driver,
1948 "Unable to register v4l2 device.\n");
1949 goto probe_out_video_release;
1950 }
1951 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
1952 spin_lock_init(&vpfe_dev->irqlock);
1953 spin_lock_init(&vpfe_dev->dma_queue_lock);
1954 mutex_init(&vpfe_dev->lock);
1955
1956 /* Initialize field of the device objects */
1957 vpfe_dev->numbuffers = config_params.numbuffers;
1958
1959 /* Initialize prio member of device object */
1960 v4l2_prio_init(&vpfe_dev->prio);
1961 /* register video device */
1962 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1963 "trying to register vpfe device.\n");
1964 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1965 "video_dev=%x\n", (int)&vpfe_dev->video_dev);
1966 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1967 ret = video_register_device(vpfe_dev->video_dev,
1968 VFL_TYPE_GRABBER, -1);
1969
1970 if (ret) {
1971 v4l2_err(pdev->dev.driver,
1972 "Unable to register video device.\n");
1973 goto probe_out_v4l2_unregister;
1974 }
1975
1976 v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
1977 /* set the driver data in platform device */
1978 platform_set_drvdata(pdev, vpfe_dev);
1979 /* set driver private data */
1980 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
1981 i2c_adap = i2c_get_adapter(1);
1982 vpfe_cfg = pdev->dev.platform_data;
1983 num_subdevs = vpfe_cfg->num_subdevs;
1984 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
1985 GFP_KERNEL);
1986 if (NULL == vpfe_dev->sd) {
1987 v4l2_err(&vpfe_dev->v4l2_dev,
1988 "unable to allocate memory for subdevice pointers\n");
1989 ret = -ENOMEM;
1990 goto probe_out_video_unregister;
1991 }
1992
1993 for (i = 0; i < num_subdevs; i++) {
1994 struct v4l2_input *inps;
1995
1996 sdinfo = &vpfe_cfg->sub_devs[i];
1997
1998 /* Load up the subdevice */
1999 vpfe_dev->sd[i] =
2000 v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
2001 i2c_adap,
2002 sdinfo->name,
2003 &sdinfo->board_info,
2004 NULL);
2005 if (vpfe_dev->sd[i]) {
2006 v4l2_info(&vpfe_dev->v4l2_dev,
2007 "v4l2 sub device %s registered\n",
2008 sdinfo->name);
2009 vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
2010 /* update tvnorms from the sub devices */
2011 for (j = 0; j < sdinfo->num_inputs; j++) {
2012 inps = &sdinfo->inputs[j];
2013 vfd->tvnorms |= inps->std;
2014 }
2015 } else {
2016 v4l2_info(&vpfe_dev->v4l2_dev,
2017 "v4l2 sub device %s register fails\n",
2018 sdinfo->name);
2019 goto probe_sd_out;
2020 }
2021 }
2022
2023 /* set first sub device as current one */
2024 vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
2025
2026 /* We have at least one sub device to work with */
2027 mutex_unlock(&ccdc_lock);
2028 return 0;
2029
2030probe_sd_out:
2031 kfree(vpfe_dev->sd);
2032probe_out_video_unregister:
2033 video_unregister_device(vpfe_dev->video_dev);
2034probe_out_v4l2_unregister:
2035 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2036probe_out_video_release:
2037 if (vpfe_dev->video_dev->minor == -1)
2038 video_device_release(vpfe_dev->video_dev);
2039probe_out_release_irq:
2040 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2041probe_out_unmap1:
2042 iounmap(ccdc_cfg->ccdc_addr);
2043probe_out_release_mem1:
2044 release_mem_region(res1->start, res1->end - res1->start + 1);
2045probe_disable_clock:
2046 vpfe_disable_clock(vpfe_dev);
2047 mutex_unlock(&ccdc_lock);
2048 kfree(ccdc_cfg);
2049probe_free_dev_mem:
2050 kfree(vpfe_dev);
2051 return ret;
2052}
2053
2054/*
2055 * vpfe_remove : It un-register device from V4L2 driver
2056 */
2057static int vpfe_remove(struct platform_device *pdev)
2058{
2059 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
2060 struct resource *res;
2061
2062 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
2063
2064 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2065 kfree(vpfe_dev->sd);
2066 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2067 video_unregister_device(vpfe_dev->video_dev);
2068 mutex_lock(&ccdc_lock);
2069 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2070 release_mem_region(res->start, res->end - res->start + 1);
2071 iounmap(ccdc_cfg->ccdc_addr);
2072 mutex_unlock(&ccdc_lock);
2073 vpfe_disable_clock(vpfe_dev);
2074 kfree(vpfe_dev);
2075 kfree(ccdc_cfg);
2076 return 0;
2077}
2078
2079static int
2080vpfe_suspend(struct device *dev)
2081{
2082 /* add suspend code here later */
2083 return -1;
2084}
2085
2086static int
2087vpfe_resume(struct device *dev)
2088{
2089 /* add resume code here later */
2090 return -1;
2091}
2092
2093static struct dev_pm_ops vpfe_dev_pm_ops = {
2094 .suspend = vpfe_suspend,
2095 .resume = vpfe_resume,
2096};
2097
2098static struct platform_driver vpfe_driver = {
2099 .driver = {
2100 .name = CAPTURE_DRV_NAME,
2101 .owner = THIS_MODULE,
2102 .pm = &vpfe_dev_pm_ops,
2103 },
2104 .probe = vpfe_probe,
2105 .remove = __devexit_p(vpfe_remove),
2106};
2107
2108static __init int vpfe_init(void)
2109{
2110 printk(KERN_NOTICE "vpfe_init\n");
2111 /* Register driver to the kernel */
2112 return platform_driver_register(&vpfe_driver);
2113}
2114
2115/*
2116 * vpfe_cleanup : This function un-registers device driver
2117 */
2118static void vpfe_cleanup(void)
2119{
2120 platform_driver_unregister(&vpfe_driver);
2121}
2122
2123module_init(vpfe_init);
2124module_exit(vpfe_cleanup);
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c
new file mode 100644
index 000000000000..3b8eac31ecae
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.c
@@ -0,0 +1,296 @@
1/*
2 * vpif - DM646x Video Port Interface driver
3 * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
4 * that receiveing video byte stream and two channels(2, 3) for video output.
5 * The hardware supports SDTV, HDTV formats, raw data capture.
6 * Currently, the driver supports NTSC and PAL standards.
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation version 2.
13 *
14 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24#include <linux/kernel.h>
25#include <linux/io.h>
26#include <mach/hardware.h>
27
28#include "vpif.h"
29
30MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
31MODULE_LICENSE("GPL");
32
33#define VPIF_CH0_MAX_MODES (22)
34#define VPIF_CH1_MAX_MODES (02)
35#define VPIF_CH2_MAX_MODES (15)
36#define VPIF_CH3_MAX_MODES (02)
37
38static resource_size_t res_len;
39static struct resource *res;
40spinlock_t vpif_lock;
41
42void __iomem *vpif_base;
43
44static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
45{
46 if (val)
47 vpif_set_bit(reg, bit);
48 else
49 vpif_clr_bit(reg, bit);
50}
51
52/* This structure is used to keep track of VPIF size register's offsets */
53struct vpif_registers {
54 u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
55 u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
56 u32 vanc1_size, width_mask, len_mask;
57 u8 max_modes;
58};
59
60static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
61 /* Channel0 */
62 {
63 VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
64 VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
65 VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
66 VPIF_CH0_MAX_MODES,
67 },
68 /* Channel1 */
69 {
70 VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
71 VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
72 VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
73 VPIF_CH1_MAX_MODES,
74 },
75 /* Channel2 */
76 {
77 VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
78 VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
79 VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
80 VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
81 VPIF_CH2_MAX_MODES
82 },
83 /* Channel3 */
84 {
85 VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
86 VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
87 VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
88 VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
89 VPIF_CH3_MAX_MODES
90 },
91};
92
93/* vpif_set_mode_info:
94 * This function is used to set horizontal and vertical config parameters
95 * As per the standard in the channel, configure the values of L1, L3,
96 * L5, L7 L9, L11 in VPIF Register , also write width and height
97 */
98static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
99 u8 channel_id, u8 config_channel_id)
100{
101 u32 value;
102
103 value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
104 value <<= VPIF_CH_LEN_SHIFT;
105 value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
106 regw(value, vpifregs[channel_id].h_cfg);
107
108 value = (config->l1 & vpifregs[config_channel_id].len_mask);
109 value <<= VPIF_CH_LEN_SHIFT;
110 value |= (config->l3 & vpifregs[config_channel_id].len_mask);
111 regw(value, vpifregs[channel_id].v_cfg_00);
112
113 value = (config->l5 & vpifregs[config_channel_id].len_mask);
114 value <<= VPIF_CH_LEN_SHIFT;
115 value |= (config->l7 & vpifregs[config_channel_id].len_mask);
116 regw(value, vpifregs[channel_id].v_cfg_01);
117
118 value = (config->l9 & vpifregs[config_channel_id].len_mask);
119 value <<= VPIF_CH_LEN_SHIFT;
120 value |= (config->l11 & vpifregs[config_channel_id].len_mask);
121 regw(value, vpifregs[channel_id].v_cfg_02);
122
123 value = (config->vsize & vpifregs[config_channel_id].len_mask);
124 regw(value, vpifregs[channel_id].v_cfg);
125}
126
127/* config_vpif_params
128 * Function to set the parameters of a channel
129 * Mainly modifies the channel ciontrol register
130 * It sets frame format, yc mux mode
131 */
132static void config_vpif_params(struct vpif_params *vpifparams,
133 u8 channel_id, u8 found)
134{
135 const struct vpif_channel_config_params *config = &vpifparams->std_info;
136 u32 value, ch_nip, reg;
137 u8 start, end;
138 int i;
139
140 start = channel_id;
141 end = channel_id + found;
142
143 for (i = start; i < end; i++) {
144 reg = vpifregs[i].ch_ctrl;
145 if (channel_id < 2)
146 ch_nip = VPIF_CAPTURE_CH_NIP;
147 else
148 ch_nip = VPIF_DISPLAY_CH_NIP;
149
150 vpif_wr_bit(reg, ch_nip, config->frm_fmt);
151 vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
152 vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
153 vpifparams->video_params.storage_mode);
154
155 /* Set raster scanning SDR Format */
156 vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
157 vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
158
159 if (channel_id > 1) /* Set the Pixel enable bit */
160 vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
161 else if (config->capture_format) {
162 /* Set the polarity of various pins */
163 vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
164 vpifparams->iface.fid_pol);
165 vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
166 vpifparams->iface.vd_pol);
167 vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
168 vpifparams->iface.hd_pol);
169
170 value = regr(reg);
171 /* Set data width */
172 value &= ((~(unsigned int)(0x3)) <<
173 VPIF_CH_DATA_WIDTH_BIT);
174 value |= ((vpifparams->params.data_sz) <<
175 VPIF_CH_DATA_WIDTH_BIT);
176 regw(value, reg);
177 }
178
179 /* Write the pitch in the driver */
180 regw((vpifparams->video_params.hpitch),
181 vpifregs[i].line_offset);
182 }
183}
184
185/* vpif_set_video_params
186 * This function is used to set video parameters in VPIF register
187 */
188int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
189{
190 const struct vpif_channel_config_params *config = &vpifparams->std_info;
191 int found = 1;
192
193 vpif_set_mode_info(config, channel_id, channel_id);
194 if (!config->ycmux_mode) {
195 /* YC are on separate channels (HDTV formats) */
196 vpif_set_mode_info(config, channel_id + 1, channel_id);
197 found = 2;
198 }
199
200 config_vpif_params(vpifparams, channel_id, found);
201
202 regw(0x80, VPIF_REQ_SIZE);
203 regw(0x01, VPIF_EMULATION_CTRL);
204
205 return found;
206}
207EXPORT_SYMBOL(vpif_set_video_params);
208
209void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
210 u8 channel_id)
211{
212 u32 value;
213
214 value = 0x3F8 & (vbiparams->hstart0);
215 value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
216 regw(value, vpifregs[channel_id].vanc0_strt);
217
218 value = 0x3F8 & (vbiparams->hstart1);
219 value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
220 regw(value, vpifregs[channel_id].vanc1_strt);
221
222 value = 0x3F8 & (vbiparams->hsize0);
223 value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
224 regw(value, vpifregs[channel_id].vanc0_size);
225
226 value = 0x3F8 & (vbiparams->hsize1);
227 value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
228 regw(value, vpifregs[channel_id].vanc1_size);
229
230}
231EXPORT_SYMBOL(vpif_set_vbi_display_params);
232
233int vpif_channel_getfid(u8 channel_id)
234{
235 return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
236 >> VPIF_CH_FID_SHIFT;
237}
238EXPORT_SYMBOL(vpif_channel_getfid);
239
240static int __init vpif_probe(struct platform_device *pdev)
241{
242 int status = 0;
243
244 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
245 if (!res)
246 return -ENOENT;
247
248 res_len = res->end - res->start + 1;
249
250 res = request_mem_region(res->start, res_len, res->name);
251 if (!res)
252 return -EBUSY;
253
254 vpif_base = ioremap(res->start, res_len);
255 if (!vpif_base) {
256 status = -EBUSY;
257 goto fail;
258 }
259
260 spin_lock_init(&vpif_lock);
261 dev_info(&pdev->dev, "vpif probe success\n");
262 return 0;
263
264fail:
265 release_mem_region(res->start, res_len);
266 return status;
267}
268
269static int vpif_remove(struct platform_device *pdev)
270{
271 iounmap(vpif_base);
272 release_mem_region(res->start, res_len);
273 return 0;
274}
275
276static struct platform_driver vpif_driver = {
277 .driver = {
278 .name = "vpif",
279 .owner = THIS_MODULE,
280 },
281 .remove = __devexit_p(vpif_remove),
282 .probe = vpif_probe,
283};
284
285static void vpif_exit(void)
286{
287 platform_driver_unregister(&vpif_driver);
288}
289
290static int __init vpif_init(void)
291{
292 return platform_driver_register(&vpif_driver);
293}
294subsys_initcall(vpif_init);
295module_exit(vpif_exit);
296
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
new file mode 100644
index 000000000000..188841b476e0
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.h
@@ -0,0 +1,642 @@
1/*
2 * VPIF header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef VPIF_H
17#define VPIF_H
18
19#include <linux/io.h>
20#include <linux/videodev2.h>
21#include <mach/hardware.h>
22#include <mach/dm646x.h>
23
24/* Maximum channel allowed */
25#define VPIF_NUM_CHANNELS (4)
26#define VPIF_CAPTURE_NUM_CHANNELS (2)
27#define VPIF_DISPLAY_NUM_CHANNELS (2)
28
29/* Macros to read/write registers */
30extern void __iomem *vpif_base;
31extern spinlock_t vpif_lock;
32
33#define regr(reg) readl((reg) + vpif_base)
34#define regw(value, reg) writel(value, (reg + vpif_base))
35
36/* Register Addresss Offsets */
37#define VPIF_PID (0x0000)
38#define VPIF_CH0_CTRL (0x0004)
39#define VPIF_CH1_CTRL (0x0008)
40#define VPIF_CH2_CTRL (0x000C)
41#define VPIF_CH3_CTRL (0x0010)
42
43#define VPIF_INTEN (0x0020)
44#define VPIF_INTEN_SET (0x0024)
45#define VPIF_INTEN_CLR (0x0028)
46#define VPIF_STATUS (0x002C)
47#define VPIF_STATUS_CLR (0x0030)
48#define VPIF_EMULATION_CTRL (0x0034)
49#define VPIF_REQ_SIZE (0x0038)
50
51#define VPIF_CH0_TOP_STRT_ADD_LUMA (0x0040)
52#define VPIF_CH0_BTM_STRT_ADD_LUMA (0x0044)
53#define VPIF_CH0_TOP_STRT_ADD_CHROMA (0x0048)
54#define VPIF_CH0_BTM_STRT_ADD_CHROMA (0x004c)
55#define VPIF_CH0_TOP_STRT_ADD_HANC (0x0050)
56#define VPIF_CH0_BTM_STRT_ADD_HANC (0x0054)
57#define VPIF_CH0_TOP_STRT_ADD_VANC (0x0058)
58#define VPIF_CH0_BTM_STRT_ADD_VANC (0x005c)
59#define VPIF_CH0_SP_CFG (0x0060)
60#define VPIF_CH0_IMG_ADD_OFST (0x0064)
61#define VPIF_CH0_HANC_ADD_OFST (0x0068)
62#define VPIF_CH0_H_CFG (0x006c)
63#define VPIF_CH0_V_CFG_00 (0x0070)
64#define VPIF_CH0_V_CFG_01 (0x0074)
65#define VPIF_CH0_V_CFG_02 (0x0078)
66#define VPIF_CH0_V_CFG_03 (0x007c)
67
68#define VPIF_CH1_TOP_STRT_ADD_LUMA (0x0080)
69#define VPIF_CH1_BTM_STRT_ADD_LUMA (0x0084)
70#define VPIF_CH1_TOP_STRT_ADD_CHROMA (0x0088)
71#define VPIF_CH1_BTM_STRT_ADD_CHROMA (0x008c)
72#define VPIF_CH1_TOP_STRT_ADD_HANC (0x0090)
73#define VPIF_CH1_BTM_STRT_ADD_HANC (0x0094)
74#define VPIF_CH1_TOP_STRT_ADD_VANC (0x0098)
75#define VPIF_CH1_BTM_STRT_ADD_VANC (0x009c)
76#define VPIF_CH1_SP_CFG (0x00a0)
77#define VPIF_CH1_IMG_ADD_OFST (0x00a4)
78#define VPIF_CH1_HANC_ADD_OFST (0x00a8)
79#define VPIF_CH1_H_CFG (0x00ac)
80#define VPIF_CH1_V_CFG_00 (0x00b0)
81#define VPIF_CH1_V_CFG_01 (0x00b4)
82#define VPIF_CH1_V_CFG_02 (0x00b8)
83#define VPIF_CH1_V_CFG_03 (0x00bc)
84
85#define VPIF_CH2_TOP_STRT_ADD_LUMA (0x00c0)
86#define VPIF_CH2_BTM_STRT_ADD_LUMA (0x00c4)
87#define VPIF_CH2_TOP_STRT_ADD_CHROMA (0x00c8)
88#define VPIF_CH2_BTM_STRT_ADD_CHROMA (0x00cc)
89#define VPIF_CH2_TOP_STRT_ADD_HANC (0x00d0)
90#define VPIF_CH2_BTM_STRT_ADD_HANC (0x00d4)
91#define VPIF_CH2_TOP_STRT_ADD_VANC (0x00d8)
92#define VPIF_CH2_BTM_STRT_ADD_VANC (0x00dc)
93#define VPIF_CH2_SP_CFG (0x00e0)
94#define VPIF_CH2_IMG_ADD_OFST (0x00e4)
95#define VPIF_CH2_HANC_ADD_OFST (0x00e8)
96#define VPIF_CH2_H_CFG (0x00ec)
97#define VPIF_CH2_V_CFG_00 (0x00f0)
98#define VPIF_CH2_V_CFG_01 (0x00f4)
99#define VPIF_CH2_V_CFG_02 (0x00f8)
100#define VPIF_CH2_V_CFG_03 (0x00fc)
101#define VPIF_CH2_HANC0_STRT (0x0100)
102#define VPIF_CH2_HANC0_SIZE (0x0104)
103#define VPIF_CH2_HANC1_STRT (0x0108)
104#define VPIF_CH2_HANC1_SIZE (0x010c)
105#define VPIF_CH2_VANC0_STRT (0x0110)
106#define VPIF_CH2_VANC0_SIZE (0x0114)
107#define VPIF_CH2_VANC1_STRT (0x0118)
108#define VPIF_CH2_VANC1_SIZE (0x011c)
109
110#define VPIF_CH3_TOP_STRT_ADD_LUMA (0x0140)
111#define VPIF_CH3_BTM_STRT_ADD_LUMA (0x0144)
112#define VPIF_CH3_TOP_STRT_ADD_CHROMA (0x0148)
113#define VPIF_CH3_BTM_STRT_ADD_CHROMA (0x014c)
114#define VPIF_CH3_TOP_STRT_ADD_HANC (0x0150)
115#define VPIF_CH3_BTM_STRT_ADD_HANC (0x0154)
116#define VPIF_CH3_TOP_STRT_ADD_VANC (0x0158)
117#define VPIF_CH3_BTM_STRT_ADD_VANC (0x015c)
118#define VPIF_CH3_SP_CFG (0x0160)
119#define VPIF_CH3_IMG_ADD_OFST (0x0164)
120#define VPIF_CH3_HANC_ADD_OFST (0x0168)
121#define VPIF_CH3_H_CFG (0x016c)
122#define VPIF_CH3_V_CFG_00 (0x0170)
123#define VPIF_CH3_V_CFG_01 (0x0174)
124#define VPIF_CH3_V_CFG_02 (0x0178)
125#define VPIF_CH3_V_CFG_03 (0x017c)
126#define VPIF_CH3_HANC0_STRT (0x0180)
127#define VPIF_CH3_HANC0_SIZE (0x0184)
128#define VPIF_CH3_HANC1_STRT (0x0188)
129#define VPIF_CH3_HANC1_SIZE (0x018c)
130#define VPIF_CH3_VANC0_STRT (0x0190)
131#define VPIF_CH3_VANC0_SIZE (0x0194)
132#define VPIF_CH3_VANC1_STRT (0x0198)
133#define VPIF_CH3_VANC1_SIZE (0x019c)
134
135#define VPIF_IODFT_CTRL (0x01c0)
136
137/* Functions for bit Manipulation */
138static inline void vpif_set_bit(u32 reg, u32 bit)
139{
140 regw((regr(reg)) | (0x01 << bit), reg);
141}
142
143static inline void vpif_clr_bit(u32 reg, u32 bit)
144{
145 regw(((regr(reg)) & ~(0x01 << bit)), reg);
146}
147
148/* Macro for Generating mask */
149#ifdef GENERATE_MASK
150#undef GENERATE_MASK
151#endif
152
153#define GENERATE_MASK(bits, pos) \
154 ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
155
156/* Bit positions in the channel control registers */
157#define VPIF_CH_DATA_MODE_BIT (2)
158#define VPIF_CH_YC_MUX_BIT (3)
159#define VPIF_CH_SDR_FMT_BIT (4)
160#define VPIF_CH_HANC_EN_BIT (8)
161#define VPIF_CH_VANC_EN_BIT (9)
162
163#define VPIF_CAPTURE_CH_NIP (10)
164#define VPIF_DISPLAY_CH_NIP (11)
165
166#define VPIF_DISPLAY_PIX_EN_BIT (10)
167
168#define VPIF_CH_INPUT_FIELD_FRAME_BIT (12)
169
170#define VPIF_CH_FID_POLARITY_BIT (15)
171#define VPIF_CH_V_VALID_POLARITY_BIT (14)
172#define VPIF_CH_H_VALID_POLARITY_BIT (13)
173#define VPIF_CH_DATA_WIDTH_BIT (28)
174
175#define VPIF_CH_CLK_EDGE_CTRL_BIT (31)
176
177/* Mask various length */
178#define VPIF_CH_EAVSAV_MASK GENERATE_MASK(13, 0)
179#define VPIF_CH_LEN_MASK GENERATE_MASK(12, 0)
180#define VPIF_CH_WIDTH_MASK GENERATE_MASK(13, 0)
181#define VPIF_CH_LEN_SHIFT (16)
182
183/* VPIF masks for registers */
184#define VPIF_REQ_SIZE_MASK (0x1ff)
185
186/* bit posotion of interrupt vpif_ch_intr register */
187#define VPIF_INTEN_FRAME_CH0 (0x00000001)
188#define VPIF_INTEN_FRAME_CH1 (0x00000002)
189#define VPIF_INTEN_FRAME_CH2 (0x00000004)
190#define VPIF_INTEN_FRAME_CH3 (0x00000008)
191
192/* bit position of clock and channel enable in vpif_chn_ctrl register */
193
194#define VPIF_CH0_CLK_EN (0x00000002)
195#define VPIF_CH0_EN (0x00000001)
196#define VPIF_CH1_CLK_EN (0x00000002)
197#define VPIF_CH1_EN (0x00000001)
198#define VPIF_CH2_CLK_EN (0x00000002)
199#define VPIF_CH2_EN (0x00000001)
200#define VPIF_CH3_CLK_EN (0x00000002)
201#define VPIF_CH3_EN (0x00000001)
202#define VPIF_CH_CLK_EN (0x00000002)
203#define VPIF_CH_EN (0x00000001)
204
205#define VPIF_INT_TOP (0x00)
206#define VPIF_INT_BOTTOM (0x01)
207#define VPIF_INT_BOTH (0x02)
208
209#define VPIF_CH0_INT_CTRL_SHIFT (6)
210#define VPIF_CH1_INT_CTRL_SHIFT (6)
211#define VPIF_CH2_INT_CTRL_SHIFT (6)
212#define VPIF_CH3_INT_CTRL_SHIFT (6)
213#define VPIF_CH_INT_CTRL_SHIFT (6)
214
215/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
216#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
217 (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
218
219/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
220#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
221 (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
222
223/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
224#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
225 (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
226
227/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
228#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
229 (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
230
231#define VPIF_CH_FID_MASK (0x20)
232#define VPIF_CH_FID_SHIFT (5)
233
234#define VPIF_NTSC_VBI_START_FIELD0 (1)
235#define VPIF_NTSC_VBI_START_FIELD1 (263)
236#define VPIF_PAL_VBI_START_FIELD0 (624)
237#define VPIF_PAL_VBI_START_FIELD1 (311)
238
239#define VPIF_NTSC_HBI_START_FIELD0 (1)
240#define VPIF_NTSC_HBI_START_FIELD1 (263)
241#define VPIF_PAL_HBI_START_FIELD0 (624)
242#define VPIF_PAL_HBI_START_FIELD1 (311)
243
244#define VPIF_NTSC_VBI_COUNT_FIELD0 (20)
245#define VPIF_NTSC_VBI_COUNT_FIELD1 (19)
246#define VPIF_PAL_VBI_COUNT_FIELD0 (24)
247#define VPIF_PAL_VBI_COUNT_FIELD1 (25)
248
249#define VPIF_NTSC_HBI_COUNT_FIELD0 (263)
250#define VPIF_NTSC_HBI_COUNT_FIELD1 (262)
251#define VPIF_PAL_HBI_COUNT_FIELD0 (312)
252#define VPIF_PAL_HBI_COUNT_FIELD1 (313)
253
254#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
255#define VPIF_PAL_VBI_SAMPLES_PER_LINE (720)
256#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
257#define VPIF_PAL_HBI_SAMPLES_PER_LINE (280)
258
259#define VPIF_CH_VANC_EN (0x20)
260#define VPIF_DMA_REQ_SIZE (0x080)
261#define VPIF_EMULATION_DISABLE (0x01)
262
263extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
264
265/* inline function to enable/disable channel0 */
266static inline void enable_channel0(int enable)
267{
268 if (enable)
269 regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
270 else
271 regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
272}
273
274/* inline function to enable/disable channel1 */
275static inline void enable_channel1(int enable)
276{
277 if (enable)
278 regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
279 else
280 regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
281}
282
283/* inline function to enable interrupt for channel0 */
284static inline void channel0_intr_enable(int enable)
285{
286 unsigned long flags;
287
288 spin_lock_irqsave(&vpif_lock, flags);
289
290 if (enable) {
291 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
292 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
293
294 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
295 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
296 VPIF_INTEN_SET);
297 } else {
298 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
299 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
300 VPIF_INTEN_SET);
301 }
302 spin_unlock_irqrestore(&vpif_lock, flags);
303}
304
305/* inline function to enable interrupt for channel1 */
306static inline void channel1_intr_enable(int enable)
307{
308 unsigned long flags;
309
310 spin_lock_irqsave(&vpif_lock, flags);
311
312 if (enable) {
313 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
314 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
315
316 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
317 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
318 VPIF_INTEN_SET);
319 } else {
320 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
321 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
322 VPIF_INTEN_SET);
323 }
324 spin_unlock_irqrestore(&vpif_lock, flags);
325}
326
327/* inline function to set buffer addresses in case of Y/C non mux mode */
328static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
329 unsigned long btm_strt_luma,
330 unsigned long top_strt_chroma,
331 unsigned long btm_strt_chroma)
332{
333 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
334 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
335 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
336 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
337}
338
339/* inline function to set buffer addresses in VPIF registers for video data */
340static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
341 unsigned long btm_strt_luma,
342 unsigned long top_strt_chroma,
343 unsigned long btm_strt_chroma)
344{
345 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
346 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
347 regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
348 regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
349}
350
351static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
352 unsigned long btm_strt_luma,
353 unsigned long top_strt_chroma,
354 unsigned long btm_strt_chroma)
355{
356
357 regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
358 regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
359 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
360 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
361}
362
363static inline void ch0_set_vbi_addr(unsigned long top_vbi,
364 unsigned long btm_vbi, unsigned long a, unsigned long b)
365{
366 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
367 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
368}
369
370static inline void ch0_set_hbi_addr(unsigned long top_vbi,
371 unsigned long btm_vbi, unsigned long a, unsigned long b)
372{
373 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
374 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
375}
376
377static inline void ch1_set_vbi_addr(unsigned long top_vbi,
378 unsigned long btm_vbi, unsigned long a, unsigned long b)
379{
380 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
381 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
382}
383
384static inline void ch1_set_hbi_addr(unsigned long top_vbi,
385 unsigned long btm_vbi, unsigned long a, unsigned long b)
386{
387 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
388 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
389}
390
391/* Inline function to enable raw vbi in the given channel */
392static inline void disable_raw_feature(u8 channel_id, u8 index)
393{
394 u32 ctrl_reg;
395 if (0 == channel_id)
396 ctrl_reg = VPIF_CH0_CTRL;
397 else
398 ctrl_reg = VPIF_CH1_CTRL;
399
400 if (1 == index)
401 vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
402 else
403 vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
404}
405
406static inline void enable_raw_feature(u8 channel_id, u8 index)
407{
408 u32 ctrl_reg;
409 if (0 == channel_id)
410 ctrl_reg = VPIF_CH0_CTRL;
411 else
412 ctrl_reg = VPIF_CH1_CTRL;
413
414 if (1 == index)
415 vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
416 else
417 vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
418}
419
420/* inline function to enable/disable channel2 */
421static inline void enable_channel2(int enable)
422{
423 if (enable) {
424 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
425 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
426 } else {
427 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
428 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
429 }
430}
431
432/* inline function to enable/disable channel3 */
433static inline void enable_channel3(int enable)
434{
435 if (enable) {
436 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
437 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
438 } else {
439 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
440 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
441 }
442}
443
444/* inline function to enable interrupt for channel2 */
445static inline void channel2_intr_enable(int enable)
446{
447 unsigned long flags;
448
449 spin_lock_irqsave(&vpif_lock, flags);
450
451 if (enable) {
452 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
453 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
454 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
455 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
456 VPIF_INTEN_SET);
457 } else {
458 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
459 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
460 VPIF_INTEN_SET);
461 }
462 spin_unlock_irqrestore(&vpif_lock, flags);
463}
464
465/* inline function to enable interrupt for channel3 */
466static inline void channel3_intr_enable(int enable)
467{
468 unsigned long flags;
469
470 spin_lock_irqsave(&vpif_lock, flags);
471
472 if (enable) {
473 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
474 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
475
476 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
477 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
478 VPIF_INTEN_SET);
479 } else {
480 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
481 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
482 VPIF_INTEN_SET);
483 }
484 spin_unlock_irqrestore(&vpif_lock, flags);
485}
486
487/* inline function to enable raw vbi data for channel2 */
488static inline void channel2_raw_enable(int enable, u8 index)
489{
490 u32 mask;
491
492 if (1 == index)
493 mask = VPIF_CH_VANC_EN_BIT;
494 else
495 mask = VPIF_CH_HANC_EN_BIT;
496
497 if (enable)
498 vpif_set_bit(VPIF_CH2_CTRL, mask);
499 else
500 vpif_clr_bit(VPIF_CH2_CTRL, mask);
501}
502
503/* inline function to enable raw vbi data for channel3*/
504static inline void channel3_raw_enable(int enable, u8 index)
505{
506 u32 mask;
507
508 if (1 == index)
509 mask = VPIF_CH_VANC_EN_BIT;
510 else
511 mask = VPIF_CH_HANC_EN_BIT;
512
513 if (enable)
514 vpif_set_bit(VPIF_CH3_CTRL, mask);
515 else
516 vpif_clr_bit(VPIF_CH3_CTRL, mask);
517}
518
519/* inline function to set buffer addresses in case of Y/C non mux mode */
520static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
521 unsigned long btm_strt_luma,
522 unsigned long top_strt_chroma,
523 unsigned long btm_strt_chroma)
524{
525 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
526 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
527 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
528 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
529}
530
531/* inline function to set buffer addresses in VPIF registers for video data */
532static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
533 unsigned long btm_strt_luma,
534 unsigned long top_strt_chroma,
535 unsigned long btm_strt_chroma)
536{
537 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
538 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
539 regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
540 regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
541}
542
543static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
544 unsigned long btm_strt_luma,
545 unsigned long top_strt_chroma,
546 unsigned long btm_strt_chroma)
547{
548 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
549 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
550 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
551 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
552}
553
554/* inline function to set buffer addresses in VPIF registers for vbi data */
555static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
556 unsigned long btm_strt_luma,
557 unsigned long top_strt_chroma,
558 unsigned long btm_strt_chroma)
559{
560 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
561 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
562}
563
564static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
565 unsigned long btm_strt_luma,
566 unsigned long top_strt_chroma,
567 unsigned long btm_strt_chroma)
568{
569 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
570 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
571}
572
573#define VPIF_MAX_NAME (30)
574
575/* This structure will store size parameters as per the mode selected by user */
576struct vpif_channel_config_params {
577 char name[VPIF_MAX_NAME]; /* Name of the mode */
578 u16 width; /* Indicates width of the image */
579 u16 height; /* Indicates height of the image */
580 u8 fps;
581 u8 frm_fmt; /* Indicates whether this is interlaced
582 * or progressive format */
583 u8 ycmux_mode; /* Indicates whether this mode requires
584 * single or two channels */
585 u16 eav2sav; /* length of sav 2 eav */
586 u16 sav2eav; /* length of sav 2 eav */
587 u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */
588 u16 vsize; /* Vertical size of the image */
589 u8 capture_format; /* Indicates whether capture format
590 * is in BT or in CCD/CMOS */
591 u8 vbi_supported; /* Indicates whether this mode
592 * supports capturing vbi or not */
593 u8 hd_sd;
594 v4l2_std_id stdid;
595};
596
597struct vpif_video_params;
598struct vpif_params;
599struct vpif_vbi_params;
600
601int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
602void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
603 u8 channel_id);
604int vpif_channel_getfid(u8 channel_id);
605
606enum data_size {
607 _8BITS = 0,
608 _10BITS,
609 _12BITS,
610};
611
612/* Structure for vpif parameters for raw vbi data */
613struct vpif_vbi_params {
614 __u32 hstart0; /* Horizontal start of raw vbi data for first field */
615 __u32 vstart0; /* Vertical start of raw vbi data for first field */
616 __u32 hsize0; /* Horizontal size of raw vbi data for first field */
617 __u32 vsize0; /* Vertical size of raw vbi data for first field */
618 __u32 hstart1; /* Horizontal start of raw vbi data for second field */
619 __u32 vstart1; /* Vertical start of raw vbi data for second field */
620 __u32 hsize1; /* Horizontal size of raw vbi data for second field */
621 __u32 vsize1; /* Vertical size of raw vbi data for second field */
622};
623
624/* structure for vpif parameters */
625struct vpif_video_params {
626 __u8 storage_mode; /* Indicates field or frame mode */
627 unsigned long hpitch;
628 v4l2_std_id stdid;
629};
630
631struct vpif_params {
632 struct vpif_interface iface;
633 struct vpif_video_params video_params;
634 struct vpif_channel_config_params std_info;
635 union param {
636 struct vpif_vbi_params vbi_params;
637 enum data_size data_sz;
638 } params;
639};
640
641#endif /* End of #ifndef VPIF_H */
642
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
new file mode 100644
index 000000000000..d947ee5e4eb4
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -0,0 +1,2168 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * TODO : add support for VBI & HBI data service
19 * add static buffer allocation
20 */
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/workqueue.h>
29#include <linux/string.h>
30#include <linux/videodev2.h>
31#include <linux/wait.h>
32#include <linux/time.h>
33#include <linux/i2c.h>
34#include <linux/platform_device.h>
35#include <linux/io.h>
36#include <linux/version.h>
37#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h>
39
40#include "vpif_capture.h"
41#include "vpif.h"
42
43MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
44MODULE_LICENSE("GPL");
45
46#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
47#define vpif_dbg(level, debug, fmt, arg...) \
48 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
49
50static int debug = 1;
51static u32 ch0_numbuffers = 3;
52static u32 ch1_numbuffers = 3;
53static u32 ch0_bufsize = 1920 * 1080 * 2;
54static u32 ch1_bufsize = 720 * 576 * 2;
55
56module_param(debug, int, 0644);
57module_param(ch0_numbuffers, uint, S_IRUGO);
58module_param(ch1_numbuffers, uint, S_IRUGO);
59module_param(ch0_bufsize, uint, S_IRUGO);
60module_param(ch1_bufsize, uint, S_IRUGO);
61
62MODULE_PARM_DESC(debug, "Debug level 0-1");
63MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
64MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
65MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
66MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
67
68static struct vpif_config_params config_params = {
69 .min_numbuffers = 3,
70 .numbuffers[0] = 3,
71 .numbuffers[1] = 3,
72 .min_bufsize[0] = 720 * 480 * 2,
73 .min_bufsize[1] = 720 * 480 * 2,
74 .channel_bufsize[0] = 1920 * 1080 * 2,
75 .channel_bufsize[1] = 720 * 576 * 2,
76};
77
78/* global variables */
79static struct vpif_device vpif_obj = { {NULL} };
80static struct device *vpif_dev;
81
82/**
83 * ch_params: video standard configuration parameters for vpif
84 */
85static const struct vpif_channel_config_params ch_params[] = {
86 {
87 "NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
88 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
89 },
90 {
91 "PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
92 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
93 },
94};
95
96/**
97 * vpif_uservirt_to_phys : translate user/virtual address to phy address
98 * @virtp: user/virtual address
99 *
100 * This inline function is used to convert user space virtual address to
101 * physical address.
102 */
103static inline u32 vpif_uservirt_to_phys(u32 virtp)
104{
105 unsigned long physp = 0;
106 struct mm_struct *mm = current->mm;
107 struct vm_area_struct *vma;
108
109 vma = find_vma(mm, virtp);
110
111 /* For kernel direct-mapped memory, take the easy way */
112 if (virtp >= PAGE_OFFSET)
113 physp = virt_to_phys((void *)virtp);
114 else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
115 /**
116 * this will catch, kernel-allocated, mmaped-to-usermode
117 * addresses
118 */
119 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
120 else {
121 /* otherwise, use get_user_pages() for general userland pages */
122 int res, nr_pages = 1;
123 struct page *pages;
124
125 down_read(&current->mm->mmap_sem);
126
127 res = get_user_pages(current, current->mm,
128 virtp, nr_pages, 1, 0, &pages, NULL);
129 up_read(&current->mm->mmap_sem);
130
131 if (res == nr_pages)
132 physp = __pa(page_address(&pages[0]) +
133 (virtp & ~PAGE_MASK));
134 else {
135 vpif_err("get_user_pages failed\n");
136 return 0;
137 }
138 }
139 return physp;
140}
141
142/**
143 * buffer_prepare : callback function for buffer prepare
144 * @q : buffer queue ptr
145 * @vb: ptr to video buffer
146 * @field: field info
147 *
148 * This is the callback function for buffer prepare when videobuf_qbuf()
149 * function is called. The buffer is prepared and user space virtual address
150 * or user address is converted into physical address
151 */
152static int vpif_buffer_prepare(struct videobuf_queue *q,
153 struct videobuf_buffer *vb,
154 enum v4l2_field field)
155{
156 /* Get the file handle object and channel object */
157 struct vpif_fh *fh = q->priv_data;
158 struct channel_obj *ch = fh->channel;
159 struct common_obj *common;
160 unsigned long addr;
161
162
163 vpif_dbg(2, debug, "vpif_buffer_prepare\n");
164
165 common = &ch->common[VPIF_VIDEO_INDEX];
166
167 /* If buffer is not initialized, initialize it */
168 if (VIDEOBUF_NEEDS_INIT == vb->state) {
169 vb->width = common->width;
170 vb->height = common->height;
171 vb->size = vb->width * vb->height;
172 vb->field = field;
173 }
174 vb->state = VIDEOBUF_PREPARED;
175 /**
176 * if user pointer memory mechanism is used, get the physical
177 * address of the buffer
178 */
179 if (V4L2_MEMORY_USERPTR == common->memory) {
180 if (0 == vb->baddr) {
181 vpif_dbg(1, debug, "buffer address is 0\n");
182 return -EINVAL;
183
184 }
185 vb->boff = vpif_uservirt_to_phys(vb->baddr);
186 if (!IS_ALIGNED(vb->boff, 8))
187 goto exit;
188 }
189
190 addr = vb->boff;
191 if (q->streaming) {
192 if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
193 !IS_ALIGNED((addr + common->ybtm_off), 8) ||
194 !IS_ALIGNED((addr + common->ctop_off), 8) ||
195 !IS_ALIGNED((addr + common->cbtm_off), 8))
196 goto exit;
197 }
198 return 0;
199exit:
200 vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
201 return -EINVAL;
202}
203
204/**
205 * vpif_buffer_setup : Callback function for buffer setup.
206 * @q: buffer queue ptr
207 * @count: number of buffers
208 * @size: size of the buffer
209 *
210 * This callback function is called when reqbuf() is called to adjust
211 * the buffer count and buffer size
212 */
213static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
214 unsigned int *size)
215{
216 /* Get the file handle object and channel object */
217 struct vpif_fh *fh = q->priv_data;
218 struct channel_obj *ch = fh->channel;
219 struct common_obj *common;
220
221 common = &ch->common[VPIF_VIDEO_INDEX];
222
223 vpif_dbg(2, debug, "vpif_buffer_setup\n");
224
225 /* If memory type is not mmap, return */
226 if (V4L2_MEMORY_MMAP != common->memory)
227 return 0;
228
229 /* Calculate the size of the buffer */
230 *size = config_params.channel_bufsize[ch->channel_id];
231
232 if (*count < config_params.min_numbuffers)
233 *count = config_params.min_numbuffers;
234 return 0;
235}
236
237/**
238 * vpif_buffer_queue : Callback function to add buffer to DMA queue
239 * @q: ptr to videobuf_queue
240 * @vb: ptr to videobuf_buffer
241 */
242static void vpif_buffer_queue(struct videobuf_queue *q,
243 struct videobuf_buffer *vb)
244{
245 /* Get the file handle object and channel object */
246 struct vpif_fh *fh = q->priv_data;
247 struct channel_obj *ch = fh->channel;
248 struct common_obj *common;
249
250 common = &ch->common[VPIF_VIDEO_INDEX];
251
252 vpif_dbg(2, debug, "vpif_buffer_queue\n");
253
254 /* add the buffer to the DMA queue */
255 list_add_tail(&vb->queue, &common->dma_queue);
256 /* Change state of the buffer */
257 vb->state = VIDEOBUF_QUEUED;
258}
259
260/**
261 * vpif_buffer_release : Callback function to free buffer
262 * @q: buffer queue ptr
263 * @vb: ptr to video buffer
264 *
265 * This function is called from the videobuf layer to free memory
266 * allocated to the buffers
267 */
268static void vpif_buffer_release(struct videobuf_queue *q,
269 struct videobuf_buffer *vb)
270{
271 /* Get the file handle object and channel object */
272 struct vpif_fh *fh = q->priv_data;
273 struct channel_obj *ch = fh->channel;
274 struct common_obj *common;
275
276 common = &ch->common[VPIF_VIDEO_INDEX];
277
278 videobuf_dma_contig_free(q, vb);
279 vb->state = VIDEOBUF_NEEDS_INIT;
280}
281
282static struct videobuf_queue_ops video_qops = {
283 .buf_setup = vpif_buffer_setup,
284 .buf_prepare = vpif_buffer_prepare,
285 .buf_queue = vpif_buffer_queue,
286 .buf_release = vpif_buffer_release,
287};
288
289static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
290 { {1, 1} };
291
292/**
293 * vpif_process_buffer_complete: process a completed buffer
294 * @common: ptr to common channel object
295 *
296 * This function time stamp the buffer and mark it as DONE. It also
297 * wake up any process waiting on the QUEUE and set the next buffer
298 * as current
299 */
300static void vpif_process_buffer_complete(struct common_obj *common)
301{
302 do_gettimeofday(&common->cur_frm->ts);
303 common->cur_frm->state = VIDEOBUF_DONE;
304 wake_up_interruptible(&common->cur_frm->done);
305 /* Make curFrm pointing to nextFrm */
306 common->cur_frm = common->next_frm;
307}
308
309/**
310 * vpif_schedule_next_buffer: set next buffer address for capture
311 * @common : ptr to common channel object
312 *
313 * This function will get next buffer from the dma queue and
314 * set the buffer address in the vpif register for capture.
315 * the buffer is marked active
316 */
317static void vpif_schedule_next_buffer(struct common_obj *common)
318{
319 unsigned long addr = 0;
320
321 common->next_frm = list_entry(common->dma_queue.next,
322 struct videobuf_buffer, queue);
323 /* Remove that buffer from the buffer queue */
324 list_del(&common->next_frm->queue);
325 common->next_frm->state = VIDEOBUF_ACTIVE;
326 if (V4L2_MEMORY_USERPTR == common->memory)
327 addr = common->next_frm->boff;
328 else
329 addr = videobuf_to_dma_contig(common->next_frm);
330
331 /* Set top and bottom field addresses in VPIF registers */
332 common->set_addr(addr + common->ytop_off,
333 addr + common->ybtm_off,
334 addr + common->ctop_off,
335 addr + common->cbtm_off);
336}
337
338/**
339 * vpif_channel_isr : ISR handler for vpif capture
340 * @irq: irq number
341 * @dev_id: dev_id ptr
342 *
343 * It changes status of the captured buffer, takes next buffer from the queue
344 * and sets its address in VPIF registers
345 */
346static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
347{
348 struct vpif_device *dev = &vpif_obj;
349 struct common_obj *common;
350 struct channel_obj *ch;
351 enum v4l2_field field;
352 int channel_id = 0;
353 int fid = -1, i;
354
355 channel_id = *(int *)(dev_id);
356 ch = dev->dev[channel_id];
357
358 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
359
360 for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
361 common = &ch->common[i];
362 /* skip If streaming is not started in this channel */
363 if (0 == common->started)
364 continue;
365
366 /* Check the field format */
367 if (1 == ch->vpifparams.std_info.frm_fmt) {
368 /* Progressive mode */
369 if (list_empty(&common->dma_queue))
370 continue;
371
372 if (!channel_first_int[i][channel_id])
373 vpif_process_buffer_complete(common);
374
375 channel_first_int[i][channel_id] = 0;
376
377 vpif_schedule_next_buffer(common);
378
379
380 channel_first_int[i][channel_id] = 0;
381 } else {
382 /**
383 * Interlaced mode. If it is first interrupt, ignore
384 * it
385 */
386 if (channel_first_int[i][channel_id]) {
387 channel_first_int[i][channel_id] = 0;
388 continue;
389 }
390 if (0 == i) {
391 ch->field_id ^= 1;
392 /* Get field id from VPIF registers */
393 fid = vpif_channel_getfid(ch->channel_id);
394 if (fid != ch->field_id) {
395 /**
396 * If field id does not match stored
397 * field id, make them in sync
398 */
399 if (0 == fid)
400 ch->field_id = fid;
401 return IRQ_HANDLED;
402 }
403 }
404 /* device field id and local field id are in sync */
405 if (0 == fid) {
406 /* this is even field */
407 if (common->cur_frm == common->next_frm)
408 continue;
409
410 /* mark the current buffer as done */
411 vpif_process_buffer_complete(common);
412 } else if (1 == fid) {
413 /* odd field */
414 if (list_empty(&common->dma_queue) ||
415 (common->cur_frm != common->next_frm))
416 continue;
417
418 vpif_schedule_next_buffer(common);
419 }
420 }
421 }
422 return IRQ_HANDLED;
423}
424
425/**
426 * vpif_update_std_info() - update standard related info
427 * @ch: ptr to channel object
428 *
429 * For a given standard selected by application, update values
430 * in the device data structures
431 */
432static int vpif_update_std_info(struct channel_obj *ch)
433{
434 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
435 struct vpif_params *vpifparams = &ch->vpifparams;
436 const struct vpif_channel_config_params *config;
437 struct vpif_channel_config_params *std_info;
438 struct video_obj *vid_ch = &ch->video;
439 int index;
440
441 vpif_dbg(2, debug, "vpif_update_std_info\n");
442
443 std_info = &vpifparams->std_info;
444
445 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
446 config = &ch_params[index];
447 if (config->stdid & vid_ch->stdid) {
448 memcpy(std_info, config, sizeof(*config));
449 break;
450 }
451 }
452
453 /* standard not found */
454 if (index == ARRAY_SIZE(ch_params))
455 return -EINVAL;
456
457 common->fmt.fmt.pix.width = std_info->width;
458 common->width = std_info->width;
459 common->fmt.fmt.pix.height = std_info->height;
460 common->height = std_info->height;
461 common->fmt.fmt.pix.bytesperline = std_info->width;
462 vpifparams->video_params.hpitch = std_info->width;
463 vpifparams->video_params.storage_mode = std_info->frm_fmt;
464 return 0;
465}
466
467/**
468 * vpif_calculate_offsets : This function calculates buffers offsets
469 * @ch : ptr to channel object
470 *
471 * This function calculates buffer offsets for Y and C in the top and
472 * bottom field
473 */
474static void vpif_calculate_offsets(struct channel_obj *ch)
475{
476 unsigned int hpitch, vpitch, sizeimage;
477 struct video_obj *vid_ch = &(ch->video);
478 struct vpif_params *vpifparams = &ch->vpifparams;
479 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
480 enum v4l2_field field = common->fmt.fmt.pix.field;
481
482 vpif_dbg(2, debug, "vpif_calculate_offsets\n");
483
484 if (V4L2_FIELD_ANY == field) {
485 if (vpifparams->std_info.frm_fmt)
486 vid_ch->buf_field = V4L2_FIELD_NONE;
487 else
488 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
489 } else
490 vid_ch->buf_field = common->fmt.fmt.pix.field;
491
492 if (V4L2_MEMORY_USERPTR == common->memory)
493 sizeimage = common->fmt.fmt.pix.sizeimage;
494 else
495 sizeimage = config_params.channel_bufsize[ch->channel_id];
496
497 hpitch = common->fmt.fmt.pix.bytesperline;
498 vpitch = sizeimage / (hpitch * 2);
499
500 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
501 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
502 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
503 common->ytop_off = 0;
504 common->ybtm_off = hpitch;
505 common->ctop_off = sizeimage / 2;
506 common->cbtm_off = sizeimage / 2 + hpitch;
507 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
508 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
509 common->ytop_off = 0;
510 common->ybtm_off = sizeimage / 4;
511 common->ctop_off = sizeimage / 2;
512 common->cbtm_off = common->ctop_off + sizeimage / 4;
513 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
514 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
515 common->ybtm_off = 0;
516 common->ytop_off = sizeimage / 4;
517 common->cbtm_off = sizeimage / 2;
518 common->ctop_off = common->cbtm_off + sizeimage / 4;
519 }
520 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
521 (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
522 vpifparams->video_params.storage_mode = 1;
523 else
524 vpifparams->video_params.storage_mode = 0;
525
526 if (1 == vpifparams->std_info.frm_fmt)
527 vpifparams->video_params.hpitch =
528 common->fmt.fmt.pix.bytesperline;
529 else {
530 if ((field == V4L2_FIELD_ANY)
531 || (field == V4L2_FIELD_INTERLACED))
532 vpifparams->video_params.hpitch =
533 common->fmt.fmt.pix.bytesperline * 2;
534 else
535 vpifparams->video_params.hpitch =
536 common->fmt.fmt.pix.bytesperline;
537 }
538
539 ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
540}
541
542/**
543 * vpif_config_format: configure default frame format in the device
544 * ch : ptr to channel object
545 */
546static void vpif_config_format(struct channel_obj *ch)
547{
548 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
549
550 vpif_dbg(2, debug, "vpif_config_format\n");
551
552 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
553 if (config_params.numbuffers[ch->channel_id] == 0)
554 common->memory = V4L2_MEMORY_USERPTR;
555 else
556 common->memory = V4L2_MEMORY_MMAP;
557
558 common->fmt.fmt.pix.sizeimage
559 = config_params.channel_bufsize[ch->channel_id];
560
561 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
562 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
563 else
564 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
565 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
566}
567
568/**
569 * vpif_get_default_field() - Get default field type based on interface
570 * @vpif_params - ptr to vpif params
571 */
572static inline enum v4l2_field vpif_get_default_field(
573 struct vpif_interface *iface)
574{
575 return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
576 V4L2_FIELD_INTERLACED;
577}
578
579/**
580 * vpif_check_format() - check given pixel format for compatibility
581 * @ch - channel ptr
582 * @pixfmt - Given pixel format
583 * @update - update the values as per hardware requirement
584 *
585 * Check the application pixel format for S_FMT and update the input
586 * values as per hardware limits for TRY_FMT. The default pixel and
587 * field format is selected based on interface type.
588 */
589static int vpif_check_format(struct channel_obj *ch,
590 struct v4l2_pix_format *pixfmt,
591 int update)
592{
593 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
594 struct vpif_params *vpif_params = &ch->vpifparams;
595 enum v4l2_field field = pixfmt->field;
596 u32 sizeimage, hpitch, vpitch;
597 int ret = -EINVAL;
598
599 vpif_dbg(2, debug, "vpif_check_format\n");
600 /**
601 * first check for the pixel format. If if_type is Raw bayer,
602 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
603 * V4L2_PIX_FMT_YUV422P is supported
604 */
605 if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
606 if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
607 if (!update) {
608 vpif_dbg(2, debug, "invalid pix format\n");
609 goto exit;
610 }
611 pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
612 }
613 } else {
614 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
615 if (!update) {
616 vpif_dbg(2, debug, "invalid pixel format\n");
617 goto exit;
618 }
619 pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
620 }
621 }
622
623 if (!(VPIF_VALID_FIELD(field))) {
624 if (!update) {
625 vpif_dbg(2, debug, "invalid field format\n");
626 goto exit;
627 }
628 /**
629 * By default use FIELD_NONE for RAW Bayer capture
630 * and FIELD_INTERLACED for other interfaces
631 */
632 field = vpif_get_default_field(&vpif_params->iface);
633 } else if (field == V4L2_FIELD_ANY)
634 /* unsupported field. Use default */
635 field = vpif_get_default_field(&vpif_params->iface);
636
637 /* validate the hpitch */
638 hpitch = pixfmt->bytesperline;
639 if (hpitch < vpif_params->std_info.width) {
640 if (!update) {
641 vpif_dbg(2, debug, "invalid hpitch\n");
642 goto exit;
643 }
644 hpitch = vpif_params->std_info.width;
645 }
646
647 if (V4L2_MEMORY_USERPTR == common->memory)
648 sizeimage = pixfmt->sizeimage;
649 else
650 sizeimage = config_params.channel_bufsize[ch->channel_id];
651
652 vpitch = sizeimage / (hpitch * 2);
653
654 /* validate the vpitch */
655 if (vpitch < vpif_params->std_info.height) {
656 if (!update) {
657 vpif_dbg(2, debug, "Invalid vpitch\n");
658 goto exit;
659 }
660 vpitch = vpif_params->std_info.height;
661 }
662
663 /* Check for 8 byte alignment */
664 if (!ALIGN(hpitch, 8)) {
665 if (!update) {
666 vpif_dbg(2, debug, "invalid pitch alignment\n");
667 goto exit;
668 }
669 /* adjust to next 8 byte boundary */
670 hpitch = (((hpitch + 7) / 8) * 8);
671 }
672 /* if update is set, modify the bytesperline and sizeimage */
673 if (update) {
674 pixfmt->bytesperline = hpitch;
675 pixfmt->sizeimage = hpitch * vpitch * 2;
676 }
677 /**
678 * Image width and height is always based on current standard width and
679 * height
680 */
681 pixfmt->width = common->fmt.fmt.pix.width;
682 pixfmt->height = common->fmt.fmt.pix.height;
683 return 0;
684exit:
685 return ret;
686}
687
688/**
689 * vpif_config_addr() - function to configure buffer address in vpif
690 * @ch - channel ptr
691 * @muxmode - channel mux mode
692 */
693static void vpif_config_addr(struct channel_obj *ch, int muxmode)
694{
695 struct common_obj *common;
696
697 vpif_dbg(2, debug, "vpif_config_addr\n");
698
699 common = &(ch->common[VPIF_VIDEO_INDEX]);
700
701 if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
702 common->set_addr = ch1_set_videobuf_addr;
703 else if (2 == muxmode)
704 common->set_addr = ch0_set_videobuf_addr_yc_nmux;
705 else
706 common->set_addr = ch0_set_videobuf_addr;
707}
708
709/**
710 * vpfe_mmap : It is used to map kernel space buffers into user spaces
711 * @filep: file pointer
712 * @vma: ptr to vm_area_struct
713 */
714static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
715{
716 /* Get the channel object and file handle object */
717 struct vpif_fh *fh = filep->private_data;
718 struct channel_obj *ch = fh->channel;
719 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
720
721 vpif_dbg(2, debug, "vpif_mmap\n");
722
723 return videobuf_mmap_mapper(&common->buffer_queue, vma);
724}
725
726/**
727 * vpif_poll: It is used for select/poll system call
728 * @filep: file pointer
729 * @wait: poll table to wait
730 */
731static unsigned int vpif_poll(struct file *filep, poll_table * wait)
732{
733 int err = 0;
734 struct vpif_fh *fh = filep->private_data;
735 struct channel_obj *channel = fh->channel;
736 struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
737
738 vpif_dbg(2, debug, "vpif_poll\n");
739
740 if (common->started)
741 err = videobuf_poll_stream(filep, &common->buffer_queue, wait);
742
743 return 0;
744}
745
746/**
747 * vpif_open : vpif open handler
748 * @filep: file ptr
749 *
750 * It creates object of file handle structure and stores it in private_data
751 * member of filepointer
752 */
753static int vpif_open(struct file *filep)
754{
755 struct vpif_capture_config *config = vpif_dev->platform_data;
756 struct video_device *vdev = video_devdata(filep);
757 struct common_obj *common;
758 struct video_obj *vid_ch;
759 struct channel_obj *ch;
760 struct vpif_fh *fh;
761 int i, ret = 0;
762
763 vpif_dbg(2, debug, "vpif_open\n");
764
765 ch = video_get_drvdata(vdev);
766
767 vid_ch = &ch->video;
768 common = &ch->common[VPIF_VIDEO_INDEX];
769
770 if (mutex_lock_interruptible(&common->lock))
771 return -ERESTARTSYS;
772
773 if (NULL == ch->curr_subdev_info) {
774 /**
775 * search through the sub device to see a registered
776 * sub device and make it as current sub device
777 */
778 for (i = 0; i < config->subdev_count; i++) {
779 if (vpif_obj.sd[i]) {
780 /* the sub device is registered */
781 ch->curr_subdev_info = &config->subdev_info[i];
782 /* make first input as the current input */
783 vid_ch->input_idx = 0;
784 break;
785 }
786 }
787 if (i == config->subdev_count) {
788 vpif_err("No sub device registered\n");
789 ret = -ENOENT;
790 goto exit;
791 }
792 }
793
794 /* Allocate memory for the file handle object */
795 fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
796 if (NULL == fh) {
797 vpif_err("unable to allocate memory for file handle object\n");
798 ret = -ENOMEM;
799 goto exit;
800 }
801
802 /* store pointer to fh in private_data member of filep */
803 filep->private_data = fh;
804 fh->channel = ch;
805 fh->initialized = 0;
806 /* If decoder is not initialized. initialize it */
807 if (!ch->initialized) {
808 fh->initialized = 1;
809 ch->initialized = 1;
810 memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
811 }
812 /* Increment channel usrs counter */
813 ch->usrs++;
814 /* Set io_allowed member to false */
815 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
816 /* Initialize priority of this instance to default priority */
817 fh->prio = V4L2_PRIORITY_UNSET;
818 v4l2_prio_open(&ch->prio, &fh->prio);
819exit:
820 mutex_unlock(&common->lock);
821 return ret;
822}
823
824/**
825 * vpif_release : function to clean up file close
826 * @filep: file pointer
827 *
828 * This function deletes buffer queue, frees the buffers and the vpfe file
829 * handle
830 */
831static int vpif_release(struct file *filep)
832{
833 struct vpif_fh *fh = filep->private_data;
834 struct channel_obj *ch = fh->channel;
835 struct common_obj *common;
836
837 vpif_dbg(2, debug, "vpif_release\n");
838
839 common = &ch->common[VPIF_VIDEO_INDEX];
840
841 if (mutex_lock_interruptible(&common->lock))
842 return -ERESTARTSYS;
843
844 /* if this instance is doing IO */
845 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
846 /* Reset io_usrs member of channel object */
847 common->io_usrs = 0;
848 /* Disable channel as per its device type and channel id */
849 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
850 enable_channel0(0);
851 channel0_intr_enable(0);
852 }
853 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
854 (2 == common->started)) {
855 enable_channel1(0);
856 channel1_intr_enable(0);
857 }
858 common->started = 0;
859 /* Free buffers allocated */
860 videobuf_queue_cancel(&common->buffer_queue);
861 videobuf_mmap_free(&common->buffer_queue);
862 }
863
864 /* Decrement channel usrs counter */
865 ch->usrs--;
866
867 /* unlock mutex on channel object */
868 mutex_unlock(&common->lock);
869
870 /* Close the priority */
871 v4l2_prio_close(&ch->prio, &fh->prio);
872
873 if (fh->initialized)
874 ch->initialized = 0;
875
876 filep->private_data = NULL;
877 kfree(fh);
878 return 0;
879}
880
881/**
882 * vpif_reqbufs() - request buffer handler
883 * @file: file ptr
884 * @priv: file handle
885 * @reqbuf: request buffer structure ptr
886 */
887static int vpif_reqbufs(struct file *file, void *priv,
888 struct v4l2_requestbuffers *reqbuf)
889{
890 struct vpif_fh *fh = priv;
891 struct channel_obj *ch = fh->channel;
892 struct common_obj *common;
893 u8 index = 0;
894 int ret = 0;
895
896 vpif_dbg(2, debug, "vpif_reqbufs\n");
897
898 /**
899 * This file handle has not initialized the channel,
900 * It is not allowed to do settings
901 */
902 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
903 || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
904 if (!fh->initialized) {
905 vpif_dbg(1, debug, "Channel Busy\n");
906 return -EBUSY;
907 }
908 }
909
910 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
911 return -EINVAL;
912
913 index = VPIF_VIDEO_INDEX;
914
915 common = &ch->common[index];
916
917 if (mutex_lock_interruptible(&common->lock))
918 return -ERESTARTSYS;
919
920 if (0 != common->io_usrs) {
921 ret = -EBUSY;
922 goto reqbuf_exit;
923 }
924
925 /* Initialize videobuf queue as per the buffer type */
926 videobuf_queue_dma_contig_init(&common->buffer_queue,
927 &video_qops, NULL,
928 &common->irqlock,
929 reqbuf->type,
930 common->fmt.fmt.pix.field,
931 sizeof(struct videobuf_buffer), fh);
932
933 /* Set io allowed member of file handle to TRUE */
934 fh->io_allowed[index] = 1;
935 /* Increment io usrs member of channel object to 1 */
936 common->io_usrs = 1;
937 /* Store type of memory requested in channel object */
938 common->memory = reqbuf->memory;
939 INIT_LIST_HEAD(&common->dma_queue);
940
941 /* Allocate buffers */
942 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
943
944reqbuf_exit:
945 mutex_unlock(&common->lock);
946 return ret;
947}
948
949/**
950 * vpif_querybuf() - query buffer handler
951 * @file: file ptr
952 * @priv: file handle
953 * @buf: v4l2 buffer structure ptr
954 */
955static int vpif_querybuf(struct file *file, void *priv,
956 struct v4l2_buffer *buf)
957{
958 struct vpif_fh *fh = priv;
959 struct channel_obj *ch = fh->channel;
960 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
961
962 vpif_dbg(2, debug, "vpif_querybuf\n");
963
964 if (common->fmt.type != buf->type)
965 return -EINVAL;
966
967 if (common->memory != V4L2_MEMORY_MMAP) {
968 vpif_dbg(1, debug, "Invalid memory\n");
969 return -EINVAL;
970 }
971
972 return videobuf_querybuf(&common->buffer_queue, buf);
973}
974
975/**
976 * vpif_qbuf() - query buffer handler
977 * @file: file ptr
978 * @priv: file handle
979 * @buf: v4l2 buffer structure ptr
980 */
981static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
982{
983
984 struct vpif_fh *fh = priv;
985 struct channel_obj *ch = fh->channel;
986 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
987 struct v4l2_buffer tbuf = *buf;
988 struct videobuf_buffer *buf1;
989 unsigned long addr = 0;
990 unsigned long flags;
991 int ret = 0;
992
993 vpif_dbg(2, debug, "vpif_qbuf\n");
994
995 if (common->fmt.type != tbuf.type) {
996 vpif_err("invalid buffer type\n");
997 return -EINVAL;
998 }
999
1000 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1001 vpif_err("fh io not allowed \n");
1002 return -EACCES;
1003 }
1004
1005 if (!(list_empty(&common->dma_queue)) ||
1006 (common->cur_frm != common->next_frm) ||
1007 !common->started ||
1008 (common->started && (0 == ch->field_id)))
1009 return videobuf_qbuf(&common->buffer_queue, buf);
1010
1011 /* bufferqueue is empty store buffer address in VPIF registers */
1012 mutex_lock(&common->buffer_queue.vb_lock);
1013 buf1 = common->buffer_queue.bufs[tbuf.index];
1014
1015 if ((buf1->state == VIDEOBUF_QUEUED) ||
1016 (buf1->state == VIDEOBUF_ACTIVE)) {
1017 vpif_err("invalid state\n");
1018 goto qbuf_exit;
1019 }
1020
1021 switch (buf1->memory) {
1022 case V4L2_MEMORY_MMAP:
1023 if (buf1->baddr == 0)
1024 goto qbuf_exit;
1025 break;
1026
1027 case V4L2_MEMORY_USERPTR:
1028 if (tbuf.length < buf1->bsize)
1029 goto qbuf_exit;
1030
1031 if ((VIDEOBUF_NEEDS_INIT != buf1->state)
1032 && (buf1->baddr != tbuf.m.userptr))
1033 vpif_buffer_release(&common->buffer_queue, buf1);
1034 buf1->baddr = tbuf.m.userptr;
1035 break;
1036
1037 default:
1038 goto qbuf_exit;
1039 }
1040
1041 local_irq_save(flags);
1042 ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
1043 common->buffer_queue.field);
1044 if (ret < 0) {
1045 local_irq_restore(flags);
1046 goto qbuf_exit;
1047 }
1048
1049 buf1->state = VIDEOBUF_ACTIVE;
1050
1051 if (V4L2_MEMORY_USERPTR == common->memory)
1052 addr = buf1->boff;
1053 else
1054 addr = videobuf_to_dma_contig(buf1);
1055
1056 common->next_frm = buf1;
1057 common->set_addr(addr + common->ytop_off,
1058 addr + common->ybtm_off,
1059 addr + common->ctop_off,
1060 addr + common->cbtm_off);
1061
1062 local_irq_restore(flags);
1063 list_add_tail(&buf1->stream, &common->buffer_queue.stream);
1064 mutex_unlock(&common->buffer_queue.vb_lock);
1065 return 0;
1066
1067qbuf_exit:
1068 mutex_unlock(&common->buffer_queue.vb_lock);
1069 return -EINVAL;
1070}
1071
1072/**
1073 * vpif_dqbuf() - query buffer handler
1074 * @file: file ptr
1075 * @priv: file handle
1076 * @buf: v4l2 buffer structure ptr
1077 */
1078static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1079{
1080 struct vpif_fh *fh = priv;
1081 struct channel_obj *ch = fh->channel;
1082 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1083
1084 vpif_dbg(2, debug, "vpif_dqbuf\n");
1085
1086 return videobuf_dqbuf(&common->buffer_queue, buf,
1087 file->f_flags & O_NONBLOCK);
1088}
1089
1090/**
1091 * vpif_streamon() - streamon handler
1092 * @file: file ptr
1093 * @priv: file handle
1094 * @buftype: v4l2 buffer type
1095 */
1096static int vpif_streamon(struct file *file, void *priv,
1097 enum v4l2_buf_type buftype)
1098{
1099
1100 struct vpif_capture_config *config = vpif_dev->platform_data;
1101 struct vpif_fh *fh = priv;
1102 struct channel_obj *ch = fh->channel;
1103 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1104 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1105 struct vpif_params *vpif;
1106 unsigned long addr = 0;
1107 int ret = 0;
1108
1109 vpif_dbg(2, debug, "vpif_streamon\n");
1110
1111 vpif = &ch->vpifparams;
1112
1113 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1114 vpif_dbg(1, debug, "buffer type not supported\n");
1115 return -EINVAL;
1116 }
1117
1118 /* If file handle is not allowed IO, return error */
1119 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1120 vpif_dbg(1, debug, "io not allowed\n");
1121 return -EACCES;
1122 }
1123
1124 /* If Streaming is already started, return error */
1125 if (common->started) {
1126 vpif_dbg(1, debug, "channel->started\n");
1127 return -EBUSY;
1128 }
1129
1130 if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
1131 oth_ch->common[VPIF_VIDEO_INDEX].started &&
1132 vpif->std_info.ycmux_mode == 0) ||
1133 ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
1134 (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1135 vpif_dbg(1, debug, "other channel is being used\n");
1136 return -EBUSY;
1137 }
1138
1139 ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
1140 if (ret)
1141 return ret;
1142
1143 /* Enable streamon on the sub device */
1144 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1145 s_stream, 1);
1146
1147 if (ret && (ret != -ENOIOCTLCMD)) {
1148 vpif_dbg(1, debug, "stream on failed in subdev\n");
1149 return ret;
1150 }
1151
1152 /* Call videobuf_streamon to start streaming in videobuf */
1153 ret = videobuf_streamon(&common->buffer_queue);
1154 if (ret) {
1155 vpif_dbg(1, debug, "videobuf_streamon\n");
1156 return ret;
1157 }
1158
1159 if (mutex_lock_interruptible(&common->lock)) {
1160 ret = -ERESTARTSYS;
1161 goto streamoff_exit;
1162 }
1163
1164 /* If buffer queue is empty, return error */
1165 if (list_empty(&common->dma_queue)) {
1166 vpif_dbg(1, debug, "buffer queue is empty\n");
1167 ret = -EIO;
1168 goto exit;
1169 }
1170
1171 /* Get the next frame from the buffer queue */
1172 common->cur_frm = list_entry(common->dma_queue.next,
1173 struct videobuf_buffer, queue);
1174 common->next_frm = common->cur_frm;
1175
1176 /* Remove buffer from the buffer queue */
1177 list_del(&common->cur_frm->queue);
1178 /* Mark state of the current frame to active */
1179 common->cur_frm->state = VIDEOBUF_ACTIVE;
1180 /* Initialize field_id and started member */
1181 ch->field_id = 0;
1182 common->started = 1;
1183
1184 if (V4L2_MEMORY_USERPTR == common->memory)
1185 addr = common->cur_frm->boff;
1186 else
1187 addr = videobuf_to_dma_contig(common->cur_frm);
1188
1189 /* Calculate the offset for Y and C data in the buffer */
1190 vpif_calculate_offsets(ch);
1191
1192 if ((vpif->std_info.frm_fmt &&
1193 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
1194 (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
1195 (!vpif->std_info.frm_fmt &&
1196 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1197 vpif_dbg(1, debug, "conflict in field format and std format\n");
1198 ret = -EINVAL;
1199 goto exit;
1200 }
1201
1202 /* configure 1 or 2 channel mode */
1203 ret = config->setup_input_channel_mode(vpif->std_info.ycmux_mode);
1204
1205 if (ret < 0) {
1206 vpif_dbg(1, debug, "can't set vpif channel mode\n");
1207 goto exit;
1208 }
1209
1210 /* Call vpif_set_params function to set the parameters and addresses */
1211 ret = vpif_set_video_params(vpif, ch->channel_id);
1212
1213 if (ret < 0) {
1214 vpif_dbg(1, debug, "can't set video params\n");
1215 goto exit;
1216 }
1217
1218 common->started = ret;
1219 vpif_config_addr(ch, ret);
1220
1221 common->set_addr(addr + common->ytop_off,
1222 addr + common->ybtm_off,
1223 addr + common->ctop_off,
1224 addr + common->cbtm_off);
1225
1226 /**
1227 * Set interrupt for both the fields in VPIF Register enable channel in
1228 * VPIF register
1229 */
1230 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
1231 channel0_intr_assert();
1232 channel0_intr_enable(1);
1233 enable_channel0(1);
1234 }
1235 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
1236 (common->started == 2)) {
1237 channel1_intr_assert();
1238 channel1_intr_enable(1);
1239 enable_channel1(1);
1240 }
1241 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1242 mutex_unlock(&common->lock);
1243 return ret;
1244
1245exit:
1246 mutex_unlock(&common->lock);
1247streamoff_exit:
1248 ret = videobuf_streamoff(&common->buffer_queue);
1249 return ret;
1250}
1251
1252/**
1253 * vpif_streamoff() - streamoff handler
1254 * @file: file ptr
1255 * @priv: file handle
1256 * @buftype: v4l2 buffer type
1257 */
1258static int vpif_streamoff(struct file *file, void *priv,
1259 enum v4l2_buf_type buftype)
1260{
1261
1262 struct vpif_fh *fh = priv;
1263 struct channel_obj *ch = fh->channel;
1264 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1265 int ret;
1266
1267 vpif_dbg(2, debug, "vpif_streamoff\n");
1268
1269 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1270 vpif_dbg(1, debug, "buffer type not supported\n");
1271 return -EINVAL;
1272 }
1273
1274 /* If io is allowed for this file handle, return error */
1275 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1276 vpif_dbg(1, debug, "io not allowed\n");
1277 return -EACCES;
1278 }
1279
1280 /* If streaming is not started, return error */
1281 if (!common->started) {
1282 vpif_dbg(1, debug, "channel->started\n");
1283 return -EINVAL;
1284 }
1285
1286 if (mutex_lock_interruptible(&common->lock))
1287 return -ERESTARTSYS;
1288
1289 /* disable channel */
1290 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
1291 enable_channel0(0);
1292 channel0_intr_enable(0);
1293 } else {
1294 enable_channel1(0);
1295 channel1_intr_enable(0);
1296 }
1297
1298 common->started = 0;
1299
1300 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1301 s_stream, 0);
1302
1303 if (ret && (ret != -ENOIOCTLCMD))
1304 vpif_dbg(1, debug, "stream off failed in subdev\n");
1305
1306 mutex_unlock(&common->lock);
1307
1308 return videobuf_streamoff(&common->buffer_queue);
1309}
1310
1311/**
1312 * vpif_map_sub_device_to_input() - Maps sub device to input
1313 * @ch - ptr to channel
1314 * @config - ptr to capture configuration
1315 * @input_index - Given input index from application
1316 * @sub_device_index - index into sd table
1317 *
1318 * lookup the sub device information for a given input index.
1319 * we report all the inputs to application. inputs table also
1320 * has sub device name for the each input
1321 */
1322static struct vpif_subdev_info *vpif_map_sub_device_to_input(
1323 struct channel_obj *ch,
1324 struct vpif_capture_config *vpif_cfg,
1325 int input_index,
1326 int *sub_device_index)
1327{
1328 struct vpif_capture_chan_config *chan_cfg;
1329 struct vpif_subdev_info *subdev_info = NULL;
1330 const char *subdev_name = NULL;
1331 int i;
1332
1333 vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
1334
1335 chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
1336
1337 /**
1338 * search through the inputs to find the sub device supporting
1339 * the input
1340 */
1341 for (i = 0; i < chan_cfg->input_count; i++) {
1342 /* For each sub device, loop through input */
1343 if (i == input_index) {
1344 subdev_name = chan_cfg->inputs[i].subdev_name;
1345 break;
1346 }
1347 }
1348
1349 /* if reached maximum. return null */
1350 if (i == chan_cfg->input_count || (NULL == subdev_name))
1351 return subdev_info;
1352
1353 /* loop through the sub device list to get the sub device info */
1354 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1355 subdev_info = &vpif_cfg->subdev_info[i];
1356 if (!strcmp(subdev_info->name, subdev_name))
1357 break;
1358 }
1359
1360 if (i == vpif_cfg->subdev_count)
1361 return subdev_info;
1362
1363 /* check if the sub device is registered */
1364 if (NULL == vpif_obj.sd[i])
1365 return NULL;
1366
1367 *sub_device_index = i;
1368 return subdev_info;
1369}
1370
1371/**
1372 * vpif_querystd() - querystd handler
1373 * @file: file ptr
1374 * @priv: file handle
1375 * @std_id: ptr to std id
1376 *
1377 * This function is called to detect standard at the selected input
1378 */
1379static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1380{
1381 struct vpif_fh *fh = priv;
1382 struct channel_obj *ch = fh->channel;
1383 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1384 int ret = 0;
1385
1386 vpif_dbg(2, debug, "vpif_querystd\n");
1387
1388 if (mutex_lock_interruptible(&common->lock))
1389 return -ERESTARTSYS;
1390
1391 /* Call querystd function of decoder device */
1392 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1393 querystd, std_id);
1394 if (ret < 0)
1395 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1396
1397 mutex_unlock(&common->lock);
1398 return ret;
1399}
1400
1401/**
1402 * vpif_g_std() - get STD handler
1403 * @file: file ptr
1404 * @priv: file handle
1405 * @std_id: ptr to std id
1406 */
1407static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1408{
1409 struct vpif_fh *fh = priv;
1410 struct channel_obj *ch = fh->channel;
1411
1412 vpif_dbg(2, debug, "vpif_g_std\n");
1413
1414 *std = ch->video.stdid;
1415 return 0;
1416}
1417
1418/**
1419 * vpif_s_std() - set STD handler
1420 * @file: file ptr
1421 * @priv: file handle
1422 * @std_id: ptr to std id
1423 */
1424static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1425{
1426 struct vpif_fh *fh = priv;
1427 struct channel_obj *ch = fh->channel;
1428 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1429 int ret = 0;
1430
1431 vpif_dbg(2, debug, "vpif_s_std\n");
1432
1433 if (common->started) {
1434 vpif_err("streaming in progress\n");
1435 return -EBUSY;
1436 }
1437
1438 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1439 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1440 if (!fh->initialized) {
1441 vpif_dbg(1, debug, "Channel Busy\n");
1442 return -EBUSY;
1443 }
1444 }
1445
1446 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1447 if (0 != ret)
1448 return ret;
1449
1450 fh->initialized = 1;
1451
1452 /* Call encoder subdevice function to set the standard */
1453 if (mutex_lock_interruptible(&common->lock))
1454 return -ERESTARTSYS;
1455
1456 ch->video.stdid = *std_id;
1457
1458 /* Get the information about the standard */
1459 if (vpif_update_std_info(ch)) {
1460 ret = -EINVAL;
1461 vpif_err("Error getting the standard info\n");
1462 goto s_std_exit;
1463 }
1464
1465 /* Configure the default format information */
1466 vpif_config_format(ch);
1467
1468 /* set standard in the sub device */
1469 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
1470 s_std, *std_id);
1471 if (ret < 0)
1472 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1473
1474s_std_exit:
1475 mutex_unlock(&common->lock);
1476 return ret;
1477}
1478
1479/**
1480 * vpif_enum_input() - ENUMINPUT handler
1481 * @file: file ptr
1482 * @priv: file handle
1483 * @input: ptr to input structure
1484 */
1485static int vpif_enum_input(struct file *file, void *priv,
1486 struct v4l2_input *input)
1487{
1488
1489 struct vpif_capture_config *config = vpif_dev->platform_data;
1490 struct vpif_capture_chan_config *chan_cfg;
1491 struct vpif_fh *fh = priv;
1492 struct channel_obj *ch = fh->channel;
1493
1494 chan_cfg = &config->chan_config[ch->channel_id];
1495
1496 if (input->index >= chan_cfg->input_count) {
1497 vpif_dbg(1, debug, "Invalid input index\n");
1498 return -EINVAL;
1499 }
1500
1501 memcpy(input, &chan_cfg->inputs[input->index].input,
1502 sizeof(*input));
1503 return 0;
1504}
1505
1506/**
1507 * vpif_g_input() - Get INPUT handler
1508 * @file: file ptr
1509 * @priv: file handle
1510 * @index: ptr to input index
1511 */
1512static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1513{
1514 struct vpif_fh *fh = priv;
1515 struct channel_obj *ch = fh->channel;
1516 struct video_obj *vid_ch = &ch->video;
1517
1518 *index = vid_ch->input_idx;
1519
1520 return 0;
1521}
1522
1523/**
1524 * vpif_s_input() - Set INPUT handler
1525 * @file: file ptr
1526 * @priv: file handle
1527 * @index: input index
1528 */
1529static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1530{
1531 struct vpif_capture_config *config = vpif_dev->platform_data;
1532 struct vpif_capture_chan_config *chan_cfg;
1533 struct vpif_fh *fh = priv;
1534 struct channel_obj *ch = fh->channel;
1535 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1536 struct video_obj *vid_ch = &ch->video;
1537 struct vpif_subdev_info *subdev_info;
1538 int ret = 0, sd_index = 0;
1539 u32 input = 0, output = 0;
1540
1541 chan_cfg = &config->chan_config[ch->channel_id];
1542
1543 if (common->started) {
1544 vpif_err("Streaming in progress\n");
1545 return -EBUSY;
1546 }
1547
1548 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1549 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1550 if (!fh->initialized) {
1551 vpif_dbg(1, debug, "Channel Busy\n");
1552 return -EBUSY;
1553 }
1554 }
1555
1556 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1557 if (0 != ret)
1558 return ret;
1559
1560 fh->initialized = 1;
1561 subdev_info = vpif_map_sub_device_to_input(ch, config, index,
1562 &sd_index);
1563 if (NULL == subdev_info) {
1564 vpif_dbg(1, debug,
1565 "couldn't lookup sub device for the input index\n");
1566 return -EINVAL;
1567 }
1568
1569 if (mutex_lock_interruptible(&common->lock))
1570 return -ERESTARTSYS;
1571
1572 /* first setup input path from sub device to vpif */
1573 if (config->setup_input_path) {
1574 ret = config->setup_input_path(ch->channel_id,
1575 subdev_info->name);
1576 if (ret < 0) {
1577 vpif_dbg(1, debug, "couldn't setup input path for the"
1578 " sub device %s, for input index %d\n",
1579 subdev_info->name, index);
1580 goto exit;
1581 }
1582 }
1583
1584 if (subdev_info->can_route) {
1585 input = subdev_info->input;
1586 output = subdev_info->output;
1587 ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
1588 input, output, 0);
1589 if (ret < 0) {
1590 vpif_dbg(1, debug, "Failed to set input\n");
1591 goto exit;
1592 }
1593 }
1594 vid_ch->input_idx = index;
1595 ch->curr_subdev_info = subdev_info;
1596 ch->curr_sd_index = sd_index;
1597 /* copy interface parameters to vpif */
1598 ch->vpifparams.iface = subdev_info->vpif_if;
1599
1600 /* update tvnorms from the sub device input info */
1601 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1602
1603exit:
1604 mutex_unlock(&common->lock);
1605 return ret;
1606}
1607
1608/**
1609 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
1610 * @file: file ptr
1611 * @priv: file handle
1612 * @index: input index
1613 */
1614static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
1615 struct v4l2_fmtdesc *fmt)
1616{
1617 struct vpif_fh *fh = priv;
1618 struct channel_obj *ch = fh->channel;
1619
1620 if (fmt->index != 0) {
1621 vpif_dbg(1, debug, "Invalid format index\n");
1622 return -EINVAL;
1623 }
1624
1625 /* Fill in the information about format */
1626 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
1627 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1628 strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
1629 fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
1630 } else {
1631 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1632 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
1633 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
1634 }
1635 return 0;
1636}
1637
1638/**
1639 * vpif_try_fmt_vid_cap() - TRY_FMT handler
1640 * @file: file ptr
1641 * @priv: file handle
1642 * @fmt: ptr to v4l2 format structure
1643 */
1644static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
1645 struct v4l2_format *fmt)
1646{
1647 struct vpif_fh *fh = priv;
1648 struct channel_obj *ch = fh->channel;
1649 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
1650
1651 return vpif_check_format(ch, pixfmt, 1);
1652}
1653
1654
1655/**
1656 * vpif_g_fmt_vid_cap() - Set INPUT handler
1657 * @file: file ptr
1658 * @priv: file handle
1659 * @fmt: ptr to v4l2 format structure
1660 */
1661static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
1662 struct v4l2_format *fmt)
1663{
1664 struct vpif_fh *fh = priv;
1665 struct channel_obj *ch = fh->channel;
1666 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1667
1668 /* Check the validity of the buffer type */
1669 if (common->fmt.type != fmt->type)
1670 return -EINVAL;
1671
1672 /* Fill in the information about format */
1673 if (mutex_lock_interruptible(&common->lock))
1674 return -ERESTARTSYS;
1675
1676 *fmt = common->fmt;
1677 mutex_unlock(&common->lock);
1678 return 0;
1679}
1680
1681/**
1682 * vpif_s_fmt_vid_cap() - Set FMT handler
1683 * @file: file ptr
1684 * @priv: file handle
1685 * @fmt: ptr to v4l2 format structure
1686 */
1687static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1688 struct v4l2_format *fmt)
1689{
1690 struct vpif_fh *fh = priv;
1691 struct channel_obj *ch = fh->channel;
1692 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1693 struct v4l2_pix_format *pixfmt;
1694 int ret = 0;
1695
1696 vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
1697
1698 /* If streaming is started, return error */
1699 if (common->started) {
1700 vpif_dbg(1, debug, "Streaming is started\n");
1701 return -EBUSY;
1702 }
1703
1704 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1705 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1706 if (!fh->initialized) {
1707 vpif_dbg(1, debug, "Channel Busy\n");
1708 return -EBUSY;
1709 }
1710 }
1711
1712 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1713 if (0 != ret)
1714 return ret;
1715
1716 fh->initialized = 1;
1717
1718 pixfmt = &fmt->fmt.pix;
1719 /* Check for valid field format */
1720 ret = vpif_check_format(ch, pixfmt, 0);
1721
1722 if (ret)
1723 return ret;
1724 /* store the format in the channel object */
1725 if (mutex_lock_interruptible(&common->lock))
1726 return -ERESTARTSYS;
1727
1728 common->fmt = *fmt;
1729 mutex_unlock(&common->lock);
1730
1731 return 0;
1732}
1733
1734/**
1735 * vpif_querycap() - QUERYCAP handler
1736 * @file: file ptr
1737 * @priv: file handle
1738 * @cap: ptr to v4l2_capability structure
1739 */
1740static int vpif_querycap(struct file *file, void *priv,
1741 struct v4l2_capability *cap)
1742{
1743 struct vpif_capture_config *config = vpif_dev->platform_data;
1744
1745 cap->version = VPIF_CAPTURE_VERSION_CODE;
1746 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1747 strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
1748 strlcpy(cap->bus_info, "DM646x Platform", sizeof(cap->bus_info));
1749 strlcpy(cap->card, config->card_name, sizeof(cap->card));
1750
1751 return 0;
1752}
1753
1754/**
1755 * vpif_g_priority() - get priority handler
1756 * @file: file ptr
1757 * @priv: file handle
1758 * @prio: ptr to v4l2_priority structure
1759 */
1760static int vpif_g_priority(struct file *file, void *priv,
1761 enum v4l2_priority *prio)
1762{
1763 struct vpif_fh *fh = priv;
1764 struct channel_obj *ch = fh->channel;
1765
1766 *prio = v4l2_prio_max(&ch->prio);
1767
1768 return 0;
1769}
1770
1771/**
1772 * vpif_s_priority() - set priority handler
1773 * @file: file ptr
1774 * @priv: file handle
1775 * @prio: ptr to v4l2_priority structure
1776 */
1777static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1778{
1779 struct vpif_fh *fh = priv;
1780 struct channel_obj *ch = fh->channel;
1781
1782 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1783}
1784
1785/**
1786 * vpif_cropcap() - cropcap handler
1787 * @file: file ptr
1788 * @priv: file handle
1789 * @crop: ptr to v4l2_cropcap structure
1790 */
1791static int vpif_cropcap(struct file *file, void *priv,
1792 struct v4l2_cropcap *crop)
1793{
1794 struct vpif_fh *fh = priv;
1795 struct channel_obj *ch = fh->channel;
1796 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1797
1798 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
1799 return -EINVAL;
1800
1801 crop->bounds.left = 0;
1802 crop->bounds.top = 0;
1803 crop->bounds.height = common->height;
1804 crop->bounds.width = common->width;
1805 crop->defrect = crop->bounds;
1806 return 0;
1807}
1808
1809/* vpif capture ioctl operations */
1810static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1811 .vidioc_querycap = vpif_querycap,
1812 .vidioc_g_priority = vpif_g_priority,
1813 .vidioc_s_priority = vpif_s_priority,
1814 .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
1815 .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
1816 .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
1817 .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
1818 .vidioc_enum_input = vpif_enum_input,
1819 .vidioc_s_input = vpif_s_input,
1820 .vidioc_g_input = vpif_g_input,
1821 .vidioc_reqbufs = vpif_reqbufs,
1822 .vidioc_querybuf = vpif_querybuf,
1823 .vidioc_querystd = vpif_querystd,
1824 .vidioc_s_std = vpif_s_std,
1825 .vidioc_g_std = vpif_g_std,
1826 .vidioc_qbuf = vpif_qbuf,
1827 .vidioc_dqbuf = vpif_dqbuf,
1828 .vidioc_streamon = vpif_streamon,
1829 .vidioc_streamoff = vpif_streamoff,
1830 .vidioc_cropcap = vpif_cropcap,
1831};
1832
1833/* vpif file operations */
1834static struct v4l2_file_operations vpif_fops = {
1835 .owner = THIS_MODULE,
1836 .open = vpif_open,
1837 .release = vpif_release,
1838 .ioctl = video_ioctl2,
1839 .mmap = vpif_mmap,
1840 .poll = vpif_poll
1841};
1842
1843/* vpif video template */
1844static struct video_device vpif_video_template = {
1845 .name = "vpif",
1846 .fops = &vpif_fops,
1847 .minor = -1,
1848 .ioctl_ops = &vpif_ioctl_ops,
1849};
1850
1851/**
1852 * initialize_vpif() - Initialize vpif data structures
1853 *
1854 * Allocate memory for data structures and initialize them
1855 */
1856static int initialize_vpif(void)
1857{
1858 int err = 0, i, j;
1859 int free_channel_objects_index;
1860
1861 /* Default number of buffers should be 3 */
1862 if ((ch0_numbuffers > 0) &&
1863 (ch0_numbuffers < config_params.min_numbuffers))
1864 ch0_numbuffers = config_params.min_numbuffers;
1865 if ((ch1_numbuffers > 0) &&
1866 (ch1_numbuffers < config_params.min_numbuffers))
1867 ch1_numbuffers = config_params.min_numbuffers;
1868
1869 /* Set buffer size to min buffers size if it is invalid */
1870 if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
1871 ch0_bufsize =
1872 config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
1873 if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
1874 ch1_bufsize =
1875 config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
1876
1877 config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
1878 config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
1879 if (ch0_numbuffers) {
1880 config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
1881 = ch0_bufsize;
1882 }
1883 if (ch1_numbuffers) {
1884 config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
1885 = ch1_bufsize;
1886 }
1887
1888 /* Allocate memory for six channel objects */
1889 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1890 vpif_obj.dev[i] =
1891 kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
1892 /* If memory allocation fails, return error */
1893 if (!vpif_obj.dev[i]) {
1894 free_channel_objects_index = i;
1895 err = -ENOMEM;
1896 goto vpif_init_free_channel_objects;
1897 }
1898 }
1899 return 0;
1900
1901vpif_init_free_channel_objects:
1902 for (j = 0; j < free_channel_objects_index; j++)
1903 kfree(vpif_obj.dev[j]);
1904 return err;
1905}
1906
1907/**
1908 * vpif_probe : This function probes the vpif capture driver
1909 * @pdev: platform device pointer
1910 *
1911 * This creates device entries by register itself to the V4L2 driver and
1912 * initializes fields of each channel objects
1913 */
1914static __init int vpif_probe(struct platform_device *pdev)
1915{
1916 struct vpif_subdev_info *subdevdata;
1917 struct vpif_capture_config *config;
1918 int i, j, k, m, q, err;
1919 struct i2c_adapter *i2c_adap;
1920 struct channel_obj *ch;
1921 struct common_obj *common;
1922 struct video_device *vfd;
1923 struct resource *res;
1924 int subdev_count;
1925
1926 vpif_dev = &pdev->dev;
1927
1928 err = initialize_vpif();
1929 if (err) {
1930 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1931 return err;
1932 }
1933
1934 k = 0;
1935 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1936 for (i = res->start; i <= res->end; i++) {
1937 if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
1938 "DM646x_Capture",
1939 (void *)(&vpif_obj.dev[k]->channel_id))) {
1940 err = -EBUSY;
1941 i--;
1942 goto vpif_int_err;
1943 }
1944 }
1945 k++;
1946 }
1947
1948 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1949 /* Get the pointer to the channel object */
1950 ch = vpif_obj.dev[i];
1951 /* Allocate memory for video device */
1952 vfd = video_device_alloc();
1953 if (NULL == vfd) {
1954 for (j = 0; j < i; j++) {
1955 ch = vpif_obj.dev[j];
1956 video_device_release(ch->video_dev);
1957 }
1958 err = -ENOMEM;
1959 goto vpif_dev_alloc_err;
1960 }
1961
1962 /* Initialize field of video device */
1963 *vfd = vpif_video_template;
1964 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1965 vfd->release = video_device_release;
1966 snprintf(vfd->name, sizeof(vfd->name),
1967 "DM646x_VPIFCapture_DRIVER_V%d.%d.%d",
1968 (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff,
1969 (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff,
1970 (VPIF_CAPTURE_VERSION_CODE) & 0xff);
1971 /* Set video_dev to the video device */
1972 ch->video_dev = vfd;
1973 }
1974
1975 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
1976 ch = vpif_obj.dev[j];
1977 ch->channel_id = j;
1978 common = &(ch->common[VPIF_VIDEO_INDEX]);
1979 spin_lock_init(&common->irqlock);
1980 mutex_init(&common->lock);
1981 /* Initialize prio member of channel object */
1982 v4l2_prio_init(&ch->prio);
1983 err = video_register_device(ch->video_dev,
1984 VFL_TYPE_GRABBER, (j ? 1 : 0));
1985 if (err)
1986 goto probe_out;
1987
1988 video_set_drvdata(ch->video_dev, ch);
1989
1990 }
1991
1992 i2c_adap = i2c_get_adapter(1);
1993 config = pdev->dev.platform_data;
1994
1995 subdev_count = config->subdev_count;
1996 vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1997 GFP_KERNEL);
1998 if (vpif_obj.sd == NULL) {
1999 vpif_err("unable to allocate memory for subdevice pointers\n");
2000 err = -ENOMEM;
2001 goto probe_out;
2002 }
2003
2004 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
2005 if (err) {
2006 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
2007 goto probe_subdev_out;
2008 }
2009
2010 for (i = 0; i < subdev_count; i++) {
2011 subdevdata = &config->subdev_info[i];
2012 vpif_obj.sd[i] =
2013 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
2014 i2c_adap,
2015 subdevdata->name,
2016 &subdevdata->board_info,
2017 NULL);
2018
2019 if (!vpif_obj.sd[i]) {
2020 vpif_err("Error registering v4l2 subdevice\n");
2021 goto probe_subdev_out;
2022 }
2023 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2024 subdevdata->name);
2025
2026 if (vpif_obj.sd[i])
2027 vpif_obj.sd[i]->grp_id = 1 << i;
2028 }
2029 v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
2030 " initialized\n");
2031
2032 return 0;
2033
2034probe_subdev_out:
2035 /* free sub devices memory */
2036 kfree(vpif_obj.sd);
2037
2038 j = VPIF_CAPTURE_MAX_DEVICES;
2039probe_out:
2040 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2041 for (k = 0; k < j; k++) {
2042 /* Get the pointer to the channel object */
2043 ch = vpif_obj.dev[k];
2044 /* Unregister video device */
2045 video_unregister_device(ch->video_dev);
2046 }
2047
2048vpif_dev_alloc_err:
2049 k = VPIF_CAPTURE_MAX_DEVICES-1;
2050 res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
2051 i = res->end;
2052
2053vpif_int_err:
2054 for (q = k; q >= 0; q--) {
2055 for (m = i; m >= (int)res->start; m--)
2056 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2057
2058 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2059 if (res)
2060 i = res->end;
2061 }
2062 return err;
2063}
2064
2065/**
2066 * vpif_remove() - driver remove handler
2067 * @device: ptr to platform device structure
2068 *
2069 * The vidoe device is unregistered
2070 */
2071static int vpif_remove(struct platform_device *device)
2072{
2073 int i;
2074 struct channel_obj *ch;
2075
2076 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2077
2078 /* un-register device */
2079 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2080 /* Get the pointer to the channel object */
2081 ch = vpif_obj.dev[i];
2082 /* Unregister video device */
2083 video_unregister_device(ch->video_dev);
2084 }
2085 return 0;
2086}
2087
2088/**
2089 * vpif_suspend: vpif device suspend
2090 *
2091 * TODO: Add suspend code here
2092 */
2093static int
2094vpif_suspend(struct device *dev)
2095{
2096 return -1;
2097}
2098
2099/**
2100 * vpif_resume: vpif device suspend
2101 *
2102 * TODO: Add resume code here
2103 */
2104static int
2105vpif_resume(struct device *dev)
2106{
2107 return -1;
2108}
2109
2110static struct dev_pm_ops vpif_dev_pm_ops = {
2111 .suspend = vpif_suspend,
2112 .resume = vpif_resume,
2113};
2114
2115static struct platform_driver vpif_driver = {
2116 .driver = {
2117 .name = "vpif_capture",
2118 .owner = THIS_MODULE,
2119 .pm = &vpif_dev_pm_ops,
2120 },
2121 .probe = vpif_probe,
2122 .remove = vpif_remove,
2123};
2124
2125/**
2126 * vpif_init: initialize the vpif driver
2127 *
2128 * This function registers device and driver to the kernel, requests irq
2129 * handler and allocates memory
2130 * for channel objects
2131 */
2132static __init int vpif_init(void)
2133{
2134 return platform_driver_register(&vpif_driver);
2135}
2136
2137/**
2138 * vpif_cleanup : This function clean up the vpif capture resources
2139 *
2140 * This will un-registers device and driver to the kernel, frees
2141 * requested irq handler and de-allocates memory allocated for channel
2142 * objects.
2143 */
2144static void vpif_cleanup(void)
2145{
2146 struct platform_device *pdev;
2147 struct resource *res;
2148 int irq_num;
2149 int i = 0;
2150
2151 pdev = container_of(vpif_dev, struct platform_device, dev);
2152 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
2153 for (irq_num = res->start; irq_num <= res->end; irq_num++)
2154 free_irq(irq_num,
2155 (void *)(&vpif_obj.dev[i]->channel_id));
2156 i++;
2157 }
2158
2159 platform_driver_unregister(&vpif_driver);
2160
2161 kfree(vpif_obj.sd);
2162 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
2163 kfree(vpif_obj.dev[i]);
2164}
2165
2166/* Function for module initialization and cleanup */
2167module_init(vpif_init);
2168module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
new file mode 100644
index 000000000000..4e12ec8cac6f
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.h
@@ -0,0 +1,165 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef VPIF_CAPTURE_H
20#define VPIF_CAPTURE_H
21
22#ifdef __KERNEL__
23
24/* Header files */
25#include <linux/videodev2.h>
26#include <linux/version.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-device.h>
29#include <media/videobuf-core.h>
30#include <media/videobuf-dma-contig.h>
31#include <mach/dm646x.h>
32
33#include "vpif.h"
34
35/* Macros */
36#define VPIF_MAJOR_RELEASE 0
37#define VPIF_MINOR_RELEASE 0
38#define VPIF_BUILD 1
39#define VPIF_CAPTURE_VERSION_CODE ((VPIF_MAJOR_RELEASE << 16) | \
40 (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
41
42#define VPIF_VALID_FIELD(field) (((V4L2_FIELD_ANY == field) || \
43 (V4L2_FIELD_NONE == field)) || \
44 (((V4L2_FIELD_INTERLACED == field) || \
45 (V4L2_FIELD_SEQ_TB == field)) || \
46 (V4L2_FIELD_SEQ_BT == field)))
47
48#define VPIF_CAPTURE_MAX_DEVICES 2
49#define VPIF_VIDEO_INDEX 0
50#define VPIF_NUMBER_OF_OBJECTS 1
51
52/* Enumerated data type to give id to each device per channel */
53enum vpif_channel_id {
54 VPIF_CHANNEL0_VIDEO = 0,
55 VPIF_CHANNEL1_VIDEO,
56};
57
58struct video_obj {
59 enum v4l2_field buf_field;
60 /* Currently selected or default standard */
61 v4l2_std_id stdid;
62 /* This is to track the last input that is passed to application */
63 u32 input_idx;
64};
65
66struct common_obj {
67 /* Pointer pointing to current v4l2_buffer */
68 struct videobuf_buffer *cur_frm;
69 /* Pointer pointing to current v4l2_buffer */
70 struct videobuf_buffer *next_frm;
71 /*
72 * This field keeps track of type of buffer exchange mechanism
73 * user has selected
74 */
75 enum v4l2_memory memory;
76 /* Used to store pixel format */
77 struct v4l2_format fmt;
78 /* Buffer queue used in video-buf */
79 struct videobuf_queue buffer_queue;
80 /* Queue of filled frames */
81 struct list_head dma_queue;
82 /* Used in video-buf */
83 spinlock_t irqlock;
84 /* lock used to access this structure */
85 struct mutex lock;
86 /* number of users performing IO */
87 u32 io_usrs;
88 /* Indicates whether streaming started */
89 u8 started;
90 /* Function pointer to set the addresses */
91 void (*set_addr) (unsigned long, unsigned long, unsigned long,
92 unsigned long);
93 /* offset where Y top starts from the starting of the buffer */
94 u32 ytop_off;
95 /* offset where Y bottom starts from the starting of the buffer */
96 u32 ybtm_off;
97 /* offset where C top starts from the starting of the buffer */
98 u32 ctop_off;
99 /* offset where C bottom starts from the starting of the buffer */
100 u32 cbtm_off;
101 /* Indicates width of the image data */
102 u32 width;
103 /* Indicates height of the image data */
104 u32 height;
105};
106
107struct channel_obj {
108 /* Identifies video device for this channel */
109 struct video_device *video_dev;
110 /* Used to keep track of state of the priority */
111 struct v4l2_prio_state prio;
112 /* number of open instances of the channel */
113 int usrs;
114 /* Indicates id of the field which is being displayed */
115 u32 field_id;
116 /* flag to indicate whether decoder is initialized */
117 u8 initialized;
118 /* Identifies channel */
119 enum vpif_channel_id channel_id;
120 /* index into sd table */
121 int curr_sd_index;
122 /* ptr to current sub device information */
123 struct vpif_subdev_info *curr_subdev_info;
124 /* vpif configuration params */
125 struct vpif_params vpifparams;
126 /* common object array */
127 struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
128 /* video object */
129 struct video_obj video;
130};
131
132/* File handle structure */
133struct vpif_fh {
134 /* pointer to channel object for opened device */
135 struct channel_obj *channel;
136 /* Indicates whether this file handle is doing IO */
137 u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
138 /* Used to keep track priority of this instance */
139 enum v4l2_priority prio;
140 /* Used to indicate channel is initialize or not */
141 u8 initialized;
142};
143
144struct vpif_device {
145 struct v4l2_device v4l2_dev;
146 struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
147 struct v4l2_subdev **sd;
148};
149
150struct vpif_config_params {
151 u8 min_numbuffers;
152 u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
153 s8 device_type;
154 u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
155 u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
156 u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
157 u8 max_device_type;
158};
159/* Struct which keeps track of the line numbers for the sliced vbi service */
160struct vpif_service_line {
161 u16 service_id;
162 u16 service_line[2];
163};
164#endif /* End of __KERNEL__ */
165#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
new file mode 100644
index 000000000000..c015da813dda
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -0,0 +1,1656 @@
1/*
2 * vpif-display - VPIF display driver
3 * Display driver for TI DaVinci VPIF
4 *
5 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27#include <linux/wait.h>
28#include <linux/time.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/io.h>
32#include <linux/version.h>
33
34#include <asm/irq.h>
35#include <asm/page.h>
36
37#include <media/adv7343.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ioctl.h>
40
41#include <mach/dm646x.h>
42
43#include "vpif_display.h"
44#include "vpif.h"
45
46MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
47MODULE_LICENSE("GPL");
48
49#define DM646X_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
50
51#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
52#define vpif_dbg(level, debug, fmt, arg...) \
53 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
54
55static int debug = 1;
56static u32 ch2_numbuffers = 3;
57static u32 ch3_numbuffers = 3;
58static u32 ch2_bufsize = 1920 * 1080 * 2;
59static u32 ch3_bufsize = 720 * 576 * 2;
60
61module_param(debug, int, 0644);
62module_param(ch2_numbuffers, uint, S_IRUGO);
63module_param(ch3_numbuffers, uint, S_IRUGO);
64module_param(ch2_bufsize, uint, S_IRUGO);
65module_param(ch3_bufsize, uint, S_IRUGO);
66
67MODULE_PARM_DESC(debug, "Debug level 0-1");
68MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
69MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
70MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
71MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
72
73static struct vpif_config_params config_params = {
74 .min_numbuffers = 3,
75 .numbuffers[0] = 3,
76 .numbuffers[1] = 3,
77 .min_bufsize[0] = 720 * 480 * 2,
78 .min_bufsize[1] = 720 * 480 * 2,
79 .channel_bufsize[0] = 1920 * 1080 * 2,
80 .channel_bufsize[1] = 720 * 576 * 2,
81};
82
83static struct vpif_device vpif_obj = { {NULL} };
84static struct device *vpif_dev;
85
86static const struct vpif_channel_config_params ch_params[] = {
87 {
88 "NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
89 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
90 },
91 {
92 "PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
93 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
94 },
95};
96
97/*
98 * vpif_uservirt_to_phys: This function is used to convert user
99 * space virtual address to physical address.
100 */
101static u32 vpif_uservirt_to_phys(u32 virtp)
102{
103 struct mm_struct *mm = current->mm;
104 unsigned long physp = 0;
105 struct vm_area_struct *vma;
106
107 vma = find_vma(mm, virtp);
108
109 /* For kernel direct-mapped memory, take the easy way */
110 if (virtp >= PAGE_OFFSET) {
111 physp = virt_to_phys((void *)virtp);
112 } else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
113 /* this will catch, kernel-allocated, mmaped-to-usermode addr */
114 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
115 } else {
116 /* otherwise, use get_user_pages() for general userland pages */
117 int res, nr_pages = 1;
118 struct page *pages;
119 down_read(&current->mm->mmap_sem);
120
121 res = get_user_pages(current, current->mm,
122 virtp, nr_pages, 1, 0, &pages, NULL);
123 up_read(&current->mm->mmap_sem);
124
125 if (res == nr_pages) {
126 physp = __pa(page_address(&pages[0]) +
127 (virtp & ~PAGE_MASK));
128 } else {
129 vpif_err("get_user_pages failed\n");
130 return 0;
131 }
132 }
133
134 return physp;
135}
136
137/*
138 * buffer_prepare: This is the callback function called from videobuf_qbuf()
139 * function the buffer is prepared and user space virtual address is converted
140 * into physical address
141 */
142static int vpif_buffer_prepare(struct videobuf_queue *q,
143 struct videobuf_buffer *vb,
144 enum v4l2_field field)
145{
146 struct vpif_fh *fh = q->priv_data;
147 struct common_obj *common;
148 unsigned long addr;
149
150 common = &fh->channel->common[VPIF_VIDEO_INDEX];
151 if (VIDEOBUF_NEEDS_INIT == vb->state) {
152 vb->width = common->width;
153 vb->height = common->height;
154 vb->size = vb->width * vb->height;
155 vb->field = field;
156 }
157 vb->state = VIDEOBUF_PREPARED;
158
159 /* if user pointer memory mechanism is used, get the physical
160 * address of the buffer */
161 if (V4L2_MEMORY_USERPTR == common->memory) {
162 if (!vb->baddr) {
163 vpif_err("buffer_address is 0\n");
164 return -EINVAL;
165 }
166
167 vb->boff = vpif_uservirt_to_phys(vb->baddr);
168 if (!ISALIGNED(vb->boff))
169 goto buf_align_exit;
170 }
171
172 addr = vb->boff;
173 if (q->streaming && (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
174 if (!ISALIGNED(addr + common->ytop_off) ||
175 !ISALIGNED(addr + common->ybtm_off) ||
176 !ISALIGNED(addr + common->ctop_off) ||
177 !ISALIGNED(addr + common->cbtm_off))
178 goto buf_align_exit;
179 }
180 return 0;
181
182buf_align_exit:
183 vpif_err("buffer offset not aligned to 8 bytes\n");
184 return -EINVAL;
185}
186
187/*
188 * vpif_buffer_setup: This function allocates memory for the buffers
189 */
190static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
191 unsigned int *size)
192{
193 struct vpif_fh *fh = q->priv_data;
194 struct channel_obj *ch = fh->channel;
195 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
196
197 if (V4L2_MEMORY_MMAP != common->memory)
198 return 0;
199
200 *size = config_params.channel_bufsize[ch->channel_id];
201 if (*count < config_params.min_numbuffers)
202 *count = config_params.min_numbuffers;
203
204 return 0;
205}
206
207/*
208 * vpif_buffer_queue: This function adds the buffer to DMA queue
209 */
210static void vpif_buffer_queue(struct videobuf_queue *q,
211 struct videobuf_buffer *vb)
212{
213 struct vpif_fh *fh = q->priv_data;
214 struct common_obj *common;
215
216 common = &fh->channel->common[VPIF_VIDEO_INDEX];
217
218 /* add the buffer to the DMA queue */
219 list_add_tail(&vb->queue, &common->dma_queue);
220 vb->state = VIDEOBUF_QUEUED;
221}
222
223/*
224 * vpif_buffer_release: This function is called from the videobuf layer to
225 * free memory allocated to the buffers
226 */
227static void vpif_buffer_release(struct videobuf_queue *q,
228 struct videobuf_buffer *vb)
229{
230 struct vpif_fh *fh = q->priv_data;
231 struct channel_obj *ch = fh->channel;
232 struct common_obj *common;
233 unsigned int buf_size = 0;
234
235 common = &ch->common[VPIF_VIDEO_INDEX];
236
237 videobuf_dma_contig_free(q, vb);
238 vb->state = VIDEOBUF_NEEDS_INIT;
239
240 if (V4L2_MEMORY_MMAP != common->memory)
241 return;
242
243 buf_size = config_params.channel_bufsize[ch->channel_id];
244}
245
246static struct videobuf_queue_ops video_qops = {
247 .buf_setup = vpif_buffer_setup,
248 .buf_prepare = vpif_buffer_prepare,
249 .buf_queue = vpif_buffer_queue,
250 .buf_release = vpif_buffer_release,
251};
252static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
253
254static void process_progressive_mode(struct common_obj *common)
255{
256 unsigned long addr = 0;
257
258 /* Get the next buffer from buffer queue */
259 common->next_frm = list_entry(common->dma_queue.next,
260 struct videobuf_buffer, queue);
261 /* Remove that buffer from the buffer queue */
262 list_del(&common->next_frm->queue);
263 /* Mark status of the buffer as active */
264 common->next_frm->state = VIDEOBUF_ACTIVE;
265
266 /* Set top and bottom field addrs in VPIF registers */
267 addr = videobuf_to_dma_contig(common->next_frm);
268 common->set_addr(addr + common->ytop_off,
269 addr + common->ybtm_off,
270 addr + common->ctop_off,
271 addr + common->cbtm_off);
272}
273
274static void process_interlaced_mode(int fid, struct common_obj *common)
275{
276 /* device field id and local field id are in sync */
277 /* If this is even field */
278 if (0 == fid) {
279 if (common->cur_frm == common->next_frm)
280 return;
281
282 /* one frame is displayed If next frame is
283 * available, release cur_frm and move on */
284 /* Copy frame display time */
285 do_gettimeofday(&common->cur_frm->ts);
286 /* Change status of the cur_frm */
287 common->cur_frm->state = VIDEOBUF_DONE;
288 /* unlock semaphore on cur_frm */
289 wake_up_interruptible(&common->cur_frm->done);
290 /* Make cur_frm pointing to next_frm */
291 common->cur_frm = common->next_frm;
292
293 } else if (1 == fid) { /* odd field */
294 if (list_empty(&common->dma_queue)
295 || (common->cur_frm != common->next_frm)) {
296 return;
297 }
298 /* one field is displayed configure the next
299 * frame if it is available else hold on current
300 * frame */
301 /* Get next from the buffer queue */
302 process_progressive_mode(common);
303
304 }
305}
306
307/*
308 * vpif_channel_isr: It changes status of the displayed buffer, takes next
309 * buffer from the queue and sets its address in VPIF registers
310 */
311static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
312{
313 struct vpif_device *dev = &vpif_obj;
314 struct channel_obj *ch;
315 struct common_obj *common;
316 enum v4l2_field field;
317 int fid = -1, i;
318 int channel_id = 0;
319
320 channel_id = *(int *)(dev_id);
321 ch = dev->dev[channel_id];
322 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
323 for (i = 0; i < VPIF_NUMOBJECTS; i++) {
324 common = &ch->common[i];
325 /* If streaming is started in this channel */
326 if (0 == common->started)
327 continue;
328
329 if (1 == ch->vpifparams.std_info.frm_fmt) {
330 if (list_empty(&common->dma_queue))
331 continue;
332
333 /* Progressive mode */
334 if (!channel_first_int[i][channel_id]) {
335 /* Mark status of the cur_frm to
336 * done and unlock semaphore on it */
337 do_gettimeofday(&common->cur_frm->ts);
338 common->cur_frm->state = VIDEOBUF_DONE;
339 wake_up_interruptible(&common->cur_frm->done);
340 /* Make cur_frm pointing to next_frm */
341 common->cur_frm = common->next_frm;
342 }
343
344 channel_first_int[i][channel_id] = 0;
345 process_progressive_mode(common);
346 } else {
347 /* Interlaced mode */
348 /* If it is first interrupt, ignore it */
349
350 if (channel_first_int[i][channel_id]) {
351 channel_first_int[i][channel_id] = 0;
352 continue;
353 }
354
355 if (0 == i) {
356 ch->field_id ^= 1;
357 /* Get field id from VPIF registers */
358 fid = vpif_channel_getfid(ch->channel_id + 2);
359 /* If fid does not match with stored field id */
360 if (fid != ch->field_id) {
361 /* Make them in sync */
362 if (0 == fid)
363 ch->field_id = fid;
364
365 return IRQ_HANDLED;
366 }
367 }
368 process_interlaced_mode(fid, common);
369 }
370 }
371
372 return IRQ_HANDLED;
373}
374
375static int vpif_get_std_info(struct channel_obj *ch)
376{
377 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
378 struct video_obj *vid_ch = &ch->video;
379 struct vpif_params *vpifparams = &ch->vpifparams;
380 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
381 const struct vpif_channel_config_params *config;
382
383 int index;
384
385 std_info->stdid = vid_ch->stdid;
386 if (!std_info)
387 return -1;
388
389 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
390 config = &ch_params[index];
391 if (config->stdid & std_info->stdid) {
392 memcpy(std_info, config, sizeof(*config));
393 break;
394 }
395 }
396
397 if (index == ARRAY_SIZE(ch_params))
398 return -1;
399
400 common->fmt.fmt.pix.width = std_info->width;
401 common->fmt.fmt.pix.height = std_info->height;
402 vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
403 common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
404
405 /* Set height and width paramateres */
406 ch->common[VPIF_VIDEO_INDEX].height = std_info->height;
407 ch->common[VPIF_VIDEO_INDEX].width = std_info->width;
408
409 return 0;
410}
411
412/*
413 * vpif_calculate_offsets: This function calculates buffers offset for Y and C
414 * in the top and bottom field
415 */
416static void vpif_calculate_offsets(struct channel_obj *ch)
417{
418 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
419 struct vpif_params *vpifparams = &ch->vpifparams;
420 enum v4l2_field field = common->fmt.fmt.pix.field;
421 struct video_obj *vid_ch = &ch->video;
422 unsigned int hpitch, vpitch, sizeimage;
423
424 if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
425 if (ch->vpifparams.std_info.frm_fmt)
426 vid_ch->buf_field = V4L2_FIELD_NONE;
427 else
428 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
429 } else {
430 vid_ch->buf_field = common->fmt.fmt.pix.field;
431 }
432
433 if (V4L2_MEMORY_USERPTR == common->memory)
434 sizeimage = common->fmt.fmt.pix.sizeimage;
435 else
436 sizeimage = config_params.channel_bufsize[ch->channel_id];
437
438 hpitch = common->fmt.fmt.pix.bytesperline;
439 vpitch = sizeimage / (hpitch * 2);
440 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
441 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
442 common->ytop_off = 0;
443 common->ybtm_off = hpitch;
444 common->ctop_off = sizeimage / 2;
445 common->cbtm_off = sizeimage / 2 + hpitch;
446 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
447 common->ytop_off = 0;
448 common->ybtm_off = sizeimage / 4;
449 common->ctop_off = sizeimage / 2;
450 common->cbtm_off = common->ctop_off + sizeimage / 4;
451 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
452 common->ybtm_off = 0;
453 common->ytop_off = sizeimage / 4;
454 common->cbtm_off = sizeimage / 2;
455 common->ctop_off = common->cbtm_off + sizeimage / 4;
456 }
457
458 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
459 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
460 vpifparams->video_params.storage_mode = 1;
461 } else {
462 vpifparams->video_params.storage_mode = 0;
463 }
464
465 if (ch->vpifparams.std_info.frm_fmt == 1) {
466 vpifparams->video_params.hpitch =
467 common->fmt.fmt.pix.bytesperline;
468 } else {
469 if ((field == V4L2_FIELD_ANY) ||
470 (field == V4L2_FIELD_INTERLACED))
471 vpifparams->video_params.hpitch =
472 common->fmt.fmt.pix.bytesperline * 2;
473 else
474 vpifparams->video_params.hpitch =
475 common->fmt.fmt.pix.bytesperline;
476 }
477
478 ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
479}
480
481static void vpif_config_format(struct channel_obj *ch)
482{
483 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
484
485 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
486 if (config_params.numbuffers[ch->channel_id] == 0)
487 common->memory = V4L2_MEMORY_USERPTR;
488 else
489 common->memory = V4L2_MEMORY_MMAP;
490
491 common->fmt.fmt.pix.sizeimage =
492 config_params.channel_bufsize[ch->channel_id];
493 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
494 common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
495}
496
497static int vpif_check_format(struct channel_obj *ch,
498 struct v4l2_pix_format *pixfmt)
499{
500 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
501 enum v4l2_field field = pixfmt->field;
502 u32 sizeimage, hpitch, vpitch;
503
504 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
505 goto invalid_fmt_exit;
506
507 if (!(VPIF_VALID_FIELD(field)))
508 goto invalid_fmt_exit;
509
510 if (pixfmt->bytesperline <= 0)
511 goto invalid_pitch_exit;
512
513 if (V4L2_MEMORY_USERPTR == common->memory)
514 sizeimage = pixfmt->sizeimage;
515 else
516 sizeimage = config_params.channel_bufsize[ch->channel_id];
517
518 if (vpif_get_std_info(ch)) {
519 vpif_err("Error getting the standard info\n");
520 return -EINVAL;
521 }
522
523 hpitch = pixfmt->bytesperline;
524 vpitch = sizeimage / (hpitch * 2);
525
526 /* Check for valid value of pitch */
527 if ((hpitch < ch->vpifparams.std_info.width) ||
528 (vpitch < ch->vpifparams.std_info.height))
529 goto invalid_pitch_exit;
530
531 /* Check for 8 byte alignment */
532 if (!ISALIGNED(hpitch)) {
533 vpif_err("invalid pitch alignment\n");
534 return -EINVAL;
535 }
536 pixfmt->width = common->fmt.fmt.pix.width;
537 pixfmt->height = common->fmt.fmt.pix.height;
538
539 return 0;
540
541invalid_fmt_exit:
542 vpif_err("invalid field format\n");
543 return -EINVAL;
544
545invalid_pitch_exit:
546 vpif_err("invalid pitch\n");
547 return -EINVAL;
548}
549
550static void vpif_config_addr(struct channel_obj *ch, int muxmode)
551{
552 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
553
554 if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
555 common->set_addr = ch3_set_videobuf_addr;
556 } else {
557 if (2 == muxmode)
558 common->set_addr = ch2_set_videobuf_addr_yc_nmux;
559 else
560 common->set_addr = ch2_set_videobuf_addr;
561 }
562}
563
564/*
565 * vpif_mmap: It is used to map kernel space buffers into user spaces
566 */
567static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
568{
569 struct vpif_fh *fh = filep->private_data;
570 struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX];
571
572 return videobuf_mmap_mapper(&common->buffer_queue, vma);
573}
574
575/*
576 * vpif_poll: It is used for select/poll system call
577 */
578static unsigned int vpif_poll(struct file *filep, poll_table *wait)
579{
580 struct vpif_fh *fh = filep->private_data;
581 struct channel_obj *ch = fh->channel;
582 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
583
584 if (common->started)
585 return videobuf_poll_stream(filep, &common->buffer_queue, wait);
586
587 return 0;
588}
589
590/*
591 * vpif_open: It creates object of file handle structure and stores it in
592 * private_data member of filepointer
593 */
594static int vpif_open(struct file *filep)
595{
596 struct video_device *vdev = video_devdata(filep);
597 struct channel_obj *ch = NULL;
598 struct vpif_fh *fh = NULL;
599
600 ch = video_get_drvdata(vdev);
601 /* Allocate memory for the file handle object */
602 fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
603 if (fh == NULL) {
604 vpif_err("unable to allocate memory for file handle object\n");
605 return -ENOMEM;
606 }
607
608 /* store pointer to fh in private_data member of filep */
609 filep->private_data = fh;
610 fh->channel = ch;
611 fh->initialized = 0;
612 if (!ch->initialized) {
613 fh->initialized = 1;
614 ch->initialized = 1;
615 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
616 }
617
618 /* Increment channel usrs counter */
619 atomic_inc(&ch->usrs);
620 /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
621 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
622 /* Initialize priority of this instance to default priority */
623 fh->prio = V4L2_PRIORITY_UNSET;
624 v4l2_prio_open(&ch->prio, &fh->prio);
625
626 return 0;
627}
628
629/*
630 * vpif_release: This function deletes buffer queue, frees the buffers and
631 * the vpif file handle
632 */
633static int vpif_release(struct file *filep)
634{
635 struct vpif_fh *fh = filep->private_data;
636 struct channel_obj *ch = fh->channel;
637 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
638
639 if (mutex_lock_interruptible(&common->lock))
640 return -ERESTARTSYS;
641
642 /* if this instance is doing IO */
643 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
644 /* Reset io_usrs member of channel object */
645 common->io_usrs = 0;
646 /* Disable channel */
647 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
648 enable_channel2(0);
649 channel2_intr_enable(0);
650 }
651 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
652 (2 == common->started)) {
653 enable_channel3(0);
654 channel3_intr_enable(0);
655 }
656 common->started = 0;
657 /* Free buffers allocated */
658 videobuf_queue_cancel(&common->buffer_queue);
659 videobuf_mmap_free(&common->buffer_queue);
660 common->numbuffers =
661 config_params.numbuffers[ch->channel_id];
662 }
663
664 mutex_unlock(&common->lock);
665
666 /* Decrement channel usrs counter */
667 atomic_dec(&ch->usrs);
668 /* If this file handle has initialize encoder device, reset it */
669 if (fh->initialized)
670 ch->initialized = 0;
671
672 /* Close the priority */
673 v4l2_prio_close(&ch->prio, &fh->prio);
674 filep->private_data = NULL;
675 fh->initialized = 0;
676 kfree(fh);
677
678 return 0;
679}
680
681/* functions implementing ioctls */
682
683static int vpif_querycap(struct file *file, void *priv,
684 struct v4l2_capability *cap)
685{
686 struct vpif_display_config *config = vpif_dev->platform_data;
687
688 cap->version = VPIF_DISPLAY_VERSION_CODE;
689 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
690 strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
691 strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
692 strlcpy(cap->card, config->card_name, sizeof(cap->card));
693
694 return 0;
695}
696
697static int vpif_enum_fmt_vid_out(struct file *file, void *priv,
698 struct v4l2_fmtdesc *fmt)
699{
700 if (fmt->index != 0) {
701 vpif_err("Invalid format index\n");
702 return -EINVAL;
703 }
704
705 /* Fill in the information about format */
706 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
707 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
708 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
709
710 return 0;
711}
712
713static int vpif_g_fmt_vid_out(struct file *file, void *priv,
714 struct v4l2_format *fmt)
715{
716 struct vpif_fh *fh = priv;
717 struct channel_obj *ch = fh->channel;
718 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
719
720 /* Check the validity of the buffer type */
721 if (common->fmt.type != fmt->type)
722 return -EINVAL;
723
724 /* Fill in the information about format */
725 if (mutex_lock_interruptible(&common->lock))
726 return -ERESTARTSYS;
727
728 if (vpif_get_std_info(ch)) {
729 vpif_err("Error getting the standard info\n");
730 return -EINVAL;
731 }
732
733 *fmt = common->fmt;
734 mutex_unlock(&common->lock);
735 return 0;
736}
737
738static int vpif_s_fmt_vid_out(struct file *file, void *priv,
739 struct v4l2_format *fmt)
740{
741 struct vpif_fh *fh = priv;
742 struct v4l2_pix_format *pixfmt;
743 struct channel_obj *ch = fh->channel;
744 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
745 int ret = 0;
746
747 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
748 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
749 if (!fh->initialized) {
750 vpif_dbg(1, debug, "Channel Busy\n");
751 return -EBUSY;
752 }
753
754 /* Check for the priority */
755 ret = v4l2_prio_check(&ch->prio, &fh->prio);
756 if (0 != ret)
757 return ret;
758 fh->initialized = 1;
759 }
760
761 if (common->started) {
762 vpif_dbg(1, debug, "Streaming in progress\n");
763 return -EBUSY;
764 }
765
766 pixfmt = &fmt->fmt.pix;
767 /* Check for valid field format */
768 ret = vpif_check_format(ch, pixfmt);
769 if (ret)
770 return ret;
771
772 /* store the pix format in the channel object */
773 common->fmt.fmt.pix = *pixfmt;
774 /* store the format in the channel object */
775 if (mutex_lock_interruptible(&common->lock))
776 return -ERESTARTSYS;
777
778 common->fmt = *fmt;
779 mutex_unlock(&common->lock);
780
781 return 0;
782}
783
784static int vpif_try_fmt_vid_out(struct file *file, void *priv,
785 struct v4l2_format *fmt)
786{
787 struct vpif_fh *fh = priv;
788 struct channel_obj *ch = fh->channel;
789 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
790 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
791 int ret = 0;
792
793 ret = vpif_check_format(ch, pixfmt);
794 if (ret) {
795 *pixfmt = common->fmt.fmt.pix;
796 pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
797 }
798
799 return ret;
800}
801
802static int vpif_reqbufs(struct file *file, void *priv,
803 struct v4l2_requestbuffers *reqbuf)
804{
805 struct vpif_fh *fh = priv;
806 struct channel_obj *ch = fh->channel;
807 struct common_obj *common;
808 enum v4l2_field field;
809 u8 index = 0;
810 int ret = 0;
811
812 /* This file handle has not initialized the channel,
813 It is not allowed to do settings */
814 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
815 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
816 if (!fh->initialized) {
817 vpif_err("Channel Busy\n");
818 return -EBUSY;
819 }
820 }
821
822 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
823 return -EINVAL;
824
825 index = VPIF_VIDEO_INDEX;
826
827 common = &ch->common[index];
828 if (mutex_lock_interruptible(&common->lock))
829 return -ERESTARTSYS;
830
831 if (common->fmt.type != reqbuf->type) {
832 ret = -EINVAL;
833 goto reqbuf_exit;
834 }
835
836 if (0 != common->io_usrs) {
837 ret = -EBUSY;
838 goto reqbuf_exit;
839 }
840
841 if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
842 if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
843 field = V4L2_FIELD_INTERLACED;
844 else
845 field = common->fmt.fmt.pix.field;
846 } else {
847 field = V4L2_VBI_INTERLACED;
848 }
849
850 /* Initialize videobuf queue as per the buffer type */
851 videobuf_queue_dma_contig_init(&common->buffer_queue,
852 &video_qops, NULL,
853 &common->irqlock,
854 reqbuf->type, field,
855 sizeof(struct videobuf_buffer), fh);
856
857 /* Set io allowed member of file handle to TRUE */
858 fh->io_allowed[index] = 1;
859 /* Increment io usrs member of channel object to 1 */
860 common->io_usrs = 1;
861 /* Store type of memory requested in channel object */
862 common->memory = reqbuf->memory;
863 INIT_LIST_HEAD(&common->dma_queue);
864
865 /* Allocate buffers */
866 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
867
868reqbuf_exit:
869 mutex_unlock(&common->lock);
870 return ret;
871}
872
873static int vpif_querybuf(struct file *file, void *priv,
874 struct v4l2_buffer *tbuf)
875{
876 struct vpif_fh *fh = priv;
877 struct channel_obj *ch = fh->channel;
878 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
879
880 if (common->fmt.type != tbuf->type)
881 return -EINVAL;
882
883 return videobuf_querybuf(&common->buffer_queue, tbuf);
884}
885
886static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
887{
888
889 struct vpif_fh *fh = priv;
890 struct channel_obj *ch = fh->channel;
891 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
892 struct v4l2_buffer tbuf = *buf;
893 struct videobuf_buffer *buf1;
894 unsigned long addr = 0;
895 unsigned long flags;
896 int ret = 0;
897
898 if (common->fmt.type != tbuf.type)
899 return -EINVAL;
900
901 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
902 vpif_err("fh->io_allowed\n");
903 return -EACCES;
904 }
905
906 if (!(list_empty(&common->dma_queue)) ||
907 (common->cur_frm != common->next_frm) ||
908 !(common->started) ||
909 (common->started && (0 == ch->field_id)))
910 return videobuf_qbuf(&common->buffer_queue, buf);
911
912 /* bufferqueue is empty store buffer address in VPIF registers */
913 mutex_lock(&common->buffer_queue.vb_lock);
914 buf1 = common->buffer_queue.bufs[tbuf.index];
915 if (buf1->memory != tbuf.memory) {
916 vpif_err("invalid buffer type\n");
917 goto qbuf_exit;
918 }
919
920 if ((buf1->state == VIDEOBUF_QUEUED) ||
921 (buf1->state == VIDEOBUF_ACTIVE)) {
922 vpif_err("invalid state\n");
923 goto qbuf_exit;
924 }
925
926 switch (buf1->memory) {
927 case V4L2_MEMORY_MMAP:
928 if (buf1->baddr == 0)
929 goto qbuf_exit;
930 break;
931
932 case V4L2_MEMORY_USERPTR:
933 if (tbuf.length < buf1->bsize)
934 goto qbuf_exit;
935
936 if ((VIDEOBUF_NEEDS_INIT != buf1->state)
937 && (buf1->baddr != tbuf.m.userptr))
938 vpif_buffer_release(&common->buffer_queue, buf1);
939 buf1->baddr = tbuf.m.userptr;
940 break;
941
942 default:
943 goto qbuf_exit;
944 }
945
946 local_irq_save(flags);
947 ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
948 common->buffer_queue.field);
949 if (ret < 0) {
950 local_irq_restore(flags);
951 goto qbuf_exit;
952 }
953
954 buf1->state = VIDEOBUF_ACTIVE;
955 addr = buf1->boff;
956 common->next_frm = buf1;
957 if (tbuf.type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
958 common->set_addr((addr + common->ytop_off),
959 (addr + common->ybtm_off),
960 (addr + common->ctop_off),
961 (addr + common->cbtm_off));
962 }
963
964 local_irq_restore(flags);
965 list_add_tail(&buf1->stream, &common->buffer_queue.stream);
966 mutex_unlock(&common->buffer_queue.vb_lock);
967 return 0;
968
969qbuf_exit:
970 mutex_unlock(&common->buffer_queue.vb_lock);
971 return -EINVAL;
972}
973
974static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
975{
976 struct vpif_fh *fh = priv;
977 struct channel_obj *ch = fh->channel;
978 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
979 int ret = 0;
980
981 if (!(*std_id & DM646X_V4L2_STD))
982 return -EINVAL;
983
984 if (common->started) {
985 vpif_err("streaming in progress\n");
986 return -EBUSY;
987 }
988
989 /* Call encoder subdevice function to set the standard */
990 if (mutex_lock_interruptible(&common->lock))
991 return -ERESTARTSYS;
992
993 ch->video.stdid = *std_id;
994 /* Get the information about the standard */
995 if (vpif_get_std_info(ch)) {
996 vpif_err("Error getting the standard info\n");
997 return -EINVAL;
998 }
999
1000 if ((ch->vpifparams.std_info.width *
1001 ch->vpifparams.std_info.height * 2) >
1002 config_params.channel_bufsize[ch->channel_id]) {
1003 vpif_err("invalid std for this size\n");
1004 ret = -EINVAL;
1005 goto s_std_exit;
1006 }
1007
1008 common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
1009 /* Configure the default format information */
1010 vpif_config_format(ch);
1011
1012 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1013 s_std_output, *std_id);
1014 if (ret < 0) {
1015 vpif_err("Failed to set output standard\n");
1016 goto s_std_exit;
1017 }
1018
1019 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
1020 s_std, *std_id);
1021 if (ret < 0)
1022 vpif_err("Failed to set standard for sub devices\n");
1023
1024s_std_exit:
1025 mutex_unlock(&common->lock);
1026 return ret;
1027}
1028
1029static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1030{
1031 struct vpif_fh *fh = priv;
1032 struct channel_obj *ch = fh->channel;
1033
1034 *std = ch->video.stdid;
1035 return 0;
1036}
1037
1038static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1039{
1040 struct vpif_fh *fh = priv;
1041 struct channel_obj *ch = fh->channel;
1042 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1043
1044 return videobuf_dqbuf(&common->buffer_queue, p,
1045 (file->f_flags & O_NONBLOCK));
1046}
1047
1048static int vpif_streamon(struct file *file, void *priv,
1049 enum v4l2_buf_type buftype)
1050{
1051 struct vpif_fh *fh = priv;
1052 struct channel_obj *ch = fh->channel;
1053 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1054 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1055 struct vpif_params *vpif = &ch->vpifparams;
1056 struct vpif_display_config *vpif_config_data =
1057 vpif_dev->platform_data;
1058 unsigned long addr = 0;
1059 int ret = 0;
1060
1061 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1062 vpif_err("buffer type not supported\n");
1063 return -EINVAL;
1064 }
1065
1066 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1067 vpif_err("fh->io_allowed\n");
1068 return -EACCES;
1069 }
1070
1071 /* If Streaming is already started, return error */
1072 if (common->started) {
1073 vpif_err("channel->started\n");
1074 return -EBUSY;
1075 }
1076
1077 if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
1078 && oth_ch->common[VPIF_VIDEO_INDEX].started &&
1079 ch->vpifparams.std_info.ycmux_mode == 0)
1080 || ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
1081 && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1082 vpif_err("other channel is using\n");
1083 return -EBUSY;
1084 }
1085
1086 ret = vpif_check_format(ch, &common->fmt.fmt.pix);
1087 if (ret < 0)
1088 return ret;
1089
1090 /* Call videobuf_streamon to start streaming in videobuf */
1091 ret = videobuf_streamon(&common->buffer_queue);
1092 if (ret < 0) {
1093 vpif_err("videobuf_streamon\n");
1094 return ret;
1095 }
1096
1097 if (mutex_lock_interruptible(&common->lock))
1098 return -ERESTARTSYS;
1099
1100 /* If buffer queue is empty, return error */
1101 if (list_empty(&common->dma_queue)) {
1102 vpif_err("buffer queue is empty\n");
1103 ret = -EIO;
1104 goto streamon_exit;
1105 }
1106
1107 /* Get the next frame from the buffer queue */
1108 common->next_frm = common->cur_frm =
1109 list_entry(common->dma_queue.next,
1110 struct videobuf_buffer, queue);
1111
1112 list_del(&common->cur_frm->queue);
1113 /* Mark state of the current frame to active */
1114 common->cur_frm->state = VIDEOBUF_ACTIVE;
1115
1116 /* Initialize field_id and started member */
1117 ch->field_id = 0;
1118 common->started = 1;
1119 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1120 addr = common->cur_frm->boff;
1121 /* Calculate the offset for Y and C data in the buffer */
1122 vpif_calculate_offsets(ch);
1123
1124 if ((ch->vpifparams.std_info.frm_fmt &&
1125 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
1126 && (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
1127 || (!ch->vpifparams.std_info.frm_fmt
1128 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1129 vpif_err("conflict in field format and std format\n");
1130 ret = -EINVAL;
1131 goto streamon_exit;
1132 }
1133
1134 /* clock settings */
1135 ret =
1136 vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
1137 ch->vpifparams.std_info.hd_sd);
1138 if (ret < 0) {
1139 vpif_err("can't set clock\n");
1140 goto streamon_exit;
1141 }
1142
1143 /* set the parameters and addresses */
1144 ret = vpif_set_video_params(vpif, ch->channel_id + 2);
1145 if (ret < 0)
1146 goto streamon_exit;
1147
1148 common->started = ret;
1149 vpif_config_addr(ch, ret);
1150 common->set_addr((addr + common->ytop_off),
1151 (addr + common->ybtm_off),
1152 (addr + common->ctop_off),
1153 (addr + common->cbtm_off));
1154
1155 /* Set interrupt for both the fields in VPIF
1156 Register enable channel in VPIF register */
1157 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1158 channel2_intr_assert();
1159 channel2_intr_enable(1);
1160 enable_channel2(1);
1161 }
1162
1163 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
1164 || (common->started == 2)) {
1165 channel3_intr_assert();
1166 channel3_intr_enable(1);
1167 enable_channel3(1);
1168 }
1169 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1170 }
1171
1172streamon_exit:
1173 mutex_unlock(&common->lock);
1174 return ret;
1175}
1176
1177static int vpif_streamoff(struct file *file, void *priv,
1178 enum v4l2_buf_type buftype)
1179{
1180 struct vpif_fh *fh = priv;
1181 struct channel_obj *ch = fh->channel;
1182 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1183
1184 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1185 vpif_err("buffer type not supported\n");
1186 return -EINVAL;
1187 }
1188
1189 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1190 vpif_err("fh->io_allowed\n");
1191 return -EACCES;
1192 }
1193
1194 if (!common->started) {
1195 vpif_err("channel->started\n");
1196 return -EINVAL;
1197 }
1198
1199 if (mutex_lock_interruptible(&common->lock))
1200 return -ERESTARTSYS;
1201
1202 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1203 /* disable channel */
1204 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1205 enable_channel2(0);
1206 channel2_intr_enable(0);
1207 }
1208 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
1209 (2 == common->started)) {
1210 enable_channel3(0);
1211 channel3_intr_enable(0);
1212 }
1213 }
1214
1215 common->started = 0;
1216 mutex_unlock(&common->lock);
1217
1218 return videobuf_streamoff(&common->buffer_queue);
1219}
1220
1221static int vpif_cropcap(struct file *file, void *priv,
1222 struct v4l2_cropcap *crop)
1223{
1224 struct vpif_fh *fh = priv;
1225 struct channel_obj *ch = fh->channel;
1226 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1227 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
1228 return -EINVAL;
1229
1230 crop->bounds.left = crop->bounds.top = 0;
1231 crop->defrect.left = crop->defrect.top = 0;
1232 crop->defrect.height = crop->bounds.height = common->height;
1233 crop->defrect.width = crop->bounds.width = common->width;
1234
1235 return 0;
1236}
1237
1238static int vpif_enum_output(struct file *file, void *fh,
1239 struct v4l2_output *output)
1240{
1241
1242 struct vpif_display_config *config = vpif_dev->platform_data;
1243
1244 if (output->index >= config->output_count) {
1245 vpif_dbg(1, debug, "Invalid output index\n");
1246 return -EINVAL;
1247 }
1248
1249 strcpy(output->name, config->output[output->index]);
1250 output->type = V4L2_OUTPUT_TYPE_ANALOG;
1251 output->std = DM646X_V4L2_STD;
1252
1253 return 0;
1254}
1255
1256static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1257{
1258 struct vpif_fh *fh = priv;
1259 struct channel_obj *ch = fh->channel;
1260 struct video_obj *vid_ch = &ch->video;
1261 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1262 int ret = 0;
1263
1264 if (mutex_lock_interruptible(&common->lock))
1265 return -ERESTARTSYS;
1266
1267 if (common->started) {
1268 vpif_err("Streaming in progress\n");
1269 ret = -EBUSY;
1270 goto s_output_exit;
1271 }
1272
1273 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1274 s_routing, 0, i, 0);
1275
1276 if (ret < 0)
1277 vpif_err("Failed to set output standard\n");
1278
1279 vid_ch->output_id = i;
1280
1281s_output_exit:
1282 mutex_unlock(&common->lock);
1283 return ret;
1284}
1285
1286static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
1287{
1288 struct vpif_fh *fh = priv;
1289 struct channel_obj *ch = fh->channel;
1290 struct video_obj *vid_ch = &ch->video;
1291
1292 *i = vid_ch->output_id;
1293
1294 return 0;
1295}
1296
1297static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
1298{
1299 struct vpif_fh *fh = priv;
1300 struct channel_obj *ch = fh->channel;
1301
1302 *p = v4l2_prio_max(&ch->prio);
1303
1304 return 0;
1305}
1306
1307static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1308{
1309 struct vpif_fh *fh = priv;
1310 struct channel_obj *ch = fh->channel;
1311
1312 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1313}
1314
1315/* vpif display ioctl operations */
1316static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1317 .vidioc_querycap = vpif_querycap,
1318 .vidioc_g_priority = vpif_g_priority,
1319 .vidioc_s_priority = vpif_s_priority,
1320 .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out,
1321 .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out,
1322 .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out,
1323 .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
1324 .vidioc_reqbufs = vpif_reqbufs,
1325 .vidioc_querybuf = vpif_querybuf,
1326 .vidioc_qbuf = vpif_qbuf,
1327 .vidioc_dqbuf = vpif_dqbuf,
1328 .vidioc_streamon = vpif_streamon,
1329 .vidioc_streamoff = vpif_streamoff,
1330 .vidioc_s_std = vpif_s_std,
1331 .vidioc_g_std = vpif_g_std,
1332 .vidioc_enum_output = vpif_enum_output,
1333 .vidioc_s_output = vpif_s_output,
1334 .vidioc_g_output = vpif_g_output,
1335 .vidioc_cropcap = vpif_cropcap,
1336};
1337
1338static const struct v4l2_file_operations vpif_fops = {
1339 .owner = THIS_MODULE,
1340 .open = vpif_open,
1341 .release = vpif_release,
1342 .ioctl = video_ioctl2,
1343 .mmap = vpif_mmap,
1344 .poll = vpif_poll
1345};
1346
1347static struct video_device vpif_video_template = {
1348 .name = "vpif",
1349 .fops = &vpif_fops,
1350 .minor = -1,
1351 .ioctl_ops = &vpif_ioctl_ops,
1352 .tvnorms = DM646X_V4L2_STD,
1353 .current_norm = V4L2_STD_625_50,
1354
1355};
1356
1357/*Configure the channels, buffer sizei, request irq */
1358static int initialize_vpif(void)
1359{
1360 int free_channel_objects_index;
1361 int free_buffer_channel_index;
1362 int free_buffer_index;
1363 int err = 0, i, j;
1364
1365 /* Default number of buffers should be 3 */
1366 if ((ch2_numbuffers > 0) &&
1367 (ch2_numbuffers < config_params.min_numbuffers))
1368 ch2_numbuffers = config_params.min_numbuffers;
1369 if ((ch3_numbuffers > 0) &&
1370 (ch3_numbuffers < config_params.min_numbuffers))
1371 ch3_numbuffers = config_params.min_numbuffers;
1372
1373 /* Set buffer size to min buffers size if invalid buffer size is
1374 * given */
1375 if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
1376 ch2_bufsize =
1377 config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
1378 if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
1379 ch3_bufsize =
1380 config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
1381
1382 config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
1383
1384 if (ch2_numbuffers) {
1385 config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
1386 ch2_bufsize;
1387 }
1388 config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
1389
1390 if (ch3_numbuffers) {
1391 config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
1392 ch3_bufsize;
1393 }
1394
1395 /* Allocate memory for six channel objects */
1396 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1397 vpif_obj.dev[i] =
1398 kmalloc(sizeof(struct channel_obj), GFP_KERNEL);
1399 /* If memory allocation fails, return error */
1400 if (!vpif_obj.dev[i]) {
1401 free_channel_objects_index = i;
1402 err = -ENOMEM;
1403 goto vpif_init_free_channel_objects;
1404 }
1405 }
1406
1407 free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
1408 free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
1409 free_buffer_index = config_params.numbuffers[i - 1];
1410
1411 return 0;
1412
1413vpif_init_free_channel_objects:
1414 for (j = 0; j < free_channel_objects_index; j++)
1415 kfree(vpif_obj.dev[j]);
1416 return err;
1417}
1418
1419/*
1420 * vpif_probe: This function creates device entries by register itself to the
1421 * V4L2 driver and initializes fields of each channel objects
1422 */
1423static __init int vpif_probe(struct platform_device *pdev)
1424{
1425 struct vpif_subdev_info *subdevdata;
1426 struct vpif_display_config *config;
1427 int i, j = 0, k, q, m, err = 0;
1428 struct i2c_adapter *i2c_adap;
1429 struct vpif_config *config;
1430 struct common_obj *common;
1431 struct channel_obj *ch;
1432 struct video_device *vfd;
1433 struct resource *res;
1434 int subdev_count;
1435
1436 vpif_dev = &pdev->dev;
1437
1438 err = initialize_vpif();
1439
1440 if (err) {
1441 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1442 return err;
1443 }
1444
1445 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
1446 if (err) {
1447 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
1448 return err;
1449 }
1450
1451 k = 0;
1452 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1453 for (i = res->start; i <= res->end; i++) {
1454 if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
1455 "DM646x_Display",
1456 (void *)(&vpif_obj.dev[k]->channel_id))) {
1457 err = -EBUSY;
1458 goto vpif_int_err;
1459 }
1460 }
1461 k++;
1462 }
1463
1464 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1465
1466 /* Get the pointer to the channel object */
1467 ch = vpif_obj.dev[i];
1468
1469 /* Allocate memory for video device */
1470 vfd = video_device_alloc();
1471 if (vfd == NULL) {
1472 for (j = 0; j < i; j++) {
1473 ch = vpif_obj.dev[j];
1474 video_device_release(ch->video_dev);
1475 }
1476 err = -ENOMEM;
1477 goto vpif_int_err;
1478 }
1479
1480 /* Initialize field of video device */
1481 *vfd = vpif_video_template;
1482 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1483 vfd->release = video_device_release;
1484 snprintf(vfd->name, sizeof(vfd->name),
1485 "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d",
1486 (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff,
1487 (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff,
1488 (VPIF_DISPLAY_VERSION_CODE) & 0xff);
1489
1490 /* Set video_dev to the video device */
1491 ch->video_dev = vfd;
1492 }
1493
1494 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
1495 ch = vpif_obj.dev[j];
1496 /* Initialize field of the channel objects */
1497 atomic_set(&ch->usrs, 0);
1498 for (k = 0; k < VPIF_NUMOBJECTS; k++) {
1499 ch->common[k].numbuffers = 0;
1500 common = &ch->common[k];
1501 common->io_usrs = 0;
1502 common->started = 0;
1503 spin_lock_init(&common->irqlock);
1504 mutex_init(&common->lock);
1505 common->numbuffers = 0;
1506 common->set_addr = NULL;
1507 common->ytop_off = common->ybtm_off = 0;
1508 common->ctop_off = common->cbtm_off = 0;
1509 common->cur_frm = common->next_frm = NULL;
1510 memset(&common->fmt, 0, sizeof(common->fmt));
1511 common->numbuffers = config_params.numbuffers[k];
1512
1513 }
1514 ch->initialized = 0;
1515 ch->channel_id = j;
1516 if (j < 2)
1517 ch->common[VPIF_VIDEO_INDEX].numbuffers =
1518 config_params.numbuffers[ch->channel_id];
1519 else
1520 ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
1521
1522 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
1523
1524 /* Initialize prio member of channel object */
1525 v4l2_prio_init(&ch->prio);
1526 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1527 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1528
1529 /* register video device */
1530 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
1531 (int)ch, (int)&ch->video_dev);
1532
1533 err = video_register_device(ch->video_dev,
1534 VFL_TYPE_GRABBER, (j ? 3 : 2));
1535 if (err < 0)
1536 goto probe_out;
1537
1538 video_set_drvdata(ch->video_dev, ch);
1539 }
1540
1541 i2c_adap = i2c_get_adapter(1);
1542 config = pdev->dev.platform_data;
1543 subdev_count = config->subdev_count;
1544 subdevdata = config->subdevinfo;
1545 vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1546 GFP_KERNEL);
1547 if (vpif_obj.sd == NULL) {
1548 vpif_err("unable to allocate memory for subdevice pointers\n");
1549 err = -ENOMEM;
1550 goto probe_out;
1551 }
1552
1553 for (i = 0; i < subdev_count; i++) {
1554 vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
1555 i2c_adap, subdevdata[i].name,
1556 &subdevdata[i].board_info,
1557 NULL);
1558 if (!vpif_obj.sd[i]) {
1559 vpif_err("Error registering v4l2 subdevice\n");
1560 goto probe_subdev_out;
1561 }
1562
1563 if (vpif_obj.sd[i])
1564 vpif_obj.sd[i]->grp_id = 1 << i;
1565 }
1566
1567 return 0;
1568
1569probe_subdev_out:
1570 kfree(vpif_obj.sd);
1571probe_out:
1572 for (k = 0; k < j; k++) {
1573 ch = vpif_obj.dev[k];
1574 video_unregister_device(ch->video_dev);
1575 video_device_release(ch->video_dev);
1576 ch->video_dev = NULL;
1577 }
1578vpif_int_err:
1579 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1580 vpif_err("VPIF IRQ request failed\n");
1581 for (q = k; k >= 0; k--) {
1582 for (m = i; m >= res->start; m--)
1583 free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
1584 res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
1585 m = res->end;
1586 }
1587
1588 return err;
1589}
1590
1591/*
1592 * vpif_remove: It un-register channels from V4L2 driver
1593 */
1594static int vpif_remove(struct platform_device *device)
1595{
1596 struct channel_obj *ch;
1597 int i;
1598
1599 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1600
1601 /* un-register device */
1602 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1603 /* Get the pointer to the channel object */
1604 ch = vpif_obj.dev[i];
1605 /* Unregister video device */
1606 video_unregister_device(ch->video_dev);
1607
1608 ch->video_dev = NULL;
1609 }
1610
1611 return 0;
1612}
1613
1614static struct platform_driver vpif_driver = {
1615 .driver = {
1616 .name = "vpif_display",
1617 .owner = THIS_MODULE,
1618 },
1619 .probe = vpif_probe,
1620 .remove = vpif_remove,
1621};
1622
1623static __init int vpif_init(void)
1624{
1625 return platform_driver_register(&vpif_driver);
1626}
1627
1628/*
1629 * vpif_cleanup: This function un-registers device and driver to the kernel,
1630 * frees requested irq handler and de-allocates memory allocated for channel
1631 * objects.
1632 */
1633static void vpif_cleanup(void)
1634{
1635 struct platform_device *pdev;
1636 struct resource *res;
1637 int irq_num;
1638 int i = 0;
1639
1640 pdev = container_of(vpif_dev, struct platform_device, dev);
1641
1642 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
1643 for (irq_num = res->start; irq_num <= res->end; irq_num++)
1644 free_irq(irq_num,
1645 (void *)(&vpif_obj.dev[i]->channel_id));
1646 i++;
1647 }
1648
1649 platform_driver_unregister(&vpif_driver);
1650 kfree(vpif_obj.sd);
1651 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
1652 kfree(vpif_obj.dev[i]);
1653}
1654
1655module_init(vpif_init);
1656module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h
new file mode 100644
index 000000000000..a2a7cd166bbf
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.h
@@ -0,0 +1,175 @@
1/*
2 * DM646x display header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef DAVINCIHD_DISPLAY_H
17#define DAVINCIHD_DISPLAY_H
18
19/* Header files */
20#include <linux/videodev2.h>
21#include <linux/version.h>
22#include <media/v4l2-common.h>
23#include <media/v4l2-device.h>
24#include <media/videobuf-core.h>
25#include <media/videobuf-dma-contig.h>
26
27#include "vpif.h"
28
29/* Macros */
30#define VPIF_MAJOR_RELEASE (0)
31#define VPIF_MINOR_RELEASE (0)
32#define VPIF_BUILD (1)
33
34#define VPIF_DISPLAY_VERSION_CODE \
35 ((VPIF_MAJOR_RELEASE << 16) | (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
36
37#define VPIF_VALID_FIELD(field) \
38 (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
39 (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
40 (V4L2_FIELD_SEQ_BT == field)))
41
42#define VPIF_DISPLAY_MAX_DEVICES (2)
43#define VPIF_SLICED_BUF_SIZE (256)
44#define VPIF_SLICED_MAX_SERVICES (3)
45#define VPIF_VIDEO_INDEX (0)
46#define VPIF_VBI_INDEX (1)
47#define VPIF_HBI_INDEX (2)
48
49/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
50#define VPIF_NUMOBJECTS (1)
51
52/* Macros */
53#define ISALIGNED(a) (0 == ((a) & 7))
54
55/* enumerated data types */
56/* Enumerated data type to give id to each device per channel */
57enum vpif_channel_id {
58 VPIF_CHANNEL2_VIDEO = 0, /* Channel2 Video */
59 VPIF_CHANNEL3_VIDEO, /* Channel3 Video */
60};
61
62/* structures */
63
64struct video_obj {
65 enum v4l2_field buf_field;
66 u32 latest_only; /* indicate whether to return
67 * most recent displayed frame only */
68 v4l2_std_id stdid; /* Currently selected or default
69 * standard */
70 u32 output_id; /* Current output id */
71};
72
73struct vbi_obj {
74 int num_services;
75 struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
76 * vbi data */
77};
78
79struct common_obj {
80 /* Buffer specific parameters */
81 u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
82 * storing frames */
83 u32 numbuffers; /* number of buffers */
84 struct videobuf_buffer *cur_frm; /* Pointer pointing to current
85 * videobuf_buffer */
86 struct videobuf_buffer *next_frm; /* Pointer pointing to next
87 * videobuf_buffer */
88 enum v4l2_memory memory; /* This field keeps track of
89 * type of buffer exchange
90 * method user has selected */
91 struct v4l2_format fmt; /* Used to store the format */
92 struct videobuf_queue buffer_queue; /* Buffer queue used in
93 * video-buf */
94 struct list_head dma_queue; /* Queue of filled frames */
95 spinlock_t irqlock; /* Used in video-buf */
96
97 /* channel specific parameters */
98 struct mutex lock; /* lock used to access this
99 * structure */
100 u32 io_usrs; /* number of users performing
101 * IO */
102 u8 started; /* Indicates whether streaming
103 * started */
104 u32 ytop_off; /* offset of Y top from the
105 * starting of the buffer */
106 u32 ybtm_off; /* offset of Y bottom from the
107 * starting of the buffer */
108 u32 ctop_off; /* offset of C top from the
109 * starting of the buffer */
110 u32 cbtm_off; /* offset of C bottom from the
111 * starting of the buffer */
112 /* Function pointer to set the addresses */
113 void (*set_addr) (unsigned long, unsigned long,
114 unsigned long, unsigned long);
115 u32 height;
116 u32 width;
117};
118
119struct channel_obj {
120 /* V4l2 specific parameters */
121 struct video_device *video_dev; /* Identifies video device for
122 * this channel */
123 struct v4l2_prio_state prio; /* Used to keep track of state of
124 * the priority */
125 atomic_t usrs; /* number of open instances of
126 * the channel */
127 u32 field_id; /* Indicates id of the field
128 * which is being displayed */
129 u8 initialized; /* flag to indicate whether
130 * encoder is initialized */
131
132 enum vpif_channel_id channel_id;/* Identifies channel */
133 struct vpif_params vpifparams;
134 struct common_obj common[VPIF_NUMOBJECTS];
135 struct video_obj video;
136 struct vbi_obj vbi;
137};
138
139/* File handle structure */
140struct vpif_fh {
141 struct channel_obj *channel; /* pointer to channel object for
142 * opened device */
143 u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
144 * is doing IO */
145 enum v4l2_priority prio; /* Used to keep track priority of
146 * this instance */
147 u8 initialized; /* Used to keep track of whether this
148 * file handle has initialized
149 * channel or not */
150};
151
152/* vpif device structure */
153struct vpif_device {
154 struct v4l2_device v4l2_dev;
155 struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
156 struct v4l2_subdev **sd;
157
158};
159
160struct vpif_config_params {
161 u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
162 u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
163 u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
164 u8 min_numbuffers;
165};
166
167/* Struct which keeps track of the line numbers for the sliced vbi service */
168struct vpif_service_line {
169 u16 service_id;
170 u16 service_line[2];
171 u16 enc_service_id;
172 u8 bytestowrite;
173};
174
175#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
new file mode 100644
index 000000000000..6d709ca8cfb0
--- /dev/null
+++ b/drivers/media/video/davinci/vpss.c
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2009 Texas Instruments.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * common vpss driver for all video drivers.
19 */
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/spinlock.h>
26#include <linux/compiler.h>
27#include <linux/io.h>
28#include <mach/hardware.h>
29#include <media/davinci/vpss.h>
30
31MODULE_LICENSE("GPL");
32MODULE_DESCRIPTION("VPSS Driver");
33MODULE_AUTHOR("Texas Instruments");
34
35/* DM644x defines */
36#define DM644X_SBL_PCR_VPSS (4)
37
38/* vpss BL register offsets */
39#define DM355_VPSSBL_CCDCMUX 0x1c
40/* vpss CLK register offsets */
41#define DM355_VPSSCLK_CLKCTRL 0x04
42/* masks and shifts */
43#define VPSS_HSSISEL_SHIFT 4
44
45/*
46 * vpss operations. Depends on platform. Not all functions are available
47 * on all platforms. The api, first check if a functio is available before
48 * invoking it. In the probe, the function ptrs are intialized based on
49 * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
50 */
51struct vpss_hw_ops {
52 /* enable clock */
53 int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
54 /* select input to ccdc */
55 void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
56 /* clear wbl overlflow bit */
57 int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
58};
59
60/* vpss configuration */
61struct vpss_oper_config {
62 __iomem void *vpss_bl_regs_base;
63 __iomem void *vpss_regs_base;
64 struct resource *r1;
65 resource_size_t len1;
66 struct resource *r2;
67 resource_size_t len2;
68 char vpss_name[32];
69 spinlock_t vpss_lock;
70 struct vpss_hw_ops hw_ops;
71};
72
73static struct vpss_oper_config oper_cfg;
74
75/* register access routines */
76static inline u32 bl_regr(u32 offset)
77{
78 return __raw_readl(oper_cfg.vpss_bl_regs_base + offset);
79}
80
81static inline void bl_regw(u32 val, u32 offset)
82{
83 __raw_writel(val, oper_cfg.vpss_bl_regs_base + offset);
84}
85
86static inline u32 vpss_regr(u32 offset)
87{
88 return __raw_readl(oper_cfg.vpss_regs_base + offset);
89}
90
91static inline void vpss_regw(u32 val, u32 offset)
92{
93 __raw_writel(val, oper_cfg.vpss_regs_base + offset);
94}
95
96static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
97{
98 bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
99}
100
101int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
102{
103 if (!oper_cfg.hw_ops.select_ccdc_source)
104 return -1;
105
106 dm355_select_ccdc_source(src_sel);
107 return 0;
108}
109EXPORT_SYMBOL(vpss_select_ccdc_source);
110
111static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
112{
113 u32 mask = 1, val;
114
115 if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
116 wbl_sel > VPSS_PCR_CCDC_WBL_O)
117 return -1;
118
119 /* writing a 0 clear the overflow */
120 mask = ~(mask << wbl_sel);
121 val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
122 bl_regw(val, DM644X_SBL_PCR_VPSS);
123 return 0;
124}
125
126int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
127{
128 if (!oper_cfg.hw_ops.clear_wbl_overflow)
129 return -1;
130
131 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
132}
133EXPORT_SYMBOL(vpss_clear_wbl_overflow);
134
135/*
136 * dm355_enable_clock - Enable VPSS Clock
137 * @clock_sel: CLock to be enabled/disabled
138 * @en: enable/disable flag
139 *
140 * This is called to enable or disable a vpss clock
141 */
142static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
143{
144 unsigned long flags;
145 u32 utemp, mask = 0x1, shift = 0;
146
147 switch (clock_sel) {
148 case VPSS_VPBE_CLOCK:
149 /* nothing since lsb */
150 break;
151 case VPSS_VENC_CLOCK_SEL:
152 shift = 2;
153 break;
154 case VPSS_CFALD_CLOCK:
155 shift = 3;
156 break;
157 case VPSS_H3A_CLOCK:
158 shift = 4;
159 break;
160 case VPSS_IPIPE_CLOCK:
161 shift = 5;
162 break;
163 case VPSS_CCDC_CLOCK:
164 shift = 6;
165 break;
166 default:
167 printk(KERN_ERR "dm355_enable_clock:"
168 " Invalid selector: %d\n", clock_sel);
169 return -1;
170 }
171
172 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
173 utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
174 if (!en)
175 utemp &= ~(mask << shift);
176 else
177 utemp |= (mask << shift);
178
179 vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
180 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
181 return 0;
182}
183
184int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
185{
186 if (!oper_cfg.hw_ops.enable_clock)
187 return -1;
188
189 return oper_cfg.hw_ops.enable_clock(clock_sel, en);
190}
191EXPORT_SYMBOL(vpss_enable_clock);
192
193static int __init vpss_probe(struct platform_device *pdev)
194{
195 int status, dm355 = 0;
196
197 if (!pdev->dev.platform_data) {
198 dev_err(&pdev->dev, "no platform data\n");
199 return -ENOENT;
200 }
201 strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
202
203 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss"))
204 dm355 = 1;
205 else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) {
206 dev_err(&pdev->dev, "vpss driver not supported on"
207 " this platform\n");
208 return -ENODEV;
209 }
210
211 dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name);
212 oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
213 if (!oper_cfg.r1)
214 return -ENOENT;
215
216 oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1;
217
218 oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
219 oper_cfg.r1->name);
220 if (!oper_cfg.r1)
221 return -EBUSY;
222
223 oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1);
224 if (!oper_cfg.vpss_bl_regs_base) {
225 status = -EBUSY;
226 goto fail1;
227 }
228
229 if (dm355) {
230 oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
231 if (!oper_cfg.r2) {
232 status = -ENOENT;
233 goto fail2;
234 }
235 oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1;
236 oper_cfg.r2 = request_mem_region(oper_cfg.r2->start,
237 oper_cfg.len2,
238 oper_cfg.r2->name);
239 if (!oper_cfg.r2) {
240 status = -EBUSY;
241 goto fail2;
242 }
243
244 oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start,
245 oper_cfg.len2);
246 if (!oper_cfg.vpss_regs_base) {
247 status = -EBUSY;
248 goto fail3;
249 }
250 }
251
252 if (dm355) {
253 oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
254 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
255 } else
256 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
257
258 spin_lock_init(&oper_cfg.vpss_lock);
259 dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name);
260 return 0;
261
262fail3:
263 release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
264fail2:
265 iounmap(oper_cfg.vpss_bl_regs_base);
266fail1:
267 release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
268 return status;
269}
270
271static int vpss_remove(struct platform_device *pdev)
272{
273 iounmap(oper_cfg.vpss_bl_regs_base);
274 release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
275 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) {
276 iounmap(oper_cfg.vpss_regs_base);
277 release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
278 }
279 return 0;
280}
281
282static struct platform_driver vpss_driver = {
283 .driver = {
284 .name = "vpss",
285 .owner = THIS_MODULE,
286 },
287 .remove = __devexit_p(vpss_remove),
288 .probe = vpss_probe,
289};
290
291static void vpss_exit(void)
292{
293 platform_driver_unregister(&vpss_driver);
294}
295
296static int __init vpss_init(void)
297{
298 return platform_driver_register(&vpss_driver);
299}
300subsys_initcall(vpss_init);
301module_exit(vpss_exit);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 6524b493e033..c7be0e097828 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -36,6 +36,7 @@ config VIDEO_EM28XX_DVB
36 depends on VIDEO_EM28XX && DVB_CORE 36 depends on VIDEO_EM28XX && DVB_CORE
37 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 37 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
39 select VIDEOBUF_DVB 40 select VIDEOBUF_DVB
40 ---help--- 41 ---help---
41 This adds support for DVB cards based on the 42 This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 8137a8c94bfc..d0f093d1d0df 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -1,5 +1,5 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ 1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o 2 em28xx-input.o em28xx-vbi.o
3 3
4em28xx-alsa-objs := em28xx-audio.o 4em28xx-alsa-objs := em28xx-audio.o
5 5
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7e3c78239fa9..bdb249bd9d5d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -170,6 +170,19 @@ static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
170 { -1, -1, -1, -1}, 170 { -1, -1, -1, -1},
171}; 171};
172 172
173/* eb1a:2868 Reddo DVB-C USB TV Box
174 GPIO4 - CU1216L NIM
175 Other GPIOs seems to be don't care. */
176static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
177 {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
178 {EM28XX_R08_GPIO, 0xde, 0xff, 10},
179 {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
180 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
181 {EM28XX_R08_GPIO, 0x7f, 0xff, 10},
182 {EM28XX_R08_GPIO, 0x6f, 0xff, 10},
183 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
184 {-1, -1, -1, -1},
185};
173 186
174/* Callback for the most boards */ 187/* Callback for the most boards */
175static struct em28xx_reg_seq default_tuner_gpio[] = { 188static struct em28xx_reg_seq default_tuner_gpio[] = {
@@ -1566,6 +1579,14 @@ struct em28xx_board em28xx_boards[] = {
1566 .gpio = evga_indtube_analog, 1579 .gpio = evga_indtube_analog,
1567 } }, 1580 } },
1568 }, 1581 },
1582 /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 +
1583 Infineon TUA6034) */
1584 [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
1585 .name = "Reddo DVB-C USB TV Box",
1586 .tuner_type = TUNER_ABSENT,
1587 .has_dvb = 1,
1588 .dvb_gpio = reddo_dvb_c_usb_box,
1589 },
1569}; 1590};
1570const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1591const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1571 1592
@@ -1593,6 +1614,8 @@ struct usb_device_id em28xx_id_table[] = {
1593 .driver_info = EM2820_BOARD_UNKNOWN }, 1614 .driver_info = EM2820_BOARD_UNKNOWN },
1594 { USB_DEVICE(0xeb1a, 0x2883), 1615 { USB_DEVICE(0xeb1a, 0x2883),
1595 .driver_info = EM2820_BOARD_UNKNOWN }, 1616 .driver_info = EM2820_BOARD_UNKNOWN },
1617 { USB_DEVICE(0xeb1a, 0x2868),
1618 .driver_info = EM2820_BOARD_UNKNOWN },
1596 { USB_DEVICE(0xeb1a, 0xe300), 1619 { USB_DEVICE(0xeb1a, 0xe300),
1597 .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, 1620 .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
1598 { USB_DEVICE(0xeb1a, 0xe303), 1621 { USB_DEVICE(0xeb1a, 0xe303),
@@ -1696,6 +1719,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1696 {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, 1719 {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
1697 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1720 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1698 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1721 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1722 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
1699}; 1723};
1700 1724
1701/* I2C devicelist hash table for devices with generic USB IDs */ 1725/* I2C devicelist hash table for devices with generic USB IDs */
@@ -2348,55 +2372,55 @@ void em28xx_card_setup(struct em28xx *dev)
2348 2372
2349 /* request some modules */ 2373 /* request some modules */
2350 if (dev->board.has_msp34xx) 2374 if (dev->board.has_msp34xx)
2351 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2375 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2352 "msp3400", "msp3400", msp3400_addrs); 2376 "msp3400", "msp3400", 0, msp3400_addrs);
2353 2377
2354 if (dev->board.decoder == EM28XX_SAA711X) 2378 if (dev->board.decoder == EM28XX_SAA711X)
2355 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2379 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2356 "saa7115", "saa7115_auto", saa711x_addrs); 2380 "saa7115", "saa7115_auto", 0, saa711x_addrs);
2357 2381
2358 if (dev->board.decoder == EM28XX_TVP5150) 2382 if (dev->board.decoder == EM28XX_TVP5150)
2359 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2383 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2360 "tvp5150", "tvp5150", tvp5150_addrs); 2384 "tvp5150", "tvp5150", 0, tvp5150_addrs);
2361 2385
2362 if (dev->em28xx_sensor == EM28XX_MT9V011) { 2386 if (dev->em28xx_sensor == EM28XX_MT9V011) {
2363 struct v4l2_subdev *sd; 2387 struct v4l2_subdev *sd;
2364 2388
2365 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2389 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2366 &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs); 2390 &dev->i2c_adap, "mt9v011", "mt9v011", 0, mt9v011_addrs);
2367 v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); 2391 v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
2368 } 2392 }
2369 2393
2370 2394
2371 if (dev->board.adecoder == EM28XX_TVAUDIO) 2395 if (dev->board.adecoder == EM28XX_TVAUDIO)
2372 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2396 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2373 "tvaudio", "tvaudio", dev->board.tvaudio_addr); 2397 "tvaudio", "tvaudio", dev->board.tvaudio_addr, NULL);
2374 2398
2375 if (dev->board.tuner_type != TUNER_ABSENT) { 2399 if (dev->board.tuner_type != TUNER_ABSENT) {
2376 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); 2400 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2377 2401
2378 if (dev->board.radio.type) 2402 if (dev->board.radio.type)
2379 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2403 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2380 "tuner", "tuner", dev->board.radio_addr); 2404 "tuner", "tuner", dev->board.radio_addr, NULL);
2381 2405
2382 if (has_demod) 2406 if (has_demod)
2383 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2407 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2384 &dev->i2c_adap, "tuner", "tuner", 2408 &dev->i2c_adap, "tuner", "tuner",
2385 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 2409 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2386 if (dev->tuner_addr == 0) { 2410 if (dev->tuner_addr == 0) {
2387 enum v4l2_i2c_tuner_type type = 2411 enum v4l2_i2c_tuner_type type =
2388 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 2412 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2389 struct v4l2_subdev *sd; 2413 struct v4l2_subdev *sd;
2390 2414
2391 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2415 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2392 &dev->i2c_adap, "tuner", "tuner", 2416 &dev->i2c_adap, "tuner", "tuner",
2393 v4l2_i2c_tuner_addrs(type)); 2417 0, v4l2_i2c_tuner_addrs(type));
2394 2418
2395 if (sd) 2419 if (sd)
2396 dev->tuner_addr = v4l2_i2c_subdev_addr(sd); 2420 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2397 } else { 2421 } else {
2398 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2422 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2399 "tuner", "tuner", dev->tuner_addr); 2423 "tuner", "tuner", dev->tuner_addr, NULL);
2400 } 2424 }
2401 } 2425 }
2402 2426
@@ -2570,7 +2594,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2570 * Default format, used for tvp5150 or saa711x output formats 2594 * Default format, used for tvp5150 or saa711x output formats
2571 */ 2595 */
2572 dev->vinmode = 0x10; 2596 dev->vinmode = 0x10;
2573 dev->vinctl = 0x11; 2597 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2598 EM28XX_VINCTRL_CCIR656_ENABLE;
2574 2599
2575 /* Do board specific init and eeprom reading */ 2600 /* Do board specific init and eeprom reading */
2576 em28xx_card_setup(dev); 2601 em28xx_card_setup(dev);
@@ -2589,6 +2614,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2589 /* init video dma queues */ 2614 /* init video dma queues */
2590 INIT_LIST_HEAD(&dev->vidq.active); 2615 INIT_LIST_HEAD(&dev->vidq.active);
2591 INIT_LIST_HEAD(&dev->vidq.queued); 2616 INIT_LIST_HEAD(&dev->vidq.queued);
2617 INIT_LIST_HEAD(&dev->vbiq.active);
2618 INIT_LIST_HEAD(&dev->vbiq.queued);
2592 2619
2593 2620
2594 if (dev->board.has_msp34xx) { 2621 if (dev->board.has_msp34xx) {
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 98e140b5d95e..a88257a7d94f 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -54,6 +54,10 @@ static int alt = EM28XX_PINOUT;
54module_param(alt, int, 0644); 54module_param(alt, int, 0644);
55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
56 56
57static unsigned int disable_vbi;
58module_param(disable_vbi, int, 0644);
59MODULE_PARM_DESC(disable_vbi, "disable vbi support");
60
57/* FIXME */ 61/* FIXME */
58#define em28xx_isocdbg(fmt, arg...) do {\ 62#define em28xx_isocdbg(fmt, arg...) do {\
59 if (core_debug) \ 63 if (core_debug) \
@@ -648,9 +652,24 @@ int em28xx_capture_start(struct em28xx *dev, int start)
648 return rc; 652 return rc;
649} 653}
650 654
655int em28xx_vbi_supported(struct em28xx *dev)
656{
657 /* Modprobe option to manually disable */
658 if (disable_vbi == 1)
659 return 0;
660
661 if (dev->chip_id == CHIP_ID_EM2860 ||
662 dev->chip_id == CHIP_ID_EM2883)
663 return 1;
664
665 /* Version of em28xx that does not support VBI */
666 return 0;
667}
668
651int em28xx_set_outfmt(struct em28xx *dev) 669int em28xx_set_outfmt(struct em28xx *dev)
652{ 670{
653 int ret; 671 int ret;
672 u8 vinctrl;
654 673
655 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, 674 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
656 dev->format->reg | 0x20, 0xff); 675 dev->format->reg | 0x20, 0xff);
@@ -661,7 +680,16 @@ int em28xx_set_outfmt(struct em28xx *dev)
661 if (ret < 0) 680 if (ret < 0)
662 return ret; 681 return ret;
663 682
664 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl); 683 vinctrl = dev->vinctl;
684 if (em28xx_vbi_supported(dev) == 1) {
685 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
686 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
687 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
688 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4);
689 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c);
690 }
691
692 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
665} 693}
666 694
667static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, 695static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -732,7 +760,14 @@ int em28xx_resolution_set(struct em28xx *dev)
732 760
733 761
734 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 762 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
735 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); 763
764 /* If we don't set the start position to 4 in VBI mode, we end up
765 with line 21 being YUYV encoded instead of being in 8-bit
766 greyscale */
767 if (em28xx_vbi_supported(dev) == 1)
768 em28xx_capture_area_set(dev, 0, 4, width >> 2, height >> 2);
769 else
770 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
736 771
737 return em28xx_scaler_set(dev, dev->hscale, dev->vscale); 772 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
738} 773}
@@ -844,8 +879,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
844 */ 879 */
845static void em28xx_irq_callback(struct urb *urb) 880static void em28xx_irq_callback(struct urb *urb)
846{ 881{
847 struct em28xx_dmaqueue *dma_q = urb->context; 882 struct em28xx *dev = urb->context;
848 struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
849 int rc, i; 883 int rc, i;
850 884
851 switch (urb->status) { 885 switch (urb->status) {
@@ -930,6 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
930 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) 964 int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
931{ 965{
932 struct em28xx_dmaqueue *dma_q = &dev->vidq; 966 struct em28xx_dmaqueue *dma_q = &dev->vidq;
967 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
933 int i; 968 int i;
934 int sb_size, pipe; 969 int sb_size, pipe;
935 struct urb *urb; 970 struct urb *urb;
@@ -959,7 +994,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
959 } 994 }
960 995
961 dev->isoc_ctl.max_pkt_size = max_pkt_size; 996 dev->isoc_ctl.max_pkt_size = max_pkt_size;
962 dev->isoc_ctl.buf = NULL; 997 dev->isoc_ctl.vid_buf = NULL;
998 dev->isoc_ctl.vbi_buf = NULL;
963 999
964 sb_size = max_packets * dev->isoc_ctl.max_pkt_size; 1000 sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
965 1001
@@ -994,7 +1030,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
994 1030
995 usb_fill_int_urb(urb, dev->udev, pipe, 1031 usb_fill_int_urb(urb, dev->udev, pipe,
996 dev->isoc_ctl.transfer_buffer[i], sb_size, 1032 dev->isoc_ctl.transfer_buffer[i], sb_size,
997 em28xx_irq_callback, dma_q, 1); 1033 em28xx_irq_callback, dev, 1);
998 1034
999 urb->number_of_packets = max_packets; 1035 urb->number_of_packets = max_packets;
1000 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1036 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
@@ -1009,6 +1045,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1009 } 1045 }
1010 1046
1011 init_waitqueue_head(&dma_q->wq); 1047 init_waitqueue_head(&dma_q->wq);
1048 init_waitqueue_head(&vbi_dma_q->wq);
1012 1049
1013 em28xx_capture_start(dev, 1); 1050 em28xx_capture_start(dev, 1);
1014 1051
@@ -1094,7 +1131,7 @@ struct em28xx *em28xx_get_device(int minor,
1094 list_for_each_entry(h, &em28xx_devlist, devlist) { 1131 list_for_each_entry(h, &em28xx_devlist, devlist) {
1095 if (h->vdev->minor == minor) 1132 if (h->vdev->minor == minor)
1096 dev = h; 1133 dev = h;
1097 if (h->vbi_dev->minor == minor) { 1134 if (h->vbi_dev && h->vbi_dev->minor == minor) {
1098 dev = h; 1135 dev = h;
1099 *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; 1136 *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1100 } 1137 }
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d603575431b4..db749461e5c6 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -33,6 +33,7 @@
33#include "s5h1409.h" 33#include "s5h1409.h"
34#include "mt352.h" 34#include "mt352.h"
35#include "mt352_priv.h" /* FIXME */ 35#include "mt352_priv.h" /* FIXME */
36#include "tda1002x.h"
36 37
37MODULE_DESCRIPTION("driver for em28xx based DVB cards"); 38MODULE_DESCRIPTION("driver for em28xx based DVB cards");
38MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 39MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -295,6 +296,11 @@ static struct mt352_config terratec_xs_mt352_cfg = {
295 .demod_init = mt352_terratec_xs_init, 296 .demod_init = mt352_terratec_xs_init,
296}; 297};
297 298
299static struct tda10023_config em28xx_tda10023_config = {
300 .demod_address = 0x0c,
301 .invert = 1,
302};
303
298/* ------------------------------------------------------------------ */ 304/* ------------------------------------------------------------------ */
299 305
300static int attach_xc3028(u8 addr, struct em28xx *dev) 306static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -549,6 +555,19 @@ static int dvb_init(struct em28xx *dev)
549 } 555 }
550 break; 556 break;
551#endif 557#endif
558 case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
559 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
560 dvb->frontend = dvb_attach(tda10023_attach,
561 &em28xx_tda10023_config,
562 &dev->i2c_adap, 0x48);
563 if (dvb->frontend) {
564 if (!dvb_attach(simple_tuner_attach, dvb->frontend,
565 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
566 result = -EINVAL;
567 goto out_free;
568 }
569 }
570 break;
552 default: 571 default:
553 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" 572 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
554 " isn't supported yet\n", 573 " isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 6bf84bd787df..ed12e7ffcbd0 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -86,7 +86,19 @@
86#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b 86#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b
87 87
88#define EM28XX_R10_VINMODE 0x10 88#define EM28XX_R10_VINMODE 0x10
89
89#define EM28XX_R11_VINCTRL 0x11 90#define EM28XX_R11_VINCTRL 0x11
91
92/* em28xx Video Input Control Register 0x11 */
93#define EM28XX_VINCTRL_VBI_SLICED 0x80
94#define EM28XX_VINCTRL_VBI_RAW 0x40
95#define EM28XX_VINCTRL_VOUT_MODE_IN 0x20 /* HREF,VREF,VACT in output */
96#define EM28XX_VINCTRL_CCIR656_ENABLE 0x10
97#define EM28XX_VINCTRL_VBI_16BIT_RAW 0x08 /* otherwise 8-bit raw */
98#define EM28XX_VINCTRL_FID_ON_HREF 0x04
99#define EM28XX_VINCTRL_DUAL_EDGE_STROBE 0x02
100#define EM28XX_VINCTRL_INTERLACED 0x01
101
90#define EM28XX_R12_VINENABLE 0x12 /* */ 102#define EM28XX_R12_VINENABLE 0x12 /* */
91 103
92#define EM28XX_R14_GAMMA 0x14 104#define EM28XX_R14_GAMMA 0x14
@@ -135,6 +147,10 @@
135#define EM28XX_R31_HSCALEHIGH 0x31 147#define EM28XX_R31_HSCALEHIGH 0x31
136#define EM28XX_R32_VSCALELOW 0x32 148#define EM28XX_R32_VSCALELOW 0x32
137#define EM28XX_R33_VSCALEHIGH 0x33 149#define EM28XX_R33_VSCALEHIGH 0x33
150#define EM28XX_R34_VBI_START_H 0x34
151#define EM28XX_R35_VBI_START_V 0x35
152#define EM28XX_R36_VBI_WIDTH 0x36
153#define EM28XX_R37_VBI_HEIGHT 0x37
138 154
139#define EM28XX_R40_AC97LSB 0x40 155#define EM28XX_R40_AC97LSB 0x40
140#define EM28XX_R41_AC97MSB 0x41 156#define EM28XX_R41_AC97MSB 0x41
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
new file mode 100644
index 000000000000..94943e5a1529
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -0,0 +1,142 @@
1/*
2 em28xx-vbi.c - VBI driver for em28xx
3
4 Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
5
6 This work was sponsored by EyeMagnet Limited.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/slab.h>
28
29#include "em28xx.h"
30
31static unsigned int vbibufs = 5;
32module_param(vbibufs, int, 0644);
33MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
34
35static unsigned int vbi_debug;
36module_param(vbi_debug, int, 0644);
37MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
38
39#define dprintk(level, fmt, arg...) if (vbi_debug >= level) \
40 printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
41
42/* ------------------------------------------------------------------ */
43
44static void
45free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
46{
47 struct em28xx_fh *fh = vq->priv_data;
48 struct em28xx *dev = fh->dev;
49 unsigned long flags = 0;
50 if (in_interrupt())
51 BUG();
52
53 /* We used to wait for the buffer to finish here, but this didn't work
54 because, as we were keeping the state as VIDEOBUF_QUEUED,
55 videobuf_queue_cancel marked it as finished for us.
56 (Also, it could wedge forever if the hardware was misconfigured.)
57
58 This should be safe; by the time we get here, the buffer isn't
59 queued anymore. If we ever start marking the buffers as
60 VIDEOBUF_ACTIVE, it won't be, though.
61 */
62 spin_lock_irqsave(&dev->slock, flags);
63 if (dev->isoc_ctl.vbi_buf == buf)
64 dev->isoc_ctl.vbi_buf = NULL;
65 spin_unlock_irqrestore(&dev->slock, flags);
66
67 videobuf_vmalloc_free(&buf->vb);
68 buf->vb.state = VIDEOBUF_NEEDS_INIT;
69}
70
71static int
72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
73{
74 *size = 720 * 12 * 2;
75 if (0 == *count)
76 *count = vbibufs;
77 if (*count < 2)
78 *count = 2;
79 if (*count > 32)
80 *count = 32;
81 return 0;
82}
83
84static int
85vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
86 enum v4l2_field field)
87{
88 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
89 int rc = 0;
90 unsigned int size;
91
92 size = 720 * 12 * 2;
93
94 buf->vb.size = size;
95
96 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
97 return -EINVAL;
98
99 buf->vb.width = 720;
100 buf->vb.height = 12;
101 buf->vb.field = field;
102
103 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
104 rc = videobuf_iolock(q, &buf->vb, NULL);
105 if (rc < 0)
106 goto fail;
107 }
108
109 buf->vb.state = VIDEOBUF_PREPARED;
110 return 0;
111
112fail:
113 free_buffer(q, buf);
114 return rc;
115}
116
117static void
118vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
119{
120 struct em28xx_buffer *buf = container_of(vb,
121 struct em28xx_buffer,
122 vb);
123 struct em28xx_fh *fh = vq->priv_data;
124 struct em28xx *dev = fh->dev;
125 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
126
127 buf->vb.state = VIDEOBUF_QUEUED;
128 list_add_tail(&buf->vb.queue, &vbiq->active);
129}
130
131static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
132{
133 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
134 free_buffer(q, buf);
135}
136
137struct videobuf_queue_ops em28xx_vbi_qops = {
138 .buf_setup = vbi_setup,
139 .buf_prepare = vbi_prepare,
140 .buf_queue = vbi_queue,
141 .buf_release = vbi_release,
142};
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index a6bdbc21410e..3a1dfb7726f8 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -163,7 +163,24 @@ static inline void buffer_filled(struct em28xx *dev,
163 buf->vb.field_count++; 163 buf->vb.field_count++;
164 do_gettimeofday(&buf->vb.ts); 164 do_gettimeofday(&buf->vb.ts);
165 165
166 dev->isoc_ctl.buf = NULL; 166 dev->isoc_ctl.vid_buf = NULL;
167
168 list_del(&buf->vb.queue);
169 wake_up(&buf->vb.done);
170}
171
172static inline void vbi_buffer_filled(struct em28xx *dev,
173 struct em28xx_dmaqueue *dma_q,
174 struct em28xx_buffer *buf)
175{
176 /* Advice that buffer was filled */
177 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
178
179 buf->vb.state = VIDEOBUF_DONE;
180 buf->vb.field_count++;
181 do_gettimeofday(&buf->vb.ts);
182
183 dev->isoc_ctl.vbi_buf = NULL;
167 184
168 list_del(&buf->vb.queue); 185 list_del(&buf->vb.queue);
169 wake_up(&buf->vb.done); 186 wake_up(&buf->vb.done);
@@ -239,7 +256,8 @@ static void em28xx_copy_video(struct em28xx *dev,
239 256
240 if ((char *)startwrite + lencopy > (char *)outp + 257 if ((char *)startwrite + lencopy > (char *)outp +
241 buf->vb.size) { 258 buf->vb.size) {
242 em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", 259 em28xx_isocdbg("Overflow of %zi bytes past buffer end"
260 "(2)\n",
243 ((char *)startwrite + lencopy) - 261 ((char *)startwrite + lencopy) -
244 ((char *)outp + buf->vb.size)); 262 ((char *)outp + buf->vb.size));
245 lencopy = remain = (char *)outp + buf->vb.size - 263 lencopy = remain = (char *)outp + buf->vb.size -
@@ -256,6 +274,63 @@ static void em28xx_copy_video(struct em28xx *dev,
256 dma_q->pos += len; 274 dma_q->pos += len;
257} 275}
258 276
277static void em28xx_copy_vbi(struct em28xx *dev,
278 struct em28xx_dmaqueue *dma_q,
279 struct em28xx_buffer *buf,
280 unsigned char *p,
281 unsigned char *outp, unsigned long len)
282{
283 void *startwrite, *startread;
284 int offset;
285 int bytesperline = 720;
286
287 if (dev == NULL) {
288 em28xx_isocdbg("dev is null\n");
289 return;
290 }
291
292 if (dma_q == NULL) {
293 em28xx_isocdbg("dma_q is null\n");
294 return;
295 }
296 if (buf == NULL) {
297 return;
298 }
299 if (p == NULL) {
300 em28xx_isocdbg("p is null\n");
301 return;
302 }
303 if (outp == NULL) {
304 em28xx_isocdbg("outp is null\n");
305 return;
306 }
307
308 if (dma_q->pos + len > buf->vb.size)
309 len = buf->vb.size - dma_q->pos;
310
311 if ((p[0] == 0x33 && p[1] == 0x95) ||
312 (p[0] == 0x88 && p[1] == 0x88)) {
313 /* Header field, advance past it */
314 p += 4;
315 } else {
316 len += 4;
317 }
318
319 startread = p;
320
321 startwrite = outp + dma_q->pos;
322 offset = dma_q->pos;
323
324 /* Make sure the bottom field populates the second half of the frame */
325 if (buf->top_field == 0) {
326 startwrite += bytesperline * 0x0c;
327 offset += bytesperline * 0x0c;
328 }
329
330 memcpy(startwrite, startread, len);
331 dma_q->pos += len;
332}
333
259static inline void print_err_status(struct em28xx *dev, 334static inline void print_err_status(struct em28xx *dev,
260 int packet, int status) 335 int packet, int status)
261{ 336{
@@ -306,7 +381,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
306 381
307 if (list_empty(&dma_q->active)) { 382 if (list_empty(&dma_q->active)) {
308 em28xx_isocdbg("No active queue to serve\n"); 383 em28xx_isocdbg("No active queue to serve\n");
309 dev->isoc_ctl.buf = NULL; 384 dev->isoc_ctl.vid_buf = NULL;
310 *buf = NULL; 385 *buf = NULL;
311 return; 386 return;
312 } 387 }
@@ -318,7 +393,34 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
318 outp = videobuf_to_vmalloc(&(*buf)->vb); 393 outp = videobuf_to_vmalloc(&(*buf)->vb);
319 memset(outp, 0, (*buf)->vb.size); 394 memset(outp, 0, (*buf)->vb.size);
320 395
321 dev->isoc_ctl.buf = *buf; 396 dev->isoc_ctl.vid_buf = *buf;
397
398 return;
399}
400
401/*
402 * video-buf generic routine to get the next available VBI buffer
403 */
404static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q,
405 struct em28xx_buffer **buf)
406{
407 struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq);
408 char *outp;
409
410 if (list_empty(&dma_q->active)) {
411 em28xx_isocdbg("No active queue to serve\n");
412 dev->isoc_ctl.vbi_buf = NULL;
413 *buf = NULL;
414 return;
415 }
416
417 /* Get the next buffer */
418 *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
419 /* Cleans up buffer - Usefull for testing for frame/URB loss */
420 outp = videobuf_to_vmalloc(&(*buf)->vb);
421 memset(outp, 0x00, (*buf)->vb.size);
422
423 dev->isoc_ctl.vbi_buf = *buf;
322 424
323 return; 425 return;
324} 426}
@@ -329,7 +431,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
329static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) 431static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
330{ 432{
331 struct em28xx_buffer *buf; 433 struct em28xx_buffer *buf;
332 struct em28xx_dmaqueue *dma_q = urb->context; 434 struct em28xx_dmaqueue *dma_q = &dev->vidq;
333 unsigned char *outp = NULL; 435 unsigned char *outp = NULL;
334 int i, len = 0, rc = 1; 436 int i, len = 0, rc = 1;
335 unsigned char *p; 437 unsigned char *p;
@@ -346,7 +448,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
346 return 0; 448 return 0;
347 } 449 }
348 450
349 buf = dev->isoc_ctl.buf; 451 buf = dev->isoc_ctl.vid_buf;
350 if (buf != NULL) 452 if (buf != NULL)
351 outp = videobuf_to_vmalloc(&buf->vb); 453 outp = videobuf_to_vmalloc(&buf->vb);
352 454
@@ -410,6 +512,153 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
410 return rc; 512 return rc;
411} 513}
412 514
515/* Version of isoc handler that takes into account a mixture of video and
516 VBI data */
517static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
518{
519 struct em28xx_buffer *buf, *vbi_buf;
520 struct em28xx_dmaqueue *dma_q = &dev->vidq;
521 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
522 unsigned char *outp = NULL;
523 unsigned char *vbioutp = NULL;
524 int i, len = 0, rc = 1;
525 unsigned char *p;
526 int vbi_size;
527
528 if (!dev)
529 return 0;
530
531 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
532 return 0;
533
534 if (urb->status < 0) {
535 print_err_status(dev, -1, urb->status);
536 if (urb->status == -ENOENT)
537 return 0;
538 }
539
540 buf = dev->isoc_ctl.vid_buf;
541 if (buf != NULL)
542 outp = videobuf_to_vmalloc(&buf->vb);
543
544 vbi_buf = dev->isoc_ctl.vbi_buf;
545 if (vbi_buf != NULL)
546 vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
547
548 for (i = 0; i < urb->number_of_packets; i++) {
549 int status = urb->iso_frame_desc[i].status;
550
551 if (status < 0) {
552 print_err_status(dev, i, status);
553 if (urb->iso_frame_desc[i].status != -EPROTO)
554 continue;
555 }
556
557 len = urb->iso_frame_desc[i].actual_length - 4;
558
559 if (urb->iso_frame_desc[i].actual_length <= 0) {
560 /* em28xx_isocdbg("packet %d is empty",i); - spammy */
561 continue;
562 }
563 if (urb->iso_frame_desc[i].actual_length >
564 dev->max_pkt_size) {
565 em28xx_isocdbg("packet bigger than packet size");
566 continue;
567 }
568
569 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
570
571 /* capture type 0 = vbi start
572 capture type 1 = video start
573 capture type 2 = video in progress */
574 if (p[0] == 0x33 && p[1] == 0x95) {
575 dev->capture_type = 0;
576 dev->vbi_read = 0;
577 em28xx_isocdbg("VBI START HEADER!!!\n");
578 dev->cur_field = p[2];
579 }
580
581 /* FIXME: get rid of hard-coded value */
582 vbi_size = 720 * 0x0c;
583
584 if (dev->capture_type == 0) {
585 if (dev->vbi_read >= vbi_size) {
586 /* We've already read all the VBI data, so
587 treat the rest as video */
588 em28xx_isocdbg("dev->vbi_read > vbi_size\n");
589 } else if ((dev->vbi_read + len) < vbi_size) {
590 /* This entire frame is VBI data */
591 if (dev->vbi_read == 0 &&
592 (!(dev->cur_field & 1))) {
593 /* Brand new frame */
594 if (vbi_buf != NULL)
595 vbi_buffer_filled(dev,
596 vbi_dma_q,
597 vbi_buf);
598 vbi_get_next_buf(vbi_dma_q, &vbi_buf);
599 if (vbi_buf == NULL)
600 vbioutp = NULL;
601 else
602 vbioutp = videobuf_to_vmalloc(
603 &vbi_buf->vb);
604 }
605
606 if (dev->vbi_read == 0) {
607 vbi_dma_q->pos = 0;
608 if (vbi_buf != NULL) {
609 if (dev->cur_field & 1)
610 vbi_buf->top_field = 0;
611 else
612 vbi_buf->top_field = 1;
613 }
614 }
615
616 dev->vbi_read += len;
617 em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
618 vbioutp, len);
619 } else {
620 /* Some of this frame is VBI data and some is
621 video data */
622 int vbi_data_len = vbi_size - dev->vbi_read;
623 dev->vbi_read += vbi_data_len;
624 em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
625 vbioutp, vbi_data_len);
626 dev->capture_type = 1;
627 p += vbi_data_len;
628 len -= vbi_data_len;
629 }
630 }
631
632 if (dev->capture_type == 1) {
633 dev->capture_type = 2;
634 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
635 len, (p[2] & 1) ? "odd" : "even");
636
637 if (dev->progressive || !(dev->cur_field & 1)) {
638 if (buf != NULL)
639 buffer_filled(dev, dma_q, buf);
640 get_next_buf(dma_q, &buf);
641 if (buf == NULL)
642 outp = NULL;
643 else
644 outp = videobuf_to_vmalloc(&buf->vb);
645 }
646 if (buf != NULL) {
647 if (dev->cur_field & 1)
648 buf->top_field = 0;
649 else
650 buf->top_field = 1;
651 }
652
653 dma_q->pos = 0;
654 }
655 if (buf != NULL && dev->capture_type == 2)
656 em28xx_copy_video(dev, dma_q, buf, p, outp, len);
657 }
658 return rc;
659}
660
661
413/* ------------------------------------------------------------------ 662/* ------------------------------------------------------------------
414 Videobuf operations 663 Videobuf operations
415 ------------------------------------------------------------------*/ 664 ------------------------------------------------------------------*/
@@ -421,7 +670,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
421 struct em28xx *dev = fh->dev; 670 struct em28xx *dev = fh->dev;
422 struct v4l2_frequency f; 671 struct v4l2_frequency f;
423 672
424 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; 673 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
674 >> 3;
425 675
426 if (0 == *count) 676 if (0 == *count)
427 *count = EM28XX_DEF_BUF; 677 *count = EM28XX_DEF_BUF;
@@ -458,8 +708,8 @@ static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
458 VIDEOBUF_ACTIVE, it won't be, though. 708 VIDEOBUF_ACTIVE, it won't be, though.
459 */ 709 */
460 spin_lock_irqsave(&dev->slock, flags); 710 spin_lock_irqsave(&dev->slock, flags);
461 if (dev->isoc_ctl.buf == buf) 711 if (dev->isoc_ctl.vid_buf == buf)
462 dev->isoc_ctl.buf = NULL; 712 dev->isoc_ctl.vid_buf = NULL;
463 spin_unlock_irqrestore(&dev->slock, flags); 713 spin_unlock_irqrestore(&dev->slock, flags);
464 714
465 videobuf_vmalloc_free(&buf->vb); 715 videobuf_vmalloc_free(&buf->vb);
@@ -475,7 +725,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
475 struct em28xx *dev = fh->dev; 725 struct em28xx *dev = fh->dev;
476 int rc = 0, urb_init = 0; 726 int rc = 0, urb_init = 0;
477 727
478 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; 728 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
729 + 7) >> 3;
479 730
480 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 731 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
481 return -EINVAL; 732 return -EINVAL;
@@ -494,9 +745,16 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
494 urb_init = 1; 745 urb_init = 1;
495 746
496 if (urb_init) { 747 if (urb_init) {
497 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 748 if (em28xx_vbi_supported(dev) == 1)
498 EM28XX_NUM_BUFS, dev->max_pkt_size, 749 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
499 em28xx_isoc_copy); 750 EM28XX_NUM_BUFS,
751 dev->max_pkt_size,
752 em28xx_isoc_copy_vbi);
753 else
754 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
755 EM28XX_NUM_BUFS,
756 dev->max_pkt_size,
757 em28xx_isoc_copy);
500 if (rc < 0) 758 if (rc < 0)
501 goto fail; 759 goto fail;
502 } 760 }
@@ -578,34 +836,63 @@ static void video_mux(struct em28xx *dev, int index)
578} 836}
579 837
580/* Usage lock check functions */ 838/* Usage lock check functions */
581static int res_get(struct em28xx_fh *fh) 839static int res_get(struct em28xx_fh *fh, unsigned int bit)
582{ 840{
583 struct em28xx *dev = fh->dev; 841 struct em28xx *dev = fh->dev;
584 int rc = 0;
585 842
586 /* This instance already has stream_on */ 843 if (fh->resources & bit)
587 if (fh->stream_on) 844 /* have it already allocated */
588 return rc; 845 return 1;
589 846
590 if (dev->stream_on) 847 /* is it free? */
591 return -EBUSY; 848 mutex_lock(&dev->lock);
849 if (dev->resources & bit) {
850 /* no, someone else uses it */
851 mutex_unlock(&dev->lock);
852 return 0;
853 }
854 /* it's free, grab it */
855 fh->resources |= bit;
856 dev->resources |= bit;
857 em28xx_videodbg("res: get %d\n", bit);
858 mutex_unlock(&dev->lock);
859 return 1;
860}
592 861
593 dev->stream_on = 1; 862static int res_check(struct em28xx_fh *fh, unsigned int bit)
594 fh->stream_on = 1; 863{
595 return rc; 864 return fh->resources & bit;
596} 865}
597 866
598static int res_check(struct em28xx_fh *fh) 867static int res_locked(struct em28xx *dev, unsigned int bit)
599{ 868{
600 return fh->stream_on; 869 return dev->resources & bit;
601} 870}
602 871
603static void res_free(struct em28xx_fh *fh) 872static void res_free(struct em28xx_fh *fh, unsigned int bits)
604{ 873{
605 struct em28xx *dev = fh->dev; 874 struct em28xx *dev = fh->dev;
606 875
607 fh->stream_on = 0; 876 BUG_ON((fh->resources & bits) != bits);
608 dev->stream_on = 0; 877
878 mutex_lock(&dev->lock);
879 fh->resources &= ~bits;
880 dev->resources &= ~bits;
881 em28xx_videodbg("res: put %d\n", bits);
882 mutex_unlock(&dev->lock);
883}
884
885static int get_ressource(struct em28xx_fh *fh)
886{
887 switch (fh->type) {
888 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
889 return EM28XX_RESOURCE_VIDEO;
890 case V4L2_BUF_TYPE_VBI_CAPTURE:
891 return EM28XX_RESOURCE_VBI;
892 default:
893 BUG();
894 return 0;
895 }
609} 896}
610 897
611/* 898/*
@@ -782,7 +1069,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
782 } else { 1069 } else {
783 /* width must even because of the YUYV format 1070 /* width must even because of the YUYV format
784 height must be even because of interlacing */ 1071 height must be even because of interlacing */
785 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); 1072 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1073 1, 0);
786 } 1074 }
787 1075
788 get_scale(dev, width, height, &hscale, &vscale); 1076 get_scale(dev, width, height, &hscale, &vscale);
@@ -848,12 +1136,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
848 goto out; 1136 goto out;
849 } 1137 }
850 1138
851 if (dev->stream_on && !fh->stream_on) {
852 em28xx_errdev("%s device in use by another fh\n", __func__);
853 rc = -EBUSY;
854 goto out;
855 }
856
857 rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat, 1139 rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
858 f->fmt.pix.width, f->fmt.pix.height); 1140 f->fmt.pix.width, f->fmt.pix.height);
859 1141
@@ -862,6 +1144,21 @@ out:
862 return rc; 1144 return rc;
863} 1145}
864 1146
1147static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1148{
1149 struct em28xx_fh *fh = priv;
1150 struct em28xx *dev = fh->dev;
1151 int rc;
1152
1153 rc = check_dev(dev);
1154 if (rc < 0)
1155 return rc;
1156
1157 *norm = dev->norm;
1158
1159 return 0;
1160}
1161
865static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) 1162static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
866{ 1163{
867 struct em28xx_fh *fh = priv; 1164 struct em28xx_fh *fh = priv;
@@ -1413,20 +1710,25 @@ static int vidioc_streamon(struct file *file, void *priv,
1413{ 1710{
1414 struct em28xx_fh *fh = priv; 1711 struct em28xx_fh *fh = priv;
1415 struct em28xx *dev = fh->dev; 1712 struct em28xx *dev = fh->dev;
1416 int rc; 1713 int rc = -EINVAL;
1417 1714
1418 rc = check_dev(dev); 1715 rc = check_dev(dev);
1419 if (rc < 0) 1716 if (rc < 0)
1420 return rc; 1717 return rc;
1421 1718
1719 if (unlikely(type != fh->type))
1720 return -EINVAL;
1422 1721
1423 mutex_lock(&dev->lock); 1722 em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
1424 rc = res_get(fh); 1723 fh, type, fh->resources, dev->resources);
1425 1724
1426 if (likely(rc >= 0)) 1725 if (unlikely(!res_get(fh, get_ressource(fh))))
1427 rc = videobuf_streamon(&fh->vb_vidq); 1726 return -EBUSY;
1428 1727
1429 mutex_unlock(&dev->lock); 1728 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1729 rc = videobuf_streamon(&fh->vb_vidq);
1730 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1731 rc = videobuf_streamon(&fh->vb_vbiq);
1430 1732
1431 return rc; 1733 return rc;
1432} 1734}
@@ -1442,17 +1744,22 @@ static int vidioc_streamoff(struct file *file, void *priv,
1442 if (rc < 0) 1744 if (rc < 0)
1443 return rc; 1745 return rc;
1444 1746
1445 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1747 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1748 fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
1446 return -EINVAL; 1749 return -EINVAL;
1447 if (type != fh->type) 1750 if (type != fh->type)
1448 return -EINVAL; 1751 return -EINVAL;
1449 1752
1450 mutex_lock(&dev->lock); 1753 em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
1754 fh, type, fh->resources, dev->resources);
1451 1755
1452 videobuf_streamoff(&fh->vb_vidq); 1756 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1453 res_free(fh); 1757 videobuf_streamoff(&fh->vb_vidq);
1454 1758 res_free(fh, EM28XX_RESOURCE_VIDEO);
1455 mutex_unlock(&dev->lock); 1759 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1760 videobuf_streamoff(&fh->vb_vbiq);
1761 res_free(fh, EM28XX_RESOURCE_VBI);
1762 }
1456 1763
1457 return 0; 1764 return 0;
1458} 1765}
@@ -1474,6 +1781,9 @@ static int vidioc_querycap(struct file *file, void *priv,
1474 V4L2_CAP_VIDEO_CAPTURE | 1781 V4L2_CAP_VIDEO_CAPTURE |
1475 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 1782 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1476 1783
1784 if (dev->vbi_dev)
1785 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
1786
1477 if (dev->audio_mode.has_audio) 1787 if (dev->audio_mode.has_audio)
1478 cap->capabilities |= V4L2_CAP_AUDIO; 1788 cap->capabilities |= V4L2_CAP_AUDIO;
1479 1789
@@ -1541,6 +1851,45 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1541 return 0; 1851 return 0;
1542} 1852}
1543 1853
1854/* RAW VBI ioctls */
1855
1856static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1857 struct v4l2_format *format)
1858{
1859 format->fmt.vbi.samples_per_line = 720;
1860 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1861 format->fmt.vbi.offset = 0;
1862 format->fmt.vbi.flags = 0;
1863
1864 /* Varies by video standard (NTSC, PAL, etc.) */
1865 /* FIXME: hard-coded for NTSC support */
1866 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
1867 format->fmt.vbi.count[0] = 12;
1868 format->fmt.vbi.count[1] = 12;
1869 format->fmt.vbi.start[0] = 10;
1870 format->fmt.vbi.start[1] = 273;
1871
1872 return 0;
1873}
1874
1875static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
1876 struct v4l2_format *format)
1877{
1878 format->fmt.vbi.samples_per_line = 720;
1879 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1880 format->fmt.vbi.offset = 0;
1881 format->fmt.vbi.flags = 0;
1882
1883 /* Varies by video standard (NTSC, PAL, etc.) */
1884 /* FIXME: hard-coded for NTSC support */
1885 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
1886 format->fmt.vbi.count[0] = 12;
1887 format->fmt.vbi.count[1] = 12;
1888 format->fmt.vbi.start[0] = 10;
1889 format->fmt.vbi.start[1] = 273;
1890
1891 return 0;
1892}
1544 1893
1545static int vidioc_reqbufs(struct file *file, void *priv, 1894static int vidioc_reqbufs(struct file *file, void *priv,
1546 struct v4l2_requestbuffers *rb) 1895 struct v4l2_requestbuffers *rb)
@@ -1553,7 +1902,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1553 if (rc < 0) 1902 if (rc < 0)
1554 return rc; 1903 return rc;
1555 1904
1556 return videobuf_reqbufs(&fh->vb_vidq, rb); 1905 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1906 return videobuf_reqbufs(&fh->vb_vidq, rb);
1907 else
1908 return videobuf_reqbufs(&fh->vb_vbiq, rb);
1557} 1909}
1558 1910
1559static int vidioc_querybuf(struct file *file, void *priv, 1911static int vidioc_querybuf(struct file *file, void *priv,
@@ -1567,7 +1919,18 @@ static int vidioc_querybuf(struct file *file, void *priv,
1567 if (rc < 0) 1919 if (rc < 0)
1568 return rc; 1920 return rc;
1569 1921
1570 return videobuf_querybuf(&fh->vb_vidq, b); 1922 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1923 return videobuf_querybuf(&fh->vb_vidq, b);
1924 else {
1925 /* FIXME: I'm not sure yet whether this is a bug in zvbi or
1926 the videobuf framework, but we probably shouldn't be
1927 returning a buffer larger than that which was asked for.
1928 At a minimum, it causes a crash in zvbi since it does
1929 a memcpy based on the source buffer length */
1930 int result = videobuf_querybuf(&fh->vb_vbiq, b);
1931 b->length = 17280;
1932 return result;
1933 }
1571} 1934}
1572 1935
1573static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1936static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1580,7 +1943,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1580 if (rc < 0) 1943 if (rc < 0)
1581 return rc; 1944 return rc;
1582 1945
1583 return videobuf_qbuf(&fh->vb_vidq, b); 1946 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1947 return videobuf_qbuf(&fh->vb_vidq, b);
1948 else
1949 return videobuf_qbuf(&fh->vb_vbiq, b);
1584} 1950}
1585 1951
1586static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1952static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1593,7 +1959,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1593 if (rc < 0) 1959 if (rc < 0)
1594 return rc; 1960 return rc;
1595 1961
1596 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); 1962 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1963 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags &
1964 O_NONBLOCK);
1965 else
1966 return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags &
1967 O_NONBLOCK);
1597} 1968}
1598 1969
1599#ifdef CONFIG_VIDEO_V4L1_COMPAT 1970#ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1601,7 +1972,10 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1601{ 1972{
1602 struct em28xx_fh *fh = priv; 1973 struct em28xx_fh *fh = priv;
1603 1974
1604 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); 1975 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1976 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1977 else
1978 return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8);
1605} 1979}
1606#endif 1980#endif
1607 1981
@@ -1766,8 +2140,15 @@ static int em28xx_v4l2_open(struct file *filp)
1766 field = V4L2_FIELD_INTERLACED; 2140 field = V4L2_FIELD_INTERLACED;
1767 2141
1768 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, 2142 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
1769 NULL, &dev->slock, fh->type, field, 2143 NULL, &dev->slock,
1770 sizeof(struct em28xx_buffer), fh); 2144 V4L2_BUF_TYPE_VIDEO_CAPTURE, field,
2145 sizeof(struct em28xx_buffer), fh);
2146
2147 videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops,
2148 NULL, &dev->slock,
2149 V4L2_BUF_TYPE_VBI_CAPTURE,
2150 V4L2_FIELD_SEQ_TB,
2151 sizeof(struct em28xx_buffer), fh);
1771 2152
1772 mutex_unlock(&dev->lock); 2153 mutex_unlock(&dev->lock);
1773 2154
@@ -1824,20 +2205,21 @@ static int em28xx_v4l2_close(struct file *filp)
1824 2205
1825 em28xx_videodbg("users=%d\n", dev->users); 2206 em28xx_videodbg("users=%d\n", dev->users);
1826 2207
2208 if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
2209 videobuf_stop(&fh->vb_vidq);
2210 res_free(fh, EM28XX_RESOURCE_VIDEO);
2211 }
1827 2212
1828 mutex_lock(&dev->lock); 2213 if (res_check(fh, EM28XX_RESOURCE_VBI)) {
1829 if (res_check(fh)) 2214 videobuf_stop(&fh->vb_vbiq);
1830 res_free(fh); 2215 res_free(fh, EM28XX_RESOURCE_VBI);
2216 }
1831 2217
1832 if (dev->users == 1) { 2218 if (dev->users == 1) {
1833 videobuf_stop(&fh->vb_vidq);
1834 videobuf_mmap_free(&fh->vb_vidq);
1835
1836 /* the device is already disconnect, 2219 /* the device is already disconnect,
1837 free the remaining resources */ 2220 free the remaining resources */
1838 if (dev->state & DEV_DISCONNECTED) { 2221 if (dev->state & DEV_DISCONNECTED) {
1839 em28xx_release_resources(dev); 2222 em28xx_release_resources(dev);
1840 mutex_unlock(&dev->lock);
1841 kfree(dev); 2223 kfree(dev);
1842 return 0; 2224 return 0;
1843 } 2225 }
@@ -1858,10 +2240,12 @@ static int em28xx_v4l2_close(struct file *filp)
1858 "0 (error=%i)\n", errCode); 2240 "0 (error=%i)\n", errCode);
1859 } 2241 }
1860 } 2242 }
2243
2244 videobuf_mmap_free(&fh->vb_vidq);
2245 videobuf_mmap_free(&fh->vb_vbiq);
1861 kfree(fh); 2246 kfree(fh);
1862 dev->users--; 2247 dev->users--;
1863 wake_up_interruptible_nr(&dev->open, 1); 2248 wake_up_interruptible_nr(&dev->open, 1);
1864 mutex_unlock(&dev->lock);
1865 return 0; 2249 return 0;
1866} 2250}
1867 2251
@@ -1886,16 +2270,22 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
1886 */ 2270 */
1887 2271
1888 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 2272 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1889 mutex_lock(&dev->lock); 2273 if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
1890 rc = res_get(fh); 2274 return -EBUSY;
1891 mutex_unlock(&dev->lock);
1892
1893 if (unlikely(rc < 0))
1894 return rc;
1895 2275
1896 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, 2276 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
1897 filp->f_flags & O_NONBLOCK); 2277 filp->f_flags & O_NONBLOCK);
1898 } 2278 }
2279
2280
2281 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2282 if (!res_get(fh, EM28XX_RESOURCE_VBI))
2283 return -EBUSY;
2284
2285 return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
2286 filp->f_flags & O_NONBLOCK);
2287 }
2288
1899 return 0; 2289 return 0;
1900} 2290}
1901 2291
@@ -1913,17 +2303,17 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
1913 if (rc < 0) 2303 if (rc < 0)
1914 return rc; 2304 return rc;
1915 2305
1916 mutex_lock(&dev->lock); 2306 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1917 rc = res_get(fh); 2307 if (!res_get(fh, EM28XX_RESOURCE_VIDEO))
1918 mutex_unlock(&dev->lock); 2308 return POLLERR;
1919 2309 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1920 if (unlikely(rc < 0)) 2310 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1921 return POLLERR; 2311 if (!res_get(fh, EM28XX_RESOURCE_VBI))
1922 2312 return POLLERR;
1923 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 2313 return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
2314 } else {
1924 return POLLERR; 2315 return POLLERR;
1925 2316 }
1926 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1927} 2317}
1928 2318
1929/* 2319/*
@@ -1939,14 +2329,10 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
1939 if (rc < 0) 2329 if (rc < 0)
1940 return rc; 2330 return rc;
1941 2331
1942 mutex_lock(&dev->lock); 2332 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1943 rc = res_get(fh); 2333 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1944 mutex_unlock(&dev->lock); 2334 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1945 2335 rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
1946 if (unlikely(rc < 0))
1947 return rc;
1948
1949 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1950 2336
1951 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", 2337 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
1952 (unsigned long)vma->vm_start, 2338 (unsigned long)vma->vm_start,
@@ -1972,6 +2358,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1972 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 2358 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1973 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 2359 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1974 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 2360 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
2361 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
2362 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1975 .vidioc_g_audio = vidioc_g_audio, 2363 .vidioc_g_audio = vidioc_g_audio,
1976 .vidioc_s_audio = vidioc_s_audio, 2364 .vidioc_s_audio = vidioc_s_audio,
1977 .vidioc_cropcap = vidioc_cropcap, 2365 .vidioc_cropcap = vidioc_cropcap,
@@ -1984,6 +2372,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1984 .vidioc_querybuf = vidioc_querybuf, 2372 .vidioc_querybuf = vidioc_querybuf,
1985 .vidioc_qbuf = vidioc_qbuf, 2373 .vidioc_qbuf = vidioc_qbuf,
1986 .vidioc_dqbuf = vidioc_dqbuf, 2374 .vidioc_dqbuf = vidioc_dqbuf,
2375 .vidioc_g_std = vidioc_g_std,
1987 .vidioc_s_std = vidioc_s_std, 2376 .vidioc_s_std = vidioc_s_std,
1988 .vidioc_g_parm = vidioc_g_parm, 2377 .vidioc_g_parm = vidioc_g_parm,
1989 .vidioc_s_parm = vidioc_s_parm, 2378 .vidioc_s_parm = vidioc_s_parm,
@@ -2105,13 +2494,10 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2105 dev->mute = 1; 2494 dev->mute = 1;
2106 dev->volume = 0x1f; 2495 dev->volume = 0x1f;
2107 2496
2108 /* enable vbi capturing */
2109
2110/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ 2497/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
2111 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); 2498 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2112 em28xx_write_reg(dev, EM28XX_R0F_XCLK, 2499 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2113 (EM28XX_XCLK_AUDIO_UNMUTE | val)); 2500 (EM28XX_XCLK_AUDIO_UNMUTE | val));
2114 em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
2115 2501
2116 em28xx_set_outfmt(dev); 2502 em28xx_set_outfmt(dev);
2117 em28xx_colorlevels_set_default(dev); 2503 em28xx_colorlevels_set_default(dev);
@@ -2134,14 +2520,17 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2134 } 2520 }
2135 2521
2136 /* Allocate and fill vbi video_device struct */ 2522 /* Allocate and fill vbi video_device struct */
2137 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); 2523 if (em28xx_vbi_supported(dev) == 1) {
2524 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2525 "vbi");
2138 2526
2139 /* register v4l2 vbi video_device */ 2527 /* register v4l2 vbi video_device */
2140 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, 2528 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2141 vbi_nr[dev->devno]); 2529 vbi_nr[dev->devno]);
2142 if (ret < 0) { 2530 if (ret < 0) {
2143 em28xx_errdev("unable to register vbi device\n"); 2531 em28xx_errdev("unable to register vbi device\n");
2144 return ret; 2532 return ret;
2533 }
2145 } 2534 }
2146 2535
2147 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { 2536 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
@@ -2161,8 +2550,12 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2161 dev->radio_dev->num); 2550 dev->radio_dev->num);
2162 } 2551 }
2163 2552
2164 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", 2553 em28xx_info("V4L2 video device registered as /dev/video%d\n",
2165 dev->vdev->num, dev->vbi_dev->num); 2554 dev->vdev->num);
2555
2556 if (dev->vbi_dev)
2557 em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n",
2558 dev->vbi_dev->num);
2166 2559
2167 return 0; 2560 return 0;
2168} 2561}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 0f2ba9a40d17..0a73e8bf0d6e 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -109,6 +109,7 @@
109#define EM2882_BOARD_EVGA_INDTUBE 70 109#define EM2882_BOARD_EVGA_INDTUBE 70
110#define EM2820_BOARD_SILVERCREST_WEBCAM 71 110#define EM2820_BOARD_SILVERCREST_WEBCAM 71
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72 111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
112 113
113/* Limits minimum and default number of buffers */ 114/* Limits minimum and default number of buffers */
114#define EM28XX_MIN_BUF 4 115#define EM28XX_MIN_BUF 4
@@ -214,7 +215,8 @@ struct em28xx_usb_isoc_ctl {
214 int tmp_buf_len; 215 int tmp_buf_len;
215 216
216 /* Stores already requested buffers */ 217 /* Stores already requested buffers */
217 struct em28xx_buffer *buf; 218 struct em28xx_buffer *vid_buf;
219 struct em28xx_buffer *vbi_buf;
218 220
219 /* Stores the number of received fields */ 221 /* Stores the number of received fields */
220 int nfields; 222 int nfields;
@@ -443,6 +445,10 @@ enum em28xx_dev_state {
443#define EM28XX_AUDIO 0x10 445#define EM28XX_AUDIO 0x10
444#define EM28XX_DVB 0x20 446#define EM28XX_DVB 0x20
445 447
448/* em28xx resource types (used for res_get/res_lock etc */
449#define EM28XX_RESOURCE_VIDEO 0x01
450#define EM28XX_RESOURCE_VBI 0x02
451
446struct em28xx_audio { 452struct em28xx_audio {
447 char name[50]; 453 char name[50];
448 char *transfer_buffer[EM28XX_AUDIO_BUFS]; 454 char *transfer_buffer[EM28XX_AUDIO_BUFS];
@@ -463,10 +469,11 @@ struct em28xx;
463 469
464struct em28xx_fh { 470struct em28xx_fh {
465 struct em28xx *dev; 471 struct em28xx *dev;
466 unsigned int stream_on:1; /* Locks streams */
467 int radio; 472 int radio;
473 unsigned int resources;
468 474
469 struct videobuf_queue vb_vidq; 475 struct videobuf_queue vb_vidq;
476 struct videobuf_queue vb_vbiq;
470 477
471 enum v4l2_buf_type type; 478 enum v4l2_buf_type type;
472}; 479};
@@ -493,7 +500,6 @@ struct em28xx {
493 /* Vinmode/Vinctl used at the driver */ 500 /* Vinmode/Vinctl used at the driver */
494 int vinmode, vinctl; 501 int vinmode, vinctl;
495 502
496 unsigned int stream_on:1; /* Locks streams */
497 unsigned int has_audio_class:1; 503 unsigned int has_audio_class:1;
498 unsigned int has_alsa_audio:1; 504 unsigned int has_alsa_audio:1;
499 505
@@ -544,6 +550,12 @@ struct em28xx {
544 enum em28xx_dev_state state; 550 enum em28xx_dev_state state;
545 enum em28xx_io_method io; 551 enum em28xx_io_method io;
546 552
553 /* vbi related state tracking */
554 int capture_type;
555 int vbi_read;
556 unsigned char cur_field;
557
558
547 struct work_struct request_module_wk; 559 struct work_struct request_module_wk;
548 560
549 /* locks */ 561 /* locks */
@@ -555,10 +567,14 @@ struct em28xx {
555 struct video_device *vbi_dev; 567 struct video_device *vbi_dev;
556 struct video_device *radio_dev; 568 struct video_device *radio_dev;
557 569
570 /* resources in use */
571 unsigned int resources;
572
558 unsigned char eedata[256]; 573 unsigned char eedata[256];
559 574
560 /* Isoc control struct */ 575 /* Isoc control struct */
561 struct em28xx_dmaqueue vidq; 576 struct em28xx_dmaqueue vidq;
577 struct em28xx_dmaqueue vbiq;
562 struct em28xx_usb_isoc_ctl isoc_ctl; 578 struct em28xx_usb_isoc_ctl isoc_ctl;
563 spinlock_t slock; 579 spinlock_t slock;
564 580
@@ -639,6 +655,7 @@ int em28xx_audio_setup(struct em28xx *dev);
639 655
640int em28xx_colorlevels_set_default(struct em28xx *dev); 656int em28xx_colorlevels_set_default(struct em28xx *dev);
641int em28xx_capture_start(struct em28xx *dev, int start); 657int em28xx_capture_start(struct em28xx *dev, int start);
658int em28xx_vbi_supported(struct em28xx *dev);
642int em28xx_set_outfmt(struct em28xx *dev); 659int em28xx_set_outfmt(struct em28xx *dev);
643int em28xx_resolution_set(struct em28xx *dev); 660int em28xx_resolution_set(struct em28xx *dev);
644int em28xx_set_alternate(struct em28xx *dev); 661int em28xx_set_alternate(struct em28xx *dev);
@@ -686,6 +703,9 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev);
686int em28xx_ir_init(struct em28xx *dev); 703int em28xx_ir_init(struct em28xx *dev);
687int em28xx_ir_fini(struct em28xx *dev); 704int em28xx_ir_fini(struct em28xx *dev);
688 705
706/* Provided by em28xx-vbi.c */
707extern struct videobuf_queue_ops em28xx_vbi_qops;
708
689/* printk macros */ 709/* printk macros */
690 710
691#define em28xx_err(fmt, arg...) do {\ 711#define em28xx_err(fmt, arg...) do {\
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index d1c1e457f0b9..74092f436be6 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1379,8 +1379,10 @@ et61x251_read(struct file* filp, char __user * buf,
1379 (!list_empty(&cam->outqueue)) || 1379 (!list_empty(&cam->outqueue)) ||
1380 (cam->state & DEV_DISCONNECTED) || 1380 (cam->state & DEV_DISCONNECTED) ||
1381 (cam->state & DEV_MISCONFIGURED), 1381 (cam->state & DEV_MISCONFIGURED),
1382 cam->module_param.frame_timeout * 1382 msecs_to_jiffies(
1383 1000 * msecs_to_jiffies(1) ); 1383 cam->module_param.frame_timeout * 1000
1384 )
1385 );
1384 if (timeout < 0) { 1386 if (timeout < 0) {
1385 mutex_unlock(&cam->fileop_mutex); 1387 mutex_unlock(&cam->fileop_mutex);
1386 return timeout; 1388 return timeout;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 8897283b0bb4..fe2e490ebc52 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -19,6 +19,7 @@ if USB_GSPCA && VIDEO_V4L2
19 19
20source "drivers/media/video/gspca/m5602/Kconfig" 20source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig" 21source "drivers/media/video/gspca/stv06xx/Kconfig"
22source "drivers/media/video/gspca/gl860/Kconfig"
22 23
23config USB_GSPCA_CONEX 24config USB_GSPCA_CONEX
24 tristate "Conexant Camera Driver" 25 tristate "Conexant Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 035616b5e867..b7420818037e 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -58,3 +58,4 @@ gspca_zc3xx-objs := zc3xx.o
58 58
59obj-$(CONFIG_USB_M5602) += m5602/ 59obj-$(CONFIG_USB_M5602) += m5602/
60obj-$(CONFIG_USB_STV06XX) += stv06xx/ 60obj-$(CONFIG_USB_STV06XX) += stv06xx/
61obj-$(CONFIG_USB_GL860) += gl860/
diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/video/gspca/gl860/Kconfig
new file mode 100644
index 000000000000..22772f53ec7b
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Kconfig
@@ -0,0 +1,8 @@
1config USB_GL860
2 tristate "GL860 USB Camera Driver"
3 depends on VIDEO_V4L2 && USB_GSPCA
4 help
5 Say Y here if you want support for cameras based on the GL860 chip.
6
7 To compile this driver as a module, choose M here: the
8 module will be called gspca_gl860.
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile
new file mode 100644
index 000000000000..13c9403cc87d
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Makefile
@@ -0,0 +1,10 @@
1obj-$(CONFIG_USB_GL860) += gspca_gl860.o
2
3gspca_gl860-objs := gl860.o \
4 gl860-mi1320.o \
5 gl860-ov2640.o \
6 gl860-ov9655.o \
7 gl860-mi2020.o
8
9EXTRA_CFLAGS += -Idrivers/media/video/gspca
10
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
new file mode 100644
index 000000000000..39f6261c1a0c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -0,0 +1,537 @@
1/* @file gl860-mi1320.c
2 * @author Olivier LORIN from my logs
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Sensor : MI1320 */
20
21#include "gl860.h"
22
23static struct validx tbl_common[] = {
24 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1},
25 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
26 {0xffff, 0xffff},
27 {0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1},
28 {0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1},
29 {0xba70, 0x0006}, {0xba0e, 0x00f1},
30 {0xffff, 0xffff},
31 {0xba74, 0x0006}, {0xba0e, 0x00f1},
32 {0xffff, 0xffff},
33 {0x0061, 0x0000}, {0x0068, 0x000d},
34};
35
36static struct validx tbl_init_at_startup[] = {
37 {0x0000, 0x0000}, {0x0010, 0x0010},
38 {35, 0xffff},
39 {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006},
40 {0x006a, 0x000d},
41};
42
43static struct validx tbl_sensor_settings_common[] = {
44 {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000},
45 {0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006},
46};
47static struct validx tbl_sensor_settings_1280[] = {
48 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
49 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
50};
51static struct validx tbl_sensor_settings_800[] = {
52 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
53 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
54};
55static struct validx tbl_sensor_settings_640[] = {
56 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
57 {0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1},
58 {0xba20, 0x0065}, {0xba00, 0x00f1},
59};
60static struct validx tbl_post_unset_alt[] = {
61 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
62 {0x0061, 0x0000}, {0x0068, 0x000d},
63};
64
65static u8 *tbl_1280[] = {
66 "\x0d\x80\xf1\x08\x03\x04\xf1\x00" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
67 "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
68 "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
69 "\xa9\x04\xf1\x00\xa1\x05\xf1\x00" "\xa4\x04\xf1\x00\xae\x0a\xf1\x08"
70 ,
71 "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
72 "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
73 "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
74 ,
75 "\xd3\x02\xd4\x28\xd5\x01\xd0\x02" "\xd1\x18\xd2\xc1"
76};
77
78static u8 *tbl_800[] = {
79 "\x0d\x80\xf1\x08\x03\x03\xf1\xc0" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
80 "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
81 "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
82 "\xa9\x03\xf1\xc0\xa1\x03\xf1\x20" "\xa4\x02\xf1\x5a\xae\x0a\xf1\x08"
83 ,
84 "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
85 "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
86 "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
87 ,
88 "\xd3\x02\xd4\x18\xd5\x21\xd0\x02" "\xd1\x10\xd2\x59"
89};
90
91static u8 *tbl_640[] = {
92 "\x0d\x80\xf1\x08\x03\x04\xf1\x04" "\x04\x05\xf1\x02\x07\x01\xf1\x7c"
93 "\x08\x00\xf1\x0e\x21\x80\xf1\x00" "\x0d\x00\xf1\x08\xf0\x00\xf1\x01"
94 "\x34\x10\xf1\x10\x3a\x43\xf1\x00" "\xa6\x05\xf1\x02\xa9\x04\xf1\x04"
95 "\xa7\x02\xf1\x81\xaa\x01\xf1\xe2" "\xae\x0c\xf1\x09"
96 ,
97 "\xf0\x00\xf1\x02\x39\x03\xf1\xfc" "\x3b\x04\xf1\x04\x57\x01\xf1\xb6"
98 "\x58\x02\xf1\x0d\x5c\x1f\xf1\x19" "\x5d\x24\xf1\x1e\x64\x5e\xf1\x1c"
99 "\xd2\x00\xf1\x00\xcb\x00\xf1\x01"
100 ,
101 "\xd3\x02\xd4\x10\xd5\x81\xd0\x02" "\xd1\x08\xd2\xe1"
102};
103
104static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d};
105static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70};
106static s32 tbl_backlight[] = {0x0e, 0x06, 0x02};
107
108static s32 tbl_cntr1[] = {
109 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0};
110static s32 tbl_cntr2[] = {
111 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10};
112
113static u8 dat_wbalNL[] =
114 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10"
115 "\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20"
116 "\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00";
117
118static u8 dat_wbalLL[] =
119 "\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40"
120 "\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00"
121 "\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00";
122
123static u8 dat_wbalBL[] =
124 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae"
125 "\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20"
126 "\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00";
127
128static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
129
130static u8 s000[] =
131 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
132 "\xd8\x04\x58\x00\x04\x02";
133static u8 s001[] =
134 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
135 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
136static u8 s002[] =
137 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
138 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
139 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
140static u8 s003[] =
141 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
142 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
143 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
144static u8 s004[] =
145 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
146static u8 s005[] =
147 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
148 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
149 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
150static u8 s006[] =
151 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
152 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
153 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
154static u8 s007[] =
155 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
156 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
157 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
158 "\xe1\xff\xf1\x00";
159static u8 s008[] =
160 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
161 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
162 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
163static u8 s009[] =
164 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
165 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
166 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
167static u8 s010[] =
168 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
169 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
170 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
171 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
172static u8 s011[] =
173 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
174 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
175 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
176
177static int mi1320_init_at_startup(struct gspca_dev *gspca_dev);
178static int mi1320_configure_alt(struct gspca_dev *gspca_dev);
179static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev);
180static int mi1320_init_post_alt(struct gspca_dev *gspca_dev);
181static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev);
182static int mi1320_sensor_settings(struct gspca_dev *gspca_dev);
183static int mi1320_camera_settings(struct gspca_dev *gspca_dev);
184/*==========================================================================*/
185
186void mi1320_init_settings(struct gspca_dev *gspca_dev)
187{
188 struct sd *sd = (struct sd *) gspca_dev;
189
190 sd->vcur.backlight = 0;
191 sd->vcur.brightness = 0;
192 sd->vcur.sharpness = 6;
193 sd->vcur.contrast = 10;
194 sd->vcur.gamma = 20;
195 sd->vcur.hue = 0;
196 sd->vcur.saturation = 6;
197 sd->vcur.whitebal = 0;
198 sd->vcur.mirror = 0;
199 sd->vcur.flip = 0;
200 sd->vcur.AC50Hz = 1;
201
202 sd->vmax.backlight = 2;
203 sd->vmax.brightness = 8;
204 sd->vmax.sharpness = 7;
205 sd->vmax.contrast = 0; /* 10 but not working with tihs driver */
206 sd->vmax.gamma = 40;
207 sd->vmax.hue = 5 + 1;
208 sd->vmax.saturation = 8;
209 sd->vmax.whitebal = 2;
210 sd->vmax.mirror = 1;
211 sd->vmax.flip = 1;
212 sd->vmax.AC50Hz = 1;
213
214 sd->dev_camera_settings = mi1320_camera_settings;
215 sd->dev_init_at_startup = mi1320_init_at_startup;
216 sd->dev_configure_alt = mi1320_configure_alt;
217 sd->dev_init_pre_alt = mi1320_init_pre_alt;
218 sd->dev_post_unset_alt = mi1320_post_unset_alt;
219}
220
221/*==========================================================================*/
222
223static void common(struct gspca_dev *gspca_dev)
224{
225 s32 n; /* reserved for FETCH macros */
226
227 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000);
228 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
229 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001);
230 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002);
232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003);
233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004);
234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005);
235 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006);
236 keep_on_fetching_validx(gspca_dev, tbl_common,
237 ARRAY_SIZE(tbl_common), n);
238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007);
239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008);
240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009);
241 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010);
242 keep_on_fetching_validx(gspca_dev, tbl_common,
243 ARRAY_SIZE(tbl_common), n);
244 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011);
245 keep_on_fetching_validx(gspca_dev, tbl_common,
246 ARRAY_SIZE(tbl_common), n);
247}
248
249static int mi1320_init_at_startup(struct gspca_dev *gspca_dev)
250{
251 fetch_validx(gspca_dev, tbl_init_at_startup,
252 ARRAY_SIZE(tbl_init_at_startup));
253
254 common(gspca_dev);
255
256/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
257
258 return 0;
259}
260
261static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev)
262{
263 struct sd *sd = (struct sd *) gspca_dev;
264
265 sd->mirrorMask = 0;
266
267 sd->vold.backlight = -1;
268 sd->vold.brightness = -1;
269 sd->vold.sharpness = -1;
270 sd->vold.contrast = -1;
271 sd->vold.saturation = -1;
272 sd->vold.gamma = -1;
273 sd->vold.hue = -1;
274 sd->vold.whitebal = -1;
275 sd->vold.mirror = -1;
276 sd->vold.flip = -1;
277 sd->vold.AC50Hz = -1;
278
279 common(gspca_dev);
280
281 mi1320_sensor_settings(gspca_dev);
282
283 mi1320_init_post_alt(gspca_dev);
284
285 return 0;
286}
287
288static int mi1320_init_post_alt(struct gspca_dev *gspca_dev)
289{
290 mi1320_camera_settings(gspca_dev);
291
292 return 0;
293}
294
295static int mi1320_sensor_settings(struct gspca_dev *gspca_dev)
296{
297 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
298
299 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
300
301 fetch_validx(gspca_dev, tbl_sensor_settings_common,
302 ARRAY_SIZE(tbl_sensor_settings_common));
303
304 switch (reso) {
305 case IMAGE_1280:
306 fetch_validx(gspca_dev, tbl_sensor_settings_1280,
307 ARRAY_SIZE(tbl_sensor_settings_1280));
308 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]);
309 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]);
310 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]);
311 break;
312
313 case IMAGE_800:
314 fetch_validx(gspca_dev, tbl_sensor_settings_800,
315 ARRAY_SIZE(tbl_sensor_settings_800));
316 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]);
317 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]);
318 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]);
319 break;
320
321 default:
322 fetch_validx(gspca_dev, tbl_sensor_settings_640,
323 ARRAY_SIZE(tbl_sensor_settings_640));
324 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]);
325 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]);
326 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]);
327 break;
328 }
329 return 0;
330}
331
332static int mi1320_configure_alt(struct gspca_dev *gspca_dev)
333{
334 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
335
336 switch (reso) {
337 case IMAGE_640:
338 gspca_dev->alt = 3 + 1;
339 break;
340
341 case IMAGE_800:
342 case IMAGE_1280:
343 gspca_dev->alt = 1 + 1;
344 break;
345 }
346 return 0;
347}
348
349int mi1320_camera_settings(struct gspca_dev *gspca_dev)
350{
351 struct sd *sd = (struct sd *) gspca_dev;
352
353 s32 backlight = sd->vcur.backlight;
354 s32 bright = sd->vcur.brightness;
355 s32 sharp = sd->vcur.sharpness;
356 s32 cntr = sd->vcur.contrast;
357 s32 gam = sd->vcur.gamma;
358 s32 hue = sd->vcur.hue;
359 s32 sat = sd->vcur.saturation;
360 s32 wbal = sd->vcur.whitebal;
361 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
362 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
363 s32 freq = (sd->vcur.AC50Hz > 0);
364 s32 i;
365
366 if (freq != sd->vold.AC50Hz) {
367 sd->vold.AC50Hz = freq;
368
369 freq = 2 * (freq == 0);
370 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
371 ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL);
372 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x005b, 0, NULL);
373 ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL);
374 }
375
376 if (wbal != sd->vold.whitebal) {
377 sd->vold.whitebal = wbal;
378 if (wbal < 0 || wbal > sd->vmax.whitebal)
379 wbal = 0;
380
381 for (i = 0; i < 2; i++) {
382 if (wbal == 0) { /* Normal light */
383 ctrl_out(gspca_dev, 0x40, 1,
384 0x0010, 0x0010, 0, NULL);
385 ctrl_out(gspca_dev, 0x40, 1,
386 0x0003, 0x00c1, 0, NULL);
387 ctrl_out(gspca_dev, 0x40, 1,
388 0x0042, 0x00c2, 0, NULL);
389 ctrl_out(gspca_dev, 0x40, 3,
390 0xba00, 0x0200, 48, dat_wbalNL);
391 }
392
393 if (wbal == 1) { /* Low light */
394 ctrl_out(gspca_dev, 0x40, 1,
395 0x0010, 0x0010, 0, NULL);
396 ctrl_out(gspca_dev, 0x40, 1,
397 0x0004, 0x00c1, 0, NULL);
398 ctrl_out(gspca_dev, 0x40, 1,
399 0x0043, 0x00c2, 0, NULL);
400 ctrl_out(gspca_dev, 0x40, 3,
401 0xba00, 0x0200, 48, dat_wbalLL);
402 }
403
404 if (wbal == 2) { /* Back light */
405 ctrl_out(gspca_dev, 0x40, 1,
406 0x0010, 0x0010, 0, NULL);
407 ctrl_out(gspca_dev, 0x40, 1,
408 0x0003, 0x00c1, 0, NULL);
409 ctrl_out(gspca_dev, 0x40, 1,
410 0x0042, 0x00c2, 0, NULL);
411 ctrl_out(gspca_dev, 0x40, 3,
412 0xba00, 0x0200, 44, dat_wbalBL);
413 }
414 }
415 }
416
417 if (bright != sd->vold.brightness) {
418 sd->vold.brightness = bright;
419 if (bright < 0 || bright > sd->vmax.brightness)
420 bright = 0;
421
422 bright = tbl_bright[bright];
423 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
424 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
425 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL);
426 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL);
427 }
428
429 if (sat != sd->vold.saturation) {
430 sd->vold.saturation = sat;
431 if (sat < 0 || sat > sd->vmax.saturation)
432 sat = 0;
433
434 sat = tbl_sat[sat];
435 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
436 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
437 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0025, 0, NULL);
438 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL);
439 }
440
441 if (sharp != sd->vold.sharpness) {
442 sd->vold.sharpness = sharp;
443 if (sharp < 0 || sharp > sd->vmax.sharpness)
444 sharp = 0;
445
446 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
447 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
448 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0005, 0, NULL);
449 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL);
450 }
451
452 if (hue != sd->vold.hue) {
453 /* 0=normal 1=NB 2="sepia" 3=negative 4=other 5=other2 */
454 if (hue < 0 || hue > sd->vmax.hue)
455 hue = 0;
456 if (hue == sd->vmax.hue)
457 sd->swapRB = 1;
458 else
459 sd->swapRB = 0;
460
461 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
462 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
463 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
464 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
465 0, NULL);
466 }
467
468 if (backlight != sd->vold.backlight) {
469 sd->vold.backlight = backlight;
470 if (backlight < 0 || backlight > sd->vmax.backlight)
471 backlight = 0;
472
473 backlight = tbl_backlight[backlight];
474 for (i = 0; i < 2; i++) {
475 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
476 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
477 ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL);
478 ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1,
479 0, NULL);
480 }
481 }
482
483 if (hue != sd->vold.hue) {
484 sd->vold.hue = hue;
485
486 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
487 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
488 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
489 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
490 0, NULL);
491 }
492
493 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
494 u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00};
495 sd->vold.mirror = mirror;
496 sd->vold.flip = flip;
497
498 dat_hvflip2[3] = flip + 2 * mirror;
499 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1);
500 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2);
501 }
502
503 if (gam != sd->vold.gamma) {
504 sd->vold.gamma = gam;
505 if (gam < 0 || gam > sd->vmax.gamma)
506 gam = 0;
507
508 gam = 2 * gam;
509 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
510 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
511 ctrl_out(gspca_dev, 0x40, 1, 0xba04 , 0x003b, 0, NULL);
512 ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL);
513 }
514
515 if (cntr != sd->vold.contrast) {
516 sd->vold.contrast = cntr;
517 if (cntr < 0 || cntr > sd->vmax.contrast)
518 cntr = 0;
519
520 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
521 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
522 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035,
523 0, NULL);
524 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1,
525 0, NULL);
526 }
527
528 return 0;
529}
530
531static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev)
532{
533 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
534
535 fetch_validx(gspca_dev, tbl_post_unset_alt,
536 ARRAY_SIZE(tbl_post_unset_alt));
537}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
new file mode 100644
index 000000000000..ffb09fed3e8c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -0,0 +1,937 @@
1/* @file gl860-mi2020.c
2 * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
4 * @date 2009-08-27
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/* Sensor : MI2020 */
21
22#include "gl860.h"
23
24static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
25static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
26static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
27static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
28static u8 dat_bright6[] = {0x90, 0x00, 0x05};
29
30static u8 dat_dummy1[] = {0x90, 0x00, 0x06};
31/*static u8 dummy2[] = {0x8c, 0xa1, 0x02};*/
32/*static u8 dummy3[] = {0x90, 0x00, 0x1f};*/
33
34static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
35static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
36static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
37static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
38
39static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
40
41static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
42static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
43
44static struct validx tbl_common_a[] = {
45 {0x0000, 0x0000},
46 {1, 0xffff}, /* msleep(35); */
47 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
48 {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0004, 0x00d8},
49 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
50};
51
52static struct validx tbl_common_b[] = {
53 {0x006a, 0x0007},
54 {35, 0xffff},
55 {0x00ef, 0x0006},
56 {35, 0xffff},
57 {0x006a, 0x000d},
58 {35, 0xffff},
59 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
60 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
61};
62
63static struct idxdata tbl_common_c[] = {
64 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
65 {6, "\xff\xff\xff"}, /* 12 */
66 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
67 {2, "\xff\xff\xff"}, /* - */
68 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"},
69 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"},
70 {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"},
71 {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"},
72 {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"},
73 {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"},
74 {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"},
75 {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"},
76 {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
77 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
78 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
79 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
80 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
81 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
82 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
83 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
84 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
85 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
86 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
87 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
88 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
89 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
90 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
91 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
92 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
93 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
94 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
95 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
96 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
97 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
98 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
99 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
100 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
101 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
102 {1, "\xff\xff\xff"},
103 {0x33, "\x78\x00\x00"},
104 {1, "\xff\xff\xff"},
105 {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
106 {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
107 {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
108 {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
109 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
110};
111
112static struct idxdata tbl_common_d[] = {
113 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
114 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
115 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
116 {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa0"},
117 {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc0"}, {0x33, "\x8c\x24\x15"},
118 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
119};
120
121static struct idxdata tbl_common_e[] = {
122 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
123 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
124 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
125 {0x33, "\x90\x00\x04"}, {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"},
126 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
127 /* msleep(53); */
128 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"},
129 {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"},
130 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
131 {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"},
132 {0x33, "\x90\x02\x84"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"},
133 {0x33, "\x8c\x27\x07"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"},
134 {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"},
135 {0x33, "\x8c\x27\x0f"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"},
136 {0x33, "\x90\x04\xbd"}, {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"},
137 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
138 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
139 {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"},
140 {0x33, "\x90\x01\x02"}, {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"},
141 {0x33, "\x8c\x27\x21"}, {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"},
142 {0x33, "\x90\x02\x85"}, {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"},
143 {0x33, "\x8c\x27\x27"}, {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"},
144 {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"},
145 {0x33, "\x8c\x27\x2d"}, {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"},
146 {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"},
147 {0x33, "\x8c\x27\x33"}, {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"},
148 {0x33, "\x90\x06\x4b"}, {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"},
149 {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"},
150 {0x33, "\x90\x00\x24"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
151 {0x33, "\x8c\x27\x41"}, {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"},
152 {0x33, "\x90\x04\xed"}, {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"},
153 {0x33, "\x8c\x27\x51"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"},
154 {0x33, "\x90\x03\x20"}, {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"},
155 {0x33, "\x8c\x27\x57"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"},
156 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"},
157 {0x33, "\x8c\x27\x63"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"},
158 {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"},
159 {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"},
160 {0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"},
161 {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"},
162 {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"},
163 {0x33, "\x8c\x24\x15"},
164};
165
166static struct validx tbl_init_at_startup[] = {
167 {0x0000, 0x0000},
168 {53, 0xffff},
169 {0x0010, 0x0010},
170 {53, 0xffff},
171 {0x0008, 0x00c0},
172 {53, 0xffff},
173 {0x0001, 0x00c1},
174 {53, 0xffff},
175 {0x0001, 0x00c2},
176 {53, 0xffff},
177 {0x0020, 0x0006},
178 {53, 0xffff},
179 {0x006a, 0x000d},
180 {53, 0xffff},
181};
182
183static struct idxdata tbl_init_post_alt_low_a[] = {
184 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
185 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
186 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
187 {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"},
188 {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"},
189 {0x33, "\x90\x00\x9b"},
190};
191
192static struct idxdata tbl_init_post_alt_low_b[] = {
193 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
194 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
195 {2, "\xff\xff\xff"},
196 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
197 {2, "\xff\xff\xff"},
198};
199
200static struct idxdata tbl_init_post_alt_low_c[] = {
201 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
202 {2, "\xff\xff\xff"},
203 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
204 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"},
205 {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"},
206 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"},
207 {2, "\xff\xff\xff"},
208 {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
209 {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
210 {2, "\xff\xff\xff"},
211 {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
212 {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
213 {2, "\xff\xff\xff"}, /* - * */
214 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
215 {2, "\xff\xff\xff"},
216 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
217 {2, "\xff\xff\xff"},
218 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
219 {2, "\xff\xff\xff"},
220 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
221 {1, "\xff\xff\xff"},
222};
223
224static struct idxdata tbl_init_post_alt_low_d[] = {
225 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
226 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
227 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
228 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
229 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
230 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
231 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
232 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
233 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
234 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
235 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
236 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
237 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
238 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
239 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
240 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
241 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
242 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
243 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
244 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
245 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
246 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
247 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
248 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
249 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
250 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"},
251 /* Flip/Mirror h/v=1 */
252 {0x33, "\x90\x00\x3c"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
253 {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, {0x33, "\x8c\xa1\x03"},
254 {0x33, "\x90\x00\x06"},
255 {130, "\xff\xff\xff"},
256 {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
257 {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
258 {100, "\xff\xff\xff"},
259 /* ?? */
260 {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"},
261 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
262 {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
263 /* Brigthness=70 */
264 {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x46"}, {0x33, "\x8c\xa1\x02"},
265 {0x33, "\x90\x00\x0f"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
266 /* Sharpness=20 */
267 {0x32, "\x6c\x14\x08"},
268};
269
270static struct idxdata tbl_init_post_alt_big_a[] = {
271 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
272 {2, "\xff\xff\xff"},
273 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
274 {2, "\xff\xff\xff"},
275 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
276 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
277 {0x33, "\x90\x00\x05"},
278 {2, "\xff\xff\xff"},
279 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
280 {2, "\xff\xff\xff"},
281 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
282 {2, "\xff\xff\xff"},
283 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"},
284 {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"},
285 {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"},
286 {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
287 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
288 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
289};
290
291static struct idxdata tbl_init_post_alt_big_b[] = {
292 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
293 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
294 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
295 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
296 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
297 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
298 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
299 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
300 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
301 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
302 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
303 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
304 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
305 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
306 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
307 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
308 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
309 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
310 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
311 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
312 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
313 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
314 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
315 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
316 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
317 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
318};
319
320static struct idxdata tbl_init_post_alt_big_c[] = {
321 {0x33, "\x8c\xa1\x02"},
322 {0x33, "\x90\x00\x1f"},
323 {0x33, "\x8c\xa1\x02"},
324 {0x33, "\x90\x00\x1f"},
325 {0x33, "\x8c\xa1\x02"},
326 {0x33, "\x90\x00\x1f"},
327 {0x33, "\x8c\xa1\x02"},
328 {0x33, "\x90\x00\x1f"},
329};
330
331static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
332static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
333static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
334static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41";
335
336static int mi2020_init_at_startup(struct gspca_dev *gspca_dev);
337static int mi2020_configure_alt(struct gspca_dev *gspca_dev);
338static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev);
339static int mi2020_init_post_alt(struct gspca_dev *gspca_dev);
340static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev);
341static int mi2020_camera_settings(struct gspca_dev *gspca_dev);
342/*==========================================================================*/
343
344void mi2020_init_settings(struct gspca_dev *gspca_dev)
345{
346 struct sd *sd = (struct sd *) gspca_dev;
347
348 sd->vcur.backlight = 0;
349 sd->vcur.brightness = 70;
350 sd->vcur.sharpness = 20;
351 sd->vcur.contrast = 0;
352 sd->vcur.gamma = 0;
353 sd->vcur.hue = 0;
354 sd->vcur.saturation = 60;
355 sd->vcur.whitebal = 50;
356 sd->vcur.mirror = 0;
357 sd->vcur.flip = 0;
358 sd->vcur.AC50Hz = 1;
359
360 sd->vmax.backlight = 64;
361 sd->vmax.brightness = 128;
362 sd->vmax.sharpness = 40;
363 sd->vmax.contrast = 3;
364 sd->vmax.gamma = 2;
365 sd->vmax.hue = 0 + 1; /* 200 */
366 sd->vmax.saturation = 0; /* 100 */
367 sd->vmax.whitebal = 0; /* 100 */
368 sd->vmax.mirror = 1;
369 sd->vmax.flip = 1;
370 sd->vmax.AC50Hz = 1;
371 if (_MI2020b_) {
372 sd->vmax.contrast = 0;
373 sd->vmax.gamma = 0;
374 sd->vmax.backlight = 0;
375 }
376
377 sd->dev_camera_settings = mi2020_camera_settings;
378 sd->dev_init_at_startup = mi2020_init_at_startup;
379 sd->dev_configure_alt = mi2020_configure_alt;
380 sd->dev_init_pre_alt = mi2020_init_pre_alt;
381 sd->dev_post_unset_alt = mi2020_post_unset_alt;
382}
383
384/*==========================================================================*/
385
386static void common(struct gspca_dev *gspca_dev)
387{
388 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
389
390 if (_MI2020b_) {
391 fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
392 } else {
393 if (_MI2020_)
394 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL);
395 else
396 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL);
397 msleep(35);
398 fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
399 }
400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01");
401 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00");
402 msleep(2); /* - * */
403 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc");
404 if (reso == IMAGE_1600)
405 msleep(2); /* 1600 */
406 fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
407
408 if (_MI2020b_ || _MI2020_)
409 fetch_idxdata(gspca_dev, tbl_common_d,
410 ARRAY_SIZE(tbl_common_d));
411
412 fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
413 if (_MI2020b_ || _MI2020_) {
414 /* Different from fret */
415 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
416 /* Same as fret */
417 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
418 /* Different from fret */
419 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x90");
420 } else {
421 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x6a");
422 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
423 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x80");
424 }
425 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
426 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x05");
427 msleep(2);
428 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
429 if (reso == IMAGE_1600)
430 msleep(14); /* 1600 */
431 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x06");
432 msleep(2);
433}
434
435static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
436{
437 u8 c;
438
439 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
440 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
441
442 fetch_validx(gspca_dev, tbl_init_at_startup,
443 ARRAY_SIZE(tbl_init_at_startup));
444
445 common(gspca_dev);
446
447 return 0;
448}
449
450static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
451{
452 struct sd *sd = (struct sd *) gspca_dev;
453
454 sd->mirrorMask = 0;
455
456 sd->vold.backlight = -1;
457 sd->vold.brightness = -1;
458 sd->vold.sharpness = -1;
459 sd->vold.contrast = -1;
460 sd->vold.gamma = -1;
461 sd->vold.hue = -1;
462 sd->vold.mirror = -1;
463 sd->vold.flip = -1;
464 sd->vold.AC50Hz = -1;
465
466 mi2020_init_post_alt(gspca_dev);
467
468 return 0;
469}
470
471static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
472{
473 struct sd *sd = (struct sd *) gspca_dev;
474 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
475
476 s32 backlight = sd->vcur.backlight;
477 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
478 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
479 s32 freq = (sd->vcur.AC50Hz > 0);
480
481 u8 dat_freq2[] = {0x90, 0x00, 0x80};
482 u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
483 u8 dat_multi2[] = {0x90, 0x00, 0x00};
484 u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
485 u8 dat_multi4[] = {0x90, 0x00, 0x00};
486 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
487 u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
488 u8 c;
489
490 sd->nbIm = -1;
491
492 dat_freq2[2] = freq ? 0xc0 : 0x80;
493 dat_multi1[2] = 0x9d;
494 dat_multi3[2] = dat_multi1[2] + 1;
495 dat_multi4[2] = dat_multi2[2] = backlight;
496 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
497 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
498
499 msleep(200);
500
501 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
502 msleep(3); /* 35 * */
503
504 common(gspca_dev);
505
506 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
507 msleep(70);
508
509 if (_MI2020b_)
510 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
511
512 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
513 ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL);
514 ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL);
515 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
516
517 switch (reso) {
518 case IMAGE_640:
519 case IMAGE_800:
520 if (reso != IMAGE_800)
521 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
522 12, dat_640);
523 else
524 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
525 12, dat_800);
526
527 if (_MI2020c_)
528 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
529 ARRAY_SIZE(tbl_init_post_alt_low_a));
530
531 if (reso == IMAGE_800)
532 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
533 ARRAY_SIZE(tbl_init_post_alt_low_b));
534
535 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
536 ARRAY_SIZE(tbl_init_post_alt_low_c));
537
538 if (_MI2020b_) {
539 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
540 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
541 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
542 msleep(150);
543 } else if (_MI2020c_) {
544 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
545 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
546 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
547 msleep(120);
548 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
549 msleep(30);
550 } else if (_MI2020_) {
551 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
552 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
553 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
554 msleep(120);
555 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
556 msleep(30);
557 }
558
559 /* AC power frequency */
560 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
561 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
562 msleep(20);
563 /* backlight */
564 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
565 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
566 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
567 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
568 /* at init time but not after */
569 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
570 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
571 /* finish the backlight */
572 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
573 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
574 msleep(5);/* " */
575
576 if (_MI2020c_) {
577 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
578 ARRAY_SIZE(tbl_init_post_alt_low_d));
579 } else {
580 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
581 msleep(14); /* 0xd8 */
582
583 /* flip/mirror */
584 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
585 3, dat_hvflip1);
586 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
587 3, dat_hvflip2);
588 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
589 3, dat_hvflip3);
590 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
591 3, dat_hvflip4);
592 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
593 3, dat_hvflip5);
594 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
595 3, dat_hvflip6);
596 msleep(21);
597 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
598 3, dat_dummy1);
599 msleep(5);
600 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
601 3, dat_dummy1);
602 msleep(5);
603 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
604 3, dat_dummy1);
605 msleep(5);
606 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
607 3, dat_dummy1);
608 msleep(5);
609 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
610 3, dat_dummy1);
611 msleep(5);
612 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
613 3, dat_dummy1);
614 /* end of flip/mirror main part */
615 msleep(246); /* 146 */
616
617 sd->nbIm = 0;
618 }
619 break;
620
621 case IMAGE_1280:
622 case IMAGE_1600:
623 if (reso == IMAGE_1280) {
624 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
625 12, dat_1280);
626 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
627 3, "\x8c\x27\x07");
628 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
629 3, "\x90\x05\x04");
630 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
631 3, "\x8c\x27\x09");
632 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
633 3, "\x90\x04\x02");
634 } else {
635 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
636 12, dat_1600);
637 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
638 3, "\x8c\x27\x07");
639 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
640 3, "\x90\x06\x40");
641 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
642 3, "\x8c\x27\x09");
643 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
644 3, "\x90\x04\xb0");
645 }
646
647 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
648 ARRAY_SIZE(tbl_init_post_alt_big_a));
649
650 if (reso == IMAGE_1600)
651 msleep(13); /* 1600 */
652 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x27\x97");
653 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x01\x00");
654 msleep(53);
655 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
656 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
657 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
658 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
659 if (reso == IMAGE_1600)
660 msleep(13); /* 1600 */
661 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
662 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
663 msleep(53);
664 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
665 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
666 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
667 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
668 if (reso == IMAGE_1600)
669 msleep(13); /* 1600 */
670 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
671 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
672 msleep(53);
673
674 if (_MI2020b_) {
675 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
676 if (reso == IMAGE_1600)
677 msleep(500); /* 1600 */
678 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
679 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
680 msleep(1850);
681 } else if (_MI2020c_ || _MI2020_) {
682 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
683 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
684 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
685 msleep(1850);
686 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
687 msleep(30);
688 }
689
690 /* AC power frequency */
691 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
692 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
693 msleep(20);
694 /* backlight */
695 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
696 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
697 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
698 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
699 /* at init time but not after */
700 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
701 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
702 /* finish the backlight */
703 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
704 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
705 msleep(6); /* " */
706
707 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
708 msleep(14);
709
710 if (_MI2020c_)
711 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
712 ARRAY_SIZE(tbl_init_post_alt_big_b));
713
714 /* flip/mirror */
715 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
716 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
717 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
718 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
719 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
720 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
721 /* end of flip/mirror main part */
722 msleep(16);
723 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
724 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
725 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
726 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
727 if (reso == IMAGE_1600)
728 msleep(25); /* 1600 */
729 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
730 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
731 msleep(103);
732 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
733 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
734 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
735 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
736 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
737 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
738 sd->nbIm = 0;
739
740 if (_MI2020c_)
741 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
742 ARRAY_SIZE(tbl_init_post_alt_big_c));
743 }
744
745 sd->vold.mirror = mirror;
746 sd->vold.flip = flip;
747 sd->vold.AC50Hz = freq;
748 sd->vold.backlight = backlight;
749
750 mi2020_camera_settings(gspca_dev);
751
752 return 0;
753}
754
755static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
756{
757 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
758
759 switch (reso) {
760 case IMAGE_640:
761 gspca_dev->alt = 3 + 1;
762 break;
763
764 case IMAGE_800:
765 case IMAGE_1280:
766 case IMAGE_1600:
767 gspca_dev->alt = 1 + 1;
768 break;
769 }
770 return 0;
771}
772
773int mi2020_camera_settings(struct gspca_dev *gspca_dev)
774{
775 struct sd *sd = (struct sd *) gspca_dev;
776
777 s32 backlight = sd->vcur.backlight;
778 s32 bright = sd->vcur.brightness;
779 s32 sharp = sd->vcur.sharpness;
780 s32 cntr = sd->vcur.contrast;
781 s32 gam = sd->vcur.gamma;
782 s32 hue = (sd->vcur.hue > 0);
783 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
784 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
785 s32 freq = (sd->vcur.AC50Hz > 0);
786
787 u8 dat_sharp[] = {0x6c, 0x00, 0x08};
788 u8 dat_bright2[] = {0x90, 0x00, 0x00};
789 u8 dat_freq2[] = {0x90, 0x00, 0x80};
790 u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
791 u8 dat_multi2[] = {0x90, 0x00, 0x00};
792 u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
793 u8 dat_multi4[] = {0x90, 0x00, 0x00};
794 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
795 u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
796
797 /* Less than 4 images received -> too early to set the settings */
798 if (sd->nbIm < 4) {
799 sd->waitSet = 1;
800 return 0;
801 }
802 sd->waitSet = 0;
803
804 if (freq != sd->vold.AC50Hz) {
805 sd->vold.AC50Hz = freq;
806
807 dat_freq2[2] = freq ? 0xc0 : 0x80;
808 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
809 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
810 msleep(20);
811 }
812
813 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
814 sd->vold.mirror = mirror;
815 sd->vold.flip = flip;
816
817 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
818 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
819 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
820 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
821 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
822 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
823 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
824 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
825 msleep(130);
826 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
827 msleep(6);
828 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
829 msleep(6);
830 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
831 msleep(6);
832 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
833 msleep(6);
834 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
835 msleep(6);
836 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
837 msleep(6);
838
839 /* Sometimes present, sometimes not, useful? */
840 /* ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
841 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
842 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
843 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
844 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
845 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
846 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
847 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);*/
848 }
849
850 if (backlight != sd->vold.backlight) {
851 sd->vold.backlight = backlight;
852 if (backlight < 0 || backlight > sd->vmax.backlight)
853 backlight = 0;
854
855 dat_multi1[2] = 0x9d;
856 dat_multi3[2] = dat_multi1[2] + 1;
857 dat_multi4[2] = dat_multi2[2] = backlight;
858 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
859 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
860 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
861 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
862 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
863 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
864 }
865
866 if (gam != sd->vold.gamma) {
867 sd->vold.gamma = gam;
868 if (gam < 0 || gam > sd->vmax.gamma)
869 gam = 0;
870
871 dat_multi1[2] = 0x6d;
872 dat_multi3[2] = dat_multi1[2] + 1;
873 dat_multi4[2] = dat_multi2[2] = 0x40 + gam;
874 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
875 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
876 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
877 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
878 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
879 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
880 }
881
882 if (cntr != sd->vold.contrast) {
883 sd->vold.contrast = cntr;
884 if (cntr < 0 || cntr > sd->vmax.contrast)
885 cntr = 0;
886
887 dat_multi1[2] = 0x6d;
888 dat_multi3[2] = dat_multi1[2] + 1;
889 dat_multi4[2] = dat_multi2[2] = 0x12 + 16 * cntr;
890 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
891 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
892 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
893 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
894 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
895 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
896 }
897
898 if (bright != sd->vold.brightness) {
899 sd->vold.brightness = bright;
900 if (bright < 0 || bright > sd->vmax.brightness)
901 bright = 0;
902
903 dat_bright2[2] = bright;
904 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
905 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
906 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
907 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
908 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
909 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
910 }
911
912 if (sharp != sd->vold.sharpness) {
913 sd->vold.sharpness = sharp;
914 if (sharp < 0 || sharp > sd->vmax.sharpness)
915 sharp = 0;
916
917 dat_sharp[1] = sharp;
918 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp);
919 }
920
921 if (hue != sd->vold.hue) {
922 sd->swapRB = hue;
923 sd->vold.hue = hue;
924 }
925
926 return 0;
927}
928
929static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
930{
931 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
932 msleep(20);
933 if (_MI2020c_ || _MI2020_)
934 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
935 else
936 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
937}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
new file mode 100644
index 000000000000..14b9c373f9f7
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -0,0 +1,505 @@
1/* @file gl860-ov2640.c
2 * @author Olivier LORIN, from Malmostoso's logs
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Sensor : OV2640 */
20
21#include "gl860.h"
22
23static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
24static u8 dat_init2[] = {0x61}; /* expected */
25static u8 dat_init3[] = {0x51}; /* expected */
26
27static u8 dat_post[] =
28 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
29
30static u8 dat_640[] = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81";
31static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
32static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
33static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
34
35static u8 c50[] = {0x50}; /* expected */
36static u8 c28[] = {0x28}; /* expected */
37static u8 ca8[] = {0xa8}; /* expected */
38
39static struct validx tbl_init_at_startup[] = {
40 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
41 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
42 {0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006},
43 {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1},
44 {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058},
45 {0x0041, 0x0000}, {0x0061, 0x0000},
46};
47
48static struct validx tbl_common[] = {
49 {0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff},
50 {0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
51 {0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013},
52 {0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b},
53 {0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039},
54 {0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023},
55 {0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007},
56 {0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a},
57 {0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025},
58 {0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
59 {0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061},
60 {0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c},
61 {0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073},
62 {0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050},
63 {0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b},
64 {0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076},
65 {0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c},
66 {0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9},
67 {0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044},
68 {0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8},
69 {0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d},
70 {0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091},
71 {0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091},
72 {0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091},
73 {0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091},
74 {0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093},
75 {0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093},
76 {0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
77 {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
78 {0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097},
79 {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097},
80 {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097},
81 {0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4},
82 {0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7},
83 {0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9},
84 {0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0},
85 {0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8},
86 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050},
87 {0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054},
88 {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b},
89 {0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da},
90 {0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
91 {0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045},
92 {0x6000, 0x0010},
93};
94
95static struct validx tbl_sensor_settings_common_a[] = {
96 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
97 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
98 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
99 {50, 0xffff},
100 {0x0061, 0x0000},
101 {0xffff, 0xffff},
102 {0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d},
103 {30, 0xffff},
104 {0x0040, 0x0000},
105};
106
107static struct validx tbl_sensor_settings_common_b[] = {
108 {0x6001, 0x00ff}, {0x6038, 0x000c},
109 {10, 0xffff},
110 {0x6000, 0x0011},
111 /* backlight=31/64 */
112 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
113 /* bright=0/256 */
114 {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
115 /* wbal=64/128 */
116 {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
117 /* cntr=0/256 */
118 {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
119 /* sat=128/256 */
120 {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
121 /* sharpness=0/32 */
122 {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
123 /* hue=0/256 */
124 {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
125 /* gam=32/64 */
126 {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
127 /* image right up */
128 {0xffff, 0xffff},
129 {15, 0xffff},
130 {0x6001, 0x00ff}, {0x6000, 0x8004},
131 {0xffff, 0xffff},
132 {0x60a8, 0x0004},
133 {15, 0xffff},
134 {0x6001, 0x00ff}, {0x6000, 0x8004},
135 {0xffff, 0xffff},
136 {0x60f8, 0x0004},
137 /* image right up */
138 {0xffff, 0xffff},
139 /* backlight=31/64 */
140 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
141};
142
143static struct validx tbl_640[] = {
144 {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
145 {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
146 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
147 {0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032},
148 {0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d},
149 {0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff},
150 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086},
151 {0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053},
152 {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a},
153 {0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0},
154 {0x60ff, 0x00dd}, {0x60a1, 0x005a},
155};
156
157static struct validx tbl_800[] = {
158 {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
159 {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
160 {0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
161 {0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032},
162 {0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d},
163 {0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020},
164 {0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1},
165 {0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0},
166 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
167};
168
169static struct validx tbl_big_a[] = {
170 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
171 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
172 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
173 {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f},
174 {0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f},
175 {0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff},
176 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
177};
178
179static struct validx tbl_big_b[] = {
180 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
181 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
182 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
183 {0x6000, 0x008e},
184};
185
186static struct validx tbl_big_c[] = {
187 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
188 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
189 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
190 {0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093},
191 {0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087},
192 {0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097},
193 {0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff},
194 {0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e},
195 {0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014},
196 {0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
197};
198
199static struct validx tbl_post_unset_alt[] = {
200 {0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000},
201 {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d},
202 {50, 0xffff},
203 {0x0021, 0x0000},
204};
205
206static int ov2640_init_at_startup(struct gspca_dev *gspca_dev);
207static int ov2640_configure_alt(struct gspca_dev *gspca_dev);
208static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev);
209static int ov2640_init_post_alt(struct gspca_dev *gspca_dev);
210static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev);
211static int ov2640_camera_settings(struct gspca_dev *gspca_dev);
212/*==========================================================================*/
213
214void ov2640_init_settings(struct gspca_dev *gspca_dev)
215{
216 struct sd *sd = (struct sd *) gspca_dev;
217
218 sd->vcur.backlight = 32;
219 sd->vcur.brightness = 0;
220 sd->vcur.sharpness = 6;
221 sd->vcur.contrast = 0;
222 sd->vcur.gamma = 32;
223 sd->vcur.hue = 0;
224 sd->vcur.saturation = 128;
225 sd->vcur.whitebal = 64;
226
227 sd->vmax.backlight = 64;
228 sd->vmax.brightness = 255;
229 sd->vmax.sharpness = 31;
230 sd->vmax.contrast = 255;
231 sd->vmax.gamma = 64;
232 sd->vmax.hue = 255 + 1;
233 sd->vmax.saturation = 255;
234 sd->vmax.whitebal = 128;
235 sd->vmax.mirror = 0;
236 sd->vmax.flip = 0;
237 sd->vmax.AC50Hz = 0;
238
239 sd->dev_camera_settings = ov2640_camera_settings;
240 sd->dev_init_at_startup = ov2640_init_at_startup;
241 sd->dev_configure_alt = ov2640_configure_alt;
242 sd->dev_init_pre_alt = ov2640_init_pre_alt;
243 sd->dev_post_unset_alt = ov2640_post_unset_alt;
244}
245
246/*==========================================================================*/
247
248static void common(struct gspca_dev *gspca_dev)
249{
250 fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
251}
252
253static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
254{
255 fetch_validx(gspca_dev, tbl_init_at_startup,
256 ARRAY_SIZE(tbl_init_at_startup));
257
258 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1);
259
260 common(gspca_dev);
261
262 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2);
263
264 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
265
266 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3);
267
268 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
269/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
270
271 return 0;
272}
273
274static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
275{
276 struct sd *sd = (struct sd *) gspca_dev;
277
278 sd->vold.backlight = -1;
279 sd->vold.brightness = -1;
280 sd->vold.sharpness = -1;
281 sd->vold.contrast = -1;
282 sd->vold.saturation = -1;
283 sd->vold.gamma = -1;
284 sd->vold.hue = -1;
285 sd->vold.whitebal = -1;
286
287 ov2640_init_post_alt(gspca_dev);
288
289 return 0;
290}
291
292static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
293{
294 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
295 s32 n; /* reserved for FETCH macros */
296
297 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
298
299 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a,
300 ARRAY_SIZE(tbl_sensor_settings_common_a));
301 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
302 common(gspca_dev);
303 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a,
304 ARRAY_SIZE(tbl_sensor_settings_common_a), n);
305
306 switch (reso) {
307 case IMAGE_640:
308 n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640));
309 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640);
310 break;
311
312 case IMAGE_800:
313 n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800));
314 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800);
315 break;
316
317 case IMAGE_1600:
318 case IMAGE_1280:
319 n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a));
320
321 if (reso == IMAGE_1280) {
322 n = fetch_validx(gspca_dev, tbl_big_b,
323 ARRAY_SIZE(tbl_big_b));
324 } else {
325 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
326 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
327 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
328 }
329
330 n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c));
331
332 if (reso == IMAGE_1280) {
333 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
334 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
335 12, dat_1280);
336 } else {
337 ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL);
338 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
339 ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL);
340 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
341 12, dat_1600);
342 }
343 break;
344 }
345
346 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b,
347 ARRAY_SIZE(tbl_sensor_settings_common_b));
348 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
349 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
350 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
351 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
352 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
353 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
354 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
355 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
356 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
357 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
358 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
359 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
360
361 ov2640_camera_settings(gspca_dev);
362
363 return 0;
364}
365
366static int ov2640_configure_alt(struct gspca_dev *gspca_dev)
367{
368 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
369
370 switch (reso) {
371 case IMAGE_640:
372 gspca_dev->alt = 3 + 1;
373 break;
374
375 case IMAGE_800:
376 case IMAGE_1280:
377 case IMAGE_1600:
378 gspca_dev->alt = 1 + 1;
379 break;
380 }
381 return 0;
382}
383
384static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
385{
386 struct sd *sd = (struct sd *) gspca_dev;
387
388 s32 backlight = sd->vcur.backlight;
389 s32 bright = sd->vcur.brightness;
390 s32 sharp = sd->vcur.sharpness;
391 s32 gam = sd->vcur.gamma;
392 s32 cntr = sd->vcur.contrast;
393 s32 sat = sd->vcur.saturation;
394 s32 hue = sd->vcur.hue;
395 s32 wbal = sd->vcur.whitebal;
396
397 if (backlight != sd->vold.backlight) {
398 if (backlight < 0 || backlight > sd->vmax.backlight)
399 backlight = 0;
400
401 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
402 0, NULL);
403 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024,
404 0, NULL);
405 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
406 0, NULL);
407 /* No sd->vold.backlight=backlight; (to be done again later) */
408 }
409
410 if (bright != sd->vold.brightness) {
411 sd->vold.brightness = bright;
412 if (bright < 0 || bright > sd->vmax.brightness)
413 bright = 0;
414
415 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
416 ctrl_out(gspca_dev, 0x40, 1, 0x6009 , 0x007c, 0, NULL);
417 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL);
418 }
419
420 if (wbal != sd->vold.whitebal) {
421 sd->vold.whitebal = wbal;
422 if (wbal < 0 || wbal > sd->vmax.whitebal)
423 wbal = 0;
424
425 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
426 ctrl_out(gspca_dev, 0x40, 1, 0x6003 , 0x007c, 0, NULL);
427 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL);
428 }
429
430 if (cntr != sd->vold.contrast) {
431 sd->vold.contrast = cntr;
432 if (cntr < 0 || cntr > sd->vmax.contrast)
433 cntr = 0;
434
435 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
436 ctrl_out(gspca_dev, 0x40, 1, 0x6007 , 0x007c, 0, NULL);
437 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL);
438 }
439
440 if (sat != sd->vold.saturation) {
441 sd->vold.saturation = sat;
442 if (sat < 0 || sat > sd->vmax.saturation)
443 sat = 0;
444
445 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
446 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x007c, 0, NULL);
447 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL);
448 }
449
450 if (sharp != sd->vold.sharpness) {
451 sd->vold.sharpness = sharp;
452 if (sharp < 0 || sharp > sd->vmax.sharpness)
453 sharp = 0;
454
455 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
456 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x0092, 0, NULL);
457 ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL);
458 }
459
460 if (hue != sd->vold.hue) {
461 sd->vold.hue = hue;
462 if (hue < 0 || hue > sd->vmax.hue)
463 hue = 0;
464
465 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
466 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
467 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
468 0, NULL);
469 if (hue >= sd->vmax.hue)
470 sd->swapRB = 1;
471 else
472 sd->swapRB = 0;
473 }
474
475 if (gam != sd->vold.gamma) {
476 sd->vold.gamma = gam;
477 if (gam < 0 || gam > sd->vmax.gamma)
478 gam = 0;
479
480 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
481 ctrl_out(gspca_dev, 0x40, 1, 0x6008 , 0x007c, 0, NULL);
482 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
483 }
484
485 if (backlight != sd->vold.backlight) {
486 sd->vold.backlight = backlight;
487
488 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
489 0, NULL);
490 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024,
491 0, NULL);
492 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
493 0, NULL);
494 }
495
496 return 0;
497}
498
499static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev)
500{
501 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
502 msleep(20);
503 fetch_validx(gspca_dev, tbl_post_unset_alt,
504 ARRAY_SIZE(tbl_post_unset_alt));
505}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
new file mode 100644
index 000000000000..eda3346f939c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -0,0 +1,337 @@
1/* @file gl860-ov9655.c
2 * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
3 * on dsd's weblog
4 * @date 2009-08-27
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/* Sensor : OV9655 */
21
22#include "gl860.h"
23
24static struct validx tbl_init_at_startup[] = {
25 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
26 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
27
28 {0x0040, 0x0000},
29};
30
31static struct validx tbl_commmon[] = {
32 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d},
33 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
34 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000},
35 {0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000},
36};
37
38static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12};
39
40static u8 *tbl_640[] = {
41 "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
42 ,
43 "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x03\x0b\x57\x0e\x61"
44 "\x0f\x42\x11\x01\x12\x60\x13\x00" "\x14\x3a\x16\x24\x17\x14\x18\x00"
45 "\x19\x01\x1a\x3d\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
46 "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
47 ,
48 "\x32\xff\x33\x00\x34\x3d\x35\x00" "\x36\xfa\x38\x72\x39\x57\x3a\x00"
49 "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc1" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
50 "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xee\x4b\xe7\x4c\xe7"
51 "\x4d\xe7\x4e\xe7"
52 ,
53 "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
54 "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
55 "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x0a\x6b\x5a\x6c\x04"
56 "\x6d\x55\x6e\x00\x6f\x9d"
57 ,
58 "\x70\x15\x71\x78\x72\x00\x73\x00" "\x74\x3a\x75\x35\x76\x01\x77\x02"
59 "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
60 "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
61 "\x8a\x23\x8c\x8d\x90\x7c\x91\x7b"
62 ,
63 "\x9d\x02\x9e\x02\x9f\x74\xa0\x73" "\xa1\x40\xa4\x50\xa5\x68\xa6\x70"
64 "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
65 "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
66 ,
67 "\xbb\xae\xbc\x4f\xbd\x4e\xbe\x6a" "\xbf\x68\xc0\xaa\xc1\xc0\xc2\x01"
68 "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
69 ,
70 "\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80"
71};
72
73static u8 *tbl_800[] = {
74 "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
75 ,
76 "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61"
77 "\x0f\x42\x11\x00\x12\x00\x13\x00" "\x14\x3a\x16\x24\x17\x1b\x18\xbb"
78 "\x19\x01\x1a\x81\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
79 "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
80 ,
81 "\x32\xa4\x33\x00\x34\x3d\x35\x00" "\x36\xf8\x38\x72\x39\x57\x3a\x00"
82 "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc2" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
83 "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xec\x4b\xe8\x4c\xe8"
84 "\x4d\xe8\x4e\xe8"
85 ,
86 "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
87 "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
88 "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x02\x6b\x5a\x6c\x04"
89 "\x6d\x55\x6e\x00\x6f\x9d"
90 ,
91 "\x70\x08\x71\x78\x72\x00\x73\x01" "\x74\x3a\x75\x35\x76\x01\x77\x02"
92 "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
93 "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
94 "\x8a\x23\x8c\x0d\x90\x90\x91\x90"
95 ,
96 "\x9d\x02\x9e\x02\x9f\x94\xa0\x94" "\xa1\x01\xa4\x50\xa5\x68\xa6\x70"
97 "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
98 "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
99 ,
100 "\xbb\xae\xbc\x38\xbd\x39\xbe\x01" "\xbf\x01\xc0\xe2\xc1\xc0\xc2\x01"
101 "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
102 ,
103 "\xd0\x21\xd1\x18\xd2\xe0\xd3\x01" "\xd4\x28\xd5\x00"
104};
105
106static u8 c04[] = {0x04};
107static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
108static u8 dat_post_2[] = "\x10\x10\xc1\x02";
109static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
110static u8 dat_post_4[] = "\x10\x02\xc1\x06";
111static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
112static u8 dat_post_6[] = "\x10\x10\xc1\x05";
113static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
114static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
115
116static struct validx tbl_init_post_alt[] = {
117 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
118 {0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff},
119 {0x6000, 0x801e},
120 {0xffff, 0xffff},
121 {0x6004, 0x001e}, {0x6000, 0x801e},
122 {0xffff, 0xffff},
123 {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
124 {0xffff, 0xffff},
125 {0x6004, 0x001e}, {0x6000, 0x801e},
126 {0xffff, 0xffff},
127 {0x6004, 0x001e}, {0x6012, 0x0003},
128 {0xffff, 0xffff},
129 {0x6000, 0x801e},
130 {0xffff, 0xffff},
131 {0x6004, 0x001e}, {0x6000, 0x801e},
132 {0xffff, 0xffff},
133 {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
134 {0xffff, 0xffff},
135 {0x6004, 0x001e}, {0x6000, 0x801e},
136 {0xffff, 0xffff},
137 {0x6004, 0x001e}, {0x6012, 0x0003},
138 {0xffff, 0xffff},
139 {0x6000, 0x801e},
140 {0xffff, 0xffff},
141 {0x6004, 0x001e}, {0x6000, 0x801e},
142 {0xffff, 0xffff},
143 {0x6004, 0x001e}, {0x6012, 0x0003},
144};
145
146static int ov9655_init_at_startup(struct gspca_dev *gspca_dev);
147static int ov9655_configure_alt(struct gspca_dev *gspca_dev);
148static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev);
149static int ov9655_init_post_alt(struct gspca_dev *gspca_dev);
150static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev);
151static int ov9655_camera_settings(struct gspca_dev *gspca_dev);
152/*==========================================================================*/
153
154void ov9655_init_settings(struct gspca_dev *gspca_dev)
155{
156 struct sd *sd = (struct sd *) gspca_dev;
157
158 sd->vcur.backlight = 0;
159 sd->vcur.brightness = 128;
160 sd->vcur.sharpness = 0;
161 sd->vcur.contrast = 0;
162 sd->vcur.gamma = 0;
163 sd->vcur.hue = 0;
164 sd->vcur.saturation = 0;
165 sd->vcur.whitebal = 0;
166
167 sd->vmax.backlight = 0;
168 sd->vmax.brightness = 255;
169 sd->vmax.sharpness = 0;
170 sd->vmax.contrast = 0;
171 sd->vmax.gamma = 0;
172 sd->vmax.hue = 0 + 1;
173 sd->vmax.saturation = 0;
174 sd->vmax.whitebal = 0;
175 sd->vmax.mirror = 0;
176 sd->vmax.flip = 0;
177 sd->vmax.AC50Hz = 0;
178
179 sd->dev_camera_settings = ov9655_camera_settings;
180 sd->dev_init_at_startup = ov9655_init_at_startup;
181 sd->dev_configure_alt = ov9655_configure_alt;
182 sd->dev_init_pre_alt = ov9655_init_pre_alt;
183 sd->dev_post_unset_alt = ov9655_post_unset_alt;
184}
185
186/*==========================================================================*/
187
188static int ov9655_init_at_startup(struct gspca_dev *gspca_dev)
189{
190 fetch_validx(gspca_dev, tbl_init_at_startup,
191 ARRAY_SIZE(tbl_init_at_startup));
192 fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
193/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/
194
195 return 0;
196}
197
198static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
199{
200 struct sd *sd = (struct sd *) gspca_dev;
201
202 sd->vold.brightness = -1;
203 sd->vold.hue = -1;
204
205 fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
206
207 ov9655_init_post_alt(gspca_dev);
208
209 return 0;
210}
211
212static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
213{
214 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
215 s32 n; /* reserved for FETCH macros */
216 s32 i;
217 u8 **tbl;
218
219 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
220
221 tbl = (reso == IMAGE_640) ? tbl_640 : tbl_800;
222
223 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
224 tbl_length[0], tbl[0]);
225 for (i = 1; i < 7; i++)
226 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200,
227 tbl_length[i], tbl[i]);
228 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
229 tbl_length[7], tbl[7]);
230
231 n = fetch_validx(gspca_dev, tbl_init_post_alt,
232 ARRAY_SIZE(tbl_init_post_alt));
233
234 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
235 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
236 ARRAY_SIZE(tbl_init_post_alt), n);
237 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
238 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
239 ARRAY_SIZE(tbl_init_post_alt), n);
240 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
241 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
242 ARRAY_SIZE(tbl_init_post_alt), n);
243 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
244 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
245 ARRAY_SIZE(tbl_init_post_alt), n);
246 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
247 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
248 ARRAY_SIZE(tbl_init_post_alt), n);
249
250 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
251 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
252 ARRAY_SIZE(tbl_init_post_alt), n);
253 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
254 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
255 ARRAY_SIZE(tbl_init_post_alt), n);
256 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
257 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
258 ARRAY_SIZE(tbl_init_post_alt), n);
259 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
260 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
261 ARRAY_SIZE(tbl_init_post_alt), n);
262 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
263 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
264 ARRAY_SIZE(tbl_init_post_alt), n);
265
266 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
267 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
268 ARRAY_SIZE(tbl_init_post_alt), n);
269 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
270 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
271 ARRAY_SIZE(tbl_init_post_alt), n);
272
273 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
274
275 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2);
276 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3);
277
278 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4);
279 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5);
280
281 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6);
282 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7);
283
284 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8);
285
286 ov9655_camera_settings(gspca_dev);
287
288 return 0;
289}
290
291static int ov9655_configure_alt(struct gspca_dev *gspca_dev)
292{
293 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
294
295 switch (reso) {
296 case IMAGE_640:
297 gspca_dev->alt = 1 + 1;
298 break;
299
300 default:
301 gspca_dev->alt = 1 + 1;
302 break;
303 }
304 return 0;
305}
306
307static int ov9655_camera_settings(struct gspca_dev *gspca_dev)
308{
309 struct sd *sd = (struct sd *) gspca_dev;
310
311 u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70";
312
313 s32 bright = sd->vcur.brightness;
314 s32 hue = sd->vcur.hue;
315
316 if (bright != sd->vold.brightness) {
317 sd->vold.brightness = bright;
318 if (bright < 0 || bright > sd->vmax.brightness)
319 bright = 0;
320
321 dat_bright[3] = bright;
322 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright);
323 }
324
325 if (hue != sd->vold.hue) {
326 sd->vold.hue = hue;
327 sd->swapRB = (hue != 0);
328 }
329
330 return 0;
331}
332
333static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev)
334{
335 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
336 ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL);
337}
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
new file mode 100644
index 000000000000..6ef59ac7f502
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -0,0 +1,785 @@
1/* @file gl860.c
2 * @date 2009-08-27
3 *
4 * Genesys Logic webcam with gl860 subdrivers
5 *
6 * Driver by Olivier Lorin <o.lorin@laposte.net>
7 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
8 * Thanks BUGabundo and Malmostoso for your amazing help!
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23#include "gspca.h"
24#include "gl860.h"
25
26MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>");
27MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver");
28MODULE_LICENSE("GPL");
29
30/*======================== static function declarations ====================*/
31
32static void (*dev_init_settings)(struct gspca_dev *gspca_dev);
33
34static int sd_config(struct gspca_dev *gspca_dev,
35 const struct usb_device_id *id);
36static int sd_init(struct gspca_dev *gspca_dev);
37static int sd_isoc_init(struct gspca_dev *gspca_dev);
38static int sd_start(struct gspca_dev *gspca_dev);
39static void sd_stop0(struct gspca_dev *gspca_dev);
40static void sd_pkt_scan(struct gspca_dev *gspca_dev,
41 struct gspca_frame *frame, u8 *data, s32 len);
42static void sd_callback(struct gspca_dev *gspca_dev);
43
44static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
45 s32 vendor_id, s32 product_id);
46
47/*============================ driver options ==============================*/
48
49static s32 AC50Hz = 0xff;
50module_param(AC50Hz, int, 0644);
51MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
52
53static char sensor[7];
54module_param_string(sensor, sensor, sizeof(sensor), 0644);
55MODULE_PARM_DESC(sensor,
56 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')");
57
58/*============================ webcam controls =============================*/
59
60/* Functions to get and set a control value */
61#define SD_SETGET(thename) \
62static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\
63{\
64 struct sd *sd = (struct sd *) gspca_dev;\
65\
66 sd->vcur.thename = val;\
67 if (gspca_dev->streaming)\
68 sd->dev_camera_settings(gspca_dev);\
69 return 0;\
70} \
71static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\
72{\
73 struct sd *sd = (struct sd *) gspca_dev;\
74\
75 *val = sd->vcur.thename;\
76 return 0;\
77}
78
79SD_SETGET(mirror)
80SD_SETGET(flip)
81SD_SETGET(AC50Hz)
82SD_SETGET(backlight)
83SD_SETGET(brightness)
84SD_SETGET(gamma)
85SD_SETGET(hue)
86SD_SETGET(saturation)
87SD_SETGET(sharpness)
88SD_SETGET(whitebal)
89SD_SETGET(contrast)
90
91#define GL860_NCTRLS 11
92
93/* control table */
94static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS];
95static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS];
96static struct ctrl sd_ctrls_mi2020b[GL860_NCTRLS];
97static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS];
98static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS];
99
100#define SET_MY_CTRL(theid, \
101 thetype, thelabel, thename) \
102 if (sd->vmax.thename != 0) {\
103 sd_ctrls[nCtrls].qctrl.id = theid;\
104 sd_ctrls[nCtrls].qctrl.type = thetype;\
105 strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\
106 sd_ctrls[nCtrls].qctrl.minimum = 0;\
107 sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\
108 sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\
109 sd_ctrls[nCtrls].qctrl.step = \
110 (sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\
111 sd_ctrls[nCtrls].set = sd_set_##thename;\
112 sd_ctrls[nCtrls].get = sd_get_##thename;\
113 nCtrls++;\
114 }
115
116static int gl860_build_control_table(struct gspca_dev *gspca_dev)
117{
118 struct sd *sd = (struct sd *) gspca_dev;
119 struct ctrl *sd_ctrls;
120 int nCtrls = 0;
121
122 if (_MI1320_)
123 sd_ctrls = sd_ctrls_mi1320;
124 else if (_MI2020_)
125 sd_ctrls = sd_ctrls_mi2020;
126 else if (_MI2020b_)
127 sd_ctrls = sd_ctrls_mi2020b;
128 else if (_OV2640_)
129 sd_ctrls = sd_ctrls_ov2640;
130 else if (_OV9655_)
131 sd_ctrls = sd_ctrls_ov9655;
132 else
133 return 0;
134
135 memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl));
136
137 SET_MY_CTRL(V4L2_CID_BRIGHTNESS,
138 V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness)
139 SET_MY_CTRL(V4L2_CID_SHARPNESS,
140 V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness)
141 SET_MY_CTRL(V4L2_CID_CONTRAST,
142 V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast)
143 SET_MY_CTRL(V4L2_CID_GAMMA,
144 V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma)
145 SET_MY_CTRL(V4L2_CID_HUE,
146 V4L2_CTRL_TYPE_INTEGER, "Palette", hue)
147 SET_MY_CTRL(V4L2_CID_SATURATION,
148 V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation)
149 SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
150 V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal)
151 SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION,
152 V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight)
153
154 SET_MY_CTRL(V4L2_CID_HFLIP,
155 V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror)
156 SET_MY_CTRL(V4L2_CID_VFLIP,
157 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
158 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
159 V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz)
160
161 return nCtrls;
162}
163
164/*==================== sud-driver structure initialisation =================*/
165
166static struct sd_desc sd_desc_mi1320 = {
167 .name = MODULE_NAME,
168 .ctrls = sd_ctrls_mi1320,
169 .nctrls = GL860_NCTRLS,
170 .config = sd_config,
171 .init = sd_init,
172 .isoc_init = sd_isoc_init,
173 .start = sd_start,
174 .stop0 = sd_stop0,
175 .pkt_scan = sd_pkt_scan,
176 .dq_callback = sd_callback,
177};
178
179static struct sd_desc sd_desc_mi2020 = {
180 .name = MODULE_NAME,
181 .ctrls = sd_ctrls_mi2020,
182 .nctrls = GL860_NCTRLS,
183 .config = sd_config,
184 .init = sd_init,
185 .isoc_init = sd_isoc_init,
186 .start = sd_start,
187 .stop0 = sd_stop0,
188 .pkt_scan = sd_pkt_scan,
189 .dq_callback = sd_callback,
190};
191
192static struct sd_desc sd_desc_mi2020b = {
193 .name = MODULE_NAME,
194 .ctrls = sd_ctrls_mi2020b,
195 .nctrls = GL860_NCTRLS,
196 .config = sd_config,
197 .init = sd_init,
198 .isoc_init = sd_isoc_init,
199 .start = sd_start,
200 .stop0 = sd_stop0,
201 .pkt_scan = sd_pkt_scan,
202 .dq_callback = sd_callback,
203};
204
205static struct sd_desc sd_desc_ov2640 = {
206 .name = MODULE_NAME,
207 .ctrls = sd_ctrls_ov2640,
208 .nctrls = GL860_NCTRLS,
209 .config = sd_config,
210 .init = sd_init,
211 .isoc_init = sd_isoc_init,
212 .start = sd_start,
213 .stop0 = sd_stop0,
214 .pkt_scan = sd_pkt_scan,
215 .dq_callback = sd_callback,
216};
217
218static struct sd_desc sd_desc_ov9655 = {
219 .name = MODULE_NAME,
220 .ctrls = sd_ctrls_ov9655,
221 .nctrls = GL860_NCTRLS,
222 .config = sd_config,
223 .init = sd_init,
224 .isoc_init = sd_isoc_init,
225 .start = sd_start,
226 .stop0 = sd_stop0,
227 .pkt_scan = sd_pkt_scan,
228 .dq_callback = sd_callback,
229};
230
231/*=========================== sub-driver image sizes =======================*/
232
233static struct v4l2_pix_format mi2020_mode[] = {
234 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
235 .bytesperline = 640,
236 .sizeimage = 640 * 480,
237 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 0
239 },
240 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
241 .bytesperline = 800,
242 .sizeimage = 800 * 600,
243 .colorspace = V4L2_COLORSPACE_SRGB,
244 .priv = 1
245 },
246 {1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
247 .bytesperline = 1280,
248 .sizeimage = 1280 * 1024,
249 .colorspace = V4L2_COLORSPACE_SRGB,
250 .priv = 2
251 },
252 {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
253 .bytesperline = 1600,
254 .sizeimage = 1600 * 1200,
255 .colorspace = V4L2_COLORSPACE_SRGB,
256 .priv = 3
257 },
258};
259
260static struct v4l2_pix_format ov2640_mode[] = {
261 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
262 .bytesperline = 640,
263 .sizeimage = 640 * 480,
264 .colorspace = V4L2_COLORSPACE_SRGB,
265 .priv = 0
266 },
267 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
268 .bytesperline = 800,
269 .sizeimage = 800 * 600,
270 .colorspace = V4L2_COLORSPACE_SRGB,
271 .priv = 1
272 },
273 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
274 .bytesperline = 1280,
275 .sizeimage = 1280 * 960,
276 .colorspace = V4L2_COLORSPACE_SRGB,
277 .priv = 2
278 },
279 {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
280 .bytesperline = 1600,
281 .sizeimage = 1600 * 1200,
282 .colorspace = V4L2_COLORSPACE_SRGB,
283 .priv = 3
284 },
285};
286
287static struct v4l2_pix_format mi1320_mode[] = {
288 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
289 .bytesperline = 640,
290 .sizeimage = 640 * 480,
291 .colorspace = V4L2_COLORSPACE_SRGB,
292 .priv = 0
293 },
294 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
295 .bytesperline = 800,
296 .sizeimage = 800 * 600,
297 .colorspace = V4L2_COLORSPACE_SRGB,
298 .priv = 1
299 },
300 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
301 .bytesperline = 1280,
302 .sizeimage = 1280 * 960,
303 .colorspace = V4L2_COLORSPACE_SRGB,
304 .priv = 2
305 },
306};
307
308static struct v4l2_pix_format ov9655_mode[] = {
309 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
310 .bytesperline = 640,
311 .sizeimage = 640 * 480,
312 .colorspace = V4L2_COLORSPACE_SRGB,
313 .priv = 0
314 },
315 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
316 .bytesperline = 1280,
317 .sizeimage = 1280 * 960,
318 .colorspace = V4L2_COLORSPACE_SRGB,
319 .priv = 1
320 },
321};
322
323/*========================= sud-driver functions ===========================*/
324
325/* This function is called at probe time */
326static int sd_config(struct gspca_dev *gspca_dev,
327 const struct usb_device_id *id)
328{
329 struct sd *sd = (struct sd *) gspca_dev;
330 struct cam *cam;
331 s32 vendor_id, product_id;
332
333 /* Get USB VendorID and ProductID */
334 vendor_id = le16_to_cpu(id->idVendor);
335 product_id = le16_to_cpu(id->idProduct);
336
337 sd->nbRightUp = 1;
338 sd->nbIm = -1;
339
340 sd->sensor = 0xff;
341 if (strcmp(sensor, "MI1320") == 0)
342 sd->sensor = ID_MI1320;
343 else if (strcmp(sensor, "OV2640") == 0)
344 sd->sensor = ID_OV2640;
345 else if (strcmp(sensor, "OV9655") == 0)
346 sd->sensor = ID_OV9655;
347 else if (strcmp(sensor, "MI2020") == 0)
348 sd->sensor = ID_MI2020;
349 else if (strcmp(sensor, "MI2020b") == 0)
350 sd->sensor = ID_MI2020b;
351
352 /* Get sensor and set the suitable init/start/../stop functions */
353 if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
354 return -1;
355
356 cam = &gspca_dev->cam;
357 gspca_dev->nbalt = 4;
358
359 switch (sd->sensor) {
360 case ID_MI1320:
361 gspca_dev->sd_desc = &sd_desc_mi1320;
362 cam->cam_mode = mi1320_mode;
363 cam->nmodes = ARRAY_SIZE(mi1320_mode);
364 dev_init_settings = mi1320_init_settings;
365 break;
366
367 case ID_MI2020:
368 gspca_dev->sd_desc = &sd_desc_mi2020;
369 cam->cam_mode = mi2020_mode;
370 cam->nmodes = ARRAY_SIZE(mi2020_mode);
371 dev_init_settings = mi2020_init_settings;
372 break;
373
374 case ID_MI2020b:
375 gspca_dev->sd_desc = &sd_desc_mi2020b;
376 cam->cam_mode = mi2020_mode;
377 cam->nmodes = ARRAY_SIZE(mi2020_mode);
378 dev_init_settings = mi2020_init_settings;
379 break;
380
381 case ID_OV2640:
382 gspca_dev->sd_desc = &sd_desc_ov2640;
383 cam->cam_mode = ov2640_mode;
384 cam->nmodes = ARRAY_SIZE(ov2640_mode);
385 dev_init_settings = ov2640_init_settings;
386 break;
387
388 case ID_OV9655:
389 gspca_dev->sd_desc = &sd_desc_ov9655;
390 cam->cam_mode = ov9655_mode;
391 cam->nmodes = ARRAY_SIZE(ov9655_mode);
392 dev_init_settings = ov9655_init_settings;
393 break;
394 }
395
396 dev_init_settings(gspca_dev);
397 if (AC50Hz != 0xff)
398 ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz;
399 gl860_build_control_table(gspca_dev);
400
401 return 0;
402}
403
404/* This function is called at probe time after sd_config */
405static int sd_init(struct gspca_dev *gspca_dev)
406{
407 struct sd *sd = (struct sd *) gspca_dev;
408
409 return sd->dev_init_at_startup(gspca_dev);
410}
411
412/* This function is called before to choose the alt setting */
413static int sd_isoc_init(struct gspca_dev *gspca_dev)
414{
415 struct sd *sd = (struct sd *) gspca_dev;
416
417 return sd->dev_configure_alt(gspca_dev);
418}
419
420/* This function is called to start the webcam */
421static int sd_start(struct gspca_dev *gspca_dev)
422{
423 struct sd *sd = (struct sd *) gspca_dev;
424
425 return sd->dev_init_pre_alt(gspca_dev);
426}
427
428/* This function is called to stop the webcam */
429static void sd_stop0(struct gspca_dev *gspca_dev)
430{
431 struct sd *sd = (struct sd *) gspca_dev;
432
433 return sd->dev_post_unset_alt(gspca_dev);
434}
435
436/* This function is called when an image is being received */
437static void sd_pkt_scan(struct gspca_dev *gspca_dev,
438 struct gspca_frame *frame, u8 *data, s32 len)
439{
440 struct sd *sd = (struct sd *) gspca_dev;
441 static s32 nSkipped;
442
443 s32 mode = (s32) gspca_dev->curr_mode;
444 s32 nToSkip =
445 sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
446
447 /* Test only against 0202h, so endianess does not matter */
448 switch (*(s16 *) data) {
449 case 0x0202: /* End of frame, start a new one */
450 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
451 nSkipped = 0;
452 if (sd->nbIm >= 0 && sd->nbIm < 10)
453 sd->nbIm++;
454 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
455 break;
456
457 default:
458 data += 2;
459 len -= 2;
460 if (nSkipped + len <= nToSkip)
461 nSkipped += len;
462 else {
463 if (nSkipped < nToSkip && nSkipped + len > nToSkip) {
464 data += nToSkip - nSkipped;
465 len -= nToSkip - nSkipped;
466 nSkipped = nToSkip + 1;
467 }
468 gspca_frame_add(gspca_dev,
469 INTER_PACKET, frame, data, len);
470 }
471 break;
472 }
473}
474
475/* This function is called when an image has been read */
476/* This function is used to monitor webcam orientation */
477static void sd_callback(struct gspca_dev *gspca_dev)
478{
479 struct sd *sd = (struct sd *) gspca_dev;
480
481 if (!_OV9655_) {
482 u8 state;
483 u8 upsideDown;
484
485 /* Probe sensor orientation */
486 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state);
487
488 /* C8/40 means upside-down (looking backwards) */
489 /* D8/50 means right-up (looking onwards) */
490 upsideDown = (state == 0xc8 || state == 0x40);
491
492 if (upsideDown && sd->nbRightUp > -4) {
493 if (sd->nbRightUp > 0)
494 sd->nbRightUp = 0;
495 if (sd->nbRightUp == -3) {
496 sd->mirrorMask = 1;
497 sd->waitSet = 1;
498 }
499 sd->nbRightUp--;
500 }
501 if (!upsideDown && sd->nbRightUp < 4) {
502 if (sd->nbRightUp < 0)
503 sd->nbRightUp = 0;
504 if (sd->nbRightUp == 3) {
505 sd->mirrorMask = 0;
506 sd->waitSet = 1;
507 }
508 sd->nbRightUp++;
509 }
510 }
511
512 if (sd->waitSet)
513 sd->dev_camera_settings(gspca_dev);
514}
515
516/*=================== USB driver structure initialisation ==================*/
517
518static const __devinitdata struct usb_device_id device_table[] = {
519 {USB_DEVICE(0x05e3, 0x0503)},
520 {USB_DEVICE(0x05e3, 0xf191)},
521 {}
522};
523
524MODULE_DEVICE_TABLE(usb, device_table);
525
526static int sd_probe(struct usb_interface *intf,
527 const struct usb_device_id *id)
528{
529 struct gspca_dev *gspca_dev;
530 s32 ret;
531
532 ret = gspca_dev_probe(intf, id,
533 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
534
535 if (ret >= 0) {
536 gspca_dev = usb_get_intfdata(intf);
537
538 PDEBUG(D_PROBE,
539 "Camera is now controlling video device /dev/video%d",
540 gspca_dev->vdev.minor);
541 }
542
543 return ret;
544}
545
546static void sd_disconnect(struct usb_interface *intf)
547{
548 gspca_disconnect(intf);
549}
550
551static struct usb_driver sd_driver = {
552 .name = MODULE_NAME,
553 .id_table = device_table,
554 .probe = sd_probe,
555 .disconnect = sd_disconnect,
556#ifdef CONFIG_PM
557 .suspend = gspca_suspend,
558 .resume = gspca_resume,
559#endif
560};
561
562/*====================== Init and Exit module functions ====================*/
563
564static int __init sd_mod_init(void)
565{
566 PDEBUG(D_PROBE, "driver startup - version %s", DRIVER_VERSION);
567
568 if (usb_register(&sd_driver) < 0)
569 return -1;
570 PDEBUG(D_PROBE, "driver registered");
571
572 return 0;
573}
574
575static void __exit sd_mod_exit(void)
576{
577 usb_deregister(&sd_driver);
578 PDEBUG(D_PROBE, "driver deregistered");
579}
580
581module_init(sd_mod_init);
582module_exit(sd_mod_exit);
583
584/*==========================================================================*/
585
586int gl860_RTx(struct gspca_dev *gspca_dev,
587 unsigned char pref, u32 req, u16 val, u16 index,
588 s32 len, void *pdata)
589{
590 struct usb_device *udev = gspca_dev->dev;
591 s32 r = 0;
592
593 if (pref == 0x40) { /* Send */
594 if (len > 0) {
595 memcpy(gspca_dev->usb_buf, pdata, len);
596 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
597 req, pref, val, index,
598 gspca_dev->usb_buf,
599 len, 400 + 200 * (len > 1));
600 } else {
601 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
602 req, pref, val, index, NULL, len, 400);
603 }
604 } else { /* Receive */
605 if (len > 0) {
606 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
607 req, pref, val, index,
608 gspca_dev->usb_buf,
609 len, 400 + 200 * (len > 1));
610 memcpy(pdata, gspca_dev->usb_buf, len);
611 } else {
612 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
613 req, pref, val, index, NULL, len, 400);
614 }
615 }
616
617 if (r < 0)
618 PDEBUG(D_ERR,
619 "ctrl transfer failed %4d "
620 "[p%02x r%d v%04x i%04x len%d]",
621 r, pref, req, val, index, len);
622 else if (len > 1 && r < len)
623 PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len);
624
625 if ((_MI2020_ || _MI2020b_ || _MI2020c_) && (val || index))
626 msleep(1);
627 if (_OV2640_)
628 msleep(1);
629
630 return r;
631}
632
633int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len)
634{
635 int n;
636
637 for (n = 0; n < len; n++) {
638 if (tbl[n].idx != 0xffff)
639 ctrl_out(gspca_dev, 0x40, 1, tbl[n].val,
640 tbl[n].idx, 0, NULL);
641 else if (tbl[n].val == 0xffff)
642 break;
643 else
644 msleep(tbl[n].val);
645 }
646 return n;
647}
648
649int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
650 int len, int n)
651{
652 while (++n < len) {
653 if (tbl[n].idx != 0xffff)
654 ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx,
655 0, NULL);
656 else if (tbl[n].val == 0xffff)
657 break;
658 else
659 msleep(tbl[n].val);
660 }
661 return n;
662}
663
664void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
665{
666 int n;
667
668 for (n = 0; n < len; n++) {
669 if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0)
670 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx,
671 3, tbl[n].data);
672 else
673 msleep(tbl[n].idx);
674 }
675}
676
677static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
678 s32 vendor_id, s32 product_id)
679{
680 struct sd *sd = (struct sd *) gspca_dev;
681 u8 probe, nb26, nb96, nOV, ntry;
682
683 if (product_id == 0xf191)
684 sd->sensor = ID_MI1320;
685
686 if (sd->sensor == 0xff) {
687 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
688 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
689
690 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
691 msleep(3);
692 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
693 msleep(3);
694 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
695 msleep(3);
696 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
697 msleep(3);
698 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
699 msleep(3);
700 ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
701 msleep(3);
702 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
703 msleep(56);
704
705 nOV = 0;
706 for (ntry = 0; ntry < 4; ntry++) {
707 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
708 msleep(3);
709 ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
710 msleep(3);
711 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
712 msleep(10);
713 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
714 PDEBUG(D_PROBE, "1st probe=%02x", probe);
715 if (probe == 0xff)
716 nOV++;
717 }
718
719 if (nOV) {
720 PDEBUG(D_PROBE, "0xff -> sensor OVXXXX");
721 PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655");
722
723 nb26 = nb96 = 0;
724 for (ntry = 0; ntry < 4; ntry++) {
725 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
726 0, NULL);
727 msleep(3);
728 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
729 0, NULL);
730 msleep(10);
731 /* Wait for 26(OV2640) or 96(OV9655) */
732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
733 1, &probe);
734
735 PDEBUG(D_PROBE, "2nd probe=%02x", probe);
736 if (probe == 0x00)
737 nb26++;
738 if (probe == 0x26 || probe == 0x40) {
739 sd->sensor = ID_OV2640;
740 nb26 += 4;
741 break;
742 }
743 if (probe == 0x96 || probe == 0x55) {
744 sd->sensor = ID_OV9655;
745 nb96 += 4;
746 break;
747 }
748 if (probe == 0xff)
749 nb96++;
750 msleep(3);
751 }
752 if (nb26 < 4 && nb96 < 4) {
753 PDEBUG(D_PROBE, "No relevant answer ");
754 PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
755 PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
756 PDEBUG(D_PROBE,
757 "To force a sensor, add that line to "
758 "/etc/modprobe.d/options.conf:");
759 PDEBUG(D_PROBE, "options gspca_gl860 "
760 "sensor=\"OV2640\" or \"OV9655\"");
761 return -1;
762 }
763 } else { /* probe = 0 */
764 PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
765 sd->sensor = ID_MI2020;
766 }
767 }
768
769 if (_MI1320_) {
770 PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
771 } else if (_MI2020_) {
772 PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
773 } else if (_MI2020b_) {
774 PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 alt. driver (2.0M)");
775 } else if (_OV9655_) {
776 PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
777 } else if (_OV2640_) {
778 PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
779 } else {
780 PDEBUG(D_PROBE, "***** Unknown sensor *****");
781 return -1;
782 }
783
784 return 0;
785}
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
new file mode 100644
index 000000000000..cef4e24c1e61
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -0,0 +1,108 @@
1/* @file gl860.h
2 * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef GL860_DEV_H
19#define GL860_DEV_H
20#include <linux/version.h>
21
22#include "gspca.h"
23
24#define MODULE_NAME "gspca_gl860"
25#define DRIVER_VERSION "0.9d10"
26
27#define ctrl_in gl860_RTx
28#define ctrl_out gl860_RTx
29
30#define ID_MI1320 1
31#define ID_OV2640 2
32#define ID_OV9655 4
33#define ID_MI2020 8
34#define ID_MI2020b 16
35
36#define _MI1320_ (((struct sd *) gspca_dev)->sensor == ID_MI1320)
37#define _MI2020_ (((struct sd *) gspca_dev)->sensor == ID_MI2020)
38#define _MI2020b_ (((struct sd *) gspca_dev)->sensor == ID_MI2020b)
39#define _MI2020c_ 0
40#define _OV2640_ (((struct sd *) gspca_dev)->sensor == ID_OV2640)
41#define _OV9655_ (((struct sd *) gspca_dev)->sensor == ID_OV9655)
42
43#define IMAGE_640 0
44#define IMAGE_800 1
45#define IMAGE_1280 2
46#define IMAGE_1600 3
47
48struct sd_gl860 {
49 u16 backlight;
50 u16 brightness;
51 u16 sharpness;
52 u16 contrast;
53 u16 gamma;
54 u16 hue;
55 u16 saturation;
56 u16 whitebal;
57 u8 mirror;
58 u8 flip;
59 u8 AC50Hz;
60};
61
62/* Specific webcam descriptor */
63struct sd {
64 struct gspca_dev gspca_dev; /* !! must be the first item */
65
66 struct sd_gl860 vcur;
67 struct sd_gl860 vold;
68 struct sd_gl860 vmax;
69
70 int (*dev_configure_alt) (struct gspca_dev *);
71 int (*dev_init_at_startup)(struct gspca_dev *);
72 int (*dev_init_pre_alt) (struct gspca_dev *);
73 void (*dev_post_unset_alt) (struct gspca_dev *);
74 int (*dev_camera_settings)(struct gspca_dev *);
75
76 u8 swapRB;
77 u8 mirrorMask;
78 u8 sensor;
79 s32 nbIm;
80 s32 nbRightUp;
81 u8 waitSet;
82};
83
84struct validx {
85 u16 val;
86 u16 idx;
87};
88
89struct idxdata {
90 u8 idx;
91 u8 data[3];
92};
93
94int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len);
95int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
96 int len, int n);
97void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len);
98
99int gl860_RTx(struct gspca_dev *gspca_dev,
100 unsigned char pref, u32 req, u16 val, u16 index,
101 s32 len, void *pdata);
102
103void mi1320_init_settings(struct gspca_dev *);
104void ov2640_init_settings(struct gspca_dev *);
105void ov9655_init_settings(struct gspca_dev *);
106void mi2020_init_settings(struct gspca_dev *);
107
108#endif
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index dbfa3ed6e8ef..a11c97ebeb0f 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -312,6 +312,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
312 312
313 /* create the JPEG header */ 313 /* create the JPEG header */
314 dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 314 dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
315 if (dev->jpeg_hdr == NULL)
316 return -ENOMEM;
315 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, 317 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
316 0x21); /* JPEG 422 */ 318 0x21); /* JPEG 422 */
317 jpeg_set_qual(dev->jpeg_hdr, dev->quality); 319 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 7aafeb7cfa07..2a28b74cb3f9 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -20,6 +20,18 @@
20 20
21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); 22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
24 __s32 *val);
25static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
26 __s32 val);
27static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
28static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
29static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
30static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
31static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
23 35
24const static struct ctrl ov7660_ctrls[] = { 36const static struct ctrl ov7660_ctrls[] = {
25#define GAIN_IDX 1 37#define GAIN_IDX 1
@@ -37,6 +49,79 @@ const static struct ctrl ov7660_ctrls[] = {
37 .set = ov7660_set_gain, 49 .set = ov7660_set_gain,
38 .get = ov7660_get_gain 50 .get = ov7660_get_gain
39 }, 51 },
52#define BLUE_BALANCE_IDX 2
53#define RED_BALANCE_IDX 3
54#define AUTO_WHITE_BALANCE_IDX 4
55 {
56 {
57 .id = V4L2_CID_AUTO_WHITE_BALANCE,
58 .type = V4L2_CTRL_TYPE_BOOLEAN,
59 .name = "auto white balance",
60 .minimum = 0,
61 .maximum = 1,
62 .step = 1,
63 .default_value = 1
64 },
65 .set = ov7660_set_auto_white_balance,
66 .get = ov7660_get_auto_white_balance
67 },
68#define AUTO_GAIN_CTRL_IDX 5
69 {
70 {
71 .id = V4L2_CID_AUTOGAIN,
72 .type = V4L2_CTRL_TYPE_BOOLEAN,
73 .name = "auto gain control",
74 .minimum = 0,
75 .maximum = 1,
76 .step = 1,
77 .default_value = 1
78 },
79 .set = ov7660_set_auto_gain,
80 .get = ov7660_get_auto_gain
81 },
82#define AUTO_EXPOSURE_IDX 6
83 {
84 {
85 .id = V4L2_CID_EXPOSURE_AUTO,
86 .type = V4L2_CTRL_TYPE_BOOLEAN,
87 .name = "auto exposure",
88 .minimum = 0,
89 .maximum = 1,
90 .step = 1,
91 .default_value = 1
92 },
93 .set = ov7660_set_auto_exposure,
94 .get = ov7660_get_auto_exposure
95 },
96#define HFLIP_IDX 7
97 {
98 {
99 .id = V4L2_CID_HFLIP,
100 .type = V4L2_CTRL_TYPE_BOOLEAN,
101 .name = "horizontal flip",
102 .minimum = 0,
103 .maximum = 1,
104 .step = 1,
105 .default_value = 0
106 },
107 .set = ov7660_set_hflip,
108 .get = ov7660_get_hflip
109 },
110#define VFLIP_IDX 8
111 {
112 {
113 .id = V4L2_CID_VFLIP,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "vertical flip",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 0
120 },
121 .set = ov7660_set_vflip,
122 .get = ov7660_get_vflip
123 },
124
40}; 125};
41 126
42static struct v4l2_pix_format ov7660_modes[] = { 127static struct v4l2_pix_format ov7660_modes[] = {
@@ -137,7 +222,7 @@ int ov7660_init(struct sd *sd)
137 } else { 222 } else {
138 data[0] = init_ov7660[i][2]; 223 data[0] = init_ov7660[i][2];
139 err = m5602_write_sensor(sd, 224 err = m5602_write_sensor(sd,
140 init_ov7660[i][1], data, 1); 225 init_ov7660[i][1], data, 1);
141 } 226 }
142 } 227 }
143 228
@@ -148,6 +233,28 @@ int ov7660_init(struct sd *sd)
148 if (err < 0) 233 if (err < 0)
149 return err; 234 return err;
150 235
236 err = ov7660_set_auto_white_balance(&sd->gspca_dev,
237 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
238 if (err < 0)
239 return err;
240
241 err = ov7660_set_auto_gain(&sd->gspca_dev,
242 sensor_settings[AUTO_GAIN_CTRL_IDX]);
243 if (err < 0)
244 return err;
245
246 err = ov7660_set_auto_exposure(&sd->gspca_dev,
247 sensor_settings[AUTO_EXPOSURE_IDX]);
248 if (err < 0)
249 return err;
250 err = ov7660_set_hflip(&sd->gspca_dev,
251 sensor_settings[HFLIP_IDX]);
252 if (err < 0)
253 return err;
254
255 err = ov7660_set_vflip(&sd->gspca_dev,
256 sensor_settings[VFLIP_IDX]);
257
151 return err; 258 return err;
152} 259}
153 260
@@ -194,6 +301,159 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
194 return err; 301 return err;
195} 302}
196 303
304
305static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
306 __s32 *val)
307{
308 struct sd *sd = (struct sd *) gspca_dev;
309 s32 *sensor_settings = sd->sensor_priv;
310
311 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
312 return 0;
313}
314
315static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
316 __s32 val)
317{
318 int err;
319 u8 i2c_data;
320 struct sd *sd = (struct sd *) gspca_dev;
321 s32 *sensor_settings = sd->sensor_priv;
322
323 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
324
325 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
326 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
327 if (err < 0)
328 return err;
329
330 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
331 err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
332
333 return err;
334}
335
336static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
337{
338 struct sd *sd = (struct sd *) gspca_dev;
339 s32 *sensor_settings = sd->sensor_priv;
340
341 *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
342 PDEBUG(D_V4L2, "Read auto gain control %d", *val);
343 return 0;
344}
345
346static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
347{
348 int err;
349 u8 i2c_data;
350 struct sd *sd = (struct sd *) gspca_dev;
351 s32 *sensor_settings = sd->sensor_priv;
352
353 PDEBUG(D_V4L2, "Set auto gain control to %d", val);
354
355 sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
356 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
357 if (err < 0)
358 return err;
359
360 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
361
362 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
363}
364
365static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
366{
367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
369
370 *val = sensor_settings[AUTO_EXPOSURE_IDX];
371 PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
372 return 0;
373}
374
375static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
376 __s32 val)
377{
378 int err;
379 u8 i2c_data;
380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
382
383 PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
384
385 sensor_settings[AUTO_EXPOSURE_IDX] = val;
386 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
387 if (err < 0)
388 return err;
389
390 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
391
392 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
393}
394
395static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
396{
397 struct sd *sd = (struct sd *) gspca_dev;
398 s32 *sensor_settings = sd->sensor_priv;
399
400 *val = sensor_settings[HFLIP_IDX];
401 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
402 return 0;
403}
404
405static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
406{
407 int err;
408 u8 i2c_data;
409 struct sd *sd = (struct sd *) gspca_dev;
410 s32 *sensor_settings = sd->sensor_priv;
411
412 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
413
414 sensor_settings[HFLIP_IDX] = val;
415
416 i2c_data = ((val & 0x01) << 5) |
417 (sensor_settings[VFLIP_IDX] << 4);
418
419 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
420
421 return err;
422}
423
424static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427 s32 *sensor_settings = sd->sensor_priv;
428
429 *val = sensor_settings[VFLIP_IDX];
430 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
431
432 return 0;
433}
434
435static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
436{
437 int err;
438 u8 i2c_data;
439 struct sd *sd = (struct sd *) gspca_dev;
440 s32 *sensor_settings = sd->sensor_priv;
441
442 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
443 sensor_settings[VFLIP_IDX] = val;
444
445 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
446 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
447 if (err < 0)
448 return err;
449
450 /* When vflip is toggled we need to readjust the bridge hsync/vsync */
451 if (gspca_dev->streaming)
452 err = ov7660_start(sd);
453
454 return err;
455}
456
197static void ov7660_dump_registers(struct sd *sd) 457static void ov7660_dump_registers(struct sd *sd)
198{ 458{
199 int address; 459 int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 3f2c169a93ea..f5588ebe667c 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -66,23 +66,23 @@
66#define OV7660_RBIAS 0x2c 66#define OV7660_RBIAS 0x2c
67#define OV7660_HREF 0x32 67#define OV7660_HREF 0x32
68#define OV7660_ADC 0x37 68#define OV7660_ADC 0x37
69#define OV7660_OFON 0x39 69#define OV7660_OFON 0x39
70#define OV7660_TSLB 0x3a 70#define OV7660_TSLB 0x3a
71#define OV7660_COM12 0x3c 71#define OV7660_COM12 0x3c
72#define OV7660_COM13 0x3d 72#define OV7660_COM13 0x3d
73#define OV7660_LCC1 0x62 73#define OV7660_LCC1 0x62
74#define OV7660_LCC2 0x63 74#define OV7660_LCC2 0x63
75#define OV7660_LCC3 0x64 75#define OV7660_LCC3 0x64
76#define OV7660_LCC4 0x65 76#define OV7660_LCC4 0x65
77#define OV7660_LCC5 0x66 77#define OV7660_LCC5 0x66
78#define OV7660_HV 0x69 78#define OV7660_HV 0x69
79#define OV7660_RSVDA1 0xa1 79#define OV7660_RSVDA1 0xa1
80 80
81#define OV7660_DEFAULT_GAIN 0x0e 81#define OV7660_DEFAULT_GAIN 0x0e
82#define OV7660_DEFAULT_RED_GAIN 0x80 82#define OV7660_DEFAULT_RED_GAIN 0x80
83#define OV7660_DEFAULT_BLUE_GAIN 0x80 83#define OV7660_DEFAULT_BLUE_GAIN 0x80
84#define OV7660_DEFAULT_SATURATION 0x00 84#define OV7660_DEFAULT_SATURATION 0x00
85#define OV7660_DEFAULT_EXPOSURE 0x20 85#define OV7660_DEFAULT_EXPOSURE 0x20
86 86
87/* Kernel module parameters */ 87/* Kernel module parameters */
88extern int force_sensor; 88extern int force_sensor;
@@ -149,45 +149,8 @@ static const unsigned char init_ov7660[][4] =
149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, 150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
152 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
153 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
154 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
155 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
156
157 {SENSOR, OV7660_OFON, 0x0c},
158 {SENSOR, OV7660_COM2, 0x11},
159 {SENSOR, OV7660_COM7, 0x05},
160
161 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 152 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
162 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
163 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
164 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
165 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
166 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
167 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
168 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
169 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
170 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
171 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
172 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
173 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
174 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
175 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
179
180 {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
181 {SENSOR, OV7660_COM1, 0x00},
182
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 153 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
186 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
187 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
188 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
189 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
190
191 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 154 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
192 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 155 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
193 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 156 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -196,11 +159,8 @@ static const unsigned char init_ov7660[][4] =
196 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 159 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
197 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 160 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
198 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, 161 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
199
200 {SENSOR, OV7660_COM7, 0x80}, 162 {SENSOR, OV7660_COM7, 0x80},
201 {SENSOR, OV7660_CLKRC, 0x80}, 163 {SENSOR, OV7660_CLKRC, 0x80},
202 {SENSOR, OV7660_BLUE_GAIN, 0x80},
203 {SENSOR, OV7660_RED_GAIN, 0x80},
204 {SENSOR, OV7660_COM9, 0x4c}, 164 {SENSOR, OV7660_COM9, 0x4c},
205 {SENSOR, OV7660_OFON, 0x43}, 165 {SENSOR, OV7660_OFON, 0x43},
206 {SENSOR, OV7660_COM12, 0x28}, 166 {SENSOR, OV7660_COM12, 0x28},
@@ -212,17 +172,17 @@ static const unsigned char init_ov7660[][4] =
212 {SENSOR, OV7660_PSHFT, 0x0b}, 172 {SENSOR, OV7660_PSHFT, 0x0b},
213 {SENSOR, OV7660_VSTART, 0x01}, 173 {SENSOR, OV7660_VSTART, 0x01},
214 {SENSOR, OV7660_VSTOP, 0x7a}, 174 {SENSOR, OV7660_VSTOP, 0x7a},
215 {SENSOR, OV7660_VREF, 0x00}, 175 {SENSOR, OV7660_VSTOP, 0x00},
216 {SENSOR, OV7660_COM7, 0x05}, 176 {SENSOR, OV7660_COM7, 0x05},
217 {SENSOR, OV7660_COM6, 0x4b}, 177 {SENSOR, OV7660_COM6, 0x42},
218 {SENSOR, OV7660_BBIAS, 0x98}, 178 {SENSOR, OV7660_BBIAS, 0x94},
219 {SENSOR, OV7660_GbBIAS, 0x98}, 179 {SENSOR, OV7660_GbBIAS, 0x94},
220 {SENSOR, OV7660_RSVD29, 0x98}, 180 {SENSOR, OV7660_RSVD29, 0x94},
221 {SENSOR, OV7660_RBIAS, 0x98}, 181 {SENSOR, OV7660_RBIAS, 0x94},
222 {SENSOR, OV7660_COM1, 0x00}, 182 {SENSOR, OV7660_COM1, 0x00},
223 {SENSOR, OV7660_AECH, 0x00}, 183 {SENSOR, OV7660_AECH, 0x00},
224 {SENSOR, OV7660_AECHH, 0x00}, 184 {SENSOR, OV7660_AECHH, 0x00},
225 {SENSOR, OV7660_ADC, 0x04}, 185 {SENSOR, OV7660_ADC, 0x05},
226 {SENSOR, OV7660_COM13, 0x00}, 186 {SENSOR, OV7660_COM13, 0x00},
227 {SENSOR, OV7660_RSVDA1, 0x23}, 187 {SENSOR, OV7660_RSVDA1, 0x23},
228 {SENSOR, OV7660_TSLB, 0x0d}, 188 {SENSOR, OV7660_TSLB, 0x0d},
@@ -233,6 +193,47 @@ static const unsigned char init_ov7660[][4] =
233 {SENSOR, OV7660_LCC4, 0x40}, 193 {SENSOR, OV7660_LCC4, 0x40},
234 {SENSOR, OV7660_LCC5, 0x01}, 194 {SENSOR, OV7660_LCC5, 0x01},
235 195
196 {SENSOR, OV7660_AECH, 0x20},
197 {SENSOR, OV7660_COM1, 0x00},
198 {SENSOR, OV7660_OFON, 0x0c},
199 {SENSOR, OV7660_COM2, 0x11},
200 {SENSOR, OV7660_COM7, 0x05},
201 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
202 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
203 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
204 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
205 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
208 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
209 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
210 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
211 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
212 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
213 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
214 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
215 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
216 {SENSOR, OV7660_AECH, 0x5f},
217 {SENSOR, OV7660_COM1, 0x03},
218 {SENSOR, OV7660_OFON, 0x0c},
219 {SENSOR, OV7660_COM2, 0x11},
220 {SENSOR, OV7660_COM7, 0x05},
221 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
222 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
223 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
224 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
225 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
226 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
227 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
228 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
229 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
230 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
231 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
232 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
233 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
234 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
235 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
236
236 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, 237 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
237 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 238 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
238 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 239 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -245,35 +246,18 @@ static const unsigned char init_ov7660[][4] =
245 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, 248 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
248 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */ 249 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 251 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
251 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 252 {BRIDGE, M5602_XB_SIG_INI, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x02}, 253 {BRIDGE, M5602_XB_SIG_INI, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 254 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */ 255 {BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, 256 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */ 257 {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
257 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 258 {BRIDGE, M5602_XB_SIG_INI, 0x00},
258
259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
261
262 {SENSOR, OV7660_AECH, 0x20},
263 {SENSOR, OV7660_COM1, 0x00},
264 {SENSOR, OV7660_OFON, 0x0c},
265 {SENSOR, OV7660_COM2, 0x11},
266 {SENSOR, OV7660_COM7, 0x05},
267 {SENSOR, OV7660_BLUE_GAIN, 0x80},
268 {SENSOR, OV7660_RED_GAIN, 0x80},
269
270 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
271 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
272 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
273 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
274 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
275 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
276 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
277}; 261};
278 262
279#endif 263#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 0163903d1c0f..59400e858965 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -47,6 +47,12 @@ static
47 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550") 47 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
48 } 48 }
49 }, { 49 }, {
50 .ident = "Fujitsu-Siemens Amilo Pa 2548",
51 .matches = {
52 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
53 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
54 }
55 }, {
50 .ident = "MSI GX700", 56 .ident = "MSI GX700",
51 .matches = { 57 .matches = {
52 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 58 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
@@ -54,6 +60,13 @@ static
54 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007") 60 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
55 } 61 }
56 }, { 62 }, {
63 .ident = "MSI GX700",
64 .matches = {
65 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
66 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
67 DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
68 }
69 }, {
57 .ident = "MSI GX700/GX705/EX700", 70 .ident = "MSI GX700/GX705/EX700",
58 .matches = { 71 .matches = {
59 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 72 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 7af511b5e9c2..65489d6b0d89 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -50,7 +50,6 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
50 0x04, 0x40, address, 0, buf, len, 50 0x04, 0x40, address, 0, buf, len,
51 STV06XX_URB_MSG_TIMEOUT); 51 STV06XX_URB_MSG_TIMEOUT);
52 52
53
54 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d", 53 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
55 i2c_data, address, err); 54 i2c_data, address, err);
56 55
@@ -69,7 +68,7 @@ int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
69 68
70 *i2c_data = buf[0]; 69 *i2c_data = buf[0];
71 70
72 PDEBUG(D_CONF, "Read 0x%x from address 0x%x, status %d", 71 PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
73 *i2c_data, address, err); 72 *i2c_data, address, err);
74 73
75 return (err < 0) ? err : 0; 74 return (err < 0) ? err : 0;
@@ -111,14 +110,14 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
111 struct usb_device *udev = sd->gspca_dev.dev; 110 struct usb_device *udev = sd->gspca_dev.dev;
112 __u8 *buf = sd->gspca_dev.usb_buf; 111 __u8 *buf = sd->gspca_dev.usb_buf;
113 112
114 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len); 113 PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
115 for (i = 0; i < len;) { 114 for (i = 0; i < len;) {
116 /* Build the command buffer */ 115 /* Build the command buffer */
117 memset(buf, 0, I2C_BUFFER_LENGTH); 116 memset(buf, 0, I2C_BUFFER_LENGTH);
118 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) { 117 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
119 buf[j] = data[2*i]; 118 buf[j] = data[2*i];
120 buf[0x10 + j] = data[2*i+1]; 119 buf[0x10 + j] = data[2*i+1];
121 PDEBUG(D_USBO, "I2C: Writing 0x%02x to reg 0x%02x", 120 PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
122 data[2*i+1], data[2*i]); 121 data[2*i+1], data[2*i]);
123 } 122 }
124 buf[0x20] = sd->sensor->i2c_addr; 123 buf[0x20] = sd->sensor->i2c_addr;
@@ -128,8 +127,8 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
128 0x04, 0x40, 0x0400, 0, buf, 127 0x04, 0x40, 0x0400, 0, buf,
129 I2C_BUFFER_LENGTH, 128 I2C_BUFFER_LENGTH,
130 STV06XX_URB_MSG_TIMEOUT); 129 STV06XX_URB_MSG_TIMEOUT);
131 if (err < 0) 130 if (err < 0)
132 return err; 131 return err;
133 } 132 }
134 return stv06xx_write_sensor_finish(sd); 133 return stv06xx_write_sensor_finish(sd);
135} 134}
@@ -140,7 +139,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
140 struct usb_device *udev = sd->gspca_dev.dev; 139 struct usb_device *udev = sd->gspca_dev.dev;
141 __u8 *buf = sd->gspca_dev.usb_buf; 140 __u8 *buf = sd->gspca_dev.usb_buf;
142 141
143 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len); 142 PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
144 143
145 for (i = 0; i < len;) { 144 for (i = 0; i < len;) {
146 /* Build the command buffer */ 145 /* Build the command buffer */
@@ -149,7 +148,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
149 buf[j] = data[2*i]; 148 buf[j] = data[2*i];
150 buf[0x10 + j * 2] = data[2*i+1]; 149 buf[0x10 + j * 2] = data[2*i+1];
151 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8; 150 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
152 PDEBUG(D_USBO, "I2C: Writing 0x%04x to reg 0x%02x", 151 PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
153 data[2*i+1], data[2*i]); 152 data[2*i+1], data[2*i]);
154 } 153 }
155 buf[0x20] = sd->sensor->i2c_addr; 154 buf[0x20] = sd->sensor->i2c_addr;
@@ -189,7 +188,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
189 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, 188 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
190 STV06XX_URB_MSG_TIMEOUT); 189 STV06XX_URB_MSG_TIMEOUT);
191 if (err < 0) { 190 if (err < 0) {
192 PDEBUG(D_ERR, "I2C Read: error writing address: %d", err); 191 PDEBUG(D_ERR, "I2C: Read error writing address: %d", err);
193 return err; 192 return err;
194 } 193 }
195 194
@@ -201,7 +200,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
201 else 200 else
202 *value = buf[0]; 201 *value = buf[0];
203 202
204 PDEBUG(D_USBO, "I2C: Read 0x%x from address 0x%x, status: %d", 203 PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
205 *value, address, err); 204 *value, address, err);
206 205
207 return (err < 0) ? err : 0; 206 return (err < 0) ? err : 0;
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index e5024c8496ef..706e08dc5254 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -37,7 +37,7 @@ static const struct ctrl hdcs1x00_ctrl[] = {
37 .type = V4L2_CTRL_TYPE_INTEGER, 37 .type = V4L2_CTRL_TYPE_INTEGER,
38 .name = "exposure", 38 .name = "exposure",
39 .minimum = 0x00, 39 .minimum = 0x00,
40 .maximum = 0xffff, 40 .maximum = 0xff,
41 .step = 0x1, 41 .step = 0x1,
42 .default_value = HDCS_DEFAULT_EXPOSURE, 42 .default_value = HDCS_DEFAULT_EXPOSURE,
43 .flags = V4L2_CTRL_FLAG_SLIDER 43 .flags = V4L2_CTRL_FLAG_SLIDER
@@ -74,7 +74,35 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
74 } 74 }
75}; 75};
76 76
77static const struct ctrl hdcs1020_ctrl[] = {}; 77static const struct ctrl hdcs1020_ctrl[] = {
78 {
79 {
80 .id = V4L2_CID_EXPOSURE,
81 .type = V4L2_CTRL_TYPE_INTEGER,
82 .name = "exposure",
83 .minimum = 0x00,
84 .maximum = 0xffff,
85 .step = 0x1,
86 .default_value = HDCS_DEFAULT_EXPOSURE,
87 .flags = V4L2_CTRL_FLAG_SLIDER
88 },
89 .set = hdcs_set_exposure,
90 .get = hdcs_get_exposure
91 }, {
92 {
93 .id = V4L2_CID_GAIN,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "gain",
96 .minimum = 0x00,
97 .maximum = 0xff,
98 .step = 0x1,
99 .default_value = HDCS_DEFAULT_GAIN,
100 .flags = V4L2_CTRL_FLAG_SLIDER
101 },
102 .set = hdcs_set_gain,
103 .get = hdcs_get_gain
104 }
105};
78 106
79static struct v4l2_pix_format hdcs1020_mode[] = { 107static struct v4l2_pix_format hdcs1020_mode[] = {
80 { 108 {
@@ -120,6 +148,7 @@ struct hdcs {
120 } exp; 148 } exp;
121 149
122 int psmp; 150 int psmp;
151 u8 exp_cache, gain_cache;
123}; 152};
124 153
125static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 154static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
@@ -205,34 +234,8 @@ static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
205 struct sd *sd = (struct sd *) gspca_dev; 234 struct sd *sd = (struct sd *) gspca_dev;
206 struct hdcs *hdcs = sd->sensor_priv; 235 struct hdcs *hdcs = sd->sensor_priv;
207 236
208 /* Column time period */ 237 *val = hdcs->exp_cache;
209 int ct;
210 /* Column processing period */
211 int cp;
212 /* Row processing period */
213 int rp;
214 int cycles;
215 int err;
216 int rowexp;
217 u16 data[2];
218
219 err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
220 if (err < 0)
221 return err;
222
223 err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
224 if (err < 0)
225 return err;
226
227 rowexp = (data[1] << 8) | data[0];
228
229 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
230 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
231 rp = hdcs->exp.rs + cp;
232 238
233 cycles = rp * rowexp;
234 *val = cycles / HDCS_CLK_FREQ_MHZ;
235 PDEBUG(D_V4L2, "Read exposure %d", *val);
236 return 0; 239 return 0;
237} 240}
238 241
@@ -252,9 +255,12 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
252 within the column processing period */ 255 within the column processing period */
253 int mnct; 256 int mnct;
254 int cycles, err; 257 int cycles, err;
255 u8 exp[4]; 258 u8 exp[14];
256 259
257 cycles = val * HDCS_CLK_FREQ_MHZ; 260 val &= 0xff;
261 hdcs->exp_cache = val;
262
263 cycles = val * HDCS_CLK_FREQ_MHZ * 257;
258 264
259 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 265 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
260 cp = hdcs->exp.cto + (hdcs->w * ct / 2); 266 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
@@ -288,73 +294,79 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
288 srowexp = max_srowexp; 294 srowexp = max_srowexp;
289 295
290 if (IS_1020(sd)) { 296 if (IS_1020(sd)) {
291 exp[0] = rowexp & 0xff; 297 exp[0] = HDCS20_CONTROL;
292 exp[1] = rowexp >> 8; 298 exp[1] = 0x00; /* Stop streaming */
293 exp[2] = (srowexp >> 2) & 0xff; 299 exp[2] = HDCS_ROWEXPL;
294 /* this clears exposure error flag */ 300 exp[3] = rowexp & 0xff;
295 exp[3] = 0x1; 301 exp[4] = HDCS_ROWEXPH;
296 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4); 302 exp[5] = rowexp >> 8;
303 exp[6] = HDCS20_SROWEXP;
304 exp[7] = (srowexp >> 2) & 0xff;
305 exp[8] = HDCS20_ERROR;
306 exp[9] = 0x10; /* Clear exposure error flag*/
307 exp[10] = HDCS20_CONTROL;
308 exp[11] = 0x04; /* Restart streaming */
309 err = stv06xx_write_sensor_bytes(sd, exp, 6);
297 } else { 310 } else {
298 exp[0] = rowexp & 0xff; 311 exp[0] = HDCS00_CONTROL;
299 exp[1] = rowexp >> 8; 312 exp[1] = 0x00; /* Stop streaming */
300 exp[2] = srowexp & 0xff; 313 exp[2] = HDCS_ROWEXPL;
301 exp[3] = srowexp >> 8; 314 exp[3] = rowexp & 0xff;
302 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4); 315 exp[4] = HDCS_ROWEXPH;
316 exp[5] = rowexp >> 8;
317 exp[6] = HDCS00_SROWEXPL;
318 exp[7] = srowexp & 0xff;
319 exp[8] = HDCS00_SROWEXPH;
320 exp[9] = srowexp >> 8;
321 exp[10] = HDCS_STATUS;
322 exp[11] = 0x10; /* Clear exposure error flag*/
323 exp[12] = HDCS00_CONTROL;
324 exp[13] = 0x04; /* Restart streaming */
325 err = stv06xx_write_sensor_bytes(sd, exp, 7);
303 if (err < 0) 326 if (err < 0)
304 return err; 327 return err;
305
306 /* clear exposure error flag */
307 err = stv06xx_write_sensor(sd,
308 HDCS_STATUS, BIT(4));
309 } 328 }
310 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", 329 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
311 val, rowexp, srowexp); 330 val, rowexp, srowexp);
312 return err; 331 return err;
313} 332}
314 333
315static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b) 334static int hdcs_set_gains(struct sd *sd, u8 g)
316{ 335{
336 struct hdcs *hdcs = sd->sensor_priv;
337 int err;
317 u8 gains[4]; 338 u8 gains[4];
318 339
340 hdcs->gain_cache = g;
341
319 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 342 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
320 if (r > 127)
321 r = 0x80 | (r / 2);
322 if (g > 127) 343 if (g > 127)
323 g = 0x80 | (g / 2); 344 g = 0x80 | (g / 2);
324 if (b > 127)
325 b = 0x80 | (b / 2);
326 345
327 gains[0] = g; 346 gains[0] = g;
328 gains[1] = r; 347 gains[1] = g;
329 gains[2] = b; 348 gains[2] = g;
330 gains[3] = g; 349 gains[3] = g;
331 350
332 return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 351 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
352 return err;
333} 353}
334 354
335static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 355static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
336{ 356{
337 struct sd *sd = (struct sd *) gspca_dev; 357 struct sd *sd = (struct sd *) gspca_dev;
338 int err; 358 struct hdcs *hdcs = sd->sensor_priv;
339 u16 data;
340
341 err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
342 359
343 /* Bit 7 doubles the gain */ 360 *val = hdcs->gain_cache;
344 if (data & 0x80)
345 *val = (data & 0x7f) * 2;
346 else
347 *val = data;
348 361
349 PDEBUG(D_V4L2, "Read gain %d", *val); 362 return 0;
350 return err;
351} 363}
352 364
353static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 365static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
354{ 366{
355 PDEBUG(D_V4L2, "Writing gain %d", val); 367 PDEBUG(D_V4L2, "Writing gain %d", val);
356 return hdcs_set_gains((struct sd *) gspca_dev, 368 return hdcs_set_gains((struct sd *) gspca_dev,
357 val & 0xff, val & 0xff, val & 0xff); 369 val & 0xff);
358} 370}
359 371
360static int hdcs_set_size(struct sd *sd, 372static int hdcs_set_size(struct sd *sd,
@@ -572,16 +584,15 @@ static int hdcs_init(struct sd *sd)
572 if (err < 0) 584 if (err < 0)
573 return err; 585 return err;
574 586
575 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN, 587 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN);
576 HDCS_DEFAULT_GAIN);
577 if (err < 0) 588 if (err < 0)
578 return err; 589 return err;
579 590
580 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE); 591 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
581 if (err < 0) 592 if (err < 0)
582 return err; 593 return err;
583 594
584 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); 595 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
585 return err; 596 return err;
586} 597}
587 598
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 412f06cf3d5c..37b31c99d956 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -124,7 +124,7 @@
124#define HDCS_RUN_ENABLE (1 << 2) 124#define HDCS_RUN_ENABLE (1 << 2)
125#define HDCS_SLEEP_MODE (1 << 1) 125#define HDCS_SLEEP_MODE (1 << 1)
126 126
127#define HDCS_DEFAULT_EXPOSURE 5000 127#define HDCS_DEFAULT_EXPOSURE 48
128#define HDCS_DEFAULT_GAIN 128 128#define HDCS_DEFAULT_GAIN 128
129 129
130static int hdcs_probe_1x00(struct sd *sd); 130static int hdcs_probe_1x00(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 87cb5b9ddfa7..c11f06e4ae76 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -166,7 +166,7 @@ static int st6422_init(struct sd *sd)
166/* 10 compressed? */ 166/* 10 compressed? */
167 167
168 { 0x1439, 0x00 }, 168 { 0x1439, 0x00 },
169/* antiflimmer?? 0xa2 ger perfekt bild mot monitor */ 169/* anti-noise? 0xa2 gives a perfect image */
170 170
171 { 0x143b, 0x05 }, 171 { 0x143b, 0x05 },
172 { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ 172 { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */
@@ -197,15 +197,14 @@ static int st6422_init(struct sd *sd)
197 { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ 197 { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */
198 198
199 { 0x1501, 0xaf }, 199 { 0x1501, 0xaf },
200/* high val-> ljus area blir morkare. */ 200/* high val-> light area gets darker */
201/* low val -> ljus area blir ljusare. */ 201/* low val -> light area gets lighter */
202 { 0x1502, 0xc2 }, 202 { 0x1502, 0xc2 },
203/* high val-> ljus area blir morkare. */ 203/* high val-> light area gets darker */
204/* low val -> ljus area blir ljusare. */ 204/* low val -> light area gets lighter */
205 { 0x1503, 0x45 }, 205 { 0x1503, 0x45 },
206/* high val-> ljus area blir morkare. */ 206/* high val-> light area gets darker */
207/* low val -> ljus area blir ljusare. */ 207/* low val -> light area gets lighter */
208
209 { 0x1505, 0x02 }, 208 { 0x1505, 0x02 },
210/* 2 : 324x248 80352 bytes */ 209/* 2 : 324x248 80352 bytes */
211/* 7 : 248x162 40176 bytes */ 210/* 7 : 248x162 40176 bytes */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 619250e70718..589042f6adbe 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2946,7 +2946,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000); 2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
2947 break; 2947 break;
2948 default: 2948 default:
2949 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 2949 if (!(sd->flags & FL_SAMSUNG))
2950 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
2950 break; 2951 break;
2951 } 2952 }
2952 msleep(100); 2953 msleep(100);
@@ -2964,7 +2965,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2964 2965
2965 if (sd->sensor == SENSOR_MI1310_SOC) 2966 if (sd->sensor == SENSOR_MI1310_SOC)
2966 reg_w(dev, 0x89, 0x058c, 0x00ff); 2967 reg_w(dev, 0x89, 0x058c, 0x00ff);
2967 else 2968 else if (!(sd->flags & FL_SAMSUNG))
2968 reg_w(dev, 0x89, 0xffff, 0xffff); 2969 reg_w(dev, 0x89, 0xffff, 0xffff);
2969 reg_w(dev, 0xa0, 0x01, 0xb301); 2970 reg_w(dev, 0xa0, 0x01, 0xb301);
2970 reg_w(dev, 0xa0, 0x09, 0xb003); 2971 reg_w(dev, 0xa0, 0x09, 0xb003);
@@ -2981,7 +2982,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2981/*fixme: is this useful?*/ 2982/*fixme: is this useful?*/
2982 if (sd->sensor == SENSOR_MI1310_SOC) 2983 if (sd->sensor == SENSOR_MI1310_SOC)
2983 reg_w(dev, 0x89, 0x058c, 0x00ff); 2984 reg_w(dev, 0x89, 0x058c, 0x00ff);
2984 else 2985 else if (!(sd->flags & FL_SAMSUNG))
2985 reg_w(dev, 0x89, 0xffff, 0xffff); 2986 reg_w(dev, 0x89, 0xffff, 0xffff);
2986} 2987}
2987 2988
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 63ea0fb66063..463ec3457d7b 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -246,7 +246,7 @@ MODULE_PARM_DESC(newi2c,
246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" 246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
247 "\t\t\tDefault is autodetect"); 247 "\t\t\tDefault is autodetect");
248 248
249MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card"); 249MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
250 250
251MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); 251MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
252MODULE_DESCRIPTION("CX23415/CX23416 driver"); 252MODULE_DESCRIPTION("CX23415/CX23416 driver");
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 8f15a31d3f66..b9c71e61f7d6 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -161,19 +161,19 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
161 return -1; 161 return -1;
162 if (hw == IVTV_HW_TUNER) { 162 if (hw == IVTV_HW_TUNER) {
163 /* special tuner handling */ 163 /* special tuner handling */
164 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 164 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
165 adap, mod, type, 165 adap, mod, type,
166 itv->card_i2c->radio); 166 0, itv->card_i2c->radio);
167 if (sd) 167 if (sd)
168 sd->grp_id = 1 << idx; 168 sd->grp_id = 1 << idx;
169 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 169 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
170 adap, mod, type, 170 adap, mod, type,
171 itv->card_i2c->demod); 171 0, itv->card_i2c->demod);
172 if (sd) 172 if (sd)
173 sd->grp_id = 1 << idx; 173 sd->grp_id = 1 << idx;
174 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 174 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
175 adap, mod, type, 175 adap, mod, type,
176 itv->card_i2c->tv); 176 0, itv->card_i2c->tv);
177 if (sd) 177 if (sd)
178 sd->grp_id = 1 << idx; 178 sd->grp_id = 1 << idx;
179 return sd ? 0 : -1; 179 return sd ? 0 : -1;
@@ -181,11 +181,11 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
181 if (!hw_addrs[idx]) 181 if (!hw_addrs[idx])
182 return -1; 182 return -1;
183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { 183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
184 sd = v4l2_i2c_new_probed_subdev_addr(&itv->v4l2_dev, 184 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
185 adap, mod, type, hw_addrs[idx]); 185 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
186 } else { 186 } else {
187 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 187 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
188 adap, mod, type, hw_addrs[idx]); 188 adap, mod, type, hw_addrs[idx], NULL);
189 } 189 }
190 if (sd) 190 if (sd)
191 sd->grp_id = 1 << idx; 191 sd->grp_id = 1 << idx;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 15da01710efc..67699e3f2aaa 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -261,8 +261,8 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
261 video_set_drvdata(s->vdev, s); 261 video_set_drvdata(s->vdev, s);
262 262
263 /* Register device. First try the desired minor, then any free one. */ 263 /* Register device. First try the desired minor, then any free one. */
264 if (video_register_device(s->vdev, vfl_type, num)) { 264 if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
265 IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", 265 IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
266 s->name, num); 266 s->name, num);
267 video_device_release(s->vdev); 267 video_device_release(s->vdev);
268 s->vdev = NULL; 268 s->vdev = NULL;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 4d794b42d6cd..45388d2ce2fd 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -13,13 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/v4l2-common.h> 16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19 19
20/* mt9m001 i2c address 0x5d 20/* mt9m001 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define ctruct i2c_board_info objects and link to them
22 * and call i2c_register_board_info() */ 22 * from struct soc_camera_link */
23 23
24/* mt9m001 selected register addresses */ 24/* mt9m001 selected register addresses */
25#define MT9M001_CHIP_VERSION 0x00 25#define MT9M001_CHIP_VERSION 0x00
@@ -39,6 +39,13 @@
39#define MT9M001_GLOBAL_GAIN 0x35 39#define MT9M001_GLOBAL_GAIN 0x35
40#define MT9M001_CHIP_ENABLE 0xF1 40#define MT9M001_CHIP_ENABLE 0xF1
41 41
42#define MT9M001_MAX_WIDTH 1280
43#define MT9M001_MAX_HEIGHT 1024
44#define MT9M001_MIN_WIDTH 48
45#define MT9M001_MIN_HEIGHT 32
46#define MT9M001_COLUMN_SKIP 20
47#define MT9M001_ROW_SKIP 12
48
42static const struct soc_camera_data_format mt9m001_colour_formats[] = { 49static const struct soc_camera_data_format mt9m001_colour_formats[] = {
43 /* Order important: first natively supported, 50 /* Order important: first natively supported,
44 * second supported with a GPIO extender */ 51 * second supported with a GPIO extender */
@@ -69,12 +76,20 @@ static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
69}; 76};
70 77
71struct mt9m001 { 78struct mt9m001 {
72 struct i2c_client *client; 79 struct v4l2_subdev subdev;
73 struct soc_camera_device icd; 80 struct v4l2_rect rect; /* Sensor window */
81 __u32 fourcc;
74 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 82 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
83 unsigned int gain;
84 unsigned int exposure;
75 unsigned char autoexposure; 85 unsigned char autoexposure;
76}; 86};
77 87
88static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
89{
90 return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
91}
92
78static int reg_read(struct i2c_client *client, const u8 reg) 93static int reg_read(struct i2c_client *client, const u8 reg)
79{ 94{
80 s32 data = i2c_smbus_read_word_data(client, reg); 95 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -109,35 +124,20 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
109 return reg_write(client, reg, ret & ~data); 124 return reg_write(client, reg, ret & ~data);
110} 125}
111 126
112static int mt9m001_init(struct soc_camera_device *icd) 127static int mt9m001_init(struct i2c_client *client)
113{ 128{
114 struct i2c_client *client = to_i2c_client(icd->control);
115 struct soc_camera_link *icl = client->dev.platform_data;
116 int ret; 129 int ret;
117 130
118 dev_dbg(icd->vdev->parent, "%s\n", __func__); 131 dev_dbg(&client->dev, "%s\n", __func__);
119 132
120 if (icl->power) { 133 /*
121 ret = icl->power(&client->dev, 1); 134 * We don't know, whether platform provides reset, issue a soft reset
122 if (ret < 0) { 135 * too. This returns all registers to their default values.
123 dev_err(icd->vdev->parent, 136 */
124 "Platform failed to power-on the camera.\n"); 137 ret = reg_write(client, MT9M001_RESET, 1);
125 return ret; 138 if (!ret)
126 } 139 ret = reg_write(client, MT9M001_RESET, 0);
127 }
128
129 /* The camera could have been already on, we reset it additionally */
130 if (icl->reset)
131 ret = icl->reset(&client->dev);
132 else
133 ret = -ENODEV;
134 140
135 if (ret < 0) {
136 /* Either no platform reset, or platform reset failed */
137 ret = reg_write(client, MT9M001_RESET, 1);
138 if (!ret)
139 ret = reg_write(client, MT9M001_RESET, 0);
140 }
141 /* Disable chip, synchronous option update */ 141 /* Disable chip, synchronous option update */
142 if (!ret) 142 if (!ret)
143 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0); 143 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
@@ -145,36 +145,12 @@ static int mt9m001_init(struct soc_camera_device *icd)
145 return ret; 145 return ret;
146} 146}
147 147
148static int mt9m001_release(struct soc_camera_device *icd) 148static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
149{ 149{
150 struct i2c_client *client = to_i2c_client(icd->control); 150 struct i2c_client *client = sd->priv;
151 struct soc_camera_link *icl = client->dev.platform_data;
152
153 /* Disable the chip */
154 reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
155
156 if (icl->power)
157 icl->power(&client->dev, 0);
158
159 return 0;
160}
161 151
162static int mt9m001_start_capture(struct soc_camera_device *icd) 152 /* Switch to master "normal" mode or stop sensor readout */
163{ 153 if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
164 struct i2c_client *client = to_i2c_client(icd->control);
165
166 /* Switch to master "normal" mode */
167 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
168 return -EIO;
169 return 0;
170}
171
172static int mt9m001_stop_capture(struct soc_camera_device *icd)
173{
174 struct i2c_client *client = to_i2c_client(icd->control);
175
176 /* Stop sensor readout */
177 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
178 return -EIO; 154 return -EIO;
179 return 0; 155 return 0;
180} 156}
@@ -182,8 +158,7 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd)
182static int mt9m001_set_bus_param(struct soc_camera_device *icd, 158static int mt9m001_set_bus_param(struct soc_camera_device *icd,
183 unsigned long flags) 159 unsigned long flags)
184{ 160{
185 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 161 struct soc_camera_link *icl = to_soc_camera_link(icd);
186 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
187 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; 162 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
188 163
189 /* Only one width bit may be set */ 164 /* Only one width bit may be set */
@@ -205,8 +180,7 @@ static int mt9m001_set_bus_param(struct soc_camera_device *icd,
205 180
206static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) 181static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
207{ 182{
208 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 183 struct soc_camera_link *icl = to_soc_camera_link(icd);
209 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
210 /* MT9M001 has all capture_format parameters fixed */ 184 /* MT9M001 has all capture_format parameters fixed */
211 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING | 185 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
212 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 186 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
@@ -220,13 +194,35 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
220 return soc_camera_apply_sensor_flags(icl, flags); 194 return soc_camera_apply_sensor_flags(icl, flags);
221} 195}
222 196
223static int mt9m001_set_crop(struct soc_camera_device *icd, 197static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
224 struct v4l2_rect *rect)
225{ 198{
226 struct i2c_client *client = to_i2c_client(icd->control); 199 struct i2c_client *client = sd->priv;
227 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 200 struct mt9m001 *mt9m001 = to_mt9m001(client);
201 struct v4l2_rect rect = a->c;
202 struct soc_camera_device *icd = client->dev.platform_data;
228 int ret; 203 int ret;
229 const u16 hblank = 9, vblank = 25; 204 const u16 hblank = 9, vblank = 25;
205 unsigned int total_h;
206
207 if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
208 mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
209 /*
210 * Bayer format - even number of rows for simplicity,
211 * but let the user play with the top row.
212 */
213 rect.height = ALIGN(rect.height, 2);
214
215 /* Datasheet requirement: see register description */
216 rect.width = ALIGN(rect.width, 2);
217 rect.left = ALIGN(rect.left, 2);
218
219 soc_camera_limit_side(&rect.left, &rect.width,
220 MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
221
222 soc_camera_limit_side(&rect.top, &rect.height,
223 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
224
225 total_h = rect.height + icd->y_skip_top + vblank;
230 226
231 /* Blanking and start values - default... */ 227 /* Blanking and start values - default... */
232 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); 228 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -236,66 +232,126 @@ static int mt9m001_set_crop(struct soc_camera_device *icd,
236 /* The caller provides a supported format, as verified per 232 /* The caller provides a supported format, as verified per
237 * call to icd->try_fmt() */ 233 * call to icd->try_fmt() */
238 if (!ret) 234 if (!ret)
239 ret = reg_write(client, MT9M001_COLUMN_START, rect->left); 235 ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
240 if (!ret) 236 if (!ret)
241 ret = reg_write(client, MT9M001_ROW_START, rect->top); 237 ret = reg_write(client, MT9M001_ROW_START, rect.top);
242 if (!ret) 238 if (!ret)
243 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1); 239 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
244 if (!ret) 240 if (!ret)
245 ret = reg_write(client, MT9M001_WINDOW_HEIGHT, 241 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
246 rect->height + icd->y_skip_top - 1); 242 rect.height + icd->y_skip_top - 1);
247 if (!ret && mt9m001->autoexposure) { 243 if (!ret && mt9m001->autoexposure) {
248 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, 244 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
249 rect->height + icd->y_skip_top + vblank);
250 if (!ret) { 245 if (!ret) {
251 const struct v4l2_queryctrl *qctrl = 246 const struct v4l2_queryctrl *qctrl =
252 soc_camera_find_qctrl(icd->ops, 247 soc_camera_find_qctrl(icd->ops,
253 V4L2_CID_EXPOSURE); 248 V4L2_CID_EXPOSURE);
254 icd->exposure = (524 + (rect->height + icd->y_skip_top + 249 mt9m001->exposure = (524 + (total_h - 1) *
255 vblank - 1) * 250 (qctrl->maximum - qctrl->minimum)) /
256 (qctrl->maximum - qctrl->minimum)) /
257 1048 + qctrl->minimum; 251 1048 + qctrl->minimum;
258 } 252 }
259 } 253 }
260 254
255 if (!ret)
256 mt9m001->rect = rect;
257
261 return ret; 258 return ret;
262} 259}
263 260
264static int mt9m001_set_fmt(struct soc_camera_device *icd, 261static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
265 struct v4l2_format *f) 262{
263 struct i2c_client *client = sd->priv;
264 struct mt9m001 *mt9m001 = to_mt9m001(client);
265
266 a->c = mt9m001->rect;
267 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
268
269 return 0;
270}
271
272static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
273{
274 a->bounds.left = MT9M001_COLUMN_SKIP;
275 a->bounds.top = MT9M001_ROW_SKIP;
276 a->bounds.width = MT9M001_MAX_WIDTH;
277 a->bounds.height = MT9M001_MAX_HEIGHT;
278 a->defrect = a->bounds;
279 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
280 a->pixelaspect.numerator = 1;
281 a->pixelaspect.denominator = 1;
282
283 return 0;
284}
285
286static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
266{ 287{
267 struct v4l2_rect rect = { 288 struct i2c_client *client = sd->priv;
268 .left = icd->x_current, 289 struct mt9m001 *mt9m001 = to_mt9m001(client);
269 .top = icd->y_current, 290 struct v4l2_pix_format *pix = &f->fmt.pix;
270 .width = f->fmt.pix.width, 291
271 .height = f->fmt.pix.height, 292 pix->width = mt9m001->rect.width;
293 pix->height = mt9m001->rect.height;
294 pix->pixelformat = mt9m001->fourcc;
295 pix->field = V4L2_FIELD_NONE;
296 pix->colorspace = V4L2_COLORSPACE_SRGB;
297
298 return 0;
299}
300
301static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
302{
303 struct i2c_client *client = sd->priv;
304 struct mt9m001 *mt9m001 = to_mt9m001(client);
305 struct v4l2_pix_format *pix = &f->fmt.pix;
306 struct v4l2_crop a = {
307 .c = {
308 .left = mt9m001->rect.left,
309 .top = mt9m001->rect.top,
310 .width = pix->width,
311 .height = pix->height,
312 },
272 }; 313 };
314 int ret;
273 315
274 /* No support for scaling so far, just crop. TODO: use skipping */ 316 /* No support for scaling so far, just crop. TODO: use skipping */
275 return mt9m001_set_crop(icd, &rect); 317 ret = mt9m001_s_crop(sd, &a);
318 if (!ret) {
319 pix->width = mt9m001->rect.width;
320 pix->height = mt9m001->rect.height;
321 mt9m001->fourcc = pix->pixelformat;
322 }
323
324 return ret;
276} 325}
277 326
278static int mt9m001_try_fmt(struct soc_camera_device *icd, 327static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
279 struct v4l2_format *f)
280{ 328{
329 struct i2c_client *client = sd->priv;
330 struct soc_camera_device *icd = client->dev.platform_data;
281 struct v4l2_pix_format *pix = &f->fmt.pix; 331 struct v4l2_pix_format *pix = &f->fmt.pix;
282 332
283 v4l_bound_align_image(&pix->width, 48, 1280, 1, 333 v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
284 &pix->height, 32 + icd->y_skip_top, 334 MT9M001_MAX_WIDTH, 1,
285 1024 + icd->y_skip_top, 0, 0); 335 &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top,
336 MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0);
337
338 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
339 pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
340 pix->height = ALIGN(pix->height - 1, 2);
286 341
287 return 0; 342 return 0;
288} 343}
289 344
290static int mt9m001_get_chip_id(struct soc_camera_device *icd, 345static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
291 struct v4l2_dbg_chip_ident *id) 346 struct v4l2_dbg_chip_ident *id)
292{ 347{
293 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 348 struct i2c_client *client = sd->priv;
349 struct mt9m001 *mt9m001 = to_mt9m001(client);
294 350
295 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 351 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
296 return -EINVAL; 352 return -EINVAL;
297 353
298 if (id->match.addr != mt9m001->client->addr) 354 if (id->match.addr != client->addr)
299 return -ENODEV; 355 return -ENODEV;
300 356
301 id->ident = mt9m001->model; 357 id->ident = mt9m001->model;
@@ -305,10 +361,10 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
305} 361}
306 362
307#ifdef CONFIG_VIDEO_ADV_DEBUG 363#ifdef CONFIG_VIDEO_ADV_DEBUG
308static int mt9m001_get_register(struct soc_camera_device *icd, 364static int mt9m001_g_register(struct v4l2_subdev *sd,
309 struct v4l2_dbg_register *reg) 365 struct v4l2_dbg_register *reg)
310{ 366{
311 struct i2c_client *client = to_i2c_client(icd->control); 367 struct i2c_client *client = sd->priv;
312 368
313 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 369 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
314 return -EINVAL; 370 return -EINVAL;
@@ -325,10 +381,10 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
325 return 0; 381 return 0;
326} 382}
327 383
328static int mt9m001_set_register(struct soc_camera_device *icd, 384static int mt9m001_s_register(struct v4l2_subdev *sd,
329 struct v4l2_dbg_register *reg) 385 struct v4l2_dbg_register *reg)
330{ 386{
331 struct i2c_client *client = to_i2c_client(icd->control); 387 struct i2c_client *client = sd->priv;
332 388
333 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 389 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
334 return -EINVAL; 390 return -EINVAL;
@@ -381,39 +437,17 @@ static const struct v4l2_queryctrl mt9m001_controls[] = {
381 } 437 }
382}; 438};
383 439
384static int mt9m001_video_probe(struct soc_camera_device *);
385static void mt9m001_video_remove(struct soc_camera_device *);
386static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
387static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
388
389static struct soc_camera_ops mt9m001_ops = { 440static struct soc_camera_ops mt9m001_ops = {
390 .owner = THIS_MODULE,
391 .probe = mt9m001_video_probe,
392 .remove = mt9m001_video_remove,
393 .init = mt9m001_init,
394 .release = mt9m001_release,
395 .start_capture = mt9m001_start_capture,
396 .stop_capture = mt9m001_stop_capture,
397 .set_crop = mt9m001_set_crop,
398 .set_fmt = mt9m001_set_fmt,
399 .try_fmt = mt9m001_try_fmt,
400 .set_bus_param = mt9m001_set_bus_param, 441 .set_bus_param = mt9m001_set_bus_param,
401 .query_bus_param = mt9m001_query_bus_param, 442 .query_bus_param = mt9m001_query_bus_param,
402 .controls = mt9m001_controls, 443 .controls = mt9m001_controls,
403 .num_controls = ARRAY_SIZE(mt9m001_controls), 444 .num_controls = ARRAY_SIZE(mt9m001_controls),
404 .get_control = mt9m001_get_control,
405 .set_control = mt9m001_set_control,
406 .get_chip_id = mt9m001_get_chip_id,
407#ifdef CONFIG_VIDEO_ADV_DEBUG
408 .get_register = mt9m001_get_register,
409 .set_register = mt9m001_set_register,
410#endif
411}; 445};
412 446
413static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 447static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
414{ 448{
415 struct i2c_client *client = to_i2c_client(icd->control); 449 struct i2c_client *client = sd->priv;
416 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 450 struct mt9m001 *mt9m001 = to_mt9m001(client);
417 int data; 451 int data;
418 452
419 switch (ctrl->id) { 453 switch (ctrl->id) {
@@ -426,14 +460,21 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
426 case V4L2_CID_EXPOSURE_AUTO: 460 case V4L2_CID_EXPOSURE_AUTO:
427 ctrl->value = mt9m001->autoexposure; 461 ctrl->value = mt9m001->autoexposure;
428 break; 462 break;
463 case V4L2_CID_GAIN:
464 ctrl->value = mt9m001->gain;
465 break;
466 case V4L2_CID_EXPOSURE:
467 ctrl->value = mt9m001->exposure;
468 break;
429 } 469 }
430 return 0; 470 return 0;
431} 471}
432 472
433static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 473static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
434{ 474{
435 struct i2c_client *client = to_i2c_client(icd->control); 475 struct i2c_client *client = sd->priv;
436 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 476 struct mt9m001 *mt9m001 = to_mt9m001(client);
477 struct soc_camera_device *icd = client->dev.platform_data;
437 const struct v4l2_queryctrl *qctrl; 478 const struct v4l2_queryctrl *qctrl;
438 int data; 479 int data;
439 480
@@ -460,7 +501,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
460 unsigned long range = qctrl->default_value - qctrl->minimum; 501 unsigned long range = qctrl->default_value - qctrl->minimum;
461 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 502 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
462 503
463 dev_dbg(&icd->dev, "Setting gain %d\n", data); 504 dev_dbg(&client->dev, "Setting gain %d\n", data);
464 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 505 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
465 if (data < 0) 506 if (data < 0)
466 return -EIO; 507 return -EIO;
@@ -478,7 +519,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
478 else 519 else
479 data = ((gain - 64) * 7 + 28) / 56 + 96; 520 data = ((gain - 64) * 7 + 28) / 56 + 96;
480 521
481 dev_dbg(&icd->dev, "Setting gain from %d to %d\n", 522 dev_dbg(&client->dev, "Setting gain from %d to %d\n",
482 reg_read(client, MT9M001_GLOBAL_GAIN), data); 523 reg_read(client, MT9M001_GLOBAL_GAIN), data);
483 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 524 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
484 if (data < 0) 525 if (data < 0)
@@ -486,7 +527,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
486 } 527 }
487 528
488 /* Success */ 529 /* Success */
489 icd->gain = ctrl->value; 530 mt9m001->gain = ctrl->value;
490 break; 531 break;
491 case V4L2_CID_EXPOSURE: 532 case V4L2_CID_EXPOSURE:
492 /* mt9m001 has maximum == default */ 533 /* mt9m001 has maximum == default */
@@ -497,23 +538,27 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
497 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 + 538 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
498 range / 2) / range + 1; 539 range / 2) / range + 1;
499 540
500 dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", 541 dev_dbg(&client->dev,
501 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter); 542 "Setting shutter width from %d to %lu\n",
543 reg_read(client, MT9M001_SHUTTER_WIDTH),
544 shutter);
502 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) 545 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
503 return -EIO; 546 return -EIO;
504 icd->exposure = ctrl->value; 547 mt9m001->exposure = ctrl->value;
505 mt9m001->autoexposure = 0; 548 mt9m001->autoexposure = 0;
506 } 549 }
507 break; 550 break;
508 case V4L2_CID_EXPOSURE_AUTO: 551 case V4L2_CID_EXPOSURE_AUTO:
509 if (ctrl->value) { 552 if (ctrl->value) {
510 const u16 vblank = 25; 553 const u16 vblank = 25;
511 if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height + 554 unsigned int total_h = mt9m001->rect.height +
512 icd->y_skip_top + vblank) < 0) 555 icd->y_skip_top + vblank;
556 if (reg_write(client, MT9M001_SHUTTER_WIDTH,
557 total_h) < 0)
513 return -EIO; 558 return -EIO;
514 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 559 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
515 icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) * 560 mt9m001->exposure = (524 + (total_h - 1) *
516 (qctrl->maximum - qctrl->minimum)) / 561 (qctrl->maximum - qctrl->minimum)) /
517 1048 + qctrl->minimum; 562 1048 + qctrl->minimum;
518 mt9m001->autoexposure = 1; 563 mt9m001->autoexposure = 1;
519 } else 564 } else
@@ -525,14 +570,14 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
525 570
526/* Interface active, can use i2c. If it fails, it can indeed mean, that 571/* Interface active, can use i2c. If it fails, it can indeed mean, that
527 * this wasn't our capture interface, so, we wait for the right one */ 572 * this wasn't our capture interface, so, we wait for the right one */
528static int mt9m001_video_probe(struct soc_camera_device *icd) 573static int mt9m001_video_probe(struct soc_camera_device *icd,
574 struct i2c_client *client)
529{ 575{
530 struct i2c_client *client = to_i2c_client(icd->control); 576 struct mt9m001 *mt9m001 = to_mt9m001(client);
531 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 577 struct soc_camera_link *icl = to_soc_camera_link(icd);
532 struct soc_camera_link *icl = client->dev.platform_data;
533 s32 data; 578 s32 data;
534 int ret;
535 unsigned long flags; 579 unsigned long flags;
580 int ret;
536 581
537 /* We must have a parent by now. And it cannot be a wrong one. 582 /* We must have a parent by now. And it cannot be a wrong one.
538 * So this entire test is completely redundant. */ 583 * So this entire test is completely redundant. */
@@ -542,7 +587,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
542 587
543 /* Enable the chip */ 588 /* Enable the chip */
544 data = reg_write(client, MT9M001_CHIP_ENABLE, 1); 589 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
545 dev_dbg(&icd->dev, "write: %d\n", data); 590 dev_dbg(&client->dev, "write: %d\n", data);
546 591
547 /* Read out the chip version register */ 592 /* Read out the chip version register */
548 data = reg_read(client, MT9M001_CHIP_VERSION); 593 data = reg_read(client, MT9M001_CHIP_VERSION);
@@ -559,10 +604,9 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
559 icd->formats = mt9m001_monochrome_formats; 604 icd->formats = mt9m001_monochrome_formats;
560 break; 605 break;
561 default: 606 default:
562 ret = -ENODEV; 607 dev_err(&client->dev,
563 dev_err(&icd->dev,
564 "No MT9M001 chip detected, register read %x\n", data); 608 "No MT9M001 chip detected, register read %x\n", data);
565 goto ei2c; 609 return -ENODEV;
566 } 610 }
567 611
568 icd->num_formats = 0; 612 icd->num_formats = 0;
@@ -585,42 +629,72 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
585 if (flags & SOCAM_DATAWIDTH_8) 629 if (flags & SOCAM_DATAWIDTH_8)
586 icd->num_formats++; 630 icd->num_formats++;
587 631
588 dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, 632 mt9m001->fourcc = icd->formats->fourcc;
633
634 dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
589 data == 0x8431 ? "C12STM" : "C12ST"); 635 data == 0x8431 ? "C12STM" : "C12ST");
590 636
591 /* Now that we know the model, we can start video */ 637 ret = mt9m001_init(client);
592 ret = soc_camera_video_start(icd); 638 if (ret < 0)
593 if (ret) 639 dev_err(&client->dev, "Failed to initialise the camera\n");
594 goto eisis;
595 640
596 return 0; 641 /* mt9m001_init() has reset the chip, returning registers to defaults */
642 mt9m001->gain = 64;
643 mt9m001->exposure = 255;
597 644
598eisis:
599ei2c:
600 return ret; 645 return ret;
601} 646}
602 647
603static void mt9m001_video_remove(struct soc_camera_device *icd) 648static void mt9m001_video_remove(struct soc_camera_device *icd)
604{ 649{
605 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 650 struct soc_camera_link *icl = to_soc_camera_link(icd);
606 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
607 651
608 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, 652 dev_dbg(&icd->dev, "Video removed: %p, %p\n",
609 icd->dev.parent, icd->vdev); 653 icd->dev.parent, icd->vdev);
610 soc_camera_video_stop(icd);
611 if (icl->free_bus) 654 if (icl->free_bus)
612 icl->free_bus(icl); 655 icl->free_bus(icl);
613} 656}
614 657
658static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
659 .g_ctrl = mt9m001_g_ctrl,
660 .s_ctrl = mt9m001_s_ctrl,
661 .g_chip_ident = mt9m001_g_chip_ident,
662#ifdef CONFIG_VIDEO_ADV_DEBUG
663 .g_register = mt9m001_g_register,
664 .s_register = mt9m001_s_register,
665#endif
666};
667
668static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
669 .s_stream = mt9m001_s_stream,
670 .s_fmt = mt9m001_s_fmt,
671 .g_fmt = mt9m001_g_fmt,
672 .try_fmt = mt9m001_try_fmt,
673 .s_crop = mt9m001_s_crop,
674 .g_crop = mt9m001_g_crop,
675 .cropcap = mt9m001_cropcap,
676};
677
678static struct v4l2_subdev_ops mt9m001_subdev_ops = {
679 .core = &mt9m001_subdev_core_ops,
680 .video = &mt9m001_subdev_video_ops,
681};
682
615static int mt9m001_probe(struct i2c_client *client, 683static int mt9m001_probe(struct i2c_client *client,
616 const struct i2c_device_id *did) 684 const struct i2c_device_id *did)
617{ 685{
618 struct mt9m001 *mt9m001; 686 struct mt9m001 *mt9m001;
619 struct soc_camera_device *icd; 687 struct soc_camera_device *icd = client->dev.platform_data;
620 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 688 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
621 struct soc_camera_link *icl = client->dev.platform_data; 689 struct soc_camera_link *icl;
622 int ret; 690 int ret;
623 691
692 if (!icd) {
693 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
694 return -EINVAL;
695 }
696
697 icl = to_soc_camera_link(icd);
624 if (!icl) { 698 if (!icl) {
625 dev_err(&client->dev, "MT9M001 driver needs platform data\n"); 699 dev_err(&client->dev, "MT9M001 driver needs platform data\n");
626 return -EINVAL; 700 return -EINVAL;
@@ -636,43 +710,40 @@ static int mt9m001_probe(struct i2c_client *client,
636 if (!mt9m001) 710 if (!mt9m001)
637 return -ENOMEM; 711 return -ENOMEM;
638 712
639 mt9m001->client = client; 713 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
640 i2c_set_clientdata(client, mt9m001);
641 714
642 /* Second stage probe - when a capture adapter is there */ 715 /* Second stage probe - when a capture adapter is there */
643 icd = &mt9m001->icd; 716 icd->ops = &mt9m001_ops;
644 icd->ops = &mt9m001_ops; 717 icd->y_skip_top = 0;
645 icd->control = &client->dev; 718
646 icd->x_min = 20; 719 mt9m001->rect.left = MT9M001_COLUMN_SKIP;
647 icd->y_min = 12; 720 mt9m001->rect.top = MT9M001_ROW_SKIP;
648 icd->x_current = 20; 721 mt9m001->rect.width = MT9M001_MAX_WIDTH;
649 icd->y_current = 12; 722 mt9m001->rect.height = MT9M001_MAX_HEIGHT;
650 icd->width_min = 48; 723
651 icd->width_max = 1280;
652 icd->height_min = 32;
653 icd->height_max = 1024;
654 icd->y_skip_top = 1;
655 icd->iface = icl->bus_id;
656 /* Simulated autoexposure. If enabled, we calculate shutter width 724 /* Simulated autoexposure. If enabled, we calculate shutter width
657 * ourselves in the driver based on vertical blanking and frame width */ 725 * ourselves in the driver based on vertical blanking and frame width */
658 mt9m001->autoexposure = 1; 726 mt9m001->autoexposure = 1;
659 727
660 ret = soc_camera_device_register(icd); 728 ret = mt9m001_video_probe(icd, client);
661 if (ret) 729 if (ret) {
662 goto eisdr; 730 icd->ops = NULL;
663 731 i2c_set_clientdata(client, NULL);
664 return 0; 732 kfree(mt9m001);
733 }
665 734
666eisdr:
667 kfree(mt9m001);
668 return ret; 735 return ret;
669} 736}
670 737
671static int mt9m001_remove(struct i2c_client *client) 738static int mt9m001_remove(struct i2c_client *client)
672{ 739{
673 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 740 struct mt9m001 *mt9m001 = to_mt9m001(client);
741 struct soc_camera_device *icd = client->dev.platform_data;
674 742
675 soc_camera_device_unregister(&mt9m001->icd); 743 icd->ops = NULL;
744 mt9m001_video_remove(icd);
745 i2c_set_clientdata(client, NULL);
746 client->driver = NULL;
676 kfree(mt9m001); 747 kfree(mt9m001);
677 748
678 return 0; 749 return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index fc5e2de03766..90da699601ea 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -148,12 +148,12 @@ enum mt9m111_context {
148}; 148};
149 149
150struct mt9m111 { 150struct mt9m111 {
151 struct i2c_client *client; 151 struct v4l2_subdev subdev;
152 struct soc_camera_device icd;
153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 152 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
154 enum mt9m111_context context; 153 enum mt9m111_context context;
155 struct v4l2_rect rect; 154 struct v4l2_rect rect;
156 u32 pixfmt; 155 u32 pixfmt;
156 unsigned int gain;
157 unsigned char autoexposure; 157 unsigned char autoexposure;
158 unsigned char datawidth; 158 unsigned char datawidth;
159 unsigned int powered:1; 159 unsigned int powered:1;
@@ -166,6 +166,11 @@ struct mt9m111 {
166 unsigned int autowhitebalance:1; 166 unsigned int autowhitebalance:1;
167}; 167};
168 168
169static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
170{
171 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
172}
173
169static int reg_page_map_set(struct i2c_client *client, const u16 reg) 174static int reg_page_map_set(struct i2c_client *client, const u16 reg)
170{ 175{
171 int ret; 176 int ret;
@@ -190,7 +195,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
190 195
191 ret = reg_page_map_set(client, reg); 196 ret = reg_page_map_set(client, reg);
192 if (!ret) 197 if (!ret)
193 ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); 198 ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff));
194 199
195 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); 200 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
196 return ret; 201 return ret;
@@ -203,7 +208,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
203 208
204 ret = reg_page_map_set(client, reg); 209 ret = reg_page_map_set(client, reg);
205 if (!ret) 210 if (!ret)
206 ret = i2c_smbus_write_word_data(client, (reg & 0xff), 211 ret = i2c_smbus_write_word_data(client, reg & 0xff,
207 swab16(data)); 212 swab16(data));
208 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); 213 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
209 return ret; 214 return ret;
@@ -229,10 +234,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
229 return mt9m111_reg_write(client, reg, ret & ~data); 234 return mt9m111_reg_write(client, reg, ret & ~data);
230} 235}
231 236
232static int mt9m111_set_context(struct soc_camera_device *icd, 237static int mt9m111_set_context(struct i2c_client *client,
233 enum mt9m111_context ctxt) 238 enum mt9m111_context ctxt)
234{ 239{
235 struct i2c_client *client = to_i2c_client(icd->control);
236 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B 240 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
237 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B 241 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
238 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B 242 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -246,17 +250,16 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
246 return reg_write(CONTEXT_CONTROL, valA); 250 return reg_write(CONTEXT_CONTROL, valA);
247} 251}
248 252
249static int mt9m111_setup_rect(struct soc_camera_device *icd, 253static int mt9m111_setup_rect(struct i2c_client *client,
250 struct v4l2_rect *rect) 254 struct v4l2_rect *rect)
251{ 255{
252 struct i2c_client *client = to_i2c_client(icd->control); 256 struct mt9m111 *mt9m111 = to_mt9m111(client);
253 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
254 int ret, is_raw_format; 257 int ret, is_raw_format;
255 int width = rect->width; 258 int width = rect->width;
256 int height = rect->height; 259 int height = rect->height;
257 260
258 if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) 261 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
259 || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) 262 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
260 is_raw_format = 1; 263 is_raw_format = 1;
261 else 264 else
262 is_raw_format = 0; 265 is_raw_format = 0;
@@ -292,9 +295,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
292 return ret; 295 return ret;
293} 296}
294 297
295static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) 298static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
296{ 299{
297 struct i2c_client *client = to_i2c_client(icd->control);
298 int ret; 300 int ret;
299 301
300 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 302 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -303,19 +305,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
303 return ret; 305 return ret;
304} 306}
305 307
306static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) 308static int mt9m111_setfmt_bayer8(struct i2c_client *client)
307{ 309{
308 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); 310 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
309} 311}
310 312
311static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) 313static int mt9m111_setfmt_bayer10(struct i2c_client *client)
312{ 314{
313 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); 315 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
314} 316}
315 317
316static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) 318static int mt9m111_setfmt_rgb565(struct i2c_client *client)
317{ 319{
318 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 320 struct mt9m111 *mt9m111 = to_mt9m111(client);
319 int val = 0; 321 int val = 0;
320 322
321 if (mt9m111->swap_rgb_red_blue) 323 if (mt9m111->swap_rgb_red_blue)
@@ -324,12 +326,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
324 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 326 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
325 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; 327 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
326 328
327 return mt9m111_setup_pixfmt(icd, val); 329 return mt9m111_setup_pixfmt(client, val);
328} 330}
329 331
330static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) 332static int mt9m111_setfmt_rgb555(struct i2c_client *client)
331{ 333{
332 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 334 struct mt9m111 *mt9m111 = to_mt9m111(client);
333 int val = 0; 335 int val = 0;
334 336
335 if (mt9m111->swap_rgb_red_blue) 337 if (mt9m111->swap_rgb_red_blue)
@@ -338,12 +340,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
338 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 340 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
339 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; 341 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
340 342
341 return mt9m111_setup_pixfmt(icd, val); 343 return mt9m111_setup_pixfmt(client, val);
342} 344}
343 345
344static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) 346static int mt9m111_setfmt_yuv(struct i2c_client *client)
345{ 347{
346 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 348 struct mt9m111 *mt9m111 = to_mt9m111(client);
347 int val = 0; 349 int val = 0;
348 350
349 if (mt9m111->swap_yuv_cb_cr) 351 if (mt9m111->swap_yuv_cb_cr)
@@ -351,52 +353,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
351 if (mt9m111->swap_yuv_y_chromas) 353 if (mt9m111->swap_yuv_y_chromas)
352 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; 354 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
353 355
354 return mt9m111_setup_pixfmt(icd, val); 356 return mt9m111_setup_pixfmt(client, val);
355} 357}
356 358
357static int mt9m111_enable(struct soc_camera_device *icd) 359static int mt9m111_enable(struct i2c_client *client)
358{ 360{
359 struct i2c_client *client = to_i2c_client(icd->control); 361 struct mt9m111 *mt9m111 = to_mt9m111(client);
360 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
361 struct soc_camera_link *icl = client->dev.platform_data;
362 int ret; 362 int ret;
363 363
364 if (icl->power) {
365 ret = icl->power(&client->dev, 1);
366 if (ret < 0) {
367 dev_err(icd->vdev->parent,
368 "Platform failed to power-on the camera.\n");
369 return ret;
370 }
371 }
372
373 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); 364 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
374 if (!ret) 365 if (!ret)
375 mt9m111->powered = 1; 366 mt9m111->powered = 1;
376 return ret; 367 return ret;
377} 368}
378 369
379static int mt9m111_disable(struct soc_camera_device *icd) 370static int mt9m111_reset(struct i2c_client *client)
380{
381 struct i2c_client *client = to_i2c_client(icd->control);
382 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
383 struct soc_camera_link *icl = client->dev.platform_data;
384 int ret;
385
386 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
387 if (!ret)
388 mt9m111->powered = 0;
389
390 if (icl->power)
391 icl->power(&client->dev, 0);
392
393 return ret;
394}
395
396static int mt9m111_reset(struct soc_camera_device *icd)
397{ 371{
398 struct i2c_client *client = to_i2c_client(icd->control);
399 struct soc_camera_link *icl = client->dev.platform_data;
400 int ret; 372 int ret;
401 373
402 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 374 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,26 +378,12 @@ static int mt9m111_reset(struct soc_camera_device *icd)
406 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE 378 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
407 | MT9M111_RESET_RESET_SOC); 379 | MT9M111_RESET_RESET_SOC);
408 380
409 if (icl->reset)
410 icl->reset(&client->dev);
411
412 return ret; 381 return ret;
413} 382}
414 383
415static int mt9m111_start_capture(struct soc_camera_device *icd)
416{
417 return 0;
418}
419
420static int mt9m111_stop_capture(struct soc_camera_device *icd)
421{
422 return 0;
423}
424
425static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) 384static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
426{ 385{
427 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 386 struct soc_camera_link *icl = to_soc_camera_link(icd);
428 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
429 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | 387 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
430 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 388 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
431 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; 389 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
@@ -438,62 +396,126 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
438 return 0; 396 return 0;
439} 397}
440 398
441static int mt9m111_set_crop(struct soc_camera_device *icd, 399static int mt9m111_make_rect(struct i2c_client *client,
442 struct v4l2_rect *rect) 400 struct v4l2_rect *rect)
443{ 401{
444 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 402 struct mt9m111 *mt9m111 = to_mt9m111(client);
403
404 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
405 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
406 /* Bayer format - even size lengths */
407 rect->width = ALIGN(rect->width, 2);
408 rect->height = ALIGN(rect->height, 2);
409 /* Let the user play with the starting pixel */
410 }
411
412 /* FIXME: the datasheet doesn't specify minimum sizes */
413 soc_camera_limit_side(&rect->left, &rect->width,
414 MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
415
416 soc_camera_limit_side(&rect->top, &rect->height,
417 MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
418
419 return mt9m111_setup_rect(client, rect);
420}
421
422static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
423{
424 struct v4l2_rect rect = a->c;
425 struct i2c_client *client = sd->priv;
426 struct mt9m111 *mt9m111 = to_mt9m111(client);
445 int ret; 427 int ret;
446 428
447 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", 429 dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
448 __func__, rect->left, rect->top, rect->width, 430 __func__, rect.left, rect.top, rect.width, rect.height);
449 rect->height);
450 431
451 ret = mt9m111_setup_rect(icd, rect); 432 ret = mt9m111_make_rect(client, &rect);
452 if (!ret) 433 if (!ret)
453 mt9m111->rect = *rect; 434 mt9m111->rect = rect;
454 return ret; 435 return ret;
455} 436}
456 437
457static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) 438static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
458{ 439{
459 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 440 struct i2c_client *client = sd->priv;
441 struct mt9m111 *mt9m111 = to_mt9m111(client);
442
443 a->c = mt9m111->rect;
444 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
445
446 return 0;
447}
448
449static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
450{
451 a->bounds.left = MT9M111_MIN_DARK_COLS;
452 a->bounds.top = MT9M111_MIN_DARK_ROWS;
453 a->bounds.width = MT9M111_MAX_WIDTH;
454 a->bounds.height = MT9M111_MAX_HEIGHT;
455 a->defrect = a->bounds;
456 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
457 a->pixelaspect.numerator = 1;
458 a->pixelaspect.denominator = 1;
459
460 return 0;
461}
462
463static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
464{
465 struct i2c_client *client = sd->priv;
466 struct mt9m111 *mt9m111 = to_mt9m111(client);
467 struct v4l2_pix_format *pix = &f->fmt.pix;
468
469 pix->width = mt9m111->rect.width;
470 pix->height = mt9m111->rect.height;
471 pix->pixelformat = mt9m111->pixfmt;
472 pix->field = V4L2_FIELD_NONE;
473 pix->colorspace = V4L2_COLORSPACE_SRGB;
474
475 return 0;
476}
477
478static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
479{
480 struct mt9m111 *mt9m111 = to_mt9m111(client);
460 int ret; 481 int ret;
461 482
462 switch (pixfmt) { 483 switch (pixfmt) {
463 case V4L2_PIX_FMT_SBGGR8: 484 case V4L2_PIX_FMT_SBGGR8:
464 ret = mt9m111_setfmt_bayer8(icd); 485 ret = mt9m111_setfmt_bayer8(client);
465 break; 486 break;
466 case V4L2_PIX_FMT_SBGGR16: 487 case V4L2_PIX_FMT_SBGGR16:
467 ret = mt9m111_setfmt_bayer10(icd); 488 ret = mt9m111_setfmt_bayer10(client);
468 break; 489 break;
469 case V4L2_PIX_FMT_RGB555: 490 case V4L2_PIX_FMT_RGB555:
470 ret = mt9m111_setfmt_rgb555(icd); 491 ret = mt9m111_setfmt_rgb555(client);
471 break; 492 break;
472 case V4L2_PIX_FMT_RGB565: 493 case V4L2_PIX_FMT_RGB565:
473 ret = mt9m111_setfmt_rgb565(icd); 494 ret = mt9m111_setfmt_rgb565(client);
474 break; 495 break;
475 case V4L2_PIX_FMT_UYVY: 496 case V4L2_PIX_FMT_UYVY:
476 mt9m111->swap_yuv_y_chromas = 0; 497 mt9m111->swap_yuv_y_chromas = 0;
477 mt9m111->swap_yuv_cb_cr = 0; 498 mt9m111->swap_yuv_cb_cr = 0;
478 ret = mt9m111_setfmt_yuv(icd); 499 ret = mt9m111_setfmt_yuv(client);
479 break; 500 break;
480 case V4L2_PIX_FMT_VYUY: 501 case V4L2_PIX_FMT_VYUY:
481 mt9m111->swap_yuv_y_chromas = 0; 502 mt9m111->swap_yuv_y_chromas = 0;
482 mt9m111->swap_yuv_cb_cr = 1; 503 mt9m111->swap_yuv_cb_cr = 1;
483 ret = mt9m111_setfmt_yuv(icd); 504 ret = mt9m111_setfmt_yuv(client);
484 break; 505 break;
485 case V4L2_PIX_FMT_YUYV: 506 case V4L2_PIX_FMT_YUYV:
486 mt9m111->swap_yuv_y_chromas = 1; 507 mt9m111->swap_yuv_y_chromas = 1;
487 mt9m111->swap_yuv_cb_cr = 0; 508 mt9m111->swap_yuv_cb_cr = 0;
488 ret = mt9m111_setfmt_yuv(icd); 509 ret = mt9m111_setfmt_yuv(client);
489 break; 510 break;
490 case V4L2_PIX_FMT_YVYU: 511 case V4L2_PIX_FMT_YVYU:
491 mt9m111->swap_yuv_y_chromas = 1; 512 mt9m111->swap_yuv_y_chromas = 1;
492 mt9m111->swap_yuv_cb_cr = 1; 513 mt9m111->swap_yuv_cb_cr = 1;
493 ret = mt9m111_setfmt_yuv(icd); 514 ret = mt9m111_setfmt_yuv(client);
494 break; 515 break;
495 default: 516 default:
496 dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); 517 dev_err(&client->dev, "Pixel format not handled : %x\n",
518 pixfmt);
497 ret = -EINVAL; 519 ret = -EINVAL;
498 } 520 }
499 521
@@ -503,10 +525,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
503 return ret; 525 return ret;
504} 526}
505 527
506static int mt9m111_set_fmt(struct soc_camera_device *icd, 528static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
507 struct v4l2_format *f)
508{ 529{
509 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 530 struct i2c_client *client = sd->priv;
531 struct mt9m111 *mt9m111 = to_mt9m111(client);
510 struct v4l2_pix_format *pix = &f->fmt.pix; 532 struct v4l2_pix_format *pix = &f->fmt.pix;
511 struct v4l2_rect rect = { 533 struct v4l2_rect rect = {
512 .left = mt9m111->rect.left, 534 .left = mt9m111->rect.left,
@@ -516,40 +538,56 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd,
516 }; 538 };
517 int ret; 539 int ret;
518 540
519 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", 541 dev_dbg(&client->dev,
520 __func__, pix->pixelformat, rect.left, rect.top, rect.width, 542 "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
521 rect.height); 543 pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
522 544
523 ret = mt9m111_setup_rect(icd, &rect); 545 ret = mt9m111_make_rect(client, &rect);
524 if (!ret) 546 if (!ret)
525 ret = mt9m111_set_pixfmt(icd, pix->pixelformat); 547 ret = mt9m111_set_pixfmt(client, pix->pixelformat);
526 if (!ret) 548 if (!ret)
527 mt9m111->rect = rect; 549 mt9m111->rect = rect;
528 return ret; 550 return ret;
529} 551}
530 552
531static int mt9m111_try_fmt(struct soc_camera_device *icd, 553static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
532 struct v4l2_format *f)
533{ 554{
534 struct v4l2_pix_format *pix = &f->fmt.pix; 555 struct v4l2_pix_format *pix = &f->fmt.pix;
556 bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
557 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
558
559 /*
560 * With Bayer format enforce even side lengths, but let the user play
561 * with the starting pixel
562 */
535 563
536 if (pix->height > MT9M111_MAX_HEIGHT) 564 if (pix->height > MT9M111_MAX_HEIGHT)
537 pix->height = MT9M111_MAX_HEIGHT; 565 pix->height = MT9M111_MAX_HEIGHT;
566 else if (pix->height < 2)
567 pix->height = 2;
568 else if (bayer)
569 pix->height = ALIGN(pix->height, 2);
570
538 if (pix->width > MT9M111_MAX_WIDTH) 571 if (pix->width > MT9M111_MAX_WIDTH)
539 pix->width = MT9M111_MAX_WIDTH; 572 pix->width = MT9M111_MAX_WIDTH;
573 else if (pix->width < 2)
574 pix->width = 2;
575 else if (bayer)
576 pix->width = ALIGN(pix->width, 2);
540 577
541 return 0; 578 return 0;
542} 579}
543 580
544static int mt9m111_get_chip_id(struct soc_camera_device *icd, 581static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
545 struct v4l2_dbg_chip_ident *id) 582 struct v4l2_dbg_chip_ident *id)
546{ 583{
547 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 584 struct i2c_client *client = sd->priv;
585 struct mt9m111 *mt9m111 = to_mt9m111(client);
548 586
549 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 587 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
550 return -EINVAL; 588 return -EINVAL;
551 589
552 if (id->match.addr != mt9m111->client->addr) 590 if (id->match.addr != client->addr)
553 return -ENODEV; 591 return -ENODEV;
554 592
555 id->ident = mt9m111->model; 593 id->ident = mt9m111->model;
@@ -559,11 +597,11 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd,
559} 597}
560 598
561#ifdef CONFIG_VIDEO_ADV_DEBUG 599#ifdef CONFIG_VIDEO_ADV_DEBUG
562static int mt9m111_get_register(struct soc_camera_device *icd, 600static int mt9m111_g_register(struct v4l2_subdev *sd,
563 struct v4l2_dbg_register *reg) 601 struct v4l2_dbg_register *reg)
564{ 602{
603 struct i2c_client *client = sd->priv;
565 int val; 604 int val;
566 struct i2c_client *client = to_i2c_client(icd->control);
567 605
568 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 606 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
569 return -EINVAL; 607 return -EINVAL;
@@ -580,10 +618,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
580 return 0; 618 return 0;
581} 619}
582 620
583static int mt9m111_set_register(struct soc_camera_device *icd, 621static int mt9m111_s_register(struct v4l2_subdev *sd,
584 struct v4l2_dbg_register *reg) 622 struct v4l2_dbg_register *reg)
585{ 623{
586 struct i2c_client *client = to_i2c_client(icd->control); 624 struct i2c_client *client = sd->priv;
587 625
588 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 626 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
589 return -EINVAL; 627 return -EINVAL;
@@ -635,45 +673,21 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
635 } 673 }
636}; 674};
637 675
638static int mt9m111_video_probe(struct soc_camera_device *);
639static void mt9m111_video_remove(struct soc_camera_device *);
640static int mt9m111_get_control(struct soc_camera_device *,
641 struct v4l2_control *);
642static int mt9m111_set_control(struct soc_camera_device *,
643 struct v4l2_control *);
644static int mt9m111_resume(struct soc_camera_device *icd); 676static int mt9m111_resume(struct soc_camera_device *icd);
645static int mt9m111_init(struct soc_camera_device *icd); 677static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);
646static int mt9m111_release(struct soc_camera_device *icd);
647 678
648static struct soc_camera_ops mt9m111_ops = { 679static struct soc_camera_ops mt9m111_ops = {
649 .owner = THIS_MODULE, 680 .suspend = mt9m111_suspend,
650 .probe = mt9m111_video_probe,
651 .remove = mt9m111_video_remove,
652 .init = mt9m111_init,
653 .resume = mt9m111_resume, 681 .resume = mt9m111_resume,
654 .release = mt9m111_release,
655 .start_capture = mt9m111_start_capture,
656 .stop_capture = mt9m111_stop_capture,
657 .set_crop = mt9m111_set_crop,
658 .set_fmt = mt9m111_set_fmt,
659 .try_fmt = mt9m111_try_fmt,
660 .query_bus_param = mt9m111_query_bus_param, 682 .query_bus_param = mt9m111_query_bus_param,
661 .set_bus_param = mt9m111_set_bus_param, 683 .set_bus_param = mt9m111_set_bus_param,
662 .controls = mt9m111_controls, 684 .controls = mt9m111_controls,
663 .num_controls = ARRAY_SIZE(mt9m111_controls), 685 .num_controls = ARRAY_SIZE(mt9m111_controls),
664 .get_control = mt9m111_get_control,
665 .set_control = mt9m111_set_control,
666 .get_chip_id = mt9m111_get_chip_id,
667#ifdef CONFIG_VIDEO_ADV_DEBUG
668 .get_register = mt9m111_get_register,
669 .set_register = mt9m111_set_register,
670#endif
671}; 686};
672 687
673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) 688static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
674{ 689{
675 struct i2c_client *client = to_i2c_client(icd->control); 690 struct mt9m111 *mt9m111 = to_mt9m111(client);
676 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
677 int ret; 691 int ret;
678 692
679 if (mt9m111->context == HIGHPOWER) { 693 if (mt9m111->context == HIGHPOWER) {
@@ -691,9 +705,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
691 return ret; 705 return ret;
692} 706}
693 707
694static int mt9m111_get_global_gain(struct soc_camera_device *icd) 708static int mt9m111_get_global_gain(struct i2c_client *client)
695{ 709{
696 struct i2c_client *client = to_i2c_client(icd->control);
697 int data; 710 int data;
698 711
699 data = reg_read(GLOBAL_GAIN); 712 data = reg_read(GLOBAL_GAIN);
@@ -703,15 +716,15 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
703 return data; 716 return data;
704} 717}
705 718
706static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 719static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
707{ 720{
708 struct i2c_client *client = to_i2c_client(icd->control); 721 struct mt9m111 *mt9m111 = to_mt9m111(client);
709 u16 val; 722 u16 val;
710 723
711 if (gain > 63 * 2 * 2) 724 if (gain > 63 * 2 * 2)
712 return -EINVAL; 725 return -EINVAL;
713 726
714 icd->gain = gain; 727 mt9m111->gain = gain;
715 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) 728 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
716 val = (1 << 10) | (1 << 9) | (gain / 4); 729 val = (1 << 10) | (1 << 9) | (gain / 4);
717 else if ((gain >= 64) && (gain < 64 * 2)) 730 else if ((gain >= 64) && (gain < 64 * 2))
@@ -722,10 +735,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
722 return reg_write(GLOBAL_GAIN, val); 735 return reg_write(GLOBAL_GAIN, val);
723} 736}
724 737
725static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) 738static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
726{ 739{
727 struct i2c_client *client = to_i2c_client(icd->control); 740 struct mt9m111 *mt9m111 = to_mt9m111(client);
728 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
729 int ret; 741 int ret;
730 742
731 if (on) 743 if (on)
@@ -739,10 +751,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
739 return ret; 751 return ret;
740} 752}
741 753
742static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) 754static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
743{ 755{
744 struct i2c_client *client = to_i2c_client(icd->control); 756 struct mt9m111 *mt9m111 = to_mt9m111(client);
745 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
746 int ret; 757 int ret;
747 758
748 if (on) 759 if (on)
@@ -756,11 +767,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
756 return ret; 767 return ret;
757} 768}
758 769
759static int mt9m111_get_control(struct soc_camera_device *icd, 770static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
760 struct v4l2_control *ctrl)
761{ 771{
762 struct i2c_client *client = to_i2c_client(icd->control); 772 struct i2c_client *client = sd->priv;
763 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 773 struct mt9m111 *mt9m111 = to_mt9m111(client);
764 int data; 774 int data;
765 775
766 switch (ctrl->id) { 776 switch (ctrl->id) {
@@ -785,7 +795,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
785 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); 795 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
786 break; 796 break;
787 case V4L2_CID_GAIN: 797 case V4L2_CID_GAIN:
788 data = mt9m111_get_global_gain(icd); 798 data = mt9m111_get_global_gain(client);
789 if (data < 0) 799 if (data < 0)
790 return data; 800 return data;
791 ctrl->value = data; 801 ctrl->value = data;
@@ -800,37 +810,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
800 return 0; 810 return 0;
801} 811}
802 812
803static int mt9m111_set_control(struct soc_camera_device *icd, 813static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
804 struct v4l2_control *ctrl)
805{ 814{
806 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 815 struct i2c_client *client = sd->priv;
816 struct mt9m111 *mt9m111 = to_mt9m111(client);
807 const struct v4l2_queryctrl *qctrl; 817 const struct v4l2_queryctrl *qctrl;
808 int ret; 818 int ret;
809 819
810 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); 820 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
811
812 if (!qctrl) 821 if (!qctrl)
813 return -EINVAL; 822 return -EINVAL;
814 823
815 switch (ctrl->id) { 824 switch (ctrl->id) {
816 case V4L2_CID_VFLIP: 825 case V4L2_CID_VFLIP:
817 mt9m111->vflip = ctrl->value; 826 mt9m111->vflip = ctrl->value;
818 ret = mt9m111_set_flip(icd, ctrl->value, 827 ret = mt9m111_set_flip(client, ctrl->value,
819 MT9M111_RMB_MIRROR_ROWS); 828 MT9M111_RMB_MIRROR_ROWS);
820 break; 829 break;
821 case V4L2_CID_HFLIP: 830 case V4L2_CID_HFLIP:
822 mt9m111->hflip = ctrl->value; 831 mt9m111->hflip = ctrl->value;
823 ret = mt9m111_set_flip(icd, ctrl->value, 832 ret = mt9m111_set_flip(client, ctrl->value,
824 MT9M111_RMB_MIRROR_COLS); 833 MT9M111_RMB_MIRROR_COLS);
825 break; 834 break;
826 case V4L2_CID_GAIN: 835 case V4L2_CID_GAIN:
827 ret = mt9m111_set_global_gain(icd, ctrl->value); 836 ret = mt9m111_set_global_gain(client, ctrl->value);
828 break; 837 break;
829 case V4L2_CID_EXPOSURE_AUTO: 838 case V4L2_CID_EXPOSURE_AUTO:
830 ret = mt9m111_set_autoexposure(icd, ctrl->value); 839 ret = mt9m111_set_autoexposure(client, ctrl->value);
831 break; 840 break;
832 case V4L2_CID_AUTO_WHITE_BALANCE: 841 case V4L2_CID_AUTO_WHITE_BALANCE:
833 ret = mt9m111_set_autowhitebalance(icd, ctrl->value); 842 ret = mt9m111_set_autowhitebalance(client, ctrl->value);
834 break; 843 break;
835 default: 844 default:
836 ret = -EINVAL; 845 ret = -EINVAL;
@@ -839,62 +848,62 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
839 return ret; 848 return ret;
840} 849}
841 850
842static int mt9m111_restore_state(struct soc_camera_device *icd) 851static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state)
843{ 852{
844 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 853 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
845 854 struct mt9m111 *mt9m111 = to_mt9m111(client);
846 mt9m111_set_context(icd, mt9m111->context); 855
847 mt9m111_set_pixfmt(icd, mt9m111->pixfmt); 856 mt9m111->gain = mt9m111_get_global_gain(client);
848 mt9m111_setup_rect(icd, &mt9m111->rect); 857
849 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 858 return 0;
850 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 859}
851 mt9m111_set_global_gain(icd, icd->gain); 860
852 mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 861static int mt9m111_restore_state(struct i2c_client *client)
853 mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance); 862{
863 struct mt9m111 *mt9m111 = to_mt9m111(client);
864
865 mt9m111_set_context(client, mt9m111->context);
866 mt9m111_set_pixfmt(client, mt9m111->pixfmt);
867 mt9m111_setup_rect(client, &mt9m111->rect);
868 mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
869 mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
870 mt9m111_set_global_gain(client, mt9m111->gain);
871 mt9m111_set_autoexposure(client, mt9m111->autoexposure);
872 mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
854 return 0; 873 return 0;
855} 874}
856 875
857static int mt9m111_resume(struct soc_camera_device *icd) 876static int mt9m111_resume(struct soc_camera_device *icd)
858{ 877{
859 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 878 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
879 struct mt9m111 *mt9m111 = to_mt9m111(client);
860 int ret = 0; 880 int ret = 0;
861 881
862 if (mt9m111->powered) { 882 if (mt9m111->powered) {
863 ret = mt9m111_enable(icd); 883 ret = mt9m111_enable(client);
864 if (!ret) 884 if (!ret)
865 ret = mt9m111_reset(icd); 885 ret = mt9m111_reset(client);
866 if (!ret) 886 if (!ret)
867 ret = mt9m111_restore_state(icd); 887 ret = mt9m111_restore_state(client);
868 } 888 }
869 return ret; 889 return ret;
870} 890}
871 891
872static int mt9m111_init(struct soc_camera_device *icd) 892static int mt9m111_init(struct i2c_client *client)
873{ 893{
874 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 894 struct mt9m111 *mt9m111 = to_mt9m111(client);
875 int ret; 895 int ret;
876 896
877 mt9m111->context = HIGHPOWER; 897 mt9m111->context = HIGHPOWER;
878 ret = mt9m111_enable(icd); 898 ret = mt9m111_enable(client);
879 if (!ret) 899 if (!ret)
880 ret = mt9m111_reset(icd); 900 ret = mt9m111_reset(client);
881 if (!ret) 901 if (!ret)
882 ret = mt9m111_set_context(icd, mt9m111->context); 902 ret = mt9m111_set_context(client, mt9m111->context);
883 if (!ret) 903 if (!ret)
884 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 904 ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
885 if (ret) 905 if (ret)
886 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); 906 dev_err(&client->dev, "mt9m11x init failed: %d\n", ret);
887 return ret;
888}
889
890static int mt9m111_release(struct soc_camera_device *icd)
891{
892 int ret;
893
894 ret = mt9m111_disable(icd);
895 if (ret < 0)
896 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
897
898 return ret; 907 return ret;
899} 908}
900 909
@@ -902,10 +911,10 @@ static int mt9m111_release(struct soc_camera_device *icd)
902 * Interface active, can use i2c. If it fails, it can indeed mean, that 911 * Interface active, can use i2c. If it fails, it can indeed mean, that
903 * this wasn't our capture interface, so, we wait for the right one 912 * this wasn't our capture interface, so, we wait for the right one
904 */ 913 */
905static int mt9m111_video_probe(struct soc_camera_device *icd) 914static int mt9m111_video_probe(struct soc_camera_device *icd,
915 struct i2c_client *client)
906{ 916{
907 struct i2c_client *client = to_i2c_client(icd->control); 917 struct mt9m111 *mt9m111 = to_mt9m111(client);
908 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
909 s32 data; 918 s32 data;
910 int ret; 919 int ret;
911 920
@@ -917,10 +926,13 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
917 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 926 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
918 return -ENODEV; 927 return -ENODEV;
919 928
920 ret = mt9m111_enable(icd); 929 mt9m111->autoexposure = 1;
921 if (ret) 930 mt9m111->autowhitebalance = 1;
922 goto ei2c; 931
923 ret = mt9m111_reset(icd); 932 mt9m111->swap_rgb_even_odd = 1;
933 mt9m111->swap_rgb_red_blue = 1;
934
935 ret = mt9m111_init(client);
924 if (ret) 936 if (ret)
925 goto ei2c; 937 goto ei2c;
926 938
@@ -935,7 +947,7 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
935 break; 947 break;
936 default: 948 default:
937 ret = -ENODEV; 949 ret = -ENODEV;
938 dev_err(&icd->dev, 950 dev_err(&client->dev,
939 "No MT9M11x chip detected, register read %x\n", data); 951 "No MT9M11x chip detected, register read %x\n", data);
940 goto ei2c; 952 goto ei2c;
941 } 953 }
@@ -943,42 +955,51 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
943 icd->formats = mt9m111_colour_formats; 955 icd->formats = mt9m111_colour_formats;
944 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); 956 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
945 957
946 dev_info(&icd->dev, "Detected a MT9M11x chip ID %x\n", data); 958 dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
947 959
948 ret = soc_camera_video_start(icd);
949 if (ret)
950 goto eisis;
951
952 mt9m111->autoexposure = 1;
953 mt9m111->autowhitebalance = 1;
954
955 mt9m111->swap_rgb_even_odd = 1;
956 mt9m111->swap_rgb_red_blue = 1;
957
958 return 0;
959eisis:
960ei2c: 960ei2c:
961 return ret; 961 return ret;
962} 962}
963 963
964static void mt9m111_video_remove(struct soc_camera_device *icd) 964static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
965{ 965 .g_ctrl = mt9m111_g_ctrl,
966 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 966 .s_ctrl = mt9m111_s_ctrl,
967 .g_chip_ident = mt9m111_g_chip_ident,
968#ifdef CONFIG_VIDEO_ADV_DEBUG
969 .g_register = mt9m111_g_register,
970 .s_register = mt9m111_s_register,
971#endif
972};
967 973
968 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, 974static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
969 mt9m111->icd.dev.parent, mt9m111->icd.vdev); 975 .s_fmt = mt9m111_s_fmt,
970 soc_camera_video_stop(&mt9m111->icd); 976 .g_fmt = mt9m111_g_fmt,
971} 977 .try_fmt = mt9m111_try_fmt,
978 .s_crop = mt9m111_s_crop,
979 .g_crop = mt9m111_g_crop,
980 .cropcap = mt9m111_cropcap,
981};
982
983static struct v4l2_subdev_ops mt9m111_subdev_ops = {
984 .core = &mt9m111_subdev_core_ops,
985 .video = &mt9m111_subdev_video_ops,
986};
972 987
973static int mt9m111_probe(struct i2c_client *client, 988static int mt9m111_probe(struct i2c_client *client,
974 const struct i2c_device_id *did) 989 const struct i2c_device_id *did)
975{ 990{
976 struct mt9m111 *mt9m111; 991 struct mt9m111 *mt9m111;
977 struct soc_camera_device *icd; 992 struct soc_camera_device *icd = client->dev.platform_data;
978 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 993 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
979 struct soc_camera_link *icl = client->dev.platform_data; 994 struct soc_camera_link *icl;
980 int ret; 995 int ret;
981 996
997 if (!icd) {
998 dev_err(&client->dev, "MT9M11x: missing soc-camera data!\n");
999 return -EINVAL;
1000 }
1001
1002 icl = to_soc_camera_link(icd);
982 if (!icl) { 1003 if (!icl) {
983 dev_err(&client->dev, "MT9M11x driver needs platform data\n"); 1004 dev_err(&client->dev, "MT9M11x driver needs platform data\n");
984 return -EINVAL; 1005 return -EINVAL;
@@ -994,38 +1015,35 @@ static int mt9m111_probe(struct i2c_client *client,
994 if (!mt9m111) 1015 if (!mt9m111)
995 return -ENOMEM; 1016 return -ENOMEM;
996 1017
997 mt9m111->client = client; 1018 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
998 i2c_set_clientdata(client, mt9m111);
999 1019
1000 /* Second stage probe - when a capture adapter is there */ 1020 /* Second stage probe - when a capture adapter is there */
1001 icd = &mt9m111->icd; 1021 icd->ops = &mt9m111_ops;
1002 icd->ops = &mt9m111_ops; 1022 icd->y_skip_top = 0;
1003 icd->control = &client->dev; 1023
1004 icd->x_min = MT9M111_MIN_DARK_COLS; 1024 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1005 icd->y_min = MT9M111_MIN_DARK_ROWS; 1025 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1006 icd->x_current = icd->x_min; 1026 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1007 icd->y_current = icd->y_min; 1027 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
1008 icd->width_min = MT9M111_MIN_DARK_ROWS; 1028
1009 icd->width_max = MT9M111_MAX_WIDTH; 1029 ret = mt9m111_video_probe(icd, client);
1010 icd->height_min = MT9M111_MIN_DARK_COLS; 1030 if (ret) {
1011 icd->height_max = MT9M111_MAX_HEIGHT; 1031 icd->ops = NULL;
1012 icd->y_skip_top = 0; 1032 i2c_set_clientdata(client, NULL);
1013 icd->iface = icl->bus_id; 1033 kfree(mt9m111);
1014 1034 }
1015 ret = soc_camera_device_register(icd);
1016 if (ret)
1017 goto eisdr;
1018 return 0;
1019 1035
1020eisdr:
1021 kfree(mt9m111);
1022 return ret; 1036 return ret;
1023} 1037}
1024 1038
1025static int mt9m111_remove(struct i2c_client *client) 1039static int mt9m111_remove(struct i2c_client *client)
1026{ 1040{
1027 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 1041 struct mt9m111 *mt9m111 = to_mt9m111(client);
1028 soc_camera_device_unregister(&mt9m111->icd); 1042 struct soc_camera_device *icd = client->dev.platform_data;
1043
1044 icd->ops = NULL;
1045 i2c_set_clientdata(client, NULL);
1046 client->driver = NULL;
1029 kfree(mt9m111); 1047 kfree(mt9m111);
1030 1048
1031 return 0; 1049 return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 4207fb342670..6966f644977e 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,13 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/v4l2-common.h> 16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19 19
20/* mt9t031 i2c address 0x5d 20/* mt9t031 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define i2c_board_info and link to it from
22 * and call i2c_register_board_info() */ 22 * struct soc_camera_link */
23 23
24/* mt9t031 selected register addresses */ 24/* mt9t031 selected register addresses */
25#define MT9T031_CHIP_VERSION 0x00 25#define MT9T031_CHIP_VERSION 0x00
@@ -47,7 +47,7 @@
47#define MT9T031_MAX_HEIGHT 1536 47#define MT9T031_MAX_HEIGHT 1536
48#define MT9T031_MAX_WIDTH 2048 48#define MT9T031_MAX_WIDTH 2048
49#define MT9T031_MIN_HEIGHT 2 49#define MT9T031_MIN_HEIGHT 2
50#define MT9T031_MIN_WIDTH 2 50#define MT9T031_MIN_WIDTH 18
51#define MT9T031_HORIZONTAL_BLANK 142 51#define MT9T031_HORIZONTAL_BLANK 142
52#define MT9T031_VERTICAL_BLANK 25 52#define MT9T031_VERTICAL_BLANK 25
53#define MT9T031_COLUMN_SKIP 32 53#define MT9T031_COLUMN_SKIP 32
@@ -68,14 +68,21 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = {
68}; 68};
69 69
70struct mt9t031 { 70struct mt9t031 {
71 struct i2c_client *client; 71 struct v4l2_subdev subdev;
72 struct soc_camera_device icd; 72 struct v4l2_rect rect; /* Sensor window */
73 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 73 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
74 unsigned char autoexposure;
75 u16 xskip; 74 u16 xskip;
76 u16 yskip; 75 u16 yskip;
76 unsigned int gain;
77 unsigned int exposure;
78 unsigned char autoexposure;
77}; 79};
78 80
81static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
82{
83 return container_of(i2c_get_clientdata(client), struct mt9t031, subdev);
84}
85
79static int reg_read(struct i2c_client *client, const u8 reg) 86static int reg_read(struct i2c_client *client, const u8 reg)
80{ 87{
81 s32 data = i2c_smbus_read_word_data(client, reg); 88 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -136,21 +143,10 @@ static int get_shutter(struct i2c_client *client, u32 *data)
136 return ret < 0 ? ret : 0; 143 return ret < 0 ? ret : 0;
137} 144}
138 145
139static int mt9t031_init(struct soc_camera_device *icd) 146static int mt9t031_idle(struct i2c_client *client)
140{ 147{
141 struct i2c_client *client = to_i2c_client(icd->control);
142 struct soc_camera_link *icl = client->dev.platform_data;
143 int ret; 148 int ret;
144 149
145 if (icl->power) {
146 ret = icl->power(&client->dev, 1);
147 if (ret < 0) {
148 dev_err(icd->vdev->parent,
149 "Platform failed to power-on the camera.\n");
150 return ret;
151 }
152 }
153
154 /* Disable chip output, synchronous option update */ 150 /* Disable chip output, synchronous option update */
155 ret = reg_write(client, MT9T031_RESET, 1); 151 ret = reg_write(client, MT9T031_RESET, 1);
156 if (ret >= 0) 152 if (ret >= 0)
@@ -158,50 +154,39 @@ static int mt9t031_init(struct soc_camera_device *icd)
158 if (ret >= 0) 154 if (ret >= 0)
159 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 155 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
160 156
161 if (ret < 0 && icl->power)
162 icl->power(&client->dev, 0);
163
164 return ret >= 0 ? 0 : -EIO; 157 return ret >= 0 ? 0 : -EIO;
165} 158}
166 159
167static int mt9t031_release(struct soc_camera_device *icd) 160static int mt9t031_disable(struct i2c_client *client)
168{ 161{
169 struct i2c_client *client = to_i2c_client(icd->control);
170 struct soc_camera_link *icl = client->dev.platform_data;
171
172 /* Disable the chip */ 162 /* Disable the chip */
173 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 163 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
174 164
175 if (icl->power)
176 icl->power(&client->dev, 0);
177
178 return 0; 165 return 0;
179} 166}
180 167
181static int mt9t031_start_capture(struct soc_camera_device *icd) 168static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
182{ 169{
183 struct i2c_client *client = to_i2c_client(icd->control); 170 struct i2c_client *client = sd->priv;
184 171 int ret;
185 /* Switch to master "normal" mode */
186 if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
187 return -EIO;
188 return 0;
189}
190 172
191static int mt9t031_stop_capture(struct soc_camera_device *icd) 173 if (enable)
192{ 174 /* Switch to master "normal" mode */
193 struct i2c_client *client = to_i2c_client(icd->control); 175 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 2);
176 else
177 /* Stop sensor readout */
178 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
194 179
195 /* Stop sensor readout */ 180 if (ret < 0)
196 if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
197 return -EIO; 181 return -EIO;
182
198 return 0; 183 return 0;
199} 184}
200 185
201static int mt9t031_set_bus_param(struct soc_camera_device *icd, 186static int mt9t031_set_bus_param(struct soc_camera_device *icd,
202 unsigned long flags) 187 unsigned long flags)
203{ 188{
204 struct i2c_client *client = to_i2c_client(icd->control); 189 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
205 190
206 /* The caller should have queried our parameters, check anyway */ 191 /* The caller should have queried our parameters, check anyway */
207 if (flags & ~MT9T031_BUS_PARAM) 192 if (flags & ~MT9T031_BUS_PARAM)
@@ -217,69 +202,73 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd,
217 202
218static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) 203static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
219{ 204{
220 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 205 struct soc_camera_link *icl = to_soc_camera_link(icd);
221 struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
222 206
223 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); 207 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
224} 208}
225 209
226/* Round up minima and round down maxima */ 210/* target must be _even_ */
227static void recalculate_limits(struct soc_camera_device *icd, 211static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
228 u16 xskip, u16 yskip)
229{ 212{
230 icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip; 213 unsigned int skip;
231 icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip; 214
232 icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip; 215 if (*source < target + target / 2) {
233 icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip; 216 *source = target;
234 icd->width_max = MT9T031_MAX_WIDTH / xskip; 217 return 1;
235 icd->height_max = MT9T031_MAX_HEIGHT / yskip; 218 }
219
220 skip = min(max, *source + target / 2) / target;
221 if (skip > 8)
222 skip = 8;
223 *source = target * skip;
224
225 return skip;
236} 226}
237 227
228/* rect is the sensor rectangle, the caller guarantees parameter validity */
238static int mt9t031_set_params(struct soc_camera_device *icd, 229static int mt9t031_set_params(struct soc_camera_device *icd,
239 struct v4l2_rect *rect, u16 xskip, u16 yskip) 230 struct v4l2_rect *rect, u16 xskip, u16 yskip)
240{ 231{
241 struct i2c_client *client = to_i2c_client(icd->control); 232 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
242 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 233 struct mt9t031 *mt9t031 = to_mt9t031(client);
243 int ret; 234 int ret;
244 u16 xbin, ybin, width, height, left, top; 235 u16 xbin, ybin;
245 const u16 hblank = MT9T031_HORIZONTAL_BLANK, 236 const u16 hblank = MT9T031_HORIZONTAL_BLANK,
246 vblank = MT9T031_VERTICAL_BLANK; 237 vblank = MT9T031_VERTICAL_BLANK;
247 238
248 /* Make sure we don't exceed sensor limits */
249 if (rect->left + rect->width > icd->width_max)
250 rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
251
252 if (rect->top + rect->height > icd->height_max)
253 rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
254
255 width = rect->width * xskip;
256 height = rect->height * yskip;
257 left = rect->left * xskip;
258 top = rect->top * yskip;
259
260 xbin = min(xskip, (u16)3); 239 xbin = min(xskip, (u16)3);
261 ybin = min(yskip, (u16)3); 240 ybin = min(yskip, (u16)3);
262 241
263 dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n", 242 /*
264 xskip, width, rect->width, yskip, height, rect->height); 243 * Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper.
265 244 * There is always a valid suitably aligned value. The worst case is
266 /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */ 245 * xbin = 3, width = 2048. Then we will start at 36, the last read out
246 * pixel will be 2083, which is < 2085 - first black pixel.
247 *
248 * MT9T031 datasheet imposes window left border alignment, depending on
249 * the selected xskip. Failing to conform to this requirement produces
250 * dark horizontal stripes in the image. However, even obeying to this
251 * requirement doesn't eliminate the stripes in all configurations. They
252 * appear "locally reproducibly," but can differ between tests under
253 * different lighting conditions.
254 */
267 switch (xbin) { 255 switch (xbin) {
268 case 2: 256 case 1:
269 left = (left + 3) & ~3; 257 rect->left &= ~1;
270 break; 258 break;
271 case 3:
272 left = roundup(left, 6);
273 }
274
275 switch (ybin) {
276 case 2: 259 case 2:
277 top = (top + 3) & ~3; 260 rect->left &= ~3;
278 break; 261 break;
279 case 3: 262 case 3:
280 top = roundup(top, 6); 263 rect->left = rect->left > roundup(MT9T031_COLUMN_SKIP, 6) ?
264 (rect->left / 6) * 6 : roundup(MT9T031_COLUMN_SKIP, 6);
281 } 265 }
282 266
267 rect->top &= ~1;
268
269 dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n",
270 xskip, yskip, rect->width, rect->height, rect->left, rect->top);
271
283 /* Disable register update, reconfigure atomically */ 272 /* Disable register update, reconfigure atomically */
284 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); 273 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
285 if (ret < 0) 274 if (ret < 0)
@@ -299,29 +288,30 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
299 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, 288 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
300 ((ybin - 1) << 4) | (yskip - 1)); 289 ((ybin - 1) << 4) | (yskip - 1));
301 } 290 }
302 dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); 291 dev_dbg(&client->dev, "new physical left %u, top %u\n",
292 rect->left, rect->top);
303 293
304 /* The caller provides a supported format, as guaranteed by 294 /* The caller provides a supported format, as guaranteed by
305 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ 295 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
306 if (ret >= 0) 296 if (ret >= 0)
307 ret = reg_write(client, MT9T031_COLUMN_START, left); 297 ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
308 if (ret >= 0) 298 if (ret >= 0)
309 ret = reg_write(client, MT9T031_ROW_START, top); 299 ret = reg_write(client, MT9T031_ROW_START, rect->top);
310 if (ret >= 0) 300 if (ret >= 0)
311 ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1); 301 ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
312 if (ret >= 0) 302 if (ret >= 0)
313 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 303 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
314 height + icd->y_skip_top - 1); 304 rect->height + icd->y_skip_top - 1);
315 if (ret >= 0 && mt9t031->autoexposure) { 305 if (ret >= 0 && mt9t031->autoexposure) {
316 ret = set_shutter(client, height + icd->y_skip_top + vblank); 306 unsigned int total_h = rect->height + icd->y_skip_top + vblank;
307 ret = set_shutter(client, total_h);
317 if (ret >= 0) { 308 if (ret >= 0) {
318 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 309 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
319 const struct v4l2_queryctrl *qctrl = 310 const struct v4l2_queryctrl *qctrl =
320 soc_camera_find_qctrl(icd->ops, 311 soc_camera_find_qctrl(icd->ops,
321 V4L2_CID_EXPOSURE); 312 V4L2_CID_EXPOSURE);
322 icd->exposure = (shutter_max / 2 + (height + 313 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
323 icd->y_skip_top + vblank - 1) * 314 (qctrl->maximum - qctrl->minimum)) /
324 (qctrl->maximum - qctrl->minimum)) /
325 shutter_max + qctrl->minimum; 315 shutter_max + qctrl->minimum;
326 } 316 }
327 } 317 }
@@ -330,58 +320,99 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
330 if (ret >= 0) 320 if (ret >= 0)
331 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); 321 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
332 322
323 if (ret >= 0) {
324 mt9t031->rect = *rect;
325 mt9t031->xskip = xskip;
326 mt9t031->yskip = yskip;
327 }
328
333 return ret < 0 ? ret : 0; 329 return ret < 0 ? ret : 0;
334} 330}
335 331
336static int mt9t031_set_crop(struct soc_camera_device *icd, 332static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
337 struct v4l2_rect *rect)
338{ 333{
339 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 334 struct v4l2_rect rect = a->c;
335 struct i2c_client *client = sd->priv;
336 struct mt9t031 *mt9t031 = to_mt9t031(client);
337 struct soc_camera_device *icd = client->dev.platform_data;
338
339 rect.width = ALIGN(rect.width, 2);
340 rect.height = ALIGN(rect.height, 2);
341
342 soc_camera_limit_side(&rect.left, &rect.width,
343 MT9T031_COLUMN_SKIP, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH);
344
345 soc_camera_limit_side(&rect.top, &rect.height,
346 MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
340 347
341 /* CROP - no change in scaling, or in limits */ 348 return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip);
342 return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
343} 349}
344 350
345static int mt9t031_set_fmt(struct soc_camera_device *icd, 351static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
346 struct v4l2_format *f)
347{ 352{
348 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 353 struct i2c_client *client = sd->priv;
349 int ret; 354 struct mt9t031 *mt9t031 = to_mt9t031(client);
350 u16 xskip, yskip;
351 struct v4l2_rect rect = {
352 .left = icd->x_current,
353 .top = icd->y_current,
354 .width = f->fmt.pix.width,
355 .height = f->fmt.pix.height,
356 };
357 355
358 /* 356 a->c = mt9t031->rect;
359 * try_fmt has put rectangle within limits. 357 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
360 * S_FMT - use binning and skipping for scaling, recalculate
361 * limits, used for cropping
362 */
363 /* Is this more optimal than just a division? */
364 for (xskip = 8; xskip > 1; xskip--)
365 if (rect.width * xskip <= MT9T031_MAX_WIDTH)
366 break;
367 358
368 for (yskip = 8; yskip > 1; yskip--) 359 return 0;
369 if (rect.height * yskip <= MT9T031_MAX_HEIGHT) 360}
370 break;
371 361
372 recalculate_limits(icd, xskip, yskip); 362static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
363{
364 a->bounds.left = MT9T031_COLUMN_SKIP;
365 a->bounds.top = MT9T031_ROW_SKIP;
366 a->bounds.width = MT9T031_MAX_WIDTH;
367 a->bounds.height = MT9T031_MAX_HEIGHT;
368 a->defrect = a->bounds;
369 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
370 a->pixelaspect.numerator = 1;
371 a->pixelaspect.denominator = 1;
373 372
374 ret = mt9t031_set_params(icd, &rect, xskip, yskip); 373 return 0;
375 if (!ret) { 374}
376 mt9t031->xskip = xskip;
377 mt9t031->yskip = yskip;
378 }
379 375
380 return ret; 376static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
377{
378 struct i2c_client *client = sd->priv;
379 struct mt9t031 *mt9t031 = to_mt9t031(client);
380 struct v4l2_pix_format *pix = &f->fmt.pix;
381
382 pix->width = mt9t031->rect.width / mt9t031->xskip;
383 pix->height = mt9t031->rect.height / mt9t031->yskip;
384 pix->pixelformat = V4L2_PIX_FMT_SGRBG10;
385 pix->field = V4L2_FIELD_NONE;
386 pix->colorspace = V4L2_COLORSPACE_SRGB;
387
388 return 0;
389}
390
391static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
392{
393 struct i2c_client *client = sd->priv;
394 struct mt9t031 *mt9t031 = to_mt9t031(client);
395 struct soc_camera_device *icd = client->dev.platform_data;
396 struct v4l2_pix_format *pix = &f->fmt.pix;
397 u16 xskip, yskip;
398 struct v4l2_rect rect = mt9t031->rect;
399
400 /*
401 * try_fmt has put width and height within limits.
402 * S_FMT: use binning and skipping for scaling
403 */
404 xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH);
405 yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT);
406
407 /* mt9t031_set_params() doesn't change width and height */
408 return mt9t031_set_params(icd, &rect, xskip, yskip);
381} 409}
382 410
383static int mt9t031_try_fmt(struct soc_camera_device *icd, 411/*
384 struct v4l2_format *f) 412 * If a user window larger than sensor window is requested, we'll increase the
413 * sensor window.
414 */
415static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
385{ 416{
386 struct v4l2_pix_format *pix = &f->fmt.pix; 417 struct v4l2_pix_format *pix = &f->fmt.pix;
387 418
@@ -392,15 +423,16 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
392 return 0; 423 return 0;
393} 424}
394 425
395static int mt9t031_get_chip_id(struct soc_camera_device *icd, 426static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
396 struct v4l2_dbg_chip_ident *id) 427 struct v4l2_dbg_chip_ident *id)
397{ 428{
398 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 429 struct i2c_client *client = sd->priv;
430 struct mt9t031 *mt9t031 = to_mt9t031(client);
399 431
400 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 432 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
401 return -EINVAL; 433 return -EINVAL;
402 434
403 if (id->match.addr != mt9t031->client->addr) 435 if (id->match.addr != client->addr)
404 return -ENODEV; 436 return -ENODEV;
405 437
406 id->ident = mt9t031->model; 438 id->ident = mt9t031->model;
@@ -410,10 +442,10 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
410} 442}
411 443
412#ifdef CONFIG_VIDEO_ADV_DEBUG 444#ifdef CONFIG_VIDEO_ADV_DEBUG
413static int mt9t031_get_register(struct soc_camera_device *icd, 445static int mt9t031_g_register(struct v4l2_subdev *sd,
414 struct v4l2_dbg_register *reg) 446 struct v4l2_dbg_register *reg)
415{ 447{
416 struct i2c_client *client = to_i2c_client(icd->control); 448 struct i2c_client *client = sd->priv;
417 449
418 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 450 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
419 return -EINVAL; 451 return -EINVAL;
@@ -429,10 +461,10 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
429 return 0; 461 return 0;
430} 462}
431 463
432static int mt9t031_set_register(struct soc_camera_device *icd, 464static int mt9t031_s_register(struct v4l2_subdev *sd,
433 struct v4l2_dbg_register *reg) 465 struct v4l2_dbg_register *reg)
434{ 466{
435 struct i2c_client *client = to_i2c_client(icd->control); 467 struct i2c_client *client = sd->priv;
436 468
437 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 469 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
438 return -EINVAL; 470 return -EINVAL;
@@ -493,39 +525,17 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
493 } 525 }
494}; 526};
495 527
496static int mt9t031_video_probe(struct soc_camera_device *);
497static void mt9t031_video_remove(struct soc_camera_device *);
498static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *);
499static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *);
500
501static struct soc_camera_ops mt9t031_ops = { 528static struct soc_camera_ops mt9t031_ops = {
502 .owner = THIS_MODULE,
503 .probe = mt9t031_video_probe,
504 .remove = mt9t031_video_remove,
505 .init = mt9t031_init,
506 .release = mt9t031_release,
507 .start_capture = mt9t031_start_capture,
508 .stop_capture = mt9t031_stop_capture,
509 .set_crop = mt9t031_set_crop,
510 .set_fmt = mt9t031_set_fmt,
511 .try_fmt = mt9t031_try_fmt,
512 .set_bus_param = mt9t031_set_bus_param, 529 .set_bus_param = mt9t031_set_bus_param,
513 .query_bus_param = mt9t031_query_bus_param, 530 .query_bus_param = mt9t031_query_bus_param,
514 .controls = mt9t031_controls, 531 .controls = mt9t031_controls,
515 .num_controls = ARRAY_SIZE(mt9t031_controls), 532 .num_controls = ARRAY_SIZE(mt9t031_controls),
516 .get_control = mt9t031_get_control,
517 .set_control = mt9t031_set_control,
518 .get_chip_id = mt9t031_get_chip_id,
519#ifdef CONFIG_VIDEO_ADV_DEBUG
520 .get_register = mt9t031_get_register,
521 .set_register = mt9t031_set_register,
522#endif
523}; 533};
524 534
525static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 535static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
526{ 536{
527 struct i2c_client *client = to_i2c_client(icd->control); 537 struct i2c_client *client = sd->priv;
528 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 538 struct mt9t031 *mt9t031 = to_mt9t031(client);
529 int data; 539 int data;
530 540
531 switch (ctrl->id) { 541 switch (ctrl->id) {
@@ -544,14 +554,21 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
544 case V4L2_CID_EXPOSURE_AUTO: 554 case V4L2_CID_EXPOSURE_AUTO:
545 ctrl->value = mt9t031->autoexposure; 555 ctrl->value = mt9t031->autoexposure;
546 break; 556 break;
557 case V4L2_CID_GAIN:
558 ctrl->value = mt9t031->gain;
559 break;
560 case V4L2_CID_EXPOSURE:
561 ctrl->value = mt9t031->exposure;
562 break;
547 } 563 }
548 return 0; 564 return 0;
549} 565}
550 566
551static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 567static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
552{ 568{
553 struct i2c_client *client = to_i2c_client(icd->control); 569 struct i2c_client *client = sd->priv;
554 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 570 struct mt9t031 *mt9t031 = to_mt9t031(client);
571 struct soc_camera_device *icd = client->dev.platform_data;
555 const struct v4l2_queryctrl *qctrl; 572 const struct v4l2_queryctrl *qctrl;
556 int data; 573 int data;
557 574
@@ -586,7 +603,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
586 unsigned long range = qctrl->default_value - qctrl->minimum; 603 unsigned long range = qctrl->default_value - qctrl->minimum;
587 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 604 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
588 605
589 dev_dbg(&icd->dev, "Setting gain %d\n", data); 606 dev_dbg(&client->dev, "Setting gain %d\n", data);
590 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 607 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
591 if (data < 0) 608 if (data < 0)
592 return -EIO; 609 return -EIO;
@@ -606,7 +623,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
606 /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */ 623 /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
607 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; 624 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
608 625
609 dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", 626 dev_dbg(&client->dev, "Set gain from 0x%x to 0x%x\n",
610 reg_read(client, MT9T031_GLOBAL_GAIN), data); 627 reg_read(client, MT9T031_GLOBAL_GAIN), data);
611 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 628 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
612 if (data < 0) 629 if (data < 0)
@@ -614,7 +631,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
614 } 631 }
615 632
616 /* Success */ 633 /* Success */
617 icd->gain = ctrl->value; 634 mt9t031->gain = ctrl->value;
618 break; 635 break;
619 case V4L2_CID_EXPOSURE: 636 case V4L2_CID_EXPOSURE:
620 /* mt9t031 has maximum == default */ 637 /* mt9t031 has maximum == default */
@@ -627,11 +644,11 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
627 u32 old; 644 u32 old;
628 645
629 get_shutter(client, &old); 646 get_shutter(client, &old);
630 dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", 647 dev_dbg(&client->dev, "Set shutter from %u to %u\n",
631 old, shutter); 648 old, shutter);
632 if (set_shutter(client, shutter) < 0) 649 if (set_shutter(client, shutter) < 0)
633 return -EIO; 650 return -EIO;
634 icd->exposure = ctrl->value; 651 mt9t031->exposure = ctrl->value;
635 mt9t031->autoexposure = 0; 652 mt9t031->autoexposure = 0;
636 } 653 }
637 break; 654 break;
@@ -639,13 +656,14 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
639 if (ctrl->value) { 656 if (ctrl->value) {
640 const u16 vblank = MT9T031_VERTICAL_BLANK; 657 const u16 vblank = MT9T031_VERTICAL_BLANK;
641 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 658 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
642 if (set_shutter(client, icd->height + 659 unsigned int total_h = mt9t031->rect.height +
643 icd->y_skip_top + vblank) < 0) 660 icd->y_skip_top + vblank;
661
662 if (set_shutter(client, total_h) < 0)
644 return -EIO; 663 return -EIO;
645 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 664 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
646 icd->exposure = (shutter_max / 2 + (icd->height + 665 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
647 icd->y_skip_top + vblank - 1) * 666 (qctrl->maximum - qctrl->minimum)) /
648 (qctrl->maximum - qctrl->minimum)) /
649 shutter_max + qctrl->minimum; 667 shutter_max + qctrl->minimum;
650 mt9t031->autoexposure = 1; 668 mt9t031->autoexposure = 1;
651 } else 669 } else
@@ -657,22 +675,16 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
657 675
658/* Interface active, can use i2c. If it fails, it can indeed mean, that 676/* Interface active, can use i2c. If it fails, it can indeed mean, that
659 * this wasn't our capture interface, so, we wait for the right one */ 677 * this wasn't our capture interface, so, we wait for the right one */
660static int mt9t031_video_probe(struct soc_camera_device *icd) 678static int mt9t031_video_probe(struct i2c_client *client)
661{ 679{
662 struct i2c_client *client = to_i2c_client(icd->control); 680 struct soc_camera_device *icd = client->dev.platform_data;
663 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 681 struct mt9t031 *mt9t031 = to_mt9t031(client);
664 s32 data; 682 s32 data;
665 int ret; 683 int ret;
666 684
667 /* We must have a parent by now. And it cannot be a wrong one.
668 * So this entire test is completely redundant. */
669 if (!icd->dev.parent ||
670 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
671 return -ENODEV;
672
673 /* Enable the chip */ 685 /* Enable the chip */
674 data = reg_write(client, MT9T031_CHIP_ENABLE, 1); 686 data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
675 dev_dbg(&icd->dev, "write: %d\n", data); 687 dev_dbg(&client->dev, "write: %d\n", data);
676 688
677 /* Read out the chip version register */ 689 /* Read out the chip version register */
678 data = reg_read(client, MT9T031_CHIP_VERSION); 690 data = reg_read(client, MT9T031_CHIP_VERSION);
@@ -684,44 +696,64 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
684 icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); 696 icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
685 break; 697 break;
686 default: 698 default:
687 ret = -ENODEV; 699 dev_err(&client->dev,
688 dev_err(&icd->dev,
689 "No MT9T031 chip detected, register read %x\n", data); 700 "No MT9T031 chip detected, register read %x\n", data);
690 goto ei2c; 701 return -ENODEV;
691 } 702 }
692 703
693 dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data); 704 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
694 705
695 /* Now that we know the model, we can start video */ 706 ret = mt9t031_idle(client);
696 ret = soc_camera_video_start(icd); 707 if (ret < 0)
697 if (ret) 708 dev_err(&client->dev, "Failed to initialise the camera\n");
698 goto evstart;
699 709
700 return 0; 710 /* mt9t031_idle() has reset the chip to default. */
711 mt9t031->exposure = 255;
712 mt9t031->gain = 64;
701 713
702evstart:
703ei2c:
704 return ret; 714 return ret;
705} 715}
706 716
707static void mt9t031_video_remove(struct soc_camera_device *icd) 717static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
708{ 718 .g_ctrl = mt9t031_g_ctrl,
709 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 719 .s_ctrl = mt9t031_s_ctrl,
720 .g_chip_ident = mt9t031_g_chip_ident,
721#ifdef CONFIG_VIDEO_ADV_DEBUG
722 .g_register = mt9t031_g_register,
723 .s_register = mt9t031_s_register,
724#endif
725};
710 726
711 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client->addr, 727static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
712 icd->dev.parent, icd->vdev); 728 .s_stream = mt9t031_s_stream,
713 soc_camera_video_stop(icd); 729 .s_fmt = mt9t031_s_fmt,
714} 730 .g_fmt = mt9t031_g_fmt,
731 .try_fmt = mt9t031_try_fmt,
732 .s_crop = mt9t031_s_crop,
733 .g_crop = mt9t031_g_crop,
734 .cropcap = mt9t031_cropcap,
735};
736
737static struct v4l2_subdev_ops mt9t031_subdev_ops = {
738 .core = &mt9t031_subdev_core_ops,
739 .video = &mt9t031_subdev_video_ops,
740};
715 741
716static int mt9t031_probe(struct i2c_client *client, 742static int mt9t031_probe(struct i2c_client *client,
717 const struct i2c_device_id *did) 743 const struct i2c_device_id *did)
718{ 744{
719 struct mt9t031 *mt9t031; 745 struct mt9t031 *mt9t031;
720 struct soc_camera_device *icd; 746 struct soc_camera_device *icd = client->dev.platform_data;
721 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 747 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
722 struct soc_camera_link *icl = client->dev.platform_data; 748 struct soc_camera_link *icl;
723 int ret; 749 int ret;
724 750
751 if (!icd) {
752 dev_err(&client->dev, "MT9T031: missing soc-camera data!\n");
753 return -EINVAL;
754 }
755
756 icl = to_soc_camera_link(icd);
725 if (!icl) { 757 if (!icl) {
726 dev_err(&client->dev, "MT9T031 driver needs platform data\n"); 758 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
727 return -EINVAL; 759 return -EINVAL;
@@ -737,23 +769,17 @@ static int mt9t031_probe(struct i2c_client *client,
737 if (!mt9t031) 769 if (!mt9t031)
738 return -ENOMEM; 770 return -ENOMEM;
739 771
740 mt9t031->client = client; 772 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
741 i2c_set_clientdata(client, mt9t031);
742 773
743 /* Second stage probe - when a capture adapter is there */ 774 /* Second stage probe - when a capture adapter is there */
744 icd = &mt9t031->icd; 775 icd->ops = &mt9t031_ops;
745 icd->ops = &mt9t031_ops; 776 icd->y_skip_top = 0;
746 icd->control = &client->dev; 777
747 icd->x_min = MT9T031_COLUMN_SKIP; 778 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
748 icd->y_min = MT9T031_ROW_SKIP; 779 mt9t031->rect.top = MT9T031_ROW_SKIP;
749 icd->x_current = icd->x_min; 780 mt9t031->rect.width = MT9T031_MAX_WIDTH;
750 icd->y_current = icd->y_min; 781 mt9t031->rect.height = MT9T031_MAX_HEIGHT;
751 icd->width_min = MT9T031_MIN_WIDTH; 782
752 icd->width_max = MT9T031_MAX_WIDTH;
753 icd->height_min = MT9T031_MIN_HEIGHT;
754 icd->height_max = MT9T031_MAX_HEIGHT;
755 icd->y_skip_top = 0;
756 icd->iface = icl->bus_id;
757 /* Simulated autoexposure. If enabled, we calculate shutter width 783 /* Simulated autoexposure. If enabled, we calculate shutter width
758 * ourselves in the driver based on vertical blanking and frame width */ 784 * ourselves in the driver based on vertical blanking and frame width */
759 mt9t031->autoexposure = 1; 785 mt9t031->autoexposure = 1;
@@ -761,24 +787,29 @@ static int mt9t031_probe(struct i2c_client *client,
761 mt9t031->xskip = 1; 787 mt9t031->xskip = 1;
762 mt9t031->yskip = 1; 788 mt9t031->yskip = 1;
763 789
764 ret = soc_camera_device_register(icd); 790 mt9t031_idle(client);
765 if (ret)
766 goto eisdr;
767 791
768 return 0; 792 ret = mt9t031_video_probe(client);
793
794 mt9t031_disable(client);
795
796 if (ret) {
797 icd->ops = NULL;
798 i2c_set_clientdata(client, NULL);
799 kfree(mt9t031);
800 }
769 801
770eisdr:
771 i2c_set_clientdata(client, NULL);
772 kfree(mt9t031);
773 return ret; 802 return ret;
774} 803}
775 804
776static int mt9t031_remove(struct i2c_client *client) 805static int mt9t031_remove(struct i2c_client *client)
777{ 806{
778 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 807 struct mt9t031 *mt9t031 = to_mt9t031(client);
808 struct soc_camera_device *icd = client->dev.platform_data;
779 809
780 soc_camera_device_unregister(&mt9t031->icd); 810 icd->ops = NULL;
781 i2c_set_clientdata(client, NULL); 811 i2c_set_clientdata(client, NULL);
812 client->driver = NULL;
782 kfree(mt9t031); 813 kfree(mt9t031);
783 814
784 return 0; 815 return 0;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index dbdcc86ae50d..995607f9d3ba 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,13 +14,13 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/v4l2-common.h> 17#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 18#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20 20
21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
22 * The platform has to define i2c_board_info 22 * The platform has to define ctruct i2c_board_info objects and link to them
23 * and call i2c_register_board_info() */ 23 * from struct soc_camera_link */
24 24
25static char *sensor_type; 25static char *sensor_type;
26module_param(sensor_type, charp, S_IRUGO); 26module_param(sensor_type, charp, S_IRUGO);
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
45#define MT9V022_PIXEL_OPERATION_MODE 0x0f 45#define MT9V022_PIXEL_OPERATION_MODE 0x0f
46#define MT9V022_LED_OUT_CONTROL 0x1b 46#define MT9V022_LED_OUT_CONTROL 0x1b
47#define MT9V022_ADC_MODE_CONTROL 0x1c 47#define MT9V022_ADC_MODE_CONTROL 0x1c
48#define MT9V022_ANALOG_GAIN 0x34 48#define MT9V022_ANALOG_GAIN 0x35
49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
50#define MT9V022_PIXCLK_FV_LV 0x74 50#define MT9V022_PIXCLK_FV_LV 0x74
51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f 51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f
@@ -55,6 +55,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
55/* Progressive scan, master, defaults */ 55/* Progressive scan, master, defaults */
56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
57 57
58#define MT9V022_MAX_WIDTH 752
59#define MT9V022_MAX_HEIGHT 480
60#define MT9V022_MIN_WIDTH 48
61#define MT9V022_MIN_HEIGHT 32
62#define MT9V022_COLUMN_SKIP 1
63#define MT9V022_ROW_SKIP 4
64
58static const struct soc_camera_data_format mt9v022_colour_formats[] = { 65static const struct soc_camera_data_format mt9v022_colour_formats[] = {
59 /* Order important: first natively supported, 66 /* Order important: first natively supported,
60 * second supported with a GPIO extender */ 67 * second supported with a GPIO extender */
@@ -85,12 +92,18 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
85}; 92};
86 93
87struct mt9v022 { 94struct mt9v022 {
88 struct i2c_client *client; 95 struct v4l2_subdev subdev;
89 struct soc_camera_device icd; 96 struct v4l2_rect rect; /* Sensor window */
97 __u32 fourcc;
90 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 98 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
91 u16 chip_control; 99 u16 chip_control;
92}; 100};
93 101
102static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
103{
104 return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
105}
106
94static int reg_read(struct i2c_client *client, const u8 reg) 107static int reg_read(struct i2c_client *client, const u8 reg)
95{ 108{
96 s32 data = i2c_smbus_read_word_data(client, reg); 109 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -125,29 +138,11 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
125 return reg_write(client, reg, ret & ~data); 138 return reg_write(client, reg, ret & ~data);
126} 139}
127 140
128static int mt9v022_init(struct soc_camera_device *icd) 141static int mt9v022_init(struct i2c_client *client)
129{ 142{
130 struct i2c_client *client = to_i2c_client(icd->control); 143 struct mt9v022 *mt9v022 = to_mt9v022(client);
131 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
132 struct soc_camera_link *icl = client->dev.platform_data;
133 int ret; 144 int ret;
134 145
135 if (icl->power) {
136 ret = icl->power(&client->dev, 1);
137 if (ret < 0) {
138 dev_err(icd->vdev->parent,
139 "Platform failed to power-on the camera.\n");
140 return ret;
141 }
142 }
143
144 /*
145 * The camera could have been already on, we hard-reset it additionally,
146 * if available. Soft reset is done in video_probe().
147 */
148 if (icl->reset)
149 icl->reset(&client->dev);
150
151 /* Almost the default mode: master, parallel, simultaneous, and an 146 /* Almost the default mode: master, parallel, simultaneous, and an
152 * undocumented bit 0x200, which is present in table 7, but not in 8, 147 * undocumented bit 0x200, which is present in table 7, but not in 8,
153 * plus snapshot mode to disable scan for now */ 148 * plus snapshot mode to disable scan for now */
@@ -161,6 +156,10 @@ static int mt9v022_init(struct soc_camera_device *icd)
161 /* AEC, AGC on */ 156 /* AEC, AGC on */
162 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); 157 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
163 if (!ret) 158 if (!ret)
159 ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
160 if (!ret)
161 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
162 if (!ret)
164 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); 163 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
165 if (!ret) 164 if (!ret)
166 /* default - auto */ 165 /* default - auto */
@@ -171,37 +170,19 @@ static int mt9v022_init(struct soc_camera_device *icd)
171 return ret; 170 return ret;
172} 171}
173 172
174static int mt9v022_release(struct soc_camera_device *icd) 173static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
175{ 174{
176 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 175 struct i2c_client *client = sd->priv;
177 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 176 struct mt9v022 *mt9v022 = to_mt9v022(client);
178
179 if (icl->power)
180 icl->power(&mt9v022->client->dev, 0);
181
182 return 0;
183}
184 177
185static int mt9v022_start_capture(struct soc_camera_device *icd) 178 if (enable)
186{ 179 /* Switch to master "normal" mode */
187 struct i2c_client *client = to_i2c_client(icd->control); 180 mt9v022->chip_control &= ~0x10;
188 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 181 else
189 /* Switch to master "normal" mode */ 182 /* Switch to snapshot mode */
190 mt9v022->chip_control &= ~0x10; 183 mt9v022->chip_control |= 0x10;
191 if (reg_write(client, MT9V022_CHIP_CONTROL,
192 mt9v022->chip_control) < 0)
193 return -EIO;
194 return 0;
195}
196 184
197static int mt9v022_stop_capture(struct soc_camera_device *icd) 185 if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
198{
199 struct i2c_client *client = to_i2c_client(icd->control);
200 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
201 /* Switch to snapshot mode */
202 mt9v022->chip_control |= 0x10;
203 if (reg_write(client, MT9V022_CHIP_CONTROL,
204 mt9v022->chip_control) < 0)
205 return -EIO; 186 return -EIO;
206 return 0; 187 return 0;
207} 188}
@@ -209,9 +190,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
209static int mt9v022_set_bus_param(struct soc_camera_device *icd, 190static int mt9v022_set_bus_param(struct soc_camera_device *icd,
210 unsigned long flags) 191 unsigned long flags)
211{ 192{
212 struct i2c_client *client = to_i2c_client(icd->control); 193 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
213 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 194 struct mt9v022 *mt9v022 = to_mt9v022(client);
214 struct soc_camera_link *icl = client->dev.platform_data; 195 struct soc_camera_link *icl = to_soc_camera_link(icd);
215 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 196 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
216 int ret; 197 int ret;
217 u16 pixclk = 0; 198 u16 pixclk = 0;
@@ -255,7 +236,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
255 if (ret < 0) 236 if (ret < 0)
256 return ret; 237 return ret;
257 238
258 dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", 239 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
259 pixclk, mt9v022->chip_control); 240 pixclk, mt9v022->chip_control);
260 241
261 return 0; 242 return 0;
@@ -263,8 +244,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
263 244
264static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) 245static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
265{ 246{
266 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 247 struct soc_camera_link *icl = to_soc_camera_link(icd);
267 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
268 unsigned int width_flag; 248 unsigned int width_flag;
269 249
270 if (icl->query_bus_param) 250 if (icl->query_bus_param)
@@ -280,60 +260,121 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
280 width_flag; 260 width_flag;
281} 261}
282 262
283static int mt9v022_set_crop(struct soc_camera_device *icd, 263static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
284 struct v4l2_rect *rect)
285{ 264{
286 struct i2c_client *client = to_i2c_client(icd->control); 265 struct i2c_client *client = sd->priv;
266 struct mt9v022 *mt9v022 = to_mt9v022(client);
267 struct v4l2_rect rect = a->c;
268 struct soc_camera_device *icd = client->dev.platform_data;
287 int ret; 269 int ret;
288 270
271 /* Bayer format - even size lengths */
272 if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
273 mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
274 rect.width = ALIGN(rect.width, 2);
275 rect.height = ALIGN(rect.height, 2);
276 /* Let the user play with the starting pixel */
277 }
278
279 soc_camera_limit_side(&rect.left, &rect.width,
280 MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
281
282 soc_camera_limit_side(&rect.top, &rect.height,
283 MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
284
289 /* Like in example app. Contradicts the datasheet though */ 285 /* Like in example app. Contradicts the datasheet though */
290 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); 286 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
291 if (ret >= 0) { 287 if (ret >= 0) {
292 if (ret & 1) /* Autoexposure */ 288 if (ret & 1) /* Autoexposure */
293 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 289 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
294 rect->height + icd->y_skip_top + 43); 290 rect.height + icd->y_skip_top + 43);
295 else 291 else
296 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 292 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
297 rect->height + icd->y_skip_top + 43); 293 rect.height + icd->y_skip_top + 43);
298 } 294 }
299 /* Setup frame format: defaults apart from width and height */ 295 /* Setup frame format: defaults apart from width and height */
300 if (!ret) 296 if (!ret)
301 ret = reg_write(client, MT9V022_COLUMN_START, rect->left); 297 ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
302 if (!ret) 298 if (!ret)
303 ret = reg_write(client, MT9V022_ROW_START, rect->top); 299 ret = reg_write(client, MT9V022_ROW_START, rect.top);
304 if (!ret) 300 if (!ret)
305 /* Default 94, Phytec driver says: 301 /* Default 94, Phytec driver says:
306 * "width + horizontal blank >= 660" */ 302 * "width + horizontal blank >= 660" */
307 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, 303 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
308 rect->width > 660 - 43 ? 43 : 304 rect.width > 660 - 43 ? 43 :
309 660 - rect->width); 305 660 - rect.width);
310 if (!ret) 306 if (!ret)
311 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); 307 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
312 if (!ret) 308 if (!ret)
313 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); 309 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
314 if (!ret) 310 if (!ret)
315 ret = reg_write(client, MT9V022_WINDOW_HEIGHT, 311 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
316 rect->height + icd->y_skip_top); 312 rect.height + icd->y_skip_top);
317 313
318 if (ret < 0) 314 if (ret < 0)
319 return ret; 315 return ret;
320 316
321 dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height); 317 dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height);
318
319 mt9v022->rect = rect;
320
321 return 0;
322}
323
324static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
325{
326 struct i2c_client *client = sd->priv;
327 struct mt9v022 *mt9v022 = to_mt9v022(client);
328
329 a->c = mt9v022->rect;
330 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
322 331
323 return 0; 332 return 0;
324} 333}
325 334
326static int mt9v022_set_fmt(struct soc_camera_device *icd, 335static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
327 struct v4l2_format *f)
328{ 336{
329 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 337 a->bounds.left = MT9V022_COLUMN_SKIP;
338 a->bounds.top = MT9V022_ROW_SKIP;
339 a->bounds.width = MT9V022_MAX_WIDTH;
340 a->bounds.height = MT9V022_MAX_HEIGHT;
341 a->defrect = a->bounds;
342 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
343 a->pixelaspect.numerator = 1;
344 a->pixelaspect.denominator = 1;
345
346 return 0;
347}
348
349static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
350{
351 struct i2c_client *client = sd->priv;
352 struct mt9v022 *mt9v022 = to_mt9v022(client);
330 struct v4l2_pix_format *pix = &f->fmt.pix; 353 struct v4l2_pix_format *pix = &f->fmt.pix;
331 struct v4l2_rect rect = { 354
332 .left = icd->x_current, 355 pix->width = mt9v022->rect.width;
333 .top = icd->y_current, 356 pix->height = mt9v022->rect.height;
334 .width = pix->width, 357 pix->pixelformat = mt9v022->fourcc;
335 .height = pix->height, 358 pix->field = V4L2_FIELD_NONE;
359 pix->colorspace = V4L2_COLORSPACE_SRGB;
360
361 return 0;
362}
363
364static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
365{
366 struct i2c_client *client = sd->priv;
367 struct mt9v022 *mt9v022 = to_mt9v022(client);
368 struct v4l2_pix_format *pix = &f->fmt.pix;
369 struct v4l2_crop a = {
370 .c = {
371 .left = mt9v022->rect.left,
372 .top = mt9v022->rect.top,
373 .width = pix->width,
374 .height = pix->height,
375 },
336 }; 376 };
377 int ret;
337 378
338 /* The caller provides a supported format, as verified per call to 379 /* The caller provides a supported format, as verified per call to
339 * icd->try_fmt(), datawidth is from our supported format list */ 380 * icd->try_fmt(), datawidth is from our supported format list */
@@ -356,30 +397,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
356 } 397 }
357 398
358 /* No support for scaling on this camera, just crop. */ 399 /* No support for scaling on this camera, just crop. */
359 return mt9v022_set_crop(icd, &rect); 400 ret = mt9v022_s_crop(sd, &a);
401 if (!ret) {
402 pix->width = mt9v022->rect.width;
403 pix->height = mt9v022->rect.height;
404 mt9v022->fourcc = pix->pixelformat;
405 }
406
407 return ret;
360} 408}
361 409
362static int mt9v022_try_fmt(struct soc_camera_device *icd, 410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
363 struct v4l2_format *f)
364{ 411{
412 struct i2c_client *client = sd->priv;
413 struct soc_camera_device *icd = client->dev.platform_data;
365 struct v4l2_pix_format *pix = &f->fmt.pix; 414 struct v4l2_pix_format *pix = &f->fmt.pix;
415 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
416 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
366 417
367 v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, 418 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
368 &pix->height, 32 + icd->y_skip_top, 419 MT9V022_MAX_WIDTH, align,
369 480 + icd->y_skip_top, 0, 0); 420 &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
421 MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
370 422
371 return 0; 423 return 0;
372} 424}
373 425
374static int mt9v022_get_chip_id(struct soc_camera_device *icd, 426static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
375 struct v4l2_dbg_chip_ident *id) 427 struct v4l2_dbg_chip_ident *id)
376{ 428{
377 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 429 struct i2c_client *client = sd->priv;
430 struct mt9v022 *mt9v022 = to_mt9v022(client);
378 431
379 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 432 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
380 return -EINVAL; 433 return -EINVAL;
381 434
382 if (id->match.addr != mt9v022->client->addr) 435 if (id->match.addr != client->addr)
383 return -ENODEV; 436 return -ENODEV;
384 437
385 id->ident = mt9v022->model; 438 id->ident = mt9v022->model;
@@ -389,10 +442,10 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
389} 442}
390 443
391#ifdef CONFIG_VIDEO_ADV_DEBUG 444#ifdef CONFIG_VIDEO_ADV_DEBUG
392static int mt9v022_get_register(struct soc_camera_device *icd, 445static int mt9v022_g_register(struct v4l2_subdev *sd,
393 struct v4l2_dbg_register *reg) 446 struct v4l2_dbg_register *reg)
394{ 447{
395 struct i2c_client *client = to_i2c_client(icd->control); 448 struct i2c_client *client = sd->priv;
396 449
397 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 450 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
398 return -EINVAL; 451 return -EINVAL;
@@ -409,10 +462,10 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
409 return 0; 462 return 0;
410} 463}
411 464
412static int mt9v022_set_register(struct soc_camera_device *icd, 465static int mt9v022_s_register(struct v4l2_subdev *sd,
413 struct v4l2_dbg_register *reg) 466 struct v4l2_dbg_register *reg)
414{ 467{
415 struct i2c_client *client = to_i2c_client(icd->control); 468 struct i2c_client *client = sd->priv;
416 469
417 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 470 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
418 return -EINVAL; 471 return -EINVAL;
@@ -481,41 +534,22 @@ static const struct v4l2_queryctrl mt9v022_controls[] = {
481 } 534 }
482}; 535};
483 536
484static int mt9v022_video_probe(struct soc_camera_device *);
485static void mt9v022_video_remove(struct soc_camera_device *);
486static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
487static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
488
489static struct soc_camera_ops mt9v022_ops = { 537static struct soc_camera_ops mt9v022_ops = {
490 .owner = THIS_MODULE,
491 .probe = mt9v022_video_probe,
492 .remove = mt9v022_video_remove,
493 .init = mt9v022_init,
494 .release = mt9v022_release,
495 .start_capture = mt9v022_start_capture,
496 .stop_capture = mt9v022_stop_capture,
497 .set_crop = mt9v022_set_crop,
498 .set_fmt = mt9v022_set_fmt,
499 .try_fmt = mt9v022_try_fmt,
500 .set_bus_param = mt9v022_set_bus_param, 538 .set_bus_param = mt9v022_set_bus_param,
501 .query_bus_param = mt9v022_query_bus_param, 539 .query_bus_param = mt9v022_query_bus_param,
502 .controls = mt9v022_controls, 540 .controls = mt9v022_controls,
503 .num_controls = ARRAY_SIZE(mt9v022_controls), 541 .num_controls = ARRAY_SIZE(mt9v022_controls),
504 .get_control = mt9v022_get_control,
505 .set_control = mt9v022_set_control,
506 .get_chip_id = mt9v022_get_chip_id,
507#ifdef CONFIG_VIDEO_ADV_DEBUG
508 .get_register = mt9v022_get_register,
509 .set_register = mt9v022_set_register,
510#endif
511}; 542};
512 543
513static int mt9v022_get_control(struct soc_camera_device *icd, 544static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
514 struct v4l2_control *ctrl)
515{ 545{
516 struct i2c_client *client = to_i2c_client(icd->control); 546 struct i2c_client *client = sd->priv;
547 const struct v4l2_queryctrl *qctrl;
548 unsigned long range;
517 int data; 549 int data;
518 550
551 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
552
519 switch (ctrl->id) { 553 switch (ctrl->id) {
520 case V4L2_CID_VFLIP: 554 case V4L2_CID_VFLIP:
521 data = reg_read(client, MT9V022_READ_MODE); 555 data = reg_read(client, MT9V022_READ_MODE);
@@ -541,19 +575,35 @@ static int mt9v022_get_control(struct soc_camera_device *icd,
541 return -EIO; 575 return -EIO;
542 ctrl->value = !!(data & 0x2); 576 ctrl->value = !!(data & 0x2);
543 break; 577 break;
578 case V4L2_CID_GAIN:
579 data = reg_read(client, MT9V022_ANALOG_GAIN);
580 if (data < 0)
581 return -EIO;
582
583 range = qctrl->maximum - qctrl->minimum;
584 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
585
586 break;
587 case V4L2_CID_EXPOSURE:
588 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
589 if (data < 0)
590 return -EIO;
591
592 range = qctrl->maximum - qctrl->minimum;
593 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
594
595 break;
544 } 596 }
545 return 0; 597 return 0;
546} 598}
547 599
548static int mt9v022_set_control(struct soc_camera_device *icd, 600static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
549 struct v4l2_control *ctrl)
550{ 601{
551 int data; 602 int data;
552 struct i2c_client *client = to_i2c_client(icd->control); 603 struct i2c_client *client = sd->priv;
553 const struct v4l2_queryctrl *qctrl; 604 const struct v4l2_queryctrl *qctrl;
554 605
555 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); 606 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
556
557 if (!qctrl) 607 if (!qctrl)
558 return -EINVAL; 608 return -EINVAL;
559 609
@@ -580,12 +630,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
580 return -EINVAL; 630 return -EINVAL;
581 else { 631 else {
582 unsigned long range = qctrl->maximum - qctrl->minimum; 632 unsigned long range = qctrl->maximum - qctrl->minimum;
583 /* Datasheet says 16 to 64. autogain only works properly 633 /* Valid values 16 to 64, 32 to 64 must be even. */
584 * after setting gain to maximum 14. Larger values
585 * produce "white fly" noise effect. On the whole,
586 * manually setting analog gain does no good. */
587 unsigned long gain = ((ctrl->value - qctrl->minimum) * 634 unsigned long gain = ((ctrl->value - qctrl->minimum) *
588 10 + range / 2) / range + 4; 635 48 + range / 2) / range + 16;
589 if (gain >= 32) 636 if (gain >= 32)
590 gain &= ~1; 637 gain &= ~1;
591 /* The user wants to set gain manually, hope, she 638 /* The user wants to set gain manually, hope, she
@@ -594,11 +641,10 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
594 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 641 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
595 return -EIO; 642 return -EIO;
596 643
597 dev_info(&icd->dev, "Setting gain from %d to %lu\n", 644 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
598 reg_read(client, MT9V022_ANALOG_GAIN), gain); 645 reg_read(client, MT9V022_ANALOG_GAIN), gain);
599 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 646 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
600 return -EIO; 647 return -EIO;
601 icd->gain = ctrl->value;
602 } 648 }
603 break; 649 break;
604 case V4L2_CID_EXPOSURE: 650 case V4L2_CID_EXPOSURE:
@@ -615,13 +661,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
615 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 661 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
616 return -EIO; 662 return -EIO;
617 663
618 dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", 664 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
619 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 665 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
620 shutter); 666 shutter);
621 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 667 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
622 shutter) < 0) 668 shutter) < 0)
623 return -EIO; 669 return -EIO;
624 icd->exposure = ctrl->value;
625 } 670 }
626 break; 671 break;
627 case V4L2_CID_AUTOGAIN: 672 case V4L2_CID_AUTOGAIN:
@@ -646,11 +691,11 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
646 691
647/* Interface active, can use i2c. If it fails, it can indeed mean, that 692/* Interface active, can use i2c. If it fails, it can indeed mean, that
648 * this wasn't our capture interface, so, we wait for the right one */ 693 * this wasn't our capture interface, so, we wait for the right one */
649static int mt9v022_video_probe(struct soc_camera_device *icd) 694static int mt9v022_video_probe(struct soc_camera_device *icd,
695 struct i2c_client *client)
650{ 696{
651 struct i2c_client *client = to_i2c_client(icd->control); 697 struct mt9v022 *mt9v022 = to_mt9v022(client);
652 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 698 struct soc_camera_link *icl = to_soc_camera_link(icd);
653 struct soc_camera_link *icl = client->dev.platform_data;
654 s32 data; 699 s32 data;
655 int ret; 700 int ret;
656 unsigned long flags; 701 unsigned long flags;
@@ -665,7 +710,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
665 /* must be 0x1311 or 0x1313 */ 710 /* must be 0x1311 or 0x1313 */
666 if (data != 0x1311 && data != 0x1313) { 711 if (data != 0x1311 && data != 0x1313) {
667 ret = -ENODEV; 712 ret = -ENODEV;
668 dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n", 713 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
669 data); 714 data);
670 goto ei2c; 715 goto ei2c;
671 } 716 }
@@ -677,7 +722,9 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
677 /* 15 clock cycles */ 722 /* 15 clock cycles */
678 udelay(200); 723 udelay(200);
679 if (reg_read(client, MT9V022_RESET)) { 724 if (reg_read(client, MT9V022_RESET)) {
680 dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); 725 dev_err(&client->dev, "Resetting MT9V022 failed!\n");
726 if (ret > 0)
727 ret = -EIO;
681 goto ei2c; 728 goto ei2c;
682 } 729 }
683 730
@@ -694,7 +741,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
694 } 741 }
695 742
696 if (ret < 0) 743 if (ret < 0)
697 goto eisis; 744 goto ei2c;
698 745
699 icd->num_formats = 0; 746 icd->num_formats = 0;
700 747
@@ -716,42 +763,70 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
716 if (flags & SOCAM_DATAWIDTH_8) 763 if (flags & SOCAM_DATAWIDTH_8)
717 icd->num_formats++; 764 icd->num_formats++;
718 765
719 ret = soc_camera_video_start(icd); 766 mt9v022->fourcc = icd->formats->fourcc;
720 if (ret < 0)
721 goto eisis;
722 767
723 dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", 768 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
724 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? 769 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
725 "monochrome" : "colour"); 770 "monochrome" : "colour");
726 771
727 return 0; 772 ret = mt9v022_init(client);
773 if (ret < 0)
774 dev_err(&client->dev, "Failed to initialise the camera\n");
728 775
729eisis:
730ei2c: 776ei2c:
731 return ret; 777 return ret;
732} 778}
733 779
734static void mt9v022_video_remove(struct soc_camera_device *icd) 780static void mt9v022_video_remove(struct soc_camera_device *icd)
735{ 781{
736 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 782 struct soc_camera_link *icl = to_soc_camera_link(icd);
737 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
738 783
739 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, 784 dev_dbg(&icd->dev, "Video removed: %p, %p\n",
740 icd->dev.parent, icd->vdev); 785 icd->dev.parent, icd->vdev);
741 soc_camera_video_stop(icd);
742 if (icl->free_bus) 786 if (icl->free_bus)
743 icl->free_bus(icl); 787 icl->free_bus(icl);
744} 788}
745 789
790static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
791 .g_ctrl = mt9v022_g_ctrl,
792 .s_ctrl = mt9v022_s_ctrl,
793 .g_chip_ident = mt9v022_g_chip_ident,
794#ifdef CONFIG_VIDEO_ADV_DEBUG
795 .g_register = mt9v022_g_register,
796 .s_register = mt9v022_s_register,
797#endif
798};
799
800static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
801 .s_stream = mt9v022_s_stream,
802 .s_fmt = mt9v022_s_fmt,
803 .g_fmt = mt9v022_g_fmt,
804 .try_fmt = mt9v022_try_fmt,
805 .s_crop = mt9v022_s_crop,
806 .g_crop = mt9v022_g_crop,
807 .cropcap = mt9v022_cropcap,
808};
809
810static struct v4l2_subdev_ops mt9v022_subdev_ops = {
811 .core = &mt9v022_subdev_core_ops,
812 .video = &mt9v022_subdev_video_ops,
813};
814
746static int mt9v022_probe(struct i2c_client *client, 815static int mt9v022_probe(struct i2c_client *client,
747 const struct i2c_device_id *did) 816 const struct i2c_device_id *did)
748{ 817{
749 struct mt9v022 *mt9v022; 818 struct mt9v022 *mt9v022;
750 struct soc_camera_device *icd; 819 struct soc_camera_device *icd = client->dev.platform_data;
751 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 820 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
752 struct soc_camera_link *icl = client->dev.platform_data; 821 struct soc_camera_link *icl;
753 int ret; 822 int ret;
754 823
824 if (!icd) {
825 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
826 return -EINVAL;
827 }
828
829 icl = to_soc_camera_link(icd);
755 if (!icl) { 830 if (!icl) {
756 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 831 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
757 return -EINVAL; 832 return -EINVAL;
@@ -767,40 +842,41 @@ static int mt9v022_probe(struct i2c_client *client,
767 if (!mt9v022) 842 if (!mt9v022)
768 return -ENOMEM; 843 return -ENOMEM;
769 844
845 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
846
770 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 847 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
771 mt9v022->client = client;
772 i2c_set_clientdata(client, mt9v022);
773
774 icd = &mt9v022->icd;
775 icd->ops = &mt9v022_ops;
776 icd->control = &client->dev;
777 icd->x_min = 1;
778 icd->y_min = 4;
779 icd->x_current = 1;
780 icd->y_current = 4;
781 icd->width_min = 48;
782 icd->width_max = 752;
783 icd->height_min = 32;
784 icd->height_max = 480;
785 icd->y_skip_top = 1;
786 icd->iface = icl->bus_id;
787
788 ret = soc_camera_device_register(icd);
789 if (ret)
790 goto eisdr;
791 848
792 return 0; 849 icd->ops = &mt9v022_ops;
850 /*
851 * MT9V022 _really_ corrupts the first read out line.
852 * TODO: verify on i.MX31
853 */
854 icd->y_skip_top = 1;
855
856 mt9v022->rect.left = MT9V022_COLUMN_SKIP;
857 mt9v022->rect.top = MT9V022_ROW_SKIP;
858 mt9v022->rect.width = MT9V022_MAX_WIDTH;
859 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
860
861 ret = mt9v022_video_probe(icd, client);
862 if (ret) {
863 icd->ops = NULL;
864 i2c_set_clientdata(client, NULL);
865 kfree(mt9v022);
866 }
793 867
794eisdr:
795 kfree(mt9v022);
796 return ret; 868 return ret;
797} 869}
798 870
799static int mt9v022_remove(struct i2c_client *client) 871static int mt9v022_remove(struct i2c_client *client)
800{ 872{
801 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 873 struct mt9v022 *mt9v022 = to_mt9v022(client);
874 struct soc_camera_device *icd = client->dev.platform_data;
802 875
803 soc_camera_device_unregister(&mt9v022->icd); 876 icd->ops = NULL;
877 mt9v022_video_remove(icd);
878 i2c_set_clientdata(client, NULL);
879 client->driver = NULL;
804 kfree(mt9v022); 880 kfree(mt9v022);
805 881
806 return 0; 882 return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 736c31d23194..5f37952c75cf 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -126,7 +126,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
126{ 126{
127 struct soc_camera_device *icd = vq->priv_data; 127 struct soc_camera_device *icd = vq->priv_data;
128 128
129 *size = icd->width * icd->height * 129 *size = icd->user_width * icd->user_height *
130 ((icd->current_fmt->depth + 7) >> 3); 130 ((icd->current_fmt->depth + 7) >> 3);
131 131
132 if (!*count) 132 if (!*count)
@@ -135,7 +135,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
135 while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 135 while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
136 (*count)--; 136 (*count)--;
137 137
138 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 138 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
139 139
140 return 0; 140 return 0;
141} 141}
@@ -147,7 +147,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
147 147
148 BUG_ON(in_interrupt()); 148 BUG_ON(in_interrupt());
149 149
150 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 150 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
151 vb, vb->baddr, vb->bsize); 151 vb, vb->baddr, vb->bsize);
152 152
153 /* This waits until this buffer is out of danger, i.e., until it is no 153 /* This waits until this buffer is out of danger, i.e., until it is no
@@ -165,7 +165,7 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
165 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 165 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
166 int ret; 166 int ret;
167 167
168 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 168 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
169 vb, vb->baddr, vb->bsize); 169 vb, vb->baddr, vb->bsize);
170 170
171 /* Added list head initialization on alloc */ 171 /* Added list head initialization on alloc */
@@ -178,12 +178,12 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
178 buf->inwork = 1; 178 buf->inwork = 1;
179 179
180 if (buf->fmt != icd->current_fmt || 180 if (buf->fmt != icd->current_fmt ||
181 vb->width != icd->width || 181 vb->width != icd->user_width ||
182 vb->height != icd->height || 182 vb->height != icd->user_height ||
183 vb->field != field) { 183 vb->field != field) {
184 buf->fmt = icd->current_fmt; 184 buf->fmt = icd->current_fmt;
185 vb->width = icd->width; 185 vb->width = icd->user_width;
186 vb->height = icd->height; 186 vb->height = icd->user_height;
187 vb->field = field; 187 vb->field = field;
188 vb->state = VIDEOBUF_NEEDS_INIT; 188 vb->state = VIDEOBUF_NEEDS_INIT;
189 } 189 }
@@ -216,10 +216,11 @@ out:
216static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) 216static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
217{ 217{
218 struct videobuf_buffer *vbuf = &pcdev->active->vb; 218 struct videobuf_buffer *vbuf = &pcdev->active->vb;
219 struct device *dev = pcdev->icd->dev.parent;
219 int ret; 220 int ret;
220 221
221 if (unlikely(!pcdev->active)) { 222 if (unlikely(!pcdev->active)) {
222 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); 223 dev_err(dev, "DMA End IRQ with no active buffer\n");
223 return -EFAULT; 224 return -EFAULT;
224 } 225 }
225 226
@@ -229,7 +230,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
229 vbuf->size, pcdev->res->start + 230 vbuf->size, pcdev->res->start +
230 CSIRXR, DMA_MODE_READ); 231 CSIRXR, DMA_MODE_READ);
231 if (unlikely(ret)) 232 if (unlikely(ret))
232 dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n"); 233 dev_err(dev, "Failed to setup DMA sg list\n");
233 234
234 return ret; 235 return ret;
235} 236}
@@ -243,7 +244,7 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
243 struct mx1_camera_dev *pcdev = ici->priv; 244 struct mx1_camera_dev *pcdev = ici->priv;
244 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 245 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
245 246
246 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 247 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
247 vb, vb->baddr, vb->bsize); 248 vb, vb->baddr, vb->bsize);
248 249
249 list_add_tail(&vb->queue, &pcdev->capture); 250 list_add_tail(&vb->queue, &pcdev->capture);
@@ -270,22 +271,23 @@ static void mx1_videobuf_release(struct videobuf_queue *vq,
270 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 271 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
271#ifdef DEBUG 272#ifdef DEBUG
272 struct soc_camera_device *icd = vq->priv_data; 273 struct soc_camera_device *icd = vq->priv_data;
274 struct device *dev = icd->dev.parent;
273 275
274 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 276 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
275 vb, vb->baddr, vb->bsize); 277 vb, vb->baddr, vb->bsize);
276 278
277 switch (vb->state) { 279 switch (vb->state) {
278 case VIDEOBUF_ACTIVE: 280 case VIDEOBUF_ACTIVE:
279 dev_dbg(&icd->dev, "%s (active)\n", __func__); 281 dev_dbg(dev, "%s (active)\n", __func__);
280 break; 282 break;
281 case VIDEOBUF_QUEUED: 283 case VIDEOBUF_QUEUED:
282 dev_dbg(&icd->dev, "%s (queued)\n", __func__); 284 dev_dbg(dev, "%s (queued)\n", __func__);
283 break; 285 break;
284 case VIDEOBUF_PREPARED: 286 case VIDEOBUF_PREPARED:
285 dev_dbg(&icd->dev, "%s (prepared)\n", __func__); 287 dev_dbg(dev, "%s (prepared)\n", __func__);
286 break; 288 break;
287 default: 289 default:
288 dev_dbg(&icd->dev, "%s (unknown)\n", __func__); 290 dev_dbg(dev, "%s (unknown)\n", __func__);
289 break; 291 break;
290 } 292 }
291#endif 293#endif
@@ -325,6 +327,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
325static void mx1_camera_dma_irq(int channel, void *data) 327static void mx1_camera_dma_irq(int channel, void *data)
326{ 328{
327 struct mx1_camera_dev *pcdev = data; 329 struct mx1_camera_dev *pcdev = data;
330 struct device *dev = pcdev->icd->dev.parent;
328 struct mx1_buffer *buf; 331 struct mx1_buffer *buf;
329 struct videobuf_buffer *vb; 332 struct videobuf_buffer *vb;
330 unsigned long flags; 333 unsigned long flags;
@@ -334,14 +337,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
334 imx_dma_disable(channel); 337 imx_dma_disable(channel);
335 338
336 if (unlikely(!pcdev->active)) { 339 if (unlikely(!pcdev->active)) {
337 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); 340 dev_err(dev, "DMA End IRQ with no active buffer\n");
338 goto out; 341 goto out;
339 } 342 }
340 343
341 vb = &pcdev->active->vb; 344 vb = &pcdev->active->vb;
342 buf = container_of(vb, struct mx1_buffer, vb); 345 buf = container_of(vb, struct mx1_buffer, vb);
343 WARN_ON(buf->inwork || list_empty(&vb->queue)); 346 WARN_ON(buf->inwork || list_empty(&vb->queue));
344 dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 347 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
345 vb, vb->baddr, vb->bsize); 348 vb, vb->baddr, vb->bsize);
346 349
347 mx1_camera_wakeup(pcdev, vb, buf); 350 mx1_camera_wakeup(pcdev, vb, buf);
@@ -362,7 +365,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
362 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 365 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
363 struct mx1_camera_dev *pcdev = ici->priv; 366 struct mx1_camera_dev *pcdev = ici->priv;
364 367
365 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev, 368 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent,
366 &pcdev->lock, 369 &pcdev->lock,
367 V4L2_BUF_TYPE_VIDEO_CAPTURE, 370 V4L2_BUF_TYPE_VIDEO_CAPTURE,
368 V4L2_FIELD_NONE, 371 V4L2_FIELD_NONE,
@@ -381,8 +384,9 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
381 * they get a nice Oops */ 384 * they get a nice Oops */
382 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; 385 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
383 386
384 dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, " 387 dev_dbg(pcdev->icd->dev.parent,
385 "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); 388 "System clock %lukHz, target freq %dkHz, divisor %lu\n",
389 lcdclk / 1000, mclk / 1000, div);
386 390
387 return div; 391 return div;
388} 392}
@@ -391,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
391{ 395{
392 unsigned int csicr1 = CSICR1_EN; 396 unsigned int csicr1 = CSICR1_EN;
393 397
394 dev_dbg(pcdev->soc_host.dev, "Activate device\n"); 398 dev_dbg(pcdev->icd->dev.parent, "Activate device\n");
395 399
396 clk_enable(pcdev->clk); 400 clk_enable(pcdev->clk);
397 401
@@ -407,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
407 411
408static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) 412static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
409{ 413{
410 dev_dbg(pcdev->soc_host.dev, "Deactivate device\n"); 414 dev_dbg(pcdev->icd->dev.parent, "Deactivate device\n");
411 415
412 /* Disable all CSI interface */ 416 /* Disable all CSI interface */
413 __raw_writel(0x00, pcdev->base + CSICR1); 417 __raw_writel(0x00, pcdev->base + CSICR1);
@@ -428,14 +432,12 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
428 goto ebusy; 432 goto ebusy;
429 } 433 }
430 434
431 dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n", 435 dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
432 icd->devnum); 436 icd->devnum);
433 437
434 mx1_camera_activate(pcdev); 438 mx1_camera_activate(pcdev);
435 ret = icd->ops->init(icd);
436 439
437 if (!ret) 440 pcdev->icd = icd;
438 pcdev->icd = icd;
439 441
440ebusy: 442ebusy:
441 return ret; 443 return ret;
@@ -456,20 +458,20 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
456 /* Stop DMA engine */ 458 /* Stop DMA engine */
457 imx_dma_disable(pcdev->dma_chan); 459 imx_dma_disable(pcdev->dma_chan);
458 460
459 dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n", 461 dev_info(icd->dev.parent, "MX1 Camera driver detached from camera %d\n",
460 icd->devnum); 462 icd->devnum);
461 463
462 icd->ops->release(icd);
463
464 mx1_camera_deactivate(pcdev); 464 mx1_camera_deactivate(pcdev);
465 465
466 pcdev->icd = NULL; 466 pcdev->icd = NULL;
467} 467}
468 468
469static int mx1_camera_set_crop(struct soc_camera_device *icd, 469static int mx1_camera_set_crop(struct soc_camera_device *icd,
470 struct v4l2_rect *rect) 470 struct v4l2_crop *a)
471{ 471{
472 return icd->ops->set_crop(icd, rect); 472 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
473
474 return v4l2_subdev_call(sd, video, s_crop, a);
473} 475}
474 476
475static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 477static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
@@ -539,18 +541,19 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
539static int mx1_camera_set_fmt(struct soc_camera_device *icd, 541static int mx1_camera_set_fmt(struct soc_camera_device *icd,
540 struct v4l2_format *f) 542 struct v4l2_format *f)
541{ 543{
542 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 544 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
543 const struct soc_camera_format_xlate *xlate; 545 const struct soc_camera_format_xlate *xlate;
544 struct v4l2_pix_format *pix = &f->fmt.pix; 546 struct v4l2_pix_format *pix = &f->fmt.pix;
545 int ret; 547 int ret;
546 548
547 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 549 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
548 if (!xlate) { 550 if (!xlate) {
549 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 551 dev_warn(icd->dev.parent, "Format %x not found\n",
552 pix->pixelformat);
550 return -EINVAL; 553 return -EINVAL;
551 } 554 }
552 555
553 ret = icd->ops->set_fmt(icd, f); 556 ret = v4l2_subdev_call(sd, video, s_fmt, f);
554 if (!ret) { 557 if (!ret) {
555 icd->buswidth = xlate->buswidth; 558 icd->buswidth = xlate->buswidth;
556 icd->current_fmt = xlate->host_fmt; 559 icd->current_fmt = xlate->host_fmt;
@@ -562,10 +565,11 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
562static int mx1_camera_try_fmt(struct soc_camera_device *icd, 565static int mx1_camera_try_fmt(struct soc_camera_device *icd,
563 struct v4l2_format *f) 566 struct v4l2_format *f)
564{ 567{
568 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
565 /* TODO: limit to mx1 hardware capabilities */ 569 /* TODO: limit to mx1 hardware capabilities */
566 570
567 /* limit to sensor capabilities */ 571 /* limit to sensor capabilities */
568 return icd->ops->try_fmt(icd, f); 572 return v4l2_subdev_call(sd, video, try_fmt, f);
569} 573}
570 574
571static int mx1_camera_reqbufs(struct soc_camera_file *icf, 575static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -737,7 +741,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
737 pcdev->soc_host.drv_name = DRIVER_NAME; 741 pcdev->soc_host.drv_name = DRIVER_NAME;
738 pcdev->soc_host.ops = &mx1_soc_camera_host_ops; 742 pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
739 pcdev->soc_host.priv = pcdev; 743 pcdev->soc_host.priv = pcdev;
740 pcdev->soc_host.dev = &pdev->dev; 744 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
741 pcdev->soc_host.nr = pdev->id; 745 pcdev->soc_host.nr = pdev->id;
742 err = soc_camera_host_register(&pcdev->soc_host); 746 err = soc_camera_host_register(&pcdev->soc_host);
743 if (err) 747 if (err)
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 9770cb7932ca..dff2e5e2d8c6 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -178,7 +178,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
178 178
179 BUG_ON(in_interrupt()); 179 BUG_ON(in_interrupt());
180 180
181 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 181 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
182 vb, vb->baddr, vb->bsize); 182 vb, vb->baddr, vb->bsize);
183 183
184 /* 184 /*
@@ -220,7 +220,7 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
220 if (!mx3_cam->idmac_channel[0]) 220 if (!mx3_cam->idmac_channel[0])
221 return -EINVAL; 221 return -EINVAL;
222 222
223 *size = icd->width * icd->height * bpp; 223 *size = icd->user_width * icd->user_height * bpp;
224 224
225 if (!*count) 225 if (!*count)
226 *count = 32; 226 *count = 32;
@@ -241,7 +241,7 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
241 struct mx3_camera_buffer *buf = 241 struct mx3_camera_buffer *buf =
242 container_of(vb, struct mx3_camera_buffer, vb); 242 container_of(vb, struct mx3_camera_buffer, vb);
243 /* current_fmt _must_ always be set */ 243 /* current_fmt _must_ always be set */
244 size_t new_size = icd->width * icd->height * 244 size_t new_size = icd->user_width * icd->user_height *
245 ((icd->current_fmt->depth + 7) >> 3); 245 ((icd->current_fmt->depth + 7) >> 3);
246 int ret; 246 int ret;
247 247
@@ -251,12 +251,12 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
251 */ 251 */
252 252
253 if (buf->fmt != icd->current_fmt || 253 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 254 vb->width != icd->user_width ||
255 vb->height != icd->height || 255 vb->height != icd->user_height ||
256 vb->field != field) { 256 vb->field != field) {
257 buf->fmt = icd->current_fmt; 257 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 258 vb->width = icd->user_width;
259 vb->height = icd->height; 259 vb->height = icd->user_height;
260 vb->field = field; 260 vb->field = field;
261 if (vb->state != VIDEOBUF_NEEDS_INIT) 261 if (vb->state != VIDEOBUF_NEEDS_INIT)
262 free_buffer(vq, buf); 262 free_buffer(vq, buf);
@@ -354,9 +354,9 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
354 354
355 /* This is the configuration of one sg-element */ 355 /* This is the configuration of one sg-element */
356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); 356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
357 video->out_width = icd->width; 357 video->out_width = icd->user_width;
358 video->out_height = icd->height; 358 video->out_height = icd->user_height;
359 video->out_stride = icd->width; 359 video->out_stride = icd->user_width;
360 360
361#ifdef DEBUG 361#ifdef DEBUG
362 /* helps to see what DMA actually has written */ 362 /* helps to see what DMA actually has written */
@@ -375,7 +375,8 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
375 spin_unlock_irq(&mx3_cam->lock); 375 spin_unlock_irq(&mx3_cam->lock);
376 376
377 cookie = txd->tx_submit(txd); 377 cookie = txd->tx_submit(txd);
378 dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg)); 378 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n",
379 cookie, sg_dma_address(&buf->sg));
379 380
380 spin_lock_irq(&mx3_cam->lock); 381 spin_lock_irq(&mx3_cam->lock);
381 382
@@ -402,9 +403,10 @@ static void mx3_videobuf_release(struct videobuf_queue *vq,
402 container_of(vb, struct mx3_camera_buffer, vb); 403 container_of(vb, struct mx3_camera_buffer, vb);
403 unsigned long flags; 404 unsigned long flags;
404 405
405 dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n", 406 dev_dbg(icd->dev.parent,
407 "Release%s DMA 0x%08x (state %d), queue %sempty\n",
406 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), 408 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
407 vb->state, list_empty(&vb->queue) ? "" : "not "); 409 vb->state, list_empty(&vb->queue) ? "" : "not ");
408 spin_lock_irqsave(&mx3_cam->lock, flags); 410 spin_lock_irqsave(&mx3_cam->lock, flags);
409 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && 411 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
410 !list_empty(&vb->queue)) { 412 !list_empty(&vb->queue)) {
@@ -431,7 +433,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
431 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 433 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
432 struct mx3_camera_dev *mx3_cam = ici->priv; 434 struct mx3_camera_dev *mx3_cam = ici->priv;
433 435
434 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev, 436 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, icd->dev.parent,
435 &mx3_cam->lock, 437 &mx3_cam->lock,
436 V4L2_BUF_TYPE_VIDEO_CAPTURE, 438 V4L2_BUF_TYPE_VIDEO_CAPTURE,
437 V4L2_FIELD_NONE, 439 V4L2_FIELD_NONE,
@@ -484,7 +486,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
484 486
485 clk_enable(mx3_cam->clk); 487 clk_enable(mx3_cam->clk);
486 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk); 488 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
487 dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate); 489 dev_dbg(icd->dev.parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
488 if (rate) 490 if (rate)
489 clk_set_rate(mx3_cam->clk, rate); 491 clk_set_rate(mx3_cam->clk, rate);
490} 492}
@@ -494,29 +496,18 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
494{ 496{
495 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 497 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
496 struct mx3_camera_dev *mx3_cam = ici->priv; 498 struct mx3_camera_dev *mx3_cam = ici->priv;
497 int ret;
498 499
499 if (mx3_cam->icd) { 500 if (mx3_cam->icd)
500 ret = -EBUSY; 501 return -EBUSY;
501 goto ebusy;
502 }
503 502
504 mx3_camera_activate(mx3_cam, icd); 503 mx3_camera_activate(mx3_cam, icd);
505 ret = icd->ops->init(icd);
506 if (ret < 0) {
507 clk_disable(mx3_cam->clk);
508 goto einit;
509 }
510 504
511 mx3_cam->icd = icd; 505 mx3_cam->icd = icd;
512 506
513einit: 507 dev_info(icd->dev.parent, "MX3 Camera driver attached to camera %d\n",
514ebusy: 508 icd->devnum);
515 if (!ret)
516 dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
517 icd->devnum);
518 509
519 return ret; 510 return 0;
520} 511}
521 512
522/* Called with .video_lock held */ 513/* Called with .video_lock held */
@@ -533,13 +524,11 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
533 *ichan = NULL; 524 *ichan = NULL;
534 } 525 }
535 526
536 icd->ops->release(icd);
537
538 clk_disable(mx3_cam->clk); 527 clk_disable(mx3_cam->clk);
539 528
540 mx3_cam->icd = NULL; 529 mx3_cam->icd = NULL;
541 530
542 dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n", 531 dev_info(icd->dev.parent, "MX3 Camera driver detached from camera %d\n",
543 icd->devnum); 532 icd->devnum);
544} 533}
545 534
@@ -551,7 +540,8 @@ static bool channel_change_requested(struct soc_camera_device *icd,
551 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 540 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
552 541
553 /* Do buffers have to be re-allocated or channel re-configured? */ 542 /* Do buffers have to be re-allocated or channel re-configured? */
554 return ichan && rect->width * rect->height > icd->width * icd->height; 543 return ichan && rect->width * rect->height >
544 icd->user_width * icd->user_height;
555} 545}
556 546
557static int test_platform_param(struct mx3_camera_dev *mx3_cam, 547static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -599,8 +589,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
599 *flags |= SOCAM_DATAWIDTH_4; 589 *flags |= SOCAM_DATAWIDTH_4;
600 break; 590 break;
601 default: 591 default:
602 dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n", 592 dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
603 buswidth); 593 "Unsupported bus width %d\n", buswidth);
604 return -EINVAL; 594 return -EINVAL;
605 } 595 }
606 596
@@ -615,7 +605,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
615 unsigned long bus_flags, camera_flags; 605 unsigned long bus_flags, camera_flags;
616 int ret = test_platform_param(mx3_cam, depth, &bus_flags); 606 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
617 607
618 dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret); 608 dev_dbg(icd->dev.parent, "request bus width %d bit: %d\n", depth, ret);
619 609
620 if (ret < 0) 610 if (ret < 0)
621 return ret; 611 return ret;
@@ -624,7 +614,8 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
624 614
625 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); 615 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
626 if (ret < 0) 616 if (ret < 0)
627 dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n", 617 dev_warn(icd->dev.parent,
618 "Flags incompatible: camera %lx, host %lx\n",
628 camera_flags, bus_flags); 619 camera_flags, bus_flags);
629 620
630 return ret; 621 return ret;
@@ -638,7 +629,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
638 if (!rq) 629 if (!rq)
639 return false; 630 return false;
640 631
641 pdata = rq->mx3_cam->soc_host.dev->platform_data; 632 pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
642 633
643 return rq->id == chan->chan_id && 634 return rq->id == chan->chan_id &&
644 pdata->dma_dev == chan->device->dev; 635 pdata->dma_dev == chan->device->dev;
@@ -698,7 +689,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
698 xlate->cam_fmt = icd->formats + idx; 689 xlate->cam_fmt = icd->formats + idx;
699 xlate->buswidth = buswidth; 690 xlate->buswidth = buswidth;
700 xlate++; 691 xlate++;
701 dev_dbg(ici->dev, "Providing format %s using %s\n", 692 dev_dbg(icd->dev.parent,
693 "Providing format %s using %s\n",
702 mx3_camera_formats[0].name, 694 mx3_camera_formats[0].name,
703 icd->formats[idx].name); 695 icd->formats[idx].name);
704 } 696 }
@@ -710,7 +702,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
710 xlate->cam_fmt = icd->formats + idx; 702 xlate->cam_fmt = icd->formats + idx;
711 xlate->buswidth = buswidth; 703 xlate->buswidth = buswidth;
712 xlate++; 704 xlate++;
713 dev_dbg(ici->dev, "Providing format %s using %s\n", 705 dev_dbg(icd->dev.parent,
706 "Providing format %s using %s\n",
714 mx3_camera_formats[0].name, 707 mx3_camera_formats[0].name,
715 icd->formats[idx].name); 708 icd->formats[idx].name);
716 } 709 }
@@ -723,7 +716,7 @@ passthrough:
723 xlate->cam_fmt = icd->formats + idx; 716 xlate->cam_fmt = icd->formats + idx;
724 xlate->buswidth = buswidth; 717 xlate->buswidth = buswidth;
725 xlate++; 718 xlate++;
726 dev_dbg(ici->dev, 719 dev_dbg(icd->dev.parent,
727 "Providing format %s in pass-through mode\n", 720 "Providing format %s in pass-through mode\n",
728 icd->formats[idx].name); 721 icd->formats[idx].name);
729 } 722 }
@@ -733,13 +726,13 @@ passthrough:
733} 726}
734 727
735static void configure_geometry(struct mx3_camera_dev *mx3_cam, 728static void configure_geometry(struct mx3_camera_dev *mx3_cam,
736 struct v4l2_rect *rect) 729 unsigned int width, unsigned int height)
737{ 730{
738 u32 ctrl, width_field, height_field; 731 u32 ctrl, width_field, height_field;
739 732
740 /* Setup frame size - this cannot be changed on-the-fly... */ 733 /* Setup frame size - this cannot be changed on-the-fly... */
741 width_field = rect->width - 1; 734 width_field = width - 1;
742 height_field = rect->height - 1; 735 height_field = height - 1;
743 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE); 736 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
744 737
745 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1); 738 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
@@ -751,11 +744,6 @@ static void configure_geometry(struct mx3_camera_dev *mx3_cam,
751 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; 744 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
752 /* Sensor does the cropping */ 745 /* Sensor does the cropping */
753 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL); 746 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
754
755 /*
756 * No need to free resources here if we fail, we'll see if we need to
757 * do this next time we are called
758 */
759} 747}
760 748
761static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam) 749static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
@@ -792,25 +780,74 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
792 return 0; 780 return 0;
793} 781}
794 782
783/*
784 * FIXME: learn to use stride != width, then we can keep stride properly aligned
785 * and support arbitrary (even) widths.
786 */
787static inline void stride_align(__s32 *width)
788{
789 if (((*width + 7) & ~7) < 4096)
790 *width = (*width + 7) & ~7;
791 else
792 *width = *width & ~7;
793}
794
795/*
796 * As long as we don't implement host-side cropping and scaling, we can use
797 * default g_crop and cropcap from soc_camera.c
798 */
795static int mx3_camera_set_crop(struct soc_camera_device *icd, 799static int mx3_camera_set_crop(struct soc_camera_device *icd,
796 struct v4l2_rect *rect) 800 struct v4l2_crop *a)
797{ 801{
802 struct v4l2_rect *rect = &a->c;
798 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 803 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
799 struct mx3_camera_dev *mx3_cam = ici->priv; 804 struct mx3_camera_dev *mx3_cam = ici->priv;
805 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
806 struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
807 struct v4l2_pix_format *pix = &f.fmt.pix;
808 int ret;
800 809
801 /* 810 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
802 * We now know pixel formats and can decide upon DMA-channel(s) 811 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
803 * So far only direct camera-to-memory is supported 812
804 */ 813 ret = v4l2_subdev_call(sd, video, s_crop, a);
805 if (channel_change_requested(icd, rect)) { 814 if (ret < 0)
806 int ret = acquire_dma_channel(mx3_cam); 815 return ret;
816
817 /* The capture device might have changed its output */
818 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
819 if (ret < 0)
820 return ret;
821
822 if (pix->width & 7) {
823 /* Ouch! We can only handle 8-byte aligned width... */
824 stride_align(&pix->width);
825 ret = v4l2_subdev_call(sd, video, s_fmt, &f);
807 if (ret < 0) 826 if (ret < 0)
808 return ret; 827 return ret;
809 } 828 }
810 829
811 configure_geometry(mx3_cam, rect); 830 if (pix->width != icd->user_width || pix->height != icd->user_height) {
831 /*
832 * We now know pixel formats and can decide upon DMA-channel(s)
833 * So far only direct camera-to-memory is supported
834 */
835 if (channel_change_requested(icd, rect)) {
836 int ret = acquire_dma_channel(mx3_cam);
837 if (ret < 0)
838 return ret;
839 }
840
841 configure_geometry(mx3_cam, pix->width, pix->height);
842 }
843
844 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
845 pix->width, pix->height);
812 846
813 return icd->ops->set_crop(icd, rect); 847 icd->user_width = pix->width;
848 icd->user_height = pix->height;
849
850 return ret;
814} 851}
815 852
816static int mx3_camera_set_fmt(struct soc_camera_device *icd, 853static int mx3_camera_set_fmt(struct soc_camera_device *icd,
@@ -818,22 +855,21 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
818{ 855{
819 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 856 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
820 struct mx3_camera_dev *mx3_cam = ici->priv; 857 struct mx3_camera_dev *mx3_cam = ici->priv;
858 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
821 const struct soc_camera_format_xlate *xlate; 859 const struct soc_camera_format_xlate *xlate;
822 struct v4l2_pix_format *pix = &f->fmt.pix; 860 struct v4l2_pix_format *pix = &f->fmt.pix;
823 struct v4l2_rect rect = {
824 .left = icd->x_current,
825 .top = icd->y_current,
826 .width = pix->width,
827 .height = pix->height,
828 };
829 int ret; 861 int ret;
830 862
831 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 863 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
832 if (!xlate) { 864 if (!xlate) {
833 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 865 dev_warn(icd->dev.parent, "Format %x not found\n",
866 pix->pixelformat);
834 return -EINVAL; 867 return -EINVAL;
835 } 868 }
836 869
870 stride_align(&pix->width);
871 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height);
872
837 ret = acquire_dma_channel(mx3_cam); 873 ret = acquire_dma_channel(mx3_cam);
838 if (ret < 0) 874 if (ret < 0)
839 return ret; 875 return ret;
@@ -844,21 +880,23 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
844 * mxc_v4l2_s_fmt() 880 * mxc_v4l2_s_fmt()
845 */ 881 */
846 882
847 configure_geometry(mx3_cam, &rect); 883 configure_geometry(mx3_cam, pix->width, pix->height);
848 884
849 ret = icd->ops->set_fmt(icd, f); 885 ret = v4l2_subdev_call(sd, video, s_fmt, f);
850 if (!ret) { 886 if (!ret) {
851 icd->buswidth = xlate->buswidth; 887 icd->buswidth = xlate->buswidth;
852 icd->current_fmt = xlate->host_fmt; 888 icd->current_fmt = xlate->host_fmt;
853 } 889 }
854 890
891 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
892
855 return ret; 893 return ret;
856} 894}
857 895
858static int mx3_camera_try_fmt(struct soc_camera_device *icd, 896static int mx3_camera_try_fmt(struct soc_camera_device *icd,
859 struct v4l2_format *f) 897 struct v4l2_format *f)
860{ 898{
861 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 899 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
862 const struct soc_camera_format_xlate *xlate; 900 const struct soc_camera_format_xlate *xlate;
863 struct v4l2_pix_format *pix = &f->fmt.pix; 901 struct v4l2_pix_format *pix = &f->fmt.pix;
864 __u32 pixfmt = pix->pixelformat; 902 __u32 pixfmt = pix->pixelformat;
@@ -867,7 +905,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
867 905
868 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 906 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
869 if (pixfmt && !xlate) { 907 if (pixfmt && !xlate) {
870 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 908 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
871 return -EINVAL; 909 return -EINVAL;
872 } 910 }
873 911
@@ -884,7 +922,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
884 /* camera has to see its format, but the user the original one */ 922 /* camera has to see its format, but the user the original one */
885 pix->pixelformat = xlate->cam_fmt->fourcc; 923 pix->pixelformat = xlate->cam_fmt->fourcc;
886 /* limit to sensor capabilities */ 924 /* limit to sensor capabilities */
887 ret = icd->ops->try_fmt(icd, f); 925 ret = v4l2_subdev_call(sd, video, try_fmt, f);
888 pix->pixelformat = xlate->host_fmt->fourcc; 926 pix->pixelformat = xlate->host_fmt->fourcc;
889 927
890 field = pix->field; 928 field = pix->field;
@@ -892,7 +930,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
892 if (field == V4L2_FIELD_ANY) { 930 if (field == V4L2_FIELD_ANY) {
893 pix->field = V4L2_FIELD_NONE; 931 pix->field = V4L2_FIELD_NONE;
894 } else if (field != V4L2_FIELD_NONE) { 932 } else if (field != V4L2_FIELD_NONE) {
895 dev_err(&icd->dev, "Field type %d unsupported.\n", field); 933 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
896 return -EINVAL; 934 return -EINVAL;
897 } 935 }
898 936
@@ -931,14 +969,15 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
931 u32 dw, sens_conf; 969 u32 dw, sens_conf;
932 int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); 970 int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
933 const struct soc_camera_format_xlate *xlate; 971 const struct soc_camera_format_xlate *xlate;
972 struct device *dev = icd->dev.parent;
934 973
935 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 974 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
936 if (!xlate) { 975 if (!xlate) {
937 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 976 dev_warn(dev, "Format %x not found\n", pixfmt);
938 return -EINVAL; 977 return -EINVAL;
939 } 978 }
940 979
941 dev_dbg(ici->dev, "requested bus width %d bit: %d\n", 980 dev_dbg(dev, "requested bus width %d bit: %d\n",
942 icd->buswidth, ret); 981 icd->buswidth, ret);
943 982
944 if (ret < 0) 983 if (ret < 0)
@@ -947,9 +986,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
947 camera_flags = icd->ops->query_bus_param(icd); 986 camera_flags = icd->ops->query_bus_param(icd);
948 987
949 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 988 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
989 dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
990 camera_flags, bus_flags, common_flags);
950 if (!common_flags) { 991 if (!common_flags) {
951 dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n", 992 dev_dbg(dev, "no common flags");
952 camera_flags, bus_flags);
953 return -EINVAL; 993 return -EINVAL;
954 } 994 }
955 995
@@ -1002,8 +1042,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1002 SOCAM_DATAWIDTH_4; 1042 SOCAM_DATAWIDTH_4;
1003 1043
1004 ret = icd->ops->set_bus_param(icd, common_flags); 1044 ret = icd->ops->set_bus_param(icd, common_flags);
1005 if (ret < 0) 1045 if (ret < 0) {
1046 dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
1047 common_flags, ret);
1006 return ret; 1048 return ret;
1049 }
1007 1050
1008 /* 1051 /*
1009 * So far only gated clock mode is supported. Add a line 1052 * So far only gated clock mode is supported. Add a line
@@ -1055,7 +1098,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1055 1098
1056 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); 1099 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1057 1100
1058 dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); 1101 dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1059 1102
1060 return 0; 1103 return 0;
1061} 1104}
@@ -1127,8 +1170,9 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1127 INIT_LIST_HEAD(&mx3_cam->capture); 1170 INIT_LIST_HEAD(&mx3_cam->capture);
1128 spin_lock_init(&mx3_cam->lock); 1171 spin_lock_init(&mx3_cam->lock);
1129 1172
1130 base = ioremap(res->start, res->end - res->start + 1); 1173 base = ioremap(res->start, resource_size(res));
1131 if (!base) { 1174 if (!base) {
1175 pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
1132 err = -ENOMEM; 1176 err = -ENOMEM;
1133 goto eioremap; 1177 goto eioremap;
1134 } 1178 }
@@ -1139,7 +1183,7 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1139 soc_host->drv_name = MX3_CAM_DRV_NAME; 1183 soc_host->drv_name = MX3_CAM_DRV_NAME;
1140 soc_host->ops = &mx3_soc_camera_host_ops; 1184 soc_host->ops = &mx3_soc_camera_host_ops;
1141 soc_host->priv = mx3_cam; 1185 soc_host->priv = mx3_cam;
1142 soc_host->dev = &pdev->dev; 1186 soc_host->v4l2_dev.dev = &pdev->dev;
1143 soc_host->nr = pdev->id; 1187 soc_host->nr = pdev->id;
1144 1188
1145 err = soc_camera_host_register(soc_host); 1189 err = soc_camera_host_register(soc_host);
@@ -1215,3 +1259,4 @@ module_exit(mx3_camera_exit);
1215MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver"); 1259MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
1216MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); 1260MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
1217MODULE_LICENSE("GPL v2"); 1261MODULE_LICENSE("GPL v2");
1262MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 35890e8b2431..3454070e63f0 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -186,19 +186,19 @@ static int mxb_probe(struct saa7146_dev *dev)
186 } 186 }
187 187
188 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 188 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
189 "saa7115", "saa7111", I2C_SAA7111A); 189 "saa7115", "saa7111", I2C_SAA7111A, NULL);
190 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 190 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
191 "tea6420", "tea6420", I2C_TEA6420_1); 191 "tea6420", "tea6420", I2C_TEA6420_1, NULL);
192 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 192 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
193 "tea6420", "tea6420", I2C_TEA6420_2); 193 "tea6420", "tea6420", I2C_TEA6420_2, NULL);
194 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 194 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
195 "tea6415c", "tea6415c", I2C_TEA6415C); 195 "tea6415c", "tea6415c", I2C_TEA6415C, NULL);
196 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 196 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
197 "tda9840", "tda9840", I2C_TDA9840); 197 "tda9840", "tda9840", I2C_TDA9840, NULL);
198 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 198 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
199 "tuner", "tuner", I2C_TUNER); 199 "tuner", "tuner", I2C_TUNER, NULL);
200 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 200 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
201 "saa5246a", "saa5246a", I2C_SAA5246A)) { 201 "saa5246a", "saa5246a", I2C_SAA5246A, NULL)) {
202 printk(KERN_INFO "mxb: found teletext decoder\n"); 202 printk(KERN_INFO "mxb: found teletext decoder\n");
203 } 203 }
204 204
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 0bce255168bd..eccb40ab7fec 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -22,7 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/videodev2.h> 23#include <linux/videodev2.h>
24#include <media/v4l2-chip-ident.h> 24#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-common.h> 25#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h> 26#include <media/soc_camera.h>
27#include <media/ov772x.h> 27#include <media/ov772x.h>
28 28
@@ -382,11 +382,10 @@ struct regval_list {
382}; 382};
383 383
384struct ov772x_color_format { 384struct ov772x_color_format {
385 char *name; 385 const struct soc_camera_data_format *format;
386 __u32 fourcc; 386 u8 dsp3;
387 u8 dsp3; 387 u8 com3;
388 u8 com3; 388 u8 com7;
389 u8 com7;
390}; 389};
391 390
392struct ov772x_win_size { 391struct ov772x_win_size {
@@ -398,14 +397,15 @@ struct ov772x_win_size {
398}; 397};
399 398
400struct ov772x_priv { 399struct ov772x_priv {
400 struct v4l2_subdev subdev;
401 struct ov772x_camera_info *info; 401 struct ov772x_camera_info *info;
402 struct i2c_client *client;
403 struct soc_camera_device icd;
404 const struct ov772x_color_format *fmt; 402 const struct ov772x_color_format *fmt;
405 const struct ov772x_win_size *win; 403 const struct ov772x_win_size *win;
406 int model; 404 int model;
407 unsigned int flag_vflip:1; 405 unsigned short flag_vflip:1;
408 unsigned int flag_hflip:1; 406 unsigned short flag_hflip:1;
407 /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
408 unsigned short band_filter;
409}; 409};
410 410
411#define ENDMARKER { 0xff, 0xff } 411#define ENDMARKER { 0xff, 0xff }
@@ -481,43 +481,43 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
481 */ 481 */
482static const struct ov772x_color_format ov772x_cfmts[] = { 482static const struct ov772x_color_format ov772x_cfmts[] = {
483 { 483 {
484 SETFOURCC(YUYV), 484 .format = &ov772x_fmt_lists[0],
485 .dsp3 = 0x0, 485 .dsp3 = 0x0,
486 .com3 = SWAP_YUV, 486 .com3 = SWAP_YUV,
487 .com7 = OFMT_YUV, 487 .com7 = OFMT_YUV,
488 }, 488 },
489 { 489 {
490 SETFOURCC(YVYU), 490 .format = &ov772x_fmt_lists[1],
491 .dsp3 = UV_ON, 491 .dsp3 = UV_ON,
492 .com3 = SWAP_YUV, 492 .com3 = SWAP_YUV,
493 .com7 = OFMT_YUV, 493 .com7 = OFMT_YUV,
494 }, 494 },
495 { 495 {
496 SETFOURCC(UYVY), 496 .format = &ov772x_fmt_lists[2],
497 .dsp3 = 0x0, 497 .dsp3 = 0x0,
498 .com3 = 0x0, 498 .com3 = 0x0,
499 .com7 = OFMT_YUV, 499 .com7 = OFMT_YUV,
500 }, 500 },
501 { 501 {
502 SETFOURCC(RGB555), 502 .format = &ov772x_fmt_lists[3],
503 .dsp3 = 0x0, 503 .dsp3 = 0x0,
504 .com3 = SWAP_RGB, 504 .com3 = SWAP_RGB,
505 .com7 = FMT_RGB555 | OFMT_RGB, 505 .com7 = FMT_RGB555 | OFMT_RGB,
506 }, 506 },
507 { 507 {
508 SETFOURCC(RGB555X), 508 .format = &ov772x_fmt_lists[4],
509 .dsp3 = 0x0, 509 .dsp3 = 0x0,
510 .com3 = 0x0, 510 .com3 = 0x0,
511 .com7 = FMT_RGB555 | OFMT_RGB, 511 .com7 = FMT_RGB555 | OFMT_RGB,
512 }, 512 },
513 { 513 {
514 SETFOURCC(RGB565), 514 .format = &ov772x_fmt_lists[5],
515 .dsp3 = 0x0, 515 .dsp3 = 0x0,
516 .com3 = SWAP_RGB, 516 .com3 = SWAP_RGB,
517 .com7 = FMT_RGB565 | OFMT_RGB, 517 .com7 = FMT_RGB565 | OFMT_RGB,
518 }, 518 },
519 { 519 {
520 SETFOURCC(RGB565X), 520 .format = &ov772x_fmt_lists[6],
521 .dsp3 = 0x0, 521 .dsp3 = 0x0,
522 .com3 = 0x0, 522 .com3 = 0x0,
523 .com7 = FMT_RGB565 | OFMT_RGB, 523 .com7 = FMT_RGB565 | OFMT_RGB,
@@ -570,6 +570,15 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
570 .step = 1, 570 .step = 1,
571 .default_value = 0, 571 .default_value = 0,
572 }, 572 },
573 {
574 .id = V4L2_CID_BAND_STOP_FILTER,
575 .type = V4L2_CTRL_TYPE_INTEGER,
576 .name = "Band-stop filter",
577 .minimum = 0,
578 .maximum = 256,
579 .step = 1,
580 .default_value = 0,
581 },
573}; 582};
574 583
575 584
@@ -577,6 +586,12 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
577 * general function 586 * general function
578 */ 587 */
579 588
589static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
590{
591 return container_of(i2c_get_clientdata(client), struct ov772x_priv,
592 subdev);
593}
594
580static int ov772x_write_array(struct i2c_client *client, 595static int ov772x_write_array(struct i2c_client *client,
581 const struct regval_list *vals) 596 const struct regval_list *vals)
582{ 597{
@@ -617,58 +632,29 @@ static int ov772x_reset(struct i2c_client *client)
617 * soc_camera_ops function 632 * soc_camera_ops function
618 */ 633 */
619 634
620static int ov772x_init(struct soc_camera_device *icd) 635static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
621{ 636{
622 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 637 struct i2c_client *client = sd->priv;
623 int ret = 0; 638 struct ov772x_priv *priv = to_ov772x(client);
624 639
625 if (priv->info->link.power) { 640 if (!enable) {
626 ret = priv->info->link.power(&priv->client->dev, 1); 641 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
627 if (ret < 0) 642 return 0;
628 return ret;
629 } 643 }
630 644
631 if (priv->info->link.reset)
632 ret = priv->info->link.reset(&priv->client->dev);
633
634 return ret;
635}
636
637static int ov772x_release(struct soc_camera_device *icd)
638{
639 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
640 int ret = 0;
641
642 if (priv->info->link.power)
643 ret = priv->info->link.power(&priv->client->dev, 0);
644
645 return ret;
646}
647
648static int ov772x_start_capture(struct soc_camera_device *icd)
649{
650 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
651
652 if (!priv->win || !priv->fmt) { 645 if (!priv->win || !priv->fmt) {
653 dev_err(&icd->dev, "norm or win select error\n"); 646 dev_err(&client->dev, "norm or win select error\n");
654 return -EPERM; 647 return -EPERM;
655 } 648 }
656 649
657 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0); 650 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
658 651
659 dev_dbg(&icd->dev, 652 dev_dbg(&client->dev, "format %s, win %s\n",
660 "format %s, win %s\n", priv->fmt->name, priv->win->name); 653 priv->fmt->format->name, priv->win->name);
661 654
662 return 0; 655 return 0;
663} 656}
664 657
665static int ov772x_stop_capture(struct soc_camera_device *icd)
666{
667 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
668 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
669 return 0;
670}
671
672static int ov772x_set_bus_param(struct soc_camera_device *icd, 658static int ov772x_set_bus_param(struct soc_camera_device *icd,
673 unsigned long flags) 659 unsigned long flags)
674{ 660{
@@ -677,8 +663,9 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
677 663
678static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) 664static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
679{ 665{
680 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 666 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
681 struct soc_camera_link *icl = &priv->info->link; 667 struct ov772x_priv *priv = i2c_get_clientdata(client);
668 struct soc_camera_link *icl = to_soc_camera_link(icd);
682 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 669 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
683 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 670 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
684 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 671 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -686,10 +673,10 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
686 return soc_camera_apply_sensor_flags(icl, flags); 673 return soc_camera_apply_sensor_flags(icl, flags);
687} 674}
688 675
689static int ov772x_get_control(struct soc_camera_device *icd, 676static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
690 struct v4l2_control *ctrl)
691{ 677{
692 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 678 struct i2c_client *client = sd->priv;
679 struct ov772x_priv *priv = to_ov772x(client);
693 680
694 switch (ctrl->id) { 681 switch (ctrl->id) {
695 case V4L2_CID_VFLIP: 682 case V4L2_CID_VFLIP:
@@ -698,14 +685,17 @@ static int ov772x_get_control(struct soc_camera_device *icd,
698 case V4L2_CID_HFLIP: 685 case V4L2_CID_HFLIP:
699 ctrl->value = priv->flag_hflip; 686 ctrl->value = priv->flag_hflip;
700 break; 687 break;
688 case V4L2_CID_BAND_STOP_FILTER:
689 ctrl->value = priv->band_filter;
690 break;
701 } 691 }
702 return 0; 692 return 0;
703} 693}
704 694
705static int ov772x_set_control(struct soc_camera_device *icd, 695static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
706 struct v4l2_control *ctrl)
707{ 696{
708 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 697 struct i2c_client *client = sd->priv;
698 struct ov772x_priv *priv = to_ov772x(client);
709 int ret = 0; 699 int ret = 0;
710 u8 val; 700 u8 val;
711 701
@@ -715,24 +705,48 @@ static int ov772x_set_control(struct soc_camera_device *icd,
715 priv->flag_vflip = ctrl->value; 705 priv->flag_vflip = ctrl->value;
716 if (priv->info->flags & OV772X_FLAG_VFLIP) 706 if (priv->info->flags & OV772X_FLAG_VFLIP)
717 val ^= VFLIP_IMG; 707 val ^= VFLIP_IMG;
718 ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val); 708 ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val);
719 break; 709 break;
720 case V4L2_CID_HFLIP: 710 case V4L2_CID_HFLIP:
721 val = ctrl->value ? HFLIP_IMG : 0x00; 711 val = ctrl->value ? HFLIP_IMG : 0x00;
722 priv->flag_hflip = ctrl->value; 712 priv->flag_hflip = ctrl->value;
723 if (priv->info->flags & OV772X_FLAG_HFLIP) 713 if (priv->info->flags & OV772X_FLAG_HFLIP)
724 val ^= HFLIP_IMG; 714 val ^= HFLIP_IMG;
725 ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val); 715 ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
716 break;
717 case V4L2_CID_BAND_STOP_FILTER:
718 if ((unsigned)ctrl->value > 256)
719 ctrl->value = 256;
720 if (ctrl->value == priv->band_filter)
721 break;
722 if (!ctrl->value) {
723 /* Switch the filter off, it is on now */
724 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
725 if (!ret)
726 ret = ov772x_mask_set(client, COM8,
727 BNDF_ON_OFF, 0);
728 } else {
729 /* Switch the filter on, set AEC low limit */
730 val = 256 - ctrl->value;
731 ret = ov772x_mask_set(client, COM8,
732 BNDF_ON_OFF, BNDF_ON_OFF);
733 if (!ret)
734 ret = ov772x_mask_set(client, BDBASE,
735 0xff, val);
736 }
737 if (!ret)
738 priv->band_filter = ctrl->value;
726 break; 739 break;
727 } 740 }
728 741
729 return ret; 742 return ret;
730} 743}
731 744
732static int ov772x_get_chip_id(struct soc_camera_device *icd, 745static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
733 struct v4l2_dbg_chip_ident *id) 746 struct v4l2_dbg_chip_ident *id)
734{ 747{
735 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 748 struct i2c_client *client = sd->priv;
749 struct ov772x_priv *priv = to_ov772x(client);
736 750
737 id->ident = priv->model; 751 id->ident = priv->model;
738 id->revision = 0; 752 id->revision = 0;
@@ -741,17 +755,17 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd,
741} 755}
742 756
743#ifdef CONFIG_VIDEO_ADV_DEBUG 757#ifdef CONFIG_VIDEO_ADV_DEBUG
744static int ov772x_get_register(struct soc_camera_device *icd, 758static int ov772x_g_register(struct v4l2_subdev *sd,
745 struct v4l2_dbg_register *reg) 759 struct v4l2_dbg_register *reg)
746{ 760{
747 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 761 struct i2c_client *client = sd->priv;
748 int ret; 762 int ret;
749 763
750 reg->size = 1; 764 reg->size = 1;
751 if (reg->reg > 0xff) 765 if (reg->reg > 0xff)
752 return -EINVAL; 766 return -EINVAL;
753 767
754 ret = i2c_smbus_read_byte_data(priv->client, reg->reg); 768 ret = i2c_smbus_read_byte_data(client, reg->reg);
755 if (ret < 0) 769 if (ret < 0)
756 return ret; 770 return ret;
757 771
@@ -760,21 +774,20 @@ static int ov772x_get_register(struct soc_camera_device *icd,
760 return 0; 774 return 0;
761} 775}
762 776
763static int ov772x_set_register(struct soc_camera_device *icd, 777static int ov772x_s_register(struct v4l2_subdev *sd,
764 struct v4l2_dbg_register *reg) 778 struct v4l2_dbg_register *reg)
765{ 779{
766 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 780 struct i2c_client *client = sd->priv;
767 781
768 if (reg->reg > 0xff || 782 if (reg->reg > 0xff ||
769 reg->val > 0xff) 783 reg->val > 0xff)
770 return -EINVAL; 784 return -EINVAL;
771 785
772 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); 786 return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
773} 787}
774#endif 788#endif
775 789
776static const struct ov772x_win_size* 790static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
777ov772x_select_win(u32 width, u32 height)
778{ 791{
779 __u32 diff; 792 __u32 diff;
780 const struct ov772x_win_size *win; 793 const struct ov772x_win_size *win;
@@ -793,9 +806,10 @@ ov772x_select_win(u32 width, u32 height)
793 return win; 806 return win;
794} 807}
795 808
796static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height, 809static int ov772x_set_params(struct i2c_client *client,
797 u32 pixfmt) 810 u32 *width, u32 *height, u32 pixfmt)
798{ 811{
812 struct ov772x_priv *priv = to_ov772x(client);
799 int ret = -EINVAL; 813 int ret = -EINVAL;
800 u8 val; 814 u8 val;
801 int i; 815 int i;
@@ -805,7 +819,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
805 */ 819 */
806 priv->fmt = NULL; 820 priv->fmt = NULL;
807 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 821 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
808 if (pixfmt == ov772x_cfmts[i].fourcc) { 822 if (pixfmt == ov772x_cfmts[i].format->fourcc) {
809 priv->fmt = ov772x_cfmts + i; 823 priv->fmt = ov772x_cfmts + i;
810 break; 824 break;
811 } 825 }
@@ -816,12 +830,12 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
816 /* 830 /*
817 * select win 831 * select win
818 */ 832 */
819 priv->win = ov772x_select_win(width, height); 833 priv->win = ov772x_select_win(*width, *height);
820 834
821 /* 835 /*
822 * reset hardware 836 * reset hardware
823 */ 837 */
824 ov772x_reset(priv->client); 838 ov772x_reset(client);
825 839
826 /* 840 /*
827 * Edge Ctrl 841 * Edge Ctrl
@@ -835,17 +849,17 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
835 * Remove it when manual mode. 849 * Remove it when manual mode.
836 */ 850 */
837 851
838 ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00); 852 ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
839 if (ret < 0) 853 if (ret < 0)
840 goto ov772x_set_fmt_error; 854 goto ov772x_set_fmt_error;
841 855
842 ret = ov772x_mask_set(priv->client, 856 ret = ov772x_mask_set(client,
843 EDGE_TRSHLD, EDGE_THRESHOLD_MASK, 857 EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
844 priv->info->edgectrl.threshold); 858 priv->info->edgectrl.threshold);
845 if (ret < 0) 859 if (ret < 0)
846 goto ov772x_set_fmt_error; 860 goto ov772x_set_fmt_error;
847 861
848 ret = ov772x_mask_set(priv->client, 862 ret = ov772x_mask_set(client,
849 EDGE_STRNGT, EDGE_STRENGTH_MASK, 863 EDGE_STRNGT, EDGE_STRENGTH_MASK,
850 priv->info->edgectrl.strength); 864 priv->info->edgectrl.strength);
851 if (ret < 0) 865 if (ret < 0)
@@ -857,13 +871,13 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
857 * 871 *
858 * set upper and lower limit 872 * set upper and lower limit
859 */ 873 */
860 ret = ov772x_mask_set(priv->client, 874 ret = ov772x_mask_set(client,
861 EDGE_UPPER, EDGE_UPPER_MASK, 875 EDGE_UPPER, EDGE_UPPER_MASK,
862 priv->info->edgectrl.upper); 876 priv->info->edgectrl.upper);
863 if (ret < 0) 877 if (ret < 0)
864 goto ov772x_set_fmt_error; 878 goto ov772x_set_fmt_error;
865 879
866 ret = ov772x_mask_set(priv->client, 880 ret = ov772x_mask_set(client,
867 EDGE_LOWER, EDGE_LOWER_MASK, 881 EDGE_LOWER, EDGE_LOWER_MASK,
868 priv->info->edgectrl.lower); 882 priv->info->edgectrl.lower);
869 if (ret < 0) 883 if (ret < 0)
@@ -873,7 +887,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
873 /* 887 /*
874 * set size format 888 * set size format
875 */ 889 */
876 ret = ov772x_write_array(priv->client, priv->win->regs); 890 ret = ov772x_write_array(client, priv->win->regs);
877 if (ret < 0) 891 if (ret < 0)
878 goto ov772x_set_fmt_error; 892 goto ov772x_set_fmt_error;
879 893
@@ -882,7 +896,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
882 */ 896 */
883 val = priv->fmt->dsp3; 897 val = priv->fmt->dsp3;
884 if (val) { 898 if (val) {
885 ret = ov772x_mask_set(priv->client, 899 ret = ov772x_mask_set(client,
886 DSP_CTRL3, UV_MASK, val); 900 DSP_CTRL3, UV_MASK, val);
887 if (ret < 0) 901 if (ret < 0)
888 goto ov772x_set_fmt_error; 902 goto ov772x_set_fmt_error;
@@ -901,7 +915,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
901 if (priv->flag_hflip) 915 if (priv->flag_hflip)
902 val ^= HFLIP_IMG; 916 val ^= HFLIP_IMG;
903 917
904 ret = ov772x_mask_set(priv->client, 918 ret = ov772x_mask_set(client,
905 COM3, SWAP_MASK | IMG_MASK, val); 919 COM3, SWAP_MASK | IMG_MASK, val);
906 if (ret < 0) 920 if (ret < 0)
907 goto ov772x_set_fmt_error; 921 goto ov772x_set_fmt_error;
@@ -910,47 +924,99 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
910 * set COM7 924 * set COM7
911 */ 925 */
912 val = priv->win->com7_bit | priv->fmt->com7; 926 val = priv->win->com7_bit | priv->fmt->com7;
913 ret = ov772x_mask_set(priv->client, 927 ret = ov772x_mask_set(client,
914 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), 928 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
915 val); 929 val);
916 if (ret < 0) 930 if (ret < 0)
917 goto ov772x_set_fmt_error; 931 goto ov772x_set_fmt_error;
918 932
933 /*
934 * set COM8
935 */
936 if (priv->band_filter) {
937 ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1);
938 if (!ret)
939 ret = ov772x_mask_set(client, BDBASE,
940 0xff, 256 - priv->band_filter);
941 if (ret < 0)
942 goto ov772x_set_fmt_error;
943 }
944
945 *width = priv->win->width;
946 *height = priv->win->height;
947
919 return ret; 948 return ret;
920 949
921ov772x_set_fmt_error: 950ov772x_set_fmt_error:
922 951
923 ov772x_reset(priv->client); 952 ov772x_reset(client);
924 priv->win = NULL; 953 priv->win = NULL;
925 priv->fmt = NULL; 954 priv->fmt = NULL;
926 955
927 return ret; 956 return ret;
928} 957}
929 958
930static int ov772x_set_crop(struct soc_camera_device *icd, 959static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
931 struct v4l2_rect *rect)
932{ 960{
933 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 961 a->c.left = 0;
962 a->c.top = 0;
963 a->c.width = VGA_WIDTH;
964 a->c.height = VGA_HEIGHT;
965 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
934 966
935 if (!priv->fmt) 967 return 0;
936 return -EINVAL; 968}
937 969
938 return ov772x_set_params(priv, rect->width, rect->height, 970static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
939 priv->fmt->fourcc); 971{
972 a->bounds.left = 0;
973 a->bounds.top = 0;
974 a->bounds.width = VGA_WIDTH;
975 a->bounds.height = VGA_HEIGHT;
976 a->defrect = a->bounds;
977 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
978 a->pixelaspect.numerator = 1;
979 a->pixelaspect.denominator = 1;
980
981 return 0;
940} 982}
941 983
942static int ov772x_set_fmt(struct soc_camera_device *icd, 984static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
943 struct v4l2_format *f) 985{
986 struct i2c_client *client = sd->priv;
987 struct ov772x_priv *priv = to_ov772x(client);
988 struct v4l2_pix_format *pix = &f->fmt.pix;
989
990 if (!priv->win || !priv->fmt) {
991 u32 width = VGA_WIDTH, height = VGA_HEIGHT;
992 int ret = ov772x_set_params(client, &width, &height,
993 V4L2_PIX_FMT_YUYV);
994 if (ret < 0)
995 return ret;
996 }
997
998 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
999
1000 pix->width = priv->win->width;
1001 pix->height = priv->win->height;
1002 pix->pixelformat = priv->fmt->format->fourcc;
1003 pix->colorspace = priv->fmt->format->colorspace;
1004 pix->field = V4L2_FIELD_NONE;
1005
1006 return 0;
1007}
1008
1009static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
944{ 1010{
945 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 1011 struct i2c_client *client = sd->priv;
946 struct v4l2_pix_format *pix = &f->fmt.pix; 1012 struct v4l2_pix_format *pix = &f->fmt.pix;
947 1013
948 return ov772x_set_params(priv, pix->width, pix->height, 1014 return ov772x_set_params(client, &pix->width, &pix->height,
949 pix->pixelformat); 1015 pix->pixelformat);
950} 1016}
951 1017
952static int ov772x_try_fmt(struct soc_camera_device *icd, 1018static int ov772x_try_fmt(struct v4l2_subdev *sd,
953 struct v4l2_format *f) 1019 struct v4l2_format *f)
954{ 1020{
955 struct v4l2_pix_format *pix = &f->fmt.pix; 1021 struct v4l2_pix_format *pix = &f->fmt.pix;
956 const struct ov772x_win_size *win; 1022 const struct ov772x_win_size *win;
@@ -967,9 +1033,10 @@ static int ov772x_try_fmt(struct soc_camera_device *icd,
967 return 0; 1033 return 0;
968} 1034}
969 1035
970static int ov772x_video_probe(struct soc_camera_device *icd) 1036static int ov772x_video_probe(struct soc_camera_device *icd,
1037 struct i2c_client *client)
971{ 1038{
972 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 1039 struct ov772x_priv *priv = to_ov772x(client);
973 u8 pid, ver; 1040 u8 pid, ver;
974 const char *devname; 1041 const char *devname;
975 1042
@@ -986,7 +1053,7 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
986 */ 1053 */
987 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth && 1054 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
988 SOCAM_DATAWIDTH_8 != priv->info->buswidth) { 1055 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
989 dev_err(&icd->dev, "bus width error\n"); 1056 dev_err(&client->dev, "bus width error\n");
990 return -ENODEV; 1057 return -ENODEV;
991 } 1058 }
992 1059
@@ -996,8 +1063,8 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
996 /* 1063 /*
997 * check and show product ID and manufacturer ID 1064 * check and show product ID and manufacturer ID
998 */ 1065 */
999 pid = i2c_smbus_read_byte_data(priv->client, PID); 1066 pid = i2c_smbus_read_byte_data(client, PID);
1000 ver = i2c_smbus_read_byte_data(priv->client, VER); 1067 ver = i2c_smbus_read_byte_data(client, VER);
1001 1068
1002 switch (VERSION(pid, ver)) { 1069 switch (VERSION(pid, ver)) {
1003 case OV7720: 1070 case OV7720:
@@ -1009,69 +1076,77 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
1009 priv->model = V4L2_IDENT_OV7725; 1076 priv->model = V4L2_IDENT_OV7725;
1010 break; 1077 break;
1011 default: 1078 default:
1012 dev_err(&icd->dev, 1079 dev_err(&client->dev,
1013 "Product ID error %x:%x\n", pid, ver); 1080 "Product ID error %x:%x\n", pid, ver);
1014 return -ENODEV; 1081 return -ENODEV;
1015 } 1082 }
1016 1083
1017 dev_info(&icd->dev, 1084 dev_info(&client->dev,
1018 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 1085 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1019 devname, 1086 devname,
1020 pid, 1087 pid,
1021 ver, 1088 ver,
1022 i2c_smbus_read_byte_data(priv->client, MIDH), 1089 i2c_smbus_read_byte_data(client, MIDH),
1023 i2c_smbus_read_byte_data(priv->client, MIDL)); 1090 i2c_smbus_read_byte_data(client, MIDL));
1024
1025 return soc_camera_video_start(icd);
1026}
1027 1091
1028static void ov772x_video_remove(struct soc_camera_device *icd) 1092 return 0;
1029{
1030 soc_camera_video_stop(icd);
1031} 1093}
1032 1094
1033static struct soc_camera_ops ov772x_ops = { 1095static struct soc_camera_ops ov772x_ops = {
1034 .owner = THIS_MODULE,
1035 .probe = ov772x_video_probe,
1036 .remove = ov772x_video_remove,
1037 .init = ov772x_init,
1038 .release = ov772x_release,
1039 .start_capture = ov772x_start_capture,
1040 .stop_capture = ov772x_stop_capture,
1041 .set_crop = ov772x_set_crop,
1042 .set_fmt = ov772x_set_fmt,
1043 .try_fmt = ov772x_try_fmt,
1044 .set_bus_param = ov772x_set_bus_param, 1096 .set_bus_param = ov772x_set_bus_param,
1045 .query_bus_param = ov772x_query_bus_param, 1097 .query_bus_param = ov772x_query_bus_param,
1046 .controls = ov772x_controls, 1098 .controls = ov772x_controls,
1047 .num_controls = ARRAY_SIZE(ov772x_controls), 1099 .num_controls = ARRAY_SIZE(ov772x_controls),
1048 .get_control = ov772x_get_control, 1100};
1049 .set_control = ov772x_set_control, 1101
1050 .get_chip_id = ov772x_get_chip_id, 1102static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1103 .g_ctrl = ov772x_g_ctrl,
1104 .s_ctrl = ov772x_s_ctrl,
1105 .g_chip_ident = ov772x_g_chip_ident,
1051#ifdef CONFIG_VIDEO_ADV_DEBUG 1106#ifdef CONFIG_VIDEO_ADV_DEBUG
1052 .get_register = ov772x_get_register, 1107 .g_register = ov772x_g_register,
1053 .set_register = ov772x_set_register, 1108 .s_register = ov772x_s_register,
1054#endif 1109#endif
1055}; 1110};
1056 1111
1112static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1113 .s_stream = ov772x_s_stream,
1114 .g_fmt = ov772x_g_fmt,
1115 .s_fmt = ov772x_s_fmt,
1116 .try_fmt = ov772x_try_fmt,
1117 .cropcap = ov772x_cropcap,
1118 .g_crop = ov772x_g_crop,
1119};
1120
1121static struct v4l2_subdev_ops ov772x_subdev_ops = {
1122 .core = &ov772x_subdev_core_ops,
1123 .video = &ov772x_subdev_video_ops,
1124};
1125
1057/* 1126/*
1058 * i2c_driver function 1127 * i2c_driver function
1059 */ 1128 */
1060 1129
1061static int ov772x_probe(struct i2c_client *client, 1130static int ov772x_probe(struct i2c_client *client,
1062 const struct i2c_device_id *did) 1131 const struct i2c_device_id *did)
1063{ 1132{
1064 struct ov772x_priv *priv; 1133 struct ov772x_priv *priv;
1065 struct ov772x_camera_info *info; 1134 struct ov772x_camera_info *info;
1066 struct soc_camera_device *icd; 1135 struct soc_camera_device *icd = client->dev.platform_data;
1067 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1136 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1137 struct soc_camera_link *icl;
1068 int ret; 1138 int ret;
1069 1139
1070 if (!client->dev.platform_data) 1140 if (!icd) {
1141 dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
1071 return -EINVAL; 1142 return -EINVAL;
1143 }
1072 1144
1073 info = container_of(client->dev.platform_data, 1145 icl = to_soc_camera_link(icd);
1074 struct ov772x_camera_info, link); 1146 if (!icl)
1147 return -EINVAL;
1148
1149 info = container_of(icl, struct ov772x_camera_info, link);
1075 1150
1076 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1151 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1077 dev_err(&adapter->dev, 1152 dev_err(&adapter->dev,
@@ -1084,20 +1159,15 @@ static int ov772x_probe(struct i2c_client *client,
1084 if (!priv) 1159 if (!priv)
1085 return -ENOMEM; 1160 return -ENOMEM;
1086 1161
1087 priv->info = info; 1162 priv->info = info;
1088 priv->client = client;
1089 i2c_set_clientdata(client, priv);
1090 1163
1091 icd = &priv->icd; 1164 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1092 icd->ops = &ov772x_ops;
1093 icd->control = &client->dev;
1094 icd->width_max = MAX_WIDTH;
1095 icd->height_max = MAX_HEIGHT;
1096 icd->iface = priv->info->link.bus_id;
1097 1165
1098 ret = soc_camera_device_register(icd); 1166 icd->ops = &ov772x_ops;
1099 1167
1168 ret = ov772x_video_probe(icd, client);
1100 if (ret) { 1169 if (ret) {
1170 icd->ops = NULL;
1101 i2c_set_clientdata(client, NULL); 1171 i2c_set_clientdata(client, NULL);
1102 kfree(priv); 1172 kfree(priv);
1103 } 1173 }
@@ -1107,9 +1177,10 @@ static int ov772x_probe(struct i2c_client *client,
1107 1177
1108static int ov772x_remove(struct i2c_client *client) 1178static int ov772x_remove(struct i2c_client *client)
1109{ 1179{
1110 struct ov772x_priv *priv = i2c_get_clientdata(client); 1180 struct ov772x_priv *priv = to_ov772x(client);
1181 struct soc_camera_device *icd = client->dev.platform_data;
1111 1182
1112 soc_camera_device_unregister(&priv->icd); 1183 icd->ops = NULL;
1113 i2c_set_clientdata(client, NULL); 1184 i2c_set_clientdata(client, NULL);
1114 kfree(priv); 1185 kfree(priv);
1115 return 0; 1186 return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 336a20eded0f..e4d7c13cab87 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -298,6 +298,7 @@ static struct tda829x_config tda829x_no_probe = {
298 298
299static struct tda18271_config hauppauge_tda18271_dvb_config = { 299static struct tda18271_config hauppauge_tda18271_dvb_config = {
300 .gate = TDA18271_GATE_ANALOG, 300 .gate = TDA18271_GATE_ANALOG,
301 .output_opt = TDA18271_OUTPUT_LT_OFF,
301}; 302};
302 303
303static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap) 304static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
@@ -393,6 +394,7 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
393static struct tda18271_config hauppauge_tda18271_config = { 394static struct tda18271_config hauppauge_tda18271_config = {
394 .std_map = &hauppauge_tda18271_std_map, 395 .std_map = &hauppauge_tda18271_std_map,
395 .gate = TDA18271_GATE_ANALOG, 396 .gate = TDA18271_GATE_ANALOG,
397 .output_opt = TDA18271_OUTPUT_LT_OFF,
396}; 398};
397 399
398static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap) 400static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index cbc388729d77..13639b302700 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2063,8 +2063,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2063 return -EINVAL; 2063 return -EINVAL;
2064 } 2064 }
2065 2065
2066 /* Note how the 2nd and 3rd arguments are the same for both 2066 /* Note how the 2nd and 3rd arguments are the same for
2067 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why? 2067 * v4l2_i2c_new_subdev(). Why?
2068 * Well the 2nd argument is the module name to load, while the 3rd 2068 * Well the 2nd argument is the module name to load, while the 3rd
2069 * argument is documented in the framework as being the "chipid" - 2069 * argument is documented in the framework as being the "chipid" -
2070 * and every other place where I can find examples of this, the 2070 * and every other place where I can find examples of this, the
@@ -2077,15 +2077,15 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2077 mid, i2caddr[0]); 2077 mid, i2caddr[0]);
2078 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, 2078 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
2079 fname, fname, 2079 fname, fname,
2080 i2caddr[0]); 2080 i2caddr[0], NULL);
2081 } else { 2081 } else {
2082 pvr2_trace(PVR2_TRACE_INIT, 2082 pvr2_trace(PVR2_TRACE_INIT,
2083 "Module ID %u:" 2083 "Module ID %u:"
2084 " Setting up with address probe list", 2084 " Setting up with address probe list",
2085 mid); 2085 mid);
2086 sd = v4l2_i2c_new_probed_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, 2086 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
2087 fname, fname, 2087 fname, fname,
2088 i2caddr); 2088 0, i2caddr);
2089 } 2089 }
2090 2090
2091 if (!sd) { 2091 if (!sd) {
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 016bb45ba0c3..6952e9602d5d 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -225,6 +225,10 @@ struct pxa_camera_dev {
225 u32 save_cicr[5]; 225 u32 save_cicr[5];
226}; 226};
227 227
228struct pxa_cam {
229 unsigned long flags;
230};
231
228static const char *pxa_cam_driver_description = "PXA_Camera"; 232static const char *pxa_cam_driver_description = "PXA_Camera";
229 233
230static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 234static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
@@ -237,9 +241,9 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
237{ 241{
238 struct soc_camera_device *icd = vq->priv_data; 242 struct soc_camera_device *icd = vq->priv_data;
239 243
240 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 244 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
241 245
242 *size = roundup(icd->width * icd->height * 246 *size = roundup(icd->user_width * icd->user_height *
243 ((icd->current_fmt->depth + 7) >> 3), 8); 247 ((icd->current_fmt->depth + 7) >> 3), 8);
244 248
245 if (0 == *count) 249 if (0 == *count)
@@ -259,7 +263,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
259 263
260 BUG_ON(in_interrupt()); 264 BUG_ON(in_interrupt());
261 265
262 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 266 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
263 &buf->vb, buf->vb.baddr, buf->vb.bsize); 267 &buf->vb, buf->vb.baddr, buf->vb.bsize);
264 268
265 /* This waits until this buffer is out of danger, i.e., until it is no 269 /* This waits until this buffer is out of danger, i.e., until it is no
@@ -270,7 +274,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
270 274
271 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { 275 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
272 if (buf->dmas[i].sg_cpu) 276 if (buf->dmas[i].sg_cpu)
273 dma_free_coherent(ici->dev, buf->dmas[i].sg_size, 277 dma_free_coherent(ici->v4l2_dev.dev,
278 buf->dmas[i].sg_size,
274 buf->dmas[i].sg_cpu, 279 buf->dmas[i].sg_cpu,
275 buf->dmas[i].sg_dma); 280 buf->dmas[i].sg_dma);
276 buf->dmas[i].sg_cpu = NULL; 281 buf->dmas[i].sg_cpu = NULL;
@@ -325,19 +330,20 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
325 struct scatterlist **sg_first, int *sg_first_ofs) 330 struct scatterlist **sg_first, int *sg_first_ofs)
326{ 331{
327 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel]; 332 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
333 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
328 struct scatterlist *sg; 334 struct scatterlist *sg;
329 int i, offset, sglen; 335 int i, offset, sglen;
330 int dma_len = 0, xfer_len = 0; 336 int dma_len = 0, xfer_len = 0;
331 337
332 if (pxa_dma->sg_cpu) 338 if (pxa_dma->sg_cpu)
333 dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, 339 dma_free_coherent(dev, pxa_dma->sg_size,
334 pxa_dma->sg_cpu, pxa_dma->sg_dma); 340 pxa_dma->sg_cpu, pxa_dma->sg_dma);
335 341
336 sglen = calculate_dma_sglen(*sg_first, dma->sglen, 342 sglen = calculate_dma_sglen(*sg_first, dma->sglen,
337 *sg_first_ofs, size); 343 *sg_first_ofs, size);
338 344
339 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); 345 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
340 pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, 346 pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
341 &pxa_dma->sg_dma, GFP_KERNEL); 347 &pxa_dma->sg_dma, GFP_KERNEL);
342 if (!pxa_dma->sg_cpu) 348 if (!pxa_dma->sg_cpu)
343 return -ENOMEM; 349 return -ENOMEM;
@@ -345,7 +351,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
345 pxa_dma->sglen = sglen; 351 pxa_dma->sglen = sglen;
346 offset = *sg_first_ofs; 352 offset = *sg_first_ofs;
347 353
348 dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", 354 dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
349 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); 355 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
350 356
351 357
@@ -368,7 +374,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
368 pxa_dma->sg_cpu[i].ddadr = 374 pxa_dma->sg_cpu[i].ddadr =
369 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); 375 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
370 376
371 dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", 377 dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
372 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), 378 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
373 sg_dma_address(sg) + offset, xfer_len); 379 sg_dma_address(sg) + offset, xfer_len);
374 offset = 0; 380 offset = 0;
@@ -418,11 +424,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
418 struct soc_camera_device *icd = vq->priv_data; 424 struct soc_camera_device *icd = vq->priv_data;
419 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 425 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
420 struct pxa_camera_dev *pcdev = ici->priv; 426 struct pxa_camera_dev *pcdev = ici->priv;
427 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
421 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 428 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
422 int ret; 429 int ret;
423 int size_y, size_u = 0, size_v = 0; 430 int size_y, size_u = 0, size_v = 0;
424 431
425 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 432 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
426 vb, vb->baddr, vb->bsize); 433 vb, vb->baddr, vb->bsize);
427 434
428 /* Added list head initialization on alloc */ 435 /* Added list head initialization on alloc */
@@ -441,12 +448,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
441 buf->inwork = 1; 448 buf->inwork = 1;
442 449
443 if (buf->fmt != icd->current_fmt || 450 if (buf->fmt != icd->current_fmt ||
444 vb->width != icd->width || 451 vb->width != icd->user_width ||
445 vb->height != icd->height || 452 vb->height != icd->user_height ||
446 vb->field != field) { 453 vb->field != field) {
447 buf->fmt = icd->current_fmt; 454 buf->fmt = icd->current_fmt;
448 vb->width = icd->width; 455 vb->width = icd->user_width;
449 vb->height = icd->height; 456 vb->height = icd->user_height;
450 vb->field = field; 457 vb->field = field;
451 vb->state = VIDEOBUF_NEEDS_INIT; 458 vb->state = VIDEOBUF_NEEDS_INIT;
452 } 459 }
@@ -480,8 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
480 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, 487 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
481 &sg, &next_ofs); 488 &sg, &next_ofs);
482 if (ret) { 489 if (ret) {
483 dev_err(pcdev->soc_host.dev, 490 dev_err(dev, "DMA initialization for Y/RGB failed\n");
484 "DMA initialization for Y/RGB failed\n");
485 goto fail; 491 goto fail;
486 } 492 }
487 493
@@ -490,8 +496,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
490 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, 496 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
491 size_u, &sg, &next_ofs); 497 size_u, &sg, &next_ofs);
492 if (ret) { 498 if (ret) {
493 dev_err(pcdev->soc_host.dev, 499 dev_err(dev, "DMA initialization for U failed\n");
494 "DMA initialization for U failed\n");
495 goto fail_u; 500 goto fail_u;
496 } 501 }
497 502
@@ -500,8 +505,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
500 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, 505 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
501 size_v, &sg, &next_ofs); 506 size_v, &sg, &next_ofs);
502 if (ret) { 507 if (ret) {
503 dev_err(pcdev->soc_host.dev, 508 dev_err(dev, "DMA initialization for V failed\n");
504 "DMA initialization for V failed\n");
505 goto fail_v; 509 goto fail_v;
506 } 510 }
507 511
@@ -514,10 +518,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
514 return 0; 518 return 0;
515 519
516fail_v: 520fail_v:
517 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size, 521 dma_free_coherent(dev, buf->dmas[1].sg_size,
518 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); 522 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
519fail_u: 523fail_u:
520 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size, 524 dma_free_coherent(dev, buf->dmas[0].sg_size,
521 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); 525 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
522fail: 526fail:
523 free_buffer(vq, buf); 527 free_buffer(vq, buf);
@@ -541,7 +545,8 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
541 active = pcdev->active; 545 active = pcdev->active;
542 546
543 for (i = 0; i < pcdev->channels; i++) { 547 for (i = 0; i < pcdev->channels; i++) {
544 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__, 548 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
549 "%s (channel=%d) ddadr=%08x\n", __func__,
545 i, active->dmas[i].sg_dma); 550 i, active->dmas[i].sg_dma);
546 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; 551 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
547 DCSR(pcdev->dma_chans[i]) = DCSR_RUN; 552 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -553,7 +558,8 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
553 int i; 558 int i;
554 559
555 for (i = 0; i < pcdev->channels; i++) { 560 for (i = 0; i < pcdev->channels; i++) {
556 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i); 561 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
562 "%s (channel=%d)\n", __func__, i);
557 DCSR(pcdev->dma_chans[i]) = 0; 563 DCSR(pcdev->dma_chans[i]) = 0;
558 } 564 }
559} 565}
@@ -589,7 +595,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
589{ 595{
590 unsigned long cicr0, cifr; 596 unsigned long cicr0, cifr;
591 597
592 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); 598 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
593 /* Reset the FIFOs */ 599 /* Reset the FIFOs */
594 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; 600 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
595 __raw_writel(cifr, pcdev->base + CIFR); 601 __raw_writel(cifr, pcdev->base + CIFR);
@@ -609,7 +615,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
609 __raw_writel(cicr0, pcdev->base + CICR0); 615 __raw_writel(cicr0, pcdev->base + CICR0);
610 616
611 pcdev->active = NULL; 617 pcdev->active = NULL;
612 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); 618 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
613} 619}
614 620
615/* Called under spinlock_irqsave(&pcdev->lock, ...) */ 621/* Called under spinlock_irqsave(&pcdev->lock, ...) */
@@ -621,8 +627,8 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
621 struct pxa_camera_dev *pcdev = ici->priv; 627 struct pxa_camera_dev *pcdev = ici->priv;
622 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 628 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
623 629
624 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__, 630 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d active=%p\n",
625 vb, vb->baddr, vb->bsize, pcdev->active); 631 __func__, vb, vb->baddr, vb->bsize, pcdev->active);
626 632
627 list_add_tail(&vb->queue, &pcdev->capture); 633 list_add_tail(&vb->queue, &pcdev->capture);
628 634
@@ -639,22 +645,23 @@ static void pxa_videobuf_release(struct videobuf_queue *vq,
639 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 645 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
640#ifdef DEBUG 646#ifdef DEBUG
641 struct soc_camera_device *icd = vq->priv_data; 647 struct soc_camera_device *icd = vq->priv_data;
648 struct device *dev = icd->dev.parent;
642 649
643 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 650 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
644 vb, vb->baddr, vb->bsize); 651 vb, vb->baddr, vb->bsize);
645 652
646 switch (vb->state) { 653 switch (vb->state) {
647 case VIDEOBUF_ACTIVE: 654 case VIDEOBUF_ACTIVE:
648 dev_dbg(&icd->dev, "%s (active)\n", __func__); 655 dev_dbg(dev, "%s (active)\n", __func__);
649 break; 656 break;
650 case VIDEOBUF_QUEUED: 657 case VIDEOBUF_QUEUED:
651 dev_dbg(&icd->dev, "%s (queued)\n", __func__); 658 dev_dbg(dev, "%s (queued)\n", __func__);
652 break; 659 break;
653 case VIDEOBUF_PREPARED: 660 case VIDEOBUF_PREPARED:
654 dev_dbg(&icd->dev, "%s (prepared)\n", __func__); 661 dev_dbg(dev, "%s (prepared)\n", __func__);
655 break; 662 break;
656 default: 663 default:
657 dev_dbg(&icd->dev, "%s (unknown)\n", __func__); 664 dev_dbg(dev, "%s (unknown)\n", __func__);
658 break; 665 break;
659 } 666 }
660#endif 667#endif
@@ -674,7 +681,8 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
674 do_gettimeofday(&vb->ts); 681 do_gettimeofday(&vb->ts);
675 vb->field_count++; 682 vb->field_count++;
676 wake_up(&vb->done); 683 wake_up(&vb->done);
677 dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); 684 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s dequeud buffer (vb=0x%p)\n",
685 __func__, vb);
678 686
679 if (list_empty(&pcdev->capture)) { 687 if (list_empty(&pcdev->capture)) {
680 pxa_camera_stop_capture(pcdev); 688 pxa_camera_stop_capture(pcdev);
@@ -710,7 +718,8 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
710 for (i = 0; i < pcdev->channels; i++) 718 for (i = 0; i < pcdev->channels; i++)
711 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) 719 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
712 is_dma_stopped = 0; 720 is_dma_stopped = 0;
713 dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n", 721 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
722 "%s : top queued buffer=%p, dma_stopped=%d\n",
714 __func__, pcdev->active, is_dma_stopped); 723 __func__, pcdev->active, is_dma_stopped);
715 if (pcdev->active && is_dma_stopped) 724 if (pcdev->active && is_dma_stopped)
716 pxa_camera_start_capture(pcdev); 725 pxa_camera_start_capture(pcdev);
@@ -719,6 +728,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
719static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, 728static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
720 enum pxa_camera_active_dma act_dma) 729 enum pxa_camera_active_dma act_dma)
721{ 730{
731 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
722 struct pxa_buffer *buf; 732 struct pxa_buffer *buf;
723 unsigned long flags; 733 unsigned long flags;
724 u32 status, camera_status, overrun; 734 u32 status, camera_status, overrun;
@@ -735,13 +745,13 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
735 overrun |= CISR_IFO_1 | CISR_IFO_2; 745 overrun |= CISR_IFO_1 | CISR_IFO_2;
736 746
737 if (status & DCSR_BUSERR) { 747 if (status & DCSR_BUSERR) {
738 dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n"); 748 dev_err(dev, "DMA Bus Error IRQ!\n");
739 goto out; 749 goto out;
740 } 750 }
741 751
742 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { 752 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
743 dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, " 753 dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
744 "status: 0x%08x\n", status); 754 status);
745 goto out; 755 goto out;
746 } 756 }
747 757
@@ -764,7 +774,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
764 buf = container_of(vb, struct pxa_buffer, vb); 774 buf = container_of(vb, struct pxa_buffer, vb);
765 WARN_ON(buf->inwork || list_empty(&vb->queue)); 775 WARN_ON(buf->inwork || list_empty(&vb->queue));
766 776
767 dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", 777 dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
768 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", 778 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
769 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); 779 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
770 780
@@ -775,7 +785,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
775 */ 785 */
776 if (camera_status & overrun && 786 if (camera_status & overrun &&
777 !list_is_last(pcdev->capture.next, &pcdev->capture)) { 787 !list_is_last(pcdev->capture.next, &pcdev->capture)) {
778 dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n", 788 dev_dbg(dev, "FIFO overrun! CISR: %x\n",
779 camera_status); 789 camera_status);
780 pxa_camera_stop_capture(pcdev); 790 pxa_camera_stop_capture(pcdev);
781 pxa_camera_start_capture(pcdev); 791 pxa_camera_start_capture(pcdev);
@@ -830,9 +840,11 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
830 sizeof(struct pxa_buffer), icd); 840 sizeof(struct pxa_buffer), icd);
831} 841}
832 842
833static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) 843static u32 mclk_get_divisor(struct platform_device *pdev,
844 struct pxa_camera_dev *pcdev)
834{ 845{
835 unsigned long mclk = pcdev->mclk; 846 unsigned long mclk = pcdev->mclk;
847 struct device *dev = &pdev->dev;
836 u32 div; 848 u32 div;
837 unsigned long lcdclk; 849 unsigned long lcdclk;
838 850
@@ -842,7 +854,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
842 /* mclk <= ciclk / 4 (27.4.2) */ 854 /* mclk <= ciclk / 4 (27.4.2) */
843 if (mclk > lcdclk / 4) { 855 if (mclk > lcdclk / 4) {
844 mclk = lcdclk / 4; 856 mclk = lcdclk / 4;
845 dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk); 857 dev_warn(dev, "Limiting master clock to %lu\n", mclk);
846 } 858 }
847 859
848 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ 860 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -852,8 +864,8 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
852 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 864 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
853 pcdev->mclk = lcdclk / (2 * (div + 1)); 865 pcdev->mclk = lcdclk / (2 * (div + 1));
854 866
855 dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, " 867 dev_dbg(dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
856 "divisor %u\n", lcdclk, mclk, div); 868 lcdclk, mclk, div);
857 869
858 return div; 870 return div;
859} 871}
@@ -870,14 +882,15 @@ static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
870static void pxa_camera_activate(struct pxa_camera_dev *pcdev) 882static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
871{ 883{
872 struct pxacamera_platform_data *pdata = pcdev->pdata; 884 struct pxacamera_platform_data *pdata = pcdev->pdata;
885 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
873 u32 cicr4 = 0; 886 u32 cicr4 = 0;
874 887
875 dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n", 888 dev_dbg(dev, "Registered platform device at %p data %p\n",
876 pcdev, pdata); 889 pcdev, pdata);
877 890
878 if (pdata && pdata->init) { 891 if (pdata && pdata->init) {
879 dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__); 892 dev_dbg(dev, "%s: Init gpios\n", __func__);
880 pdata->init(pcdev->soc_host.dev); 893 pdata->init(dev);
881 } 894 }
882 895
883 /* disable all interrupts */ 896 /* disable all interrupts */
@@ -919,7 +932,8 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
919 struct videobuf_buffer *vb; 932 struct videobuf_buffer *vb;
920 933
921 status = __raw_readl(pcdev->base + CISR); 934 status = __raw_readl(pcdev->base + CISR);
922 dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status); 935 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
936 "Camera interrupt status 0x%lx\n", status);
923 937
924 if (!status) 938 if (!status)
925 return IRQ_NONE; 939 return IRQ_NONE;
@@ -951,24 +965,18 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
951{ 965{
952 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 966 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
953 struct pxa_camera_dev *pcdev = ici->priv; 967 struct pxa_camera_dev *pcdev = ici->priv;
954 int ret;
955 968
956 if (pcdev->icd) { 969 if (pcdev->icd)
957 ret = -EBUSY; 970 return -EBUSY;
958 goto ebusy;
959 }
960
961 dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
962 icd->devnum);
963 971
964 pxa_camera_activate(pcdev); 972 pxa_camera_activate(pcdev);
965 ret = icd->ops->init(icd);
966 973
967 if (!ret) 974 pcdev->icd = icd;
968 pcdev->icd = icd;
969 975
970ebusy: 976 dev_info(icd->dev.parent, "PXA Camera driver attached to camera %d\n",
971 return ret; 977 icd->devnum);
978
979 return 0;
972} 980}
973 981
974/* Called with .video_lock held */ 982/* Called with .video_lock held */
@@ -979,7 +987,7 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
979 987
980 BUG_ON(icd != pcdev->icd); 988 BUG_ON(icd != pcdev->icd);
981 989
982 dev_info(&icd->dev, "PXA Camera driver detached from camera %d\n", 990 dev_info(icd->dev.parent, "PXA Camera driver detached from camera %d\n",
983 icd->devnum); 991 icd->devnum);
984 992
985 /* disable capture, disable interrupts */ 993 /* disable capture, disable interrupts */
@@ -990,8 +998,6 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
990 DCSR(pcdev->dma_chans[1]) = 0; 998 DCSR(pcdev->dma_chans[1]) = 0;
991 DCSR(pcdev->dma_chans[2]) = 0; 999 DCSR(pcdev->dma_chans[2]) = 0;
992 1000
993 icd->ops->release(icd);
994
995 pxa_camera_deactivate(pcdev); 1001 pxa_camera_deactivate(pcdev);
996 1002
997 pcdev->icd = NULL; 1003 pcdev->icd = NULL;
@@ -1039,57 +1045,17 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
1039 return 0; 1045 return 0;
1040} 1046}
1041 1047
1042static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1048static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1049 unsigned long flags, __u32 pixfmt)
1043{ 1050{
1044 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1051 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1045 struct pxa_camera_dev *pcdev = ici->priv; 1052 struct pxa_camera_dev *pcdev = ici->priv;
1046 unsigned long dw, bpp, bus_flags, camera_flags, common_flags; 1053 unsigned long dw, bpp;
1047 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0; 1054 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
1048 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
1049
1050 if (ret < 0)
1051 return ret;
1052
1053 camera_flags = icd->ops->query_bus_param(icd);
1054
1055 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1056 if (!common_flags)
1057 return -EINVAL;
1058
1059 pcdev->channels = 1;
1060
1061 /* Make choises, based on platform preferences */
1062 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
1063 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
1064 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1065 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
1066 else
1067 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
1068 }
1069
1070 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
1071 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
1072 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1073 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
1074 else
1075 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
1076 }
1077
1078 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
1079 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
1080 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1081 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
1082 else
1083 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
1084 }
1085
1086 ret = icd->ops->set_bus_param(icd, common_flags);
1087 if (ret < 0)
1088 return ret;
1089 1055
1090 /* Datawidth is now guaranteed to be equal to one of the three values. 1056 /* Datawidth is now guaranteed to be equal to one of the three values.
1091 * We fix bit-per-pixel equal to data-width... */ 1057 * We fix bit-per-pixel equal to data-width... */
1092 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 1058 switch (flags & SOCAM_DATAWIDTH_MASK) {
1093 case SOCAM_DATAWIDTH_10: 1059 case SOCAM_DATAWIDTH_10:
1094 dw = 4; 1060 dw = 4;
1095 bpp = 0x40; 1061 bpp = 0x40;
@@ -1110,18 +1076,18 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1110 cicr4 |= CICR4_PCLK_EN; 1076 cicr4 |= CICR4_PCLK_EN;
1111 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 1077 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1112 cicr4 |= CICR4_MCLK_EN; 1078 cicr4 |= CICR4_MCLK_EN;
1113 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 1079 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
1114 cicr4 |= CICR4_PCP; 1080 cicr4 |= CICR4_PCP;
1115 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 1081 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
1116 cicr4 |= CICR4_HSP; 1082 cicr4 |= CICR4_HSP;
1117 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 1083 if (flags & SOCAM_VSYNC_ACTIVE_LOW)
1118 cicr4 |= CICR4_VSP; 1084 cicr4 |= CICR4_VSP;
1119 1085
1120 cicr0 = __raw_readl(pcdev->base + CICR0); 1086 cicr0 = __raw_readl(pcdev->base + CICR0);
1121 if (cicr0 & CICR0_ENB) 1087 if (cicr0 & CICR0_ENB)
1122 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0); 1088 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
1123 1089
1124 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; 1090 cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw;
1125 1091
1126 switch (pixfmt) { 1092 switch (pixfmt) {
1127 case V4L2_PIX_FMT_YUV422P: 1093 case V4L2_PIX_FMT_YUV422P:
@@ -1150,7 +1116,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1150 } 1116 }
1151 1117
1152 cicr2 = 0; 1118 cicr2 = 0;
1153 cicr3 = CICR3_LPF_VAL(icd->height - 1) | 1119 cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
1154 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 1120 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
1155 cicr4 |= pcdev->mclk_divisor; 1121 cicr4 |= pcdev->mclk_divisor;
1156 1122
@@ -1164,6 +1130,59 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1164 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP)); 1130 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
1165 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK; 1131 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
1166 __raw_writel(cicr0, pcdev->base + CICR0); 1132 __raw_writel(cicr0, pcdev->base + CICR0);
1133}
1134
1135static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1136{
1137 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1138 struct pxa_camera_dev *pcdev = ici->priv;
1139 unsigned long bus_flags, camera_flags, common_flags;
1140 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
1141 struct pxa_cam *cam = icd->host_priv;
1142
1143 if (ret < 0)
1144 return ret;
1145
1146 camera_flags = icd->ops->query_bus_param(icd);
1147
1148 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1149 if (!common_flags)
1150 return -EINVAL;
1151
1152 pcdev->channels = 1;
1153
1154 /* Make choises, based on platform preferences */
1155 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
1156 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
1157 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1158 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
1159 else
1160 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
1161 }
1162
1163 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
1164 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
1165 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1166 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
1167 else
1168 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
1169 }
1170
1171 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
1172 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
1173 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1174 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
1175 else
1176 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
1177 }
1178
1179 cam->flags = common_flags;
1180
1181 ret = icd->ops->set_bus_param(icd, common_flags);
1182 if (ret < 0)
1183 return ret;
1184
1185 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1167 1186
1168 return 0; 1187 return 0;
1169} 1188}
@@ -1227,8 +1246,9 @@ static int required_buswidth(const struct soc_camera_data_format *fmt)
1227static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, 1246static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1228 struct soc_camera_format_xlate *xlate) 1247 struct soc_camera_format_xlate *xlate)
1229{ 1248{
1230 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1249 struct device *dev = icd->dev.parent;
1231 int formats = 0, buswidth, ret; 1250 int formats = 0, buswidth, ret;
1251 struct pxa_cam *cam;
1232 1252
1233 buswidth = required_buswidth(icd->formats + idx); 1253 buswidth = required_buswidth(icd->formats + idx);
1234 1254
@@ -1239,6 +1259,16 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1239 if (ret < 0) 1259 if (ret < 0)
1240 return 0; 1260 return 0;
1241 1261
1262 if (!icd->host_priv) {
1263 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1264 if (!cam)
1265 return -ENOMEM;
1266
1267 icd->host_priv = cam;
1268 } else {
1269 cam = icd->host_priv;
1270 }
1271
1242 switch (icd->formats[idx].fourcc) { 1272 switch (icd->formats[idx].fourcc) {
1243 case V4L2_PIX_FMT_UYVY: 1273 case V4L2_PIX_FMT_UYVY:
1244 formats++; 1274 formats++;
@@ -1247,7 +1277,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1247 xlate->cam_fmt = icd->formats + idx; 1277 xlate->cam_fmt = icd->formats + idx;
1248 xlate->buswidth = buswidth; 1278 xlate->buswidth = buswidth;
1249 xlate++; 1279 xlate++;
1250 dev_dbg(ici->dev, "Providing format %s using %s\n", 1280 dev_dbg(dev, "Providing format %s using %s\n",
1251 pxa_camera_formats[0].name, 1281 pxa_camera_formats[0].name,
1252 icd->formats[idx].name); 1282 icd->formats[idx].name);
1253 } 1283 }
@@ -1262,7 +1292,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1262 xlate->cam_fmt = icd->formats + idx; 1292 xlate->cam_fmt = icd->formats + idx;
1263 xlate->buswidth = buswidth; 1293 xlate->buswidth = buswidth;
1264 xlate++; 1294 xlate++;
1265 dev_dbg(ici->dev, "Providing format %s packed\n", 1295 dev_dbg(dev, "Providing format %s packed\n",
1266 icd->formats[idx].name); 1296 icd->formats[idx].name);
1267 } 1297 }
1268 break; 1298 break;
@@ -1274,7 +1304,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1274 xlate->cam_fmt = icd->formats + idx; 1304 xlate->cam_fmt = icd->formats + idx;
1275 xlate->buswidth = icd->formats[idx].depth; 1305 xlate->buswidth = icd->formats[idx].depth;
1276 xlate++; 1306 xlate++;
1277 dev_dbg(ici->dev, 1307 dev_dbg(dev,
1278 "Providing format %s in pass-through mode\n", 1308 "Providing format %s in pass-through mode\n",
1279 icd->formats[idx].name); 1309 icd->formats[idx].name);
1280 } 1310 }
@@ -1283,31 +1313,80 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1283 return formats; 1313 return formats;
1284} 1314}
1285 1315
1316static void pxa_camera_put_formats(struct soc_camera_device *icd)
1317{
1318 kfree(icd->host_priv);
1319 icd->host_priv = NULL;
1320}
1321
1322static int pxa_camera_check_frame(struct v4l2_pix_format *pix)
1323{
1324 /* limit to pxa hardware capabilities */
1325 return pix->height < 32 || pix->height > 2048 || pix->width < 48 ||
1326 pix->width > 2048 || (pix->width & 0x01);
1327}
1328
1286static int pxa_camera_set_crop(struct soc_camera_device *icd, 1329static int pxa_camera_set_crop(struct soc_camera_device *icd,
1287 struct v4l2_rect *rect) 1330 struct v4l2_crop *a)
1288{ 1331{
1332 struct v4l2_rect *rect = &a->c;
1289 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1333 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1290 struct pxa_camera_dev *pcdev = ici->priv; 1334 struct pxa_camera_dev *pcdev = ici->priv;
1335 struct device *dev = icd->dev.parent;
1336 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1291 struct soc_camera_sense sense = { 1337 struct soc_camera_sense sense = {
1292 .master_clock = pcdev->mclk, 1338 .master_clock = pcdev->mclk,
1293 .pixel_clock_max = pcdev->ciclk / 4, 1339 .pixel_clock_max = pcdev->ciclk / 4,
1294 }; 1340 };
1341 struct v4l2_format f;
1342 struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
1343 struct pxa_cam *cam = icd->host_priv;
1295 int ret; 1344 int ret;
1296 1345
1297 /* If PCLK is used to latch data from the sensor, check sense */ 1346 /* If PCLK is used to latch data from the sensor, check sense */
1298 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1347 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1299 icd->sense = &sense; 1348 icd->sense = &sense;
1300 1349
1301 ret = icd->ops->set_crop(icd, rect); 1350 ret = v4l2_subdev_call(sd, video, s_crop, a);
1302 1351
1303 icd->sense = NULL; 1352 icd->sense = NULL;
1304 1353
1305 if (ret < 0) { 1354 if (ret < 0) {
1306 dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n", 1355 dev_warn(dev, "Failed to crop to %ux%u@%u:%u\n",
1307 rect->width, rect->height, rect->left, rect->top); 1356 rect->width, rect->height, rect->left, rect->top);
1308 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1357 return ret;
1358 }
1359
1360 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1361
1362 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1363 if (ret < 0)
1364 return ret;
1365
1366 pix_tmp = *pix;
1367 if (pxa_camera_check_frame(pix)) {
1368 /*
1369 * Camera cropping produced a frame beyond our capabilities.
1370 * FIXME: just extract a subframe, that we can process.
1371 */
1372 v4l_bound_align_image(&pix->width, 48, 2048, 1,
1373 &pix->height, 32, 2048, 0,
1374 icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?
1375 4 : 0);
1376 ret = v4l2_subdev_call(sd, video, s_fmt, &f);
1377 if (ret < 0)
1378 return ret;
1379
1380 if (pxa_camera_check_frame(pix)) {
1381 dev_warn(icd->dev.parent,
1382 "Inconsistent state. Use S_FMT to repair\n");
1383 return -EINVAL;
1384 }
1385 }
1386
1387 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1309 if (sense.pixel_clock > sense.pixel_clock_max) { 1388 if (sense.pixel_clock > sense.pixel_clock_max) {
1310 dev_err(ici->dev, 1389 dev_err(dev,
1311 "pixel clock %lu set by the camera too high!", 1390 "pixel clock %lu set by the camera too high!",
1312 sense.pixel_clock); 1391 sense.pixel_clock);
1313 return -EIO; 1392 return -EIO;
@@ -1315,6 +1394,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1315 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1394 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1316 } 1395 }
1317 1396
1397 icd->user_width = pix->width;
1398 icd->user_height = pix->height;
1399
1400 pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc);
1401
1318 return ret; 1402 return ret;
1319} 1403}
1320 1404
@@ -1323,6 +1407,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1323{ 1407{
1324 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1408 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1325 struct pxa_camera_dev *pcdev = ici->priv; 1409 struct pxa_camera_dev *pcdev = ici->priv;
1410 struct device *dev = icd->dev.parent;
1411 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1326 const struct soc_camera_data_format *cam_fmt = NULL; 1412 const struct soc_camera_data_format *cam_fmt = NULL;
1327 const struct soc_camera_format_xlate *xlate = NULL; 1413 const struct soc_camera_format_xlate *xlate = NULL;
1328 struct soc_camera_sense sense = { 1414 struct soc_camera_sense sense = {
@@ -1335,7 +1421,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1335 1421
1336 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1422 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1337 if (!xlate) { 1423 if (!xlate) {
1338 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 1424 dev_warn(dev, "Format %x not found\n", pix->pixelformat);
1339 return -EINVAL; 1425 return -EINVAL;
1340 } 1426 }
1341 1427
@@ -1346,16 +1432,21 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1346 icd->sense = &sense; 1432 icd->sense = &sense;
1347 1433
1348 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; 1434 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
1349 ret = icd->ops->set_fmt(icd, &cam_f); 1435 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1350 1436
1351 icd->sense = NULL; 1437 icd->sense = NULL;
1352 1438
1353 if (ret < 0) { 1439 if (ret < 0) {
1354 dev_warn(ici->dev, "Failed to configure for format %x\n", 1440 dev_warn(dev, "Failed to configure for format %x\n",
1355 pix->pixelformat); 1441 pix->pixelformat);
1442 } else if (pxa_camera_check_frame(pix)) {
1443 dev_warn(dev,
1444 "Camera driver produced an unsupported frame %dx%d\n",
1445 pix->width, pix->height);
1446 ret = -EINVAL;
1356 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1447 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1357 if (sense.pixel_clock > sense.pixel_clock_max) { 1448 if (sense.pixel_clock > sense.pixel_clock_max) {
1358 dev_err(ici->dev, 1449 dev_err(dev,
1359 "pixel clock %lu set by the camera too high!", 1450 "pixel clock %lu set by the camera too high!",
1360 sense.pixel_clock); 1451 sense.pixel_clock);
1361 return -EIO; 1452 return -EIO;
@@ -1375,6 +1466,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1375 struct v4l2_format *f) 1466 struct v4l2_format *f)
1376{ 1467{
1377 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1468 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1469 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1378 const struct soc_camera_format_xlate *xlate; 1470 const struct soc_camera_format_xlate *xlate;
1379 struct v4l2_pix_format *pix = &f->fmt.pix; 1471 struct v4l2_pix_format *pix = &f->fmt.pix;
1380 __u32 pixfmt = pix->pixelformat; 1472 __u32 pixfmt = pix->pixelformat;
@@ -1383,7 +1475,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1383 1475
1384 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1476 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1385 if (!xlate) { 1477 if (!xlate) {
1386 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1478 dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
1387 return -EINVAL; 1479 return -EINVAL;
1388 } 1480 }
1389 1481
@@ -1395,7 +1487,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1395 */ 1487 */
1396 v4l_bound_align_image(&pix->width, 48, 2048, 1, 1488 v4l_bound_align_image(&pix->width, 48, 2048, 1,
1397 &pix->height, 32, 2048, 0, 1489 &pix->height, 32, 2048, 0,
1398 xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); 1490 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1399 1491
1400 pix->bytesperline = pix->width * 1492 pix->bytesperline = pix->width *
1401 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1493 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
@@ -1404,15 +1496,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1404 /* camera has to see its format, but the user the original one */ 1496 /* camera has to see its format, but the user the original one */
1405 pix->pixelformat = xlate->cam_fmt->fourcc; 1497 pix->pixelformat = xlate->cam_fmt->fourcc;
1406 /* limit to sensor capabilities */ 1498 /* limit to sensor capabilities */
1407 ret = icd->ops->try_fmt(icd, f); 1499 ret = v4l2_subdev_call(sd, video, try_fmt, f);
1408 pix->pixelformat = xlate->host_fmt->fourcc; 1500 pix->pixelformat = pixfmt;
1409 1501
1410 field = pix->field; 1502 field = pix->field;
1411 1503
1412 if (field == V4L2_FIELD_ANY) { 1504 if (field == V4L2_FIELD_ANY) {
1413 pix->field = V4L2_FIELD_NONE; 1505 pix->field = V4L2_FIELD_NONE;
1414 } else if (field != V4L2_FIELD_NONE) { 1506 } else if (field != V4L2_FIELD_NONE) {
1415 dev_err(&icd->dev, "Field type %d unsupported.\n", field); 1507 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
1416 return -EINVAL; 1508 return -EINVAL;
1417 } 1509 }
1418 1510
@@ -1518,6 +1610,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1518 .resume = pxa_camera_resume, 1610 .resume = pxa_camera_resume,
1519 .set_crop = pxa_camera_set_crop, 1611 .set_crop = pxa_camera_set_crop,
1520 .get_formats = pxa_camera_get_formats, 1612 .get_formats = pxa_camera_get_formats,
1613 .put_formats = pxa_camera_put_formats,
1521 .set_fmt = pxa_camera_set_fmt, 1614 .set_fmt = pxa_camera_set_fmt,
1522 .try_fmt = pxa_camera_try_fmt, 1615 .try_fmt = pxa_camera_try_fmt,
1523 .init_videobuf = pxa_camera_init_videobuf, 1616 .init_videobuf = pxa_camera_init_videobuf,
@@ -1575,8 +1668,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1575 pcdev->mclk = 20000000; 1668 pcdev->mclk = 20000000;
1576 } 1669 }
1577 1670
1578 pcdev->soc_host.dev = &pdev->dev; 1671 pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
1579 pcdev->mclk_divisor = mclk_get_divisor(pcdev);
1580 1672
1581 INIT_LIST_HEAD(&pcdev->capture); 1673 INIT_LIST_HEAD(&pcdev->capture);
1582 spin_lock_init(&pcdev->lock); 1674 spin_lock_init(&pcdev->lock);
@@ -1641,6 +1733,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1641 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; 1733 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
1642 pcdev->soc_host.ops = &pxa_soc_camera_host_ops; 1734 pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
1643 pcdev->soc_host.priv = pcdev; 1735 pcdev->soc_host.priv = pcdev;
1736 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1644 pcdev->soc_host.nr = pdev->id; 1737 pcdev->soc_host.nr = pdev->id;
1645 1738
1646 err = soc_camera_host_register(&pcdev->soc_host); 1739 err = soc_camera_host_register(&pcdev->soc_host);
@@ -1722,3 +1815,4 @@ module_exit(pxa_camera_exit);
1722MODULE_DESCRIPTION("PXA27x SoC Camera Host driver"); 1815MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
1723MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 1816MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
1724MODULE_LICENSE("GPL"); 1817MODULE_LICENSE("GPL");
1818MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 1b29487fd254..71145bff94fa 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4164,7 +4164,7 @@ struct saa7134_board saa7134_boards[] = {
4164 /*Dmitry Belimov <d.belimov@gmail.com> */ 4164 /*Dmitry Belimov <d.belimov@gmail.com> */
4165 .name = "Beholder BeholdTV 505 RDS", 4165 .name = "Beholder BeholdTV 505 RDS",
4166 .audio_clock = 0x00200000, 4166 .audio_clock = 0x00200000,
4167 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4167 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4168 .radio_type = UNSET, 4168 .radio_type = UNSET,
4169 .tuner_addr = ADDR_UNSET, 4169 .tuner_addr = ADDR_UNSET,
4170 .radio_addr = ADDR_UNSET, 4170 .radio_addr = ADDR_UNSET,
@@ -4229,7 +4229,7 @@ struct saa7134_board saa7134_boards[] = {
4229 /*Dmitry Belimov <d.belimov@gmail.com> */ 4229 /*Dmitry Belimov <d.belimov@gmail.com> */
4230 .name = "Beholder BeholdTV 507 RDS", 4230 .name = "Beholder BeholdTV 507 RDS",
4231 .audio_clock = 0x00187de7, 4231 .audio_clock = 0x00187de7,
4232 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4232 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4233 .radio_type = UNSET, 4233 .radio_type = UNSET,
4234 .tuner_addr = ADDR_UNSET, 4234 .tuner_addr = ADDR_UNSET,
4235 .radio_addr = ADDR_UNSET, 4235 .radio_addr = ADDR_UNSET,
@@ -4380,7 +4380,7 @@ struct saa7134_board saa7134_boards[] = {
4380 /* Andrey Melnikoff <temnota@kmv.ru> */ 4380 /* Andrey Melnikoff <temnota@kmv.ru> */
4381 .name = "Beholder BeholdTV 607 FM", 4381 .name = "Beholder BeholdTV 607 FM",
4382 .audio_clock = 0x00187de7, 4382 .audio_clock = 0x00187de7,
4383 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4383 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4384 .radio_type = UNSET, 4384 .radio_type = UNSET,
4385 .tuner_addr = ADDR_UNSET, 4385 .tuner_addr = ADDR_UNSET,
4386 .radio_addr = ADDR_UNSET, 4386 .radio_addr = ADDR_UNSET,
@@ -4408,7 +4408,7 @@ struct saa7134_board saa7134_boards[] = {
4408 /* Andrey Melnikoff <temnota@kmv.ru> */ 4408 /* Andrey Melnikoff <temnota@kmv.ru> */
4409 .name = "Beholder BeholdTV 609 FM", 4409 .name = "Beholder BeholdTV 609 FM",
4410 .audio_clock = 0x00187de7, 4410 .audio_clock = 0x00187de7,
4411 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4411 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4412 .radio_type = UNSET, 4412 .radio_type = UNSET,
4413 .tuner_addr = ADDR_UNSET, 4413 .tuner_addr = ADDR_UNSET,
4414 .radio_addr = ADDR_UNSET, 4414 .radio_addr = ADDR_UNSET,
@@ -4494,7 +4494,7 @@ struct saa7134_board saa7134_boards[] = {
4494 /* Andrey Melnikoff <temnota@kmv.ru> */ 4494 /* Andrey Melnikoff <temnota@kmv.ru> */
4495 .name = "Beholder BeholdTV 607 RDS", 4495 .name = "Beholder BeholdTV 607 RDS",
4496 .audio_clock = 0x00187de7, 4496 .audio_clock = 0x00187de7,
4497 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4497 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4498 .radio_type = UNSET, 4498 .radio_type = UNSET,
4499 .tuner_addr = ADDR_UNSET, 4499 .tuner_addr = ADDR_UNSET,
4500 .radio_addr = ADDR_UNSET, 4500 .radio_addr = ADDR_UNSET,
@@ -4523,7 +4523,7 @@ struct saa7134_board saa7134_boards[] = {
4523 /* Andrey Melnikoff <temnota@kmv.ru> */ 4523 /* Andrey Melnikoff <temnota@kmv.ru> */
4524 .name = "Beholder BeholdTV 609 RDS", 4524 .name = "Beholder BeholdTV 609 RDS",
4525 .audio_clock = 0x00187de7, 4525 .audio_clock = 0x00187de7,
4526 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4526 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4527 .radio_type = UNSET, 4527 .radio_type = UNSET,
4528 .tuner_addr = ADDR_UNSET, 4528 .tuner_addr = ADDR_UNSET,
4529 .radio_addr = ADDR_UNSET, 4529 .radio_addr = ADDR_UNSET,
@@ -4630,7 +4630,7 @@ struct saa7134_board saa7134_boards[] = {
4630 /* Alexey Osipov <lion-simba@pridelands.ru> */ 4630 /* Alexey Osipov <lion-simba@pridelands.ru> */
4631 .name = "Beholder BeholdTV M6 Extra", 4631 .name = "Beholder BeholdTV M6 Extra",
4632 .audio_clock = 0x00187de7, 4632 .audio_clock = 0x00187de7,
4633 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4633 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4634 .radio_type = UNSET, 4634 .radio_type = UNSET,
4635 .tuner_addr = ADDR_UNSET, 4635 .tuner_addr = ADDR_UNSET,
4636 .radio_addr = ADDR_UNSET, 4636 .radio_addr = ADDR_UNSET,
@@ -5257,6 +5257,27 @@ struct saa7134_board saa7134_boards[] = {
5257 .amux = TV, 5257 .amux = TV,
5258 }, 5258 },
5259 }, 5259 },
5260 [SAA7134_BOARD_ZOLID_HYBRID_PCI] = {
5261 .name = "Zolid Hybrid TV Tuner PCI",
5262 .audio_clock = 0x00187de7,
5263 .tuner_type = TUNER_PHILIPS_TDA8290,
5264 .radio_type = UNSET,
5265 .tuner_addr = ADDR_UNSET,
5266 .radio_addr = ADDR_UNSET,
5267 .tuner_config = 0,
5268 .mpeg = SAA7134_MPEG_DVB,
5269 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5270 .inputs = {{
5271 .name = name_tv,
5272 .vmux = 1,
5273 .amux = TV,
5274 .tv = 1,
5275 } },
5276 .radio = { /* untested */
5277 .name = name_radio,
5278 .amux = TV,
5279 },
5280 },
5260 5281
5261}; 5282};
5262 5283
@@ -6390,6 +6411,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6390 .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */ 6411 .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
6391 .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM, 6412 .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
6392 }, { 6413 }, {
6414 .vendor = PCI_VENDOR_ID_PHILIPS,
6415 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6416 .subvendor = PCI_VENDOR_ID_PHILIPS,
6417 .subdevice = 0x2004,
6418 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
6419 }, {
6393 /* --- boards without eeprom + subsystem ID --- */ 6420 /* --- boards without eeprom + subsystem ID --- */
6394 .vendor = PCI_VENDOR_ID_PHILIPS, 6421 .vendor = PCI_VENDOR_ID_PHILIPS,
6395 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6422 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -7208,22 +7235,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7208 if (dev->radio_type != UNSET) 7235 if (dev->radio_type != UNSET)
7209 v4l2_i2c_new_subdev(&dev->v4l2_dev, 7236 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7210 &dev->i2c_adap, "tuner", "tuner", 7237 &dev->i2c_adap, "tuner", "tuner",
7211 dev->radio_addr); 7238 dev->radio_addr, NULL);
7212 if (has_demod) 7239 if (has_demod)
7213 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 7240 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7214 &dev->i2c_adap, "tuner", "tuner", 7241 &dev->i2c_adap, "tuner", "tuner",
7215 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 7242 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
7216 if (dev->tuner_addr == ADDR_UNSET) { 7243 if (dev->tuner_addr == ADDR_UNSET) {
7217 enum v4l2_i2c_tuner_type type = 7244 enum v4l2_i2c_tuner_type type =
7218 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 7245 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
7219 7246
7220 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 7247 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7221 &dev->i2c_adap, "tuner", "tuner", 7248 &dev->i2c_adap, "tuner", "tuner",
7222 v4l2_i2c_tuner_addrs(type)); 7249 0, v4l2_i2c_tuner_addrs(type));
7223 } else { 7250 } else {
7224 v4l2_i2c_new_subdev(&dev->v4l2_dev, 7251 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7225 &dev->i2c_adap, "tuner", "tuner", 7252 &dev->i2c_adap, "tuner", "tuner",
7226 dev->tuner_addr); 7253 dev->tuner_addr, NULL);
7227 } 7254 }
7228 } 7255 }
7229 7256
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index cb78c956d810..f87757fccc72 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1000,7 +1000,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1000 struct v4l2_subdev *sd = 1000 struct v4l2_subdev *sd =
1001 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 1001 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
1002 "saa6752hs", "saa6752hs", 1002 "saa6752hs", "saa6752hs",
1003 saa7134_boards[dev->board].empress_addr); 1003 saa7134_boards[dev->board].empress_addr, NULL);
1004 1004
1005 if (sd) 1005 if (sd)
1006 sd->grp_id = GRP_EMPRESS; 1006 sd->grp_id = GRP_EMPRESS;
@@ -1009,9 +1009,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1009 if (saa7134_boards[dev->board].rds_addr) { 1009 if (saa7134_boards[dev->board].rds_addr) {
1010 struct v4l2_subdev *sd; 1010 struct v4l2_subdev *sd;
1011 1011
1012 sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev, 1012 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1013 &dev->i2c_adap, "saa6588", "saa6588", 1013 &dev->i2c_adap, "saa6588", "saa6588",
1014 saa7134_boards[dev->board].rds_addr); 1014 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
1015 if (sd) { 1015 if (sd) {
1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name); 1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
1017 dev->has_rds = 1; 1017 dev->has_rds = 1;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index ebde21dba7e3..a26e997a9ce6 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1007,12 +1007,29 @@ static struct tda18271_config hcw_tda18271_config = {
1007 .std_map = &hauppauge_tda18271_std_map, 1007 .std_map = &hauppauge_tda18271_std_map,
1008 .gate = TDA18271_GATE_ANALOG, 1008 .gate = TDA18271_GATE_ANALOG,
1009 .config = 3, 1009 .config = 3,
1010 .output_opt = TDA18271_OUTPUT_LT_OFF,
1010}; 1011};
1011 1012
1012static struct tda829x_config tda829x_no_probe = { 1013static struct tda829x_config tda829x_no_probe = {
1013 .probe_tuner = TDA829X_DONT_PROBE, 1014 .probe_tuner = TDA829X_DONT_PROBE,
1014}; 1015};
1015 1016
1017static struct tda10048_config zolid_tda10048_config = {
1018 .demod_address = 0x10 >> 1,
1019 .output_mode = TDA10048_PARALLEL_OUTPUT,
1020 .fwbulkwritelen = TDA10048_BULKWRITE_200,
1021 .inversion = TDA10048_INVERSION_ON,
1022 .dtv6_if_freq_khz = TDA10048_IF_3300,
1023 .dtv7_if_freq_khz = TDA10048_IF_3500,
1024 .dtv8_if_freq_khz = TDA10048_IF_4000,
1025 .clk_freq_khz = TDA10048_CLK_16000,
1026 .disable_gate_access = 1,
1027};
1028
1029static struct tda18271_config zolid_tda18271_config = {
1030 .gate = TDA18271_GATE_ANALOG,
1031};
1032
1016/* ================================================================== 1033/* ==================================================================
1017 * Core code 1034 * Core code
1018 */ 1035 */
@@ -1488,6 +1505,19 @@ static int dvb_init(struct saa7134_dev *dev)
1488 __func__); 1505 __func__);
1489 1506
1490 break; 1507 break;
1508 case SAA7134_BOARD_ZOLID_HYBRID_PCI:
1509 fe0->dvb.frontend = dvb_attach(tda10048_attach,
1510 &zolid_tda10048_config,
1511 &dev->i2c_adap);
1512 if (fe0->dvb.frontend != NULL) {
1513 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1514 &dev->i2c_adap, 0x4b,
1515 &tda829x_no_probe);
1516 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1517 0x60, &dev->i2c_adap,
1518 &zolid_tda18271_config);
1519 }
1520 break;
1491 default: 1521 default:
1492 wprintk("Huh? unknown DVB card?\n"); 1522 wprintk("Huh? unknown DVB card?\n");
1493 break; 1523 break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index e1e83c7b966e..a0e8c62e6ae1 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -251,6 +251,10 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
251 if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir) 251 if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir)
252 return 0; 252 return 0;
253 253
254 /* Wrong data decode fix */
255 if (data[9] != (unsigned char)(~data[8]))
256 return 0;
257
254 *ir_key = data[9]; 258 *ir_key = data[9];
255 *ir_raw = data[9]; 259 *ir_raw = data[9];
256 260
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index d18bb9643856..6ee3e9b7769e 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -296,6 +296,7 @@ struct saa7134_format {
296#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170 296#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170
297#define SAA7134_BOARD_BEHOLD_X7 171 297#define SAA7134_BOARD_BEHOLD_X7 171
298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
299 300
300#define SAA7134_MAXBOARDS 32 301#define SAA7134_MAXBOARDS 32
301#define SAA7134_INPUT_MAX 8 302#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig
new file mode 100644
index 000000000000..353263725172
--- /dev/null
+++ b/drivers/media/video/saa7164/Kconfig
@@ -0,0 +1,18 @@
1config VIDEO_SAA7164
2 tristate "NXP SAA7164 support"
3 depends on DVB_CORE && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_TUNER
7 select VIDEO_TVEEPROM
8 select VIDEOBUF_DVB
9 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
10 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
12 ---help---
13 This is a video4linux driver for NXP SAA7164 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called saa7164
18
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
new file mode 100644
index 000000000000..4b329fd42add
--- /dev/null
+++ b/drivers/media/video/saa7164/Makefile
@@ -0,0 +1,12 @@
1saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
2 saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
3 saa7164-buffer.o
4
5obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
6
7EXTRA_CFLAGS += -Idrivers/media/video
8EXTRA_CFLAGS += -Idrivers/media/common/tuners
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11
12EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
new file mode 100644
index 000000000000..bb6df1b276be
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -0,0 +1,600 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/wait.h>
23
24#include "saa7164.h"
25
26int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
27{
28 int ret;
29
30 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
31 SAA_STATE_CONTROL, sizeof(mode), &mode);
32 if (ret != SAA_OK)
33 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
34
35 return ret;
36}
37
38int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
39{
40 int ret;
41
42 ret = saa7164_cmd_send(dev, 0, GET_CUR,
43 GET_FW_VERSION_CONTROL, sizeof(u32), version);
44 if (ret != SAA_OK)
45 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
46
47 return ret;
48}
49
50int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
51{
52 u8 reg[] = { 0x0f, 0x00 };
53
54 if (buflen < 128)
55 return -ENOMEM;
56
57 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
58 /* TODO: Pull the details from the boards struct */
59 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
60 &reg[0], 128, buf);
61}
62
63
64int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
65 struct saa7164_tsport *port,
66 tmComResTSFormatDescrHeader_t *tsfmt)
67{
68 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
69 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
70 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
71 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
72 dprintk(DBGLVL_API, " bguid = (....)\n");
73
74 /* Cache the hardware configuration in the port */
75
76 port->bufcounter = port->hwcfg.BARLocation;
77 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
78 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
79 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
80 port->bufptr32l = port->hwcfg.BARLocation +
81 (4 * sizeof(u32)) +
82 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
83 port->bufptr32h = port->hwcfg.BARLocation +
84 (4 * sizeof(u32)) +
85 (sizeof(u32) * port->hwcfg.buffercount);
86 port->bufptr64 = port->hwcfg.BARLocation +
87 (4 * sizeof(u32)) +
88 (sizeof(u32) * port->hwcfg.buffercount);
89 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
90 port->hwcfg.BARLocation);
91
92 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
93 port->nr);
94
95 return 0;
96}
97
98int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
99{
100 struct saa7164_tsport *port = 0;
101 u32 idx, next_offset;
102 int i;
103 tmComResDescrHeader_t *hdr, *t;
104 tmComResExtDevDescrHeader_t *exthdr;
105 tmComResPathDescrHeader_t *pathhdr;
106 tmComResAntTermDescrHeader_t *anttermhdr;
107 tmComResTunerDescrHeader_t *tunerunithdr;
108 tmComResDMATermDescrHeader_t *vcoutputtermhdr;
109 tmComResTSFormatDescrHeader_t *tsfmt;
110 u32 currpath = 0;
111
112 dprintk(DBGLVL_API,
113 "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
114 __func__, len, (u32)sizeof(tmComResDescrHeader_t));
115
116 for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
117
118 hdr = (tmComResDescrHeader_t *)(buf + idx);
119
120 if (hdr->type != CS_INTERFACE)
121 return SAA_ERR_NOT_SUPPORTED;
122
123 dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
124 switch (hdr->subtype) {
125 case GENERAL_REQUEST:
126 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
127 break;
128 case VC_TUNER_PATH:
129 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
130 pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
131 dprintk(DBGLVL_API, " pathid = 0x%x\n",
132 pathhdr->pathid);
133 currpath = pathhdr->pathid;
134 break;
135 case VC_INPUT_TERMINAL:
136 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
137 anttermhdr =
138 (tmComResAntTermDescrHeader_t *)(buf + idx);
139 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
140 anttermhdr->terminalid);
141 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
142 anttermhdr->terminaltype);
143 switch (anttermhdr->terminaltype) {
144 case ITT_ANTENNA:
145 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
146 break;
147 case LINE_CONNECTOR:
148 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
149 break;
150 case SPDIF_CONNECTOR:
151 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
152 break;
153 case COMPOSITE_CONNECTOR:
154 dprintk(DBGLVL_API,
155 " = COMPOSITE_CONNECTOR\n");
156 break;
157 case SVIDEO_CONNECTOR:
158 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
159 break;
160 case COMPONENT_CONNECTOR:
161 dprintk(DBGLVL_API,
162 " = COMPONENT_CONNECTOR\n");
163 break;
164 case STANDARD_DMA:
165 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
166 break;
167 default:
168 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
169 anttermhdr->terminaltype);
170 }
171 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
172 anttermhdr->assocterminal);
173 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
174 anttermhdr->iterminal);
175 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
176 anttermhdr->controlsize);
177 break;
178 case VC_OUTPUT_TERMINAL:
179 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
180 vcoutputtermhdr =
181 (tmComResDMATermDescrHeader_t *)(buf + idx);
182 dprintk(DBGLVL_API, " unitid = 0x%x\n",
183 vcoutputtermhdr->unitid);
184 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
185 vcoutputtermhdr->terminaltype);
186 switch (vcoutputtermhdr->terminaltype) {
187 case ITT_ANTENNA:
188 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
189 break;
190 case LINE_CONNECTOR:
191 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
192 break;
193 case SPDIF_CONNECTOR:
194 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
195 break;
196 case COMPOSITE_CONNECTOR:
197 dprintk(DBGLVL_API,
198 " = COMPOSITE_CONNECTOR\n");
199 break;
200 case SVIDEO_CONNECTOR:
201 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
202 break;
203 case COMPONENT_CONNECTOR:
204 dprintk(DBGLVL_API,
205 " = COMPONENT_CONNECTOR\n");
206 break;
207 case STANDARD_DMA:
208 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
209 break;
210 default:
211 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
212 vcoutputtermhdr->terminaltype);
213 }
214 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
215 vcoutputtermhdr->assocterminal);
216 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
217 vcoutputtermhdr->sourceid);
218 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
219 vcoutputtermhdr->iterminal);
220 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
221 vcoutputtermhdr->BARLocation);
222 dprintk(DBGLVL_API, " flags = 0x%x\n",
223 vcoutputtermhdr->flags);
224 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
225 vcoutputtermhdr->interruptid);
226 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
227 vcoutputtermhdr->buffercount);
228 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
229 vcoutputtermhdr->metadatasize);
230 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
231 vcoutputtermhdr->controlsize);
232 dprintk(DBGLVL_API, " numformats = 0x%x\n",
233 vcoutputtermhdr->numformats);
234
235 t = (tmComResDescrHeader_t *)
236 ((tmComResDMATermDescrHeader_t *)(buf + idx));
237 next_offset = idx + (vcoutputtermhdr->len);
238 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
239 t = (tmComResDescrHeader_t *)
240 (buf + next_offset);
241 switch (t->subtype) {
242 case VS_FORMAT_MPEG2TS:
243 tsfmt =
244 (tmComResTSFormatDescrHeader_t *)t;
245 if (currpath == 1)
246 port = &dev->ts1;
247 else
248 port = &dev->ts2;
249 memcpy(&port->hwcfg, vcoutputtermhdr,
250 sizeof(*vcoutputtermhdr));
251 saa7164_api_configure_port_mpeg2ts(dev,
252 port, tsfmt);
253 break;
254 case VS_FORMAT_MPEG2PS:
255 dprintk(DBGLVL_API,
256 " = VS_FORMAT_MPEG2PS\n");
257 break;
258 case VS_FORMAT_VBI:
259 dprintk(DBGLVL_API,
260 " = VS_FORMAT_VBI\n");
261 break;
262 case VS_FORMAT_RDS:
263 dprintk(DBGLVL_API,
264 " = VS_FORMAT_RDS\n");
265 break;
266 case VS_FORMAT_UNCOMPRESSED:
267 dprintk(DBGLVL_API,
268 " = VS_FORMAT_UNCOMPRESSED\n");
269 break;
270 case VS_FORMAT_TYPE:
271 dprintk(DBGLVL_API,
272 " = VS_FORMAT_TYPE\n");
273 break;
274 default:
275 dprintk(DBGLVL_API,
276 " = undefined (0x%x)\n",
277 t->subtype);
278 }
279 next_offset += t->len;
280 }
281
282 break;
283 case TUNER_UNIT:
284 dprintk(DBGLVL_API, " TUNER_UNIT\n");
285 tunerunithdr =
286 (tmComResTunerDescrHeader_t *)(buf + idx);
287 dprintk(DBGLVL_API, " unitid = 0x%x\n",
288 tunerunithdr->unitid);
289 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
290 tunerunithdr->sourceid);
291 dprintk(DBGLVL_API, " iunit = 0x%x\n",
292 tunerunithdr->iunit);
293 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
294 tunerunithdr->tuningstandards);
295 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
296 tunerunithdr->controlsize);
297 dprintk(DBGLVL_API, " controls = 0x%x\n",
298 tunerunithdr->controls);
299 break;
300 case VC_SELECTOR_UNIT:
301 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
302 break;
303 case VC_PROCESSING_UNIT:
304 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
305 break;
306 case FEATURE_UNIT:
307 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
308 break;
309 case ENCODER_UNIT:
310 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
311 break;
312 case EXTENSION_UNIT:
313 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
314 exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
315 dprintk(DBGLVL_API, " unitid = 0x%x\n",
316 exthdr->unitid);
317 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
318 exthdr->deviceid);
319 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
320 exthdr->devicetype);
321 if (exthdr->devicetype & 0x1)
322 dprintk(DBGLVL_API, " = Decoder Device\n");
323 if (exthdr->devicetype & 0x2)
324 dprintk(DBGLVL_API, " = GPIO Source\n");
325 if (exthdr->devicetype & 0x4)
326 dprintk(DBGLVL_API, " = Video Decoder\n");
327 if (exthdr->devicetype & 0x8)
328 dprintk(DBGLVL_API, " = Audio Decoder\n");
329 if (exthdr->devicetype & 0x20)
330 dprintk(DBGLVL_API, " = Crossbar\n");
331 if (exthdr->devicetype & 0x40)
332 dprintk(DBGLVL_API, " = Tuner\n");
333 if (exthdr->devicetype & 0x80)
334 dprintk(DBGLVL_API, " = IF PLL\n");
335 if (exthdr->devicetype & 0x100)
336 dprintk(DBGLVL_API, " = Demodulator\n");
337 if (exthdr->devicetype & 0x200)
338 dprintk(DBGLVL_API, " = RDS Decoder\n");
339 if (exthdr->devicetype & 0x400)
340 dprintk(DBGLVL_API, " = Encoder\n");
341 if (exthdr->devicetype & 0x800)
342 dprintk(DBGLVL_API, " = IR Decoder\n");
343 if (exthdr->devicetype & 0x1000)
344 dprintk(DBGLVL_API, " = EEPROM\n");
345 if (exthdr->devicetype & 0x2000)
346 dprintk(DBGLVL_API,
347 " = VBI Decoder\n");
348 if (exthdr->devicetype & 0x10000)
349 dprintk(DBGLVL_API,
350 " = Streaming Device\n");
351 if (exthdr->devicetype & 0x20000)
352 dprintk(DBGLVL_API,
353 " = DRM Device\n");
354 if (exthdr->devicetype & 0x40000000)
355 dprintk(DBGLVL_API,
356 " = Generic Device\n");
357 if (exthdr->devicetype & 0x80000000)
358 dprintk(DBGLVL_API,
359 " = Config Space Device\n");
360 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
361 exthdr->numgpiopins);
362 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
363 exthdr->numgpiogroups);
364 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
365 exthdr->controlsize);
366 break;
367 case PVC_INFRARED_UNIT:
368 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
369 break;
370 case DRM_UNIT:
371 dprintk(DBGLVL_API, " DRM_UNIT\n");
372 break;
373 default:
374 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
375 }
376
377 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
378 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
379 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
380 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
381
382 idx += hdr->len;
383 }
384
385 return 0;
386}
387
388int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
389{
390 int ret;
391 u32 buflen = 0;
392 u8 *buf;
393
394 dprintk(DBGLVL_API, "%s()\n", __func__);
395
396 /* Get the total descriptor length */
397 ret = saa7164_cmd_send(dev, 0, GET_LEN,
398 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
399 if (ret != SAA_OK)
400 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
401
402 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
403 __func__, buflen);
404
405 /* Allocate enough storage for all of the descs */
406 buf = kzalloc(buflen, GFP_KERNEL);
407 if (buf == NULL)
408 return SAA_ERR_NO_RESOURCES;
409
410 /* Retrieve them */
411 ret = saa7164_cmd_send(dev, 0, GET_CUR,
412 GET_DESCRIPTORS_CONTROL, buflen, buf);
413 if (ret != SAA_OK) {
414 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
415 goto out;
416 }
417
418 if (debug & DBGLVL_API)
419 saa7164_dumphex16(dev, buf, (buflen/16)*16);
420
421 saa7164_api_dump_subdevs(dev, buf, buflen);
422
423out:
424 kfree(buf);
425 return ret;
426}
427
428int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
429 u32 datalen, u8 *data)
430{
431 struct saa7164_dev *dev = bus->dev;
432 u16 len = 0;
433 int unitid;
434 u32 regval;
435 u8 buf[256];
436 int ret;
437
438 dprintk(DBGLVL_API, "%s()\n", __func__);
439
440 if (reglen > 4)
441 return -EIO;
442
443 if (reglen == 1)
444 regval = *(reg);
445 else
446 if (reglen == 2)
447 regval = ((*(reg) << 8) || *(reg+1));
448 else
449 if (reglen == 3)
450 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
451 else
452 if (reglen == 4)
453 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
454 (*(reg+2) << 8) | *(reg+3));
455
456 /* Prepare the send buffer */
457 /* Bytes 00-03 source register length
458 * 04-07 source bytes to read
459 * 08... register address
460 */
461 memset(buf, 0, sizeof(buf));
462 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
463 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
464 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
465
466 unitid = saa7164_i2caddr_to_unitid(bus, addr);
467 if (unitid < 0) {
468 printk(KERN_ERR
469 "%s() error, cannot translate regaddr 0x%x to unitid\n",
470 __func__, addr);
471 return -EIO;
472 }
473
474 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
475 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
476 if (ret != SAA_OK) {
477 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
478 return -EIO;
479 }
480
481 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
482
483 if (debug & DBGLVL_I2C)
484 saa7164_dumphex16(dev, buf, 2 * 16);
485
486 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
487 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
488 if (ret != SAA_OK)
489 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
490 else {
491 if (debug & DBGLVL_I2C)
492 saa7164_dumphex16(dev, buf, sizeof(buf));
493 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
494 }
495
496 return ret == SAA_OK ? 0 : -EIO;
497}
498
499/* For a given 8 bit i2c address device, write the buffer */
500int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
501 u8 *data)
502{
503 struct saa7164_dev *dev = bus->dev;
504 u16 len = 0;
505 int unitid;
506 int reglen;
507 u8 buf[256];
508 int ret;
509
510 dprintk(DBGLVL_API, "%s()\n", __func__);
511
512 if ((datalen == 0) || (datalen > 232))
513 return -EIO;
514
515 memset(buf, 0, sizeof(buf));
516
517 unitid = saa7164_i2caddr_to_unitid(bus, addr);
518 if (unitid < 0) {
519 printk(KERN_ERR
520 "%s() error, cannot translate regaddr 0x%x to unitid\n",
521 __func__, addr);
522 return -EIO;
523 }
524
525 reglen = saa7164_i2caddr_to_reglen(bus, addr);
526 if (unitid < 0) {
527 printk(KERN_ERR
528 "%s() error, cannot translate regaddr to reglen\n",
529 __func__);
530 return -EIO;
531 }
532
533 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
534 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
535 if (ret != SAA_OK) {
536 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
537 return -EIO;
538 }
539
540 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
541
542 /* Prepare the send buffer */
543 /* Bytes 00-03 dest register length
544 * 04-07 dest bytes to write
545 * 08... register address
546 */
547 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
548 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
549 memcpy((buf + 2 * sizeof(u32)), data, datalen);
550
551 if (debug & DBGLVL_I2C)
552 saa7164_dumphex16(dev, buf, sizeof(buf));
553
554 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
555 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
556 if (ret != SAA_OK)
557 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
558
559 return ret == SAA_OK ? 0 : -EIO;
560}
561
562
563int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
564 u8 pin, u8 state)
565{
566 int ret;
567 tmComResGPIO_t t;
568
569 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
570 __func__, unitid, pin, state);
571
572 if ((pin > 7) || (state > 2))
573 return SAA_ERR_BAD_PARAMETER;
574
575 t.pin = pin;
576 t.state = state;
577
578 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
579 EXU_GPIO_CONTROL, sizeof(t), &t);
580 if (ret != SAA_OK)
581 printk(KERN_ERR "%s() error, ret = 0x%x\n",
582 __func__, ret);
583
584 return ret;
585}
586
587int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
588 u8 pin)
589{
590 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
591}
592
593int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
594 u8 pin)
595{
596 return saa7164_api_modify_gpio(dev, unitid, pin, 0);
597}
598
599
600
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 000000000000..9ca5c83d165b
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,155 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24/* The PCI address space for buffer handling looks like this:
25
26 +-u32 wide-------------+
27 | +
28 +-u64 wide------------------------------------+
29 + +
30 +----------------------+
31 | CurrentBufferPtr + Pointer to current PCI buffer >-+
32 +----------------------+ |
33 | Unused + |
34 +----------------------+ |
35 | Pitch + = 188 (bytes) |
36 +----------------------+ |
37 | PCI buffer size + = pitch * number of lines (312) |
38 +----------------------+ |
39 |0| Buf0 Write Offset + |
40 +----------------------+ v
41 |1| Buf1 Write Offset + |
42 +----------------------+ |
43 |2| Buf2 Write Offset + |
44 +----------------------+ |
45 |3| Buf3 Write Offset + |
46 +----------------------+ |
47 ... More write offsets |
48 +---------------------------------------------+ |
49 +0| set of ptrs to PCI pagetables + |
50 +---------------------------------------------+ |
51 +1| set of ptrs to PCI pagetables + <--------+
52 +---------------------------------------------+
53 +2| set of ptrs to PCI pagetables +
54 +---------------------------------------------+
55 +3| set of ptrs to PCI pagetables + >--+
56 +---------------------------------------------+ |
57 ... More buffer pointers | +----------------+
58 +->| pt[0] TS data |
59 | +----------------+
60 |
61 | +----------------+
62 +->| pt[1] TS data |
63 | +----------------+
64 | etc
65 */
66
67/* Allocate a new buffer structure and associated PCI space in bytes.
68 * len must be a multiple of sizeof(u64)
69 */
70struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
71 u32 len)
72{
73 struct saa7164_buffer *buf = 0;
74 struct saa7164_dev *dev = port->dev;
75 int i;
76
77 if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
78 log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
79 goto ret;
80 }
81
82 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
83 if (buf == NULL) {
84 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
85 goto ret;
86 }
87
88 buf->port = port;
89 buf->flags = SAA7164_BUFFER_FREE;
90 /* TODO: arg len is being ignored */
91 buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
92 buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
93
94 /* Allocate contiguous memory */
95 buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
96 &buf->dma);
97 if (!buf->cpu)
98 goto fail1;
99
100 buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
101 &buf->pt_dma);
102 if (!buf->pt_cpu)
103 goto fail2;
104
105 /* init the buffers to a known pattern, easier during debugging */
106 memset(buf->cpu, 0xff, buf->pci_size);
107 memset(buf->pt_cpu, 0xff, buf->pt_size);
108
109 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p\n", __func__, buf);
110 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
111 buf->cpu, (long)buf->dma, buf->pci_size);
112 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
113 buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
114
115 /* Format the Page Table Entries to point into the data buffer */
116 for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
117
118 *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
119
120 }
121
122 goto ret;
123
124fail2:
125 pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
126fail1:
127 kfree(buf);
128
129 buf = 0;
130ret:
131 return buf;
132}
133
134int saa7164_buffer_dealloc(struct saa7164_tsport *port,
135 struct saa7164_buffer *buf)
136{
137 struct saa7164_dev *dev = port->dev;
138
139 if ((buf == 0) || (port == 0))
140 return SAA_ERR_BAD_PARAMETER;
141
142 dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
143
144 if (buf->flags != SAA7164_BUFFER_FREE)
145 log_warn(" freeing a non-free buffer\n");
146
147 pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
148 pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
149 buf->pt_dma);
150
151 kfree(buf);
152
153 return SAA_OK;
154}
155
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
new file mode 100644
index 000000000000..83a04640a25a
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -0,0 +1,448 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24/* The message bus to/from the firmware is a ring buffer in PCI address
25 * space. Establish the defaults.
26 */
27int saa7164_bus_setup(struct saa7164_dev *dev)
28{
29 tmComResBusInfo_t *b = &dev->bus;
30
31 mutex_init(&b->lock);
32
33 b->Type = TYPE_BUS_PCIe;
34 b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE;
35
36 b->m_pdwSetRing = (u8 *)(dev->bmmio +
37 ((u32)dev->busdesc.CommandRing));
38
39 b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
40
41 b->m_pdwGetRing = (u8 *)(dev->bmmio +
42 ((u32)dev->busdesc.ResponseRing));
43
44 b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
45
46 b->m_pdwSetWritePos = (u32 *)((u8 *)(dev->bmmio +
47 ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64))));
48
49 b->m_pdwSetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
50 1 * sizeof(u32));
51
52 b->m_pdwGetWritePos = (u32 *)((u8 *)b->m_pdwSetWritePos +
53 2 * sizeof(u32));
54
55 b->m_pdwGetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
56 3 * sizeof(u32));
57
58 return 0;
59}
60
61void saa7164_bus_dump(struct saa7164_dev *dev)
62{
63 tmComResBusInfo_t *b = &dev->bus;
64
65 dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
66 dprintk(DBGLVL_BUS, " .type = %d\n", b->Type);
67 dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio);
68 dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize);
69 dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing);
70 dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing);
71 dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing);
72 dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing);
73
74 dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n",
75 b->m_pdwSetWritePos, *b->m_pdwSetWritePos);
76
77 dprintk(DBGLVL_BUS, " .m_pdwSetReadPos = 0x%p (0x%08x)\n",
78 b->m_pdwSetReadPos, *b->m_pdwSetReadPos);
79
80 dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n",
81 b->m_pdwGetWritePos, *b->m_pdwGetWritePos);
82
83 dprintk(DBGLVL_BUS, " .m_pdwGetReadPos = 0x%p (0x%08x)\n",
84 b->m_pdwGetReadPos, *b->m_pdwGetReadPos);
85}
86
87void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
88{
89 dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
90 dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
91 dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags);
92 dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size);
93 dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command);
94 dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector);
95 dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno);
96 if (buf)
97 dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
98}
99
100/*
101 * Places a command or a response on the bus. The implementation does not
102 * know if it is a command or a response it just places the data on the
103 * bus depending on the bus information given in the tmComResBusInfo_t
104 * structure. If the command or response does not fit into the bus ring
105 * buffer it will be refused.
106 *
107 * Return Value:
108 * SAA_OK The function executed successfully.
109 * < 0 One or more members are not initialized.
110 */
111int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
112{
113 tmComResBusInfo_t *bus = &dev->bus;
114 u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp;
115 u32 new_swp, space_rem;
116 int ret = SAA_ERR_BAD_PARAMETER;
117
118 if (!msg) {
119 printk(KERN_ERR "%s() !msg\n", __func__);
120 return SAA_ERR_BAD_PARAMETER;
121 }
122
123 dprintk(DBGLVL_BUS, "%s()\n", __func__);
124
125 msg->size = cpu_to_le16(msg->size);
126 msg->command = cpu_to_le16(msg->command);
127 msg->controlselector = cpu_to_le16(msg->controlselector);
128
129 if (msg->size > dev->bus.m_wMaxReqSize) {
130 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
131 __func__);
132 return SAA_ERR_BAD_PARAMETER;
133 }
134
135 if ((msg->size > 0) && (buf == 0)) {
136 printk(KERN_ERR "%s() Missing message buffer\n", __func__);
137 return SAA_ERR_BAD_PARAMETER;
138 }
139
140 /* Lock the bus from any other access */
141 mutex_lock(&bus->lock);
142
143 bytes_to_write = sizeof(*msg) + msg->size;
144 read_distance = 0;
145 timeout = SAA_BUS_TIMEOUT;
146 curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
147 curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos);
148
149 /* Deal with ring wrapping issues */
150 if (curr_srp > curr_swp)
151 /* The ring has not wrapped yet */
152 read_distance = curr_srp - curr_swp;
153 else
154 /* Deal with the wrapped ring */
155 read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
156
157 dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
158 bytes_to_write);
159
160 dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__,
161 read_distance);
162
163 dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
164 dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
165
166 /* Process the msg and write the content onto the bus */
167 while (bytes_to_write >= read_distance) {
168
169 if (timeout-- == 0) {
170 printk(KERN_ERR "%s() bus timeout\n", __func__);
171 ret = SAA_ERR_NO_RESOURCES;
172 goto out;
173 }
174
175 /* TODO: Review this delay, efficient? */
176 /* Wait, allowing the hardware fetch time */
177 mdelay(1);
178
179 /* Check the space usage again */
180 curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
181
182 /* Deal with ring wrapping issues */
183 if (curr_srp > curr_swp)
184 /* Read didn't wrap around the buffer */
185 read_distance = curr_srp - curr_swp;
186 else
187 /* Deal with the wrapped ring */
188 read_distance = (curr_srp + bus->m_dwSizeSetRing) -
189 curr_swp;
190
191 }
192
193 /* Calculate the new write position */
194 new_swp = curr_swp + bytes_to_write;
195
196 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
197 dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
198 bus->m_dwSizeSetRing);
199
200 /* Mental Note: line 462 tmmhComResBusPCIe.cpp */
201
202 /* Check if we're going to wrap again */
203 if (new_swp > bus->m_dwSizeSetRing) {
204
205 /* Ring wraps */
206 new_swp -= bus->m_dwSizeSetRing;
207
208 space_rem = bus->m_dwSizeSetRing - curr_swp;
209
210 dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
211 space_rem);
212
213 dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
214 (u32)sizeof(*msg));
215
216 if (space_rem < sizeof(*msg)) {
217 dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
218
219 /* Split the msg into pieces as the ring wraps */
220 memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
221 memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
222 sizeof(*msg) - space_rem);
223
224 memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
225 buf, msg->size);
226
227 } else if (space_rem == sizeof(*msg)) {
228 dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
229
230 /* Additional data at the beginning of the ring */
231 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
232 memcpy(bus->m_pdwSetRing, buf, msg->size);
233
234 } else {
235 /* Additional data wraps around the ring */
236 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
237 if (msg->size > 0) {
238 memcpy(bus->m_pdwSetRing + curr_swp +
239 sizeof(*msg), buf, space_rem -
240 sizeof(*msg));
241 memcpy(bus->m_pdwSetRing, (u8 *)buf +
242 space_rem - sizeof(*msg),
243 bytes_to_write - space_rem);
244 }
245
246 }
247
248 } /* (new_swp > bus->m_dwSizeSetRing) */
249 else {
250 dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
251
252 /* The ring buffer doesn't wrap, two simple copies */
253 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
254 memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
255 msg->size);
256 }
257
258 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
259
260 /* TODO: Convert all of the direct PCI writes into
261 * saa7164_writel/b calls for consistency.
262 */
263
264 /* Update the bus write position */
265 *bus->m_pdwSetWritePos = cpu_to_le32(new_swp);
266 ret = SAA_OK;
267
268out:
269 mutex_unlock(&bus->lock);
270 return ret;
271}
272
273/*
274 * Receive a command or a response from the bus. The implementation does not
275 * know if it is a command or a response it simply dequeues the data,
276 * depending on the bus information given in the tmComResBusInfo_t structure.
277 *
278 * Return Value:
279 * 0 The function executed successfully.
280 * < 0 One or more members are not initialized.
281 */
282int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
283 int peekonly)
284{
285 tmComResBusInfo_t *bus = &dev->bus;
286 u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
287 new_grp, buf_size, space_rem;
288 tmComResInfo_t msg_tmp;
289 int ret = SAA_ERR_BAD_PARAMETER;
290
291 if (msg == 0)
292 return ret;
293
294 if (msg->size > dev->bus.m_wMaxReqSize) {
295 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
296 __func__);
297 return ret;
298 }
299
300 if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) {
301 printk(KERN_ERR
302 "%s() Missing msg buf, size should be %d bytes\n",
303 __func__, msg->size);
304 return ret;
305 }
306
307 mutex_lock(&bus->lock);
308
309 /* Peek the bus to see if a msg exists, if it's not what we're expecting
310 * then return cleanly else read the message from the bus.
311 */
312 curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos);
313 curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos);
314
315 if (curr_gwp == curr_grp) {
316 dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__);
317 ret = SAA_ERR_EMPTY;
318 goto out;
319 }
320
321 bytes_to_read = sizeof(*msg);
322
323 /* Calculate write distance to current read position */
324 write_distance = 0;
325 if (curr_gwp >= curr_grp)
326 /* Write doesn't wrap around the ring */
327 write_distance = curr_gwp - curr_grp;
328 else
329 /* Write wraps around the ring */
330 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
331
332 if (bytes_to_read > write_distance) {
333 printk(KERN_ERR "%s() No message/response found\n", __func__);
334 ret = SAA_ERR_INVALID_COMMAND;
335 goto out;
336 }
337
338 /* Calculate the new read position */
339 new_grp = curr_grp + bytes_to_read;
340 if (new_grp > bus->m_dwSizeGetRing) {
341
342 /* Ring wraps */
343 new_grp -= bus->m_dwSizeGetRing;
344 space_rem = bus->m_dwSizeGetRing - curr_grp;
345
346 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
347 memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
348 bytes_to_read - space_rem);
349
350 } else {
351 /* No wrapping */
352 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
353 }
354
355 /* No need to update the read positions, because this was a peek */
356 /* If the caller specifically want to peek, return */
357 if (peekonly) {
358 memcpy(msg, &msg_tmp, sizeof(*msg));
359 goto peekout;
360 }
361
362 /* Check if the command/response matches what is expected */
363 if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
364 (msg_tmp.controlselector != msg->controlselector) ||
365 (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
366
367 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
368 saa7164_bus_dumpmsg(dev, msg, buf);
369 saa7164_bus_dumpmsg(dev, &msg_tmp, 0);
370 ret = SAA_ERR_INVALID_COMMAND;
371 goto out;
372 }
373
374 /* Get the actual command and response from the bus */
375 buf_size = msg->size;
376
377 bytes_to_read = sizeof(*msg) + msg->size;
378 /* Calculate write distance to current read position */
379 write_distance = 0;
380 if (curr_gwp >= curr_grp)
381 /* Write doesn't wrap around the ring */
382 write_distance = curr_gwp - curr_grp;
383 else
384 /* Write wraps around the ring */
385 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
386
387 if (bytes_to_read > write_distance) {
388 printk(KERN_ERR "%s() Invalid bus state, missing msg "
389 "or mangled ring, faulty H/W / bad code?\n", __func__);
390 ret = SAA_ERR_INVALID_COMMAND;
391 goto out;
392 }
393
394 /* Calculate the new read position */
395 new_grp = curr_grp + bytes_to_read;
396 if (new_grp > bus->m_dwSizeGetRing) {
397
398 /* Ring wraps */
399 new_grp -= bus->m_dwSizeGetRing;
400 space_rem = bus->m_dwSizeGetRing - curr_grp;
401
402 if (space_rem < sizeof(*msg)) {
403 /* msg wraps around the ring */
404 memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
405 memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
406 sizeof(*msg) - space_rem);
407 if (buf)
408 memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
409 space_rem, buf_size);
410
411 } else if (space_rem == sizeof(*msg)) {
412 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
413 if (buf)
414 memcpy(buf, bus->m_pdwGetRing, buf_size);
415 } else {
416 /* Additional data wraps around the ring */
417 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
418 if (buf) {
419 memcpy(buf, bus->m_pdwGetRing + curr_grp +
420 sizeof(*msg), space_rem - sizeof(*msg));
421 memcpy(buf + space_rem - sizeof(*msg),
422 bus->m_pdwGetRing, bytes_to_read -
423 space_rem);
424 }
425
426 }
427
428 } else {
429 /* No wrapping */
430 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
431 if (buf)
432 memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
433 buf_size);
434 }
435
436 /* Update the read positions, adjusting the ring */
437 *bus->m_pdwGetReadPos = cpu_to_le32(new_grp);
438
439peekout:
440 msg->size = le16_to_cpu(msg->size);
441 msg->command = le16_to_cpu(msg->command);
442 msg->controlselector = le16_to_cpu(msg->controlselector);
443 ret = SAA_OK;
444out:
445 mutex_unlock(&bus->lock);
446 return ret;
447}
448
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
new file mode 100644
index 000000000000..a3c299405f46
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -0,0 +1,624 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26
27#include "saa7164.h"
28
29/* The Bridge API needs to understand register widths (in bytes) for the
30 * attached I2C devices, so we can simplify the virtual i2c mechansms
31 * and keep the -i2c.c implementation clean.
32 */
33#define REGLEN_8bit 1
34#define REGLEN_16bit 2
35
36struct saa7164_board saa7164_boards[] = {
37 [SAA7164_BOARD_UNKNOWN] = {
38 /* Bridge will not load any firmware, without knowing
39 * the rev this would be fatal. */
40 .name = "Unknown",
41 },
42 [SAA7164_BOARD_UNKNOWN_REV2] = {
43 /* Bridge will load the v2 f/w and dump descriptors */
44 /* Required during new board bringup */
45 .name = "Generic Rev2",
46 .chiprev = SAA7164_CHIP_REV2,
47 },
48 [SAA7164_BOARD_UNKNOWN_REV3] = {
49 /* Bridge will load the v2 f/w and dump descriptors */
50 /* Required during new board bringup */
51 .name = "Generic Rev3",
52 .chiprev = SAA7164_CHIP_REV3,
53 },
54 [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
55 .name = "Hauppauge WinTV-HVR2200",
56 .porta = SAA7164_MPEG_DVB,
57 .portb = SAA7164_MPEG_DVB,
58 .chiprev = SAA7164_CHIP_REV3,
59 .unit = {{
60 .id = 0x1d,
61 .type = SAA7164_UNIT_EEPROM,
62 .name = "4K EEPROM",
63 .i2c_bus_nr = SAA7164_I2C_BUS_0,
64 .i2c_bus_addr = 0xa0 >> 1,
65 .i2c_reg_len = REGLEN_8bit,
66 }, {
67 .id = 0x04,
68 .type = SAA7164_UNIT_TUNER,
69 .name = "TDA18271-1",
70 .i2c_bus_nr = SAA7164_I2C_BUS_1,
71 .i2c_bus_addr = 0xc0 >> 1,
72 .i2c_reg_len = REGLEN_8bit,
73 }, {
74 .id = 0x1b,
75 .type = SAA7164_UNIT_TUNER,
76 .name = "TDA18271-2",
77 .i2c_bus_nr = SAA7164_I2C_BUS_2,
78 .i2c_bus_addr = 0xc0 >> 1,
79 .i2c_reg_len = REGLEN_8bit,
80 }, {
81 .id = 0x1e,
82 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
83 .name = "TDA10048-1",
84 .i2c_bus_nr = SAA7164_I2C_BUS_1,
85 .i2c_bus_addr = 0x10 >> 1,
86 .i2c_reg_len = REGLEN_8bit,
87 }, {
88 .id = 0x1f,
89 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
90 .name = "TDA10048-2",
91 .i2c_bus_nr = SAA7164_I2C_BUS_2,
92 .i2c_bus_addr = 0x12 >> 1,
93 .i2c_reg_len = REGLEN_8bit,
94 } },
95 },
96 [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
97 .name = "Hauppauge WinTV-HVR2200",
98 .porta = SAA7164_MPEG_DVB,
99 .portb = SAA7164_MPEG_DVB,
100 .chiprev = SAA7164_CHIP_REV2,
101 .unit = {{
102 .id = 0x06,
103 .type = SAA7164_UNIT_EEPROM,
104 .name = "4K EEPROM",
105 .i2c_bus_nr = SAA7164_I2C_BUS_0,
106 .i2c_bus_addr = 0xa0 >> 1,
107 .i2c_reg_len = REGLEN_8bit,
108 }, {
109 .id = 0x04,
110 .type = SAA7164_UNIT_TUNER,
111 .name = "TDA18271-1",
112 .i2c_bus_nr = SAA7164_I2C_BUS_1,
113 .i2c_bus_addr = 0xc0 >> 1,
114 .i2c_reg_len = REGLEN_8bit,
115 }, {
116 .id = 0x05,
117 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
118 .name = "TDA10048-1",
119 .i2c_bus_nr = SAA7164_I2C_BUS_1,
120 .i2c_bus_addr = 0x10 >> 1,
121 .i2c_reg_len = REGLEN_8bit,
122 }, {
123 .id = 0x1e,
124 .type = SAA7164_UNIT_TUNER,
125 .name = "TDA18271-2",
126 .i2c_bus_nr = SAA7164_I2C_BUS_2,
127 .i2c_bus_addr = 0xc0 >> 1,
128 .i2c_reg_len = REGLEN_8bit,
129 }, {
130 .id = 0x1f,
131 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
132 .name = "TDA10048-2",
133 .i2c_bus_nr = SAA7164_I2C_BUS_2,
134 .i2c_bus_addr = 0x12 >> 1,
135 .i2c_reg_len = REGLEN_8bit,
136 } },
137 },
138 [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
139 .name = "Hauppauge WinTV-HVR2200",
140 .porta = SAA7164_MPEG_DVB,
141 .portb = SAA7164_MPEG_DVB,
142 .chiprev = SAA7164_CHIP_REV2,
143 .unit = {{
144 .id = 0x1d,
145 .type = SAA7164_UNIT_EEPROM,
146 .name = "4K EEPROM",
147 .i2c_bus_nr = SAA7164_I2C_BUS_0,
148 .i2c_bus_addr = 0xa0 >> 1,
149 .i2c_reg_len = REGLEN_8bit,
150 }, {
151 .id = 0x04,
152 .type = SAA7164_UNIT_TUNER,
153 .name = "TDA18271-1",
154 .i2c_bus_nr = SAA7164_I2C_BUS_1,
155 .i2c_bus_addr = 0xc0 >> 1,
156 .i2c_reg_len = REGLEN_8bit,
157 }, {
158 .id = 0x05,
159 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
160 .name = "TDA8290-1",
161 .i2c_bus_nr = SAA7164_I2C_BUS_1,
162 .i2c_bus_addr = 0x84 >> 1,
163 .i2c_reg_len = REGLEN_8bit,
164 }, {
165 .id = 0x1b,
166 .type = SAA7164_UNIT_TUNER,
167 .name = "TDA18271-2",
168 .i2c_bus_nr = SAA7164_I2C_BUS_2,
169 .i2c_bus_addr = 0xc0 >> 1,
170 .i2c_reg_len = REGLEN_8bit,
171 }, {
172 .id = 0x1c,
173 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
174 .name = "TDA8290-2",
175 .i2c_bus_nr = SAA7164_I2C_BUS_2,
176 .i2c_bus_addr = 0x84 >> 1,
177 .i2c_reg_len = REGLEN_8bit,
178 }, {
179 .id = 0x1e,
180 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
181 .name = "TDA10048-1",
182 .i2c_bus_nr = SAA7164_I2C_BUS_1,
183 .i2c_bus_addr = 0x10 >> 1,
184 .i2c_reg_len = REGLEN_8bit,
185 }, {
186 .id = 0x1f,
187 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
188 .name = "TDA10048-2",
189 .i2c_bus_nr = SAA7164_I2C_BUS_2,
190 .i2c_bus_addr = 0x12 >> 1,
191 .i2c_reg_len = REGLEN_8bit,
192 } },
193 },
194 [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
195 .name = "Hauppauge WinTV-HVR2250",
196 .porta = SAA7164_MPEG_DVB,
197 .portb = SAA7164_MPEG_DVB,
198 .chiprev = SAA7164_CHIP_REV3,
199 .unit = {{
200 .id = 0x22,
201 .type = SAA7164_UNIT_EEPROM,
202 .name = "4K EEPROM",
203 .i2c_bus_nr = SAA7164_I2C_BUS_0,
204 .i2c_bus_addr = 0xa0 >> 1,
205 .i2c_reg_len = REGLEN_8bit,
206 }, {
207 .id = 0x04,
208 .type = SAA7164_UNIT_TUNER,
209 .name = "TDA18271-1",
210 .i2c_bus_nr = SAA7164_I2C_BUS_1,
211 .i2c_bus_addr = 0xc0 >> 1,
212 .i2c_reg_len = REGLEN_8bit,
213 }, {
214 .id = 0x07,
215 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
216 .name = "CX24228/S5H1411-1 (TOP)",
217 .i2c_bus_nr = SAA7164_I2C_BUS_1,
218 .i2c_bus_addr = 0x32 >> 1,
219 .i2c_reg_len = REGLEN_8bit,
220 }, {
221 .id = 0x08,
222 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
223 .name = "CX24228/S5H1411-1 (QAM)",
224 .i2c_bus_nr = SAA7164_I2C_BUS_1,
225 .i2c_bus_addr = 0x34 >> 1,
226 .i2c_reg_len = REGLEN_8bit,
227 }, {
228 .id = 0x1e,
229 .type = SAA7164_UNIT_TUNER,
230 .name = "TDA18271-2",
231 .i2c_bus_nr = SAA7164_I2C_BUS_2,
232 .i2c_bus_addr = 0xc0 >> 1,
233 .i2c_reg_len = REGLEN_8bit,
234 }, {
235 .id = 0x20,
236 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
237 .name = "CX24228/S5H1411-2 (TOP)",
238 .i2c_bus_nr = SAA7164_I2C_BUS_2,
239 .i2c_bus_addr = 0x32 >> 1,
240 .i2c_reg_len = REGLEN_8bit,
241 }, {
242 .id = 0x23,
243 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
244 .name = "CX24228/S5H1411-2 (QAM)",
245 .i2c_bus_nr = SAA7164_I2C_BUS_2,
246 .i2c_bus_addr = 0x34 >> 1,
247 .i2c_reg_len = REGLEN_8bit,
248 } },
249 },
250 [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
251 .name = "Hauppauge WinTV-HVR2250",
252 .porta = SAA7164_MPEG_DVB,
253 .portb = SAA7164_MPEG_DVB,
254 .chiprev = SAA7164_CHIP_REV3,
255 .unit = {{
256 .id = 0x28,
257 .type = SAA7164_UNIT_EEPROM,
258 .name = "4K EEPROM",
259 .i2c_bus_nr = SAA7164_I2C_BUS_0,
260 .i2c_bus_addr = 0xa0 >> 1,
261 .i2c_reg_len = REGLEN_8bit,
262 }, {
263 .id = 0x04,
264 .type = SAA7164_UNIT_TUNER,
265 .name = "TDA18271-1",
266 .i2c_bus_nr = SAA7164_I2C_BUS_1,
267 .i2c_bus_addr = 0xc0 >> 1,
268 .i2c_reg_len = REGLEN_8bit,
269 }, {
270 .id = 0x07,
271 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
272 .name = "CX24228/S5H1411-1 (TOP)",
273 .i2c_bus_nr = SAA7164_I2C_BUS_1,
274 .i2c_bus_addr = 0x32 >> 1,
275 .i2c_reg_len = REGLEN_8bit,
276 }, {
277 .id = 0x08,
278 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
279 .name = "CX24228/S5H1411-1 (QAM)",
280 .i2c_bus_nr = SAA7164_I2C_BUS_1,
281 .i2c_bus_addr = 0x34 >> 1,
282 .i2c_reg_len = REGLEN_8bit,
283 }, {
284 .id = 0x24,
285 .type = SAA7164_UNIT_TUNER,
286 .name = "TDA18271-2",
287 .i2c_bus_nr = SAA7164_I2C_BUS_2,
288 .i2c_bus_addr = 0xc0 >> 1,
289 .i2c_reg_len = REGLEN_8bit,
290 }, {
291 .id = 0x26,
292 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
293 .name = "CX24228/S5H1411-2 (TOP)",
294 .i2c_bus_nr = SAA7164_I2C_BUS_2,
295 .i2c_bus_addr = 0x32 >> 1,
296 .i2c_reg_len = REGLEN_8bit,
297 }, {
298 .id = 0x29,
299 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
300 .name = "CX24228/S5H1411-2 (QAM)",
301 .i2c_bus_nr = SAA7164_I2C_BUS_2,
302 .i2c_bus_addr = 0x34 >> 1,
303 .i2c_reg_len = REGLEN_8bit,
304 } },
305 },
306 [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
307 .name = "Hauppauge WinTV-HVR2250",
308 .porta = SAA7164_MPEG_DVB,
309 .portb = SAA7164_MPEG_DVB,
310 .chiprev = SAA7164_CHIP_REV3,
311 .unit = {{
312 .id = 0x26,
313 .type = SAA7164_UNIT_EEPROM,
314 .name = "4K EEPROM",
315 .i2c_bus_nr = SAA7164_I2C_BUS_0,
316 .i2c_bus_addr = 0xa0 >> 1,
317 .i2c_reg_len = REGLEN_8bit,
318 }, {
319 .id = 0x04,
320 .type = SAA7164_UNIT_TUNER,
321 .name = "TDA18271-1",
322 .i2c_bus_nr = SAA7164_I2C_BUS_1,
323 .i2c_bus_addr = 0xc0 >> 1,
324 .i2c_reg_len = REGLEN_8bit,
325 }, {
326 .id = 0x07,
327 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
328 .name = "CX24228/S5H1411-1 (TOP)",
329 .i2c_bus_nr = SAA7164_I2C_BUS_1,
330 .i2c_bus_addr = 0x32 >> 1,
331 .i2c_reg_len = REGLEN_8bit,
332 }, {
333 .id = 0x08,
334 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
335 .name = "CX24228/S5H1411-1 (QAM)",
336 .i2c_bus_nr = SAA7164_I2C_BUS_1,
337 .i2c_bus_addr = 0x34 >> 1,
338 .i2c_reg_len = REGLEN_8bit,
339 }, {
340 .id = 0x22,
341 .type = SAA7164_UNIT_TUNER,
342 .name = "TDA18271-2",
343 .i2c_bus_nr = SAA7164_I2C_BUS_2,
344 .i2c_bus_addr = 0xc0 >> 1,
345 .i2c_reg_len = REGLEN_8bit,
346 }, {
347 .id = 0x24,
348 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
349 .name = "CX24228/S5H1411-2 (TOP)",
350 .i2c_bus_nr = SAA7164_I2C_BUS_2,
351 .i2c_bus_addr = 0x32 >> 1,
352 .i2c_reg_len = REGLEN_8bit,
353 }, {
354 .id = 0x27,
355 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
356 .name = "CX24228/S5H1411-2 (QAM)",
357 .i2c_bus_nr = SAA7164_I2C_BUS_2,
358 .i2c_bus_addr = 0x34 >> 1,
359 .i2c_reg_len = REGLEN_8bit,
360 } },
361 },
362};
363const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
364
365/* ------------------------------------------------------------------ */
366/* PCI subsystem IDs */
367
368struct saa7164_subid saa7164_subids[] = {
369 {
370 .subvendor = 0x0070,
371 .subdevice = 0x8880,
372 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
373 }, {
374 .subvendor = 0x0070,
375 .subdevice = 0x8810,
376 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
377 }, {
378 .subvendor = 0x0070,
379 .subdevice = 0x8980,
380 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
381 }, {
382 .subvendor = 0x0070,
383 .subdevice = 0x8900,
384 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
385 }, {
386 .subvendor = 0x0070,
387 .subdevice = 0x8901,
388 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
389 }, {
390 .subvendor = 0x0070,
391 .subdevice = 0x88A1,
392 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
393 }, {
394 .subvendor = 0x0070,
395 .subdevice = 0x8891,
396 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
397 }, {
398 .subvendor = 0x0070,
399 .subdevice = 0x8851,
400 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
401 },
402};
403const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
404
405void saa7164_card_list(struct saa7164_dev *dev)
406{
407 int i;
408
409 if (0 == dev->pci->subsystem_vendor &&
410 0 == dev->pci->subsystem_device) {
411 printk(KERN_ERR
412 "%s: Board has no valid PCIe Subsystem ID and can't\n"
413 "%s: be autodetected. Pass card=<n> insmod option to\n"
414 "%s: workaround that. Send complaints to the vendor\n"
415 "%s: of the TV card. Best regards,\n"
416 "%s: -- tux\n",
417 dev->name, dev->name, dev->name, dev->name, dev->name);
418 } else {
419 printk(KERN_ERR
420 "%s: Your board isn't known (yet) to the driver.\n"
421 "%s: Try to pick one of the existing card configs via\n"
422 "%s: card=<n> insmod option. Updating to the latest\n"
423 "%s: version might help as well.\n",
424 dev->name, dev->name, dev->name, dev->name);
425 }
426
427 printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
428 "option:\n", dev->name);
429
430 for (i = 0; i < saa7164_bcount; i++)
431 printk(KERN_ERR "%s: card=%d -> %s\n",
432 dev->name, i, saa7164_boards[i].name);
433}
434
435/* TODO: clean this define up into the -cards.c structs */
436#define PCIEBRIDGE_UNITID 2
437
438void saa7164_gpio_setup(struct saa7164_dev *dev)
439{
440
441
442 switch (dev->board) {
443 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
444 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
445 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
446 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
447 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
448 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
449 /*
450 GPIO 2: s5h1411 / tda10048-1 demod reset
451 GPIO 3: s5h1411 / tda10048-2 demod reset
452 GPIO 7: IRBlaster Zilog reset
453 */
454
455 /* Reset parts by going in and out of reset */
456 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
457 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
458
459 msleep(10);
460
461 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
462 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
463 break;
464 }
465
466}
467
468static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
469{
470 struct tveeprom tv;
471
472 /* TODO: Assumption: eeprom on bus 0 */
473 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
474 eeprom_data);
475
476 /* Make sure we support the board model */
477 switch (tv.model) {
478 case 88001:
479 /* Development board - Limit circulation */
480 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
481 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
482 case 88021:
483 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
484 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
485 break;
486 case 88041:
487 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
488 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
489 break;
490 case 88061:
491 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
492 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
493 break;
494 case 89519:
495 case 89609:
496 /* WinTV-HVR2200 (PCIe, Retail, full-height)
497 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
498 break;
499 case 89619:
500 /* WinTV-HVR2200 (PCIe, Retail, half-height)
501 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
502 break;
503 default:
504 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
505 dev->name, tv.model);
506 break;
507 }
508
509 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
510 tv.model);
511}
512
513void saa7164_card_setup(struct saa7164_dev *dev)
514{
515 static u8 eeprom[256];
516
517 if (dev->i2c_bus[0].i2c_rc == 0) {
518 if (saa7164_api_read_eeprom(dev, &eeprom[0],
519 sizeof(eeprom)) < 0)
520 return;
521 }
522
523 switch (dev->board) {
524 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
525 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
526 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
527 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
528 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
529 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
530 hauppauge_eeprom(dev, &eeprom[0]);
531 break;
532 }
533}
534
535/* With most other drivers, the kernel expects to communicate with subdrivers
536 * through i2c. This bridge does not allow that, it does not expose any direct
537 * access to I2C. Instead we have to communicate through the device f/w for
538 * register access to 'processing units'. Each unit has a unique
539 * id, regardless of how the physical implementation occurs across
540 * the three physical i2c busses. The being said if we want leverge of
541 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
542 * to this bridge implements 3 virtual i2c buses. This is a helper function
543 * for those.
544 *
545 * Description: Translate the kernels notion of an i2c address and bus into
546 * the appropriate unitid.
547 */
548int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
549{
550 /* For a given bus and i2c device address, return the saa7164 unique
551 * unitid. < 0 on error */
552
553 struct saa7164_dev *dev = bus->dev;
554 struct saa7164_unit *unit;
555 int i;
556
557 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
558 unit = &saa7164_boards[dev->board].unit[i];
559
560 if (unit->type == SAA7164_UNIT_UNDEFINED)
561 continue;
562 if ((bus->nr == unit->i2c_bus_nr) &&
563 (addr == unit->i2c_bus_addr))
564 return unit->id;
565 }
566
567 return -1;
568}
569
570/* The 7164 API needs to know the i2c register length in advance.
571 * this is a helper function. Based on a specific chip addr and bus return the
572 * reg length.
573 */
574int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
575{
576 /* For a given bus and i2c device address, return the
577 * saa7164 registry address width. < 0 on error
578 */
579
580 struct saa7164_dev *dev = bus->dev;
581 struct saa7164_unit *unit;
582 int i;
583
584 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
585 unit = &saa7164_boards[dev->board].unit[i];
586
587 if (unit->type == SAA7164_UNIT_UNDEFINED)
588 continue;
589
590 if ((bus->nr == unit->i2c_bus_nr) &&
591 (addr == unit->i2c_bus_addr))
592 return unit->i2c_reg_len;
593 }
594
595 return -1;
596}
597/* TODO: implement a 'findeeprom' functio like the above and fix any other
598 * eeprom related todo's in -api.c.
599 */
600
601/* Translate a unitid into a x readable device name, for display purposes. */
602char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
603{
604 char *undefed = "UNDEFINED";
605 char *bridge = "BRIDGE";
606 struct saa7164_unit *unit;
607 int i;
608
609 if (unitid == 0)
610 return bridge;
611
612 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
613 unit = &saa7164_boards[dev->board].unit[i];
614
615 if (unit->type == SAA7164_UNIT_UNDEFINED)
616 continue;
617
618 if (unitid == unit->id)
619 return unit->name;
620 }
621
622 return undefed;
623}
624
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
new file mode 100644
index 000000000000..e097f1a0969a
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -0,0 +1,572 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/wait.h>
23
24#include "saa7164.h"
25
26int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
27{
28 int i, ret = -1;
29
30 mutex_lock(&dev->lock);
31 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
32 if (dev->cmds[i].inuse == 0) {
33 dev->cmds[i].inuse = 1;
34 dev->cmds[i].signalled = 0;
35 dev->cmds[i].timeout = 0;
36 ret = dev->cmds[i].seqno;
37 break;
38 }
39 }
40 mutex_unlock(&dev->lock);
41
42 return ret;
43}
44
45void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
46{
47 mutex_lock(&dev->lock);
48 if ((dev->cmds[seqno].inuse == 1) &&
49 (dev->cmds[seqno].seqno == seqno)) {
50 dev->cmds[seqno].inuse = 0;
51 dev->cmds[seqno].signalled = 0;
52 dev->cmds[seqno].timeout = 0;
53 }
54 mutex_unlock(&dev->lock);
55}
56
57void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
58{
59 mutex_lock(&dev->lock);
60 if ((dev->cmds[seqno].inuse == 1) &&
61 (dev->cmds[seqno].seqno == seqno)) {
62 dev->cmds[seqno].timeout = 1;
63 }
64 mutex_unlock(&dev->lock);
65}
66
67u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
68{
69 int ret = 0;
70
71 mutex_lock(&dev->lock);
72 if ((dev->cmds[seqno].inuse == 1) &&
73 (dev->cmds[seqno].seqno == seqno)) {
74 ret = dev->cmds[seqno].timeout;
75 }
76 mutex_unlock(&dev->lock);
77
78 return ret;
79}
80
81/* Commands to the f/w get marshelled to/from this code then onto the PCI
82 * -bus/c running buffer. */
83int saa7164_irq_dequeue(struct saa7164_dev *dev)
84{
85 int ret = SAA_OK;
86 u32 timeout;
87 wait_queue_head_t *q = 0;
88 dprintk(DBGLVL_CMD, "%s()\n", __func__);
89
90 /* While any outstand message on the bus exists... */
91 do {
92
93 /* Peek the msg bus */
94 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
95 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
96 if (ret != SAA_OK)
97 break;
98
99 q = &dev->cmds[tRsp.seqno].wait;
100 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
101 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
102 if (!timeout) {
103 dprintk(DBGLVL_CMD,
104 "%s() signalled seqno(%d) (for dequeue)\n",
105 __func__, tRsp.seqno);
106 dev->cmds[tRsp.seqno].signalled = 1;
107 wake_up(q);
108 } else {
109 printk(KERN_ERR
110 "%s() found timed out command on the bus\n",
111 __func__);
112 }
113 } while (0);
114
115 return ret;
116}
117
118/* Commands to the f/w get marshelled to/from this code then onto the PCI
119 * -bus/c running buffer. */
120int saa7164_cmd_dequeue(struct saa7164_dev *dev)
121{
122 int loop = 1;
123 int ret;
124 u32 timeout;
125 wait_queue_head_t *q = 0;
126 u8 tmp[512];
127 dprintk(DBGLVL_CMD, "%s()\n", __func__);
128
129 while (loop) {
130
131 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
132 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
133 if (ret == SAA_ERR_EMPTY)
134 return SAA_OK;
135
136 if (ret != SAA_OK)
137 return ret;
138
139 q = &dev->cmds[tRsp.seqno].wait;
140 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
141 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
142 if (timeout) {
143 printk(KERN_ERR "found timed out command on the bus\n");
144
145 /* Clean the bus */
146 ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
147 printk(KERN_ERR "ret = %x\n", ret);
148 if (ret == SAA_ERR_EMPTY)
149 /* Someone else already fetched the response */
150 return SAA_OK;
151
152 if (ret != SAA_OK)
153 return ret;
154
155 if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
156 printk(KERN_ERR "split response\n");
157 else
158 saa7164_cmd_free_seqno(dev, tRsp.seqno);
159
160 printk(KERN_ERR " timeout continue\n");
161 continue;
162 }
163
164 dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
165 __func__, tRsp.seqno);
166 dev->cmds[tRsp.seqno].signalled = 1;
167 wake_up(q);
168 return SAA_OK;
169 }
170
171 return SAA_OK;
172}
173
174int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
175{
176 tmComResBusInfo_t *bus = &dev->bus;
177 u8 cmd_sent;
178 u16 size, idx;
179 u32 cmds;
180 void *tmp;
181 int ret = -1;
182
183 if (!msg) {
184 printk(KERN_ERR "%s() !msg\n", __func__);
185 return SAA_ERR_BAD_PARAMETER;
186 }
187
188 mutex_lock(&dev->cmds[msg->id].lock);
189
190 size = msg->size;
191 idx = 0;
192 cmds = size / bus->m_wMaxReqSize;
193 if (size % bus->m_wMaxReqSize == 0)
194 cmds -= 1;
195
196 cmd_sent = 0;
197
198 /* Split the request into smaller chunks */
199 for (idx = 0; idx < cmds; idx++) {
200
201 msg->flags |= SAA_CMDFLAG_CONTINUE;
202 msg->size = bus->m_wMaxReqSize;
203 tmp = buf + idx * bus->m_wMaxReqSize;
204
205 ret = saa7164_bus_set(dev, msg, tmp);
206 if (ret != SAA_OK) {
207 printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
208
209 if (cmd_sent) {
210 ret = SAA_ERR_BUSY;
211 goto out;
212 }
213 ret = SAA_ERR_OVERFLOW;
214 goto out;
215 }
216 cmd_sent = 1;
217 }
218
219 /* If not the last command... */
220 if (idx != 0)
221 msg->flags &= ~SAA_CMDFLAG_CONTINUE;
222
223 msg->size = size - idx * bus->m_wMaxReqSize;
224
225 ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
226 if (ret != SAA_OK) {
227 printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
228
229 if (cmd_sent) {
230 ret = SAA_ERR_BUSY;
231 goto out;
232 }
233 ret = SAA_ERR_OVERFLOW;
234 goto out;
235 }
236 ret = SAA_OK;
237
238out:
239 mutex_unlock(&dev->cmds[msg->id].lock);
240 return ret;
241}
242
243/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
244 * the event never occured, or SAA_OK if it was signaled during the wait.
245 */
246int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
247{
248 wait_queue_head_t *q = 0;
249 int ret = SAA_BUS_TIMEOUT;
250 unsigned long stamp;
251 int r;
252
253 if (debug >= 4)
254 saa7164_bus_dump(dev);
255
256 dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
257
258 mutex_lock(&dev->lock);
259 if ((dev->cmds[seqno].inuse == 1) &&
260 (dev->cmds[seqno].seqno == seqno)) {
261 q = &dev->cmds[seqno].wait;
262 }
263 mutex_unlock(&dev->lock);
264
265 if (q) {
266 /* If we haven't been signalled we need to wait */
267 if (dev->cmds[seqno].signalled == 0) {
268 stamp = jiffies;
269 dprintk(DBGLVL_CMD,
270 "%s(seqno=%d) Waiting (signalled=%d)\n",
271 __func__, seqno, dev->cmds[seqno].signalled);
272
273 /* Wait for signalled to be flagged or timeout */
274 /* In a highly stressed system this can easily extend
275 * into multiple seconds before the deferred worker
276 * is scheduled, and we're woken up via signal.
277 * We typically are signalled in < 50ms but it can
278 * take MUCH longer.
279 */
280 wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
281 r = time_before(jiffies, stamp + (HZ * waitsecs));
282 if (r)
283 ret = SAA_OK;
284 else
285 saa7164_cmd_timeout_seqno(dev, seqno);
286
287 dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
288 "(signalled=%d)\n", __func__, seqno, r,
289 dev->cmds[seqno].signalled);
290 } else
291 ret = SAA_OK;
292 } else
293 printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
294 __func__, seqno);
295
296 return ret;
297}
298
299void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
300{
301 int i;
302 dprintk(DBGLVL_CMD, "%s()\n", __func__);
303
304 mutex_lock(&dev->lock);
305 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
306 if (dev->cmds[i].inuse == 1) {
307 dprintk(DBGLVL_CMD,
308 "seqno %d inuse, sig = %d, t/out = %d\n",
309 dev->cmds[i].seqno,
310 dev->cmds[i].signalled,
311 dev->cmds[i].timeout);
312 }
313 }
314
315 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
316 if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
317 (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
318 dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
319 __func__, i);
320 dev->cmds[i].signalled = 1;
321 wake_up(&dev->cmds[i].wait);
322 }
323 }
324 mutex_unlock(&dev->lock);
325}
326
327int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
328 u16 controlselector, u16 size, void *buf)
329{
330 tmComResInfo_t command_t, *pcommand_t;
331 tmComResInfo_t response_t, *presponse_t;
332 u8 errdata[256];
333 u16 resp_dsize;
334 u16 data_recd;
335 u32 loop;
336 int ret;
337 int safety = 0;
338
339 dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
340 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
341 command, controlselector);
342
343 if ((size == 0) || (buf == 0)) {
344 printk(KERN_ERR "%s() Invalid param\n", __func__);
345 return SAA_ERR_BAD_PARAMETER;
346 }
347
348 /* Prepare some basic command/response structures */
349 memset(&command_t, 0, sizeof(command_t));
350 memset(&response_t, 0, sizeof(&response_t));
351 pcommand_t = &command_t;
352 presponse_t = &response_t;
353 command_t.id = id;
354 command_t.command = command;
355 command_t.controlselector = controlselector;
356 command_t.size = size;
357
358 /* Allocate a unique sequence number */
359 ret = saa7164_cmd_alloc_seqno(dev);
360 if (ret < 0) {
361 printk(KERN_ERR "%s() No free sequences\n", __func__);
362 ret = SAA_ERR_NO_RESOURCES;
363 goto out;
364 }
365
366 command_t.seqno = (u8)ret;
367
368 /* Send Command */
369 resp_dsize = size;
370 pcommand_t->size = size;
371
372 dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
373 __func__, pcommand_t->seqno);
374
375 dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
376 __func__, pcommand_t->size);
377
378 ret = saa7164_cmd_set(dev, pcommand_t, buf);
379 if (ret != SAA_OK) {
380 printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
381
382 if (ret != SAA_ERR_BUSY)
383 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
384 else
385 /* Flag a timeout, because at least one
386 * command was sent */
387 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
388
389 goto out;
390 }
391
392 /* With split responses we have to collect the msgs piece by piece */
393 data_recd = 0;
394 loop = 1;
395 while (loop) {
396 dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
397
398 ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
399 dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
400
401 /* if power is down and this is not a power command ... */
402
403 if (ret == SAA_BUS_TIMEOUT) {
404 printk(KERN_ERR "Event timed out\n");
405 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
406 return ret;
407 }
408
409 if (ret != SAA_OK) {
410 printk(KERN_ERR "spurious error\n");
411 return ret;
412 }
413
414 /* Peek response */
415 ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
416 if (ret == SAA_ERR_EMPTY) {
417 dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
418 continue;
419 }
420 if (ret != SAA_OK) {
421 printk(KERN_ERR "peek failed\n");
422 return ret;
423 }
424
425 dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
426 __func__, presponse_t->seqno);
427
428 dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
429 __func__, presponse_t->flags);
430
431 dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
432 __func__, presponse_t->size);
433
434 /* Check if the response was for our command */
435 if (presponse_t->seqno != pcommand_t->seqno) {
436
437 dprintk(DBGLVL_CMD,
438 "wrong event: seqno = %d, "
439 "expected seqno = %d, "
440 "will dequeue regardless\n",
441 presponse_t->seqno, pcommand_t->seqno);
442
443 ret = saa7164_cmd_dequeue(dev);
444 if (ret != SAA_OK) {
445 printk(KERN_ERR "dequeue failed, ret = %d\n",
446 ret);
447 if (safety++ > 16) {
448 printk(KERN_ERR
449 "dequeue exceeded, safety exit\n");
450 return SAA_ERR_BUSY;
451 }
452 }
453
454 continue;
455 }
456
457 if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
458
459 memset(&errdata[0], 0, sizeof(errdata));
460
461 ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
462 if (ret != SAA_OK) {
463 printk(KERN_ERR "get error(2)\n");
464 return ret;
465 }
466
467 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
468
469 dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
470 __func__, errdata[0], errdata[1], errdata[2],
471 errdata[3]);
472
473 /* Map error codes */
474 dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
475 __func__, errdata[0]);
476
477 switch (errdata[0]) {
478 case PVC_ERRORCODE_INVALID_COMMAND:
479 dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
480 __func__);
481 ret = SAA_ERR_INVALID_COMMAND;
482 break;
483 case PVC_ERRORCODE_INVALID_DATA:
484 dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
485 __func__);
486 ret = SAA_ERR_BAD_PARAMETER;
487 break;
488 case PVC_ERRORCODE_TIMEOUT:
489 dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
490 ret = SAA_ERR_TIMEOUT;
491 break;
492 case PVC_ERRORCODE_NAK:
493 dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
494 ret = SAA_ERR_NULL_PACKET;
495 break;
496 case PVC_ERRORCODE_UNKNOWN:
497 case PVC_ERRORCODE_INVALID_CONTROL:
498 dprintk(DBGLVL_CMD,
499 "%s() UNKNOWN OR INVALID CONTROL\n",
500 __func__);
501 default:
502 dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
503 ret = SAA_ERR_NOT_SUPPORTED;
504 }
505
506 /* See of other commands are on the bus */
507 if (saa7164_cmd_dequeue(dev) != SAA_OK)
508 printk(KERN_ERR "dequeue(2) failed\n");
509
510 return ret;
511 }
512
513 /* If response is invalid */
514 if ((presponse_t->id != pcommand_t->id) ||
515 (presponse_t->command != pcommand_t->command) ||
516 (presponse_t->controlselector !=
517 pcommand_t->controlselector) ||
518 (((resp_dsize - data_recd) != presponse_t->size) &&
519 !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
520 ((resp_dsize - data_recd) < presponse_t->size)) {
521
522 /* Invalid */
523 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
524 ret = saa7164_bus_get(dev, presponse_t, 0, 0);
525 if (ret != SAA_OK) {
526 printk(KERN_ERR "get failed\n");
527 return ret;
528 }
529
530 /* See of other commands are on the bus */
531 if (saa7164_cmd_dequeue(dev) != SAA_OK)
532 printk(KERN_ERR "dequeue(3) failed\n");
533 continue;
534 }
535
536 /* OK, now we're actually getting out correct response */
537 ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
538 if (ret != SAA_OK) {
539 printk(KERN_ERR "get failed\n");
540 return ret;
541 }
542
543 data_recd = presponse_t->size + data_recd;
544 if (resp_dsize == data_recd) {
545 dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
546 break;
547 }
548
549 /* See of other commands are on the bus */
550 if (saa7164_cmd_dequeue(dev) != SAA_OK)
551 printk(KERN_ERR "dequeue(3) failed\n");
552
553 continue;
554
555 } /* (loop) */
556
557 /* Release the sequence number allocation */
558 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
559
560 /* if powerdown signal all pending commands */
561
562 dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
563
564 /* See of other commands are on the bus */
565 if (saa7164_cmd_dequeue(dev) != SAA_OK)
566 printk(KERN_ERR "dequeue(4) failed\n");
567
568 ret = SAA_OK;
569out:
570 return ret;
571}
572
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
new file mode 100644
index 000000000000..f0dbead188c8
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -0,0 +1,740 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kmod.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <asm/div64.h>
32
33#include "saa7164.h"
34
35MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
36MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
37MODULE_LICENSE("GPL");
38
39/*
40 1 Basic
41 2
42 4 i2c
43 8 api
44 16 cmd
45 32 bus
46 */
47
48unsigned int debug;
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "enable debug messages");
51
52unsigned int waitsecs = 10;
53module_param(waitsecs, int, 0644);
54MODULE_PARM_DESC(debug, "timeout on firmware messages");
55
56static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card, "card type");
59
60static unsigned int saa7164_devcount;
61
62static DEFINE_MUTEX(devlist);
63LIST_HEAD(saa7164_devlist);
64
65#define INT_SIZE 16
66
67static void saa7164_work_cmdhandler(struct work_struct *w)
68{
69 struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
70
71 /* Wake up any complete commands */
72 saa7164_irq_dequeue(dev);
73}
74
75static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
76{
77 struct saa7164_tsport *port = buf->port;
78
79 /* Feed the transport payload into the kernel demux */
80 dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
81 SAA7164_TS_NUMBER_OF_LINES);
82
83}
84
85static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
86{
87 struct saa7164_dev *dev = port->dev;
88 struct saa7164_buffer *buf;
89 struct list_head *c, *n;
90 int wp, i = 0, rp;
91
92 /* Find the current write point from the hardware */
93 wp = saa7164_readl(port->bufcounter);
94 if (wp > (port->hwcfg.buffercount - 1))
95 BUG();
96
97 /* Find the previous buffer to the current write point */
98 if (wp == 0)
99 rp = 7;
100 else
101 rp = wp - 1;
102
103 /* Lookup the WP in the buffer list */
104 /* TODO: turn this into a worker thread */
105 list_for_each_safe(c, n, &port->dmaqueue.list) {
106 buf = list_entry(c, struct saa7164_buffer, list);
107 if (i++ > port->hwcfg.buffercount)
108 BUG();
109
110 if (buf->nr == rp) {
111 /* Found the buffer, deal with it */
112 dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
113 __func__, wp, rp);
114 saa7164_buffer_deliver(buf);
115 break;
116 }
117
118 }
119 return 0;
120}
121
122/* Primary IRQ handler and dispatch mechanism */
123static irqreturn_t saa7164_irq(int irq, void *dev_id)
124{
125 struct saa7164_dev *dev = dev_id;
126 u32 intid, intstat[INT_SIZE/4];
127 int i, handled = 0, bit;
128
129 if (dev == 0) {
130 printk(KERN_ERR "%s() No device specified\n", __func__);
131 handled = 0;
132 goto out;
133 }
134
135 /* Check that the hardware is accessable. If the status bytes are
136 * 0xFF then the device is not accessable, the the IRQ belongs
137 * to another driver.
138 * 4 x u32 interrupt registers.
139 */
140 for (i = 0; i < INT_SIZE/4; i++) {
141
142 /* TODO: Convert into saa7164_readl() */
143 /* Read the 4 hardware interrupt registers */
144 intstat[i] = saa7164_readl(dev->int_status + (i * 4));
145
146 if (intstat[i])
147 handled = 1;
148 }
149 if (handled == 0)
150 goto out;
151
152 /* For each of the HW interrupt registers */
153 for (i = 0; i < INT_SIZE/4; i++) {
154
155 if (intstat[i]) {
156 /* Each function of the board has it's own interruptid.
157 * Find the function that triggered then call
158 * it's handler.
159 */
160 for (bit = 0; bit < 32; bit++) {
161
162 if (((intstat[i] >> bit) & 0x00000001) == 0)
163 continue;
164
165 /* Calculate the interrupt id (0x00 to 0x7f) */
166
167 intid = (i * 32) + bit;
168 if (intid == dev->intfdesc.bInterruptId) {
169 /* A response to an cmd/api call */
170 schedule_work(&dev->workcmd);
171 } else if (intid ==
172 dev->ts1.hwcfg.interruptid) {
173
174 /* Transport path 1 */
175 saa7164_irq_ts(&dev->ts1);
176
177 } else if (intid ==
178 dev->ts2.hwcfg.interruptid) {
179
180 /* Transport path 2 */
181 saa7164_irq_ts(&dev->ts2);
182
183 } else {
184 /* Find the function */
185 dprintk(DBGLVL_IRQ,
186 "%s() unhandled interrupt "
187 "reg 0x%x bit 0x%x "
188 "intid = 0x%x\n",
189 __func__, i, bit, intid);
190 }
191 }
192
193 /* Ack it */
194 saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
195
196 }
197 }
198out:
199 return IRQ_RETVAL(handled);
200}
201
202void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
203{
204 struct saa7164_fw_status *s = &dev->fw_status;
205
206 dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
207 dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
208 dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
209 dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
210 dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
211 dev->fw_status.remainheap =
212 saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
213
214 dprintk(1, "Firmware status:\n");
215 dprintk(1, " .status = 0x%08x\n", s->status);
216 dprintk(1, " .mode = 0x%08x\n", s->mode);
217 dprintk(1, " .spec = 0x%08x\n", s->spec);
218 dprintk(1, " .inst = 0x%08x\n", s->inst);
219 dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
220 dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
221}
222
223u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
224{
225 u32 reg;
226
227 reg = saa7164_readl(SAA_DEVICE_VERSION);
228 dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
229 (reg & 0x0000fc00) >> 10,
230 (reg & 0x000003e0) >> 5,
231 (reg & 0x0000001f),
232 (reg & 0xffff0000) >> 16,
233 reg);
234
235 return reg;
236}
237
238/* TODO: Debugging func, remove */
239void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
240{
241 int i;
242
243 printk(KERN_INFO "--------------------> "
244 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
245
246 for (i = 0; i < len; i += 16)
247 printk(KERN_INFO " [0x%08x] "
248 "%02x %02x %02x %02x %02x %02x %02x %02x "
249 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
250 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
251 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
252 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
253 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
254}
255
256/* TODO: Debugging func, remove */
257void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
258{
259 int i;
260
261 dprintk(1, "--------------------> "
262 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
263
264 for (i = 0; i < 0x100; i += 16)
265 dprintk(1, "region0[0x%08x] = "
266 "%02x %02x %02x %02x %02x %02x %02x %02x"
267 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
268 (u8)saa7164_readb(addr + i + 0),
269 (u8)saa7164_readb(addr + i + 1),
270 (u8)saa7164_readb(addr + i + 2),
271 (u8)saa7164_readb(addr + i + 3),
272 (u8)saa7164_readb(addr + i + 4),
273 (u8)saa7164_readb(addr + i + 5),
274 (u8)saa7164_readb(addr + i + 6),
275 (u8)saa7164_readb(addr + i + 7),
276 (u8)saa7164_readb(addr + i + 8),
277 (u8)saa7164_readb(addr + i + 9),
278 (u8)saa7164_readb(addr + i + 10),
279 (u8)saa7164_readb(addr + i + 11),
280 (u8)saa7164_readb(addr + i + 12),
281 (u8)saa7164_readb(addr + i + 13),
282 (u8)saa7164_readb(addr + i + 14),
283 (u8)saa7164_readb(addr + i + 15)
284 );
285}
286
287static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
288{
289 dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
290 &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
291
292 dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
293 dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
294 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
295 dev->hwdesc.bDescriptorSubtype);
296
297 dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
298 dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
299 dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
300 dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
301 dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
302 dev->hwdesc.dwDeviceRegistersLocation);
303
304 dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
305 dev->hwdesc.dwHostMemoryRegion);
306
307 dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
308 dev->hwdesc.dwHostMemoryRegionSize);
309
310 dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
311 dev->hwdesc.dwHostHibernatMemRegion);
312
313 dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
314 dev->hwdesc.dwHostHibernatMemRegionSize);
315}
316
317static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
318{
319 dprintk(1, "@0x%p intfdesc "
320 "sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
321 &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
322
323 dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
324 dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
325 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
326 dev->intfdesc.bDescriptorSubtype);
327
328 dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
329 dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
330 dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
331 dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
332 dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
333 dprintk(1, " .bDebugInterruptId = 0x%x\n",
334 dev->intfdesc.bDebugInterruptId);
335
336 dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
337}
338
339static void saa7164_dump_busdesc(struct saa7164_dev *dev)
340{
341 dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
342 &dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
343
344 dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
345 dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
346 dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
347 dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
348 dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
349 dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
350}
351
352/* Much of the hardware configuration and PCI registers are configured
353 * dynamically depending on firmware. We have to cache some initial
354 * structures then use these to locate other important structures
355 * from PCI space.
356 */
357static void saa7164_get_descriptors(struct saa7164_dev *dev)
358{
359 memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
360 memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
361 sizeof(tmComResInterfaceDescr_t));
362 memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
363 sizeof(tmComResBusDescr_t));
364
365 if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
366 printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
367 printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
368 (u32)sizeof(tmComResHWDescr_t));
369 } else
370 saa7164_dump_hwdesc(dev);
371
372 if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
373 printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
374 printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
375 (u32)sizeof(tmComResInterfaceDescr_t));
376 } else
377 saa7164_dump_intfdesc(dev);
378
379 saa7164_dump_busdesc(dev);
380}
381
382static int saa7164_pci_quirks(struct saa7164_dev *dev)
383{
384 return 0;
385}
386
387static int get_resources(struct saa7164_dev *dev)
388{
389 if (request_mem_region(pci_resource_start(dev->pci, 0),
390 pci_resource_len(dev->pci, 0), dev->name)) {
391
392 if (request_mem_region(pci_resource_start(dev->pci, 2),
393 pci_resource_len(dev->pci, 2), dev->name))
394 return 0;
395 }
396
397 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
398 dev->name,
399 (u64)pci_resource_start(dev->pci, 0),
400 (u64)pci_resource_start(dev->pci, 2));
401
402 return -EBUSY;
403}
404
405static int saa7164_dev_setup(struct saa7164_dev *dev)
406{
407 int i;
408
409 mutex_init(&dev->lock);
410 atomic_inc(&dev->refcount);
411 dev->nr = saa7164_devcount++;
412
413 sprintf(dev->name, "saa7164[%d]", dev->nr);
414
415 mutex_lock(&devlist);
416 list_add_tail(&dev->devlist, &saa7164_devlist);
417 mutex_unlock(&devlist);
418
419 /* board config */
420 dev->board = UNSET;
421 if (card[dev->nr] < saa7164_bcount)
422 dev->board = card[dev->nr];
423
424 for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
425 if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
426 dev->pci->subsystem_device ==
427 saa7164_subids[i].subdevice)
428 dev->board = saa7164_subids[i].card;
429
430 if (UNSET == dev->board) {
431 dev->board = SAA7164_BOARD_UNKNOWN;
432 saa7164_card_list(dev);
433 }
434
435 dev->pci_bus = dev->pci->bus->number;
436 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
437
438 /* I2C Defaults / setup */
439 dev->i2c_bus[0].dev = dev;
440 dev->i2c_bus[0].nr = 0;
441 dev->i2c_bus[1].dev = dev;
442 dev->i2c_bus[1].nr = 1;
443 dev->i2c_bus[2].dev = dev;
444 dev->i2c_bus[2].nr = 2;
445
446 /* Transport port A Defaults / setup */
447 dev->ts1.dev = dev;
448 dev->ts1.nr = 0;
449 mutex_init(&dev->ts1.dvb.lock);
450 INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
451 INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
452 mutex_init(&dev->ts1.dmaqueue_lock);
453 mutex_init(&dev->ts1.dummy_dmaqueue_lock);
454
455 /* Transport port B Defaults / setup */
456 dev->ts2.dev = dev;
457 dev->ts2.nr = 1;
458 mutex_init(&dev->ts2.dvb.lock);
459 INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
460 INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
461 mutex_init(&dev->ts2.dmaqueue_lock);
462 mutex_init(&dev->ts2.dummy_dmaqueue_lock);
463
464 if (get_resources(dev) < 0) {
465 printk(KERN_ERR "CORE %s No more PCIe resources for "
466 "subsystem: %04x:%04x\n",
467 dev->name, dev->pci->subsystem_vendor,
468 dev->pci->subsystem_device);
469
470 saa7164_devcount--;
471 return -ENODEV;
472 }
473
474 /* PCI/e allocations */
475 dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
476 pci_resource_len(dev->pci, 0));
477
478 dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
479 pci_resource_len(dev->pci, 2));
480
481 dev->bmmio = (u8 __iomem *)dev->lmmio;
482 dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
483
484 /* Inerrupt and ack register locations offset of bmmio */
485 dev->int_status = 0x183000 + 0xf80;
486 dev->int_ack = 0x183000 + 0xf90;
487
488 printk(KERN_INFO
489 "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
490 dev->name, dev->pci->subsystem_vendor,
491 dev->pci->subsystem_device, saa7164_boards[dev->board].name,
492 dev->board, card[dev->nr] == dev->board ?
493 "insmod option" : "autodetected");
494
495 saa7164_pci_quirks(dev);
496
497 return 0;
498}
499
500static void saa7164_dev_unregister(struct saa7164_dev *dev)
501{
502 dprintk(1, "%s()\n", __func__);
503
504 release_mem_region(pci_resource_start(dev->pci, 0),
505 pci_resource_len(dev->pci, 0));
506
507 release_mem_region(pci_resource_start(dev->pci, 2),
508 pci_resource_len(dev->pci, 2));
509
510 if (!atomic_dec_and_test(&dev->refcount))
511 return;
512
513 iounmap(dev->lmmio);
514 iounmap(dev->lmmio2);
515
516 return;
517}
518
519static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
520 const struct pci_device_id *pci_id)
521{
522 struct saa7164_dev *dev;
523 int err, i;
524 u32 version;
525
526 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
527 if (NULL == dev)
528 return -ENOMEM;
529
530 /* pci init */
531 dev->pci = pci_dev;
532 if (pci_enable_device(pci_dev)) {
533 err = -EIO;
534 goto fail_free;
535 }
536
537 if (saa7164_dev_setup(dev) < 0) {
538 err = -EINVAL;
539 goto fail_free;
540 }
541
542 /* print pci info */
543 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
544 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
545 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
546 "latency: %d, mmio: 0x%llx\n", dev->name,
547 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
548 dev->pci_lat,
549 (unsigned long long)pci_resource_start(pci_dev, 0));
550
551 pci_set_master(pci_dev);
552 /* TODO */
553 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
554 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
555 err = -EIO;
556 goto fail_irq;
557 }
558
559 err = request_irq(pci_dev->irq, saa7164_irq,
560 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
561 if (err < 0) {
562 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
563 pci_dev->irq);
564 err = -EIO;
565 goto fail_irq;
566 }
567
568 pci_set_drvdata(pci_dev, dev);
569
570 /* Init the internal command list */
571 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
572 dev->cmds[i].seqno = i;
573 dev->cmds[i].inuse = 0;
574 mutex_init(&dev->cmds[i].lock);
575 init_waitqueue_head(&dev->cmds[i].wait);
576 }
577
578 /* We need a deferred interrupt handler for cmd handling */
579 INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
580
581 /* Only load the firmware if we know the board */
582 if (dev->board != SAA7164_BOARD_UNKNOWN) {
583
584 err = saa7164_downloadfirmware(dev);
585 if (err < 0) {
586 printk(KERN_ERR
587 "Failed to boot firmware, no features "
588 "registered\n");
589 goto fail_fw;
590 }
591
592 saa7164_get_descriptors(dev);
593 saa7164_dumpregs(dev, 0);
594 saa7164_getcurrentfirmwareversion(dev);
595 saa7164_getfirmwarestatus(dev);
596 err = saa7164_bus_setup(dev);
597 if (err < 0)
598 printk(KERN_ERR
599 "Failed to setup the bus, will continue\n");
600 saa7164_bus_dump(dev);
601
602 /* Ping the running firmware via the command bus and get the
603 * firmware version, this checks the bus is running OK.
604 */
605 version = 0;
606 if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
607 dprintk(1, "Bus is operating correctly using "
608 "version %d.%d.%d.%d (0x%x)\n",
609 (version & 0x0000fc00) >> 10,
610 (version & 0x000003e0) >> 5,
611 (version & 0x0000001f),
612 (version & 0xffff0000) >> 16,
613 version);
614 else
615 printk(KERN_ERR
616 "Failed to communicate with the firmware\n");
617
618 /* Bring up the I2C buses */
619 saa7164_i2c_register(&dev->i2c_bus[0]);
620 saa7164_i2c_register(&dev->i2c_bus[1]);
621 saa7164_i2c_register(&dev->i2c_bus[2]);
622 saa7164_gpio_setup(dev);
623 saa7164_card_setup(dev);
624
625
626 /* Parse the dynamic device configuration, find various
627 * media endpoints (MPEG, WMV, PS, TS) and cache their
628 * configuration details into the driver, so we can
629 * reference them later during simething_register() func,
630 * interrupt handlers, deferred work handlers etc.
631 */
632 saa7164_api_enum_subdevs(dev);
633
634 /* Begin to create the video sub-systems and register funcs */
635 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
636 if (saa7164_dvb_register(&dev->ts1) < 0) {
637 printk(KERN_ERR "%s() Failed to register "
638 "dvb adapters on porta\n",
639 __func__);
640 }
641 }
642
643 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
644 if (saa7164_dvb_register(&dev->ts2) < 0) {
645 printk(KERN_ERR"%s() Failed to register "
646 "dvb adapters on portb\n",
647 __func__);
648 }
649 }
650
651 } /* != BOARD_UNKNOWN */
652 else
653 printk(KERN_ERR "%s() Unsupported board detected, "
654 "registering without firmware\n", __func__);
655
656 dprintk(1, "%s() parameter debug = %d\n", __func__, debug);
657 dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
658
659fail_fw:
660 return 0;
661
662fail_irq:
663 saa7164_dev_unregister(dev);
664fail_free:
665 kfree(dev);
666 return err;
667}
668
669static void saa7164_shutdown(struct saa7164_dev *dev)
670{
671 dprintk(1, "%s()\n", __func__);
672}
673
674static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
675{
676 struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
677
678 saa7164_shutdown(dev);
679
680 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
681 saa7164_dvb_unregister(&dev->ts1);
682
683 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
684 saa7164_dvb_unregister(&dev->ts2);
685
686 saa7164_i2c_unregister(&dev->i2c_bus[0]);
687 saa7164_i2c_unregister(&dev->i2c_bus[1]);
688 saa7164_i2c_unregister(&dev->i2c_bus[2]);
689
690 pci_disable_device(pci_dev);
691
692 /* unregister stuff */
693 free_irq(pci_dev->irq, dev);
694 pci_set_drvdata(pci_dev, NULL);
695
696 mutex_lock(&devlist);
697 list_del(&dev->devlist);
698 mutex_unlock(&devlist);
699
700 saa7164_dev_unregister(dev);
701 kfree(dev);
702}
703
704static struct pci_device_id saa7164_pci_tbl[] = {
705 {
706 /* SAA7164 */
707 .vendor = 0x1131,
708 .device = 0x7164,
709 .subvendor = PCI_ANY_ID,
710 .subdevice = PCI_ANY_ID,
711 }, {
712 /* --- end of list --- */
713 }
714};
715MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
716
717static struct pci_driver saa7164_pci_driver = {
718 .name = "saa7164",
719 .id_table = saa7164_pci_tbl,
720 .probe = saa7164_initdev,
721 .remove = __devexit_p(saa7164_finidev),
722 /* TODO */
723 .suspend = NULL,
724 .resume = NULL,
725};
726
727static int saa7164_init(void)
728{
729 printk(KERN_INFO "saa7164 driver loaded\n");
730 return pci_register_driver(&saa7164_pci_driver);
731}
732
733static void saa7164_fini(void)
734{
735 pci_unregister_driver(&saa7164_pci_driver);
736}
737
738module_init(saa7164_init);
739module_exit(saa7164_fini);
740
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
new file mode 100644
index 000000000000..6a2d847d6a88
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -0,0 +1,602 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24#include "tda10048.h"
25#include "tda18271.h"
26#include "s5h1411.h"
27
28#define DRIVER_NAME "saa7164"
29
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32/* addr is in the card struct, get it from there */
33static struct tda10048_config hauppauge_hvr2200_1_config = {
34 .demod_address = 0x10 >> 1,
35 .output_mode = TDA10048_SERIAL_OUTPUT,
36 .fwbulkwritelen = TDA10048_BULKWRITE_200,
37 .inversion = TDA10048_INVERSION_ON,
38 .dtv6_if_freq_khz = TDA10048_IF_3300,
39 .dtv7_if_freq_khz = TDA10048_IF_3500,
40 .dtv8_if_freq_khz = TDA10048_IF_4000,
41 .clk_freq_khz = TDA10048_CLK_16000,
42};
43static struct tda10048_config hauppauge_hvr2200_2_config = {
44 .demod_address = 0x12 >> 1,
45 .output_mode = TDA10048_SERIAL_OUTPUT,
46 .fwbulkwritelen = TDA10048_BULKWRITE_200,
47 .inversion = TDA10048_INVERSION_ON,
48 .dtv6_if_freq_khz = TDA10048_IF_3300,
49 .dtv7_if_freq_khz = TDA10048_IF_3500,
50 .dtv8_if_freq_khz = TDA10048_IF_4000,
51 .clk_freq_khz = TDA10048_CLK_16000,
52};
53
54static struct tda18271_std_map hauppauge_tda18271_std_map = {
55 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
56 .if_lvl = 6, .rfagc_top = 0x37 },
57 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
58 .if_lvl = 6, .rfagc_top = 0x37 },
59};
60
61static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
62 .std_map = &hauppauge_tda18271_std_map,
63 .gate = TDA18271_GATE_ANALOG,
64 .role = TDA18271_MASTER,
65};
66
67static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
68 .std_map = &hauppauge_tda18271_std_map,
69 .gate = TDA18271_GATE_ANALOG,
70 .role = TDA18271_SLAVE,
71 .rf_cal_on_startup = 1
72};
73
74static struct s5h1411_config hauppauge_s5h1411_config = {
75 .output_mode = S5H1411_SERIAL_OUTPUT,
76 .gpio = S5H1411_GPIO_ON,
77 .qam_if = S5H1411_IF_4000,
78 .vsb_if = S5H1411_IF_3250,
79 .inversion = S5H1411_INVERSION_ON,
80 .status_mode = S5H1411_DEMODLOCKING,
81 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
82};
83
84static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
85{
86 struct saa7164_dev *dev = port->dev;
87 int ret;
88
89 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
90 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
91 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
92 __func__, ret);
93 ret = -EIO;
94 } else {
95 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
96 ret = 0;
97 }
98
99 return ret;
100}
101
102static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
103{
104 struct saa7164_dev *dev = port->dev;
105 int ret;
106
107 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
108 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
109 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
110 __func__, ret);
111 ret = -EIO;
112 } else {
113 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
114 ret = 0;
115 }
116
117 return ret;
118}
119
120static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
121{
122 struct saa7164_dev *dev = port->dev;
123 int ret;
124
125 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
126 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
127 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
128 __func__, ret);
129 ret = -EIO;
130 } else {
131 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
132 ret = 0;
133 }
134
135 return ret;
136}
137
138/* Firmware is very windows centric, meaning you have to transition
139 * the part through AVStream / KS Windows stages, forwards or backwards.
140 * States are: stopped, acquired (h/w), paused, started.
141 */
142static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
143{
144 struct saa7164_dev *dev = port->dev;
145 int ret;
146
147 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
148
149 ret = saa7164_dvb_pause_tsport(port);
150 ret = saa7164_dvb_acquire_tsport(port);
151 ret = saa7164_dvb_stop_tsport(port);
152
153 return ret;
154}
155
156static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
157{
158 tmHWStreamParameters_t *params = &port->hw_streamingparams;
159 struct saa7164_dev *dev = port->dev;
160 struct saa7164_buffer *buf;
161 struct list_head *c, *n;
162 int i = 0;
163
164 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
165
166 saa7164_writel(port->pitch, params->pitch);
167 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
168
169 dprintk(DBGLVL_DVB, " configured:\n");
170 dprintk(DBGLVL_DVB, " lmmio 0x%p\n", dev->lmmio);
171 dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
172 saa7164_readl(port->bufcounter));
173
174 dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch,
175 saa7164_readl(port->pitch));
176
177 dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize,
178 saa7164_readl(port->bufsize));
179
180 dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount);
181 dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset);
182 dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h);
183 dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l);
184
185 /* Poke the buffers and offsets into PCI space */
186 mutex_lock(&port->dmaqueue_lock);
187 list_for_each_safe(c, n, &port->dmaqueue.list) {
188 buf = list_entry(c, struct saa7164_buffer, list);
189
190 /* TODO: Review this in light of 32v64 assignments */
191 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
192 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
193 buf->pt_dma);
194 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
195
196 dprintk(DBGLVL_DVB,
197 " buf[%d] offset 0x%llx (0x%x) "
198 "buf 0x%llx/%llx (0x%x/%x)\n",
199 i,
200 (u64)port->bufoffset + (i * sizeof(u32)),
201 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
202 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
203 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
204 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
205 * 2)),
206 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
207 * 2)));
208
209 if (i++ > port->hwcfg.buffercount)
210 BUG();
211
212 }
213 mutex_unlock(&port->dmaqueue_lock);
214
215 return 0;
216}
217
218static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
219{
220 struct saa7164_dev *dev = port->dev;
221 int ret = 0, result;
222
223 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
224
225 saa7164_dvb_cfg_tsport(port);
226
227 /* Acquire the hardware */
228 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
229 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
230 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
231 __func__, result);
232
233 /* Stop the hardware, regardless */
234 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
235 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
236 printk(KERN_ERR "%s() acquire/forced stop transition "
237 "failed, res = 0x%x\n", __func__, result);
238 }
239 ret = -EIO;
240 goto out;
241 } else
242 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
243
244 /* Pause the hardware */
245 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
246 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
247 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
248 __func__, result);
249
250 /* Stop the hardware, regardless */
251 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
252 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
253 printk(KERN_ERR "%s() pause/forced stop transition "
254 "failed, res = 0x%x\n", __func__, result);
255 }
256
257 ret = -EIO;
258 goto out;
259 } else
260 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
261
262 /* Start the hardware */
263 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
264 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
265 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
266 __func__, result);
267
268 /* Stop the hardware, regardless */
269 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
270 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
271 printk(KERN_ERR "%s() run/forced stop transition "
272 "failed, res = 0x%x\n", __func__, result);
273 }
274
275 ret = -EIO;
276 } else
277 dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
278
279out:
280 return ret;
281}
282
283static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
284{
285 struct dvb_demux *demux = feed->demux;
286 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
287 struct saa7164_dvb *dvb = &port->dvb;
288 struct saa7164_dev *dev = port->dev;
289 int ret = 0;
290
291 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
292
293 if (!demux->dmx.frontend)
294 return -EINVAL;
295
296 if (dvb) {
297 mutex_lock(&dvb->lock);
298 if (dvb->feeding++ == 0) {
299 /* Start transport */
300 ret = saa7164_dvb_start_tsport(port);
301 }
302 mutex_unlock(&dvb->lock);
303 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
304 __func__, port->nr, dvb->feeding);
305 }
306
307 return ret;
308}
309
310static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
311{
312 struct dvb_demux *demux = feed->demux;
313 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
314 struct saa7164_dvb *dvb = &port->dvb;
315 struct saa7164_dev *dev = port->dev;
316 int ret = 0;
317
318 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
319
320 if (dvb) {
321 mutex_lock(&dvb->lock);
322 if (--dvb->feeding == 0) {
323 /* Stop transport */
324 ret = saa7164_dvb_stop_streaming(port);
325 }
326 mutex_unlock(&dvb->lock);
327 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
328 __func__, port->nr, dvb->feeding);
329 }
330
331 return ret;
332}
333
334static int dvb_register(struct saa7164_tsport *port)
335{
336 struct saa7164_dvb *dvb = &port->dvb;
337 struct saa7164_dev *dev = port->dev;
338 struct saa7164_buffer *buf;
339 int result, i;
340
341 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
342
343 /* Sanity check that the PCI configuration space is active */
344 if (port->hwcfg.BARLocation == 0) {
345 result = -ENOMEM;
346 printk(KERN_ERR "%s: dvb_register_adapter failed "
347 "(errno = %d), NO PCI configuration\n",
348 DRIVER_NAME, result);
349 goto fail_adapter;
350 }
351
352 /* Init and establish defaults */
353 port->hw_streamingparams.bitspersample = 8;
354 port->hw_streamingparams.samplesperline = 188;
355 port->hw_streamingparams.numberoflines =
356 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
357
358 port->hw_streamingparams.pitch = 188;
359 port->hw_streamingparams.linethreshold = 0;
360 port->hw_streamingparams.pagetablelistvirt = 0;
361 port->hw_streamingparams.pagetablelistphys = 0;
362 port->hw_streamingparams.numpagetables = 2 +
363 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
364
365 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
366
367 /* Allocate the PCI resources */
368 for (i = 0; i < port->hwcfg.buffercount; i++) {
369 buf = saa7164_buffer_alloc(port,
370 port->hw_streamingparams.numberoflines *
371 port->hw_streamingparams.pitch);
372
373 if (!buf) {
374 result = -ENOMEM;
375 printk(KERN_ERR "%s: dvb_register_adapter failed "
376 "(errno = %d), unable to allocate buffers\n",
377 DRIVER_NAME, result);
378 goto fail_adapter;
379 }
380 buf->nr = i;
381
382 mutex_lock(&port->dmaqueue_lock);
383 list_add_tail(&buf->list, &port->dmaqueue.list);
384 mutex_unlock(&port->dmaqueue_lock);
385 }
386
387 /* register adapter */
388 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
389 &dev->pci->dev, adapter_nr);
390 if (result < 0) {
391 printk(KERN_ERR "%s: dvb_register_adapter failed "
392 "(errno = %d)\n", DRIVER_NAME, result);
393 goto fail_adapter;
394 }
395 dvb->adapter.priv = port;
396
397 /* register frontend */
398 result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
399 if (result < 0) {
400 printk(KERN_ERR "%s: dvb_register_frontend failed "
401 "(errno = %d)\n", DRIVER_NAME, result);
402 goto fail_frontend;
403 }
404
405 /* register demux stuff */
406 dvb->demux.dmx.capabilities =
407 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
408 DMX_MEMORY_BASED_FILTERING;
409 dvb->demux.priv = port;
410 dvb->demux.filternum = 256;
411 dvb->demux.feednum = 256;
412 dvb->demux.start_feed = saa7164_dvb_start_feed;
413 dvb->demux.stop_feed = saa7164_dvb_stop_feed;
414 result = dvb_dmx_init(&dvb->demux);
415 if (result < 0) {
416 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
417 DRIVER_NAME, result);
418 goto fail_dmx;
419 }
420
421 dvb->dmxdev.filternum = 256;
422 dvb->dmxdev.demux = &dvb->demux.dmx;
423 dvb->dmxdev.capabilities = 0;
424 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
425 if (result < 0) {
426 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
427 DRIVER_NAME, result);
428 goto fail_dmxdev;
429 }
430
431 dvb->fe_hw.source = DMX_FRONTEND_0;
432 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
433 if (result < 0) {
434 printk(KERN_ERR "%s: add_frontend failed "
435 "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
436 goto fail_fe_hw;
437 }
438
439 dvb->fe_mem.source = DMX_MEMORY_FE;
440 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
441 if (result < 0) {
442 printk(KERN_ERR "%s: add_frontend failed "
443 "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
444 goto fail_fe_mem;
445 }
446
447 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
448 if (result < 0) {
449 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
450 DRIVER_NAME, result);
451 goto fail_fe_conn;
452 }
453
454 /* register network adapter */
455 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
456 return 0;
457
458fail_fe_conn:
459 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
460fail_fe_mem:
461 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
462fail_fe_hw:
463 dvb_dmxdev_release(&dvb->dmxdev);
464fail_dmxdev:
465 dvb_dmx_release(&dvb->demux);
466fail_dmx:
467 dvb_unregister_frontend(dvb->frontend);
468fail_frontend:
469 dvb_frontend_detach(dvb->frontend);
470 dvb_unregister_adapter(&dvb->adapter);
471fail_adapter:
472 return result;
473}
474
475int saa7164_dvb_unregister(struct saa7164_tsport *port)
476{
477 struct saa7164_dvb *dvb = &port->dvb;
478 struct saa7164_dev *dev = port->dev;
479 struct saa7164_buffer *b;
480 struct list_head *c, *n;
481
482 dprintk(DBGLVL_DVB, "%s()\n", __func__);
483
484 /* Remove any allocated buffers */
485 mutex_lock(&port->dmaqueue_lock);
486 list_for_each_safe(c, n, &port->dmaqueue.list) {
487 b = list_entry(c, struct saa7164_buffer, list);
488 list_del(c);
489 saa7164_buffer_dealloc(port, b);
490 }
491 mutex_unlock(&port->dmaqueue_lock);
492
493 if (dvb->frontend == NULL)
494 return 0;
495
496 dvb_net_release(&dvb->net);
497 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
498 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
499 dvb_dmxdev_release(&dvb->dmxdev);
500 dvb_dmx_release(&dvb->demux);
501 dvb_unregister_frontend(dvb->frontend);
502 dvb_frontend_detach(dvb->frontend);
503 dvb_unregister_adapter(&dvb->adapter);
504 return 0;
505}
506
507/* All the DVB attach calls go here, this function get's modified
508 * for each new card.
509 */
510int saa7164_dvb_register(struct saa7164_tsport *port)
511{
512 struct saa7164_dev *dev = port->dev;
513 struct saa7164_dvb *dvb = &port->dvb;
514 struct saa7164_i2c *i2c_bus = NULL;
515 int ret;
516
517 dprintk(DBGLVL_DVB, "%s()\n", __func__);
518
519 /* init frontend */
520 switch (dev->board) {
521 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
522 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
523 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
524 i2c_bus = &dev->i2c_bus[port->nr + 1];
525 switch (port->nr) {
526 case 0:
527 port->dvb.frontend = dvb_attach(tda10048_attach,
528 &hauppauge_hvr2200_1_config,
529 &i2c_bus->i2c_adap);
530
531 if (port->dvb.frontend != NULL) {
532 /* TODO: addr is in the card struct */
533 dvb_attach(tda18271_attach, port->dvb.frontend,
534 0xc0 >> 1, &i2c_bus->i2c_adap,
535 &hauppauge_hvr22x0_tuner_config);
536 }
537
538 break;
539 case 1:
540 port->dvb.frontend = dvb_attach(tda10048_attach,
541 &hauppauge_hvr2200_2_config,
542 &i2c_bus->i2c_adap);
543
544 if (port->dvb.frontend != NULL) {
545 /* TODO: addr is in the card struct */
546 dvb_attach(tda18271_attach, port->dvb.frontend,
547 0xc0 >> 1, &i2c_bus->i2c_adap,
548 &hauppauge_hvr22x0s_tuner_config);
549 }
550
551 break;
552 }
553 break;
554 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
555 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
556 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
557 i2c_bus = &dev->i2c_bus[port->nr + 1];
558
559 port->dvb.frontend = dvb_attach(s5h1411_attach,
560 &hauppauge_s5h1411_config,
561 &i2c_bus->i2c_adap);
562
563 if (port->dvb.frontend != NULL) {
564 if (port->nr == 0) {
565 /* Master TDA18271 */
566 /* TODO: addr is in the card struct */
567 dvb_attach(tda18271_attach, port->dvb.frontend,
568 0xc0 >> 1, &i2c_bus->i2c_adap,
569 &hauppauge_hvr22x0_tuner_config);
570 } else {
571 /* Slave TDA18271 */
572 dvb_attach(tda18271_attach, port->dvb.frontend,
573 0xc0 >> 1, &i2c_bus->i2c_adap,
574 &hauppauge_hvr22x0s_tuner_config);
575 }
576 }
577
578 break;
579 default:
580 printk(KERN_ERR "%s: The frontend isn't supported\n",
581 dev->name);
582 break;
583 }
584 if (NULL == dvb->frontend) {
585 printk(KERN_ERR "%s() Frontend initialization failed\n",
586 __func__);
587 return -1;
588 }
589
590 /* Put the analog decoder in standby to keep it quiet */
591
592 /* register everything */
593 ret = dvb_register(port);
594 if (ret < 0) {
595 if (dvb->frontend->ops.release)
596 dvb->frontend->ops.release(dvb->frontend);
597 return ret;
598 }
599
600 return 0;
601}
602
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
new file mode 100644
index 000000000000..ee0af3534ede
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -0,0 +1,613 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/firmware.h>
23
24#include "saa7164.h"
25
26#define SAA7164_REV2_FIRMWARE "v4l-saa7164-1.0.2.fw"
27#define SAA7164_REV2_FIRMWARE_SIZE 3978608
28
29#define SAA7164_REV3_FIRMWARE "v4l-saa7164-1.0.3.fw"
30#define SAA7164_REV3_FIRMWARE_SIZE 3978608
31
32struct fw_header {
33 u32 firmwaresize;
34 u32 bslsize;
35 u32 reserved;
36 u32 version;
37};
38
39int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
40{
41 u32 timeout = SAA_DEVICE_TIMEOUT;
42 while ((saa7164_readl(reg) & 0x01) == 0) {
43 timeout -= 10;
44 if (timeout == 0) {
45 printk(KERN_ERR "%s() timeout (no d/l ack)\n",
46 __func__);
47 return -EBUSY;
48 }
49 msleep(100);
50 }
51
52 return 0;
53}
54
55int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
56{
57 u32 timeout = SAA_DEVICE_TIMEOUT;
58 while (saa7164_readl(reg) & 0x01) {
59 timeout -= 10;
60 if (timeout == 0) {
61 printk(KERN_ERR "%s() timeout (no d/l clr)\n",
62 __func__);
63 return -EBUSY;
64 }
65 msleep(100);
66 }
67
68 return 0;
69}
70
71/* TODO: move dlflags into dev-> and change to write/readl/b */
72/* TODO: Excessive levels of debug */
73int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
74 u32 dlflags, u8 *dst, u32 dstsize)
75{
76 u32 reg, timeout, offset;
77 u8 *srcbuf = NULL;
78 int ret;
79
80 u32 dlflag = dlflags;
81 u32 dlflag_ack = dlflag + 4;
82 u32 drflag = dlflag_ack + 4;
83 u32 drflag_ack = drflag + 4;
84 u32 bleflag = drflag_ack + 4;
85
86 dprintk(DBGLVL_FW,
87 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
88 __func__, src, srcsize, dlflags, dst, dstsize);
89
90 if ((src == 0) || (dst == 0)) {
91 ret = -EIO;
92 goto out;
93 }
94
95 srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
96 if (NULL == srcbuf) {
97 ret = -ENOMEM;
98 goto out;
99 }
100
101 if (srcsize > (4*1048576)) {
102 ret = -ENOMEM;
103 goto out;
104 }
105
106 memcpy(srcbuf, src, srcsize);
107
108 dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
109 dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
110 dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
111 dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
112 dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
113
114 reg = saa7164_readl(dlflag);
115 dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
116 if (reg == 1)
117 dprintk(DBGLVL_FW,
118 "%s() Download flag already set, please reboot\n",
119 __func__);
120
121 /* Indicate download start */
122 saa7164_writel(dlflag, 1);
123 ret = saa7164_dl_wait_ack(dev, dlflag_ack);
124 if (ret < 0)
125 goto out;
126
127 /* Ack download start, then wait for wait */
128 saa7164_writel(dlflag, 0);
129 ret = saa7164_dl_wait_clr(dev, dlflag_ack);
130 if (ret < 0)
131 goto out;
132
133 /* Deal with the raw firmware, in the appropriate chunk size */
134 for (offset = 0; srcsize > dstsize;
135 srcsize -= dstsize, offset += dstsize) {
136
137 dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
138 memcpy(dst, srcbuf + offset, dstsize);
139
140 /* Flag the data as ready */
141 saa7164_writel(drflag, 1);
142 ret = saa7164_dl_wait_ack(dev, drflag_ack);
143 if (ret < 0)
144 goto out;
145
146 /* Wait for indication data was received */
147 saa7164_writel(drflag, 0);
148 ret = saa7164_dl_wait_clr(dev, drflag_ack);
149 if (ret < 0)
150 goto out;
151
152 }
153
154 dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
155 /* Write last block to the device */
156 memcpy(dst, srcbuf+offset, srcsize);
157
158 /* Flag the data as ready */
159 saa7164_writel(drflag, 1);
160 ret = saa7164_dl_wait_ack(dev, drflag_ack);
161 if (ret < 0)
162 goto out;
163
164 saa7164_writel(drflag, 0);
165 timeout = 0;
166 while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
167 if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
168 printk(KERN_ERR "%s() image corrupt\n", __func__);
169 ret = -EBUSY;
170 goto out;
171 }
172
173 if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
174 printk(KERN_ERR "%s() device memory corrupt\n",
175 __func__);
176 ret = -EBUSY;
177 goto out;
178 }
179
180 msleep(10);
181 if (timeout++ > 60)
182 break;
183 }
184
185 printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
186
187 ret = saa7164_dl_wait_clr(dev, drflag_ack);
188 if (ret < 0)
189 goto out;
190
191 printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
192 ret = 0;
193
194out:
195 kfree(srcbuf);
196 return ret;
197}
198
199/* TODO: Excessive debug */
200/* Load the firmware. Optionally it can be in ROM or newer versions
201 * can be on disk, saving the expense of the ROM hardware. */
202int saa7164_downloadfirmware(struct saa7164_dev *dev)
203{
204 /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
205 u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
206 u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
207 const struct firmware *fw = NULL;
208 struct fw_header *hdr, *boothdr = NULL, *fwhdr;
209 u32 bootloaderversion = 0, fwloadersize;
210 u8 *bootloaderoffset = NULL, *fwloaderoffset;
211 char *fwname;
212 int ret;
213
214 dprintk(DBGLVL_FW, "%s()\n", __func__);
215
216 if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
217 fwname = SAA7164_REV2_FIRMWARE;
218 fwlength = SAA7164_REV2_FIRMWARE_SIZE;
219 } else {
220 fwname = SAA7164_REV3_FIRMWARE;
221 fwlength = SAA7164_REV3_FIRMWARE_SIZE;
222 }
223
224 version = saa7164_getcurrentfirmwareversion(dev);
225
226 if (version == 0x00) {
227
228 second_timeout = 100;
229 first_timeout = 100;
230 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
231 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
232 __func__, err_flags);
233
234 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
235 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
236 __func__, err_flags);
237 msleep(10);
238
239 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
240 printk(KERN_ERR "%s() firmware corrupt\n",
241 __func__);
242 break;
243 }
244 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
245 printk(KERN_ERR "%s() device memory corrupt\n",
246 __func__);
247 break;
248 }
249 if (err_flags & SAA_DEVICE_NO_IMAGE) {
250 printk(KERN_ERR "%s() no first image\n",
251 __func__);
252 break;
253 }
254 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
255 first_timeout -= 10;
256 if (first_timeout == 0) {
257 printk(KERN_ERR
258 "%s() no first image\n",
259 __func__);
260 break;
261 }
262 } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
263 second_timeout -= 10;
264 if (second_timeout == 0) {
265 printk(KERN_ERR
266 "%s() FW load time exceeded\n",
267 __func__);
268 break;
269 }
270 } else {
271 second_timeout -= 10;
272 if (second_timeout == 0) {
273 printk(KERN_ERR
274 "%s() Unknown bootloader flags 0x%x\n",
275 __func__, err_flags);
276 break;
277 }
278 }
279
280 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
281 } /* While != Booting */
282
283 if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
284 dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
285 __func__);
286 first_timeout = SAA_DEVICE_TIMEOUT;
287 second_timeout = 60 * SAA_DEVICE_TIMEOUT;
288 second_timeout = 100;
289
290 err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
291 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
292 __func__, err_flags);
293 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
294 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
295 __func__, err_flags);
296 msleep(10);
297
298 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
299 printk(KERN_ERR
300 "%s() firmware corrupt\n",
301 __func__);
302 break;
303 }
304 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
305 printk(KERN_ERR
306 "%s() device memory corrupt\n",
307 __func__);
308 break;
309 }
310 if (err_flags & SAA_DEVICE_NO_IMAGE) {
311 printk(KERN_ERR "%s() no first image\n",
312 __func__);
313 break;
314 }
315 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
316 first_timeout -= 10;
317 if (first_timeout == 0) {
318 printk(KERN_ERR
319 "%s() no second image\n",
320 __func__);
321 break;
322 }
323 } else if (err_flags &
324 SAA_DEVICE_IMAGE_LOADING) {
325 second_timeout -= 10;
326 if (second_timeout == 0) {
327 printk(KERN_ERR
328 "%s() FW load time exceeded\n",
329 __func__);
330 break;
331 }
332 } else {
333 second_timeout -= 10;
334 if (second_timeout == 0) {
335 printk(KERN_ERR
336 "%s() Unknown bootloader flags 0x%x\n",
337 __func__, err_flags);
338 break;
339 }
340 }
341
342 err_flags =
343 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
344 } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
345
346 dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
347 __func__,
348 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
349 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
350
351 } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
352
353 /* It's possible for both firmwares to have booted,
354 * but that doesn't mean they've finished booting yet.
355 */
356 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
357 SAA_DEVICE_IMAGE_BOOTING) &&
358 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
359 SAA_DEVICE_IMAGE_BOOTING)) {
360
361
362 dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
363 __func__);
364
365 first_timeout = SAA_DEVICE_TIMEOUT;
366 while (first_timeout) {
367 msleep(10);
368
369 version =
370 saa7164_getcurrentfirmwareversion(dev);
371 if (version) {
372 dprintk(DBGLVL_FW,
373 "%s() All f/w loaded successfully\n",
374 __func__);
375 break;
376 } else {
377 first_timeout -= 10;
378 if (first_timeout == 0) {
379 printk(KERN_ERR
380 "%s() FW did not boot\n",
381 __func__);
382 break;
383 }
384 }
385 }
386 }
387 version = saa7164_getcurrentfirmwareversion(dev);
388 } /* version == 0 */
389
390 /* Has the firmware really booted? */
391 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
392 SAA_DEVICE_IMAGE_BOOTING) &&
393 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
394 SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
395
396 printk(KERN_ERR
397 "%s() The firmware hung, probably bad firmware\n",
398 __func__);
399
400 /* Tell the second stage loader we have a deadlock */
401 saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
402 SAA_DEVICE_DEADLOCK_DETECTED);
403
404 saa7164_getfirmwarestatus(dev);
405
406 return -ENOMEM;
407 }
408
409 dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
410 (version & 0x0000fc00) >> 10,
411 (version & 0x000003e0) >> 5,
412 (version & 0x0000001f),
413 (version & 0xffff0000) >> 16);
414
415 /* Load the firmwware from the disk if required */
416 if (version == 0) {
417
418 printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
419 __func__, fwname);
420
421 ret = request_firmware(&fw, fwname, &dev->pci->dev);
422 if (ret) {
423 printk(KERN_ERR "%s() Upload failed. "
424 "(file not found?)\n", __func__);
425 return -ENOMEM;
426 }
427
428 printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
429 __func__, fw->size);
430
431 if (fw->size != fwlength) {
432 printk(KERN_ERR "xc5000: firmware incorrect size\n");
433 ret = -ENOMEM;
434 goto out;
435 }
436
437 printk(KERN_INFO "%s() firmware loaded.\n", __func__);
438
439 hdr = (struct fw_header *)fw->data;
440 printk(KERN_INFO "Firmware file header part 1:\n");
441 printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
442 printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
443 printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
444 printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
445
446 /* Retreive bootloader if reqd */
447 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
448 /* Second bootloader in the firmware file */
449 filesize = hdr->reserved * 16;
450 else
451 filesize = (hdr->firmwaresize + hdr->bslsize) *
452 16 + sizeof(struct fw_header);
453
454 printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
455 __func__, filesize);
456
457 /* Get bootloader (if reqd) and firmware header */
458 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
459 /* Second boot loader is required */
460
461 /* Get the loader header */
462 boothdr = (struct fw_header *)(fw->data +
463 sizeof(struct fw_header));
464
465 bootloaderversion =
466 saa7164_readl(SAA_DEVICE_2ND_VERSION);
467 dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
468 dprintk(DBGLVL_FW, "->Flag 0x%x\n",
469 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
470 dprintk(DBGLVL_FW, "->Ack 0x%x\n",
471 saa7164_readl(SAA_DATAREADY_FLAG_ACK));
472 dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
473 dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
474 bootloaderversion);
475
476 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
477 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
478 == 0x00) && (version == 0x00)) {
479
480 dprintk(DBGLVL_FW, "BootLoader version in "
481 "rom %d.%d.%d.%d\n",
482 (bootloaderversion & 0x0000fc00) >> 10,
483 (bootloaderversion & 0x000003e0) >> 5,
484 (bootloaderversion & 0x0000001f),
485 (bootloaderversion & 0xffff0000) >> 16
486 );
487 dprintk(DBGLVL_FW, "BootLoader version "
488 "in file %d.%d.%d.%d\n",
489 (boothdr->version & 0x0000fc00) >> 10,
490 (boothdr->version & 0x000003e0) >> 5,
491 (boothdr->version & 0x0000001f),
492 (boothdr->version & 0xffff0000) >> 16
493 );
494
495 if (bootloaderversion == boothdr->version)
496 updatebootloader = 0;
497 }
498
499 /* Calculate offset to firmware header */
500 tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
501 (sizeof(struct fw_header) +
502 sizeof(struct fw_header));
503
504 fwhdr = (struct fw_header *)(fw->data+tmp);
505 } else {
506 /* No second boot loader */
507 fwhdr = hdr;
508 }
509
510 dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
511 (fwhdr->version & 0x0000fc00) >> 10,
512 (fwhdr->version & 0x000003e0) >> 5,
513 (fwhdr->version & 0x0000001f),
514 (fwhdr->version & 0xffff0000) >> 16
515 );
516
517 if (version == fwhdr->version) {
518 /* No download, firmware already on board */
519 ret = 0;
520 goto out;
521 }
522
523 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
524 if (updatebootloader) {
525 /* Get ready to upload the bootloader */
526 bootloadersize = (boothdr->firmwaresize +
527 boothdr->bslsize) * 16 +
528 sizeof(struct fw_header);
529
530 bootloaderoffset = (u8 *)(fw->data +
531 sizeof(struct fw_header));
532
533 dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
534 printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
535 __func__, boothdr->firmwaresize);
536 printk(KERN_INFO "%s() BSLSize = 0x%x\n",
537 __func__, boothdr->bslsize);
538 printk(KERN_INFO "%s() Reserved = 0x%x\n",
539 __func__, boothdr->reserved);
540 printk(KERN_INFO "%s() Version = 0x%x\n",
541 __func__, boothdr->version);
542 ret = saa7164_downloadimage(
543 dev,
544 bootloaderoffset,
545 bootloadersize,
546 SAA_DOWNLOAD_FLAGS,
547 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
548 SAA_DEVICE_BUFFERBLOCKSIZE);
549 if (ret < 0) {
550 printk(KERN_ERR
551 "bootloader d/l has failed\n");
552 goto out;
553 }
554 dprintk(DBGLVL_FW,
555 "bootloader download complete.\n");
556
557 }
558
559 printk(KERN_ERR "starting firmware download(2)\n");
560 bootloadersize = (boothdr->firmwaresize +
561 boothdr->bslsize) * 16 +
562 sizeof(struct fw_header);
563
564 bootloaderoffset =
565 (u8 *)(fw->data + sizeof(struct fw_header));
566
567 fwloaderoffset = bootloaderoffset + bootloadersize;
568
569 /* TODO: fix this bounds overrun here with old f/ws */
570 fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
571 16 + sizeof(struct fw_header);
572
573 ret = saa7164_downloadimage(
574 dev,
575 fwloaderoffset,
576 fwloadersize,
577 SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
578 dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
579 SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
580 if (ret < 0) {
581 printk(KERN_ERR "firmware download failed\n");
582 goto out;
583 }
584 printk(KERN_ERR "firmware download complete.\n");
585
586 } else {
587
588 /* No bootloader update reqd, download firmware only */
589 printk(KERN_ERR "starting firmware download(3)\n");
590
591 ret = saa7164_downloadimage(
592 dev,
593 (u8 *)fw->data,
594 fw->size,
595 SAA_DOWNLOAD_FLAGS,
596 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
597 SAA_DEVICE_BUFFERBLOCKSIZE);
598 if (ret < 0) {
599 printk(KERN_ERR "firmware download failed\n");
600 goto out;
601 }
602 printk(KERN_ERR "firmware download complete.\n");
603 }
604 }
605
606 ret = 0;
607
608out:
609 if (fw)
610 release_firmware(fw);
611
612 return ret;
613}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
new file mode 100644
index 000000000000..e1ae9b01bf0f
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -0,0 +1,141 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <asm/io.h>
27
28#include "saa7164.h"
29
30static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
31{
32 struct saa7164_i2c *bus = i2c_adap->algo_data;
33 struct saa7164_dev *dev = bus->dev;
34 int i, retval = 0;
35
36 dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
37
38 for (i = 0 ; i < num; i++) {
39 dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
40 __func__, num, msgs[i].addr, msgs[i].len);
41 if (msgs[i].flags & I2C_M_RD) {
42 /* Unsupported - Yet*/
43 printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
44 continue;
45 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
46 msgs[i].addr == msgs[i + 1].addr) {
47 /* write then read from same address */
48
49 retval = saa7164_api_i2c_read(bus, msgs[i].addr,
50 msgs[i].len, msgs[i].buf,
51 msgs[i+1].len, msgs[i+1].buf
52 );
53
54 i++;
55
56 if (retval < 0)
57 goto err;
58 } else {
59 /* write */
60 retval = saa7164_api_i2c_write(bus, msgs[i].addr,
61 msgs[i].len, msgs[i].buf);
62 }
63 if (retval < 0)
64 goto err;
65 }
66 return num;
67
68 err:
69 return retval;
70}
71
72void saa7164_call_i2c_clients(struct saa7164_i2c *bus, unsigned int cmd,
73 void *arg)
74{
75 if (bus->i2c_rc != 0)
76 return;
77
78 i2c_clients_command(&bus->i2c_adap, cmd, arg);
79}
80
81static u32 saa7164_functionality(struct i2c_adapter *adap)
82{
83 return I2C_FUNC_I2C;
84}
85
86static struct i2c_algorithm saa7164_i2c_algo_template = {
87 .master_xfer = i2c_xfer,
88 .functionality = saa7164_functionality,
89};
90
91/* ----------------------------------------------------------------------- */
92
93static struct i2c_adapter saa7164_i2c_adap_template = {
94 .name = "saa7164",
95 .owner = THIS_MODULE,
96 .algo = &saa7164_i2c_algo_template,
97};
98
99static struct i2c_client saa7164_i2c_client_template = {
100 .name = "saa7164 internal",
101};
102
103int saa7164_i2c_register(struct saa7164_i2c *bus)
104{
105 struct saa7164_dev *dev = bus->dev;
106
107 dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
108
109 memcpy(&bus->i2c_adap, &saa7164_i2c_adap_template,
110 sizeof(bus->i2c_adap));
111
112 memcpy(&bus->i2c_algo, &saa7164_i2c_algo_template,
113 sizeof(bus->i2c_algo));
114
115 memcpy(&bus->i2c_client, &saa7164_i2c_client_template,
116 sizeof(bus->i2c_client));
117
118 bus->i2c_adap.dev.parent = &dev->pci->dev;
119
120 strlcpy(bus->i2c_adap.name, bus->dev->name,
121 sizeof(bus->i2c_adap.name));
122
123 bus->i2c_algo.data = bus;
124 bus->i2c_adap.algo_data = bus;
125 i2c_set_adapdata(&bus->i2c_adap, bus);
126 i2c_add_adapter(&bus->i2c_adap);
127
128 bus->i2c_client.adapter = &bus->i2c_adap;
129
130 if (0 != bus->i2c_rc)
131 printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
132 dev->name, bus->nr);
133
134 return bus->i2c_rc;
135}
136
137int saa7164_i2c_unregister(struct saa7164_i2c *bus)
138{
139 i2c_del_adapter(&bus->i2c_adap);
140 return 0;
141}
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
new file mode 100644
index 000000000000..06be4c13d5b1
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-reg.h
@@ -0,0 +1,166 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/* TODO: Retest the driver with errors expressed as negatives */
23
24/* Result codes */
25#define SAA_OK 0
26#define SAA_ERR_BAD_PARAMETER 0x09
27#define SAA_ERR_NO_RESOURCES 0x0c
28#define SAA_ERR_NOT_SUPPORTED 0x13
29#define SAA_ERR_BUSY 0x15
30#define SAA_ERR_READ 0x17
31#define SAA_ERR_TIMEOUT 0x1f
32#define SAA_ERR_OVERFLOW 0x20
33#define SAA_ERR_EMPTY 0x22
34#define SAA_ERR_NOT_STARTED 0x23
35#define SAA_ERR_ALREADY_STARTED 0x24
36#define SAA_ERR_NOT_STOPPED 0x25
37#define SAA_ERR_ALREADY_STOPPED 0x26
38#define SAA_ERR_INVALID_COMMAND 0x3e
39#define SAA_ERR_NULL_PACKET 0x59
40
41/* Errors and flags from the silicon */
42#define PVC_ERRORCODE_UNKNOWN 0x00
43#define PVC_ERRORCODE_INVALID_COMMAND 0x01
44#define PVC_ERRORCODE_INVALID_CONTROL 0x02
45#define PVC_ERRORCODE_INVALID_DATA 0x03
46#define PVC_ERRORCODE_TIMEOUT 0x04
47#define PVC_ERRORCODE_NAK 0x05
48#define PVC_RESPONSEFLAG_ERROR 0x01
49#define PVC_RESPONSEFLAG_OVERFLOW 0x02
50#define PVC_RESPONSEFLAG_RESET 0x04
51#define PVC_RESPONSEFLAG_INTERFACE 0x08
52#define PVC_RESPONSEFLAG_CONTINUED 0x10
53#define PVC_CMDFLAG_INTERRUPT 0x02
54#define PVC_CMDFLAG_INTERFACE 0x04
55#define PVC_CMDFLAG_SERIALIZE 0x08
56#define PVC_CMDFLAG_CONTINUE 0x10
57
58/* Silicon Commands */
59#define GET_DESCRIPTORS_CONTROL 0x01
60#define GET_STRING_CONTROL 0x03
61#define GET_LANGUAGE_CONTROL 0x05
62#define SET_POWER_CONTROL 0x07
63#define GET_FW_VERSION_CONTROL 0x09
64#define SET_DEBUG_LEVEL_CONTROL 0x0B
65#define GET_DEBUG_DATA_CONTROL 0x0C
66#define GET_PRODUCTION_INFO_CONTROL 0x0D
67
68/* cmd defines */
69#define SAA_CMDFLAG_CONTINUE 0x10
70#define SAA_CMD_MAX_MSG_UNITS 256
71
72/* Some defines */
73#define SAA_BUS_TIMEOUT 50
74#define SAA_DEVICE_TIMEOUT 5000
75#define SAA_DEVICE_MAXREQUESTSIZE 256
76
77/* Register addresses */
78#define SAA_DEVICE_VERSION 0x30
79#define SAA_DOWNLOAD_FLAGS 0x34
80#define SAA_DOWNLOAD_FLAG 0x34
81#define SAA_DOWNLOAD_FLAG_ACK 0x38
82#define SAA_DATAREADY_FLAG 0x3C
83#define SAA_DATAREADY_FLAG_ACK 0x40
84
85/* Boot loader register and bit definitions */
86#define SAA_BOOTLOADERERROR_FLAGS 0x44
87#define SAA_DEVICE_IMAGE_SEARCHING 0x01
88#define SAA_DEVICE_IMAGE_LOADING 0x02
89#define SAA_DEVICE_IMAGE_BOOTING 0x03
90#define SAA_DEVICE_IMAGE_CORRUPT 0x04
91#define SAA_DEVICE_MEMORY_CORRUPT 0x08
92#define SAA_DEVICE_NO_IMAGE 0x10
93
94/* Register addresses */
95#define SAA_DEVICE_2ND_VERSION 0x50
96#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54
97
98/* Register addresses */
99#define SAA_SECONDSTAGEERROR_FLAGS 0x64
100
101/* Bootloader regs and flags */
102#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C
103#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD
104
105/* Basic firmware status registers */
106#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70
107#define SAA_DEVICE_SYSINIT_STATUS 0x70
108#define SAA_DEVICE_SYSINIT_MODE 0x74
109#define SAA_DEVICE_SYSINIT_SPEC 0x78
110#define SAA_DEVICE_SYSINIT_INST 0x7C
111#define SAA_DEVICE_SYSINIT_CPULOAD 0x80
112#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84
113
114#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000
115#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000
116
117#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000
118#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000
119
120/* Descriptors */
121#define CS_INTERFACE 0x24
122
123/* Descriptor subtypes */
124#define VC_INPUT_TERMINAL 0x02
125#define VC_OUTPUT_TERMINAL 0x03
126#define VC_SELECTOR_UNIT 0x04
127#define VC_PROCESSING_UNIT 0x05
128#define FEATURE_UNIT 0x06
129#define TUNER_UNIT 0x09
130#define ENCODER_UNIT 0x0A
131#define EXTENSION_UNIT 0x0B
132#define VC_TUNER_PATH 0xF0
133#define PVC_HARDWARE_DESCRIPTOR 0xF1
134#define PVC_INTERFACE_DESCRIPTOR 0xF2
135#define PVC_INFRARED_UNIT 0xF3
136#define DRM_UNIT 0xF4
137#define GENERAL_REQUEST 0xF5
138
139/* Format Types */
140#define VS_FORMAT_TYPE 0x02
141#define VS_FORMAT_TYPE_I 0x01
142#define VS_FORMAT_UNCOMPRESSED 0x04
143#define VS_FRAME_UNCOMPRESSED 0x05
144#define VS_FORMAT_MPEG2PS 0x09
145#define VS_FORMAT_MPEG2TS 0x0A
146#define VS_FORMAT_MPEG4SL 0x0B
147#define VS_FORMAT_WM9 0x0C
148#define VS_FORMAT_DIVX 0x0D
149#define VS_FORMAT_VBI 0x0E
150#define VS_FORMAT_RDS 0x0F
151
152/* Device extension commands */
153#define EXU_REGISTER_ACCESS_CONTROL 0x00
154#define EXU_GPIO_CONTROL 0x01
155#define EXU_GPIO_GROUP_CONTROL 0x02
156#define EXU_INTERRUPT_CONTROL 0x03
157
158/* State Transition and args */
159#define SAA_STATE_CONTROL 0x03
160#define SAA_DMASTATE_STOP 0x00
161#define SAA_DMASTATE_ACQUIRE 0x01
162#define SAA_DMASTATE_PAUSE 0x02
163#define SAA_DMASTATE_RUN 0x03
164
165/* Hardware registers */
166
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
new file mode 100644
index 000000000000..99093f23aae5
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-types.h
@@ -0,0 +1,287 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/* TODO: Cleanup and shorten the namespace */
23
24/* Some structues are passed directly to/from the firmware and
25 * have strict alignment requirements. This is one of them.
26 */
27typedef struct {
28 u8 bLength;
29 u8 bDescriptorType;
30 u8 bDescriptorSubtype;
31 u16 bcdSpecVersion;
32 u32 dwClockFrequency;
33 u32 dwClockUpdateRes;
34 u8 bCapabilities;
35 u32 dwDeviceRegistersLocation;
36 u32 dwHostMemoryRegion;
37 u32 dwHostMemoryRegionSize;
38 u32 dwHostHibernatMemRegion;
39 u32 dwHostHibernatMemRegionSize;
40} __attribute__((packed)) tmComResHWDescr_t;
41
42/* This is DWORD aligned on windows but I can't find the right
43 * gcc syntax to match the binary data from the device.
44 * I've manually padded with Reserved[3] bytes to match the hardware,
45 * but this could break if GCC decies to pack in a different way.
46 */
47typedef struct {
48 u8 bLength;
49 u8 bDescriptorType;
50 u8 bDescriptorSubtype;
51 u8 bFlags;
52 u8 bInterfaceType;
53 u8 bInterfaceId;
54 u8 bBaseInterface;
55 u8 bInterruptId;
56 u8 bDebugInterruptId;
57 u8 BARLocation;
58 u8 Reserved[3];
59} tmComResInterfaceDescr_t;
60
61typedef struct {
62 u64 CommandRing;
63 u64 ResponseRing;
64 u32 CommandWrite;
65 u32 CommandRead;
66 u32 ResponseWrite;
67 u32 ResponseRead;
68} tmComResBusDescr_t;
69
70typedef enum {
71 NONE = 0,
72 TYPE_BUS_PCI = 1,
73 TYPE_BUS_PCIe = 2,
74 TYPE_BUS_USB = 3,
75 TYPE_BUS_I2C = 4
76} tmBusType_t;
77
78typedef struct {
79 tmBusType_t Type;
80 u16 m_wMaxReqSize;
81 u8 *m_pdwSetRing;
82 u32 m_dwSizeSetRing;
83 u8 *m_pdwGetRing;
84 u32 m_dwSizeGetRing;
85 u32 *m_pdwSetWritePos;
86 u32 *m_pdwSetReadPos;
87 u32 *m_pdwGetWritePos;
88 u32 *m_pdwGetReadPos;
89
90 /* All access is protected */
91 struct mutex lock;
92
93} tmComResBusInfo_t;
94
95typedef struct {
96 u8 id;
97 u8 flags;
98 u16 size;
99 u32 command;
100 u16 controlselector;
101 u8 seqno;
102} __attribute__((packed)) tmComResInfo_t;
103
104typedef enum {
105 SET_CUR = 0x01,
106 GET_CUR = 0x81,
107 GET_MIN = 0x82,
108 GET_MAX = 0x83,
109 GET_RES = 0x84,
110 GET_LEN = 0x85,
111 GET_INFO = 0x86,
112 GET_DEF = 0x87
113} tmComResCmd_t;
114
115struct cmd {
116 u8 seqno;
117 u32 inuse;
118 u32 timeout;
119 u32 signalled;
120 struct mutex lock;
121 wait_queue_head_t wait;
122};
123
124typedef struct {
125 u32 pathid;
126 u32 size;
127 void *descriptor;
128} tmDescriptor_t;
129
130typedef struct {
131 u8 len;
132 u8 type;
133 u8 subtype;
134 u8 unitid;
135} __attribute__((packed)) tmComResDescrHeader_t;
136
137typedef struct {
138 u8 len;
139 u8 type;
140 u8 subtype;
141 u8 unitid;
142 u32 devicetype;
143 u16 deviceid;
144 u32 numgpiopins;
145 u8 numgpiogroups;
146 u8 controlsize;
147} __attribute__((packed)) tmComResExtDevDescrHeader_t;
148
149typedef struct {
150 u32 pin;
151 u8 state;
152} __attribute__((packed)) tmComResGPIO_t;
153
154typedef struct {
155 u8 len;
156 u8 type;
157 u8 subtype;
158 u8 pathid;
159} __attribute__((packed)) tmComResPathDescrHeader_t;
160
161/* terminaltype */
162typedef enum {
163 ITT_ANTENNA = 0x0203,
164 LINE_CONNECTOR = 0x0603,
165 SPDIF_CONNECTOR = 0x0605,
166 COMPOSITE_CONNECTOR = 0x0401,
167 SVIDEO_CONNECTOR = 0x0402,
168 COMPONENT_CONNECTOR = 0x0403,
169 STANDARD_DMA = 0xF101
170} tmComResTermType_t;
171
172typedef struct {
173 u8 len;
174 u8 type;
175 u8 subtype;
176 u8 terminalid;
177 u16 terminaltype;
178 u8 assocterminal;
179 u8 iterminal;
180 u8 controlsize;
181} __attribute__((packed)) tmComResAntTermDescrHeader_t;
182
183typedef struct {
184 u8 len;
185 u8 type;
186 u8 subtype;
187 u8 unitid;
188 u8 sourceid;
189 u8 iunit;
190 u32 tuningstandards;
191 u8 controlsize;
192 u32 controls;
193} __attribute__((packed)) tmComResTunerDescrHeader_t;
194
195typedef enum {
196 /* the buffer does not contain any valid data */
197 TM_BUFFER_FLAG_EMPTY,
198
199 /* the buffer is filled with valid data */
200 TM_BUFFER_FLAG_DONE,
201
202 /* the buffer is the dummy buffer - TODO??? */
203 TM_BUFFER_FLAG_DUMMY_BUFFER
204} tmBufferFlag_t;
205
206typedef struct {
207 u64 *pagetablevirt;
208 u64 pagetablephys;
209 u16 offset;
210 u8 *context;
211 u64 timestamp;
212 tmBufferFlag_t BufferFlag_t;
213 u32 lostbuffers;
214 u32 validbuffers;
215 u64 *dummypagevirt;
216 u64 dummypagephys;
217 u64 *addressvirt;
218} tmBuffer_t;
219
220typedef struct {
221 u32 bitspersample;
222 u32 samplesperline;
223 u32 numberoflines;
224 u32 pitch;
225 u32 linethreshold;
226 u64 **pagetablelistvirt;
227 u64 *pagetablelistphys;
228 u32 numpagetables;
229 u32 numpagetableentries;
230} tmHWStreamParameters_t;
231
232typedef struct {
233 tmHWStreamParameters_t HWStreamParameters_t;
234 u64 qwDummyPageTablePhys;
235 u64 *pDummyPageTableVirt;
236} tmStreamParameters_t;
237
238typedef struct {
239 u8 len;
240 u8 type;
241 u8 subtyle;
242 u8 unitid;
243 u16 terminaltype;
244 u8 assocterminal;
245 u8 sourceid;
246 u8 iterminal;
247 u32 BARLocation;
248 u8 flags;
249 u8 interruptid;
250 u8 buffercount;
251 u8 metadatasize;
252 u8 numformats;
253 u8 controlsize;
254} __attribute__((packed)) tmComResDMATermDescrHeader_t;
255
256/*
257 *
258 * Description:
259 * This is the transport stream format header.
260 *
261 * Settings:
262 * bLength - The size of this descriptor in bytes.
263 * bDescriptorType - CS_INTERFACE.
264 * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype.
265 * bFormatIndex - A non-zero constant that uniquely identifies the
266 * format.
267 * bDataOffset - Offset to TSP packet within MPEG-2 TS transport
268 * stride, in bytes.
269 * bPacketLength - Length of TSP packet, in bytes (typically 188).
270 * bStrideLength - Length of MPEG-2 TS transport stride.
271 * guidStrideFormat - A Globally Unique Identifier indicating the
272 * format of the stride data (if any). Set to zeros
273 * if there is no Stride Data, or if the Stride
274 * Data is to be ignored by the application.
275 *
276 */
277typedef struct {
278 u8 len;
279 u8 type;
280 u8 subtype;
281 u8 bFormatIndex;
282 u8 bDataOffset;
283 u8 bPacketLength;
284 u8 bStrideLength;
285 u8 guidStrideFormat[16];
286} __attribute__((packed)) tmComResTSFormatDescrHeader_t;
287
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
new file mode 100644
index 000000000000..6753008a9c9b
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -0,0 +1,400 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/*
23 Driver architecture
24 *******************
25
26 saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
27 | : Standard Linux driver framework for creating
28 | : exposing and managing interfaces to the rest
29 | : of the kernel or userland. Also uses _fw.c to load
30 | : firmware direct into the PCIe bus, bypassing layers.
31 V
32 saa7164_api..() : Translate kernel specific functions/features
33 | : into command buffers.
34 V
35 saa7164_cmd..() : Manages the flow of command packets on/off,
36 | : the bus. Deal with bus errors, timeouts etc.
37 V
38 saa7164_bus..() : Manage a read/write memory ring buffer in the
39 | : PCIe Address space.
40 |
41 | saa7164_fw...() : Load any frimware
42 | | : direct into the device
43 V V
44 <- ----------------- PCIe address space -------------------- ->
45*/
46
47#include <linux/pci.h>
48#include <linux/i2c.h>
49#include <linux/i2c-algo-bit.h>
50#include <linux/kdev_t.h>
51
52#include <media/tuner.h>
53#include <media/tveeprom.h>
54#include <media/videobuf-dma-sg.h>
55#include <media/videobuf-dvb.h>
56
57#include "saa7164-reg.h"
58#include "saa7164-types.h"
59
60#include <linux/version.h>
61#include <linux/mutex.h>
62
63#define SAA7164_MAXBOARDS 8
64
65#define UNSET (-1U)
66#define SAA7164_BOARD_NOAUTO UNSET
67#define SAA7164_BOARD_UNKNOWN 0
68#define SAA7164_BOARD_UNKNOWN_REV2 1
69#define SAA7164_BOARD_UNKNOWN_REV3 2
70#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3
71#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4
72#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5
73#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6
74#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7
75#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8
76
77#define SAA7164_MAX_UNITS 8
78#define SAA7164_TS_NUMBER_OF_LINES 312
79#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */
80
81#define DBGLVL_FW 4
82#define DBGLVL_DVB 8
83#define DBGLVL_I2C 16
84#define DBGLVL_API 32
85#define DBGLVL_CMD 64
86#define DBGLVL_BUS 128
87#define DBGLVL_IRQ 256
88#define DBGLVL_BUF 512
89
90enum port_t {
91 SAA7164_MPEG_UNDEFINED = 0,
92 SAA7164_MPEG_DVB,
93};
94
95enum saa7164_i2c_bus_nr {
96 SAA7164_I2C_BUS_0 = 0,
97 SAA7164_I2C_BUS_1,
98 SAA7164_I2C_BUS_2,
99};
100
101enum saa7164_buffer_flags {
102 SAA7164_BUFFER_UNDEFINED = 0,
103 SAA7164_BUFFER_FREE,
104 SAA7164_BUFFER_BUSY,
105 SAA7164_BUFFER_FULL
106};
107
108enum saa7164_unit_type {
109 SAA7164_UNIT_UNDEFINED = 0,
110 SAA7164_UNIT_DIGITAL_DEMODULATOR,
111 SAA7164_UNIT_ANALOG_DEMODULATOR,
112 SAA7164_UNIT_TUNER,
113 SAA7164_UNIT_EEPROM,
114 SAA7164_UNIT_ZILOG_IRBLASTER,
115 SAA7164_UNIT_ENCODER,
116};
117
118/* The PCIe bridge doesn't grant direct access to i2c.
119 * Instead, you address i2c devices using a uniqely
120 * allocated 'unitid' value via a messaging API. This
121 * is a problem. The kernel and existing demod/tuner
122 * drivers expect to talk 'i2c', so we have to maintain
123 * a translation layer, and a series of functions to
124 * convert i2c bus + device address into a unit id.
125 */
126struct saa7164_unit {
127 enum saa7164_unit_type type;
128 u8 id;
129 char *name;
130 enum saa7164_i2c_bus_nr i2c_bus_nr;
131 u8 i2c_bus_addr;
132 u8 i2c_reg_len;
133};
134
135struct saa7164_board {
136 char *name;
137 enum port_t porta, portb;
138 enum {
139 SAA7164_CHIP_UNDEFINED = 0,
140 SAA7164_CHIP_REV2,
141 SAA7164_CHIP_REV3,
142 } chiprev;
143 struct saa7164_unit unit[SAA7164_MAX_UNITS];
144};
145
146struct saa7164_subid {
147 u16 subvendor;
148 u16 subdevice;
149 u32 card;
150};
151
152struct saa7164_fw_status {
153
154 /* RISC Core details */
155 u32 status;
156 u32 mode;
157 u32 spec;
158 u32 inst;
159 u32 cpuload;
160 u32 remainheap;
161
162 /* Firmware version */
163 u32 version;
164 u32 major;
165 u32 sub;
166 u32 rel;
167 u32 buildnr;
168};
169
170struct saa7164_dvb {
171 struct mutex lock;
172 struct dvb_adapter adapter;
173 struct dvb_frontend *frontend;
174 struct dvb_demux demux;
175 struct dmxdev dmxdev;
176 struct dmx_frontend fe_hw;
177 struct dmx_frontend fe_mem;
178 struct dvb_net net;
179 int feeding;
180};
181
182struct saa7164_i2c {
183 struct saa7164_dev *dev;
184
185 enum saa7164_i2c_bus_nr nr;
186
187 /* I2C I/O */
188 struct i2c_adapter i2c_adap;
189 struct i2c_algo_bit_data i2c_algo;
190 struct i2c_client i2c_client;
191 u32 i2c_rc;
192};
193
194struct saa7164_tsport;
195
196struct saa7164_buffer {
197 struct list_head list;
198
199 u32 nr;
200
201 struct saa7164_tsport *port;
202
203 /* Hardware Specific */
204 /* PCI Memory allocations */
205 enum saa7164_buffer_flags flags; /* Free, Busy, Full */
206
207 /* A block of page align PCI memory */
208 u32 pci_size; /* PCI allocation size in bytes */
209 u64 *cpu; /* Virtual address */
210 dma_addr_t dma; /* Physical address */
211
212 /* A page table that splits the block into a number of entries */
213 u32 pt_size; /* PCI allocation size in bytes */
214 u64 *pt_cpu; /* Virtual address */
215 dma_addr_t pt_dma; /* Physical address */
216};
217
218struct saa7164_tsport {
219
220 struct saa7164_dev *dev;
221 int nr;
222 enum port_t type;
223
224 struct saa7164_dvb dvb;
225
226 /* HW related stream parameters */
227 tmHWStreamParameters_t hw_streamingparams;
228
229 /* DMA configuration values, is seeded during initialization */
230 tmComResDMATermDescrHeader_t hwcfg;
231
232 /* hardware specific registers */
233 u32 bufcounter;
234 u32 pitch;
235 u32 bufsize;
236 u32 bufoffset;
237 u32 bufptr32l;
238 u32 bufptr32h;
239 u64 bufptr64;
240
241 u32 numpte; /* Number of entries in array, only valid in head */
242 struct mutex dmaqueue_lock;
243 struct mutex dummy_dmaqueue_lock;
244 struct saa7164_buffer dmaqueue;
245 struct saa7164_buffer dummy_dmaqueue;
246
247};
248
249struct saa7164_dev {
250 struct list_head devlist;
251 atomic_t refcount;
252
253 /* pci stuff */
254 struct pci_dev *pci;
255 unsigned char pci_rev, pci_lat;
256 int pci_bus, pci_slot;
257 u32 __iomem *lmmio;
258 u8 __iomem *bmmio;
259 u32 __iomem *lmmio2;
260 u8 __iomem *bmmio2;
261 int pci_irqmask;
262
263 /* board details */
264 int nr;
265 int hwrevision;
266 u32 board;
267 char name[32];
268
269 /* firmware status */
270 struct saa7164_fw_status fw_status;
271
272 tmComResHWDescr_t hwdesc;
273 tmComResInterfaceDescr_t intfdesc;
274 tmComResBusDescr_t busdesc;
275
276 tmComResBusInfo_t bus;
277
278 /* Interrupt status and ack registers */
279 u32 int_status;
280 u32 int_ack;
281
282 struct cmd cmds[SAA_CMD_MAX_MSG_UNITS];
283 struct mutex lock;
284
285 /* I2c related */
286 struct saa7164_i2c i2c_bus[3];
287
288 /* Transport related */
289 struct saa7164_tsport ts1, ts2;
290
291 /* Deferred command/api interrupts handling */
292 struct work_struct workcmd;
293
294};
295
296extern struct list_head saa7164_devlist;
297extern unsigned int waitsecs;
298
299/* ----------------------------------------------------------- */
300/* saa7164-core.c */
301void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
302void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
303void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
304u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
305
306/* ----------------------------------------------------------- */
307/* saa7164-fw.c */
308int saa7164_downloadfirmware(struct saa7164_dev *dev);
309
310/* ----------------------------------------------------------- */
311/* saa7164-i2c.c */
312extern int saa7164_i2c_register(struct saa7164_i2c *bus);
313extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
314extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
315 unsigned int cmd, void *arg);
316
317/* ----------------------------------------------------------- */
318/* saa7164-bus.c */
319int saa7164_bus_setup(struct saa7164_dev *dev);
320void saa7164_bus_dump(struct saa7164_dev *dev);
321int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf);
322int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg,
323 void *buf, int peekonly);
324
325/* ----------------------------------------------------------- */
326/* saa7164-cmd.c */
327int saa7164_cmd_send(struct saa7164_dev *dev,
328 u8 id, tmComResCmd_t command, u16 controlselector,
329 u16 size, void *buf);
330void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
331int saa7164_irq_dequeue(struct saa7164_dev *dev);
332
333/* ----------------------------------------------------------- */
334/* saa7164-api.c */
335int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
336int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
337int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
338 u32 datalen, u8 *data);
339int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
340 u32 datalen, u8 *data);
341int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
342 u32 datalen, u8 *data);
343int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
344int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
345int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
346int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode);
347
348/* ----------------------------------------------------------- */
349/* saa7164-cards.c */
350extern struct saa7164_board saa7164_boards[];
351extern const unsigned int saa7164_bcount;
352
353extern struct saa7164_subid saa7164_subids[];
354extern const unsigned int saa7164_idcount;
355
356extern void saa7164_card_list(struct saa7164_dev *dev);
357extern void saa7164_gpio_setup(struct saa7164_dev *dev);
358extern void saa7164_card_setup(struct saa7164_dev *dev);
359
360extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
361extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
362extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
363
364/* ----------------------------------------------------------- */
365/* saa7164-dvb.c */
366extern int saa7164_dvb_register(struct saa7164_tsport *port);
367extern int saa7164_dvb_unregister(struct saa7164_tsport *port);
368
369/* ----------------------------------------------------------- */
370/* saa7164-buffer.c */
371extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
372 u32 len);
373extern int saa7164_buffer_dealloc(struct saa7164_tsport *port,
374 struct saa7164_buffer *buf);
375
376/* ----------------------------------------------------------- */
377
378extern unsigned int debug;
379#define dprintk(level, fmt, arg...)\
380 do { if (debug & level)\
381 printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
382 } while (0)
383
384#define log_warn(fmt, arg...)\
385 do { \
386 printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
387 } while (0)
388
389#define log_err(fmt, arg...)\
390 do { \
391 printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
392 } while (0)
393
394#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
395#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
396
397
398#define saa7164_readb(reg) readl(dev->bmmio + (reg))
399#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg))
400
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 61c47b824083..5ab7c5aefd62 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -74,6 +74,13 @@
74#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */ 74#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
75#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */ 75#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
76 76
77#undef DEBUG_GEOMETRY
78#ifdef DEBUG_GEOMETRY
79#define dev_geo dev_info
80#else
81#define dev_geo dev_dbg
82#endif
83
77/* per video frame buffer */ 84/* per video frame buffer */
78struct sh_mobile_ceu_buffer { 85struct sh_mobile_ceu_buffer {
79 struct videobuf_buffer vb; /* v4l buffer must be first */ 86 struct videobuf_buffer vb; /* v4l buffer must be first */
@@ -92,10 +99,21 @@ struct sh_mobile_ceu_dev {
92 spinlock_t lock; 99 spinlock_t lock;
93 struct list_head capture; 100 struct list_head capture;
94 struct videobuf_buffer *active; 101 struct videobuf_buffer *active;
95 int is_interlaced;
96 102
97 struct sh_mobile_ceu_info *pdata; 103 struct sh_mobile_ceu_info *pdata;
98 104
105 u32 cflcr;
106
107 unsigned int is_interlaced:1;
108 unsigned int image_mode:1;
109 unsigned int is_16bit:1;
110};
111
112struct sh_mobile_ceu_cam {
113 struct v4l2_rect ceu_rect;
114 unsigned int cam_width;
115 unsigned int cam_height;
116 const struct soc_camera_data_format *extra_fmt;
99 const struct soc_camera_data_format *camera_fmt; 117 const struct soc_camera_data_format *camera_fmt;
100}; 118};
101 119
@@ -146,7 +164,8 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
146 struct sh_mobile_ceu_dev *pcdev = ici->priv; 164 struct sh_mobile_ceu_dev *pcdev = ici->priv;
147 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; 165 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
148 166
149 *size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel); 167 *size = PAGE_ALIGN(icd->user_width * icd->user_height *
168 bytes_per_pixel);
150 169
151 if (0 == *count) 170 if (0 == *count)
152 *count = 2; 171 *count = 2;
@@ -156,7 +175,7 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
156 (*count)--; 175 (*count)--;
157 } 176 }
158 177
159 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 178 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
160 179
161 return 0; 180 return 0;
162} 181}
@@ -165,8 +184,9 @@ static void free_buffer(struct videobuf_queue *vq,
165 struct sh_mobile_ceu_buffer *buf) 184 struct sh_mobile_ceu_buffer *buf)
166{ 185{
167 struct soc_camera_device *icd = vq->priv_data; 186 struct soc_camera_device *icd = vq->priv_data;
187 struct device *dev = icd->dev.parent;
168 188
169 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 189 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
170 &buf->vb, buf->vb.baddr, buf->vb.bsize); 190 &buf->vb, buf->vb.baddr, buf->vb.bsize);
171 191
172 if (in_interrupt()) 192 if (in_interrupt())
@@ -174,7 +194,7 @@ static void free_buffer(struct videobuf_queue *vq,
174 194
175 videobuf_waiton(&buf->vb, 0, 0); 195 videobuf_waiton(&buf->vb, 0, 0);
176 videobuf_dma_contig_free(vq, &buf->vb); 196 videobuf_dma_contig_free(vq, &buf->vb);
177 dev_dbg(&icd->dev, "%s freed\n", __func__); 197 dev_dbg(dev, "%s freed\n", __func__);
178 buf->vb.state = VIDEOBUF_NEEDS_INIT; 198 buf->vb.state = VIDEOBUF_NEEDS_INIT;
179} 199}
180 200
@@ -205,7 +225,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
205 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 225 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
206 ceu_write(pcdev, CDAYR, phys_addr_top); 226 ceu_write(pcdev, CDAYR, phys_addr_top);
207 if (pcdev->is_interlaced) { 227 if (pcdev->is_interlaced) {
208 phys_addr_bottom = phys_addr_top + icd->width; 228 phys_addr_bottom = phys_addr_top + icd->user_width;
209 ceu_write(pcdev, CDBYR, phys_addr_bottom); 229 ceu_write(pcdev, CDBYR, phys_addr_bottom);
210 } 230 }
211 231
@@ -214,10 +234,12 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
214 case V4L2_PIX_FMT_NV21: 234 case V4L2_PIX_FMT_NV21:
215 case V4L2_PIX_FMT_NV16: 235 case V4L2_PIX_FMT_NV16:
216 case V4L2_PIX_FMT_NV61: 236 case V4L2_PIX_FMT_NV61:
217 phys_addr_top += icd->width * icd->height; 237 phys_addr_top += icd->user_width *
238 icd->user_height;
218 ceu_write(pcdev, CDACR, phys_addr_top); 239 ceu_write(pcdev, CDACR, phys_addr_top);
219 if (pcdev->is_interlaced) { 240 if (pcdev->is_interlaced) {
220 phys_addr_bottom = phys_addr_top + icd->width; 241 phys_addr_bottom = phys_addr_top +
242 icd->user_width;
221 ceu_write(pcdev, CDBCR, phys_addr_bottom); 243 ceu_write(pcdev, CDBCR, phys_addr_bottom);
222 } 244 }
223 } 245 }
@@ -236,7 +258,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
236 258
237 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); 259 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
238 260
239 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 261 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
240 vb, vb->baddr, vb->bsize); 262 vb, vb->baddr, vb->bsize);
241 263
242 /* Added list head initialization on alloc */ 264 /* Added list head initialization on alloc */
@@ -251,12 +273,12 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
251 BUG_ON(NULL == icd->current_fmt); 273 BUG_ON(NULL == icd->current_fmt);
252 274
253 if (buf->fmt != icd->current_fmt || 275 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 276 vb->width != icd->user_width ||
255 vb->height != icd->height || 277 vb->height != icd->user_height ||
256 vb->field != field) { 278 vb->field != field) {
257 buf->fmt = icd->current_fmt; 279 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 280 vb->width = icd->user_width;
259 vb->height = icd->height; 281 vb->height = icd->user_height;
260 vb->field = field; 282 vb->field = field;
261 vb->state = VIDEOBUF_NEEDS_INIT; 283 vb->state = VIDEOBUF_NEEDS_INIT;
262 } 284 }
@@ -289,7 +311,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
289 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 311 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
290 struct sh_mobile_ceu_dev *pcdev = ici->priv; 312 struct sh_mobile_ceu_dev *pcdev = ici->priv;
291 313
292 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 314 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
293 vb, vb->baddr, vb->bsize); 315 vb, vb->baddr, vb->bsize);
294 316
295 vb->state = VIDEOBUF_QUEUED; 317 vb->state = VIDEOBUF_QUEUED;
@@ -304,6 +326,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
304static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, 326static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
305 struct videobuf_buffer *vb) 327 struct videobuf_buffer *vb)
306{ 328{
329 struct soc_camera_device *icd = vq->priv_data;
330 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
331 struct sh_mobile_ceu_dev *pcdev = ici->priv;
332 unsigned long flags;
333
334 spin_lock_irqsave(&pcdev->lock, flags);
335
336 if (pcdev->active == vb) {
337 /* disable capture (release DMA buffer), reset */
338 ceu_write(pcdev, CAPSR, 1 << 16);
339 pcdev->active = NULL;
340 }
341
342 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
343 !list_empty(&vb->queue)) {
344 vb->state = VIDEOBUF_ERROR;
345 list_del_init(&vb->queue);
346 }
347
348 spin_unlock_irqrestore(&pcdev->lock, flags);
349
307 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); 350 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb));
308} 351}
309 352
@@ -323,6 +366,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
323 spin_lock_irqsave(&pcdev->lock, flags); 366 spin_lock_irqsave(&pcdev->lock, flags);
324 367
325 vb = pcdev->active; 368 vb = pcdev->active;
369 if (!vb)
370 /* Stale interrupt from a released buffer */
371 goto out;
372
326 list_del_init(&vb->queue); 373 list_del_init(&vb->queue);
327 374
328 if (!list_empty(&pcdev->capture)) 375 if (!list_empty(&pcdev->capture))
@@ -337,6 +384,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
337 do_gettimeofday(&vb->ts); 384 do_gettimeofday(&vb->ts);
338 vb->field_count++; 385 vb->field_count++;
339 wake_up(&vb->done); 386 wake_up(&vb->done);
387
388out:
340 spin_unlock_irqrestore(&pcdev->lock, flags); 389 spin_unlock_irqrestore(&pcdev->lock, flags);
341 390
342 return IRQ_HANDLED; 391 return IRQ_HANDLED;
@@ -347,28 +396,23 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
347{ 396{
348 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 397 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
349 struct sh_mobile_ceu_dev *pcdev = ici->priv; 398 struct sh_mobile_ceu_dev *pcdev = ici->priv;
350 int ret = -EBUSY;
351 399
352 if (pcdev->icd) 400 if (pcdev->icd)
353 goto err; 401 return -EBUSY;
354 402
355 dev_info(&icd->dev, 403 dev_info(icd->dev.parent,
356 "SuperH Mobile CEU driver attached to camera %d\n", 404 "SuperH Mobile CEU driver attached to camera %d\n",
357 icd->devnum); 405 icd->devnum);
358 406
359 ret = icd->ops->init(icd); 407 clk_enable(pcdev->clk);
360 if (ret)
361 goto err;
362
363 pm_runtime_get_sync(ici->dev);
364 408
365 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 409 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
366 while (ceu_read(pcdev, CSTSR) & 1) 410 while (ceu_read(pcdev, CSTSR) & 1)
367 msleep(1); 411 msleep(1);
368 412
369 pcdev->icd = icd; 413 pcdev->icd = icd;
370err: 414
371 return ret; 415 return 0;
372} 416}
373 417
374/* Called with .video_lock held */ 418/* Called with .video_lock held */
@@ -394,25 +438,151 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
394 } 438 }
395 spin_unlock_irqrestore(&pcdev->lock, flags); 439 spin_unlock_irqrestore(&pcdev->lock, flags);
396 440
397 pm_runtime_put_sync(ici->dev); 441 clk_disable(pcdev->clk);
398 442
399 icd->ops->release(icd); 443 dev_info(icd->dev.parent,
400
401 dev_info(&icd->dev,
402 "SuperH Mobile CEU driver detached from camera %d\n", 444 "SuperH Mobile CEU driver detached from camera %d\n",
403 icd->devnum); 445 icd->devnum);
404 446
405 pcdev->icd = NULL; 447 pcdev->icd = NULL;
406} 448}
407 449
450/*
451 * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
452 * in SH7722 Hardware Manual
453 */
454static unsigned int size_dst(unsigned int src, unsigned int scale)
455{
456 unsigned int mant_pre = scale >> 12;
457 if (!src || !scale)
458 return src;
459 return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
460 mant_pre * 4096 / scale + 1;
461}
462
463static u16 calc_scale(unsigned int src, unsigned int *dst)
464{
465 u16 scale;
466
467 if (src == *dst)
468 return 0;
469
470 scale = (src * 4096 / *dst) & ~7;
471
472 while (scale > 4096 && size_dst(src, scale) < *dst)
473 scale -= 8;
474
475 *dst = size_dst(src, scale);
476
477 return scale;
478}
479
480/* rect is guaranteed to not exceed the scaled camera rectangle */
481static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
482 unsigned int out_width,
483 unsigned int out_height)
484{
485 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
486 struct sh_mobile_ceu_cam *cam = icd->host_priv;
487 struct v4l2_rect *rect = &cam->ceu_rect;
488 struct sh_mobile_ceu_dev *pcdev = ici->priv;
489 unsigned int height, width, cdwdr_width, in_width, in_height;
490 unsigned int left_offset, top_offset;
491 u32 camor;
492
493 dev_dbg(icd->dev.parent, "Crop %ux%u@%u:%u\n",
494 rect->width, rect->height, rect->left, rect->top);
495
496 left_offset = rect->left;
497 top_offset = rect->top;
498
499 if (pcdev->image_mode) {
500 in_width = rect->width;
501 if (!pcdev->is_16bit) {
502 in_width *= 2;
503 left_offset *= 2;
504 }
505 width = cdwdr_width = out_width;
506 } else {
507 unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3;
508
509 width = out_width * w_factor / 2;
510
511 if (!pcdev->is_16bit)
512 w_factor *= 2;
513
514 in_width = rect->width * w_factor / 2;
515 left_offset = left_offset * w_factor / 2;
516
517 cdwdr_width = width * 2;
518 }
519
520 height = out_height;
521 in_height = rect->height;
522 if (pcdev->is_interlaced) {
523 height /= 2;
524 in_height /= 2;
525 top_offset /= 2;
526 cdwdr_width *= 2;
527 }
528
529 /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
530 camor = left_offset | (top_offset << 16);
531
532 dev_geo(icd->dev.parent,
533 "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
534 (in_height << 16) | in_width, (height << 16) | width,
535 cdwdr_width);
536
537 ceu_write(pcdev, CAMOR, camor);
538 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
539 ceu_write(pcdev, CFSZR, (height << 16) | width);
540 ceu_write(pcdev, CDWDR, cdwdr_width);
541}
542
543static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
544{
545 u32 capsr = ceu_read(pcdev, CAPSR);
546 ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
547 return capsr;
548}
549
550static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
551{
552 unsigned long timeout = jiffies + 10 * HZ;
553
554 /*
555 * Wait until the end of the current frame. It can take a long time,
556 * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
557 */
558 while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
559 msleep(1);
560
561 if (time_after(jiffies, timeout)) {
562 dev_err(pcdev->ici.v4l2_dev.dev,
563 "Timeout waiting for frame end! Interface problem?\n");
564 return;
565 }
566
567 /* Wait until reset clears, this shall not hang... */
568 while (ceu_read(pcdev, CAPSR) & (1 << 16))
569 udelay(10);
570
571 /* Anything to restore? */
572 if (capsr & ~(1 << 16))
573 ceu_write(pcdev, CAPSR, capsr);
574}
575
408static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 576static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
409 __u32 pixfmt) 577 __u32 pixfmt)
410{ 578{
411 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 579 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
412 struct sh_mobile_ceu_dev *pcdev = ici->priv; 580 struct sh_mobile_ceu_dev *pcdev = ici->priv;
413 int ret, buswidth, width, height, cfszr_width, cdwdr_width; 581 int ret;
414 unsigned long camera_flags, common_flags, value; 582 unsigned long camera_flags, common_flags, value;
415 int yuv_mode, yuv_lineskip; 583 int yuv_lineskip;
584 struct sh_mobile_ceu_cam *cam = icd->host_priv;
585 u32 capsr = capture_save_reset(pcdev);
416 586
417 camera_flags = icd->ops->query_bus_param(icd); 587 camera_flags = icd->ops->query_bus_param(icd);
418 common_flags = soc_camera_bus_param_compatible(camera_flags, 588 common_flags = soc_camera_bus_param_compatible(camera_flags,
@@ -426,10 +596,10 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
426 596
427 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 597 switch (common_flags & SOCAM_DATAWIDTH_MASK) {
428 case SOCAM_DATAWIDTH_8: 598 case SOCAM_DATAWIDTH_8:
429 buswidth = 8; 599 pcdev->is_16bit = 0;
430 break; 600 break;
431 case SOCAM_DATAWIDTH_16: 601 case SOCAM_DATAWIDTH_16:
432 buswidth = 16; 602 pcdev->is_16bit = 1;
433 break; 603 break;
434 default: 604 default:
435 return -EINVAL; 605 return -EINVAL;
@@ -439,7 +609,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
439 ceu_write(pcdev, CRCMPR, 0); 609 ceu_write(pcdev, CRCMPR, 0);
440 610
441 value = 0x00000010; /* data fetch by default */ 611 value = 0x00000010; /* data fetch by default */
442 yuv_mode = yuv_lineskip = 0; 612 yuv_lineskip = 0;
443 613
444 switch (icd->current_fmt->fourcc) { 614 switch (icd->current_fmt->fourcc) {
445 case V4L2_PIX_FMT_NV12: 615 case V4L2_PIX_FMT_NV12:
@@ -448,8 +618,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
448 /* fall-through */ 618 /* fall-through */
449 case V4L2_PIX_FMT_NV16: 619 case V4L2_PIX_FMT_NV16:
450 case V4L2_PIX_FMT_NV61: 620 case V4L2_PIX_FMT_NV61:
451 yuv_mode = 1; 621 switch (cam->camera_fmt->fourcc) {
452 switch (pcdev->camera_fmt->fourcc) {
453 case V4L2_PIX_FMT_UYVY: 622 case V4L2_PIX_FMT_UYVY:
454 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ 623 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
455 break; 624 break;
@@ -473,36 +642,16 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
473 642
474 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; 643 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
475 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; 644 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
476 value |= buswidth == 16 ? 1 << 12 : 0; 645 value |= pcdev->is_16bit ? 1 << 12 : 0;
477 ceu_write(pcdev, CAMCR, value); 646 ceu_write(pcdev, CAMCR, value);
478 647
479 ceu_write(pcdev, CAPCR, 0x00300000); 648 ceu_write(pcdev, CAPCR, 0x00300000);
480 ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0); 649 ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
481 650
651 sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
482 mdelay(1); 652 mdelay(1);
483 653
484 if (yuv_mode) { 654 ceu_write(pcdev, CFLCR, pcdev->cflcr);
485 width = icd->width * 2;
486 width = buswidth == 16 ? width / 2 : width;
487 cfszr_width = cdwdr_width = icd->width;
488 } else {
489 width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
490 width = buswidth == 16 ? width / 2 : width;
491 cfszr_width = buswidth == 8 ? width / 2 : width;
492 cdwdr_width = buswidth == 16 ? width * 2 : width;
493 }
494
495 height = icd->height;
496 if (pcdev->is_interlaced) {
497 height /= 2;
498 cdwdr_width *= 2;
499 }
500
501 ceu_write(pcdev, CAMOR, 0);
502 ceu_write(pcdev, CAPWR, (height << 16) | width);
503 ceu_write(pcdev, CFLCR, 0); /* no scaling */
504 ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width);
505 ceu_write(pcdev, CLFCR, 0); /* no lowpass filter */
506 655
507 /* A few words about byte order (observed in Big Endian mode) 656 /* A few words about byte order (observed in Big Endian mode)
508 * 657 *
@@ -521,10 +670,15 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
521 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */ 670 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
522 671
523 ceu_write(pcdev, CDOCR, value); 672 ceu_write(pcdev, CDOCR, value);
524
525 ceu_write(pcdev, CDWDR, cdwdr_width);
526 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 673 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
527 674
675 dev_dbg(icd->dev.parent, "S_FMT successful for %c%c%c%c %ux%u\n",
676 pixfmt & 0xff, (pixfmt >> 8) & 0xff,
677 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
678 icd->user_width, icd->user_height);
679
680 capture_restore(pcdev, capsr);
681
528 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */ 682 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
529 return 0; 683 return 0;
530} 684}
@@ -574,24 +728,35 @@ static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
574static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, 728static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
575 struct soc_camera_format_xlate *xlate) 729 struct soc_camera_format_xlate *xlate)
576{ 730{
577 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 731 struct device *dev = icd->dev.parent;
578 int ret, k, n; 732 int ret, k, n;
579 int formats = 0; 733 int formats = 0;
734 struct sh_mobile_ceu_cam *cam;
580 735
581 ret = sh_mobile_ceu_try_bus_param(icd); 736 ret = sh_mobile_ceu_try_bus_param(icd);
582 if (ret < 0) 737 if (ret < 0)
583 return 0; 738 return 0;
584 739
740 if (!icd->host_priv) {
741 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
742 if (!cam)
743 return -ENOMEM;
744
745 icd->host_priv = cam;
746 } else {
747 cam = icd->host_priv;
748 }
749
585 /* Beginning of a pass */ 750 /* Beginning of a pass */
586 if (!idx) 751 if (!idx)
587 icd->host_priv = NULL; 752 cam->extra_fmt = NULL;
588 753
589 switch (icd->formats[idx].fourcc) { 754 switch (icd->formats[idx].fourcc) {
590 case V4L2_PIX_FMT_UYVY: 755 case V4L2_PIX_FMT_UYVY:
591 case V4L2_PIX_FMT_VYUY: 756 case V4L2_PIX_FMT_VYUY:
592 case V4L2_PIX_FMT_YUYV: 757 case V4L2_PIX_FMT_YUYV:
593 case V4L2_PIX_FMT_YVYU: 758 case V4L2_PIX_FMT_YVYU:
594 if (icd->host_priv) 759 if (cam->extra_fmt)
595 goto add_single_format; 760 goto add_single_format;
596 761
597 /* 762 /*
@@ -603,7 +768,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
603 * the host_priv pointer and check whether the format you're 768 * the host_priv pointer and check whether the format you're
604 * going to add now is already there. 769 * going to add now is already there.
605 */ 770 */
606 icd->host_priv = (void *)sh_mobile_ceu_formats; 771 cam->extra_fmt = (void *)sh_mobile_ceu_formats;
607 772
608 n = ARRAY_SIZE(sh_mobile_ceu_formats); 773 n = ARRAY_SIZE(sh_mobile_ceu_formats);
609 formats += n; 774 formats += n;
@@ -612,7 +777,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
612 xlate->cam_fmt = icd->formats + idx; 777 xlate->cam_fmt = icd->formats + idx;
613 xlate->buswidth = icd->formats[idx].depth; 778 xlate->buswidth = icd->formats[idx].depth;
614 xlate++; 779 xlate++;
615 dev_dbg(ici->dev, "Providing format %s using %s\n", 780 dev_dbg(dev, "Providing format %s using %s\n",
616 sh_mobile_ceu_formats[k].name, 781 sh_mobile_ceu_formats[k].name,
617 icd->formats[idx].name); 782 icd->formats[idx].name);
618 } 783 }
@@ -625,7 +790,7 @@ add_single_format:
625 xlate->cam_fmt = icd->formats + idx; 790 xlate->cam_fmt = icd->formats + idx;
626 xlate->buswidth = icd->formats[idx].depth; 791 xlate->buswidth = icd->formats[idx].depth;
627 xlate++; 792 xlate++;
628 dev_dbg(ici->dev, 793 dev_dbg(dev,
629 "Providing format %s in pass-through mode\n", 794 "Providing format %s in pass-through mode\n",
630 icd->formats[idx].name); 795 icd->formats[idx].name);
631 } 796 }
@@ -634,82 +799,714 @@ add_single_format:
634 return formats; 799 return formats;
635} 800}
636 801
802static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
803{
804 kfree(icd->host_priv);
805 icd->host_priv = NULL;
806}
807
808/* Check if any dimension of r1 is smaller than respective one of r2 */
809static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
810{
811 return r1->width < r2->width || r1->height < r2->height;
812}
813
814/* Check if r1 fails to cover r2 */
815static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
816{
817 return r1->left > r2->left || r1->top > r2->top ||
818 r1->left + r1->width < r2->left + r2->width ||
819 r1->top + r1->height < r2->top + r2->height;
820}
821
822static unsigned int scale_down(unsigned int size, unsigned int scale)
823{
824 return (size * 4096 + scale / 2) / scale;
825}
826
827static unsigned int scale_up(unsigned int size, unsigned int scale)
828{
829 return (size * scale + 2048) / 4096;
830}
831
832static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
833{
834 return (input * 4096 + output / 2) / output;
835}
836
837static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
838{
839 struct v4l2_crop crop;
840 struct v4l2_cropcap cap;
841 int ret;
842
843 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
844
845 ret = v4l2_subdev_call(sd, video, g_crop, &crop);
846 if (!ret) {
847 *rect = crop.c;
848 return ret;
849 }
850
851 /* Camera driver doesn't support .g_crop(), assume default rectangle */
852 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
853
854 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
855 if (ret < 0)
856 return ret;
857
858 *rect = cap.defrect;
859
860 return ret;
861}
862
863/*
864 * The common for both scaling and cropping iterative approach is:
865 * 1. try if the client can produce exactly what requested by the user
866 * 2. if (1) failed, try to double the client image until we get one big enough
867 * 3. if (2) failed, try to request the maximum image
868 */
869static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
870 struct v4l2_crop *cam_crop)
871{
872 struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
873 struct device *dev = sd->v4l2_dev->dev;
874 struct v4l2_cropcap cap;
875 int ret;
876 unsigned int width, height;
877
878 v4l2_subdev_call(sd, video, s_crop, crop);
879 ret = client_g_rect(sd, cam_rect);
880 if (ret < 0)
881 return ret;
882
883 /*
884 * Now cam_crop contains the current camera input rectangle, and it must
885 * be within camera cropcap bounds
886 */
887 if (!memcmp(rect, cam_rect, sizeof(*rect))) {
888 /* Even if camera S_CROP failed, but camera rectangle matches */
889 dev_dbg(dev, "Camera S_CROP successful for %ux%u@%u:%u\n",
890 rect->width, rect->height, rect->left, rect->top);
891 return 0;
892 }
893
894 /* Try to fix cropping, that camera hasn't managed to set */
895 dev_geo(dev, "Fix camera S_CROP for %ux%u@%u:%u to %ux%u@%u:%u\n",
896 cam_rect->width, cam_rect->height,
897 cam_rect->left, cam_rect->top,
898 rect->width, rect->height, rect->left, rect->top);
899
900 /* We need sensor maximum rectangle */
901 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
902 if (ret < 0)
903 return ret;
904
905 soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
906 cap.bounds.width);
907 soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
908 cap.bounds.height);
909
910 /*
911 * Popular special case - some cameras can only handle fixed sizes like
912 * QVGA, VGA,... Take care to avoid infinite loop.
913 */
914 width = max(cam_rect->width, 2);
915 height = max(cam_rect->height, 2);
916
917 while (!ret && (is_smaller(cam_rect, rect) ||
918 is_inside(cam_rect, rect)) &&
919 (cap.bounds.width > width || cap.bounds.height > height)) {
920
921 width *= 2;
922 height *= 2;
923
924 cam_rect->width = width;
925 cam_rect->height = height;
926
927 /*
928 * We do not know what capabilities the camera has to set up
929 * left and top borders. We could try to be smarter in iterating
930 * them, e.g., if camera current left is to the right of the
931 * target left, set it to the middle point between the current
932 * left and minimum left. But that would add too much
933 * complexity: we would have to iterate each border separately.
934 */
935 if (cam_rect->left > rect->left)
936 cam_rect->left = cap.bounds.left;
937
938 if (cam_rect->left + cam_rect->width < rect->left + rect->width)
939 cam_rect->width = rect->left + rect->width -
940 cam_rect->left;
941
942 if (cam_rect->top > rect->top)
943 cam_rect->top = cap.bounds.top;
944
945 if (cam_rect->top + cam_rect->height < rect->top + rect->height)
946 cam_rect->height = rect->top + rect->height -
947 cam_rect->top;
948
949 v4l2_subdev_call(sd, video, s_crop, cam_crop);
950 ret = client_g_rect(sd, cam_rect);
951 dev_geo(dev, "Camera S_CROP %d for %ux%u@%u:%u\n", ret,
952 cam_rect->width, cam_rect->height,
953 cam_rect->left, cam_rect->top);
954 }
955
956 /* S_CROP must not modify the rectangle */
957 if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
958 /*
959 * The camera failed to configure a suitable cropping,
960 * we cannot use the current rectangle, set to max
961 */
962 *cam_rect = cap.bounds;
963 v4l2_subdev_call(sd, video, s_crop, cam_crop);
964 ret = client_g_rect(sd, cam_rect);
965 dev_geo(dev, "Camera S_CROP %d for max %ux%u@%u:%u\n", ret,
966 cam_rect->width, cam_rect->height,
967 cam_rect->left, cam_rect->top);
968 }
969
970 return ret;
971}
972
973static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
974 unsigned int *scale_h, unsigned int *scale_v)
975{
976 struct v4l2_format f;
977 int ret;
978
979 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
980
981 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
982 if (ret < 0)
983 return ret;
984
985 *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width);
986 *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height);
987
988 return 0;
989}
990
991static int get_camera_subwin(struct soc_camera_device *icd,
992 struct v4l2_rect *cam_subrect,
993 unsigned int cam_hscale, unsigned int cam_vscale)
994{
995 struct sh_mobile_ceu_cam *cam = icd->host_priv;
996 struct v4l2_rect *ceu_rect = &cam->ceu_rect;
997
998 if (!ceu_rect->width) {
999 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1000 struct device *dev = icd->dev.parent;
1001 struct v4l2_format f;
1002 struct v4l2_pix_format *pix = &f.fmt.pix;
1003 int ret;
1004 /* First time */
1005
1006 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1007
1008 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1009 if (ret < 0)
1010 return ret;
1011
1012 dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height);
1013
1014 if (pix->width > 2560) {
1015 ceu_rect->width = 2560;
1016 ceu_rect->left = (pix->width - 2560) / 2;
1017 } else {
1018 ceu_rect->width = pix->width;
1019 ceu_rect->left = 0;
1020 }
1021
1022 if (pix->height > 1920) {
1023 ceu_rect->height = 1920;
1024 ceu_rect->top = (pix->height - 1920) / 2;
1025 } else {
1026 ceu_rect->height = pix->height;
1027 ceu_rect->top = 0;
1028 }
1029
1030 dev_geo(dev, "initialised CEU rect %ux%u@%u:%u\n",
1031 ceu_rect->width, ceu_rect->height,
1032 ceu_rect->left, ceu_rect->top);
1033 }
1034
1035 cam_subrect->width = scale_up(ceu_rect->width, cam_hscale);
1036 cam_subrect->left = scale_up(ceu_rect->left, cam_hscale);
1037 cam_subrect->height = scale_up(ceu_rect->height, cam_vscale);
1038 cam_subrect->top = scale_up(ceu_rect->top, cam_vscale);
1039
1040 return 0;
1041}
1042
1043static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f,
1044 bool ceu_can_scale)
1045{
1046 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1047 struct device *dev = icd->dev.parent;
1048 struct v4l2_pix_format *pix = &f->fmt.pix;
1049 unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h;
1050 unsigned int max_width, max_height;
1051 struct v4l2_cropcap cap;
1052 int ret;
1053
1054 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1055
1056 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1057 if (ret < 0)
1058 return ret;
1059
1060 max_width = min(cap.bounds.width, 2560);
1061 max_height = min(cap.bounds.height, 1920);
1062
1063 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1064 if (ret < 0)
1065 return ret;
1066
1067 dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height);
1068
1069 if ((width == pix->width && height == pix->height) || !ceu_can_scale)
1070 return 0;
1071
1072 /* Camera set a format, but geometry is not precise, try to improve */
1073 tmp_w = pix->width;
1074 tmp_h = pix->height;
1075
1076 /* width <= max_width && height <= max_height - guaranteed by try_fmt */
1077 while ((width > tmp_w || height > tmp_h) &&
1078 tmp_w < max_width && tmp_h < max_height) {
1079 tmp_w = min(2 * tmp_w, max_width);
1080 tmp_h = min(2 * tmp_h, max_height);
1081 pix->width = tmp_w;
1082 pix->height = tmp_h;
1083 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1084 dev_geo(dev, "Camera scaled to %ux%u\n",
1085 pix->width, pix->height);
1086 if (ret < 0) {
1087 /* This shouldn't happen */
1088 dev_err(dev, "Client failed to set format: %d\n", ret);
1089 return ret;
1090 }
1091 }
1092
1093 return 0;
1094}
1095
1096/**
1097 * @rect - camera cropped rectangle
1098 * @sub_rect - CEU cropped rectangle, mapped back to camera input area
1099 * @ceu_rect - on output calculated CEU crop rectangle
1100 */
1101static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
1102 struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect,
1103 struct v4l2_format *f, bool ceu_can_scale)
1104{
1105 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1106 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1107 struct device *dev = icd->dev.parent;
1108 struct v4l2_format f_tmp = *f;
1109 struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix;
1110 unsigned int scale_h, scale_v;
1111 int ret;
1112
1113 /* 5. Apply iterative camera S_FMT for camera user window. */
1114 ret = client_s_fmt(icd, &f_tmp, ceu_can_scale);
1115 if (ret < 0)
1116 return ret;
1117
1118 dev_geo(dev, "5: camera scaled to %ux%u\n",
1119 pix_tmp->width, pix_tmp->height);
1120
1121 /* 6. Retrieve camera output window (g_fmt) */
1122
1123 /* unneeded - it is already in "f_tmp" */
1124
1125 /* 7. Calculate new camera scales. */
1126 ret = get_camera_scales(sd, rect, &scale_h, &scale_v);
1127 if (ret < 0)
1128 return ret;
1129
1130 dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
1131
1132 cam->cam_width = pix_tmp->width;
1133 cam->cam_height = pix_tmp->height;
1134 f->fmt.pix.width = pix_tmp->width;
1135 f->fmt.pix.height = pix_tmp->height;
1136
1137 /*
1138 * 8. Calculate new CEU crop - apply camera scales to previously
1139 * calculated "effective" crop.
1140 */
1141 ceu_rect->left = scale_down(sub_rect->left, scale_h);
1142 ceu_rect->width = scale_down(sub_rect->width, scale_h);
1143 ceu_rect->top = scale_down(sub_rect->top, scale_v);
1144 ceu_rect->height = scale_down(sub_rect->height, scale_v);
1145
1146 dev_geo(dev, "8: new CEU rect %ux%u@%u:%u\n",
1147 ceu_rect->width, ceu_rect->height,
1148 ceu_rect->left, ceu_rect->top);
1149
1150 return 0;
1151}
1152
1153/* Get combined scales */
1154static int get_scales(struct soc_camera_device *icd,
1155 unsigned int *scale_h, unsigned int *scale_v)
1156{
1157 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1158 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1159 struct v4l2_crop cam_crop;
1160 unsigned int width_in, height_in;
1161 int ret;
1162
1163 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1164
1165 ret = client_g_rect(sd, &cam_crop.c);
1166 if (ret < 0)
1167 return ret;
1168
1169 ret = get_camera_scales(sd, &cam_crop.c, scale_h, scale_v);
1170 if (ret < 0)
1171 return ret;
1172
1173 width_in = scale_up(cam->ceu_rect.width, *scale_h);
1174 height_in = scale_up(cam->ceu_rect.height, *scale_v);
1175
1176 *scale_h = calc_generic_scale(cam->ceu_rect.width, icd->user_width);
1177 *scale_v = calc_generic_scale(cam->ceu_rect.height, icd->user_height);
1178
1179 return 0;
1180}
1181
1182/*
1183 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
1184 * framerate by always requesting the maximum image from the client. See
1185 * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of
1186 * scaling and cropping algorithms and for the meaning of referenced here steps.
1187 */
637static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 1188static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
638 struct v4l2_rect *rect) 1189 struct v4l2_crop *a)
639{ 1190{
640 return icd->ops->set_crop(icd, rect); 1191 struct v4l2_rect *rect = &a->c;
1192 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1193 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1194 struct v4l2_crop cam_crop;
1195 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1196 struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect;
1197 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1198 struct device *dev = icd->dev.parent;
1199 struct v4l2_format f;
1200 struct v4l2_pix_format *pix = &f.fmt.pix;
1201 unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v,
1202 out_width, out_height;
1203 u32 capsr, cflcr;
1204 int ret;
1205
1206 /* 1. Calculate current combined scales. */
1207 ret = get_scales(icd, &scale_comb_h, &scale_comb_v);
1208 if (ret < 0)
1209 return ret;
1210
1211 dev_geo(dev, "1: combined scales %u:%u\n", scale_comb_h, scale_comb_v);
1212
1213 /* 2. Apply iterative camera S_CROP for new input window. */
1214 ret = client_s_crop(sd, a, &cam_crop);
1215 if (ret < 0)
1216 return ret;
1217
1218 dev_geo(dev, "2: camera cropped to %ux%u@%u:%u\n",
1219 cam_rect->width, cam_rect->height,
1220 cam_rect->left, cam_rect->top);
1221
1222 /* On success cam_crop contains current camera crop */
1223
1224 /*
1225 * 3. If old combined scales applied to new crop produce an impossible
1226 * user window, adjust scales to produce nearest possible window.
1227 */
1228 out_width = scale_down(rect->width, scale_comb_h);
1229 out_height = scale_down(rect->height, scale_comb_v);
1230
1231 if (out_width > 2560)
1232 out_width = 2560;
1233 else if (out_width < 2)
1234 out_width = 2;
1235
1236 if (out_height > 1920)
1237 out_height = 1920;
1238 else if (out_height < 4)
1239 out_height = 4;
1240
1241 dev_geo(dev, "3: Adjusted output %ux%u\n", out_width, out_height);
1242
1243 /* 4. Use G_CROP to retrieve actual input window: already in cam_crop */
1244
1245 /*
1246 * 5. Using actual input window and calculated combined scales calculate
1247 * camera target output window.
1248 */
1249 pix->width = scale_down(cam_rect->width, scale_comb_h);
1250 pix->height = scale_down(cam_rect->height, scale_comb_v);
1251
1252 dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height);
1253
1254 /* 6. - 9. */
1255 pix->pixelformat = cam->camera_fmt->fourcc;
1256 pix->colorspace = cam->camera_fmt->colorspace;
1257
1258 capsr = capture_save_reset(pcdev);
1259 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1260
1261 /* Make relative to camera rectangle */
1262 rect->left -= cam_rect->left;
1263 rect->top -= cam_rect->top;
1264
1265 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1266
1267 ret = client_scale(icd, cam_rect, rect, ceu_rect, &f,
1268 pcdev->image_mode && !pcdev->is_interlaced);
1269
1270 dev_geo(dev, "6-9: %d\n", ret);
1271
1272 /* 10. Use CEU cropping to crop to the new window. */
1273 sh_mobile_ceu_set_rect(icd, out_width, out_height);
1274
1275 dev_geo(dev, "10: CEU cropped to %ux%u@%u:%u\n",
1276 ceu_rect->width, ceu_rect->height,
1277 ceu_rect->left, ceu_rect->top);
1278
1279 /*
1280 * 11. Calculate CEU scales from camera scales from results of (10) and
1281 * user window from (3)
1282 */
1283 scale_ceu_h = calc_scale(ceu_rect->width, &out_width);
1284 scale_ceu_v = calc_scale(ceu_rect->height, &out_height);
1285
1286 dev_geo(dev, "11: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1287
1288 /* 12. Apply CEU scales. */
1289 cflcr = scale_ceu_h | (scale_ceu_v << 16);
1290 if (cflcr != pcdev->cflcr) {
1291 pcdev->cflcr = cflcr;
1292 ceu_write(pcdev, CFLCR, cflcr);
1293 }
1294
1295 /* Restore capture */
1296 if (pcdev->active)
1297 capsr |= 1;
1298 capture_restore(pcdev, capsr);
1299
1300 icd->user_width = out_width;
1301 icd->user_height = out_height;
1302
1303 /* Even if only camera cropping succeeded */
1304 return ret;
641} 1305}
642 1306
1307/* Similar to set_crop multistage iterative algorithm */
643static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, 1308static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
644 struct v4l2_format *f) 1309 struct v4l2_format *f)
645{ 1310{
646 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1311 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
647 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1312 struct sh_mobile_ceu_dev *pcdev = ici->priv;
648 __u32 pixfmt = f->fmt.pix.pixelformat; 1313 struct sh_mobile_ceu_cam *cam = icd->host_priv;
649 const struct soc_camera_format_xlate *xlate; 1314 struct v4l2_pix_format *pix = &f->fmt.pix;
650 struct v4l2_format cam_f = *f; 1315 struct v4l2_format cam_f = *f;
1316 struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix;
1317 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1318 struct device *dev = icd->dev.parent;
1319 __u32 pixfmt = pix->pixelformat;
1320 const struct soc_camera_format_xlate *xlate;
1321 struct v4l2_crop cam_crop;
1322 struct v4l2_rect *cam_rect = &cam_crop.c, cam_subrect, ceu_rect;
1323 unsigned int scale_cam_h, scale_cam_v;
1324 u16 scale_v, scale_h;
651 int ret; 1325 int ret;
1326 bool is_interlaced, image_mode;
1327
1328 switch (pix->field) {
1329 case V4L2_FIELD_INTERLACED:
1330 is_interlaced = true;
1331 break;
1332 case V4L2_FIELD_ANY:
1333 default:
1334 pix->field = V4L2_FIELD_NONE;
1335 /* fall-through */
1336 case V4L2_FIELD_NONE:
1337 is_interlaced = false;
1338 break;
1339 }
652 1340
653 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1341 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
654 if (!xlate) { 1342 if (!xlate) {
655 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1343 dev_warn(dev, "Format %x not found\n", pixfmt);
656 return -EINVAL; 1344 return -EINVAL;
657 } 1345 }
658 1346
659 cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc; 1347 /* 1. Calculate current camera scales. */
660 ret = icd->ops->set_fmt(icd, &cam_f); 1348 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
661 1349
662 if (!ret) { 1350 ret = client_g_rect(sd, cam_rect);
663 icd->buswidth = xlate->buswidth; 1351 if (ret < 0)
664 icd->current_fmt = xlate->host_fmt; 1352 return ret;
665 pcdev->camera_fmt = xlate->cam_fmt; 1353
1354 ret = get_camera_scales(sd, cam_rect, &scale_cam_h, &scale_cam_v);
1355 if (ret < 0)
1356 return ret;
1357
1358 dev_geo(dev, "1: camera scales %u:%u\n", scale_cam_h, scale_cam_v);
1359
1360 /*
1361 * 2. Calculate "effective" input crop (sensor subwindow) - CEU crop
1362 * scaled back at current camera scales onto input window.
1363 */
1364 ret = get_camera_subwin(icd, &cam_subrect, scale_cam_h, scale_cam_v);
1365 if (ret < 0)
1366 return ret;
1367
1368 dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
1369 cam_subrect.width, cam_subrect.height,
1370 cam_subrect.left, cam_subrect.top);
1371
1372 /*
1373 * 3. Calculate new combined scales from "effective" input window to
1374 * requested user window.
1375 */
1376 scale_h = calc_generic_scale(cam_subrect.width, pix->width);
1377 scale_v = calc_generic_scale(cam_subrect.height, pix->height);
1378
1379 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1380
1381 /*
1382 * 4. Calculate camera output window by applying combined scales to real
1383 * input window.
1384 */
1385 cam_pix->width = scale_down(cam_rect->width, scale_h);
1386 cam_pix->height = scale_down(cam_rect->height, scale_v);
1387 cam_pix->pixelformat = xlate->cam_fmt->fourcc;
1388
1389 switch (pixfmt) {
1390 case V4L2_PIX_FMT_NV12:
1391 case V4L2_PIX_FMT_NV21:
1392 case V4L2_PIX_FMT_NV16:
1393 case V4L2_PIX_FMT_NV61:
1394 image_mode = true;
1395 break;
1396 default:
1397 image_mode = false;
666 } 1398 }
667 1399
668 return ret; 1400 dev_geo(dev, "4: camera output %ux%u\n",
1401 cam_pix->width, cam_pix->height);
1402
1403 /* 5. - 9. */
1404 ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f,
1405 image_mode && !is_interlaced);
1406
1407 dev_geo(dev, "5-9: client scale %d\n", ret);
1408
1409 /* Done with the camera. Now see if we can improve the result */
1410
1411 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1412 ret, cam_pix->width, cam_pix->height, pix->width, pix->height);
1413 if (ret < 0)
1414 return ret;
1415
1416 /* 10. Use CEU scaling to scale to the requested user window. */
1417
1418 /* We cannot scale up */
1419 if (pix->width > cam_pix->width)
1420 pix->width = cam_pix->width;
1421 if (pix->width > ceu_rect.width)
1422 pix->width = ceu_rect.width;
1423
1424 if (pix->height > cam_pix->height)
1425 pix->height = cam_pix->height;
1426 if (pix->height > ceu_rect.height)
1427 pix->height = ceu_rect.height;
1428
1429 /* Let's rock: scale pix->{width x height} down to width x height */
1430 scale_h = calc_scale(ceu_rect.width, &pix->width);
1431 scale_v = calc_scale(ceu_rect.height, &pix->height);
1432
1433 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
1434 ceu_rect.width, scale_h, pix->width,
1435 ceu_rect.height, scale_v, pix->height);
1436
1437 pcdev->cflcr = scale_h | (scale_v << 16);
1438
1439 icd->buswidth = xlate->buswidth;
1440 icd->current_fmt = xlate->host_fmt;
1441 cam->camera_fmt = xlate->cam_fmt;
1442 cam->ceu_rect = ceu_rect;
1443
1444 pcdev->is_interlaced = is_interlaced;
1445 pcdev->image_mode = image_mode;
1446
1447 return 0;
669} 1448}
670 1449
671static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1450static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
672 struct v4l2_format *f) 1451 struct v4l2_format *f)
673{ 1452{
674 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
675 struct sh_mobile_ceu_dev *pcdev = ici->priv;
676 const struct soc_camera_format_xlate *xlate; 1453 const struct soc_camera_format_xlate *xlate;
677 __u32 pixfmt = f->fmt.pix.pixelformat; 1454 struct v4l2_pix_format *pix = &f->fmt.pix;
1455 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1456 __u32 pixfmt = pix->pixelformat;
1457 int width, height;
678 int ret; 1458 int ret;
679 1459
680 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1460 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
681 if (!xlate) { 1461 if (!xlate) {
682 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1462 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
683 return -EINVAL; 1463 return -EINVAL;
684 } 1464 }
685 1465
686 /* FIXME: calculate using depth and bus width */ 1466 /* FIXME: calculate using depth and bus width */
687 1467
688 v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1, 1468 v4l_bound_align_image(&pix->width, 2, 2560, 1,
689 &f->fmt.pix.height, 4, 1920, 2, 0); 1469 &pix->height, 4, 1920, 2, 0);
1470
1471 width = pix->width;
1472 height = pix->height;
690 1473
691 f->fmt.pix.bytesperline = f->fmt.pix.width * 1474 pix->bytesperline = pix->width *
692 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1475 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
693 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 1476 pix->sizeimage = pix->height * pix->bytesperline;
1477
1478 pix->pixelformat = xlate->cam_fmt->fourcc;
694 1479
695 /* limit to sensor capabilities */ 1480 /* limit to sensor capabilities */
696 ret = icd->ops->try_fmt(icd, f); 1481 ret = v4l2_subdev_call(sd, video, try_fmt, f);
1482 pix->pixelformat = pixfmt;
697 if (ret < 0) 1483 if (ret < 0)
698 return ret; 1484 return ret;
699 1485
700 switch (f->fmt.pix.field) { 1486 switch (pixfmt) {
701 case V4L2_FIELD_INTERLACED: 1487 case V4L2_PIX_FMT_NV12:
702 pcdev->is_interlaced = 1; 1488 case V4L2_PIX_FMT_NV21:
703 break; 1489 case V4L2_PIX_FMT_NV16:
704 case V4L2_FIELD_ANY: 1490 case V4L2_PIX_FMT_NV61:
705 f->fmt.pix.field = V4L2_FIELD_NONE; 1491 /* FIXME: check against rect_max after converting soc-camera */
706 /* fall-through */ 1492 /* We can scale precisely, need a bigger image from camera */
707 case V4L2_FIELD_NONE: 1493 if (pix->width < width || pix->height < height) {
708 pcdev->is_interlaced = 0; 1494 int tmp_w = pix->width, tmp_h = pix->height;
709 break; 1495 pix->width = 2560;
710 default: 1496 pix->height = 1920;
711 ret = -EINVAL; 1497 ret = v4l2_subdev_call(sd, video, try_fmt, f);
712 break; 1498 if (ret < 0) {
1499 /* Shouldn't actually happen... */
1500 dev_err(icd->dev.parent,
1501 "FIXME: try_fmt() returned %d\n", ret);
1502 pix->width = tmp_w;
1503 pix->height = tmp_h;
1504 }
1505 }
1506 if (pix->width > width)
1507 pix->width = width;
1508 if (pix->height > height)
1509 pix->height = height;
713 } 1510 }
714 1511
715 return ret; 1512 return ret;
@@ -769,7 +1566,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
769 1566
770 videobuf_queue_dma_contig_init(q, 1567 videobuf_queue_dma_contig_init(q,
771 &sh_mobile_ceu_videobuf_ops, 1568 &sh_mobile_ceu_videobuf_ops,
772 ici->dev, &pcdev->lock, 1569 icd->dev.parent, &pcdev->lock,
773 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1570 V4L2_BUF_TYPE_VIDEO_CAPTURE,
774 pcdev->is_interlaced ? 1571 pcdev->is_interlaced ?
775 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, 1572 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -777,22 +1574,76 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
777 icd); 1574 icd);
778} 1575}
779 1576
1577static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1578 struct v4l2_control *ctrl)
1579{
1580 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1581 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1582 u32 val;
1583
1584 switch (ctrl->id) {
1585 case V4L2_CID_SHARPNESS:
1586 val = ceu_read(pcdev, CLFCR);
1587 ctrl->value = val ^ 1;
1588 return 0;
1589 }
1590 return -ENOIOCTLCMD;
1591}
1592
1593static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1594 struct v4l2_control *ctrl)
1595{
1596 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1597 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1598
1599 switch (ctrl->id) {
1600 case V4L2_CID_SHARPNESS:
1601 switch (icd->current_fmt->fourcc) {
1602 case V4L2_PIX_FMT_NV12:
1603 case V4L2_PIX_FMT_NV21:
1604 case V4L2_PIX_FMT_NV16:
1605 case V4L2_PIX_FMT_NV61:
1606 ceu_write(pcdev, CLFCR, !ctrl->value);
1607 return 0;
1608 }
1609 return -EINVAL;
1610 }
1611 return -ENOIOCTLCMD;
1612}
1613
1614static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
1615 {
1616 .id = V4L2_CID_SHARPNESS,
1617 .type = V4L2_CTRL_TYPE_BOOLEAN,
1618 .name = "Low-pass filter",
1619 .minimum = 0,
1620 .maximum = 1,
1621 .step = 1,
1622 .default_value = 0,
1623 },
1624};
1625
780static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { 1626static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
781 .owner = THIS_MODULE, 1627 .owner = THIS_MODULE,
782 .add = sh_mobile_ceu_add_device, 1628 .add = sh_mobile_ceu_add_device,
783 .remove = sh_mobile_ceu_remove_device, 1629 .remove = sh_mobile_ceu_remove_device,
784 .get_formats = sh_mobile_ceu_get_formats, 1630 .get_formats = sh_mobile_ceu_get_formats,
1631 .put_formats = sh_mobile_ceu_put_formats,
785 .set_crop = sh_mobile_ceu_set_crop, 1632 .set_crop = sh_mobile_ceu_set_crop,
786 .set_fmt = sh_mobile_ceu_set_fmt, 1633 .set_fmt = sh_mobile_ceu_set_fmt,
787 .try_fmt = sh_mobile_ceu_try_fmt, 1634 .try_fmt = sh_mobile_ceu_try_fmt,
1635 .set_ctrl = sh_mobile_ceu_set_ctrl,
1636 .get_ctrl = sh_mobile_ceu_get_ctrl,
788 .reqbufs = sh_mobile_ceu_reqbufs, 1637 .reqbufs = sh_mobile_ceu_reqbufs,
789 .poll = sh_mobile_ceu_poll, 1638 .poll = sh_mobile_ceu_poll,
790 .querycap = sh_mobile_ceu_querycap, 1639 .querycap = sh_mobile_ceu_querycap,
791 .set_bus_param = sh_mobile_ceu_set_bus_param, 1640 .set_bus_param = sh_mobile_ceu_set_bus_param,
792 .init_videobuf = sh_mobile_ceu_init_videobuf, 1641 .init_videobuf = sh_mobile_ceu_init_videobuf,
1642 .controls = sh_mobile_ceu_controls,
1643 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
793}; 1644};
794 1645
795static int sh_mobile_ceu_probe(struct platform_device *pdev) 1646static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
796{ 1647{
797 struct sh_mobile_ceu_dev *pcdev; 1648 struct sh_mobile_ceu_dev *pcdev;
798 struct resource *res; 1649 struct resource *res;
@@ -865,7 +1716,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
865 pm_runtime_resume(&pdev->dev); 1716 pm_runtime_resume(&pdev->dev);
866 1717
867 pcdev->ici.priv = pcdev; 1718 pcdev->ici.priv = pcdev;
868 pcdev->ici.dev = &pdev->dev; 1719 pcdev->ici.v4l2_dev.dev = &pdev->dev;
869 pcdev->ici.nr = pdev->id; 1720 pcdev->ici.nr = pdev->id;
870 pcdev->ici.drv_name = dev_name(&pdev->dev); 1721 pcdev->ici.drv_name = dev_name(&pdev->dev);
871 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 1722 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
@@ -889,7 +1740,7 @@ exit:
889 return err; 1740 return err;
890} 1741}
891 1742
892static int sh_mobile_ceu_remove(struct platform_device *pdev) 1743static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
893{ 1744{
894 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); 1745 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
895 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, 1746 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
@@ -927,7 +1778,7 @@ static struct platform_driver sh_mobile_ceu_driver = {
927 .pm = &sh_mobile_ceu_dev_pm_ops, 1778 .pm = &sh_mobile_ceu_dev_pm_ops,
928 }, 1779 },
929 .probe = sh_mobile_ceu_probe, 1780 .probe = sh_mobile_ceu_probe,
930 .remove = sh_mobile_ceu_remove, 1781 .remove = __exit_p(sh_mobile_ceu_remove),
931}; 1782};
932 1783
933static int __init sh_mobile_ceu_init(void) 1784static int __init sh_mobile_ceu_init(void)
@@ -946,3 +1797,4 @@ module_exit(sh_mobile_ceu_exit);
946MODULE_DESCRIPTION("SuperH Mobile CEU driver"); 1797MODULE_DESCRIPTION("SuperH Mobile CEU driver");
947MODULE_AUTHOR("Magnus Damm"); 1798MODULE_AUTHOR("Magnus Damm");
948MODULE_LICENSE("GPL"); 1799MODULE_LICENSE("GPL");
1800MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 23edfdc4d4bc..9d84c94e8a40 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1954,8 +1954,10 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1954 (!list_empty(&cam->outqueue)) || 1954 (!list_empty(&cam->outqueue)) ||
1955 (cam->state & DEV_DISCONNECTED) || 1955 (cam->state & DEV_DISCONNECTED) ||
1956 (cam->state & DEV_MISCONFIGURED), 1956 (cam->state & DEV_MISCONFIGURED),
1957 cam->module_param.frame_timeout * 1957 msecs_to_jiffies(
1958 1000 * msecs_to_jiffies(1) ); 1958 cam->module_param.frame_timeout * 1000
1959 )
1960 );
1959 if (timeout < 0) { 1961 if (timeout < 0) {
1960 mutex_unlock(&cam->fileop_mutex); 1962 mutex_unlock(&cam->fileop_mutex);
1961 return timeout; 1963 return timeout;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 9f5ae8167855..59aa7a3694c2 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -21,15 +21,15 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28 28
29#include <media/soc_camera.h> 29#include <media/soc_camera.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-dev.h>
32#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-dev.h>
33#include <media/videobuf-core.h> 33#include <media/videobuf-core.h>
34 34
35/* Default to VGA resolution */ 35/* Default to VGA resolution */
@@ -38,7 +38,7 @@
38 38
39static LIST_HEAD(hosts); 39static LIST_HEAD(hosts);
40static LIST_HEAD(devices); 40static LIST_HEAD(devices);
41static DEFINE_MUTEX(list_lock); 41static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
42 42
43const struct soc_camera_data_format *soc_camera_format_by_fourcc( 43const struct soc_camera_data_format *soc_camera_format_by_fourcc(
44 struct soc_camera_device *icd, unsigned int fourcc) 44 struct soc_camera_device *icd, unsigned int fourcc)
@@ -152,12 +152,9 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
152{ 152{
153 struct soc_camera_file *icf = file->private_data; 153 struct soc_camera_file *icf = file->private_data;
154 struct soc_camera_device *icd = icf->icd; 154 struct soc_camera_device *icd = icf->icd;
155 int ret = 0; 155 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
156
157 if (icd->ops->set_std)
158 ret = icd->ops->set_std(icd, a);
159 156
160 return ret; 157 return v4l2_subdev_call(sd, core, s_std, *a);
161} 158}
162 159
163static int soc_camera_reqbufs(struct file *file, void *priv, 160static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -170,8 +167,6 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
170 167
171 WARN_ON(priv != file->private_data); 168 WARN_ON(priv != file->private_data);
172 169
173 dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory);
174
175 ret = videobuf_reqbufs(&icf->vb_vidq, p); 170 ret = videobuf_reqbufs(&icf->vb_vidq, p);
176 if (ret < 0) 171 if (ret < 0)
177 return ret; 172 return ret;
@@ -209,10 +204,11 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
209 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); 204 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
210} 205}
211 206
207/* Always entered with .video_lock held */
212static int soc_camera_init_user_formats(struct soc_camera_device *icd) 208static int soc_camera_init_user_formats(struct soc_camera_device *icd)
213{ 209{
214 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 210 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
215 int i, fmts = 0; 211 int i, fmts = 0, ret;
216 212
217 if (!ici->ops->get_formats) 213 if (!ici->ops->get_formats)
218 /* 214 /*
@@ -225,8 +221,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
225 * First pass - only count formats this host-sensor 221 * First pass - only count formats this host-sensor
226 * configuration can provide 222 * configuration can provide
227 */ 223 */
228 for (i = 0; i < icd->num_formats; i++) 224 for (i = 0; i < icd->num_formats; i++) {
229 fmts += ici->ops->get_formats(icd, i, NULL); 225 ret = ici->ops->get_formats(icd, i, NULL);
226 if (ret < 0)
227 return ret;
228 fmts += ret;
229 }
230 230
231 if (!fmts) 231 if (!fmts)
232 return -ENXIO; 232 return -ENXIO;
@@ -248,20 +248,39 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
248 icd->user_formats[i].cam_fmt = icd->formats + i; 248 icd->user_formats[i].cam_fmt = icd->formats + i;
249 icd->user_formats[i].buswidth = icd->formats[i].depth; 249 icd->user_formats[i].buswidth = icd->formats[i].depth;
250 } else { 250 } else {
251 fmts += ici->ops->get_formats(icd, i, 251 ret = ici->ops->get_formats(icd, i,
252 &icd->user_formats[fmts]); 252 &icd->user_formats[fmts]);
253 if (ret < 0)
254 goto egfmt;
255 fmts += ret;
253 } 256 }
254 257
255 icd->current_fmt = icd->user_formats[0].host_fmt; 258 icd->current_fmt = icd->user_formats[0].host_fmt;
256 259
257 return 0; 260 return 0;
261
262egfmt:
263 icd->num_user_formats = 0;
264 vfree(icd->user_formats);
265 return ret;
258} 266}
259 267
268/* Always entered with .video_lock held */
260static void soc_camera_free_user_formats(struct soc_camera_device *icd) 269static void soc_camera_free_user_formats(struct soc_camera_device *icd)
261{ 270{
271 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
272
273 if (ici->ops->put_formats)
274 ici->ops->put_formats(icd);
275 icd->current_fmt = NULL;
276 icd->num_user_formats = 0;
262 vfree(icd->user_formats); 277 vfree(icd->user_formats);
278 icd->user_formats = NULL;
263} 279}
264 280
281#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
282 ((x) >> 24) & 0xff
283
265/* Called with .vb_lock held */ 284/* Called with .vb_lock held */
266static int soc_camera_set_fmt(struct soc_camera_file *icf, 285static int soc_camera_set_fmt(struct soc_camera_file *icf,
267 struct v4l2_format *f) 286 struct v4l2_format *f)
@@ -271,6 +290,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
271 struct v4l2_pix_format *pix = &f->fmt.pix; 290 struct v4l2_pix_format *pix = &f->fmt.pix;
272 int ret; 291 int ret;
273 292
293 dev_dbg(&icd->dev, "S_FMT(%c%c%c%c, %ux%u)\n",
294 pixfmtstr(pix->pixelformat), pix->width, pix->height);
295
274 /* We always call try_fmt() before set_fmt() or set_crop() */ 296 /* We always call try_fmt() before set_fmt() or set_crop() */
275 ret = ici->ops->try_fmt(icd, f); 297 ret = ici->ops->try_fmt(icd, f);
276 if (ret < 0) 298 if (ret < 0)
@@ -281,13 +303,13 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
281 return ret; 303 return ret;
282 } else if (!icd->current_fmt || 304 } else if (!icd->current_fmt ||
283 icd->current_fmt->fourcc != pix->pixelformat) { 305 icd->current_fmt->fourcc != pix->pixelformat) {
284 dev_err(ici->dev, 306 dev_err(&icd->dev,
285 "Host driver hasn't set up current format correctly!\n"); 307 "Host driver hasn't set up current format correctly!\n");
286 return -EINVAL; 308 return -EINVAL;
287 } 309 }
288 310
289 icd->width = pix->width; 311 icd->user_width = pix->width;
290 icd->height = pix->height; 312 icd->user_height = pix->height;
291 icf->vb_vidq.field = 313 icf->vb_vidq.field =
292 icd->field = pix->field; 314 icd->field = pix->field;
293 315
@@ -296,7 +318,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
296 f->type); 318 f->type);
297 319
298 dev_dbg(&icd->dev, "set width: %d height: %d\n", 320 dev_dbg(&icd->dev, "set width: %d height: %d\n",
299 icd->width, icd->height); 321 icd->user_width, icd->user_height);
300 322
301 /* set physical bus parameters */ 323 /* set physical bus parameters */
302 return ici->ops->set_bus_param(icd, pix->pixelformat); 324 return ici->ops->set_bus_param(icd, pix->pixelformat);
@@ -304,30 +326,24 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
304 326
305static int soc_camera_open(struct file *file) 327static int soc_camera_open(struct file *file)
306{ 328{
307 struct video_device *vdev; 329 struct video_device *vdev = video_devdata(file);
308 struct soc_camera_device *icd; 330 struct soc_camera_device *icd = container_of(vdev->parent,
331 struct soc_camera_device,
332 dev);
333 struct soc_camera_link *icl = to_soc_camera_link(icd);
309 struct soc_camera_host *ici; 334 struct soc_camera_host *ici;
310 struct soc_camera_file *icf; 335 struct soc_camera_file *icf;
311 int ret; 336 int ret;
312 337
313 icf = vmalloc(sizeof(*icf)); 338 if (!icd->ops)
314 if (!icf) 339 /* No device driver attached */
315 return -ENOMEM; 340 return -ENODEV;
316
317 /*
318 * It is safe to dereference these pointers now as long as a user has
319 * the video device open - we are protected by the held cdev reference.
320 */
321 341
322 vdev = video_devdata(file);
323 icd = container_of(vdev->parent, struct soc_camera_device, dev);
324 ici = to_soc_camera_host(icd->dev.parent); 342 ici = to_soc_camera_host(icd->dev.parent);
325 343
326 if (!try_module_get(icd->ops->owner)) { 344 icf = vmalloc(sizeof(*icf));
327 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 345 if (!icf)
328 ret = -EINVAL; 346 return -ENOMEM;
329 goto emgd;
330 }
331 347
332 if (!try_module_get(ici->ops->owner)) { 348 if (!try_module_get(ici->ops->owner)) {
333 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 349 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
@@ -335,7 +351,10 @@ static int soc_camera_open(struct file *file)
335 goto emgi; 351 goto emgi;
336 } 352 }
337 353
338 /* Protect against icd->remove() until we module_get() both drivers. */ 354 /*
355 * Protect against icd->ops->remove() until we module_get() both
356 * drivers.
357 */
339 mutex_lock(&icd->video_lock); 358 mutex_lock(&icd->video_lock);
340 359
341 icf->icd = icd; 360 icf->icd = icd;
@@ -347,14 +366,24 @@ static int soc_camera_open(struct file *file)
347 struct v4l2_format f = { 366 struct v4l2_format f = {
348 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 367 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
349 .fmt.pix = { 368 .fmt.pix = {
350 .width = icd->width, 369 .width = icd->user_width,
351 .height = icd->height, 370 .height = icd->user_height,
352 .field = icd->field, 371 .field = icd->field,
353 .pixelformat = icd->current_fmt->fourcc, 372 .pixelformat = icd->current_fmt->fourcc,
354 .colorspace = icd->current_fmt->colorspace, 373 .colorspace = icd->current_fmt->colorspace,
355 }, 374 },
356 }; 375 };
357 376
377 if (icl->power) {
378 ret = icl->power(icd->pdev, 1);
379 if (ret < 0)
380 goto epower;
381 }
382
383 /* The camera could have been already on, try to reset */
384 if (icl->reset)
385 icl->reset(icd->pdev);
386
358 ret = ici->ops->add(icd); 387 ret = ici->ops->add(icd);
359 if (ret < 0) { 388 if (ret < 0) {
360 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 389 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
@@ -367,28 +396,29 @@ static int soc_camera_open(struct file *file)
367 goto esfmt; 396 goto esfmt;
368 } 397 }
369 398
370 mutex_unlock(&icd->video_lock);
371
372 file->private_data = icf; 399 file->private_data = icf;
373 dev_dbg(&icd->dev, "camera device open\n"); 400 dev_dbg(&icd->dev, "camera device open\n");
374 401
375 ici->ops->init_videobuf(&icf->vb_vidq, icd); 402 ici->ops->init_videobuf(&icf->vb_vidq, icd);
376 403
404 mutex_unlock(&icd->video_lock);
405
377 return 0; 406 return 0;
378 407
379 /* 408 /*
380 * First three errors are entered with the .video_lock held 409 * First five errors are entered with the .video_lock held
381 * and use_count == 1 410 * and use_count == 1
382 */ 411 */
383esfmt: 412esfmt:
384 ici->ops->remove(icd); 413 ici->ops->remove(icd);
385eiciadd: 414eiciadd:
415 if (icl->power)
416 icl->power(icd->pdev, 0);
417epower:
386 icd->use_count--; 418 icd->use_count--;
387 mutex_unlock(&icd->video_lock); 419 mutex_unlock(&icd->video_lock);
388 module_put(ici->ops->owner); 420 module_put(ici->ops->owner);
389emgi: 421emgi:
390 module_put(icd->ops->owner);
391emgd:
392 vfree(icf); 422 vfree(icf);
393 return ret; 423 return ret;
394} 424}
@@ -398,21 +428,24 @@ static int soc_camera_close(struct file *file)
398 struct soc_camera_file *icf = file->private_data; 428 struct soc_camera_file *icf = file->private_data;
399 struct soc_camera_device *icd = icf->icd; 429 struct soc_camera_device *icd = icf->icd;
400 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 430 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
401 struct video_device *vdev = icd->vdev;
402 431
403 mutex_lock(&icd->video_lock); 432 mutex_lock(&icd->video_lock);
404 icd->use_count--; 433 icd->use_count--;
405 if (!icd->use_count) 434 if (!icd->use_count) {
435 struct soc_camera_link *icl = to_soc_camera_link(icd);
436
406 ici->ops->remove(icd); 437 ici->ops->remove(icd);
438 if (icl->power)
439 icl->power(icd->pdev, 0);
440 }
407 441
408 mutex_unlock(&icd->video_lock); 442 mutex_unlock(&icd->video_lock);
409 443
410 module_put(icd->ops->owner);
411 module_put(ici->ops->owner); 444 module_put(ici->ops->owner);
412 445
413 vfree(icf); 446 vfree(icf);
414 447
415 dev_dbg(vdev->parent, "camera device close\n"); 448 dev_dbg(&icd->dev, "camera device close\n");
416 449
417 return 0; 450 return 0;
418} 451}
@@ -422,10 +455,9 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
422{ 455{
423 struct soc_camera_file *icf = file->private_data; 456 struct soc_camera_file *icf = file->private_data;
424 struct soc_camera_device *icd = icf->icd; 457 struct soc_camera_device *icd = icf->icd;
425 struct video_device *vdev = icd->vdev;
426 int err = -EINVAL; 458 int err = -EINVAL;
427 459
428 dev_err(vdev->parent, "camera device read not implemented\n"); 460 dev_err(&icd->dev, "camera device read not implemented\n");
429 461
430 return err; 462 return err;
431} 463}
@@ -483,8 +515,8 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
483 515
484 mutex_lock(&icf->vb_vidq.vb_lock); 516 mutex_lock(&icf->vb_vidq.vb_lock);
485 517
486 if (videobuf_queue_is_busy(&icf->vb_vidq)) { 518 if (icf->vb_vidq.bufs[0]) {
487 dev_err(&icd->dev, "S_FMT denied: queue busy\n"); 519 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
488 ret = -EBUSY; 520 ret = -EBUSY;
489 goto unlock; 521 goto unlock;
490 } 522 }
@@ -525,8 +557,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
525 557
526 WARN_ON(priv != file->private_data); 558 WARN_ON(priv != file->private_data);
527 559
528 pix->width = icd->width; 560 pix->width = icd->user_width;
529 pix->height = icd->height; 561 pix->height = icd->user_height;
530 pix->field = icf->vb_vidq.field; 562 pix->field = icf->vb_vidq.field;
531 pix->pixelformat = icd->current_fmt->fourcc; 563 pix->pixelformat = icd->current_fmt->fourcc;
532 pix->bytesperline = pix->width * 564 pix->bytesperline = pix->width *
@@ -555,18 +587,17 @@ static int soc_camera_streamon(struct file *file, void *priv,
555{ 587{
556 struct soc_camera_file *icf = file->private_data; 588 struct soc_camera_file *icf = file->private_data;
557 struct soc_camera_device *icd = icf->icd; 589 struct soc_camera_device *icd = icf->icd;
590 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
558 int ret; 591 int ret;
559 592
560 WARN_ON(priv != file->private_data); 593 WARN_ON(priv != file->private_data);
561 594
562 dev_dbg(&icd->dev, "%s\n", __func__);
563
564 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 595 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
565 return -EINVAL; 596 return -EINVAL;
566 597
567 mutex_lock(&icd->video_lock); 598 mutex_lock(&icd->video_lock);
568 599
569 icd->ops->start_capture(icd); 600 v4l2_subdev_call(sd, video, s_stream, 1);
570 601
571 /* This calls buf_queue from host driver's videobuf_queue_ops */ 602 /* This calls buf_queue from host driver's videobuf_queue_ops */
572 ret = videobuf_streamon(&icf->vb_vidq); 603 ret = videobuf_streamon(&icf->vb_vidq);
@@ -581,11 +612,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
581{ 612{
582 struct soc_camera_file *icf = file->private_data; 613 struct soc_camera_file *icf = file->private_data;
583 struct soc_camera_device *icd = icf->icd; 614 struct soc_camera_device *icd = icf->icd;
615 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
584 616
585 WARN_ON(priv != file->private_data); 617 WARN_ON(priv != file->private_data);
586 618
587 dev_dbg(&icd->dev, "%s\n", __func__);
588
589 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 619 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
590 return -EINVAL; 620 return -EINVAL;
591 621
@@ -595,7 +625,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
595 * remaining buffers. When the last buffer is freed, stop capture */ 625 * remaining buffers. When the last buffer is freed, stop capture */
596 videobuf_streamoff(&icf->vb_vidq); 626 videobuf_streamoff(&icf->vb_vidq);
597 627
598 icd->ops->stop_capture(icd); 628 v4l2_subdev_call(sd, video, s_stream, 0);
599 629
600 mutex_unlock(&icd->video_lock); 630 mutex_unlock(&icd->video_lock);
601 631
@@ -607,6 +637,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
607{ 637{
608 struct soc_camera_file *icf = file->private_data; 638 struct soc_camera_file *icf = file->private_data;
609 struct soc_camera_device *icd = icf->icd; 639 struct soc_camera_device *icd = icf->icd;
640 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
610 int i; 641 int i;
611 642
612 WARN_ON(priv != file->private_data); 643 WARN_ON(priv != file->private_data);
@@ -614,6 +645,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
614 if (!qc->id) 645 if (!qc->id)
615 return -EINVAL; 646 return -EINVAL;
616 647
648 /* First check host controls */
649 for (i = 0; i < ici->ops->num_controls; i++)
650 if (qc->id == ici->ops->controls[i].id) {
651 memcpy(qc, &(ici->ops->controls[i]),
652 sizeof(*qc));
653 return 0;
654 }
655
656 /* Then device controls */
617 for (i = 0; i < icd->ops->num_controls; i++) 657 for (i = 0; i < icd->ops->num_controls; i++)
618 if (qc->id == icd->ops->controls[i].id) { 658 if (qc->id == icd->ops->controls[i].id) {
619 memcpy(qc, &(icd->ops->controls[i]), 659 memcpy(qc, &(icd->ops->controls[i]),
@@ -629,25 +669,19 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
629{ 669{
630 struct soc_camera_file *icf = file->private_data; 670 struct soc_camera_file *icf = file->private_data;
631 struct soc_camera_device *icd = icf->icd; 671 struct soc_camera_device *icd = icf->icd;
672 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
673 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
674 int ret;
632 675
633 WARN_ON(priv != file->private_data); 676 WARN_ON(priv != file->private_data);
634 677
635 switch (ctrl->id) { 678 if (ici->ops->get_ctrl) {
636 case V4L2_CID_GAIN: 679 ret = ici->ops->get_ctrl(icd, ctrl);
637 if (icd->gain == (unsigned short)~0) 680 if (ret != -ENOIOCTLCMD)
638 return -EINVAL; 681 return ret;
639 ctrl->value = icd->gain;
640 return 0;
641 case V4L2_CID_EXPOSURE:
642 if (icd->exposure == (unsigned short)~0)
643 return -EINVAL;
644 ctrl->value = icd->exposure;
645 return 0;
646 } 682 }
647 683
648 if (icd->ops->get_control) 684 return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
649 return icd->ops->get_control(icd, ctrl);
650 return -EINVAL;
651} 685}
652 686
653static int soc_camera_s_ctrl(struct file *file, void *priv, 687static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -655,12 +689,19 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
655{ 689{
656 struct soc_camera_file *icf = file->private_data; 690 struct soc_camera_file *icf = file->private_data;
657 struct soc_camera_device *icd = icf->icd; 691 struct soc_camera_device *icd = icf->icd;
692 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
693 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
694 int ret;
658 695
659 WARN_ON(priv != file->private_data); 696 WARN_ON(priv != file->private_data);
660 697
661 if (icd->ops->set_control) 698 if (ici->ops->set_ctrl) {
662 return icd->ops->set_control(icd, ctrl); 699 ret = ici->ops->set_ctrl(icd, ctrl);
663 return -EINVAL; 700 if (ret != -ENOIOCTLCMD)
701 return ret;
702 }
703
704 return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
664} 705}
665 706
666static int soc_camera_cropcap(struct file *file, void *fh, 707static int soc_camera_cropcap(struct file *file, void *fh,
@@ -668,20 +709,9 @@ static int soc_camera_cropcap(struct file *file, void *fh,
668{ 709{
669 struct soc_camera_file *icf = file->private_data; 710 struct soc_camera_file *icf = file->private_data;
670 struct soc_camera_device *icd = icf->icd; 711 struct soc_camera_device *icd = icf->icd;
712 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
671 713
672 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 714 return ici->ops->cropcap(icd, a);
673 a->bounds.left = icd->x_min;
674 a->bounds.top = icd->y_min;
675 a->bounds.width = icd->width_max;
676 a->bounds.height = icd->height_max;
677 a->defrect.left = icd->x_min;
678 a->defrect.top = icd->y_min;
679 a->defrect.width = DEFAULT_WIDTH;
680 a->defrect.height = DEFAULT_HEIGHT;
681 a->pixelaspect.numerator = 1;
682 a->pixelaspect.denominator = 1;
683
684 return 0;
685} 715}
686 716
687static int soc_camera_g_crop(struct file *file, void *fh, 717static int soc_camera_g_crop(struct file *file, void *fh,
@@ -689,36 +719,53 @@ static int soc_camera_g_crop(struct file *file, void *fh,
689{ 719{
690 struct soc_camera_file *icf = file->private_data; 720 struct soc_camera_file *icf = file->private_data;
691 struct soc_camera_device *icd = icf->icd; 721 struct soc_camera_device *icd = icf->icd;
722 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
723 int ret;
692 724
693 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 725 mutex_lock(&icf->vb_vidq.vb_lock);
694 a->c.left = icd->x_current; 726 ret = ici->ops->get_crop(icd, a);
695 a->c.top = icd->y_current; 727 mutex_unlock(&icf->vb_vidq.vb_lock);
696 a->c.width = icd->width;
697 a->c.height = icd->height;
698 728
699 return 0; 729 return ret;
700} 730}
701 731
732/*
733 * According to the V4L2 API, drivers shall not update the struct v4l2_crop
734 * argument with the actual geometry, instead, the user shall use G_CROP to
735 * retrieve it. However, we expect camera host and client drivers to update
736 * the argument, which we then use internally, but do not return to the user.
737 */
702static int soc_camera_s_crop(struct file *file, void *fh, 738static int soc_camera_s_crop(struct file *file, void *fh,
703 struct v4l2_crop *a) 739 struct v4l2_crop *a)
704{ 740{
705 struct soc_camera_file *icf = file->private_data; 741 struct soc_camera_file *icf = file->private_data;
706 struct soc_camera_device *icd = icf->icd; 742 struct soc_camera_device *icd = icf->icd;
707 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 743 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
744 struct v4l2_rect *rect = &a->c;
745 struct v4l2_crop current_crop;
708 int ret; 746 int ret;
709 747
710 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 748 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
711 return -EINVAL; 749 return -EINVAL;
712 750
751 dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n",
752 rect->width, rect->height, rect->left, rect->top);
753
713 /* Cropping is allowed during a running capture, guard consistency */ 754 /* Cropping is allowed during a running capture, guard consistency */
714 mutex_lock(&icf->vb_vidq.vb_lock); 755 mutex_lock(&icf->vb_vidq.vb_lock);
715 756
716 ret = ici->ops->set_crop(icd, &a->c); 757 /* If get_crop fails, we'll let host and / or client drivers decide */
717 if (!ret) { 758 ret = ici->ops->get_crop(icd, &current_crop);
718 icd->width = a->c.width; 759
719 icd->height = a->c.height; 760 /* Prohibit window size change with initialised buffers */
720 icd->x_current = a->c.left; 761 if (icf->vb_vidq.bufs[0] && !ret &&
721 icd->y_current = a->c.top; 762 (a->c.width != current_crop.c.width ||
763 a->c.height != current_crop.c.height)) {
764 dev_err(&icd->dev,
765 "S_CROP denied: queue initialised and sizes differ\n");
766 ret = -EBUSY;
767 } else {
768 ret = ici->ops->set_crop(icd, a);
722 } 769 }
723 770
724 mutex_unlock(&icf->vb_vidq.vb_lock); 771 mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -731,11 +778,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
731{ 778{
732 struct soc_camera_file *icf = file->private_data; 779 struct soc_camera_file *icf = file->private_data;
733 struct soc_camera_device *icd = icf->icd; 780 struct soc_camera_device *icd = icf->icd;
781 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
734 782
735 if (!icd->ops->get_chip_id) 783 return v4l2_subdev_call(sd, core, g_chip_ident, id);
736 return -EINVAL;
737
738 return icd->ops->get_chip_id(icd, id);
739} 784}
740 785
741#ifdef CONFIG_VIDEO_ADV_DEBUG 786#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -744,11 +789,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
744{ 789{
745 struct soc_camera_file *icf = file->private_data; 790 struct soc_camera_file *icf = file->private_data;
746 struct soc_camera_device *icd = icf->icd; 791 struct soc_camera_device *icd = icf->icd;
792 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
747 793
748 if (!icd->ops->get_register) 794 return v4l2_subdev_call(sd, core, g_register, reg);
749 return -EINVAL;
750
751 return icd->ops->get_register(icd, reg);
752} 795}
753 796
754static int soc_camera_s_register(struct file *file, void *fh, 797static int soc_camera_s_register(struct file *file, void *fh,
@@ -756,37 +799,12 @@ static int soc_camera_s_register(struct file *file, void *fh,
756{ 799{
757 struct soc_camera_file *icf = file->private_data; 800 struct soc_camera_file *icf = file->private_data;
758 struct soc_camera_device *icd = icf->icd; 801 struct soc_camera_device *icd = icf->icd;
802 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
759 803
760 if (!icd->ops->set_register) 804 return v4l2_subdev_call(sd, core, s_register, reg);
761 return -EINVAL;
762
763 return icd->ops->set_register(icd, reg);
764} 805}
765#endif 806#endif
766 807
767static int device_register_link(struct soc_camera_device *icd)
768{
769 int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
770
771 if (!ret)
772 ret = device_register(&icd->dev);
773
774 if (ret < 0) {
775 /* Prevent calling device_unregister() */
776 icd->dev.parent = NULL;
777 dev_err(&icd->dev, "Cannot register device: %d\n", ret);
778 /* Even if probe() was unsuccessful for all registered drivers,
779 * device_register() returns 0, and we add the link, just to
780 * document this camera's control device */
781 } else if (icd->control)
782 /* Have to sysfs_remove_link() before device_unregister()? */
783 if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj,
784 "control"))
785 dev_warn(&icd->dev,
786 "Failed creating the control symlink\n");
787 return ret;
788}
789
790/* So far this function cannot fail */ 808/* So far this function cannot fail */
791static void scan_add_host(struct soc_camera_host *ici) 809static void scan_add_host(struct soc_camera_host *ici)
792{ 810{
@@ -796,106 +814,193 @@ static void scan_add_host(struct soc_camera_host *ici)
796 814
797 list_for_each_entry(icd, &devices, list) { 815 list_for_each_entry(icd, &devices, list) {
798 if (icd->iface == ici->nr) { 816 if (icd->iface == ici->nr) {
799 icd->dev.parent = ici->dev; 817 int ret;
800 device_register_link(icd); 818 icd->dev.parent = ici->v4l2_dev.dev;
819 dev_set_name(&icd->dev, "%u-%u", icd->iface,
820 icd->devnum);
821 ret = device_register(&icd->dev);
822 if (ret < 0) {
823 icd->dev.parent = NULL;
824 dev_err(&icd->dev,
825 "Cannot register device: %d\n", ret);
826 }
801 } 827 }
802 } 828 }
803 829
804 mutex_unlock(&list_lock); 830 mutex_unlock(&list_lock);
805} 831}
806 832
807/* return: 0 if no match found or a match found and 833#ifdef CONFIG_I2C_BOARDINFO
808 * device_register() successful, error code otherwise */ 834static int soc_camera_init_i2c(struct soc_camera_device *icd,
809static int scan_add_device(struct soc_camera_device *icd) 835 struct soc_camera_link *icl)
810{ 836{
811 struct soc_camera_host *ici; 837 struct i2c_client *client;
812 int ret = 0; 838 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
839 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
840 struct v4l2_subdev *subdev;
841 int ret;
813 842
814 mutex_lock(&list_lock); 843 if (!adap) {
844 ret = -ENODEV;
845 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
846 icl->i2c_adapter_id);
847 goto ei2cga;
848 }
815 849
816 list_add_tail(&icd->list, &devices); 850 icl->board_info->platform_data = icd;
817 851
818 /* Watch out for class_for_each_device / class_find_device API by 852 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
819 * Dave Young <hidave.darkstar@gmail.com> */ 853 icl->module_name, icl->board_info, NULL);
820 list_for_each_entry(ici, &hosts, list) { 854 if (!subdev) {
821 if (icd->iface == ici->nr) { 855 ret = -ENOMEM;
822 ret = 1; 856 goto ei2cnd;
823 icd->dev.parent = ici->dev;
824 break;
825 }
826 } 857 }
827 858
828 mutex_unlock(&list_lock); 859 client = subdev->priv;
829 860
830 if (ret) 861 /* Use to_i2c_client(dev) to recover the i2c client */
831 ret = device_register_link(icd); 862 dev_set_drvdata(&icd->dev, &client->dev);
832 863
864 return 0;
865ei2cnd:
866 i2c_put_adapter(adap);
867ei2cga:
833 return ret; 868 return ret;
834} 869}
835 870
871static void soc_camera_free_i2c(struct soc_camera_device *icd)
872{
873 struct i2c_client *client =
874 to_i2c_client(to_soc_camera_control(icd));
875 dev_set_drvdata(&icd->dev, NULL);
876 v4l2_device_unregister_subdev(i2c_get_clientdata(client));
877 i2c_unregister_device(client);
878 i2c_put_adapter(client->adapter);
879}
880#else
881#define soc_camera_init_i2c(icd, icl) (-ENODEV)
882#define soc_camera_free_i2c(icd) do {} while (0)
883#endif
884
885static int soc_camera_video_start(struct soc_camera_device *icd);
886static int video_dev_create(struct soc_camera_device *icd);
887/* Called during host-driver probe */
836static int soc_camera_probe(struct device *dev) 888static int soc_camera_probe(struct device *dev)
837{ 889{
838 struct soc_camera_device *icd = to_soc_camera_dev(dev); 890 struct soc_camera_device *icd = to_soc_camera_dev(dev);
839 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 891 struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
892 struct soc_camera_link *icl = to_soc_camera_link(icd);
893 struct device *control = NULL;
894 struct v4l2_subdev *sd;
895 struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
840 int ret; 896 int ret;
841 897
842 /* 898 dev_info(dev, "Probing %s\n", dev_name(dev));
843 * Possible race scenario:
844 * modprobe <camera-host-driver> triggers __func__
845 * at this moment respective <camera-sensor-driver> gets rmmod'ed
846 * to protect take module references.
847 */
848 899
849 if (!try_module_get(icd->ops->owner)) { 900 if (icl->power) {
850 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 901 ret = icl->power(icd->pdev, 1);
851 ret = -EINVAL; 902 if (ret < 0) {
852 goto emgd; 903 dev_err(dev,
904 "Platform failed to power-on the camera.\n");
905 goto epower;
906 }
853 } 907 }
854 908
855 if (!try_module_get(ici->ops->owner)) { 909 /* The camera could have been already on, try to reset */
856 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 910 if (icl->reset)
911 icl->reset(icd->pdev);
912
913 ret = ici->ops->add(icd);
914 if (ret < 0)
915 goto eadd;
916
917 /* Must have icd->vdev before registering the device */
918 ret = video_dev_create(icd);
919 if (ret < 0)
920 goto evdc;
921
922 /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
923 if (icl->board_info) {
924 ret = soc_camera_init_i2c(icd, icl);
925 if (ret < 0)
926 goto eadddev;
927 } else if (!icl->add_device || !icl->del_device) {
857 ret = -EINVAL; 928 ret = -EINVAL;
858 goto emgi; 929 goto eadddev;
930 } else {
931 if (icl->module_name)
932 ret = request_module(icl->module_name);
933
934 ret = icl->add_device(icl, &icd->dev);
935 if (ret < 0)
936 goto eadddev;
937
938 /*
939 * FIXME: this is racy, have to use driver-binding notification,
940 * when it is available
941 */
942 control = to_soc_camera_control(icd);
943 if (!control || !control->driver || !dev_get_drvdata(control) ||
944 !try_module_get(control->driver->owner)) {
945 icl->del_device(icl);
946 goto enodrv;
947 }
859 } 948 }
860 949
950 /* At this point client .probe() should have run already */
951 ret = soc_camera_init_user_formats(icd);
952 if (ret < 0)
953 goto eiufmt;
954
955 icd->field = V4L2_FIELD_ANY;
956
957 /* ..._video_start() will create a device node, so we have to protect */
861 mutex_lock(&icd->video_lock); 958 mutex_lock(&icd->video_lock);
862 959
863 /* We only call ->add() here to activate and probe the camera. 960 ret = soc_camera_video_start(icd);
864 * We shall ->remove() and deactivate it immediately afterwards. */
865 ret = ici->ops->add(icd);
866 if (ret < 0) 961 if (ret < 0)
867 goto eiadd; 962 goto evidstart;
963
964 /* Try to improve our guess of a reasonable window format */
965 sd = soc_camera_to_subdev(icd);
966 if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
967 icd->user_width = f.fmt.pix.width;
968 icd->user_height = f.fmt.pix.height;
969 }
868 970
869 ret = icd->ops->probe(icd); 971 /* Do we have to sysfs_remove_link() before device_unregister()? */
870 if (ret >= 0) { 972 if (sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
871 const struct v4l2_queryctrl *qctrl; 973 "control"))
974 dev_warn(&icd->dev, "Failed creating the control symlink\n");
872 975
873 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); 976 ici->ops->remove(icd);
874 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
875 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
876 icd->exposure = qctrl ? qctrl->default_value :
877 (unsigned short)~0;
878 977
879 ret = soc_camera_init_user_formats(icd); 978 if (icl->power)
880 if (ret < 0) { 979 icl->power(icd->pdev, 0);
881 if (icd->ops->remove)
882 icd->ops->remove(icd);
883 goto eiufmt;
884 }
885 980
886 icd->height = DEFAULT_HEIGHT; 981 mutex_unlock(&icd->video_lock);
887 icd->width = DEFAULT_WIDTH;
888 icd->field = V4L2_FIELD_ANY;
889 }
890 982
983 return 0;
984
985evidstart:
986 mutex_unlock(&icd->video_lock);
987 soc_camera_free_user_formats(icd);
891eiufmt: 988eiufmt:
989 if (icl->board_info) {
990 soc_camera_free_i2c(icd);
991 } else {
992 icl->del_device(icl);
993 module_put(control->driver->owner);
994 }
995enodrv:
996eadddev:
997 video_device_release(icd->vdev);
998evdc:
892 ici->ops->remove(icd); 999 ici->ops->remove(icd);
893eiadd: 1000eadd:
894 mutex_unlock(&icd->video_lock); 1001 if (icl->power)
895 module_put(ici->ops->owner); 1002 icl->power(icd->pdev, 0);
896emgi: 1003epower:
897 module_put(icd->ops->owner);
898emgd:
899 return ret; 1004 return ret;
900} 1005}
901 1006
@@ -904,12 +1009,28 @@ emgd:
904static int soc_camera_remove(struct device *dev) 1009static int soc_camera_remove(struct device *dev)
905{ 1010{
906 struct soc_camera_device *icd = to_soc_camera_dev(dev); 1011 struct soc_camera_device *icd = to_soc_camera_dev(dev);
1012 struct soc_camera_link *icl = to_soc_camera_link(icd);
1013 struct video_device *vdev = icd->vdev;
907 1014
908 mutex_lock(&icd->video_lock); 1015 BUG_ON(!dev->parent);
909 if (icd->ops->remove)
910 icd->ops->remove(icd);
911 mutex_unlock(&icd->video_lock);
912 1016
1017 if (vdev) {
1018 mutex_lock(&icd->video_lock);
1019 video_unregister_device(vdev);
1020 icd->vdev = NULL;
1021 mutex_unlock(&icd->video_lock);
1022 }
1023
1024 if (icl->board_info) {
1025 soc_camera_free_i2c(icd);
1026 } else {
1027 struct device_driver *drv = to_soc_camera_control(icd) ?
1028 to_soc_camera_control(icd)->driver : NULL;
1029 if (drv) {
1030 icl->del_device(icl);
1031 module_put(drv->owner);
1032 }
1033 }
913 soc_camera_free_user_formats(icd); 1034 soc_camera_free_user_formats(icd);
914 1035
915 return 0; 1036 return 0;
@@ -957,14 +1078,33 @@ static void dummy_release(struct device *dev)
957{ 1078{
958} 1079}
959 1080
1081static int default_cropcap(struct soc_camera_device *icd,
1082 struct v4l2_cropcap *a)
1083{
1084 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1085 return v4l2_subdev_call(sd, video, cropcap, a);
1086}
1087
1088static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
1089{
1090 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1091 return v4l2_subdev_call(sd, video, g_crop, a);
1092}
1093
1094static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
1095{
1096 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1097 return v4l2_subdev_call(sd, video, s_crop, a);
1098}
1099
960int soc_camera_host_register(struct soc_camera_host *ici) 1100int soc_camera_host_register(struct soc_camera_host *ici)
961{ 1101{
962 struct soc_camera_host *ix; 1102 struct soc_camera_host *ix;
1103 int ret;
963 1104
964 if (!ici || !ici->ops || 1105 if (!ici || !ici->ops ||
965 !ici->ops->try_fmt || 1106 !ici->ops->try_fmt ||
966 !ici->ops->set_fmt || 1107 !ici->ops->set_fmt ||
967 !ici->ops->set_crop ||
968 !ici->ops->set_bus_param || 1108 !ici->ops->set_bus_param ||
969 !ici->ops->querycap || 1109 !ici->ops->querycap ||
970 !ici->ops->init_videobuf || 1110 !ici->ops->init_videobuf ||
@@ -972,18 +1112,27 @@ int soc_camera_host_register(struct soc_camera_host *ici)
972 !ici->ops->add || 1112 !ici->ops->add ||
973 !ici->ops->remove || 1113 !ici->ops->remove ||
974 !ici->ops->poll || 1114 !ici->ops->poll ||
975 !ici->dev) 1115 !ici->v4l2_dev.dev)
976 return -EINVAL; 1116 return -EINVAL;
977 1117
1118 if (!ici->ops->set_crop)
1119 ici->ops->set_crop = default_s_crop;
1120 if (!ici->ops->get_crop)
1121 ici->ops->get_crop = default_g_crop;
1122 if (!ici->ops->cropcap)
1123 ici->ops->cropcap = default_cropcap;
1124
978 mutex_lock(&list_lock); 1125 mutex_lock(&list_lock);
979 list_for_each_entry(ix, &hosts, list) { 1126 list_for_each_entry(ix, &hosts, list) {
980 if (ix->nr == ici->nr) { 1127 if (ix->nr == ici->nr) {
981 mutex_unlock(&list_lock); 1128 ret = -EBUSY;
982 return -EBUSY; 1129 goto edevreg;
983 } 1130 }
984 } 1131 }
985 1132
986 dev_set_drvdata(ici->dev, ici); 1133 ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
1134 if (ret < 0)
1135 goto edevreg;
987 1136
988 list_add_tail(&ici->list, &hosts); 1137 list_add_tail(&ici->list, &hosts);
989 mutex_unlock(&list_lock); 1138 mutex_unlock(&list_lock);
@@ -991,6 +1140,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
991 scan_add_host(ici); 1140 scan_add_host(ici);
992 1141
993 return 0; 1142 return 0;
1143
1144edevreg:
1145 mutex_unlock(&list_lock);
1146 return ret;
994} 1147}
995EXPORT_SYMBOL(soc_camera_host_register); 1148EXPORT_SYMBOL(soc_camera_host_register);
996 1149
@@ -1004,42 +1157,34 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1004 list_del(&ici->list); 1157 list_del(&ici->list);
1005 1158
1006 list_for_each_entry(icd, &devices, list) { 1159 list_for_each_entry(icd, &devices, list) {
1007 if (icd->dev.parent == ici->dev) { 1160 if (icd->iface == ici->nr) {
1161 /* The bus->remove will be called */
1008 device_unregister(&icd->dev); 1162 device_unregister(&icd->dev);
1009 /* Not before device_unregister(), .remove 1163 /* Not before device_unregister(), .remove
1010 * needs parent to call ici->ops->remove() */ 1164 * needs parent to call ici->ops->remove() */
1011 icd->dev.parent = NULL; 1165 icd->dev.parent = NULL;
1166
1167 /* If the host module is loaded again, device_register()
1168 * would complain "already initialised" */
1012 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj)); 1169 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
1013 } 1170 }
1014 } 1171 }
1015 1172
1016 mutex_unlock(&list_lock); 1173 mutex_unlock(&list_lock);
1017 1174
1018 dev_set_drvdata(ici->dev, NULL); 1175 v4l2_device_unregister(&ici->v4l2_dev);
1019} 1176}
1020EXPORT_SYMBOL(soc_camera_host_unregister); 1177EXPORT_SYMBOL(soc_camera_host_unregister);
1021 1178
1022/* Image capture device */ 1179/* Image capture device */
1023int soc_camera_device_register(struct soc_camera_device *icd) 1180static int soc_camera_device_register(struct soc_camera_device *icd)
1024{ 1181{
1025 struct soc_camera_device *ix; 1182 struct soc_camera_device *ix;
1026 int num = -1, i; 1183 int num = -1, i;
1027 1184
1028 if (!icd || !icd->ops ||
1029 !icd->ops->probe ||
1030 !icd->ops->init ||
1031 !icd->ops->release ||
1032 !icd->ops->start_capture ||
1033 !icd->ops->stop_capture ||
1034 !icd->ops->set_crop ||
1035 !icd->ops->set_fmt ||
1036 !icd->ops->try_fmt ||
1037 !icd->ops->query_bus_param ||
1038 !icd->ops->set_bus_param)
1039 return -EINVAL;
1040
1041 for (i = 0; i < 256 && num < 0; i++) { 1185 for (i = 0; i < 256 && num < 0; i++) {
1042 num = i; 1186 num = i;
1187 /* Check if this index is available on this interface */
1043 list_for_each_entry(ix, &devices, list) { 1188 list_for_each_entry(ix, &devices, list) {
1044 if (ix->iface == icd->iface && ix->devnum == i) { 1189 if (ix->iface == icd->iface && ix->devnum == i) {
1045 num = -1; 1190 num = -1;
@@ -1061,21 +1206,15 @@ int soc_camera_device_register(struct soc_camera_device *icd)
1061 icd->host_priv = NULL; 1206 icd->host_priv = NULL;
1062 mutex_init(&icd->video_lock); 1207 mutex_init(&icd->video_lock);
1063 1208
1064 return scan_add_device(icd); 1209 list_add_tail(&icd->list, &devices);
1210
1211 return 0;
1065} 1212}
1066EXPORT_SYMBOL(soc_camera_device_register);
1067 1213
1068void soc_camera_device_unregister(struct soc_camera_device *icd) 1214static void soc_camera_device_unregister(struct soc_camera_device *icd)
1069{ 1215{
1070 mutex_lock(&list_lock);
1071 list_del(&icd->list); 1216 list_del(&icd->list);
1072
1073 /* The bus->remove will be eventually called */
1074 if (icd->dev.parent)
1075 device_unregister(&icd->dev);
1076 mutex_unlock(&list_lock);
1077} 1217}
1078EXPORT_SYMBOL(soc_camera_device_unregister);
1079 1218
1080static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1219static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1081 .vidioc_querycap = soc_camera_querycap, 1220 .vidioc_querycap = soc_camera_querycap,
@@ -1106,23 +1245,13 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1106#endif 1245#endif
1107}; 1246};
1108 1247
1109/* 1248static int video_dev_create(struct soc_camera_device *icd)
1110 * Usually called from the struct soc_camera_ops .probe() method, i.e., from
1111 * soc_camera_probe() above with .video_lock held
1112 */
1113int soc_camera_video_start(struct soc_camera_device *icd)
1114{ 1249{
1115 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1250 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1116 int err = -ENOMEM; 1251 struct video_device *vdev = video_device_alloc();
1117 struct video_device *vdev;
1118 1252
1119 if (!icd->dev.parent)
1120 return -ENODEV;
1121
1122 vdev = video_device_alloc();
1123 if (!vdev) 1253 if (!vdev)
1124 goto evidallocd; 1254 return -ENOMEM;
1125 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1126 1255
1127 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1256 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1128 1257
@@ -1132,87 +1261,93 @@ int soc_camera_video_start(struct soc_camera_device *icd)
1132 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1261 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1133 vdev->release = video_device_release; 1262 vdev->release = video_device_release;
1134 vdev->minor = -1; 1263 vdev->minor = -1;
1135 vdev->tvnorms = V4L2_STD_UNKNOWN, 1264 vdev->tvnorms = V4L2_STD_UNKNOWN;
1136 1265
1137 err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
1138 if (err < 0) {
1139 dev_err(vdev->parent, "video_register_device failed\n");
1140 goto evidregd;
1141 }
1142 icd->vdev = vdev; 1266 icd->vdev = vdev;
1143 1267
1144 return 0; 1268 return 0;
1145
1146evidregd:
1147 video_device_release(vdev);
1148evidallocd:
1149 return err;
1150} 1269}
1151EXPORT_SYMBOL(soc_camera_video_start);
1152 1270
1153/* Called from client .remove() methods with .video_lock held */ 1271/*
1154void soc_camera_video_stop(struct soc_camera_device *icd) 1272 * Called from soc_camera_probe() above (with .video_lock held???)
1273 */
1274static int soc_camera_video_start(struct soc_camera_device *icd)
1155{ 1275{
1156 struct video_device *vdev = icd->vdev; 1276 int ret;
1157 1277
1158 dev_dbg(&icd->dev, "%s\n", __func__); 1278 if (!icd->dev.parent)
1279 return -ENODEV;
1159 1280
1160 if (!icd->dev.parent || !vdev) 1281 if (!icd->ops ||
1161 return; 1282 !icd->ops->query_bus_param ||
1283 !icd->ops->set_bus_param)
1284 return -EINVAL;
1285
1286 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
1287 icd->vdev->minor);
1288 if (ret < 0) {
1289 dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
1290 return ret;
1291 }
1162 1292
1163 video_unregister_device(vdev); 1293 return 0;
1164 icd->vdev = NULL;
1165} 1294}
1166EXPORT_SYMBOL(soc_camera_video_stop);
1167 1295
1168static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1296static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1169{ 1297{
1170 struct soc_camera_link *icl = pdev->dev.platform_data; 1298 struct soc_camera_link *icl = pdev->dev.platform_data;
1171 struct i2c_adapter *adap; 1299 struct soc_camera_device *icd;
1172 struct i2c_client *client; 1300 int ret;
1173 1301
1174 if (!icl) 1302 if (!icl)
1175 return -EINVAL; 1303 return -EINVAL;
1176 1304
1177 adap = i2c_get_adapter(icl->i2c_adapter_id); 1305 icd = kzalloc(sizeof(*icd), GFP_KERNEL);
1178 if (!adap) { 1306 if (!icd)
1179 dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
1180 icl->i2c_adapter_id);
1181 /* -ENODEV and -ENXIO do not produce an error on probe()... */
1182 return -ENOENT;
1183 }
1184
1185 icl->board_info->platform_data = icl;
1186 client = i2c_new_device(adap, icl->board_info);
1187 if (!client) {
1188 i2c_put_adapter(adap);
1189 return -ENOMEM; 1307 return -ENOMEM;
1190 }
1191 1308
1192 platform_set_drvdata(pdev, client); 1309 icd->iface = icl->bus_id;
1310 icd->pdev = &pdev->dev;
1311 platform_set_drvdata(pdev, icd);
1312 icd->dev.platform_data = icl;
1313
1314 ret = soc_camera_device_register(icd);
1315 if (ret < 0)
1316 goto escdevreg;
1317
1318 icd->user_width = DEFAULT_WIDTH;
1319 icd->user_height = DEFAULT_HEIGHT;
1193 1320
1194 return 0; 1321 return 0;
1322
1323escdevreg:
1324 kfree(icd);
1325
1326 return ret;
1195} 1327}
1196 1328
1329/* Only called on rmmod for each platform device, since they are not
1330 * hot-pluggable. Now we know, that all our users - hosts and devices have
1331 * been unloaded already */
1197static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) 1332static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1198{ 1333{
1199 struct i2c_client *client = platform_get_drvdata(pdev); 1334 struct soc_camera_device *icd = platform_get_drvdata(pdev);
1200 1335
1201 if (!client) 1336 if (!icd)
1202 return -ENODEV; 1337 return -EINVAL;
1203 1338
1204 i2c_unregister_device(client); 1339 soc_camera_device_unregister(icd);
1205 i2c_put_adapter(client->adapter); 1340
1341 kfree(icd);
1206 1342
1207 return 0; 1343 return 0;
1208} 1344}
1209 1345
1210static struct platform_driver __refdata soc_camera_pdrv = { 1346static struct platform_driver __refdata soc_camera_pdrv = {
1211 .probe = soc_camera_pdrv_probe, 1347 .remove = __devexit_p(soc_camera_pdrv_remove),
1212 .remove = __devexit_p(soc_camera_pdrv_remove), 1348 .driver = {
1213 .driver = { 1349 .name = "soc-camera-pdrv",
1214 .name = "soc-camera-pdrv", 1350 .owner = THIS_MODULE,
1215 .owner = THIS_MODULE,
1216 }, 1351 },
1217}; 1352};
1218 1353
@@ -1225,7 +1360,7 @@ static int __init soc_camera_init(void)
1225 if (ret) 1360 if (ret)
1226 goto edrvr; 1361 goto edrvr;
1227 1362
1228 ret = platform_driver_register(&soc_camera_pdrv); 1363 ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);
1229 if (ret) 1364 if (ret)
1230 goto epdr; 1365 goto epdr;
1231 1366
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index c48676356ab7..b6a575ce5da2 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -16,54 +16,32 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19#include <media/v4l2-common.h> 19#include <media/v4l2-subdev.h>
20#include <media/soc_camera.h> 20#include <media/soc_camera.h>
21#include <media/soc_camera_platform.h> 21#include <media/soc_camera_platform.h>
22 22
23struct soc_camera_platform_priv { 23struct soc_camera_platform_priv {
24 struct soc_camera_platform_info *info; 24 struct v4l2_subdev subdev;
25 struct soc_camera_device icd;
26 struct soc_camera_data_format format; 25 struct soc_camera_data_format format;
27}; 26};
28 27
29static struct soc_camera_platform_info * 28static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
30soc_camera_platform_get_info(struct soc_camera_device *icd)
31{ 29{
32 struct soc_camera_platform_priv *priv; 30 struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
33 priv = container_of(icd, struct soc_camera_platform_priv, icd); 31 return container_of(subdev, struct soc_camera_platform_priv, subdev);
34 return priv->info;
35}
36
37static int soc_camera_platform_init(struct soc_camera_device *icd)
38{
39 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
40
41 if (p->power)
42 p->power(1);
43
44 return 0;
45}
46
47static int soc_camera_platform_release(struct soc_camera_device *icd)
48{
49 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
50
51 if (p->power)
52 p->power(0);
53
54 return 0;
55} 32}
56 33
57static int soc_camera_platform_start_capture(struct soc_camera_device *icd) 34static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
58{ 35{
59 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 36 struct platform_device *pdev =
60 return p->set_capture(p, 1); 37 to_platform_device(to_soc_camera_control(icd));
38 return pdev->dev.platform_data;
61} 39}
62 40
63static int soc_camera_platform_stop_capture(struct soc_camera_device *icd) 41static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
64{ 42{
65 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 43 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
66 return p->set_capture(p, 0); 44 return p->set_capture(p, enable);
67} 45}
68 46
69static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd, 47static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
@@ -75,26 +53,14 @@ static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
75static unsigned long 53static unsigned long
76soc_camera_platform_query_bus_param(struct soc_camera_device *icd) 54soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
77{ 55{
78 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 56 struct soc_camera_platform_info *p = get_info(icd);
79 return p->bus_param; 57 return p->bus_param;
80} 58}
81 59
82static int soc_camera_platform_set_crop(struct soc_camera_device *icd, 60static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
83 struct v4l2_rect *rect)
84{
85 return 0;
86}
87
88static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
89 struct v4l2_format *f) 61 struct v4l2_format *f)
90{ 62{
91 return 0; 63 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
92}
93
94static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
95 struct v4l2_format *f)
96{
97 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
98 struct v4l2_pix_format *pix = &f->fmt.pix; 64 struct v4l2_pix_format *pix = &f->fmt.pix;
99 65
100 pix->width = p->format.width; 66 pix->width = p->format.width;
@@ -102,82 +68,99 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
102 return 0; 68 return 0;
103} 69}
104 70
105static int soc_camera_platform_video_probe(struct soc_camera_device *icd) 71static void soc_camera_platform_video_probe(struct soc_camera_device *icd,
72 struct platform_device *pdev)
106{ 73{
107 struct soc_camera_platform_priv *priv; 74 struct soc_camera_platform_priv *priv = get_priv(pdev);
108 priv = container_of(icd, struct soc_camera_platform_priv, icd); 75 struct soc_camera_platform_info *p = pdev->dev.platform_data;
109 76
110 priv->format.name = priv->info->format_name; 77 priv->format.name = p->format_name;
111 priv->format.depth = priv->info->format_depth; 78 priv->format.depth = p->format_depth;
112 priv->format.fourcc = priv->info->format.pixelformat; 79 priv->format.fourcc = p->format.pixelformat;
113 priv->format.colorspace = priv->info->format.colorspace; 80 priv->format.colorspace = p->format.colorspace;
114 81
115 icd->formats = &priv->format; 82 icd->formats = &priv->format;
116 icd->num_formats = 1; 83 icd->num_formats = 1;
117
118 return soc_camera_video_start(icd);
119} 84}
120 85
121static void soc_camera_platform_video_remove(struct soc_camera_device *icd) 86static struct v4l2_subdev_core_ops platform_subdev_core_ops;
122{ 87
123 soc_camera_video_stop(icd); 88static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
124} 89 .s_stream = soc_camera_platform_s_stream,
90 .try_fmt = soc_camera_platform_try_fmt,
91};
92
93static struct v4l2_subdev_ops platform_subdev_ops = {
94 .core = &platform_subdev_core_ops,
95 .video = &platform_subdev_video_ops,
96};
125 97
126static struct soc_camera_ops soc_camera_platform_ops = { 98static struct soc_camera_ops soc_camera_platform_ops = {
127 .owner = THIS_MODULE,
128 .probe = soc_camera_platform_video_probe,
129 .remove = soc_camera_platform_video_remove,
130 .init = soc_camera_platform_init,
131 .release = soc_camera_platform_release,
132 .start_capture = soc_camera_platform_start_capture,
133 .stop_capture = soc_camera_platform_stop_capture,
134 .set_crop = soc_camera_platform_set_crop,
135 .set_fmt = soc_camera_platform_set_fmt,
136 .try_fmt = soc_camera_platform_try_fmt,
137 .set_bus_param = soc_camera_platform_set_bus_param, 99 .set_bus_param = soc_camera_platform_set_bus_param,
138 .query_bus_param = soc_camera_platform_query_bus_param, 100 .query_bus_param = soc_camera_platform_query_bus_param,
139}; 101};
140 102
141static int soc_camera_platform_probe(struct platform_device *pdev) 103static int soc_camera_platform_probe(struct platform_device *pdev)
142{ 104{
105 struct soc_camera_host *ici;
143 struct soc_camera_platform_priv *priv; 106 struct soc_camera_platform_priv *priv;
144 struct soc_camera_platform_info *p; 107 struct soc_camera_platform_info *p = pdev->dev.platform_data;
145 struct soc_camera_device *icd; 108 struct soc_camera_device *icd;
146 int ret; 109 int ret;
147 110
148 p = pdev->dev.platform_data;
149 if (!p) 111 if (!p)
150 return -EINVAL; 112 return -EINVAL;
151 113
114 if (!p->dev) {
115 dev_err(&pdev->dev,
116 "Platform has not set soc_camera_device pointer!\n");
117 return -EINVAL;
118 }
119
152 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 120 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
153 if (!priv) 121 if (!priv)
154 return -ENOMEM; 122 return -ENOMEM;
155 123
156 priv->info = p; 124 icd = to_soc_camera_dev(p->dev);
157 platform_set_drvdata(pdev, priv); 125
126 /* soc-camera convention: control's drvdata points to the subdev */
127 platform_set_drvdata(pdev, &priv->subdev);
128 /* Set the control device reference */
129 dev_set_drvdata(&icd->dev, &pdev->dev);
130
131 icd->y_skip_top = 0;
132 icd->ops = &soc_camera_platform_ops;
133
134 ici = to_soc_camera_host(icd->dev.parent);
158 135
159 icd = &priv->icd; 136 soc_camera_platform_video_probe(icd, pdev);
160 icd->ops = &soc_camera_platform_ops;
161 icd->control = &pdev->dev;
162 icd->width_min = 0;
163 icd->width_max = priv->info->format.width;
164 icd->height_min = 0;
165 icd->height_max = priv->info->format.height;
166 icd->y_skip_top = 0;
167 icd->iface = priv->info->iface;
168 137
169 ret = soc_camera_device_register(icd); 138 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
139 v4l2_set_subdevdata(&priv->subdev, p);
140 strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
141
142 ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
170 if (ret) 143 if (ret)
171 kfree(priv); 144 goto evdrs;
145
146 return ret;
172 147
148evdrs:
149 icd->ops = NULL;
150 platform_set_drvdata(pdev, NULL);
151 kfree(priv);
173 return ret; 152 return ret;
174} 153}
175 154
176static int soc_camera_platform_remove(struct platform_device *pdev) 155static int soc_camera_platform_remove(struct platform_device *pdev)
177{ 156{
178 struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev); 157 struct soc_camera_platform_priv *priv = get_priv(pdev);
158 struct soc_camera_platform_info *p = pdev->dev.platform_data;
159 struct soc_camera_device *icd = to_soc_camera_dev(p->dev);
179 160
180 soc_camera_device_unregister(&priv->icd); 161 v4l2_device_unregister_subdev(&priv->subdev);
162 icd->ops = NULL;
163 platform_set_drvdata(pdev, NULL);
181 kfree(priv); 164 kfree(priv);
182 return 0; 165 return 0;
183} 166}
@@ -185,6 +168,7 @@ static int soc_camera_platform_remove(struct platform_device *pdev)
185static struct platform_driver soc_camera_platform_driver = { 168static struct platform_driver soc_camera_platform_driver = {
186 .driver = { 169 .driver = {
187 .name = "soc_camera_platform", 170 .name = "soc_camera_platform",
171 .owner = THIS_MODULE,
188 }, 172 },
189 .probe = soc_camera_platform_probe, 173 .probe = soc_camera_platform_probe,
190 .remove = soc_camera_platform_remove, 174 .remove = soc_camera_platform_remove,
@@ -206,3 +190,4 @@ module_exit(soc_camera_platform_module_exit);
206MODULE_DESCRIPTION("SoC Camera Platform driver"); 190MODULE_DESCRIPTION("SoC Camera Platform driver");
207MODULE_AUTHOR("Magnus Damm"); 191MODULE_AUTHOR("Magnus Damm");
208MODULE_LICENSE("GPL v2"); 192MODULE_LICENSE("GPL v2");
193MODULE_ALIAS("platform:soc_camera_platform");
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2816f1839230..aba92e2313d8 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -29,6 +29,7 @@
29#include "tuner-simple.h" 29#include "tuner-simple.h"
30#include "tda9887.h" 30#include "tda9887.h"
31#include "xc5000.h" 31#include "xc5000.h"
32#include "tda18271.h"
32 33
33#define UNSET (-1U) 34#define UNSET (-1U)
34 35
@@ -420,6 +421,17 @@ static void set_type(struct i2c_client *c, unsigned int type,
420 goto attach_failed; 421 goto attach_failed;
421 break; 422 break;
422 } 423 }
424 case TUNER_NXP_TDA18271:
425 {
426 struct tda18271_config cfg = {
427 .config = t->config,
428 };
429
430 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
431 t->i2c->adapter, &cfg))
432 goto attach_failed;
433 break;
434 }
423 default: 435 default:
424 if (!dvb_attach(simple_tuner_attach, &t->fe, 436 if (!dvb_attach(simple_tuner_attach, &t->fe,
425 t->i2c->adapter, t->i2c->addr, t->type)) 437 t->i2c->adapter, t->i2c->addr, t->type))
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 3750f7fadb12..244372627df2 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -31,7 +31,10 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
34#include <media/v4l2-int-device.h> 34
35#include <media/v4l2-device.h>
36#include <media/v4l2-common.h>
37#include <media/v4l2-chip-ident.h>
35#include <media/tvp514x.h> 38#include <media/tvp514x.h>
36 39
37#include "tvp514x_regs.h" 40#include "tvp514x_regs.h"
@@ -49,15 +52,11 @@ static int debug;
49module_param(debug, bool, 0644); 52module_param(debug, bool, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-1)"); 53MODULE_PARM_DESC(debug, "Debug level (0-1)");
51 54
52#define dump_reg(client, reg, val) \ 55MODULE_AUTHOR("Texas Instruments");
53 do { \ 56MODULE_DESCRIPTION("TVP514X linux decoder driver");
54 val = tvp514x_read_reg(client, reg); \ 57MODULE_LICENSE("GPL");
55 v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
56 } while (0)
57 58
58/** 59/* enum tvp514x_std - enum for supported standards */
59 * enum tvp514x_std - enum for supported standards
60 */
61enum tvp514x_std { 60enum tvp514x_std {
62 STD_NTSC_MJ = 0, 61 STD_NTSC_MJ = 0,
63 STD_PAL_BDGHIN, 62 STD_PAL_BDGHIN,
@@ -65,14 +64,6 @@ enum tvp514x_std {
65}; 64};
66 65
67/** 66/**
68 * enum tvp514x_state - enum for different decoder states
69 */
70enum tvp514x_state {
71 STATE_NOT_DETECTED,
72 STATE_DETECTED
73};
74
75/**
76 * struct tvp514x_std_info - Structure to store standard informations 67 * struct tvp514x_std_info - Structure to store standard informations
77 * @width: Line width in pixels 68 * @width: Line width in pixels
78 * @height:Number of active lines 69 * @height:Number of active lines
@@ -89,33 +80,27 @@ struct tvp514x_std_info {
89static struct tvp514x_reg tvp514x_reg_list_default[0x40]; 80static struct tvp514x_reg tvp514x_reg_list_default[0x40];
90/** 81/**
91 * struct tvp514x_decoder - TVP5146/47 decoder object 82 * struct tvp514x_decoder - TVP5146/47 decoder object
92 * @v4l2_int_device: Slave handle 83 * @sd: Subdevice Slave handle
93 * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
94 * @tvp514x_regs: copy of hw's regs with preset values. 84 * @tvp514x_regs: copy of hw's regs with preset values.
95 * @pdata: Board specific 85 * @pdata: Board specific
96 * @client: I2C client data
97 * @id: Entry from I2C table
98 * @ver: Chip version 86 * @ver: Chip version
99 * @state: TVP5146/47 decoder state - detected or not-detected 87 * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
100 * @pix: Current pixel format 88 * @pix: Current pixel format
101 * @num_fmts: Number of formats 89 * @num_fmts: Number of formats
102 * @fmt_list: Format list 90 * @fmt_list: Format list
103 * @current_std: Current standard 91 * @current_std: Current standard
104 * @num_stds: Number of standards 92 * @num_stds: Number of standards
105 * @std_list: Standards list 93 * @std_list: Standards list
106 * @route: input and output routing at chip level 94 * @input: Input routing at chip level
95 * @output: Output routing at chip level
107 */ 96 */
108struct tvp514x_decoder { 97struct tvp514x_decoder {
109 struct v4l2_int_device v4l2_int_device; 98 struct v4l2_subdev sd;
110 struct v4l2_int_slave tvp514x_slave;
111 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; 99 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
112 const struct tvp514x_platform_data *pdata; 100 const struct tvp514x_platform_data *pdata;
113 struct i2c_client *client;
114
115 struct i2c_device_id *id;
116 101
117 int ver; 102 int ver;
118 enum tvp514x_state state; 103 int streaming;
119 104
120 struct v4l2_pix_format pix; 105 struct v4l2_pix_format pix;
121 int num_fmts; 106 int num_fmts;
@@ -124,15 +109,18 @@ struct tvp514x_decoder {
124 enum tvp514x_std current_std; 109 enum tvp514x_std current_std;
125 int num_stds; 110 int num_stds;
126 struct tvp514x_std_info *std_list; 111 struct tvp514x_std_info *std_list;
127 112 /* Input and Output Routing parameters */
128 struct v4l2_routing route; 113 u32 input;
114 u32 output;
129}; 115};
130 116
131/* TVP514x default register values */ 117/* TVP514x default register values */
132static struct tvp514x_reg tvp514x_reg_list_default[] = { 118static struct tvp514x_reg tvp514x_reg_list_default[] = {
133 {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ 119 /* Composite selected */
120 {TOK_WRITE, REG_INPUT_SEL, 0x05},
134 {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, 121 {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
135 {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ 122 /* Auto mode */
123 {TOK_WRITE, REG_VIDEO_STD, 0x00},
136 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 124 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
137 {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F}, 125 {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
138 {TOK_WRITE, REG_COLOR_KILLER, 0x10}, 126 {TOK_WRITE, REG_COLOR_KILLER, 0x10},
@@ -145,53 +133,74 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
145 {TOK_WRITE, REG_HUE, 0x00}, 133 {TOK_WRITE, REG_HUE, 0x00},
146 {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00}, 134 {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
147 {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E}, 135 {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
148 {TOK_SKIP, 0x0F, 0x00}, /* Reserved */ 136 /* Reserved */
137 {TOK_SKIP, 0x0F, 0x00},
149 {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80}, 138 {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
150 {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80}, 139 {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
151 {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80}, 140 {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
152 {TOK_SKIP, 0x13, 0x00}, /* Reserved */ 141 /* Reserved */
142 {TOK_SKIP, 0x13, 0x00},
153 {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80}, 143 {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
154 {TOK_SKIP, 0x15, 0x00}, /* Reserved */ 144 /* Reserved */
155 {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55}, /* NTSC timing */ 145 {TOK_SKIP, 0x15, 0x00},
146 /* NTSC timing */
147 {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},
156 {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00}, 148 {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
157 {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25}, 149 {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
158 {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03}, 150 {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
159 {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00}, /* NTSC timing */ 151 /* NTSC timing */
152 {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},
160 {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00}, 153 {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
161 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40}, 154 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
162 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00}, 155 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
163 {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04}, /* NTSC timing */ 156 /* NTSC timing */
157 {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},
164 {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00}, 158 {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
165 {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07}, 159 {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
166 {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00}, 160 {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
167 {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01}, /* NTSC timing */ 161 /* NTSC timing */
162 {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},
168 {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00}, 163 {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
169 {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15}, 164 {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
170 {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00}, 165 {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
171 {TOK_SKIP, 0x26, 0x00}, /* Reserved */ 166 /* Reserved */
172 {TOK_SKIP, 0x27, 0x00}, /* Reserved */ 167 {TOK_SKIP, 0x26, 0x00},
168 /* Reserved */
169 {TOK_SKIP, 0x27, 0x00},
173 {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC}, 170 {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
174 {TOK_SKIP, 0x29, 0x00}, /* Reserved */ 171 /* Reserved */
172 {TOK_SKIP, 0x29, 0x00},
175 {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00}, 173 {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
176 {TOK_SKIP, 0x2B, 0x00}, /* Reserved */ 174 /* Reserved */
175 {TOK_SKIP, 0x2B, 0x00},
177 {TOK_SKIP, REG_SCART_DELAY, 0x00}, 176 {TOK_SKIP, REG_SCART_DELAY, 0x00},
178 {TOK_SKIP, REG_CTI_DELAY, 0x00}, 177 {TOK_SKIP, REG_CTI_DELAY, 0x00},
179 {TOK_SKIP, REG_CTI_CONTROL, 0x00}, 178 {TOK_SKIP, REG_CTI_CONTROL, 0x00},
180 {TOK_SKIP, 0x2F, 0x00}, /* Reserved */ 179 /* Reserved */
181 {TOK_SKIP, 0x30, 0x00}, /* Reserved */ 180 {TOK_SKIP, 0x2F, 0x00},
182 {TOK_SKIP, 0x31, 0x00}, /* Reserved */ 181 /* Reserved */
183 {TOK_WRITE, REG_SYNC_CONTROL, 0x00}, /* HS, VS active high */ 182 {TOK_SKIP, 0x30, 0x00},
184 {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00}, /* 10-bit BT.656 */ 183 /* Reserved */
185 {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11}, /* Enable clk & data */ 184 {TOK_SKIP, 0x31, 0x00},
186 {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE}, /* Enable AVID & FLD */ 185 /* HS, VS active high */
187 {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF}, /* Enable VS & HS */ 186 {TOK_WRITE, REG_SYNC_CONTROL, 0x00},
187 /* 10-bit BT.656 */
188 {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},
189 /* Enable clk & data */
190 {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},
191 /* Enable AVID & FLD */
192 {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},
193 /* Enable VS & HS */
194 {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},
188 {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF}, 195 {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
189 {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF}, 196 {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
190 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, /* Clear status */ 197 /* Clear status */
198 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},
191 {TOK_TERM, 0, 0}, 199 {TOK_TERM, 0, 0},
192}; 200};
193 201
194/* List of image formats supported by TVP5146/47 decoder 202/**
203 * List of image formats supported by TVP5146/47 decoder
195 * Currently we are using 8 bit mode only, but can be 204 * Currently we are using 8 bit mode only, but can be
196 * extended to 10/20 bit mode. 205 * extended to 10/20 bit mode.
197 */ 206 */
@@ -205,7 +214,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
205 }, 214 },
206}; 215};
207 216
208/* 217/**
209 * Supported standards - 218 * Supported standards -
210 * 219 *
211 * Currently supports two standards only, need to add support for rest of the 220 * Currently supports two standards only, need to add support for rest of the
@@ -240,35 +249,32 @@ static struct tvp514x_std_info tvp514x_std_list[] = {
240 }, 249 },
241 /* Standard: need to add for additional standard */ 250 /* Standard: need to add for additional standard */
242}; 251};
243/*
244 * Control structure for Auto Gain
245 * This is temporary data, will get replaced once
246 * v4l2_ctrl_query_fill supports it.
247 */
248static const struct v4l2_queryctrl tvp514x_autogain_ctrl = {
249 .id = V4L2_CID_AUTOGAIN,
250 .name = "Gain, Automatic",
251 .type = V4L2_CTRL_TYPE_BOOLEAN,
252 .minimum = 0,
253 .maximum = 1,
254 .step = 1,
255 .default_value = 1,
256};
257 252
258/* 253
259 * Read a value from a register in an TVP5146/47 decoder device. 254static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
255{
256 return container_of(sd, struct tvp514x_decoder, sd);
257}
258
259
260/**
261 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
262 * @sd: ptr to v4l2_subdev struct
263 * @reg: TVP5146/47 register address
264 *
260 * Returns value read if successful, or non-zero (-1) otherwise. 265 * Returns value read if successful, or non-zero (-1) otherwise.
261 */ 266 */
262static int tvp514x_read_reg(struct i2c_client *client, u8 reg) 267static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
263{ 268{
264 int err; 269 int err, retry = 0;
265 int retry = 0; 270 struct i2c_client *client = v4l2_get_subdevdata(sd);
271
266read_again: 272read_again:
267 273
268 err = i2c_smbus_read_byte_data(client, reg); 274 err = i2c_smbus_read_byte_data(client, reg);
269 if (err == -1) { 275 if (err == -1) {
270 if (retry <= I2C_RETRY_COUNT) { 276 if (retry <= I2C_RETRY_COUNT) {
271 v4l_warn(client, "Read: retry ... %d\n", retry); 277 v4l2_warn(sd, "Read: retry ... %d\n", retry);
272 retry++; 278 retry++;
273 msleep_interruptible(10); 279 msleep_interruptible(10);
274 goto read_again; 280 goto read_again;
@@ -278,20 +284,39 @@ read_again:
278 return err; 284 return err;
279} 285}
280 286
281/* 287/**
288 * dump_reg() - dump the register content of TVP5146/47.
289 * @sd: ptr to v4l2_subdev struct
290 * @reg: TVP5146/47 register address
291 */
292static void dump_reg(struct v4l2_subdev *sd, u8 reg)
293{
294 u32 val;
295
296 val = tvp514x_read_reg(sd, reg);
297 v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val);
298}
299
300/**
301 * tvp514x_write_reg() - Write a value to a register in TVP5146/47
302 * @sd: ptr to v4l2_subdev struct
303 * @reg: TVP5146/47 register address
304 * @val: value to be written to the register
305 *
282 * Write a value to a register in an TVP5146/47 decoder device. 306 * Write a value to a register in an TVP5146/47 decoder device.
283 * Returns zero if successful, or non-zero otherwise. 307 * Returns zero if successful, or non-zero otherwise.
284 */ 308 */
285static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val) 309static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
286{ 310{
287 int err; 311 int err, retry = 0;
288 int retry = 0; 312 struct i2c_client *client = v4l2_get_subdevdata(sd);
313
289write_again: 314write_again:
290 315
291 err = i2c_smbus_write_byte_data(client, reg, val); 316 err = i2c_smbus_write_byte_data(client, reg, val);
292 if (err) { 317 if (err) {
293 if (retry <= I2C_RETRY_COUNT) { 318 if (retry <= I2C_RETRY_COUNT) {
294 v4l_warn(client, "Write: retry ... %d\n", retry); 319 v4l2_warn(sd, "Write: retry ... %d\n", retry);
295 retry++; 320 retry++;
296 msleep_interruptible(10); 321 msleep_interruptible(10);
297 goto write_again; 322 goto write_again;
@@ -301,17 +326,19 @@ write_again:
301 return err; 326 return err;
302} 327}
303 328
304/* 329/**
305 * tvp514x_write_regs : Initializes a list of TVP5146/47 registers 330 * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers
331 * @sd: ptr to v4l2_subdev struct
332 * @reglist: list of TVP5146/47 registers and values
333 *
334 * Initializes a list of TVP5146/47 registers:-
306 * if token is TOK_TERM, then entire write operation terminates 335 * if token is TOK_TERM, then entire write operation terminates
307 * if token is TOK_DELAY, then a delay of 'val' msec is introduced 336 * if token is TOK_DELAY, then a delay of 'val' msec is introduced
308 * if token is TOK_SKIP, then the register write is skipped 337 * if token is TOK_SKIP, then the register write is skipped
309 * if token is TOK_WRITE, then the register write is performed 338 * if token is TOK_WRITE, then the register write is performed
310 *
311 * reglist - list of registers to be written
312 * Returns zero if successful, or non-zero otherwise. 339 * Returns zero if successful, or non-zero otherwise.
313 */ 340 */
314static int tvp514x_write_regs(struct i2c_client *client, 341static int tvp514x_write_regs(struct v4l2_subdev *sd,
315 const struct tvp514x_reg reglist[]) 342 const struct tvp514x_reg reglist[])
316{ 343{
317 int err; 344 int err;
@@ -326,31 +353,33 @@ static int tvp514x_write_regs(struct i2c_client *client,
326 if (next->token == TOK_SKIP) 353 if (next->token == TOK_SKIP)
327 continue; 354 continue;
328 355
329 err = tvp514x_write_reg(client, next->reg, (u8) next->val); 356 err = tvp514x_write_reg(sd, next->reg, (u8) next->val);
330 if (err) { 357 if (err) {
331 v4l_err(client, "Write failed. Err[%d]\n", err); 358 v4l2_err(sd, "Write failed. Err[%d]\n", err);
332 return err; 359 return err;
333 } 360 }
334 } 361 }
335 return 0; 362 return 0;
336} 363}
337 364
338/* 365/**
339 * tvp514x_get_current_std: 366 * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47
340 * Returns the current standard detected by TVP5146/47 367 * @sd: ptr to v4l2_subdev struct
368 *
369 * Get current standard detected by TVP5146/47, STD_INVALID if there is no
370 * standard detected.
341 */ 371 */
342static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder 372static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd)
343 *decoder)
344{ 373{
345 u8 std, std_status; 374 u8 std, std_status;
346 375
347 std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD); 376 std = tvp514x_read_reg(sd, REG_VIDEO_STD);
348 if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) { 377 if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT)
349 /* use the standard status register */ 378 /* use the standard status register */
350 std_status = tvp514x_read_reg(decoder->client, 379 std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS);
351 REG_VIDEO_STD_STATUS); 380 else
352 } else 381 /* use the standard register itself */
353 std_status = std; /* use the standard register itself */ 382 std_status = std;
354 383
355 switch (std_status & VIDEO_STD_MASK) { 384 switch (std_status & VIDEO_STD_MASK) {
356 case VIDEO_STD_NTSC_MJ_BIT: 385 case VIDEO_STD_NTSC_MJ_BIT:
@@ -366,94 +395,99 @@ static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
366 return STD_INVALID; 395 return STD_INVALID;
367} 396}
368 397
369/* 398/* TVP5146/47 register dump function */
370 * TVP5146/47 register dump function 399static void tvp514x_reg_dump(struct v4l2_subdev *sd)
371 */
372static void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
373{ 400{
374 u8 value; 401 dump_reg(sd, REG_INPUT_SEL);
375 402 dump_reg(sd, REG_AFE_GAIN_CTRL);
376 dump_reg(decoder->client, REG_INPUT_SEL, value); 403 dump_reg(sd, REG_VIDEO_STD);
377 dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value); 404 dump_reg(sd, REG_OPERATION_MODE);
378 dump_reg(decoder->client, REG_VIDEO_STD, value); 405 dump_reg(sd, REG_COLOR_KILLER);
379 dump_reg(decoder->client, REG_OPERATION_MODE, value); 406 dump_reg(sd, REG_LUMA_CONTROL1);
380 dump_reg(decoder->client, REG_COLOR_KILLER, value); 407 dump_reg(sd, REG_LUMA_CONTROL2);
381 dump_reg(decoder->client, REG_LUMA_CONTROL1, value); 408 dump_reg(sd, REG_LUMA_CONTROL3);
382 dump_reg(decoder->client, REG_LUMA_CONTROL2, value); 409 dump_reg(sd, REG_BRIGHTNESS);
383 dump_reg(decoder->client, REG_LUMA_CONTROL3, value); 410 dump_reg(sd, REG_CONTRAST);
384 dump_reg(decoder->client, REG_BRIGHTNESS, value); 411 dump_reg(sd, REG_SATURATION);
385 dump_reg(decoder->client, REG_CONTRAST, value); 412 dump_reg(sd, REG_HUE);
386 dump_reg(decoder->client, REG_SATURATION, value); 413 dump_reg(sd, REG_CHROMA_CONTROL1);
387 dump_reg(decoder->client, REG_HUE, value); 414 dump_reg(sd, REG_CHROMA_CONTROL2);
388 dump_reg(decoder->client, REG_CHROMA_CONTROL1, value); 415 dump_reg(sd, REG_COMP_PR_SATURATION);
389 dump_reg(decoder->client, REG_CHROMA_CONTROL2, value); 416 dump_reg(sd, REG_COMP_Y_CONTRAST);
390 dump_reg(decoder->client, REG_COMP_PR_SATURATION, value); 417 dump_reg(sd, REG_COMP_PB_SATURATION);
391 dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value); 418 dump_reg(sd, REG_COMP_Y_BRIGHTNESS);
392 dump_reg(decoder->client, REG_COMP_PB_SATURATION, value); 419 dump_reg(sd, REG_AVID_START_PIXEL_LSB);
393 dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value); 420 dump_reg(sd, REG_AVID_START_PIXEL_MSB);
394 dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value); 421 dump_reg(sd, REG_AVID_STOP_PIXEL_LSB);
395 dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value); 422 dump_reg(sd, REG_AVID_STOP_PIXEL_MSB);
396 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value); 423 dump_reg(sd, REG_HSYNC_START_PIXEL_LSB);
397 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value); 424 dump_reg(sd, REG_HSYNC_START_PIXEL_MSB);
398 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value); 425 dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB);
399 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value); 426 dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB);
400 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value); 427 dump_reg(sd, REG_VSYNC_START_LINE_LSB);
401 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value); 428 dump_reg(sd, REG_VSYNC_START_LINE_MSB);
402 dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value); 429 dump_reg(sd, REG_VSYNC_STOP_LINE_LSB);
403 dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value); 430 dump_reg(sd, REG_VSYNC_STOP_LINE_MSB);
404 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value); 431 dump_reg(sd, REG_VBLK_START_LINE_LSB);
405 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value); 432 dump_reg(sd, REG_VBLK_START_LINE_MSB);
406 dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value); 433 dump_reg(sd, REG_VBLK_STOP_LINE_LSB);
407 dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value); 434 dump_reg(sd, REG_VBLK_STOP_LINE_MSB);
408 dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value); 435 dump_reg(sd, REG_SYNC_CONTROL);
409 dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value); 436 dump_reg(sd, REG_OUTPUT_FORMATTER1);
410 dump_reg(decoder->client, REG_SYNC_CONTROL, value); 437 dump_reg(sd, REG_OUTPUT_FORMATTER2);
411 dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value); 438 dump_reg(sd, REG_OUTPUT_FORMATTER3);
412 dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value); 439 dump_reg(sd, REG_OUTPUT_FORMATTER4);
413 dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value); 440 dump_reg(sd, REG_OUTPUT_FORMATTER5);
414 dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value); 441 dump_reg(sd, REG_OUTPUT_FORMATTER6);
415 dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value); 442 dump_reg(sd, REG_CLEAR_LOST_LOCK);
416 dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
417 dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
418} 443}
419 444
420/* 445/**
421 * Configure the TVP5146/47 with the current register settings 446 * tvp514x_configure() - Configure the TVP5146/47 registers
447 * @sd: ptr to v4l2_subdev struct
448 * @decoder: ptr to tvp514x_decoder structure
449 *
422 * Returns zero if successful, or non-zero otherwise. 450 * Returns zero if successful, or non-zero otherwise.
423 */ 451 */
424static int tvp514x_configure(struct tvp514x_decoder *decoder) 452static int tvp514x_configure(struct v4l2_subdev *sd,
453 struct tvp514x_decoder *decoder)
425{ 454{
426 int err; 455 int err;
427 456
428 /* common register initialization */ 457 /* common register initialization */
429 err = 458 err =
430 tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); 459 tvp514x_write_regs(sd, decoder->tvp514x_regs);
431 if (err) 460 if (err)
432 return err; 461 return err;
433 462
434 if (debug) 463 if (debug)
435 tvp514x_reg_dump(decoder); 464 tvp514x_reg_dump(sd);
436 465
437 return 0; 466 return 0;
438} 467}
439 468
440/* 469/**
441 * Detect if an tvp514x is present, and if so which revision. 470 * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision.
471 * @sd: pointer to standard V4L2 sub-device structure
472 * @decoder: pointer to tvp514x_decoder structure
473 *
442 * A device is considered to be detected if the chip ID (LSB and MSB) 474 * A device is considered to be detected if the chip ID (LSB and MSB)
443 * registers match the expected values. 475 * registers match the expected values.
444 * Any value of the rom version register is accepted. 476 * Any value of the rom version register is accepted.
445 * Returns ENODEV error number if no device is detected, or zero 477 * Returns ENODEV error number if no device is detected, or zero
446 * if a device is detected. 478 * if a device is detected.
447 */ 479 */
448static int tvp514x_detect(struct tvp514x_decoder *decoder) 480static int tvp514x_detect(struct v4l2_subdev *sd,
481 struct tvp514x_decoder *decoder)
449{ 482{
450 u8 chip_id_msb, chip_id_lsb, rom_ver; 483 u8 chip_id_msb, chip_id_lsb, rom_ver;
484 struct i2c_client *client = v4l2_get_subdevdata(sd);
451 485
452 chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB); 486 chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB);
453 chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB); 487 chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB);
454 rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION); 488 rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION);
455 489
456 v4l_dbg(1, debug, decoder->client, 490 v4l2_dbg(1, debug, sd,
457 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n", 491 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
458 chip_id_msb, chip_id_lsb, rom_ver); 492 chip_id_msb, chip_id_lsb, rom_ver);
459 if ((chip_id_msb != TVP514X_CHIP_ID_MSB) 493 if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
@@ -462,38 +496,30 @@ static int tvp514x_detect(struct tvp514x_decoder *decoder)
462 /* We didn't read the values we expected, so this must not be 496 /* We didn't read the values we expected, so this must not be
463 * an TVP5146/47. 497 * an TVP5146/47.
464 */ 498 */
465 v4l_err(decoder->client, 499 v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n",
466 "chip id mismatch msb:0x%x lsb:0x%x\n", 500 chip_id_msb, chip_id_lsb);
467 chip_id_msb, chip_id_lsb);
468 return -ENODEV; 501 return -ENODEV;
469 } 502 }
470 503
471 decoder->ver = rom_ver; 504 decoder->ver = rom_ver;
472 decoder->state = STATE_DETECTED;
473 505
474 v4l_info(decoder->client, 506 v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n",
475 "%s found at 0x%x (%s)\n", decoder->client->name, 507 client->name, decoder->ver,
476 decoder->client->addr << 1, 508 client->addr << 1, client->adapter->name);
477 decoder->client->adapter->name);
478 return 0; 509 return 0;
479} 510}
480 511
481/*
482 * Following are decoder interface functions implemented by
483 * TVP5146/47 decoder driver.
484 */
485
486/** 512/**
487 * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl 513 * tvp514x_querystd() - V4L2 decoder interface handler for querystd
488 * @s: pointer to standard V4L2 device structure 514 * @sd: pointer to standard V4L2 sub-device structure
489 * @std_id: standard V4L2 std_id ioctl enum 515 * @std_id: standard V4L2 std_id ioctl enum
490 * 516 *
491 * Returns the current standard detected by TVP5146/47. If no active input is 517 * Returns the current standard detected by TVP5146/47. If no active input is
492 * detected, returns -EINVAL 518 * detected, returns -EINVAL
493 */ 519 */
494static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id) 520static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
495{ 521{
496 struct tvp514x_decoder *decoder = s->priv; 522 struct tvp514x_decoder *decoder = to_decoder(sd);
497 enum tvp514x_std current_std; 523 enum tvp514x_std current_std;
498 enum tvp514x_input input_sel; 524 enum tvp514x_input input_sel;
499 u8 sync_lock_status, lock_mask; 525 u8 sync_lock_status, lock_mask;
@@ -502,11 +528,11 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
502 return -EINVAL; 528 return -EINVAL;
503 529
504 /* get the current standard */ 530 /* get the current standard */
505 current_std = tvp514x_get_current_std(decoder); 531 current_std = tvp514x_get_current_std(sd);
506 if (current_std == STD_INVALID) 532 if (current_std == STD_INVALID)
507 return -EINVAL; 533 return -EINVAL;
508 534
509 input_sel = decoder->route.input; 535 input_sel = decoder->input;
510 536
511 switch (input_sel) { 537 switch (input_sel) {
512 case INPUT_CVBS_VI1A: 538 case INPUT_CVBS_VI1A:
@@ -544,42 +570,39 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
544 return -EINVAL; 570 return -EINVAL;
545 } 571 }
546 /* check whether signal is locked */ 572 /* check whether signal is locked */
547 sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1); 573 sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
548 if (lock_mask != (sync_lock_status & lock_mask)) 574 if (lock_mask != (sync_lock_status & lock_mask))
549 return -EINVAL; /* No input detected */ 575 return -EINVAL; /* No input detected */
550 576
551 decoder->current_std = current_std; 577 decoder->current_std = current_std;
552 *std_id = decoder->std_list[current_std].standard.id; 578 *std_id = decoder->std_list[current_std].standard.id;
553 579
554 v4l_dbg(1, debug, decoder->client, "Current STD: %s", 580 v4l2_dbg(1, debug, sd, "Current STD: %s",
555 decoder->std_list[current_std].standard.name); 581 decoder->std_list[current_std].standard.name);
556 return 0; 582 return 0;
557} 583}
558 584
559/** 585/**
560 * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl 586 * tvp514x_s_std() - V4L2 decoder interface handler for s_std
561 * @s: pointer to standard V4L2 device structure 587 * @sd: pointer to standard V4L2 sub-device structure
562 * @std_id: standard V4L2 v4l2_std_id ioctl enum 588 * @std_id: standard V4L2 v4l2_std_id ioctl enum
563 * 589 *
564 * If std_id is supported, sets the requested standard. Otherwise, returns 590 * If std_id is supported, sets the requested standard. Otherwise, returns
565 * -EINVAL 591 * -EINVAL
566 */ 592 */
567static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) 593static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
568{ 594{
569 struct tvp514x_decoder *decoder = s->priv; 595 struct tvp514x_decoder *decoder = to_decoder(sd);
570 int err, i; 596 int err, i;
571 597
572 if (std_id == NULL)
573 return -EINVAL;
574
575 for (i = 0; i < decoder->num_stds; i++) 598 for (i = 0; i < decoder->num_stds; i++)
576 if (*std_id & decoder->std_list[i].standard.id) 599 if (std_id & decoder->std_list[i].standard.id)
577 break; 600 break;
578 601
579 if ((i == decoder->num_stds) || (i == STD_INVALID)) 602 if ((i == decoder->num_stds) || (i == STD_INVALID))
580 return -EINVAL; 603 return -EINVAL;
581 604
582 err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD, 605 err = tvp514x_write_reg(sd, REG_VIDEO_STD,
583 decoder->std_list[i].video_std); 606 decoder->std_list[i].video_std);
584 if (err) 607 if (err)
585 return err; 608 return err;
@@ -588,24 +611,26 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
588 decoder->tvp514x_regs[REG_VIDEO_STD].val = 611 decoder->tvp514x_regs[REG_VIDEO_STD].val =
589 decoder->std_list[i].video_std; 612 decoder->std_list[i].video_std;
590 613
591 v4l_dbg(1, debug, decoder->client, "Standard set to: %s", 614 v4l2_dbg(1, debug, sd, "Standard set to: %s",
592 decoder->std_list[i].standard.name); 615 decoder->std_list[i].standard.name);
593 return 0; 616 return 0;
594} 617}
595 618
596/** 619/**
597 * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl 620 * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing
598 * @s: pointer to standard V4L2 device structure 621 * @sd: pointer to standard V4L2 sub-device structure
599 * @index: number of the input 622 * @input: input selector for routing the signal
623 * @output: output selector for routing the signal
624 * @config: config value. Not used
600 * 625 *
601 * If index is valid, selects the requested input. Otherwise, returns -EINVAL if 626 * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
602 * the input is not supported or there is no active signal present in the 627 * the input is not supported or there is no active signal present in the
603 * selected input. 628 * selected input.
604 */ 629 */
605static int ioctl_s_routing(struct v4l2_int_device *s, 630static int tvp514x_s_routing(struct v4l2_subdev *sd,
606 struct v4l2_routing *route) 631 u32 input, u32 output, u32 config)
607{ 632{
608 struct tvp514x_decoder *decoder = s->priv; 633 struct tvp514x_decoder *decoder = to_decoder(sd);
609 int err; 634 int err;
610 enum tvp514x_input input_sel; 635 enum tvp514x_input input_sel;
611 enum tvp514x_output output_sel; 636 enum tvp514x_output output_sel;
@@ -613,20 +638,21 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
613 u8 sync_lock_status, lock_mask; 638 u8 sync_lock_status, lock_mask;
614 int try_count = LOCK_RETRY_COUNT; 639 int try_count = LOCK_RETRY_COUNT;
615 640
616 if ((!route) || (route->input >= INPUT_INVALID) || 641 if ((input >= INPUT_INVALID) ||
617 (route->output >= OUTPUT_INVALID)) 642 (output >= OUTPUT_INVALID))
618 return -EINVAL; /* Index out of bound */ 643 /* Index out of bound */
644 return -EINVAL;
619 645
620 input_sel = route->input; 646 input_sel = input;
621 output_sel = route->output; 647 output_sel = output;
622 648
623 err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel); 649 err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel);
624 if (err) 650 if (err)
625 return err; 651 return err;
626 652
627 output_sel |= tvp514x_read_reg(decoder->client, 653 output_sel |= tvp514x_read_reg(sd,
628 REG_OUTPUT_FORMATTER1) & 0x7; 654 REG_OUTPUT_FORMATTER1) & 0x7;
629 err = tvp514x_write_reg(decoder->client, REG_OUTPUT_FORMATTER1, 655 err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1,
630 output_sel); 656 output_sel);
631 if (err) 657 if (err)
632 return err; 658 return err;
@@ -637,7 +663,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
637 /* Clear status */ 663 /* Clear status */
638 msleep(LOCK_RETRY_DELAY); 664 msleep(LOCK_RETRY_DELAY);
639 err = 665 err =
640 tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01); 666 tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01);
641 if (err) 667 if (err)
642 return err; 668 return err;
643 669
@@ -672,7 +698,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
672 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT | 698 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
673 STATUS_VIRT_SYNC_LOCK_BIT; 699 STATUS_VIRT_SYNC_LOCK_BIT;
674 break; 700 break;
675 /*Need to add other interfaces*/ 701 /* Need to add other interfaces*/
676 default: 702 default:
677 return -EINVAL; 703 return -EINVAL;
678 } 704 }
@@ -682,42 +708,41 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
682 msleep(LOCK_RETRY_DELAY); 708 msleep(LOCK_RETRY_DELAY);
683 709
684 /* get the current standard for future reference */ 710 /* get the current standard for future reference */
685 current_std = tvp514x_get_current_std(decoder); 711 current_std = tvp514x_get_current_std(sd);
686 if (current_std == STD_INVALID) 712 if (current_std == STD_INVALID)
687 continue; 713 continue;
688 714
689 sync_lock_status = tvp514x_read_reg(decoder->client, 715 sync_lock_status = tvp514x_read_reg(sd,
690 REG_STATUS1); 716 REG_STATUS1);
691 if (lock_mask == (sync_lock_status & lock_mask)) 717 if (lock_mask == (sync_lock_status & lock_mask))
692 break; /* Input detected */ 718 /* Input detected */
719 break;
693 } 720 }
694 721
695 if ((current_std == STD_INVALID) || (try_count < 0)) 722 if ((current_std == STD_INVALID) || (try_count < 0))
696 return -EINVAL; 723 return -EINVAL;
697 724
698 decoder->current_std = current_std; 725 decoder->current_std = current_std;
699 decoder->route.input = route->input; 726 decoder->input = input;
700 decoder->route.output = route->output; 727 decoder->output = output;
701 728
702 v4l_dbg(1, debug, decoder->client, 729 v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d",
703 "Input set to: %d, std : %d",
704 input_sel, current_std); 730 input_sel, current_std);
705 731
706 return 0; 732 return 0;
707} 733}
708 734
709/** 735/**
710 * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl 736 * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
711 * @s: pointer to standard V4L2 device structure 737 * @sd: pointer to standard V4L2 sub-device structure
712 * @qctrl: standard V4L2 v4l2_queryctrl structure 738 * @qctrl: standard V4L2 v4l2_queryctrl structure
713 * 739 *
714 * If the requested control is supported, returns the control information. 740 * If the requested control is supported, returns the control information.
715 * Otherwise, returns -EINVAL if the control is not supported. 741 * Otherwise, returns -EINVAL if the control is not supported.
716 */ 742 */
717static int 743static int
718ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) 744tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
719{ 745{
720 struct tvp514x_decoder *decoder = s->priv;
721 int err = -EINVAL; 746 int err = -EINVAL;
722 747
723 if (qctrl == NULL) 748 if (qctrl == NULL)
@@ -725,13 +750,13 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
725 750
726 switch (qctrl->id) { 751 switch (qctrl->id) {
727 case V4L2_CID_BRIGHTNESS: 752 case V4L2_CID_BRIGHTNESS:
728 /* Brightness supported is (0-255), 753 /* Brightness supported is (0-255), */
729 */
730 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); 754 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
731 break; 755 break;
732 case V4L2_CID_CONTRAST: 756 case V4L2_CID_CONTRAST:
733 case V4L2_CID_SATURATION: 757 case V4L2_CID_SATURATION:
734 /* Saturation and Contrast supported is - 758 /**
759 * Saturation and Contrast supported is -
735 * Contrast: 0 - 255 (Default - 128) 760 * Contrast: 0 - 255 (Default - 128)
736 * Saturation: 0 - 255 (Default - 128) 761 * Saturation: 0 - 255 (Default - 128)
737 */ 762 */
@@ -744,30 +769,27 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
744 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0); 769 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
745 break; 770 break;
746 case V4L2_CID_AUTOGAIN: 771 case V4L2_CID_AUTOGAIN:
747 /* Autogain is either 0 or 1*/ 772 /**
748 memcpy(qctrl, &tvp514x_autogain_ctrl, 773 * Auto Gain supported is -
749 sizeof(struct v4l2_queryctrl)); 774 * 0 - 1 (Default - 1)
750 err = 0; 775 */
776 err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
751 break; 777 break;
752 default: 778 default:
753 v4l_err(decoder->client, 779 v4l2_err(sd, "invalid control id %d\n", qctrl->id);
754 "invalid control id %d\n", qctrl->id);
755 return err; 780 return err;
756 } 781 }
757 782
758 v4l_dbg(1, debug, decoder->client, 783 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d",
759 "Query Control: %s : Min - %d, Max - %d, Def - %d", 784 qctrl->name, qctrl->minimum, qctrl->maximum,
760 qctrl->name,
761 qctrl->minimum,
762 qctrl->maximum,
763 qctrl->default_value); 785 qctrl->default_value);
764 786
765 return err; 787 return err;
766} 788}
767 789
768/** 790/**
769 * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl 791 * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
770 * @s: pointer to standard V4L2 device structure 792 * @sd: pointer to standard V4L2 sub-device structure
771 * @ctrl: pointer to v4l2_control structure 793 * @ctrl: pointer to v4l2_control structure
772 * 794 *
773 * If the requested control is supported, returns the control's current 795 * If the requested control is supported, returns the control's current
@@ -775,9 +797,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
775 * supported. 797 * supported.
776 */ 798 */
777static int 799static int
778ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) 800tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
779{ 801{
780 struct tvp514x_decoder *decoder = s->priv; 802 struct tvp514x_decoder *decoder = to_decoder(sd);
781 803
782 if (ctrl == NULL) 804 if (ctrl == NULL)
783 return -EINVAL; 805 return -EINVAL;
@@ -811,74 +833,70 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
811 833
812 break; 834 break;
813 default: 835 default:
814 v4l_err(decoder->client, 836 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
815 "invalid control id %d\n", ctrl->id);
816 return -EINVAL; 837 return -EINVAL;
817 } 838 }
818 839
819 v4l_dbg(1, debug, decoder->client, 840 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d",
820 "Get Control: ID - %d - %d",
821 ctrl->id, ctrl->value); 841 ctrl->id, ctrl->value);
822 return 0; 842 return 0;
823} 843}
824 844
825/** 845/**
826 * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl 846 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
827 * @s: pointer to standard V4L2 device structure 847 * @sd: pointer to standard V4L2 sub-device structure
828 * @ctrl: pointer to v4l2_control structure 848 * @ctrl: pointer to v4l2_control structure
829 * 849 *
830 * If the requested control is supported, sets the control's current 850 * If the requested control is supported, sets the control's current
831 * value in HW. Otherwise, returns -EINVAL if the control is not supported. 851 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
832 */ 852 */
833static int 853static int
834ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) 854tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
835{ 855{
836 struct tvp514x_decoder *decoder = s->priv; 856 struct tvp514x_decoder *decoder = to_decoder(sd);
837 int err = -EINVAL, value; 857 int err = -EINVAL, value;
838 858
839 if (ctrl == NULL) 859 if (ctrl == NULL)
840 return err; 860 return err;
841 861
842 value = (__s32) ctrl->value; 862 value = ctrl->value;
843 863
844 switch (ctrl->id) { 864 switch (ctrl->id) {
845 case V4L2_CID_BRIGHTNESS: 865 case V4L2_CID_BRIGHTNESS:
846 if (ctrl->value < 0 || ctrl->value > 255) { 866 if (ctrl->value < 0 || ctrl->value > 255) {
847 v4l_err(decoder->client, 867 v4l2_err(sd, "invalid brightness setting %d\n",
848 "invalid brightness setting %d\n",
849 ctrl->value); 868 ctrl->value);
850 return -ERANGE; 869 return -ERANGE;
851 } 870 }
852 err = tvp514x_write_reg(decoder->client, REG_BRIGHTNESS, 871 err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
853 value); 872 value);
854 if (err) 873 if (err)
855 return err; 874 return err;
875
856 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; 876 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
857 break; 877 break;
858 case V4L2_CID_CONTRAST: 878 case V4L2_CID_CONTRAST:
859 if (ctrl->value < 0 || ctrl->value > 255) { 879 if (ctrl->value < 0 || ctrl->value > 255) {
860 v4l_err(decoder->client, 880 v4l2_err(sd, "invalid contrast setting %d\n",
861 "invalid contrast setting %d\n",
862 ctrl->value); 881 ctrl->value);
863 return -ERANGE; 882 return -ERANGE;
864 } 883 }
865 err = tvp514x_write_reg(decoder->client, REG_CONTRAST, 884 err = tvp514x_write_reg(sd, REG_CONTRAST, value);
866 value);
867 if (err) 885 if (err)
868 return err; 886 return err;
887
869 decoder->tvp514x_regs[REG_CONTRAST].val = value; 888 decoder->tvp514x_regs[REG_CONTRAST].val = value;
870 break; 889 break;
871 case V4L2_CID_SATURATION: 890 case V4L2_CID_SATURATION:
872 if (ctrl->value < 0 || ctrl->value > 255) { 891 if (ctrl->value < 0 || ctrl->value > 255) {
873 v4l_err(decoder->client, 892 v4l2_err(sd, "invalid saturation setting %d\n",
874 "invalid saturation setting %d\n",
875 ctrl->value); 893 ctrl->value);
876 return -ERANGE; 894 return -ERANGE;
877 } 895 }
878 err = tvp514x_write_reg(decoder->client, REG_SATURATION, 896 err = tvp514x_write_reg(sd, REG_SATURATION, value);
879 value);
880 if (err) 897 if (err)
881 return err; 898 return err;
899
882 decoder->tvp514x_regs[REG_SATURATION].val = value; 900 decoder->tvp514x_regs[REG_SATURATION].val = value;
883 break; 901 break;
884 case V4L2_CID_HUE: 902 case V4L2_CID_HUE:
@@ -889,15 +907,13 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
889 else if (value == 0) 907 else if (value == 0)
890 value = 0; 908 value = 0;
891 else { 909 else {
892 v4l_err(decoder->client, 910 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
893 "invalid hue setting %d\n",
894 ctrl->value);
895 return -ERANGE; 911 return -ERANGE;
896 } 912 }
897 err = tvp514x_write_reg(decoder->client, REG_HUE, 913 err = tvp514x_write_reg(sd, REG_HUE, value);
898 value);
899 if (err) 914 if (err)
900 return err; 915 return err;
916
901 decoder->tvp514x_regs[REG_HUE].val = value; 917 decoder->tvp514x_regs[REG_HUE].val = value;
902 break; 918 break;
903 case V4L2_CID_AUTOGAIN: 919 case V4L2_CID_AUTOGAIN:
@@ -906,41 +922,38 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
906 else if (value == 0) 922 else if (value == 0)
907 value = 0x0C; 923 value = 0x0C;
908 else { 924 else {
909 v4l_err(decoder->client, 925 v4l2_err(sd, "invalid auto gain setting %d\n",
910 "invalid auto gain setting %d\n",
911 ctrl->value); 926 ctrl->value);
912 return -ERANGE; 927 return -ERANGE;
913 } 928 }
914 err = tvp514x_write_reg(decoder->client, REG_AFE_GAIN_CTRL, 929 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
915 value);
916 if (err) 930 if (err)
917 return err; 931 return err;
932
918 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; 933 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
919 break; 934 break;
920 default: 935 default:
921 v4l_err(decoder->client, 936 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
922 "invalid control id %d\n", ctrl->id);
923 return err; 937 return err;
924 } 938 }
925 939
926 v4l_dbg(1, debug, decoder->client, 940 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d",
927 "Set Control: ID - %d - %d",
928 ctrl->id, ctrl->value); 941 ctrl->id, ctrl->value);
929 942
930 return err; 943 return err;
931} 944}
932 945
933/** 946/**
934 * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl 947 * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt
935 * @s: pointer to standard V4L2 device structure 948 * @sd: pointer to standard V4L2 sub-device structure
936 * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure 949 * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
937 * 950 *
938 * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats 951 * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
939 */ 952 */
940static int 953static int
941ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) 954tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
942{ 955{
943 struct tvp514x_decoder *decoder = s->priv; 956 struct tvp514x_decoder *decoder = to_decoder(sd);
944 int index; 957 int index;
945 958
946 if (fmt == NULL) 959 if (fmt == NULL)
@@ -948,24 +961,25 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
948 961
949 index = fmt->index; 962 index = fmt->index;
950 if ((index >= decoder->num_fmts) || (index < 0)) 963 if ((index >= decoder->num_fmts) || (index < 0))
951 return -EINVAL; /* Index out of bound */ 964 /* Index out of bound */
965 return -EINVAL;
952 966
953 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 967 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
954 return -EINVAL; /* only capture is supported */ 968 /* only capture is supported */
969 return -EINVAL;
955 970
956 memcpy(fmt, &decoder->fmt_list[index], 971 memcpy(fmt, &decoder->fmt_list[index],
957 sizeof(struct v4l2_fmtdesc)); 972 sizeof(struct v4l2_fmtdesc));
958 973
959 v4l_dbg(1, debug, decoder->client, 974 v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)",
960 "Current FMT: index - %d (%s)",
961 decoder->fmt_list[index].index, 975 decoder->fmt_list[index].index,
962 decoder->fmt_list[index].description); 976 decoder->fmt_list[index].description);
963 return 0; 977 return 0;
964} 978}
965 979
966/** 980/**
967 * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl 981 * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
968 * @s: pointer to standard V4L2 device structure 982 * @sd: pointer to standard V4L2 sub-device structure
969 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure 983 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
970 * 984 *
971 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This 985 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
@@ -973,9 +987,9 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
973 * without actually making it take effect. 987 * without actually making it take effect.
974 */ 988 */
975static int 989static int
976ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 990tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
977{ 991{
978 struct tvp514x_decoder *decoder = s->priv; 992 struct tvp514x_decoder *decoder = to_decoder(sd);
979 int ifmt; 993 int ifmt;
980 struct v4l2_pix_format *pix; 994 struct v4l2_pix_format *pix;
981 enum tvp514x_std current_std; 995 enum tvp514x_std current_std;
@@ -984,12 +998,13 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
984 return -EINVAL; 998 return -EINVAL;
985 999
986 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1000 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1001 /* only capture is supported */
987 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1002 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
988 1003
989 pix = &f->fmt.pix; 1004 pix = &f->fmt.pix;
990 1005
991 /* Calculate height and width based on current standard */ 1006 /* Calculate height and width based on current standard */
992 current_std = tvp514x_get_current_std(decoder); 1007 current_std = tvp514x_get_current_std(sd);
993 if (current_std == STD_INVALID) 1008 if (current_std == STD_INVALID)
994 return -EINVAL; 1009 return -EINVAL;
995 1010
@@ -1003,7 +1018,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1003 break; 1018 break;
1004 } 1019 }
1005 if (ifmt == decoder->num_fmts) 1020 if (ifmt == decoder->num_fmts)
1006 ifmt = 0; /* None of the format matched, select default */ 1021 /* None of the format matched, select default */
1022 ifmt = 0;
1007 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; 1023 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
1008 1024
1009 pix->field = V4L2_FIELD_INTERLACED; 1025 pix->field = V4L2_FIELD_INTERLACED;
@@ -1012,8 +1028,7 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1012 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 1028 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1013 pix->priv = 0; 1029 pix->priv = 0;
1014 1030
1015 v4l_dbg(1, debug, decoder->client, 1031 v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
1016 "Try FMT: pixelformat - %s, bytesperline - %d"
1017 "Width - %d, Height - %d", 1032 "Width - %d, Height - %d",
1018 decoder->fmt_list[ifmt].description, pix->bytesperline, 1033 decoder->fmt_list[ifmt].description, pix->bytesperline,
1019 pix->width, pix->height); 1034 pix->width, pix->height);
@@ -1021,8 +1036,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1021} 1036}
1022 1037
1023/** 1038/**
1024 * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl 1039 * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt
1025 * @s: pointer to standard V4L2 device structure 1040 * @sd: pointer to standard V4L2 sub-device structure
1026 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure 1041 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
1027 * 1042 *
1028 * If the requested format is supported, configures the HW to use that 1043 * If the requested format is supported, configures the HW to use that
@@ -1030,9 +1045,9 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1030 * correctly configured. 1045 * correctly configured.
1031 */ 1046 */
1032static int 1047static int
1033ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 1048tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1034{ 1049{
1035 struct tvp514x_decoder *decoder = s->priv; 1050 struct tvp514x_decoder *decoder = to_decoder(sd);
1036 struct v4l2_pix_format *pix; 1051 struct v4l2_pix_format *pix;
1037 int rval; 1052 int rval;
1038 1053
@@ -1040,10 +1055,11 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1040 return -EINVAL; 1055 return -EINVAL;
1041 1056
1042 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1057 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1043 return -EINVAL; /* only capture is supported */ 1058 /* only capture is supported */
1059 return -EINVAL;
1044 1060
1045 pix = &f->fmt.pix; 1061 pix = &f->fmt.pix;
1046 rval = ioctl_try_fmt_cap(s, f); 1062 rval = tvp514x_try_fmt_cap(sd, f);
1047 if (rval) 1063 if (rval)
1048 return rval; 1064 return rval;
1049 1065
@@ -1053,28 +1069,28 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1053} 1069}
1054 1070
1055/** 1071/**
1056 * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap 1072 * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap
1057 * @s: pointer to standard V4L2 device structure 1073 * @sd: pointer to standard V4L2 sub-device structure
1058 * @f: pointer to standard V4L2 v4l2_format structure 1074 * @f: pointer to standard V4L2 v4l2_format structure
1059 * 1075 *
1060 * Returns the decoder's current pixel format in the v4l2_format 1076 * Returns the decoder's current pixel format in the v4l2_format
1061 * parameter. 1077 * parameter.
1062 */ 1078 */
1063static int 1079static int
1064ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 1080tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1065{ 1081{
1066 struct tvp514x_decoder *decoder = s->priv; 1082 struct tvp514x_decoder *decoder = to_decoder(sd);
1067 1083
1068 if (f == NULL) 1084 if (f == NULL)
1069 return -EINVAL; 1085 return -EINVAL;
1070 1086
1071 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1087 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1072 return -EINVAL; /* only capture is supported */ 1088 /* only capture is supported */
1089 return -EINVAL;
1073 1090
1074 f->fmt.pix = decoder->pix; 1091 f->fmt.pix = decoder->pix;
1075 1092
1076 v4l_dbg(1, debug, decoder->client, 1093 v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
1077 "Current FMT: bytesperline - %d"
1078 "Width - %d, Height - %d", 1094 "Width - %d, Height - %d",
1079 decoder->pix.bytesperline, 1095 decoder->pix.bytesperline,
1080 decoder->pix.width, decoder->pix.height); 1096 decoder->pix.width, decoder->pix.height);
@@ -1082,16 +1098,16 @@ ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1082} 1098}
1083 1099
1084/** 1100/**
1085 * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl 1101 * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm
1086 * @s: pointer to standard V4L2 device structure 1102 * @sd: pointer to standard V4L2 sub-device structure
1087 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure 1103 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1088 * 1104 *
1089 * Returns the decoder's video CAPTURE parameters. 1105 * Returns the decoder's video CAPTURE parameters.
1090 */ 1106 */
1091static int 1107static int
1092ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) 1108tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1093{ 1109{
1094 struct tvp514x_decoder *decoder = s->priv; 1110 struct tvp514x_decoder *decoder = to_decoder(sd);
1095 struct v4l2_captureparm *cparm; 1111 struct v4l2_captureparm *cparm;
1096 enum tvp514x_std current_std; 1112 enum tvp514x_std current_std;
1097 1113
@@ -1099,13 +1115,14 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1099 return -EINVAL; 1115 return -EINVAL;
1100 1116
1101 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1117 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1102 return -EINVAL; /* only capture is supported */ 1118 /* only capture is supported */
1119 return -EINVAL;
1103 1120
1104 memset(a, 0, sizeof(*a)); 1121 memset(a, 0, sizeof(*a));
1105 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1122 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1106 1123
1107 /* get the current standard */ 1124 /* get the current standard */
1108 current_std = tvp514x_get_current_std(decoder); 1125 current_std = tvp514x_get_current_std(sd);
1109 if (current_std == STD_INVALID) 1126 if (current_std == STD_INVALID)
1110 return -EINVAL; 1127 return -EINVAL;
1111 1128
@@ -1120,17 +1137,17 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1120} 1137}
1121 1138
1122/** 1139/**
1123 * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl 1140 * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm
1124 * @s: pointer to standard V4L2 device structure 1141 * @sd: pointer to standard V4L2 sub-device structure
1125 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure 1142 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1126 * 1143 *
1127 * Configures the decoder to use the input parameters, if possible. If 1144 * Configures the decoder to use the input parameters, if possible. If
1128 * not possible, returns the appropriate error code. 1145 * not possible, returns the appropriate error code.
1129 */ 1146 */
1130static int 1147static int
1131ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) 1148tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1132{ 1149{
1133 struct tvp514x_decoder *decoder = s->priv; 1150 struct tvp514x_decoder *decoder = to_decoder(sd);
1134 struct v4l2_fract *timeperframe; 1151 struct v4l2_fract *timeperframe;
1135 enum tvp514x_std current_std; 1152 enum tvp514x_std current_std;
1136 1153
@@ -1138,12 +1155,13 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1138 return -EINVAL; 1155 return -EINVAL;
1139 1156
1140 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1157 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1141 return -EINVAL; /* only capture is supported */ 1158 /* only capture is supported */
1159 return -EINVAL;
1142 1160
1143 timeperframe = &a->parm.capture.timeperframe; 1161 timeperframe = &a->parm.capture.timeperframe;
1144 1162
1145 /* get the current standard */ 1163 /* get the current standard */
1146 current_std = tvp514x_get_current_std(decoder); 1164 current_std = tvp514x_get_current_std(sd);
1147 if (current_std == STD_INVALID) 1165 if (current_std == STD_INVALID)
1148 return -EINVAL; 1166 return -EINVAL;
1149 1167
@@ -1156,111 +1174,58 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1156} 1174}
1157 1175
1158/** 1176/**
1159 * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num 1177 * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream
1160 * @s: pointer to standard V4L2 device structure 1178 * @sd: pointer to standard V4L2 sub-device structure
1161 * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure 1179 * @enable: streaming enable or disable
1162 *
1163 * Gets slave interface parameters.
1164 * Calculates the required xclk value to support the requested
1165 * clock parameters in p. This value is returned in the p
1166 * parameter.
1167 */
1168static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
1169{
1170 struct tvp514x_decoder *decoder = s->priv;
1171 int rval;
1172
1173 if (p == NULL)
1174 return -EINVAL;
1175
1176 if (NULL == decoder->pdata->ifparm)
1177 return -EINVAL;
1178
1179 rval = decoder->pdata->ifparm(p);
1180 if (rval) {
1181 v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval);
1182 return rval;
1183 }
1184
1185 p->u.bt656.clock_curr = TVP514X_XCLK_BT656;
1186
1187 return 0;
1188}
1189
1190/**
1191 * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num
1192 * @s: pointer to standard V4L2 device structure
1193 * @p: void pointer to hold decoder's private data address
1194 *
1195 * Returns device's (decoder's) private data area address in p parameter
1196 */
1197static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
1198{
1199 struct tvp514x_decoder *decoder = s->priv;
1200
1201 if (NULL == decoder->pdata->priv_data_set)
1202 return -EINVAL;
1203
1204 return decoder->pdata->priv_data_set(p);
1205}
1206
1207/**
1208 * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num
1209 * @s: pointer to standard V4L2 device structure
1210 * @on: power state to which device is to be set
1211 * 1180 *
1212 * Sets devices power state to requrested state, if possible. 1181 * Sets streaming to enable or disable, if possible.
1213 */ 1182 */
1214static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on) 1183static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
1215{ 1184{
1216 struct tvp514x_decoder *decoder = s->priv;
1217 int err = 0; 1185 int err = 0;
1186 struct i2c_client *client = v4l2_get_subdevdata(sd);
1187 struct tvp514x_decoder *decoder = to_decoder(sd);
1218 1188
1219 switch (on) { 1189 if (decoder->streaming == enable)
1220 case V4L2_POWER_OFF: 1190 return 0;
1221 /* Power Down Sequence */
1222 err =
1223 tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
1224 0x01);
1225 /* Disable mux for TVP5146/47 decoder data path */
1226 if (decoder->pdata->power_set)
1227 err |= decoder->pdata->power_set(on);
1228 decoder->state = STATE_NOT_DETECTED;
1229 break;
1230 1191
1231 case V4L2_POWER_STANDBY: 1192 switch (enable) {
1232 if (decoder->pdata->power_set) 1193 case 0:
1233 err = decoder->pdata->power_set(on); 1194 {
1195 /* Power Down Sequence */
1196 err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01);
1197 if (err) {
1198 v4l2_err(sd, "Unable to turn off decoder\n");
1199 return err;
1200 }
1201 decoder->streaming = enable;
1234 break; 1202 break;
1203 }
1204 case 1:
1205 {
1206 struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
1207 client->driver->id_table->driver_data;
1235 1208
1236 case V4L2_POWER_ON: 1209 /* Power Up Sequence */
1237 /* Enable mux for TVP5146/47 decoder data path */ 1210 err = tvp514x_write_regs(sd, int_seq);
1238 if ((decoder->pdata->power_set) && 1211 if (err) {
1239 (decoder->state == STATE_NOT_DETECTED)) { 1212 v4l2_err(sd, "Unable to turn on decoder\n");
1240 int i; 1213 return err;
1241 struct tvp514x_init_seq *int_seq =
1242 (struct tvp514x_init_seq *)
1243 decoder->id->driver_data;
1244
1245 err = decoder->pdata->power_set(on);
1246
1247 /* Power Up Sequence */
1248 for (i = 0; i < int_seq->no_regs; i++) {
1249 err |= tvp514x_write_reg(decoder->client,
1250 int_seq->init_reg_seq[i].reg,
1251 int_seq->init_reg_seq[i].val);
1252 }
1253 /* Detect the sensor is not already detected */
1254 err |= tvp514x_detect(decoder);
1255 if (err) {
1256 v4l_err(decoder->client,
1257 "Unable to detect decoder\n");
1258 return err;
1259 }
1260 } 1214 }
1261 err |= tvp514x_configure(decoder); 1215 /* Detect if not already detected */
1216 err = tvp514x_detect(sd, decoder);
1217 if (err) {
1218 v4l2_err(sd, "Unable to detect decoder\n");
1219 return err;
1220 }
1221 err = tvp514x_configure(sd, decoder);
1222 if (err) {
1223 v4l2_err(sd, "Unable to configure decoder\n");
1224 return err;
1225 }
1226 decoder->streaming = enable;
1262 break; 1227 break;
1263 1228 }
1264 default: 1229 default:
1265 err = -ENODEV; 1230 err = -ENODEV;
1266 break; 1231 break;
@@ -1269,93 +1234,38 @@ static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
1269 return err; 1234 return err;
1270} 1235}
1271 1236
1272/** 1237static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
1273 * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT 1238 .queryctrl = tvp514x_queryctrl,
1274 * @s: pointer to standard V4L2 device structure 1239 .g_ctrl = tvp514x_g_ctrl,
1275 * 1240 .s_ctrl = tvp514x_s_ctrl,
1276 * Initialize the decoder device (calls tvp514x_configure()) 1241 .s_std = tvp514x_s_std,
1277 */ 1242};
1278static int ioctl_init(struct v4l2_int_device *s)
1279{
1280 struct tvp514x_decoder *decoder = s->priv;
1281
1282 /* Set default standard to auto */
1283 decoder->tvp514x_regs[REG_VIDEO_STD].val =
1284 VIDEO_STD_AUTO_SWITCH_BIT;
1285
1286 return tvp514x_configure(decoder);
1287}
1288
1289/**
1290 * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num
1291 * @s: pointer to standard V4L2 device structure
1292 *
1293 * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
1294 */
1295static int ioctl_dev_exit(struct v4l2_int_device *s)
1296{
1297 return 0;
1298}
1299
1300/**
1301 * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num
1302 * @s: pointer to standard V4L2 device structure
1303 *
1304 * Initialise the device when slave attaches to the master. Returns 0 if
1305 * TVP5146/47 device could be found, otherwise returns appropriate error.
1306 */
1307static int ioctl_dev_init(struct v4l2_int_device *s)
1308{
1309 struct tvp514x_decoder *decoder = s->priv;
1310 int err;
1311
1312 err = tvp514x_detect(decoder);
1313 if (err < 0) {
1314 v4l_err(decoder->client,
1315 "Unable to detect decoder\n");
1316 return err;
1317 }
1318
1319 v4l_info(decoder->client,
1320 "chip version 0x%.2x detected\n", decoder->ver);
1321 1243
1322 return 0; 1244static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
1323} 1245 .s_routing = tvp514x_s_routing,
1246 .querystd = tvp514x_querystd,
1247 .enum_fmt = tvp514x_enum_fmt_cap,
1248 .g_fmt = tvp514x_g_fmt_cap,
1249 .try_fmt = tvp514x_try_fmt_cap,
1250 .s_fmt = tvp514x_s_fmt_cap,
1251 .g_parm = tvp514x_g_parm,
1252 .s_parm = tvp514x_s_parm,
1253 .s_stream = tvp514x_s_stream,
1254};
1324 1255
1325static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { 1256static const struct v4l2_subdev_ops tvp514x_ops = {
1326 {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init}, 1257 .core = &tvp514x_core_ops,
1327 {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit}, 1258 .video = &tvp514x_video_ops,
1328 {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
1329 {vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv},
1330 {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
1331 {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
1332 {vidioc_int_enum_fmt_cap_num,
1333 (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
1334 {vidioc_int_try_fmt_cap_num,
1335 (v4l2_int_ioctl_func *) ioctl_try_fmt_cap},
1336 {vidioc_int_g_fmt_cap_num,
1337 (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
1338 {vidioc_int_s_fmt_cap_num,
1339 (v4l2_int_ioctl_func *) ioctl_s_fmt_cap},
1340 {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
1341 {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
1342 {vidioc_int_queryctrl_num,
1343 (v4l2_int_ioctl_func *) ioctl_queryctrl},
1344 {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
1345 {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
1346 {vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd},
1347 {vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std},
1348 {vidioc_int_s_video_routing_num,
1349 (v4l2_int_ioctl_func *) ioctl_s_routing},
1350}; 1259};
1351 1260
1352static struct tvp514x_decoder tvp514x_dev = { 1261static struct tvp514x_decoder tvp514x_dev = {
1353 .state = STATE_NOT_DETECTED, 1262 .streaming = 0,
1354 1263
1355 .fmt_list = tvp514x_fmt_list, 1264 .fmt_list = tvp514x_fmt_list,
1356 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), 1265 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
1357 1266
1358 .pix = { /* Default to NTSC 8-bit YUV 422 */ 1267 .pix = {
1268 /* Default to NTSC 8-bit YUV 422 */
1359 .width = NTSC_NUM_ACTIVE_PIXELS, 1269 .width = NTSC_NUM_ACTIVE_PIXELS,
1360 .height = NTSC_NUM_ACTIVE_LINES, 1270 .height = NTSC_NUM_ACTIVE_LINES,
1361 .pixelformat = V4L2_PIX_FMT_UYVY, 1271 .pixelformat = V4L2_PIX_FMT_UYVY,
@@ -1369,20 +1279,13 @@ static struct tvp514x_decoder tvp514x_dev = {
1369 .current_std = STD_NTSC_MJ, 1279 .current_std = STD_NTSC_MJ,
1370 .std_list = tvp514x_std_list, 1280 .std_list = tvp514x_std_list,
1371 .num_stds = ARRAY_SIZE(tvp514x_std_list), 1281 .num_stds = ARRAY_SIZE(tvp514x_std_list),
1372 .v4l2_int_device = { 1282
1373 .module = THIS_MODULE,
1374 .name = TVP514X_MODULE_NAME,
1375 .type = v4l2_int_type_slave,
1376 },
1377 .tvp514x_slave = {
1378 .ioctls = tvp514x_ioctl_desc,
1379 .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
1380 },
1381}; 1283};
1382 1284
1383/** 1285/**
1384 * tvp514x_probe - decoder driver i2c probe handler 1286 * tvp514x_probe() - decoder driver i2c probe handler
1385 * @client: i2c driver client device structure 1287 * @client: i2c driver client device structure
1288 * @id: i2c driver id table
1386 * 1289 *
1387 * Register decoder as an i2c client device and V4L2 1290 * Register decoder as an i2c client device and V4L2
1388 * device. 1291 * device.
@@ -1391,88 +1294,71 @@ static int
1391tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) 1294tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1392{ 1295{
1393 struct tvp514x_decoder *decoder; 1296 struct tvp514x_decoder *decoder;
1394 int err; 1297 struct v4l2_subdev *sd;
1395 1298
1396 /* Check if the adapter supports the needed features */ 1299 /* Check if the adapter supports the needed features */
1397 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1300 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1398 return -EIO; 1301 return -EIO;
1399 1302
1303 if (!client->dev.platform_data) {
1304 v4l2_err(client, "No platform data!!\n");
1305 return -ENODEV;
1306 }
1307
1400 decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); 1308 decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
1401 if (!decoder) 1309 if (!decoder)
1402 return -ENOMEM; 1310 return -ENOMEM;
1403 1311
1404 if (!client->dev.platform_data) { 1312 /* Initialize the tvp514x_decoder with default configuration */
1405 v4l_err(client, "No platform data!!\n");
1406 err = -ENODEV;
1407 goto out_free;
1408 }
1409
1410 *decoder = tvp514x_dev; 1313 *decoder = tvp514x_dev;
1411 decoder->v4l2_int_device.priv = decoder; 1314 /* Copy default register configuration */
1412 decoder->pdata = client->dev.platform_data;
1413 decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
1414 memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, 1315 memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
1415 sizeof(tvp514x_reg_list_default)); 1316 sizeof(tvp514x_reg_list_default));
1416 /* 1317
1318 /* Copy board specific information here */
1319 decoder->pdata = client->dev.platform_data;
1320
1321 /**
1417 * Fetch platform specific data, and configure the 1322 * Fetch platform specific data, and configure the
1418 * tvp514x_reg_list[] accordingly. Since this is one 1323 * tvp514x_reg_list[] accordingly. Since this is one
1419 * time configuration, no need to preserve. 1324 * time configuration, no need to preserve.
1420 */ 1325 */
1421 decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= 1326 decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
1422 (decoder->pdata->clk_polarity << 1); 1327 (decoder->pdata->clk_polarity << 1);
1423 decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= 1328 decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
1424 ((decoder->pdata->hs_polarity << 2) | 1329 ((decoder->pdata->hs_polarity << 2) |
1425 (decoder->pdata->vs_polarity << 3)); 1330 (decoder->pdata->vs_polarity << 3));
1426 /* 1331 /* Set default standard to auto */
1427 * Save the id data, required for power up sequence 1332 decoder->tvp514x_regs[REG_VIDEO_STD].val =
1428 */ 1333 VIDEO_STD_AUTO_SWITCH_BIT;
1429 decoder->id = (struct i2c_device_id *)id;
1430 /* Attach to Master */
1431 strcpy(decoder->v4l2_int_device.u.slave->attach_to,
1432 decoder->pdata->master);
1433 decoder->client = client;
1434 i2c_set_clientdata(client, decoder);
1435 1334
1436 /* Register with V4L2 layer as slave device */ 1335 /* Register with V4L2 layer as slave device */
1437 err = v4l2_int_device_register(&decoder->v4l2_int_device); 1336 sd = &decoder->sd;
1438 if (err) { 1337 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
1439 i2c_set_clientdata(client, NULL); 1338
1440 v4l_err(client, 1339 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
1441 "Unable to register to v4l2. Err[%d]\n", err); 1340
1442 goto out_free;
1443
1444 } else
1445 v4l_info(client, "Registered to v4l2 master %s!!\n",
1446 decoder->pdata->master);
1447 return 0; 1341 return 0;
1448 1342
1449out_free:
1450 kfree(decoder);
1451 return err;
1452} 1343}
1453 1344
1454/** 1345/**
1455 * tvp514x_remove - decoder driver i2c remove handler 1346 * tvp514x_remove() - decoder driver i2c remove handler
1456 * @client: i2c driver client device structure 1347 * @client: i2c driver client device structure
1457 * 1348 *
1458 * Unregister decoder as an i2c client device and V4L2 1349 * Unregister decoder as an i2c client device and V4L2
1459 * device. Complement of tvp514x_probe(). 1350 * device. Complement of tvp514x_probe().
1460 */ 1351 */
1461static int __exit tvp514x_remove(struct i2c_client *client) 1352static int tvp514x_remove(struct i2c_client *client)
1462{ 1353{
1463 struct tvp514x_decoder *decoder = i2c_get_clientdata(client); 1354 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1464 1355 struct tvp514x_decoder *decoder = to_decoder(sd);
1465 if (!client->adapter)
1466 return -ENODEV; /* our client isn't attached */
1467 1356
1468 v4l2_int_device_unregister(&decoder->v4l2_int_device); 1357 v4l2_device_unregister_subdev(sd);
1469 i2c_set_clientdata(client, NULL);
1470 kfree(decoder); 1358 kfree(decoder);
1471 return 0; 1359 return 0;
1472} 1360}
1473/* 1361/* TVP5146 Init/Power on Sequence */
1474 * TVP5146 Init/Power on Sequence
1475 */
1476static const struct tvp514x_reg tvp5146_init_reg_seq[] = { 1362static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
1477 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, 1363 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1478 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, 1364 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1485,14 +1371,10 @@ static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
1485 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, 1371 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1486 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1372 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1487 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1373 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1374 {TOK_TERM, 0, 0},
1488}; 1375};
1489static const struct tvp514x_init_seq tvp5146_init = { 1376
1490 .no_regs = ARRAY_SIZE(tvp5146_init_reg_seq), 1377/* TVP5147 Init/Power on Sequence */
1491 .init_reg_seq = tvp5146_init_reg_seq,
1492};
1493/*
1494 * TVP5147 Init/Power on Sequence
1495 */
1496static const struct tvp514x_reg tvp5147_init_reg_seq[] = { 1378static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
1497 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, 1379 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1498 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, 1380 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1512,71 +1394,51 @@ static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
1512 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, 1394 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1513 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1395 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1514 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1396 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1397 {TOK_TERM, 0, 0},
1515}; 1398};
1516static const struct tvp514x_init_seq tvp5147_init = { 1399
1517 .no_regs = ARRAY_SIZE(tvp5147_init_reg_seq), 1400/* TVP5146M2/TVP5147M1 Init/Power on Sequence */
1518 .init_reg_seq = tvp5147_init_reg_seq,
1519};
1520/*
1521 * TVP5146M2/TVP5147M1 Init/Power on Sequence
1522 */
1523static const struct tvp514x_reg tvp514xm_init_reg_seq[] = { 1401static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
1524 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1402 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1525 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1403 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1404 {TOK_TERM, 0, 0},
1526}; 1405};
1527static const struct tvp514x_init_seq tvp514xm_init = { 1406
1528 .no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq), 1407/**
1529 .init_reg_seq = tvp514xm_init_reg_seq,
1530};
1531/*
1532 * I2C Device Table - 1408 * I2C Device Table -
1533 * 1409 *
1534 * name - Name of the actual device/chip. 1410 * name - Name of the actual device/chip.
1535 * driver_data - Driver data 1411 * driver_data - Driver data
1536 */ 1412 */
1537static const struct i2c_device_id tvp514x_id[] = { 1413static const struct i2c_device_id tvp514x_id[] = {
1538 {"tvp5146", (unsigned long)&tvp5146_init}, 1414 {"tvp5146", (unsigned long)tvp5146_init_reg_seq},
1539 {"tvp5146m2", (unsigned long)&tvp514xm_init}, 1415 {"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq},
1540 {"tvp5147", (unsigned long)&tvp5147_init}, 1416 {"tvp5147", (unsigned long)tvp5147_init_reg_seq},
1541 {"tvp5147m1", (unsigned long)&tvp514xm_init}, 1417 {"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq},
1542 {}, 1418 {},
1543}; 1419};
1544 1420
1545MODULE_DEVICE_TABLE(i2c, tvp514x_id); 1421MODULE_DEVICE_TABLE(i2c, tvp514x_id);
1546 1422
1547static struct i2c_driver tvp514x_i2c_driver = { 1423static struct i2c_driver tvp514x_driver = {
1548 .driver = { 1424 .driver = {
1549 .name = TVP514X_MODULE_NAME, 1425 .owner = THIS_MODULE,
1550 .owner = THIS_MODULE, 1426 .name = TVP514X_MODULE_NAME,
1551 }, 1427 },
1552 .probe = tvp514x_probe, 1428 .probe = tvp514x_probe,
1553 .remove = __exit_p(tvp514x_remove), 1429 .remove = tvp514x_remove,
1554 .id_table = tvp514x_id, 1430 .id_table = tvp514x_id,
1555}; 1431};
1556 1432
1557/**
1558 * tvp514x_init
1559 *
1560 * Module init function
1561 */
1562static int __init tvp514x_init(void) 1433static int __init tvp514x_init(void)
1563{ 1434{
1564 return i2c_add_driver(&tvp514x_i2c_driver); 1435 return i2c_add_driver(&tvp514x_driver);
1565} 1436}
1566 1437
1567/** 1438static void __exit tvp514x_exit(void)
1568 * tvp514x_cleanup
1569 *
1570 * Module exit function
1571 */
1572static void __exit tvp514x_cleanup(void)
1573{ 1439{
1574 i2c_del_driver(&tvp514x_i2c_driver); 1440 i2c_del_driver(&tvp514x_driver);
1575} 1441}
1576 1442
1577module_init(tvp514x_init); 1443module_init(tvp514x_init);
1578module_exit(tvp514x_cleanup); 1444module_exit(tvp514x_exit);
1579
1580MODULE_AUTHOR("Texas Instruments");
1581MODULE_DESCRIPTION("TVP514X linux decoder driver");
1582MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
index 351620aeecc2..18f29ad0dfe2 100644
--- a/drivers/media/video/tvp514x_regs.h
+++ b/drivers/media/video/tvp514x_regs.h
@@ -284,14 +284,4 @@ struct tvp514x_reg {
284 u32 val; 284 u32 val;
285}; 285};
286 286
287/**
288 * struct tvp514x_init_seq - Structure for TVP5146/47/46M2/47M1 power up
289 * Sequence.
290 * @ no_regs - Number of registers to write for power up sequence.
291 * @ init_reg_seq - Array of registers and respective value to write.
292 */
293struct tvp514x_init_seq {
294 unsigned int no_regs;
295 const struct tvp514x_reg *init_reg_seq;
296};
297#endif /* ifndef _TVP514X_REGS_H */ 287#endif /* ifndef _TVP514X_REGS_H */
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index aa5065ea09ed..269ab044072a 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -24,7 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h> 26#include <media/v4l2-chip-ident.h>
27#include <media/v4l2-common.h> 27#include <media/v4l2-subdev.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30 30
@@ -223,9 +223,8 @@ struct tw9910_hsync_ctrl {
223}; 223};
224 224
225struct tw9910_priv { 225struct tw9910_priv {
226 struct v4l2_subdev subdev;
226 struct tw9910_video_info *info; 227 struct tw9910_video_info *info;
227 struct i2c_client *client;
228 struct soc_camera_device icd;
229 const struct tw9910_scale_ctrl *scale; 228 const struct tw9910_scale_ctrl *scale;
230}; 229};
231 230
@@ -356,6 +355,12 @@ static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
356/* 355/*
357 * general function 356 * general function
358 */ 357 */
358static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
359{
360 return container_of(i2c_get_clientdata(client), struct tw9910_priv,
361 subdev);
362}
363
359static int tw9910_set_scale(struct i2c_client *client, 364static int tw9910_set_scale(struct i2c_client *client,
360 const struct tw9910_scale_ctrl *scale) 365 const struct tw9910_scale_ctrl *scale)
361{ 366{
@@ -509,44 +514,20 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
509/* 514/*
510 * soc_camera_ops function 515 * soc_camera_ops function
511 */ 516 */
512static int tw9910_init(struct soc_camera_device *icd) 517static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
513{
514 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
515 int ret = 0;
516
517 if (priv->info->link.power) {
518 ret = priv->info->link.power(&priv->client->dev, 1);
519 if (ret < 0)
520 return ret;
521 }
522
523 if (priv->info->link.reset)
524 ret = priv->info->link.reset(&priv->client->dev);
525
526 return ret;
527}
528
529static int tw9910_release(struct soc_camera_device *icd)
530{ 518{
531 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 519 struct i2c_client *client = sd->priv;
532 int ret = 0; 520 struct tw9910_priv *priv = to_tw9910(client);
533
534 if (priv->info->link.power)
535 ret = priv->info->link.power(&priv->client->dev, 0);
536
537 return ret;
538}
539 521
540static int tw9910_start_capture(struct soc_camera_device *icd) 522 if (!enable)
541{ 523 return 0;
542 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
543 524
544 if (!priv->scale) { 525 if (!priv->scale) {
545 dev_err(&icd->dev, "norm select error\n"); 526 dev_err(&client->dev, "norm select error\n");
546 return -EPERM; 527 return -EPERM;
547 } 528 }
548 529
549 dev_dbg(&icd->dev, "%s %dx%d\n", 530 dev_dbg(&client->dev, "%s %dx%d\n",
550 priv->scale->name, 531 priv->scale->name,
551 priv->scale->width, 532 priv->scale->width,
552 priv->scale->height); 533 priv->scale->height);
@@ -554,11 +535,6 @@ static int tw9910_start_capture(struct soc_camera_device *icd)
554 return 0; 535 return 0;
555} 536}
556 537
557static int tw9910_stop_capture(struct soc_camera_device *icd)
558{
559 return 0;
560}
561
562static int tw9910_set_bus_param(struct soc_camera_device *icd, 538static int tw9910_set_bus_param(struct soc_camera_device *icd,
563 unsigned long flags) 539 unsigned long flags)
564{ 540{
@@ -567,8 +543,9 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
567 543
568static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) 544static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
569{ 545{
570 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 546 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
571 struct soc_camera_link *icl = priv->client->dev.platform_data; 547 struct tw9910_priv *priv = to_tw9910(client);
548 struct soc_camera_link *icl = to_soc_camera_link(icd);
572 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 549 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
573 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 550 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
574 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 551 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -576,21 +553,11 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
576 return soc_camera_apply_sensor_flags(icl, flags); 553 return soc_camera_apply_sensor_flags(icl, flags);
577} 554}
578 555
579static int tw9910_get_chip_id(struct soc_camera_device *icd, 556static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
580 struct v4l2_dbg_chip_ident *id)
581{
582 id->ident = V4L2_IDENT_TW9910;
583 id->revision = 0;
584
585 return 0;
586}
587
588static int tw9910_set_std(struct soc_camera_device *icd,
589 v4l2_std_id *a)
590{ 557{
591 int ret = -EINVAL; 558 int ret = -EINVAL;
592 559
593 if (*a & (V4L2_STD_NTSC | V4L2_STD_PAL)) 560 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
594 ret = 0; 561 ret = 0;
595 562
596 return ret; 563 return ret;
@@ -606,17 +573,26 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
606 return 0; 573 return 0;
607} 574}
608 575
576static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
577 struct v4l2_dbg_chip_ident *id)
578{
579 id->ident = V4L2_IDENT_TW9910;
580 id->revision = 0;
581
582 return 0;
583}
584
609#ifdef CONFIG_VIDEO_ADV_DEBUG 585#ifdef CONFIG_VIDEO_ADV_DEBUG
610static int tw9910_get_register(struct soc_camera_device *icd, 586static int tw9910_g_register(struct v4l2_subdev *sd,
611 struct v4l2_dbg_register *reg) 587 struct v4l2_dbg_register *reg)
612{ 588{
613 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 589 struct i2c_client *client = sd->priv;
614 int ret; 590 int ret;
615 591
616 if (reg->reg > 0xff) 592 if (reg->reg > 0xff)
617 return -EINVAL; 593 return -EINVAL;
618 594
619 ret = i2c_smbus_read_byte_data(priv->client, reg->reg); 595 ret = i2c_smbus_read_byte_data(client, reg->reg);
620 if (ret < 0) 596 if (ret < 0)
621 return ret; 597 return ret;
622 598
@@ -628,23 +604,25 @@ static int tw9910_get_register(struct soc_camera_device *icd,
628 return 0; 604 return 0;
629} 605}
630 606
631static int tw9910_set_register(struct soc_camera_device *icd, 607static int tw9910_s_register(struct v4l2_subdev *sd,
632 struct v4l2_dbg_register *reg) 608 struct v4l2_dbg_register *reg)
633{ 609{
634 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 610 struct i2c_client *client = sd->priv;
635 611
636 if (reg->reg > 0xff || 612 if (reg->reg > 0xff ||
637 reg->val > 0xff) 613 reg->val > 0xff)
638 return -EINVAL; 614 return -EINVAL;
639 615
640 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); 616 return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
641} 617}
642#endif 618#endif
643 619
644static int tw9910_set_crop(struct soc_camera_device *icd, 620static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
645 struct v4l2_rect *rect)
646{ 621{
647 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 622 struct v4l2_rect *rect = &a->c;
623 struct i2c_client *client = sd->priv;
624 struct tw9910_priv *priv = to_tw9910(client);
625 struct soc_camera_device *icd = client->dev.platform_data;
648 int ret = -EINVAL; 626 int ret = -EINVAL;
649 u8 val; 627 u8 val;
650 628
@@ -658,8 +636,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
658 /* 636 /*
659 * reset hardware 637 * reset hardware
660 */ 638 */
661 tw9910_reset(priv->client); 639 tw9910_reset(client);
662 ret = tw9910_write_array(priv->client, tw9910_default_regs); 640 ret = tw9910_write_array(client, tw9910_default_regs);
663 if (ret < 0) 641 if (ret < 0)
664 goto tw9910_set_fmt_error; 642 goto tw9910_set_fmt_error;
665 643
@@ -670,7 +648,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
670 if (SOCAM_DATAWIDTH_16 == priv->info->buswidth) 648 if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
671 val = LEN; 649 val = LEN;
672 650
673 ret = tw9910_mask_set(priv->client, OPFORM, LEN, val); 651 ret = tw9910_mask_set(client, OPFORM, LEN, val);
674 if (ret < 0) 652 if (ret < 0)
675 goto tw9910_set_fmt_error; 653 goto tw9910_set_fmt_error;
676 654
@@ -698,52 +676,139 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
698 val = 0; 676 val = 0;
699 } 677 }
700 678
701 ret = tw9910_mask_set(priv->client, VBICNTL, RTSEL_MASK, val); 679 ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
702 if (ret < 0) 680 if (ret < 0)
703 goto tw9910_set_fmt_error; 681 goto tw9910_set_fmt_error;
704 682
705 /* 683 /*
706 * set scale 684 * set scale
707 */ 685 */
708 ret = tw9910_set_scale(priv->client, priv->scale); 686 ret = tw9910_set_scale(client, priv->scale);
709 if (ret < 0) 687 if (ret < 0)
710 goto tw9910_set_fmt_error; 688 goto tw9910_set_fmt_error;
711 689
712 /* 690 /*
713 * set cropping 691 * set cropping
714 */ 692 */
715 ret = tw9910_set_cropping(priv->client, &tw9910_cropping_ctrl); 693 ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
716 if (ret < 0) 694 if (ret < 0)
717 goto tw9910_set_fmt_error; 695 goto tw9910_set_fmt_error;
718 696
719 /* 697 /*
720 * set hsync 698 * set hsync
721 */ 699 */
722 ret = tw9910_set_hsync(priv->client, &tw9910_hsync_ctrl); 700 ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
723 if (ret < 0) 701 if (ret < 0)
724 goto tw9910_set_fmt_error; 702 goto tw9910_set_fmt_error;
725 703
704 rect->width = priv->scale->width;
705 rect->height = priv->scale->height;
706 rect->left = 0;
707 rect->top = 0;
708
726 return ret; 709 return ret;
727 710
728tw9910_set_fmt_error: 711tw9910_set_fmt_error:
729 712
730 tw9910_reset(priv->client); 713 tw9910_reset(client);
731 priv->scale = NULL; 714 priv->scale = NULL;
732 715
733 return ret; 716 return ret;
734} 717}
735 718
736static int tw9910_set_fmt(struct soc_camera_device *icd, 719static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
737 struct v4l2_format *f) 720{
721 struct i2c_client *client = sd->priv;
722 struct tw9910_priv *priv = to_tw9910(client);
723
724 if (!priv->scale) {
725 int ret;
726 struct v4l2_crop crop = {
727 .c = {
728 .left = 0,
729 .top = 0,
730 .width = 640,
731 .height = 480,
732 },
733 };
734 ret = tw9910_s_crop(sd, &crop);
735 if (ret < 0)
736 return ret;
737 }
738
739 a->c.left = 0;
740 a->c.top = 0;
741 a->c.width = priv->scale->width;
742 a->c.height = priv->scale->height;
743 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
744
745 return 0;
746}
747
748static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
738{ 749{
750 a->bounds.left = 0;
751 a->bounds.top = 0;
752 a->bounds.width = 768;
753 a->bounds.height = 576;
754 a->defrect.left = 0;
755 a->defrect.top = 0;
756 a->defrect.width = 640;
757 a->defrect.height = 480;
758 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 a->pixelaspect.numerator = 1;
760 a->pixelaspect.denominator = 1;
761
762 return 0;
763}
764
765static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
766{
767 struct i2c_client *client = sd->priv;
768 struct tw9910_priv *priv = to_tw9910(client);
769 struct v4l2_pix_format *pix = &f->fmt.pix;
770
771 if (!priv->scale) {
772 int ret;
773 struct v4l2_crop crop = {
774 .c = {
775 .left = 0,
776 .top = 0,
777 .width = 640,
778 .height = 480,
779 },
780 };
781 ret = tw9910_s_crop(sd, &crop);
782 if (ret < 0)
783 return ret;
784 }
785
786 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
787
788 pix->width = priv->scale->width;
789 pix->height = priv->scale->height;
790 pix->pixelformat = V4L2_PIX_FMT_VYUY;
791 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
792 pix->field = V4L2_FIELD_INTERLACED;
793
794 return 0;
795}
796
797static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
798{
799 struct i2c_client *client = sd->priv;
800 struct tw9910_priv *priv = to_tw9910(client);
739 struct v4l2_pix_format *pix = &f->fmt.pix; 801 struct v4l2_pix_format *pix = &f->fmt.pix;
740 struct v4l2_rect rect = { 802 /* See tw9910_s_crop() - no proper cropping support */
741 .left = icd->x_current, 803 struct v4l2_crop a = {
742 .top = icd->y_current, 804 .c = {
743 .width = pix->width, 805 .left = 0,
744 .height = pix->height, 806 .top = 0,
807 .width = pix->width,
808 .height = pix->height,
809 },
745 }; 810 };
746 int i; 811 int i, ret;
747 812
748 /* 813 /*
749 * check color format 814 * check color format
@@ -755,19 +820,25 @@ static int tw9910_set_fmt(struct soc_camera_device *icd,
755 if (i == ARRAY_SIZE(tw9910_color_fmt)) 820 if (i == ARRAY_SIZE(tw9910_color_fmt))
756 return -EINVAL; 821 return -EINVAL;
757 822
758 return tw9910_set_crop(icd, &rect); 823 ret = tw9910_s_crop(sd, &a);
824 if (!ret) {
825 pix->width = priv->scale->width;
826 pix->height = priv->scale->height;
827 }
828 return ret;
759} 829}
760 830
761static int tw9910_try_fmt(struct soc_camera_device *icd, 831static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
762 struct v4l2_format *f)
763{ 832{
833 struct i2c_client *client = sd->priv;
834 struct soc_camera_device *icd = client->dev.platform_data;
764 struct v4l2_pix_format *pix = &f->fmt.pix; 835 struct v4l2_pix_format *pix = &f->fmt.pix;
765 const struct tw9910_scale_ctrl *scale; 836 const struct tw9910_scale_ctrl *scale;
766 837
767 if (V4L2_FIELD_ANY == pix->field) { 838 if (V4L2_FIELD_ANY == pix->field) {
768 pix->field = V4L2_FIELD_INTERLACED; 839 pix->field = V4L2_FIELD_INTERLACED;
769 } else if (V4L2_FIELD_INTERLACED != pix->field) { 840 } else if (V4L2_FIELD_INTERLACED != pix->field) {
770 dev_err(&icd->dev, "Field type invalid.\n"); 841 dev_err(&client->dev, "Field type invalid.\n");
771 return -EINVAL; 842 return -EINVAL;
772 } 843 }
773 844
@@ -784,11 +855,11 @@ static int tw9910_try_fmt(struct soc_camera_device *icd,
784 return 0; 855 return 0;
785} 856}
786 857
787static int tw9910_video_probe(struct soc_camera_device *icd) 858static int tw9910_video_probe(struct soc_camera_device *icd,
859 struct i2c_client *client)
788{ 860{
789 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 861 struct tw9910_priv *priv = to_tw9910(client);
790 s32 val; 862 s32 val;
791 int ret;
792 863
793 /* 864 /*
794 * We must have a parent by now. And it cannot be a wrong one. 865 * We must have a parent by now. And it cannot be a wrong one.
@@ -803,7 +874,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
803 */ 874 */
804 if (SOCAM_DATAWIDTH_16 != priv->info->buswidth && 875 if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
805 SOCAM_DATAWIDTH_8 != priv->info->buswidth) { 876 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
806 dev_err(&icd->dev, "bus width error\n"); 877 dev_err(&client->dev, "bus width error\n");
807 return -ENODEV; 878 return -ENODEV;
808 } 879 }
809 880
@@ -813,54 +884,54 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
813 /* 884 /*
814 * check and show Product ID 885 * check and show Product ID
815 */ 886 */
816 val = i2c_smbus_read_byte_data(priv->client, ID); 887 val = i2c_smbus_read_byte_data(client, ID);
888
817 if (0x0B != GET_ID(val) || 889 if (0x0B != GET_ID(val) ||
818 0x00 != GET_ReV(val)) { 890 0x00 != GET_ReV(val)) {
819 dev_err(&icd->dev, 891 dev_err(&client->dev,
820 "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val)); 892 "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
821 return -ENODEV; 893 return -ENODEV;
822 } 894 }
823 895
824 dev_info(&icd->dev, 896 dev_info(&client->dev,
825 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val)); 897 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
826 898
827 ret = soc_camera_video_start(icd);
828 if (ret < 0)
829 return ret;
830
831 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 899 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
832 icd->vdev->current_norm = V4L2_STD_NTSC; 900 icd->vdev->current_norm = V4L2_STD_NTSC;
833 901
834 return ret; 902 return 0;
835}
836
837static void tw9910_video_remove(struct soc_camera_device *icd)
838{
839 soc_camera_video_stop(icd);
840} 903}
841 904
842static struct soc_camera_ops tw9910_ops = { 905static struct soc_camera_ops tw9910_ops = {
843 .owner = THIS_MODULE,
844 .probe = tw9910_video_probe,
845 .remove = tw9910_video_remove,
846 .init = tw9910_init,
847 .release = tw9910_release,
848 .start_capture = tw9910_start_capture,
849 .stop_capture = tw9910_stop_capture,
850 .set_crop = tw9910_set_crop,
851 .set_fmt = tw9910_set_fmt,
852 .try_fmt = tw9910_try_fmt,
853 .set_bus_param = tw9910_set_bus_param, 906 .set_bus_param = tw9910_set_bus_param,
854 .query_bus_param = tw9910_query_bus_param, 907 .query_bus_param = tw9910_query_bus_param,
855 .get_chip_id = tw9910_get_chip_id,
856 .set_std = tw9910_set_std,
857 .enum_input = tw9910_enum_input, 908 .enum_input = tw9910_enum_input,
909};
910
911static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
912 .g_chip_ident = tw9910_g_chip_ident,
913 .s_std = tw9910_s_std,
858#ifdef CONFIG_VIDEO_ADV_DEBUG 914#ifdef CONFIG_VIDEO_ADV_DEBUG
859 .get_register = tw9910_get_register, 915 .g_register = tw9910_g_register,
860 .set_register = tw9910_set_register, 916 .s_register = tw9910_s_register,
861#endif 917#endif
862}; 918};
863 919
920static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
921 .s_stream = tw9910_s_stream,
922 .g_fmt = tw9910_g_fmt,
923 .s_fmt = tw9910_s_fmt,
924 .try_fmt = tw9910_try_fmt,
925 .cropcap = tw9910_cropcap,
926 .g_crop = tw9910_g_crop,
927 .s_crop = tw9910_s_crop,
928};
929
930static struct v4l2_subdev_ops tw9910_subdev_ops = {
931 .core = &tw9910_subdev_core_ops,
932 .video = &tw9910_subdev_video_ops,
933};
934
864/* 935/*
865 * i2c_driver function 936 * i2c_driver function
866 */ 937 */
@@ -871,18 +942,24 @@ static int tw9910_probe(struct i2c_client *client,
871{ 942{
872 struct tw9910_priv *priv; 943 struct tw9910_priv *priv;
873 struct tw9910_video_info *info; 944 struct tw9910_video_info *info;
874 struct soc_camera_device *icd; 945 struct soc_camera_device *icd = client->dev.platform_data;
875 const struct tw9910_scale_ctrl *scale; 946 struct i2c_adapter *adapter =
876 int i, ret; 947 to_i2c_adapter(client->dev.parent);
948 struct soc_camera_link *icl;
949 int ret;
950
951 if (!icd) {
952 dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
953 return -EINVAL;
954 }
877 955
878 if (!client->dev.platform_data) 956 icl = to_soc_camera_link(icd);
957 if (!icl)
879 return -EINVAL; 958 return -EINVAL;
880 959
881 info = container_of(client->dev.platform_data, 960 info = container_of(icl, struct tw9910_video_info, link);
882 struct tw9910_video_info, link);
883 961
884 if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent), 962 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
885 I2C_FUNC_SMBUS_BYTE_DATA)) {
886 dev_err(&client->dev, 963 dev_err(&client->dev,
887 "I2C-Adapter doesn't support " 964 "I2C-Adapter doesn't support "
888 "I2C_FUNC_SMBUS_BYTE_DATA\n"); 965 "I2C_FUNC_SMBUS_BYTE_DATA\n");
@@ -894,40 +971,15 @@ static int tw9910_probe(struct i2c_client *client,
894 return -ENOMEM; 971 return -ENOMEM;
895 972
896 priv->info = info; 973 priv->info = info;
897 priv->client = client;
898 i2c_set_clientdata(client, priv);
899 974
900 icd = &priv->icd; 975 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
976
901 icd->ops = &tw9910_ops; 977 icd->ops = &tw9910_ops;
902 icd->control = &client->dev;
903 icd->iface = info->link.bus_id; 978 icd->iface = info->link.bus_id;
904 979
905 /* 980 ret = tw9910_video_probe(icd, client);
906 * set width and height
907 */
908 icd->width_max = tw9910_ntsc_scales[0].width; /* set default */
909 icd->width_min = tw9910_ntsc_scales[0].width;
910 icd->height_max = tw9910_ntsc_scales[0].height;
911 icd->height_min = tw9910_ntsc_scales[0].height;
912
913 scale = tw9910_ntsc_scales;
914 for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++) {
915 icd->width_max = max(scale[i].width, icd->width_max);
916 icd->width_min = min(scale[i].width, icd->width_min);
917 icd->height_max = max(scale[i].height, icd->height_max);
918 icd->height_min = min(scale[i].height, icd->height_min);
919 }
920 scale = tw9910_pal_scales;
921 for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++) {
922 icd->width_max = max(scale[i].width, icd->width_max);
923 icd->width_min = min(scale[i].width, icd->width_min);
924 icd->height_max = max(scale[i].height, icd->height_max);
925 icd->height_min = min(scale[i].height, icd->height_min);
926 }
927
928 ret = soc_camera_device_register(icd);
929
930 if (ret) { 981 if (ret) {
982 icd->ops = NULL;
931 i2c_set_clientdata(client, NULL); 983 i2c_set_clientdata(client, NULL);
932 kfree(priv); 984 kfree(priv);
933 } 985 }
@@ -937,9 +989,10 @@ static int tw9910_probe(struct i2c_client *client,
937 989
938static int tw9910_remove(struct i2c_client *client) 990static int tw9910_remove(struct i2c_client *client)
939{ 991{
940 struct tw9910_priv *priv = i2c_get_clientdata(client); 992 struct tw9910_priv *priv = to_tw9910(client);
993 struct soc_camera_device *icd = client->dev.platform_data;
941 994
942 soc_camera_device_unregister(&priv->icd); 995 icd->ops = NULL;
943 i2c_set_clientdata(client, NULL); 996 i2c_set_clientdata(client, NULL);
944 kfree(priv); 997 kfree(priv);
945 return 0; 998 return 0;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 1fe5befbbf85..f97fd06d5948 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -246,9 +246,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
246 switch (usbvision_device_data[usbvision->DevModel].Codec) { 246 switch (usbvision_device_data[usbvision->DevModel].Codec) {
247 case CODEC_SAA7113: 247 case CODEC_SAA7113:
248 case CODEC_SAA7111: 248 case CODEC_SAA7111:
249 v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 249 v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
250 &usbvision->i2c_adap, "saa7115", 250 &usbvision->i2c_adap, "saa7115",
251 "saa7115_auto", saa711x_addrs); 251 "saa7115_auto", 0, saa711x_addrs);
252 break; 252 break;
253 } 253 }
254 if (usbvision_device_data[usbvision->DevModel].Tuner == 1) { 254 if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
@@ -256,16 +256,16 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
256 enum v4l2_i2c_tuner_type type; 256 enum v4l2_i2c_tuner_type type;
257 struct tuner_setup tun_setup; 257 struct tuner_setup tun_setup;
258 258
259 sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 259 sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
260 &usbvision->i2c_adap, "tuner", 260 &usbvision->i2c_adap, "tuner",
261 "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 261 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
262 /* depending on whether we found a demod or not, select 262 /* depending on whether we found a demod or not, select
263 the tuner type. */ 263 the tuner type. */
264 type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 264 type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
265 265
266 sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 266 sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
267 &usbvision->i2c_adap, "tuner", 267 &usbvision->i2c_adap, "tuner",
268 "tuner", v4l2_i2c_tuner_addrs(type)); 268 "tuner", 0, v4l2_i2c_tuner_addrs(type));
269 269
270 if (usbvision->tuner_type != -1) { 270 if (usbvision->tuner_type != -1) {
271 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; 271 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5b757f32d997..f960e8ea4f17 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -124,13 +124,14 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
124 int ret; 124 int ret;
125 125
126 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; 126 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
127 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
128 query == UVC_GET_DEF)
129 return -EIO;
130
127 data = kmalloc(size, GFP_KERNEL); 131 data = kmalloc(size, GFP_KERNEL);
128 if (data == NULL) 132 if (data == NULL)
129 return -ENOMEM; 133 return -ENOMEM;
130 134
131 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF)
132 return -EIO;
133
134 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, 135 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
135 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 136 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
136 size, UVC_CTRL_STREAMING_TIMEOUT); 137 size, UVC_CTRL_STREAMING_TIMEOUT);
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 761fbd64db58..0c2105ca611e 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -564,10 +564,9 @@ static noinline long v4l1_compat_get_input_info(
564 break; 564 break;
565 } 565 }
566 chan->norm = 0; 566 chan->norm = 0;
567 err = drv(file, VIDIOC_G_STD, &sid); 567 /* Note: G_STD might not be present for radio receivers,
568 if (err < 0) 568 * so we should ignore any errors. */
569 dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %ld\n", err); 569 if (drv(file, VIDIOC_G_STD, &sid) == 0) {
570 if (err == 0) {
571 if (sid & V4L2_STD_PAL) 570 if (sid & V4L2_STD_PAL)
572 chan->norm = VIDEO_MODE_PAL; 571 chan->norm = VIDEO_MODE_PAL;
573 if (sid & V4L2_STD_NTSC) 572 if (sid & V4L2_STD_NTSC)
@@ -776,10 +775,9 @@ static noinline long v4l1_compat_get_tuner(
776 tun->flags |= VIDEO_TUNER_SECAM; 775 tun->flags |= VIDEO_TUNER_SECAM;
777 } 776 }
778 777
779 err = drv(file, VIDIOC_G_STD, &sid); 778 /* Note: G_STD might not be present for radio receivers,
780 if (err < 0) 779 * so we should ignore any errors. */
781 dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err); 780 if (drv(file, VIDIOC_G_STD, &sid) == 0) {
782 if (err == 0) {
783 if (sid & V4L2_STD_PAL) 781 if (sid & V4L2_STD_PAL)
784 tun->mode = VIDEO_MODE_PAL; 782 tun->mode = VIDEO_MODE_PAL;
785 if (sid & V4L2_STD_NTSC) 783 if (sid & V4L2_STD_NTSC)
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 3a0c64935b0e..f5a93ae3cdf9 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -814,139 +814,6 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
814 814
815 815
816/* Load an i2c sub-device. */ 816/* Load an i2c sub-device. */
817struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
818 struct i2c_adapter *adapter,
819 const char *module_name, const char *client_type, u8 addr)
820{
821 struct v4l2_subdev *sd = NULL;
822 struct i2c_client *client;
823 struct i2c_board_info info;
824
825 BUG_ON(!v4l2_dev);
826
827 if (module_name)
828 request_module(module_name);
829
830 /* Setup the i2c board info with the device type and
831 the device address. */
832 memset(&info, 0, sizeof(info));
833 strlcpy(info.type, client_type, sizeof(info.type));
834 info.addr = addr;
835
836 /* Create the i2c client */
837 client = i2c_new_device(adapter, &info);
838 /* Note: it is possible in the future that
839 c->driver is NULL if the driver is still being loaded.
840 We need better support from the kernel so that we
841 can easily wait for the load to finish. */
842 if (client == NULL || client->driver == NULL)
843 goto error;
844
845 /* Lock the module so we can safely get the v4l2_subdev pointer */
846 if (!try_module_get(client->driver->driver.owner))
847 goto error;
848 sd = i2c_get_clientdata(client);
849
850 /* Register with the v4l2_device which increases the module's
851 use count as well. */
852 if (v4l2_device_register_subdev(v4l2_dev, sd))
853 sd = NULL;
854 /* Decrease the module use count to match the first try_module_get. */
855 module_put(client->driver->driver.owner);
856
857 if (sd) {
858 /* We return errors from v4l2_subdev_call only if we have the
859 callback as the .s_config is not mandatory */
860 int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
861
862 if (err && err != -ENOIOCTLCMD) {
863 v4l2_device_unregister_subdev(sd);
864 sd = NULL;
865 }
866 }
867
868error:
869 /* If we have a client but no subdev, then something went wrong and
870 we must unregister the client. */
871 if (client && sd == NULL)
872 i2c_unregister_device(client);
873 return sd;
874}
875EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
876
877/* Probe and load an i2c sub-device. */
878struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
879 struct i2c_adapter *adapter,
880 const char *module_name, const char *client_type,
881 const unsigned short *addrs)
882{
883 struct v4l2_subdev *sd = NULL;
884 struct i2c_client *client = NULL;
885 struct i2c_board_info info;
886
887 BUG_ON(!v4l2_dev);
888
889 if (module_name)
890 request_module(module_name);
891
892 /* Setup the i2c board info with the device type and
893 the device address. */
894 memset(&info, 0, sizeof(info));
895 strlcpy(info.type, client_type, sizeof(info.type));
896
897 /* Probe and create the i2c client */
898 client = i2c_new_probed_device(adapter, &info, addrs);
899 /* Note: it is possible in the future that
900 c->driver is NULL if the driver is still being loaded.
901 We need better support from the kernel so that we
902 can easily wait for the load to finish. */
903 if (client == NULL || client->driver == NULL)
904 goto error;
905
906 /* Lock the module so we can safely get the v4l2_subdev pointer */
907 if (!try_module_get(client->driver->driver.owner))
908 goto error;
909 sd = i2c_get_clientdata(client);
910
911 /* Register with the v4l2_device which increases the module's
912 use count as well. */
913 if (v4l2_device_register_subdev(v4l2_dev, sd))
914 sd = NULL;
915 /* Decrease the module use count to match the first try_module_get. */
916 module_put(client->driver->driver.owner);
917
918 if (sd) {
919 /* We return errors from v4l2_subdev_call only if we have the
920 callback as the .s_config is not mandatory */
921 int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
922
923 if (err && err != -ENOIOCTLCMD) {
924 v4l2_device_unregister_subdev(sd);
925 sd = NULL;
926 }
927 }
928
929error:
930 /* If we have a client but no subdev, then something went wrong and
931 we must unregister the client. */
932 if (client && sd == NULL)
933 i2c_unregister_device(client);
934 return sd;
935}
936EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
937
938struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
939 struct i2c_adapter *adapter,
940 const char *module_name, const char *client_type, u8 addr)
941{
942 unsigned short addrs[2] = { addr, I2C_CLIENT_END };
943
944 return v4l2_i2c_new_probed_subdev(v4l2_dev, adapter,
945 module_name, client_type, addrs);
946}
947EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
948
949/* Load an i2c sub-device. */
950struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, 817struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
951 struct i2c_adapter *adapter, const char *module_name, 818 struct i2c_adapter *adapter, const char *module_name,
952 struct i2c_board_info *info, const unsigned short *probe_addrs) 819 struct i2c_board_info *info, const unsigned short *probe_addrs)
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index a7f1b69a7dab..500cbe9891ac 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -66,7 +66,49 @@ static struct device_attribute video_device_attrs[] = {
66 */ 66 */
67static struct video_device *video_device[VIDEO_NUM_DEVICES]; 67static struct video_device *video_device[VIDEO_NUM_DEVICES];
68static DEFINE_MUTEX(videodev_lock); 68static DEFINE_MUTEX(videodev_lock);
69static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES); 69static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
70
71/* Device node utility functions */
72
73/* Note: these utility functions all assume that vfl_type is in the range
74 [0, VFL_TYPE_MAX-1]. */
75
76#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
77/* Return the bitmap corresponding to vfl_type. */
78static inline unsigned long *devnode_bits(int vfl_type)
79{
80 /* Any types not assigned to fixed minor ranges must be mapped to
81 one single bitmap for the purposes of finding a free node number
82 since all those unassigned types use the same minor range. */
83 int idx = (vfl_type > VFL_TYPE_VTX) ? VFL_TYPE_MAX - 1 : vfl_type;
84
85 return devnode_nums[idx];
86}
87#else
88/* Return the bitmap corresponding to vfl_type. */
89static inline unsigned long *devnode_bits(int vfl_type)
90{
91 return devnode_nums[vfl_type];
92}
93#endif
94
95/* Mark device node number vdev->num as used */
96static inline void devnode_set(struct video_device *vdev)
97{
98 set_bit(vdev->num, devnode_bits(vdev->vfl_type));
99}
100
101/* Mark device node number vdev->num as unused */
102static inline void devnode_clear(struct video_device *vdev)
103{
104 clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
105}
106
107/* Try to find a free device node number in the range [from, to> */
108static inline int devnode_find(struct video_device *vdev, int from, int to)
109{
110 return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
111}
70 112
71struct video_device *video_device_alloc(void) 113struct video_device *video_device_alloc(void)
72{ 114{
@@ -119,8 +161,8 @@ static void v4l2_device_release(struct device *cd)
119 the release() callback. */ 161 the release() callback. */
120 vdev->cdev = NULL; 162 vdev->cdev = NULL;
121 163
122 /* Mark minor as free */ 164 /* Mark device node number as free */
123 clear_bit(vdev->num, video_nums[vdev->vfl_type]); 165 devnode_clear(vdev);
124 166
125 mutex_unlock(&videodev_lock); 167 mutex_unlock(&videodev_lock);
126 168
@@ -299,32 +341,28 @@ static const struct file_operations v4l2_fops = {
299}; 341};
300 342
301/** 343/**
302 * get_index - assign stream number based on parent device 344 * get_index - assign stream index number based on parent device
303 * @vdev: video_device to assign index number to, vdev->parent should be assigned 345 * @vdev: video_device to assign index number to, vdev->parent should be assigned
304 * @num: -1 if auto assign, requested number otherwise
305 * 346 *
306 * Note that when this is called the new device has not yet been registered 347 * Note that when this is called the new device has not yet been registered
307 * in the video_device array. 348 * in the video_device array, but it was able to obtain a minor number.
349 *
350 * This means that we can always obtain a free stream index number since
351 * the worst case scenario is that there are VIDEO_NUM_DEVICES - 1 slots in
352 * use of the video_device array.
308 * 353 *
309 * Returns -ENFILE if num is already in use, a free index number if 354 * Returns a free index number.
310 * successful.
311 */ 355 */
312static int get_index(struct video_device *vdev, int num) 356static int get_index(struct video_device *vdev)
313{ 357{
314 /* This can be static since this function is called with the global 358 /* This can be static since this function is called with the global
315 videodev_lock held. */ 359 videodev_lock held. */
316 static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); 360 static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
317 int i; 361 int i;
318 362
319 if (num >= VIDEO_NUM_DEVICES) { 363 /* Some drivers do not set the parent. In that case always return 0. */
320 printk(KERN_ERR "videodev: %s num is too large\n", __func__);
321 return -EINVAL;
322 }
323
324 /* Some drivers do not set the parent. In that case always return
325 num or 0. */
326 if (vdev->parent == NULL) 364 if (vdev->parent == NULL)
327 return num >= 0 ? num : 0; 365 return 0;
328 366
329 bitmap_zero(used, VIDEO_NUM_DEVICES); 367 bitmap_zero(used, VIDEO_NUM_DEVICES);
330 368
@@ -335,35 +373,23 @@ static int get_index(struct video_device *vdev, int num)
335 } 373 }
336 } 374 }
337 375
338 if (num >= 0) { 376 return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
339 if (test_bit(num, used))
340 return -ENFILE;
341 return num;
342 }
343
344 i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
345 return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
346} 377}
347 378
348int video_register_device(struct video_device *vdev, int type, int nr)
349{
350 return video_register_device_index(vdev, type, nr, -1);
351}
352EXPORT_SYMBOL(video_register_device);
353
354/** 379/**
355 * video_register_device_index - register video4linux devices 380 * video_register_device - register video4linux devices
356 * @vdev: video device structure we want to register 381 * @vdev: video device structure we want to register
357 * @type: type of device to register 382 * @type: type of device to register
358 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 383 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
359 * -1 == first free) 384 * -1 == first free)
360 * @index: stream number based on parent device; 385 * @warn_if_nr_in_use: warn if the desired device node number
361 * -1 if auto assign, requested number otherwise 386 * was already in use and another number was chosen instead.
362 * 387 *
363 * The registration code assigns minor numbers based on the type 388 * The registration code assigns minor numbers and device node numbers
364 * requested. -ENFILE is returned in all the device slots for this 389 * based on the requested type and registers the new device node with
365 * category are full. If not then the minor field is set and the 390 * the kernel.
366 * driver initialize function is called (if non %NULL). 391 * An error is returned if no free minor or device node number could be
392 * found, or if the registration of the device node failed.
367 * 393 *
368 * Zero is returned on success. 394 * Zero is returned on success.
369 * 395 *
@@ -377,8 +403,8 @@ EXPORT_SYMBOL(video_register_device);
377 * 403 *
378 * %VFL_TYPE_RADIO - A radio card 404 * %VFL_TYPE_RADIO - A radio card
379 */ 405 */
380int video_register_device_index(struct video_device *vdev, int type, int nr, 406static int __video_register_device(struct video_device *vdev, int type, int nr,
381 int index) 407 int warn_if_nr_in_use)
382{ 408{
383 int i = 0; 409 int i = 0;
384 int ret; 410 int ret;
@@ -421,7 +447,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
421 if (vdev->v4l2_dev && vdev->v4l2_dev->dev) 447 if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
422 vdev->parent = vdev->v4l2_dev->dev; 448 vdev->parent = vdev->v4l2_dev->dev;
423 449
424 /* Part 2: find a free minor, kernel number and device index. */ 450 /* Part 2: find a free minor, device node number and device index. */
425#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 451#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
426 /* Keep the ranges for the first four types for historical 452 /* Keep the ranges for the first four types for historical
427 * reasons. 453 * reasons.
@@ -452,21 +478,22 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
452 } 478 }
453#endif 479#endif
454 480
455 /* Pick a minor number */ 481 /* Pick a device node number */
456 mutex_lock(&videodev_lock); 482 mutex_lock(&videodev_lock);
457 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); 483 nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
458 if (nr == minor_cnt) 484 if (nr == minor_cnt)
459 nr = find_first_zero_bit(video_nums[type], minor_cnt); 485 nr = devnode_find(vdev, 0, minor_cnt);
460 if (nr == minor_cnt) { 486 if (nr == minor_cnt) {
461 printk(KERN_ERR "could not get a free kernel number\n"); 487 printk(KERN_ERR "could not get a free device node number\n");
462 mutex_unlock(&videodev_lock); 488 mutex_unlock(&videodev_lock);
463 return -ENFILE; 489 return -ENFILE;
464 } 490 }
465#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 491#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
466 /* 1-on-1 mapping of kernel number to minor number */ 492 /* 1-on-1 mapping of device node number to minor number */
467 i = nr; 493 i = nr;
468#else 494#else
469 /* The kernel number and minor numbers are independent */ 495 /* The device node number and minor numbers are independent, so
496 we just find the first free minor number. */
470 for (i = 0; i < VIDEO_NUM_DEVICES; i++) 497 for (i = 0; i < VIDEO_NUM_DEVICES; i++)
471 if (video_device[i] == NULL) 498 if (video_device[i] == NULL)
472 break; 499 break;
@@ -478,17 +505,13 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
478#endif 505#endif
479 vdev->minor = i + minor_offset; 506 vdev->minor = i + minor_offset;
480 vdev->num = nr; 507 vdev->num = nr;
481 set_bit(nr, video_nums[type]); 508 devnode_set(vdev);
509
482 /* Should not happen since we thought this minor was free */ 510 /* Should not happen since we thought this minor was free */
483 WARN_ON(video_device[vdev->minor] != NULL); 511 WARN_ON(video_device[vdev->minor] != NULL);
484 ret = vdev->index = get_index(vdev, index); 512 vdev->index = get_index(vdev);
485 mutex_unlock(&videodev_lock); 513 mutex_unlock(&videodev_lock);
486 514
487 if (ret < 0) {
488 printk(KERN_ERR "%s: get_index failed\n", __func__);
489 goto cleanup;
490 }
491
492 /* Part 3: Initialize the character device */ 515 /* Part 3: Initialize the character device */
493 vdev->cdev = cdev_alloc(); 516 vdev->cdev = cdev_alloc();
494 if (vdev->cdev == NULL) { 517 if (vdev->cdev == NULL) {
@@ -517,7 +540,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
517 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); 540 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
518 if (vdev->parent) 541 if (vdev->parent)
519 vdev->dev.parent = vdev->parent; 542 vdev->dev.parent = vdev->parent;
520 dev_set_name(&vdev->dev, "%s%d", name_base, nr); 543 dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
521 ret = device_register(&vdev->dev); 544 ret = device_register(&vdev->dev);
522 if (ret < 0) { 545 if (ret < 0) {
523 printk(KERN_ERR "%s: device_register failed\n", __func__); 546 printk(KERN_ERR "%s: device_register failed\n", __func__);
@@ -527,6 +550,10 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
527 reference to the device goes away. */ 550 reference to the device goes away. */
528 vdev->dev.release = v4l2_device_release; 551 vdev->dev.release = v4l2_device_release;
529 552
553 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
554 printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
555 __func__, name_base, nr, name_base, vdev->num);
556
530 /* Part 5: Activate this minor. The char device can now be used. */ 557 /* Part 5: Activate this minor. The char device can now be used. */
531 mutex_lock(&videodev_lock); 558 mutex_lock(&videodev_lock);
532 video_device[vdev->minor] = vdev; 559 video_device[vdev->minor] = vdev;
@@ -537,13 +564,24 @@ cleanup:
537 mutex_lock(&videodev_lock); 564 mutex_lock(&videodev_lock);
538 if (vdev->cdev) 565 if (vdev->cdev)
539 cdev_del(vdev->cdev); 566 cdev_del(vdev->cdev);
540 clear_bit(vdev->num, video_nums[type]); 567 devnode_clear(vdev);
541 mutex_unlock(&videodev_lock); 568 mutex_unlock(&videodev_lock);
542 /* Mark this video device as never having been registered. */ 569 /* Mark this video device as never having been registered. */
543 vdev->minor = -1; 570 vdev->minor = -1;
544 return ret; 571 return ret;
545} 572}
546EXPORT_SYMBOL(video_register_device_index); 573
574int video_register_device(struct video_device *vdev, int type, int nr)
575{
576 return __video_register_device(vdev, type, nr, 1);
577}
578EXPORT_SYMBOL(video_register_device);
579
580int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
581{
582 return __video_register_device(vdev, type, nr, 0);
583}
584EXPORT_SYMBOL(video_register_device_no_warn);
547 585
548/** 586/**
549 * video_unregister_device - unregister a video4linux device 587 * video_unregister_device - unregister a video4linux device
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index f3b6e15d91f2..cd6a3446ab7e 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4333,11 +4333,11 @@ static int __init vino_module_init(void)
4333 vino_init_stage++; 4333 vino_init_stage++;
4334 4334
4335 vino_drvdata->decoder = 4335 vino_drvdata->decoder =
4336 v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev, 4336 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4337 &vino_i2c_adapter, "saa7191", "saa7191", 0x45); 4337 "saa7191", "saa7191", 0, I2C_ADDRS(0x45));
4338 vino_drvdata->camera = 4338 vino_drvdata->camera =
4339 v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev, 4339 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4340 &vino_i2c_adapter, "indycam", "indycam", 0x2b); 4340 "indycam", "indycam", 0, I2C_ADDRS(0x2b));
4341 4341
4342 dprintk("init complete!\n"); 4342 dprintk("init complete!\n");
4343 4343
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 602484dd3da9..37fcdc447db5 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -3515,9 +3515,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3515 w9968cf_turn_on_led(cam); 3515 w9968cf_turn_on_led(cam);
3516 3516
3517 w9968cf_i2c_init(cam); 3517 w9968cf_i2c_init(cam);
3518 cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->v4l2_dev, 3518 cam->sensor_sd = v4l2_i2c_new_subdev(&cam->v4l2_dev,
3519 &cam->i2c_adapter, 3519 &cam->i2c_adapter,
3520 "ovcamchip", "ovcamchip", addrs); 3520 "ovcamchip", "ovcamchip", 0, addrs);
3521 3521
3522 usb_set_intfdata(intf, cam); 3522 usb_set_intfdata(intf, cam);
3523 mutex_unlock(&cam->dev_mutex); 3523 mutex_unlock(&cam->dev_mutex);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 96971044fc78..b3c6436b33ba 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -819,8 +819,10 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
819 (!list_empty(&cam->outqueue)) || 819 (!list_empty(&cam->outqueue)) ||
820 (cam->state & DEV_DISCONNECTED) || 820 (cam->state & DEV_DISCONNECTED) ||
821 (cam->state & DEV_MISCONFIGURED), 821 (cam->state & DEV_MISCONFIGURED),
822 cam->module_param.frame_timeout * 822 msecs_to_jiffies(
823 1000 * msecs_to_jiffies(1) ); 823 cam->module_param.frame_timeout * 1000
824 )
825 );
824 if (timeout < 0) { 826 if (timeout < 0) {
825 mutex_unlock(&cam->fileop_mutex); 827 mutex_unlock(&cam->fileop_mutex);
826 return timeout; 828 return timeout;
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 0c4d9b1f8e6f..be70574870de 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1357,15 +1357,15 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
1357 goto zr_free_irq; 1357 goto zr_free_irq;
1358 } 1358 }
1359 1359
1360 zr->decoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev, 1360 zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
1361 &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder, 1361 &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
1362 zr->card.addrs_decoder); 1362 0, zr->card.addrs_decoder);
1363 1363
1364 if (zr->card.mod_encoder) 1364 if (zr->card.mod_encoder)
1365 zr->encoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev, 1365 zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
1366 &zr->i2c_adapter, 1366 &zr->i2c_adapter,
1367 zr->card.mod_encoder, zr->card.i2c_encoder, 1367 zr->card.mod_encoder, zr->card.i2c_encoder,
1368 zr->card.addrs_encoder); 1368 0, zr->card.addrs_encoder);
1369 1369
1370 dprintk(2, 1370 dprintk(2,
1371 KERN_INFO "%s: Initializing videocodec bus...\n", 1371 KERN_INFO "%s: Initializing videocodec bus...\n",
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 54b0186915fb..4876977e52cb 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -196,4 +196,36 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
196 printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm); 196 printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
197} 197}
198 198
199/**
200 * ubi_dbg_dump_flash - dump a region of flash.
201 * @ubi: UBI device description object
202 * @pnum: the physical eraseblock number to dump
203 * @offset: the starting offset within the physical eraseblock to dump
204 * @len: the length of the region to dump
205 */
206void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
207{
208 int err;
209 size_t read;
210 void *buf;
211 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
212
213 buf = vmalloc(len);
214 if (!buf)
215 return;
216 err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
217 if (err && err != -EUCLEAN) {
218 ubi_err("error %d while reading %d bytes from PEB %d:%d, "
219 "read %zd bytes", err, len, pnum, offset, read);
220 goto out;
221 }
222
223 dbg_msg("dumping %d bytes of data from PEB %d, offset %d",
224 len, pnum, offset);
225 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
226out:
227 vfree(buf);
228 return;
229}
230
199#endif /* CONFIG_MTD_UBI_DEBUG */ 231#endif /* CONFIG_MTD_UBI_DEBUG */
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index a4da7a09b949..f30bcb372c05 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -55,6 +55,7 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
55void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); 55void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv);
56void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); 56void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type);
57void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); 57void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
58void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
58 59
59#ifdef CONFIG_MTD_UBI_DEBUG_MSG 60#ifdef CONFIG_MTD_UBI_DEBUG_MSG
60/* General debugging messages */ 61/* General debugging messages */
@@ -167,6 +168,7 @@ static inline int ubi_dbg_is_erase_failure(void)
167#define ubi_dbg_dump_sv(sv) ({}) 168#define ubi_dbg_dump_sv(sv) ({})
168#define ubi_dbg_dump_seb(seb, type) ({}) 169#define ubi_dbg_dump_seb(seb, type) ({})
169#define ubi_dbg_dump_mkvol_req(req) ({}) 170#define ubi_dbg_dump_mkvol_req(req) ({})
171#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({})
170 172
171#define UBI_IO_DEBUG 0 173#define UBI_IO_DEBUG 0
172#define DBG_DISABLE_BGT 0 174#define DBG_DISABLE_BGT 0
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 4cb69925d8d9..8aa51e7a6a7d 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -269,6 +269,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
269 ubi_err("error %d while writing %d bytes to PEB %d:%d, written " 269 ubi_err("error %d while writing %d bytes to PEB %d:%d, written "
270 "%zd bytes", err, len, pnum, offset, written); 270 "%zd bytes", err, len, pnum, offset, written);
271 ubi_dbg_dump_stack(); 271 ubi_dbg_dump_stack();
272 ubi_dbg_dump_flash(ubi, pnum, offset, len);
272 } else 273 } else
273 ubi_assert(written == len); 274 ubi_assert(written == len);
274 275
@@ -475,30 +476,46 @@ out:
475 */ 476 */
476static int nor_erase_prepare(struct ubi_device *ubi, int pnum) 477static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
477{ 478{
478 int err; 479 int err, err1;
479 size_t written; 480 size_t written;
480 loff_t addr; 481 loff_t addr;
481 uint32_t data = 0; 482 uint32_t data = 0;
483 struct ubi_vid_hdr vid_hdr;
482 484
483 addr = (loff_t)pnum * ubi->peb_size; 485 addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
484 err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); 486 err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
485 if (err) { 487 if (!err) {
486 ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " 488 addr -= ubi->vid_hdr_aloffset;
487 "%zd bytes", err, pnum, 0, written); 489 err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
488 ubi_dbg_dump_stack(); 490 (void *)&data);
489 return err; 491 if (!err)
492 return 0;
490 } 493 }
491 494
492 addr += ubi->vid_hdr_aloffset; 495 /*
493 err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); 496 * We failed to write to the media. This was observed with Spansion
494 if (err) { 497 * S29GL512N NOR flash. Most probably the eraseblock erasure was
495 ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " 498 * interrupted at a very inappropriate moment, so it became unwritable.
496 "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); 499 * In this case we probably anyway have garbage in this PEB.
497 ubi_dbg_dump_stack(); 500 */
498 return err; 501 err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
499 } 502 if (err1 == UBI_IO_BAD_VID_HDR)
503 /*
504 * The VID header is corrupted, so we can safely erase this
505 * PEB and not afraid that it will be treated as a valid PEB in
506 * case of an unclean reboot.
507 */
508 return 0;
500 509
501 return 0; 510 /*
511 * The PEB contains a valid VID header, but we cannot invalidate it.
512 * Supposedly the flash media or the driver is screwed up, so return an
513 * error.
514 */
515 ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
516 pnum, err, err1);
517 ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size);
518 return -EIO;
502} 519}
503 520
504/** 521/**
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index b847745394b4..e7161adc419d 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -75,9 +75,10 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
75 dbg_bld("add to free: PEB %d, EC %d", pnum, ec); 75 dbg_bld("add to free: PEB %d, EC %d", pnum, ec);
76 else if (list == &si->erase) 76 else if (list == &si->erase)
77 dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); 77 dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);
78 else if (list == &si->corr) 78 else if (list == &si->corr) {
79 dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); 79 dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
80 else if (list == &si->alien) 80 si->corr_count += 1;
81 } else if (list == &si->alien)
81 dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); 82 dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);
82 else 83 else
83 BUG(); 84 BUG();
@@ -864,7 +865,9 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
864 } 865 }
865 } 866 }
866 867
867 /* Both UBI headers seem to be fine */ 868 if (ec_corr)
869 ubi_warn("valid VID header but corrupted EC header at PEB %d",
870 pnum);
868 err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips); 871 err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips);
869 if (err) 872 if (err)
870 return err; 873 return err;
@@ -936,6 +939,19 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
936 ubi_msg("empty MTD device detected"); 939 ubi_msg("empty MTD device detected");
937 940
938 /* 941 /*
942 * Few corrupted PEBs are not a problem and may be just a result of
943 * unclean reboots. However, many of them may indicate some problems
944 * with the flash HW or driver. Print a warning in this case.
945 */
946 if (si->corr_count >= 8 || si->corr_count >= ubi->peb_count / 4) {
947 ubi_warn("%d PEBs are corrupted", si->corr_count);
948 printk(KERN_WARNING "corrupted PEBs are:");
949 list_for_each_entry(seb, &si->corr, u.list)
950 printk(KERN_CONT " %d", seb->pnum);
951 printk(KERN_CONT "\n");
952 }
953
954 /*
939 * In case of unknown erase counter we use the mean erase counter 955 * In case of unknown erase counter we use the mean erase counter
940 * value. 956 * value.
941 */ 957 */
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 1017cf12def5..bab31695dace 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -102,6 +102,7 @@ struct ubi_scan_volume {
102 * @mean_ec: mean erase counter value 102 * @mean_ec: mean erase counter value
103 * @ec_sum: a temporary variable used when calculating @mean_ec 103 * @ec_sum: a temporary variable used when calculating @mean_ec
104 * @ec_count: a temporary variable used when calculating @mean_ec 104 * @ec_count: a temporary variable used when calculating @mean_ec
105 * @corr_count: count of corrupted PEBs
105 * @image_seq_set: indicates @ubi->image_seq is known 106 * @image_seq_set: indicates @ubi->image_seq is known
106 * 107 *
107 * This data structure contains the result of scanning and may be used by other 108 * This data structure contains the result of scanning and may be used by other
@@ -125,6 +126,7 @@ struct ubi_scan_info {
125 int mean_ec; 126 int mean_ec;
126 uint64_t ec_sum; 127 uint64_t ec_sum;
127 int ec_count; 128 int ec_count;
129 int corr_count;
128 int image_seq_set; 130 int image_seq_set;
129}; 131};
130 132
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 6a5fe9633783..c290f51dd178 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -579,7 +579,8 @@ void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
579 for (rb = rb_first(root), \ 579 for (rb = rb_first(root), \
580 pos = (rb ? container_of(rb, typeof(*pos), member) : NULL); \ 580 pos = (rb ? container_of(rb, typeof(*pos), member) : NULL); \
581 rb; \ 581 rb; \
582 rb = rb_next(rb), pos = container_of(rb, typeof(*pos), member)) 582 rb = rb_next(rb), \
583 pos = (rb ? container_of(rb, typeof(*pos), member) : NULL))
583 584
584/** 585/**
585 * ubi_zalloc_vid_hdr - allocate a volume identifier header object. 586 * ubi_zalloc_vid_hdr - allocate a volume identifier header object.
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 26f6ee93a064..e17c535a577e 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -616,6 +616,14 @@ static void sl_uninit(struct net_device *dev)
616 sl_free_bufs(sl); 616 sl_free_bufs(sl);
617} 617}
618 618
619/* Hook the destructor so we can free slip devices at the right point in time */
620static void sl_free_netdev(struct net_device *dev)
621{
622 int i = dev->base_addr;
623 free_netdev(dev);
624 slip_devs[i] = NULL;
625}
626
619static const struct net_device_ops sl_netdev_ops = { 627static const struct net_device_ops sl_netdev_ops = {
620 .ndo_init = sl_init, 628 .ndo_init = sl_init,
621 .ndo_uninit = sl_uninit, 629 .ndo_uninit = sl_uninit,
@@ -634,7 +642,7 @@ static const struct net_device_ops sl_netdev_ops = {
634static void sl_setup(struct net_device *dev) 642static void sl_setup(struct net_device *dev)
635{ 643{
636 dev->netdev_ops = &sl_netdev_ops; 644 dev->netdev_ops = &sl_netdev_ops;
637 dev->destructor = free_netdev; 645 dev->destructor = sl_free_netdev;
638 646
639 dev->hard_header_len = 0; 647 dev->hard_header_len = 0;
640 dev->addr_len = 0; 648 dev->addr_len = 0;
@@ -712,8 +720,6 @@ static void sl_sync(void)
712static struct slip *sl_alloc(dev_t line) 720static struct slip *sl_alloc(dev_t line)
713{ 721{
714 int i; 722 int i;
715 int sel = -1;
716 int score = -1;
717 struct net_device *dev = NULL; 723 struct net_device *dev = NULL;
718 struct slip *sl; 724 struct slip *sl;
719 725
@@ -724,55 +730,7 @@ static struct slip *sl_alloc(dev_t line)
724 dev = slip_devs[i]; 730 dev = slip_devs[i];
725 if (dev == NULL) 731 if (dev == NULL)
726 break; 732 break;
727
728 sl = netdev_priv(dev);
729 if (sl->leased) {
730 if (sl->line != line)
731 continue;
732 if (sl->tty)
733 return NULL;
734
735 /* Clear ESCAPE & ERROR flags */
736 sl->flags &= (1 << SLF_INUSE);
737 return sl;
738 }
739
740 if (sl->tty)
741 continue;
742
743 if (current->pid == sl->pid) {
744 if (sl->line == line && score < 3) {
745 sel = i;
746 score = 3;
747 continue;
748 }
749 if (score < 2) {
750 sel = i;
751 score = 2;
752 }
753 continue;
754 }
755 if (sl->line == line && score < 1) {
756 sel = i;
757 score = 1;
758 continue;
759 }
760 if (score < 0) {
761 sel = i;
762 score = 0;
763 }
764 }
765
766 if (sel >= 0) {
767 i = sel;
768 dev = slip_devs[i];
769 if (score > 1) {
770 sl = netdev_priv(dev);
771 sl->flags &= (1 << SLF_INUSE);
772 return sl;
773 }
774 } 733 }
775
776 /* Sorry, too many, all slots in use */ 734 /* Sorry, too many, all slots in use */
777 if (i >= slip_maxdev) 735 if (i >= slip_maxdev)
778 return NULL; 736 return NULL;
@@ -909,30 +867,13 @@ err_exit:
909} 867}
910 868
911/* 869/*
912
913 FIXME: 1,2 are fixed 3 was never true anyway.
914
915 Let me to blame a bit.
916 1. TTY module calls this funstion on soft interrupt.
917 2. TTY module calls this function WITH MASKED INTERRUPTS!
918 3. TTY module does not notify us about line discipline
919 shutdown,
920
921 Seems, now it is clean. The solution is to consider netdevice and
922 line discipline sides as two independent threads.
923
924 By-product (not desired): sl? does not feel hangups and remains open.
925 It is supposed, that user level program (dip, diald, slattach...)
926 will catch SIGHUP and make the rest of work.
927
928 I see no way to make more with current tty code. --ANK
929 */
930
931/*
932 * Close down a SLIP channel. 870 * Close down a SLIP channel.
933 * This means flushing out any pending queues, and then returning. This 871 * This means flushing out any pending queues, and then returning. This
934 * call is serialized against other ldisc functions. 872 * call is serialized against other ldisc functions.
873 *
874 * We also use this method fo a hangup event
935 */ 875 */
876
936static void slip_close(struct tty_struct *tty) 877static void slip_close(struct tty_struct *tty)
937{ 878{
938 struct slip *sl = tty->disc_data; 879 struct slip *sl = tty->disc_data;
@@ -951,10 +892,16 @@ static void slip_close(struct tty_struct *tty)
951 del_timer_sync(&sl->keepalive_timer); 892 del_timer_sync(&sl->keepalive_timer);
952 del_timer_sync(&sl->outfill_timer); 893 del_timer_sync(&sl->outfill_timer);
953#endif 894#endif
954 895 /* Flush network side */
955 /* Count references from TTY module */ 896 unregister_netdev(sl->dev);
897 /* This will complete via sl_free_netdev */
956} 898}
957 899
900static int slip_hangup(struct tty_struct *tty)
901{
902 slip_close(tty);
903 return 0;
904}
958 /************************************************************************ 905 /************************************************************************
959 * STANDARD SLIP ENCAPSULATION * 906 * STANDARD SLIP ENCAPSULATION *
960 ************************************************************************/ 907 ************************************************************************/
@@ -1311,6 +1258,7 @@ static struct tty_ldisc_ops sl_ldisc = {
1311 .name = "slip", 1258 .name = "slip",
1312 .open = slip_open, 1259 .open = slip_open,
1313 .close = slip_close, 1260 .close = slip_close,
1261 .hangup = slip_hangup,
1314 .ioctl = slip_ioctl, 1262 .ioctl = slip_ioctl,
1315 .receive_buf = slip_receive_buf, 1263 .receive_buf = slip_receive_buf,
1316 .write_wakeup = slip_write_wakeup, 1264 .write_wakeup = slip_write_wakeup,
@@ -1384,6 +1332,8 @@ static void __exit slip_exit(void)
1384 } 1332 }
1385 } while (busy && time_before(jiffies, timeout)); 1333 } while (busy && time_before(jiffies, timeout));
1386 1334
1335 /* FIXME: hangup is async so we should wait when doing this second
1336 phase */
1387 1337
1388 for (i = 0; i < slip_maxdev; i++) { 1338 for (i = 0; i < slip_maxdev; i++) {
1389 dev = slip_devs[i]; 1339 dev = slip_devs[i];
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3f5d28851aa2..d3ee1994b02f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1370,7 +1370,7 @@ static const struct file_operations tun_fops = {
1370static struct miscdevice tun_miscdev = { 1370static struct miscdevice tun_miscdev = {
1371 .minor = TUN_MINOR, 1371 .minor = TUN_MINOR,
1372 .name = "tun", 1372 .name = "tun",
1373 .devnode = "net/tun", 1373 .nodename = "net/tun",
1374 .fops = &tun_fops, 1374 .fops = &tun_fops,
1375}; 1375};
1376 1376
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 62a4c2026072..11ae5c94608b 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -29,7 +29,6 @@
29#include <linux/ethtool.h> 29#include <linux/ethtool.h>
30#include <linux/if_ether.h> 30#include <linux/if_ether.h>
31#include <linux/if_vlan.h> 31#include <linux/if_vlan.h>
32#include <linux/netdevice.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/bitops.h> 33#include <linux/bitops.h>
35#include <net/rtnetlink.h> 34#include <net/rtnetlink.h>
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 9928704e235f..d9b0e9d31983 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -73,7 +73,6 @@
73#include <linux/of.h> 73#include <linux/of.h>
74#include <asm/firmware.h> 74#include <asm/firmware.h>
75#include <asm/vio.h> 75#include <asm/vio.h>
76#include <asm/firmware.h>
77#include <scsi/scsi.h> 76#include <scsi/scsi.h>
78#include <scsi/scsi_cmnd.h> 77#include <scsi/scsi_cmnd.h>
79#include <scsi/scsi_host.h> 78#include <scsi/scsi_host.h>
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index cb6d85d7ff43..1e3d19397a59 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -86,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port)
86static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) 86static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
87{ 87{
88 struct uart_port *port = dev_id; 88 struct uart_port *port = dev_id;
89 struct tty_struct *tty = port->info->port.tty; 89 struct tty_struct *tty = port->state->port.tty;
90 unsigned int status, ch, flag, rxs, max_count = 256; 90 unsigned int status, ch, flag, rxs, max_count = 256;
91 91
92 status = *CSR_UARTFLG; 92 status = *CSR_UARTFLG;
@@ -124,7 +124,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
124static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) 124static irqreturn_t serial21285_tx_chars(int irq, void *dev_id)
125{ 125{
126 struct uart_port *port = dev_id; 126 struct uart_port *port = dev_id;
127 struct circ_buf *xmit = &port->info->xmit; 127 struct circ_buf *xmit = &port->state->xmit;
128 int count = 256; 128 int count = 256;
129 129
130 if (port->x_char) { 130 if (port->x_char) {
@@ -235,8 +235,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
235 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 235 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
236 quot = uart_get_divisor(port, baud); 236 quot = uart_get_divisor(port, baud);
237 237
238 if (port->info && port->info->port.tty) { 238 if (port->state && port->state->port.tty) {
239 struct tty_struct *tty = port->info->port.tty; 239 struct tty_struct *tty = port->state->port.tty;
240 unsigned int b = port->uartclk / (16 * quot); 240 unsigned int b = port->uartclk / (16 * quot);
241 tty_encode_baud_rate(tty, b, b); 241 tty_encode_baud_rate(tty, b, b);
242 } 242 }
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index fb867a9f55e9..2209620d2349 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1382,7 +1382,7 @@ static void serial8250_enable_ms(struct uart_port *port)
1382static void 1382static void
1383receive_chars(struct uart_8250_port *up, unsigned int *status) 1383receive_chars(struct uart_8250_port *up, unsigned int *status)
1384{ 1384{
1385 struct tty_struct *tty = up->port.info->port.tty; 1385 struct tty_struct *tty = up->port.state->port.tty;
1386 unsigned char ch, lsr = *status; 1386 unsigned char ch, lsr = *status;
1387 int max_count = 256; 1387 int max_count = 256;
1388 char flag; 1388 char flag;
@@ -1457,7 +1457,7 @@ ignore_char:
1457 1457
1458static void transmit_chars(struct uart_8250_port *up) 1458static void transmit_chars(struct uart_8250_port *up)
1459{ 1459{
1460 struct circ_buf *xmit = &up->port.info->xmit; 1460 struct circ_buf *xmit = &up->port.state->xmit;
1461 int count; 1461 int count;
1462 1462
1463 if (up->port.x_char) { 1463 if (up->port.x_char) {
@@ -1500,7 +1500,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
1500 status |= up->msr_saved_flags; 1500 status |= up->msr_saved_flags;
1501 up->msr_saved_flags = 0; 1501 up->msr_saved_flags = 0;
1502 if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && 1502 if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
1503 up->port.info != NULL) { 1503 up->port.state != NULL) {
1504 if (status & UART_MSR_TERI) 1504 if (status & UART_MSR_TERI)
1505 up->port.icount.rng++; 1505 up->port.icount.rng++;
1506 if (status & UART_MSR_DDSR) 1506 if (status & UART_MSR_DDSR)
@@ -1510,7 +1510,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
1510 if (status & UART_MSR_DCTS) 1510 if (status & UART_MSR_DCTS)
1511 uart_handle_cts_change(&up->port, status & UART_MSR_CTS); 1511 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
1512 1512
1513 wake_up_interruptible(&up->port.info->delta_msr_wait); 1513 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
1514 } 1514 }
1515 1515
1516 return status; 1516 return status;
@@ -1677,7 +1677,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
1677 INIT_LIST_HEAD(&up->list); 1677 INIT_LIST_HEAD(&up->list);
1678 i->head = &up->list; 1678 i->head = &up->list;
1679 spin_unlock_irq(&i->lock); 1679 spin_unlock_irq(&i->lock);
1680 1680 irq_flags |= up->port.irqflags;
1681 ret = request_irq(up->port.irq, serial8250_interrupt, 1681 ret = request_irq(up->port.irq, serial8250_interrupt,
1682 irq_flags, "serial", i); 1682 irq_flags, "serial", i);
1683 if (ret < 0) 1683 if (ret < 0)
@@ -1764,7 +1764,7 @@ static void serial8250_backup_timeout(unsigned long data)
1764 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1764 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
1765 spin_unlock_irqrestore(&up->port.lock, flags); 1765 spin_unlock_irqrestore(&up->port.lock, flags);
1766 if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && 1766 if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
1767 (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && 1767 (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
1768 (lsr & UART_LSR_THRE)) { 1768 (lsr & UART_LSR_THRE)) {
1769 iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); 1769 iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
1770 iir |= UART_IIR_THRI; 1770 iir |= UART_IIR_THRI;
@@ -2026,7 +2026,7 @@ static int serial8250_startup(struct uart_port *port)
2026 * allow register changes to become visible. 2026 * allow register changes to become visible.
2027 */ 2027 */
2028 spin_lock_irqsave(&up->port.lock, flags); 2028 spin_lock_irqsave(&up->port.lock, flags);
2029 if (up->port.flags & UPF_SHARE_IRQ) 2029 if (up->port.irqflags & IRQF_SHARED)
2030 disable_irq_nosync(up->port.irq); 2030 disable_irq_nosync(up->port.irq);
2031 2031
2032 wait_for_xmitr(up, UART_LSR_THRE); 2032 wait_for_xmitr(up, UART_LSR_THRE);
@@ -2039,7 +2039,7 @@ static int serial8250_startup(struct uart_port *port)
2039 iir = serial_in(up, UART_IIR); 2039 iir = serial_in(up, UART_IIR);
2040 serial_out(up, UART_IER, 0); 2040 serial_out(up, UART_IER, 0);
2041 2041
2042 if (up->port.flags & UPF_SHARE_IRQ) 2042 if (up->port.irqflags & IRQF_SHARED)
2043 enable_irq(up->port.irq); 2043 enable_irq(up->port.irq);
2044 spin_unlock_irqrestore(&up->port.lock, flags); 2044 spin_unlock_irqrestore(&up->port.lock, flags);
2045 2045
@@ -2272,7 +2272,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
2272 /* 2272 /*
2273 * Ask the core to calculate the divisor for us. 2273 * Ask the core to calculate the divisor for us.
2274 */ 2274 */
2275 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 2275 baud = uart_get_baud_rate(port, termios, old,
2276 port->uartclk / 16 / 0xffff,
2277 port->uartclk / 16);
2276 quot = serial8250_get_divisor(port, baud); 2278 quot = serial8250_get_divisor(port, baud);
2277 2279
2278 /* 2280 /*
@@ -2671,6 +2673,7 @@ static void __init serial8250_isa_init_ports(void)
2671 i++, up++) { 2673 i++, up++) {
2672 up->port.iobase = old_serial_port[i].port; 2674 up->port.iobase = old_serial_port[i].port;
2673 up->port.irq = irq_canonicalize(old_serial_port[i].irq); 2675 up->port.irq = irq_canonicalize(old_serial_port[i].irq);
2676 up->port.irqflags = old_serial_port[i].irqflags;
2674 up->port.uartclk = old_serial_port[i].baud_base * 16; 2677 up->port.uartclk = old_serial_port[i].baud_base * 16;
2675 up->port.flags = old_serial_port[i].flags; 2678 up->port.flags = old_serial_port[i].flags;
2676 up->port.hub6 = old_serial_port[i].hub6; 2679 up->port.hub6 = old_serial_port[i].hub6;
@@ -2679,7 +2682,7 @@ static void __init serial8250_isa_init_ports(void)
2679 up->port.regshift = old_serial_port[i].iomem_reg_shift; 2682 up->port.regshift = old_serial_port[i].iomem_reg_shift;
2680 set_io_from_upio(&up->port); 2683 set_io_from_upio(&up->port);
2681 if (share_irqs) 2684 if (share_irqs)
2682 up->port.flags |= UPF_SHARE_IRQ; 2685 up->port.irqflags |= IRQF_SHARED;
2683 } 2686 }
2684} 2687}
2685 2688
@@ -2869,6 +2872,7 @@ int __init early_serial_setup(struct uart_port *port)
2869 p->iobase = port->iobase; 2872 p->iobase = port->iobase;
2870 p->membase = port->membase; 2873 p->membase = port->membase;
2871 p->irq = port->irq; 2874 p->irq = port->irq;
2875 p->irqflags = port->irqflags;
2872 p->uartclk = port->uartclk; 2876 p->uartclk = port->uartclk;
2873 p->fifosize = port->fifosize; 2877 p->fifosize = port->fifosize;
2874 p->regshift = port->regshift; 2878 p->regshift = port->regshift;
@@ -2942,6 +2946,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
2942 port.iobase = p->iobase; 2946 port.iobase = p->iobase;
2943 port.membase = p->membase; 2947 port.membase = p->membase;
2944 port.irq = p->irq; 2948 port.irq = p->irq;
2949 port.irqflags = p->irqflags;
2945 port.uartclk = p->uartclk; 2950 port.uartclk = p->uartclk;
2946 port.regshift = p->regshift; 2951 port.regshift = p->regshift;
2947 port.iotype = p->iotype; 2952 port.iotype = p->iotype;
@@ -2954,7 +2959,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
2954 port.serial_out = p->serial_out; 2959 port.serial_out = p->serial_out;
2955 port.dev = &dev->dev; 2960 port.dev = &dev->dev;
2956 if (share_irqs) 2961 if (share_irqs)
2957 port.flags |= UPF_SHARE_IRQ; 2962 port.irqflags |= IRQF_SHARED;
2958 ret = serial8250_register_port(&port); 2963 ret = serial8250_register_port(&port);
2959 if (ret < 0) { 2964 if (ret < 0) {
2960 dev_err(&dev->dev, "unable to register port at index %d " 2965 dev_err(&dev->dev, "unable to register port at index %d "
@@ -3096,6 +3101,7 @@ int serial8250_register_port(struct uart_port *port)
3096 uart->port.iobase = port->iobase; 3101 uart->port.iobase = port->iobase;
3097 uart->port.membase = port->membase; 3102 uart->port.membase = port->membase;
3098 uart->port.irq = port->irq; 3103 uart->port.irq = port->irq;
3104 uart->port.irqflags = port->irqflags;
3099 uart->port.uartclk = port->uartclk; 3105 uart->port.uartclk = port->uartclk;
3100 uart->port.fifosize = port->fifosize; 3106 uart->port.fifosize = port->fifosize;
3101 uart->port.regshift = port->regshift; 3107 uart->port.regshift = port->regshift;
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 520260326f3d..6e19ea3e48d5 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -25,6 +25,7 @@ struct old_serial_port {
25 unsigned char io_type; 25 unsigned char io_type;
26 unsigned char *iomem_base; 26 unsigned char *iomem_base;
27 unsigned short iomem_reg_shift; 27 unsigned short iomem_reg_shift;
28 unsigned long irqflags;
28}; 29};
29 30
30/* 31/*
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 58a4879c7e48..429a8ae86933 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -117,7 +117,7 @@ static void pl010_enable_ms(struct uart_port *port)
117 117
118static void pl010_rx_chars(struct uart_amba_port *uap) 118static void pl010_rx_chars(struct uart_amba_port *uap)
119{ 119{
120 struct tty_struct *tty = uap->port.info->port.tty; 120 struct tty_struct *tty = uap->port.state->port.tty;
121 unsigned int status, ch, flag, rsr, max_count = 256; 121 unsigned int status, ch, flag, rsr, max_count = 256;
122 122
123 status = readb(uap->port.membase + UART01x_FR); 123 status = readb(uap->port.membase + UART01x_FR);
@@ -172,7 +172,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap)
172 172
173static void pl010_tx_chars(struct uart_amba_port *uap) 173static void pl010_tx_chars(struct uart_amba_port *uap)
174{ 174{
175 struct circ_buf *xmit = &uap->port.info->xmit; 175 struct circ_buf *xmit = &uap->port.state->xmit;
176 int count; 176 int count;
177 177
178 if (uap->port.x_char) { 178 if (uap->port.x_char) {
@@ -225,7 +225,7 @@ static void pl010_modem_status(struct uart_amba_port *uap)
225 if (delta & UART01x_FR_CTS) 225 if (delta & UART01x_FR_CTS)
226 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); 226 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
227 227
228 wake_up_interruptible(&uap->port.info->delta_msr_wait); 228 wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
229} 229}
230 230
231static irqreturn_t pl010_int(int irq, void *dev_id) 231static irqreturn_t pl010_int(int irq, void *dev_id)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 72ba0c6d3551..ef7adc8135dd 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -124,7 +124,7 @@ static void pl011_enable_ms(struct uart_port *port)
124 124
125static void pl011_rx_chars(struct uart_amba_port *uap) 125static void pl011_rx_chars(struct uart_amba_port *uap)
126{ 126{
127 struct tty_struct *tty = uap->port.info->port.tty; 127 struct tty_struct *tty = uap->port.state->port.tty;
128 unsigned int status, ch, flag, max_count = 256; 128 unsigned int status, ch, flag, max_count = 256;
129 129
130 status = readw(uap->port.membase + UART01x_FR); 130 status = readw(uap->port.membase + UART01x_FR);
@@ -175,7 +175,7 @@ static void pl011_rx_chars(struct uart_amba_port *uap)
175 175
176static void pl011_tx_chars(struct uart_amba_port *uap) 176static void pl011_tx_chars(struct uart_amba_port *uap)
177{ 177{
178 struct circ_buf *xmit = &uap->port.info->xmit; 178 struct circ_buf *xmit = &uap->port.state->xmit;
179 int count; 179 int count;
180 180
181 if (uap->port.x_char) { 181 if (uap->port.x_char) {
@@ -226,7 +226,7 @@ static void pl011_modem_status(struct uart_amba_port *uap)
226 if (delta & UART01x_FR_CTS) 226 if (delta & UART01x_FR_CTS)
227 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); 227 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
228 228
229 wake_up_interruptible(&uap->port.info->delta_msr_wait); 229 wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
230} 230}
231 231
232static irqreturn_t pl011_int(int irq, void *dev_id) 232static irqreturn_t pl011_int(int irq, void *dev_id)
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 607d43a31048..3551c5cb7094 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -427,7 +427,7 @@ static void atmel_rx_chars(struct uart_port *port)
427 */ 427 */
428static void atmel_tx_chars(struct uart_port *port) 428static void atmel_tx_chars(struct uart_port *port)
429{ 429{
430 struct circ_buf *xmit = &port->info->xmit; 430 struct circ_buf *xmit = &port->state->xmit;
431 431
432 if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) { 432 if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {
433 UART_PUT_CHAR(port, port->x_char); 433 UART_PUT_CHAR(port, port->x_char);
@@ -560,7 +560,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
560static void atmel_tx_dma(struct uart_port *port) 560static void atmel_tx_dma(struct uart_port *port)
561{ 561{
562 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); 562 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
563 struct circ_buf *xmit = &port->info->xmit; 563 struct circ_buf *xmit = &port->state->xmit;
564 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; 564 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
565 int count; 565 int count;
566 566
@@ -663,14 +663,14 @@ static void atmel_rx_from_ring(struct uart_port *port)
663 * uart_start(), which takes the lock. 663 * uart_start(), which takes the lock.
664 */ 664 */
665 spin_unlock(&port->lock); 665 spin_unlock(&port->lock);
666 tty_flip_buffer_push(port->info->port.tty); 666 tty_flip_buffer_push(port->state->port.tty);
667 spin_lock(&port->lock); 667 spin_lock(&port->lock);
668} 668}
669 669
670static void atmel_rx_from_dma(struct uart_port *port) 670static void atmel_rx_from_dma(struct uart_port *port)
671{ 671{
672 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); 672 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
673 struct tty_struct *tty = port->info->port.tty; 673 struct tty_struct *tty = port->state->port.tty;
674 struct atmel_dma_buffer *pdc; 674 struct atmel_dma_buffer *pdc;
675 int rx_idx = atmel_port->pdc_rx_idx; 675 int rx_idx = atmel_port->pdc_rx_idx;
676 unsigned int head; 676 unsigned int head;
@@ -776,7 +776,7 @@ static void atmel_tasklet_func(unsigned long data)
776 if (status_change & ATMEL_US_CTS) 776 if (status_change & ATMEL_US_CTS)
777 uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); 777 uart_handle_cts_change(port, !(status & ATMEL_US_CTS));
778 778
779 wake_up_interruptible(&port->info->delta_msr_wait); 779 wake_up_interruptible(&port->state->port.delta_msr_wait);
780 780
781 atmel_port->irq_status_prev = status; 781 atmel_port->irq_status_prev = status;
782 } 782 }
@@ -795,7 +795,7 @@ static void atmel_tasklet_func(unsigned long data)
795static int atmel_startup(struct uart_port *port) 795static int atmel_startup(struct uart_port *port)
796{ 796{
797 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); 797 struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
798 struct tty_struct *tty = port->info->port.tty; 798 struct tty_struct *tty = port->state->port.tty;
799 int retval; 799 int retval;
800 800
801 /* 801 /*
@@ -854,7 +854,7 @@ static int atmel_startup(struct uart_port *port)
854 } 854 }
855 if (atmel_use_dma_tx(port)) { 855 if (atmel_use_dma_tx(port)) {
856 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx; 856 struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
857 struct circ_buf *xmit = &port->info->xmit; 857 struct circ_buf *xmit = &port->state->xmit;
858 858
859 pdc->buf = xmit->buf; 859 pdc->buf = xmit->buf;
860 pdc->dma_addr = dma_map_single(port->dev, 860 pdc->dma_addr = dma_map_single(port->dev,
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index b4a7650af696..50abb7e557f4 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -42,6 +42,10 @@
42# undef CONFIG_EARLY_PRINTK 42# undef CONFIG_EARLY_PRINTK
43#endif 43#endif
44 44
45#ifdef CONFIG_SERIAL_BFIN_MODULE
46# undef CONFIG_EARLY_PRINTK
47#endif
48
45/* UART name and device definitions */ 49/* UART name and device definitions */
46#define BFIN_SERIAL_NAME "ttyBF" 50#define BFIN_SERIAL_NAME "ttyBF"
47#define BFIN_SERIAL_MAJOR 204 51#define BFIN_SERIAL_MAJOR 204
@@ -140,7 +144,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
140{ 144{
141 struct bfin_serial_port *uart = (struct bfin_serial_port *)port; 145 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
142#ifdef CONFIG_SERIAL_BFIN_DMA 146#ifdef CONFIG_SERIAL_BFIN_DMA
143 struct circ_buf *xmit = &uart->port.info->xmit; 147 struct circ_buf *xmit = &uart->port.state->xmit;
144#endif 148#endif
145 149
146 while (!(UART_GET_LSR(uart) & TEMT)) 150 while (!(UART_GET_LSR(uart) & TEMT))
@@ -167,7 +171,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
167static void bfin_serial_start_tx(struct uart_port *port) 171static void bfin_serial_start_tx(struct uart_port *port)
168{ 172{
169 struct bfin_serial_port *uart = (struct bfin_serial_port *)port; 173 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
170 struct tty_struct *tty = uart->port.info->port.tty; 174 struct tty_struct *tty = uart->port.state->port.tty;
171 175
172#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS 176#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
173 if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { 177 if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
@@ -239,10 +243,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
239 return; 243 return;
240 } 244 }
241 245
242 if (!uart->port.info || !uart->port.info->port.tty) 246 if (!uart->port.state || !uart->port.state->port.tty)
243 return; 247 return;
244#endif 248#endif
245 tty = uart->port.info->port.tty; 249 tty = uart->port.state->port.tty;
246 250
247 if (ANOMALY_05000363) { 251 if (ANOMALY_05000363) {
248 /* The BF533 (and BF561) family of processors have a nice anomaly 252 /* The BF533 (and BF561) family of processors have a nice anomaly
@@ -327,7 +331,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
327 331
328static void bfin_serial_tx_chars(struct bfin_serial_port *uart) 332static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
329{ 333{
330 struct circ_buf *xmit = &uart->port.info->xmit; 334 struct circ_buf *xmit = &uart->port.state->xmit;
331 335
332 if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { 336 if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
333#ifdef CONFIG_BF54x 337#ifdef CONFIG_BF54x
@@ -394,7 +398,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
394#ifdef CONFIG_SERIAL_BFIN_DMA 398#ifdef CONFIG_SERIAL_BFIN_DMA
395static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) 399static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
396{ 400{
397 struct circ_buf *xmit = &uart->port.info->xmit; 401 struct circ_buf *xmit = &uart->port.state->xmit;
398 402
399 uart->tx_done = 0; 403 uart->tx_done = 0;
400 404
@@ -432,7 +436,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
432 436
433static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) 437static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
434{ 438{
435 struct tty_struct *tty = uart->port.info->port.tty; 439 struct tty_struct *tty = uart->port.state->port.tty;
436 int i, flg, status; 440 int i, flg, status;
437 441
438 status = UART_GET_LSR(uart); 442 status = UART_GET_LSR(uart);
@@ -525,7 +529,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
525static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) 529static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
526{ 530{
527 struct bfin_serial_port *uart = dev_id; 531 struct bfin_serial_port *uart = dev_id;
528 struct circ_buf *xmit = &uart->port.info->xmit; 532 struct circ_buf *xmit = &uart->port.state->xmit;
529 533
530#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS 534#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
531 if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { 535 if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
@@ -961,10 +965,10 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
961 int line = port->line; 965 int line = port->line;
962 unsigned short val; 966 unsigned short val;
963 967
964 if (line >= port->info->port.tty->driver->num) 968 if (line >= port->state->port.tty->driver->num)
965 return; 969 return;
966 970
967 switch (port->info->port.tty->termios->c_line) { 971 switch (port->state->port.tty->termios->c_line) {
968 case N_IRDA: 972 case N_IRDA:
969 val = UART_GET_GCTL(&bfin_serial_ports[line]); 973 val = UART_GET_GCTL(&bfin_serial_ports[line]);
970 val |= (IREN | RPOLC); 974 val |= (IREN | RPOLC);
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index c108b1a0ce98..088bb35475f1 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -178,7 +178,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
178static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) 178static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
179{ 179{
180 struct sport_uart_port *up = dev_id; 180 struct sport_uart_port *up = dev_id;
181 struct tty_struct *tty = up->port.info->port.tty; 181 struct tty_struct *tty = up->port.state->port.tty;
182 unsigned int ch; 182 unsigned int ch;
183 183
184 do { 184 do {
@@ -205,7 +205,7 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
205static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) 205static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
206{ 206{
207 struct sport_uart_port *up = dev_id; 207 struct sport_uart_port *up = dev_id;
208 struct tty_struct *tty = up->port.info->port.tty; 208 struct tty_struct *tty = up->port.state->port.tty;
209 unsigned int stat = SPORT_GET_STAT(up); 209 unsigned int stat = SPORT_GET_STAT(up);
210 210
211 /* Overflow in RX FIFO */ 211 /* Overflow in RX FIFO */
@@ -290,7 +290,7 @@ fail1:
290 290
291static void sport_uart_tx_chars(struct sport_uart_port *up) 291static void sport_uart_tx_chars(struct sport_uart_port *up)
292{ 292{
293 struct circ_buf *xmit = &up->port.info->xmit; 293 struct circ_buf *xmit = &up->port.state->xmit;
294 294
295 if (SPORT_GET_STAT(up) & TXF) 295 if (SPORT_GET_STAT(up) & TXF)
296 return; 296 return;
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 80e76426131d..b6acd19b458e 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -93,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
93static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) 93static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
94{ 94{
95 struct uart_port *port = dev_id; 95 struct uart_port *port = dev_id;
96 struct tty_struct *tty = port->info->port.tty; 96 struct tty_struct *tty = port->state->port.tty;
97 unsigned int status, ch, flg; 97 unsigned int status, ch, flg;
98 98
99 status = clps_readl(SYSFLG(port)); 99 status = clps_readl(SYSFLG(port));
@@ -147,7 +147,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
147static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) 147static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
148{ 148{
149 struct uart_port *port = dev_id; 149 struct uart_port *port = dev_id;
150 struct circ_buf *xmit = &port->info->xmit; 150 struct circ_buf *xmit = &port->state->xmit;
151 int count; 151 int count;
152 152
153 if (port->x_char) { 153 if (port->x_char) {
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index f8df0681e160..8d349b23249a 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -244,7 +244,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
244 int i; 244 int i;
245 unsigned char ch; 245 unsigned char ch;
246 u8 *cp; 246 u8 *cp;
247 struct tty_struct *tty = port->info->port.tty; 247 struct tty_struct *tty = port->state->port.tty;
248 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 248 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
249 cbd_t __iomem *bdp; 249 cbd_t __iomem *bdp;
250 u16 status; 250 u16 status;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 6042b87797a1..57421d776329 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
197 while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { 197 while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
198 dport = &mux->dport[LINE(status)]; 198 dport = &mux->dport[LINE(status)];
199 uport = &dport->port; 199 uport = &dport->port;
200 tty = uport->info->port.tty; /* point to the proper dev */ 200 tty = uport->state->port.tty; /* point to the proper dev */
201 201
202 ch = UCHAR(status); /* grab the char */ 202 ch = UCHAR(status); /* grab the char */
203 flag = TTY_NORMAL; 203 flag = TTY_NORMAL;
@@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
249 } 249 }
250 for (i = 0; i < DZ_NB_PORT; i++) 250 for (i = 0; i < DZ_NB_PORT; i++)
251 if (lines_rx[i]) 251 if (lines_rx[i])
252 tty_flip_buffer_push(mux->dport[i].port.info->port.tty); 252 tty_flip_buffer_push(mux->dport[i].port.state->port.tty);
253} 253}
254 254
255/* 255/*
@@ -268,7 +268,7 @@ static inline void dz_transmit_chars(struct dz_mux *mux)
268 268
269 status = dz_in(dport, DZ_CSR); 269 status = dz_in(dport, DZ_CSR);
270 dport = &mux->dport[LINE(status)]; 270 dport = &mux->dport[LINE(status)];
271 xmit = &dport->port.info->xmit; 271 xmit = &dport->port.state->xmit;
272 272
273 if (dport->port.x_char) { /* XON/XOFF chars */ 273 if (dport->port.x_char) { /* XON/XOFF chars */
274 dz_out(dport, DZ_TDR, dport->port.x_char); 274 dz_out(dport, DZ_TDR, dport->port.x_char);
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index cd1b6a45bb82..2d7feecaf492 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -617,7 +617,7 @@ static void shutdown(struct icom_port *icom_port)
617 * disable break condition 617 * disable break condition
618 */ 618 */
619 cmdReg = readb(&icom_port->dram->CmdReg); 619 cmdReg = readb(&icom_port->dram->CmdReg);
620 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) { 620 if (cmdReg & CMD_SND_BREAK) {
621 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); 621 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
622 } 622 }
623} 623}
@@ -627,7 +627,7 @@ static int icom_write(struct uart_port *port)
627 unsigned long data_count; 627 unsigned long data_count;
628 unsigned char cmdReg; 628 unsigned char cmdReg;
629 unsigned long offset; 629 unsigned long offset;
630 int temp_tail = port->info->xmit.tail; 630 int temp_tail = port->state->xmit.tail;
631 631
632 trace(ICOM_PORT, "WRITE", 0); 632 trace(ICOM_PORT, "WRITE", 0);
633 633
@@ -638,11 +638,11 @@ static int icom_write(struct uart_port *port)
638 } 638 }
639 639
640 data_count = 0; 640 data_count = 0;
641 while ((port->info->xmit.head != temp_tail) && 641 while ((port->state->xmit.head != temp_tail) &&
642 (data_count <= XMIT_BUFF_SZ)) { 642 (data_count <= XMIT_BUFF_SZ)) {
643 643
644 ICOM_PORT->xmit_buf[data_count++] = 644 ICOM_PORT->xmit_buf[data_count++] =
645 port->info->xmit.buf[temp_tail]; 645 port->state->xmit.buf[temp_tail];
646 646
647 temp_tail++; 647 temp_tail++;
648 temp_tail &= (UART_XMIT_SIZE - 1); 648 temp_tail &= (UART_XMIT_SIZE - 1);
@@ -694,8 +694,8 @@ static inline void check_modem_status(struct icom_port *icom_port)
694 uart_handle_cts_change(&icom_port->uart_port, 694 uart_handle_cts_change(&icom_port->uart_port,
695 delta_status & ICOM_CTS); 695 delta_status & ICOM_CTS);
696 696
697 wake_up_interruptible(&icom_port->uart_port.info-> 697 wake_up_interruptible(&icom_port->uart_port.state->
698 delta_msr_wait); 698 port.delta_msr_wait);
699 old_status = status; 699 old_status = status;
700 } 700 }
701 spin_unlock(&icom_port->uart_port.lock); 701 spin_unlock(&icom_port->uart_port.lock);
@@ -718,10 +718,10 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
718 icom_port->uart_port.icount.tx += count; 718 icom_port->uart_port.icount.tx += count;
719 719
720 for (i=0; i<count && 720 for (i=0; i<count &&
721 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) { 721 !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
722 722
723 icom_port->uart_port.info->xmit.tail++; 723 icom_port->uart_port.state->xmit.tail++;
724 icom_port->uart_port.info->xmit.tail &= 724 icom_port->uart_port.state->xmit.tail &=
725 (UART_XMIT_SIZE - 1); 725 (UART_XMIT_SIZE - 1);
726 } 726 }
727 727
@@ -735,7 +735,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
735static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) 735static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
736{ 736{
737 short int count, rcv_buff; 737 short int count, rcv_buff;
738 struct tty_struct *tty = icom_port->uart_port.info->port.tty; 738 struct tty_struct *tty = icom_port->uart_port.state->port.tty;
739 unsigned short int status; 739 unsigned short int status;
740 struct uart_icount *icount; 740 struct uart_icount *icount;
741 unsigned long offset; 741 unsigned long offset;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 7485afd0df4c..18130f11238e 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -224,7 +224,7 @@ static void imx_mctrl_check(struct imx_port *sport)
224 if (changed & TIOCM_CTS) 224 if (changed & TIOCM_CTS)
225 uart_handle_cts_change(&sport->port, status & TIOCM_CTS); 225 uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
226 226
227 wake_up_interruptible(&sport->port.info->delta_msr_wait); 227 wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
228} 228}
229 229
230/* 230/*
@@ -236,7 +236,7 @@ static void imx_timeout(unsigned long data)
236 struct imx_port *sport = (struct imx_port *)data; 236 struct imx_port *sport = (struct imx_port *)data;
237 unsigned long flags; 237 unsigned long flags;
238 238
239 if (sport->port.info) { 239 if (sport->port.state) {
240 spin_lock_irqsave(&sport->port.lock, flags); 240 spin_lock_irqsave(&sport->port.lock, flags);
241 imx_mctrl_check(sport); 241 imx_mctrl_check(sport);
242 spin_unlock_irqrestore(&sport->port.lock, flags); 242 spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -323,7 +323,7 @@ static void imx_enable_ms(struct uart_port *port)
323 323
324static inline void imx_transmit_buffer(struct imx_port *sport) 324static inline void imx_transmit_buffer(struct imx_port *sport)
325{ 325{
326 struct circ_buf *xmit = &sport->port.info->xmit; 326 struct circ_buf *xmit = &sport->port.state->xmit;
327 327
328 while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) { 328 while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
329 /* send xmit->buf[xmit->tail] 329 /* send xmit->buf[xmit->tail]
@@ -388,7 +388,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id)
388 388
389 writel(USR1_RTSD, sport->port.membase + USR1); 389 writel(USR1_RTSD, sport->port.membase + USR1);
390 uart_handle_cts_change(&sport->port, !!val); 390 uart_handle_cts_change(&sport->port, !!val);
391 wake_up_interruptible(&sport->port.info->delta_msr_wait); 391 wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
392 392
393 spin_unlock_irqrestore(&sport->port.lock, flags); 393 spin_unlock_irqrestore(&sport->port.lock, flags);
394 return IRQ_HANDLED; 394 return IRQ_HANDLED;
@@ -397,7 +397,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id)
397static irqreturn_t imx_txint(int irq, void *dev_id) 397static irqreturn_t imx_txint(int irq, void *dev_id)
398{ 398{
399 struct imx_port *sport = dev_id; 399 struct imx_port *sport = dev_id;
400 struct circ_buf *xmit = &sport->port.info->xmit; 400 struct circ_buf *xmit = &sport->port.state->xmit;
401 unsigned long flags; 401 unsigned long flags;
402 402
403 spin_lock_irqsave(&sport->port.lock,flags); 403 spin_lock_irqsave(&sport->port.lock,flags);
@@ -427,7 +427,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
427{ 427{
428 struct imx_port *sport = dev_id; 428 struct imx_port *sport = dev_id;
429 unsigned int rx,flg,ignored = 0; 429 unsigned int rx,flg,ignored = 0;
430 struct tty_struct *tty = sport->port.info->port.tty; 430 struct tty_struct *tty = sport->port.state->port.tty;
431 unsigned long flags, temp; 431 unsigned long flags, temp;
432 432
433 spin_lock_irqsave(&sport->port.lock,flags); 433 spin_lock_irqsave(&sport->port.lock,flags);
@@ -900,11 +900,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
900 rational_best_approximation(16 * div * baud, sport->port.uartclk, 900 rational_best_approximation(16 * div * baud, sport->port.uartclk,
901 1 << 16, 1 << 16, &num, &denom); 901 1 << 16, 1 << 16, &num, &denom);
902 902
903 if (port->info && port->info->port.tty) { 903 if (port->state && port->state->port.tty) {
904 tdiv64 = sport->port.uartclk; 904 tdiv64 = sport->port.uartclk;
905 tdiv64 *= num; 905 tdiv64 *= num;
906 do_div(tdiv64, denom * 16 * div); 906 do_div(tdiv64, denom * 16 * div);
907 tty_encode_baud_rate(sport->port.info->port.tty, 907 tty_encode_baud_rate(sport->port.state->port.tty,
908 (speed_t)tdiv64, (speed_t)tdiv64); 908 (speed_t)tdiv64, (speed_t)tdiv64);
909 } 909 }
910 910
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index ae3699d77dd0..d8983dd5c4b2 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -897,25 +897,25 @@ static void transmit_chars(struct uart_port *the_port)
897 char *start; 897 char *start;
898 struct tty_struct *tty; 898 struct tty_struct *tty;
899 struct ioc3_port *port = get_ioc3_port(the_port); 899 struct ioc3_port *port = get_ioc3_port(the_port);
900 struct uart_info *info; 900 struct uart_state *state;
901 901
902 if (!the_port) 902 if (!the_port)
903 return; 903 return;
904 if (!port) 904 if (!port)
905 return; 905 return;
906 906
907 info = the_port->info; 907 state = the_port->state;
908 tty = info->port.tty; 908 tty = state->port.tty;
909 909
910 if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) { 910 if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
911 /* Nothing to do or hw stopped */ 911 /* Nothing to do or hw stopped */
912 set_notification(port, N_ALL_OUTPUT, 0); 912 set_notification(port, N_ALL_OUTPUT, 0);
913 return; 913 return;
914 } 914 }
915 915
916 head = info->xmit.head; 916 head = state->xmit.head;
917 tail = info->xmit.tail; 917 tail = state->xmit.tail;
918 start = (char *)&info->xmit.buf[tail]; 918 start = (char *)&state->xmit.buf[tail];
919 919
920 /* write out all the data or until the end of the buffer */ 920 /* write out all the data or until the end of the buffer */
921 xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); 921 xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
@@ -928,14 +928,14 @@ static void transmit_chars(struct uart_port *the_port)
928 /* advance the pointers */ 928 /* advance the pointers */
929 tail += result; 929 tail += result;
930 tail &= UART_XMIT_SIZE - 1; 930 tail &= UART_XMIT_SIZE - 1;
931 info->xmit.tail = tail; 931 state->xmit.tail = tail;
932 start = (char *)&info->xmit.buf[tail]; 932 start = (char *)&state->xmit.buf[tail];
933 } 933 }
934 } 934 }
935 if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS) 935 if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
936 uart_write_wakeup(the_port); 936 uart_write_wakeup(the_port);
937 937
938 if (uart_circ_empty(&info->xmit)) { 938 if (uart_circ_empty(&state->xmit)) {
939 set_notification(port, N_OUTPUT_LOWAT, 0); 939 set_notification(port, N_OUTPUT_LOWAT, 0);
940 } else { 940 } else {
941 set_notification(port, N_OUTPUT_LOWAT, 1); 941 set_notification(port, N_OUTPUT_LOWAT, 1);
@@ -956,7 +956,7 @@ ioc3_change_speed(struct uart_port *the_port,
956 unsigned int cflag; 956 unsigned int cflag;
957 int baud; 957 int baud;
958 int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; 958 int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
959 struct uart_info *info = the_port->info; 959 struct uart_state *state = the_port->state;
960 960
961 cflag = new_termios->c_cflag; 961 cflag = new_termios->c_cflag;
962 962
@@ -997,14 +997,14 @@ ioc3_change_speed(struct uart_port *the_port,
997 997
998 the_port->ignore_status_mask = N_ALL_INPUT; 998 the_port->ignore_status_mask = N_ALL_INPUT;
999 999
1000 info->port.tty->low_latency = 1; 1000 state->port.tty->low_latency = 1;
1001 1001
1002 if (I_IGNPAR(info->port.tty)) 1002 if (I_IGNPAR(state->port.tty))
1003 the_port->ignore_status_mask &= ~(N_PARITY_ERROR 1003 the_port->ignore_status_mask &= ~(N_PARITY_ERROR
1004 | N_FRAMING_ERROR); 1004 | N_FRAMING_ERROR);
1005 if (I_IGNBRK(info->port.tty)) { 1005 if (I_IGNBRK(state->port.tty)) {
1006 the_port->ignore_status_mask &= ~N_BREAK; 1006 the_port->ignore_status_mask &= ~N_BREAK;
1007 if (I_IGNPAR(info->port.tty)) 1007 if (I_IGNPAR(state->port.tty))
1008 the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; 1008 the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
1009 } 1009 }
1010 if (!(cflag & CREAD)) { 1010 if (!(cflag & CREAD)) {
@@ -1286,8 +1286,8 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len)
1286 uart_handle_dcd_change 1286 uart_handle_dcd_change
1287 (port->ip_port, 0); 1287 (port->ip_port, 0);
1288 wake_up_interruptible 1288 wake_up_interruptible
1289 (&the_port->info-> 1289 (&the_port->state->
1290 delta_msr_wait); 1290 port.delta_msr_wait);
1291 } 1291 }
1292 1292
1293 /* If we had any data to return, we 1293 /* If we had any data to return, we
@@ -1392,21 +1392,21 @@ static int receive_chars(struct uart_port *the_port)
1392 struct tty_struct *tty; 1392 struct tty_struct *tty;
1393 unsigned char ch[MAX_CHARS]; 1393 unsigned char ch[MAX_CHARS];
1394 int read_count = 0, read_room, flip = 0; 1394 int read_count = 0, read_room, flip = 0;
1395 struct uart_info *info = the_port->info; 1395 struct uart_state *state = the_port->state;
1396 struct ioc3_port *port = get_ioc3_port(the_port); 1396 struct ioc3_port *port = get_ioc3_port(the_port);
1397 unsigned long pflags; 1397 unsigned long pflags;
1398 1398
1399 /* Make sure all the pointers are "good" ones */ 1399 /* Make sure all the pointers are "good" ones */
1400 if (!info) 1400 if (!state)
1401 return 0; 1401 return 0;
1402 if (!info->port.tty) 1402 if (!state->port.tty)
1403 return 0; 1403 return 0;
1404 1404
1405 if (!(port->ip_flags & INPUT_ENABLE)) 1405 if (!(port->ip_flags & INPUT_ENABLE))
1406 return 0; 1406 return 0;
1407 1407
1408 spin_lock_irqsave(&the_port->lock, pflags); 1408 spin_lock_irqsave(&the_port->lock, pflags);
1409 tty = info->port.tty; 1409 tty = state->port.tty;
1410 1410
1411 read_count = do_read(the_port, ch, MAX_CHARS); 1411 read_count = do_read(the_port, ch, MAX_CHARS);
1412 if (read_count > 0) { 1412 if (read_count > 0) {
@@ -1491,7 +1491,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is,
1491 uart_handle_dcd_change(the_port, 1491 uart_handle_dcd_change(the_port,
1492 shadow & SHADOW_DCD); 1492 shadow & SHADOW_DCD);
1493 wake_up_interruptible 1493 wake_up_interruptible
1494 (&the_port->info->delta_msr_wait); 1494 (&the_port->state->port.delta_msr_wait);
1495 } else if ((port->ip_notify & N_DDCD) 1495 } else if ((port->ip_notify & N_DDCD)
1496 && !(shadow & SHADOW_DCD)) { 1496 && !(shadow & SHADOW_DCD)) {
1497 /* Flag delta DCD/no DCD */ 1497 /* Flag delta DCD/no DCD */
@@ -1511,7 +1511,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is,
1511 uart_handle_cts_change(the_port, shadow 1511 uart_handle_cts_change(the_port, shadow
1512 & SHADOW_CTS); 1512 & SHADOW_CTS);
1513 wake_up_interruptible 1513 wake_up_interruptible
1514 (&the_port->info->delta_msr_wait); 1514 (&the_port->state->port.delta_msr_wait);
1515 } 1515 }
1516 } 1516 }
1517 1517
@@ -1721,14 +1721,14 @@ static void ic3_shutdown(struct uart_port *the_port)
1721{ 1721{
1722 unsigned long port_flags; 1722 unsigned long port_flags;
1723 struct ioc3_port *port; 1723 struct ioc3_port *port;
1724 struct uart_info *info; 1724 struct uart_state *state;
1725 1725
1726 port = get_ioc3_port(the_port); 1726 port = get_ioc3_port(the_port);
1727 if (!port) 1727 if (!port)
1728 return; 1728 return;
1729 1729
1730 info = the_port->info; 1730 state = the_port->state;
1731 wake_up_interruptible(&info->delta_msr_wait); 1731 wake_up_interruptible(&state->port.delta_msr_wait);
1732 1732
1733 spin_lock_irqsave(&the_port->lock, port_flags); 1733 spin_lock_irqsave(&the_port->lock, port_flags);
1734 set_notification(port, N_ALL, 0); 1734 set_notification(port, N_ALL, 0);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index e5c58fe7e745..2e02c3026d24 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -1627,25 +1627,25 @@ static void transmit_chars(struct uart_port *the_port)
1627 char *start; 1627 char *start;
1628 struct tty_struct *tty; 1628 struct tty_struct *tty;
1629 struct ioc4_port *port = get_ioc4_port(the_port, 0); 1629 struct ioc4_port *port = get_ioc4_port(the_port, 0);
1630 struct uart_info *info; 1630 struct uart_state *state;
1631 1631
1632 if (!the_port) 1632 if (!the_port)
1633 return; 1633 return;
1634 if (!port) 1634 if (!port)
1635 return; 1635 return;
1636 1636
1637 info = the_port->info; 1637 state = the_port->state;
1638 tty = info->port.tty; 1638 tty = state->port.tty;
1639 1639
1640 if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) { 1640 if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
1641 /* Nothing to do or hw stopped */ 1641 /* Nothing to do or hw stopped */
1642 set_notification(port, N_ALL_OUTPUT, 0); 1642 set_notification(port, N_ALL_OUTPUT, 0);
1643 return; 1643 return;
1644 } 1644 }
1645 1645
1646 head = info->xmit.head; 1646 head = state->xmit.head;
1647 tail = info->xmit.tail; 1647 tail = state->xmit.tail;
1648 start = (char *)&info->xmit.buf[tail]; 1648 start = (char *)&state->xmit.buf[tail];
1649 1649
1650 /* write out all the data or until the end of the buffer */ 1650 /* write out all the data or until the end of the buffer */
1651 xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail); 1651 xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
@@ -1658,14 +1658,14 @@ static void transmit_chars(struct uart_port *the_port)
1658 /* advance the pointers */ 1658 /* advance the pointers */
1659 tail += result; 1659 tail += result;
1660 tail &= UART_XMIT_SIZE - 1; 1660 tail &= UART_XMIT_SIZE - 1;
1661 info->xmit.tail = tail; 1661 state->xmit.tail = tail;
1662 start = (char *)&info->xmit.buf[tail]; 1662 start = (char *)&state->xmit.buf[tail];
1663 } 1663 }
1664 } 1664 }
1665 if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS) 1665 if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
1666 uart_write_wakeup(the_port); 1666 uart_write_wakeup(the_port);
1667 1667
1668 if (uart_circ_empty(&info->xmit)) { 1668 if (uart_circ_empty(&state->xmit)) {
1669 set_notification(port, N_OUTPUT_LOWAT, 0); 1669 set_notification(port, N_OUTPUT_LOWAT, 0);
1670 } else { 1670 } else {
1671 set_notification(port, N_OUTPUT_LOWAT, 1); 1671 set_notification(port, N_OUTPUT_LOWAT, 1);
@@ -1686,7 +1686,7 @@ ioc4_change_speed(struct uart_port *the_port,
1686 int baud, bits; 1686 int baud, bits;
1687 unsigned cflag; 1687 unsigned cflag;
1688 int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; 1688 int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
1689 struct uart_info *info = the_port->info; 1689 struct uart_state *state = the_port->state;
1690 1690
1691 cflag = new_termios->c_cflag; 1691 cflag = new_termios->c_cflag;
1692 1692
@@ -1738,14 +1738,14 @@ ioc4_change_speed(struct uart_port *the_port,
1738 1738
1739 the_port->ignore_status_mask = N_ALL_INPUT; 1739 the_port->ignore_status_mask = N_ALL_INPUT;
1740 1740
1741 info->port.tty->low_latency = 1; 1741 state->port.tty->low_latency = 1;
1742 1742
1743 if (I_IGNPAR(info->port.tty)) 1743 if (I_IGNPAR(state->port.tty))
1744 the_port->ignore_status_mask &= ~(N_PARITY_ERROR 1744 the_port->ignore_status_mask &= ~(N_PARITY_ERROR
1745 | N_FRAMING_ERROR); 1745 | N_FRAMING_ERROR);
1746 if (I_IGNBRK(info->port.tty)) { 1746 if (I_IGNBRK(state->port.tty)) {
1747 the_port->ignore_status_mask &= ~N_BREAK; 1747 the_port->ignore_status_mask &= ~N_BREAK;
1748 if (I_IGNPAR(info->port.tty)) 1748 if (I_IGNPAR(state->port.tty))
1749 the_port->ignore_status_mask &= ~N_OVERRUN_ERROR; 1749 the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
1750 } 1750 }
1751 if (!(cflag & CREAD)) { 1751 if (!(cflag & CREAD)) {
@@ -1784,7 +1784,7 @@ ioc4_change_speed(struct uart_port *the_port,
1784static inline int ic4_startup_local(struct uart_port *the_port) 1784static inline int ic4_startup_local(struct uart_port *the_port)
1785{ 1785{
1786 struct ioc4_port *port; 1786 struct ioc4_port *port;
1787 struct uart_info *info; 1787 struct uart_state *state;
1788 1788
1789 if (!the_port) 1789 if (!the_port)
1790 return -1; 1790 return -1;
@@ -1793,7 +1793,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
1793 if (!port) 1793 if (!port)
1794 return -1; 1794 return -1;
1795 1795
1796 info = the_port->info; 1796 state = the_port->state;
1797 1797
1798 local_open(port); 1798 local_open(port);
1799 1799
@@ -1801,7 +1801,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
1801 ioc4_set_proto(port, the_port->mapbase); 1801 ioc4_set_proto(port, the_port->mapbase);
1802 1802
1803 /* set the speed of the serial port */ 1803 /* set the speed of the serial port */
1804 ioc4_change_speed(the_port, info->port.tty->termios, 1804 ioc4_change_speed(the_port, state->port.tty->termios,
1805 (struct ktermios *)0); 1805 (struct ktermios *)0);
1806 1806
1807 return 0; 1807 return 0;
@@ -1882,7 +1882,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
1882 the_port = port->ip_port; 1882 the_port = port->ip_port;
1883 the_port->icount.dcd = 1; 1883 the_port->icount.dcd = 1;
1884 wake_up_interruptible 1884 wake_up_interruptible
1885 (&the_port-> info->delta_msr_wait); 1885 (&the_port->state->port.delta_msr_wait);
1886 } else if ((port->ip_notify & N_DDCD) 1886 } else if ((port->ip_notify & N_DDCD)
1887 && !(shadow & IOC4_SHADOW_DCD)) { 1887 && !(shadow & IOC4_SHADOW_DCD)) {
1888 /* Flag delta DCD/no DCD */ 1888 /* Flag delta DCD/no DCD */
@@ -1904,7 +1904,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
1904 the_port->icount.cts = 1904 the_port->icount.cts =
1905 (shadow & IOC4_SHADOW_CTS) ? 1 : 0; 1905 (shadow & IOC4_SHADOW_CTS) ? 1 : 0;
1906 wake_up_interruptible 1906 wake_up_interruptible
1907 (&the_port->info->delta_msr_wait); 1907 (&the_port->state->port.delta_msr_wait);
1908 } 1908 }
1909 } 1909 }
1910 1910
@@ -2236,8 +2236,8 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
2236 && port->ip_port) { 2236 && port->ip_port) {
2237 the_port->icount.dcd = 0; 2237 the_port->icount.dcd = 0;
2238 wake_up_interruptible 2238 wake_up_interruptible
2239 (&the_port->info-> 2239 (&the_port->state->
2240 delta_msr_wait); 2240 port.delta_msr_wait);
2241 } 2241 }
2242 2242
2243 /* If we had any data to return, we 2243 /* If we had any data to return, we
@@ -2341,17 +2341,17 @@ static void receive_chars(struct uart_port *the_port)
2341 unsigned char ch[IOC4_MAX_CHARS]; 2341 unsigned char ch[IOC4_MAX_CHARS];
2342 int read_count, request_count = IOC4_MAX_CHARS; 2342 int read_count, request_count = IOC4_MAX_CHARS;
2343 struct uart_icount *icount; 2343 struct uart_icount *icount;
2344 struct uart_info *info = the_port->info; 2344 struct uart_state *state = the_port->state;
2345 unsigned long pflags; 2345 unsigned long pflags;
2346 2346
2347 /* Make sure all the pointers are "good" ones */ 2347 /* Make sure all the pointers are "good" ones */
2348 if (!info) 2348 if (!state)
2349 return; 2349 return;
2350 if (!info->port.tty) 2350 if (!state->port.tty)
2351 return; 2351 return;
2352 2352
2353 spin_lock_irqsave(&the_port->lock, pflags); 2353 spin_lock_irqsave(&the_port->lock, pflags);
2354 tty = info->port.tty; 2354 tty = state->port.tty;
2355 2355
2356 request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); 2356 request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
2357 2357
@@ -2430,19 +2430,19 @@ static void ic4_shutdown(struct uart_port *the_port)
2430{ 2430{
2431 unsigned long port_flags; 2431 unsigned long port_flags;
2432 struct ioc4_port *port; 2432 struct ioc4_port *port;
2433 struct uart_info *info; 2433 struct uart_state *state;
2434 2434
2435 port = get_ioc4_port(the_port, 0); 2435 port = get_ioc4_port(the_port, 0);
2436 if (!port) 2436 if (!port)
2437 return; 2437 return;
2438 2438
2439 info = the_port->info; 2439 state = the_port->state;
2440 port->ip_port = NULL; 2440 port->ip_port = NULL;
2441 2441
2442 wake_up_interruptible(&info->delta_msr_wait); 2442 wake_up_interruptible(&state->port.delta_msr_wait);
2443 2443
2444 if (info->port.tty) 2444 if (state->port.tty)
2445 set_bit(TTY_IO_ERROR, &info->port.tty->flags); 2445 set_bit(TTY_IO_ERROR, &state->port.tty->flags);
2446 2446
2447 spin_lock_irqsave(&the_port->lock, port_flags); 2447 spin_lock_irqsave(&the_port->lock, port_flags);
2448 set_notification(port, N_ALL, 0); 2448 set_notification(port, N_ALL, 0);
@@ -2538,7 +2538,7 @@ static int ic4_startup(struct uart_port *the_port)
2538 int retval; 2538 int retval;
2539 struct ioc4_port *port; 2539 struct ioc4_port *port;
2540 struct ioc4_control *control; 2540 struct ioc4_control *control;
2541 struct uart_info *info; 2541 struct uart_state *state;
2542 unsigned long port_flags; 2542 unsigned long port_flags;
2543 2543
2544 if (!the_port) 2544 if (!the_port)
@@ -2546,7 +2546,7 @@ static int ic4_startup(struct uart_port *the_port)
2546 port = get_ioc4_port(the_port, 1); 2546 port = get_ioc4_port(the_port, 1);
2547 if (!port) 2547 if (!port)
2548 return -ENODEV; 2548 return -ENODEV;
2549 info = the_port->info; 2549 state = the_port->state;
2550 2550
2551 control = port->ip_control; 2551 control = port->ip_control;
2552 if (!control) { 2552 if (!control) {
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 0d9acbd0bb70..ebff4a1d4bcc 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -256,9 +256,9 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up
256 unsigned int r1; 256 unsigned int r1;
257 257
258 tty = NULL; 258 tty = NULL;
259 if (up->port.info != NULL && 259 if (up->port.state != NULL &&
260 up->port.info->port.tty != NULL) 260 up->port.state->port.tty != NULL)
261 tty = up->port.info->port.tty; 261 tty = up->port.state->port.tty;
262 262
263 for (;;) { 263 for (;;) {
264 ch = readb(&channel->control); 264 ch = readb(&channel->control);
@@ -354,7 +354,7 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
354 uart_handle_cts_change(&up->port, 354 uart_handle_cts_change(&up->port,
355 (status & CTS)); 355 (status & CTS));
356 356
357 wake_up_interruptible(&up->port.info->delta_msr_wait); 357 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
358 } 358 }
359 359
360 up->prev_status = status; 360 up->prev_status = status;
@@ -404,9 +404,9 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
404 return; 404 return;
405 } 405 }
406 406
407 if (up->port.info == NULL) 407 if (up->port.state == NULL)
408 goto ack_tx_int; 408 goto ack_tx_int;
409 xmit = &up->port.info->xmit; 409 xmit = &up->port.state->xmit;
410 if (uart_circ_empty(xmit)) 410 if (uart_circ_empty(xmit))
411 goto ack_tx_int; 411 goto ack_tx_int;
412 if (uart_tx_stopped(&up->port)) 412 if (uart_tx_stopped(&up->port))
@@ -607,7 +607,7 @@ static void ip22zilog_start_tx(struct uart_port *port)
607 port->icount.tx++; 607 port->icount.tx++;
608 port->x_char = 0; 608 port->x_char = 0;
609 } else { 609 } else {
610 struct circ_buf *xmit = &port->info->xmit; 610 struct circ_buf *xmit = &port->state->xmit;
611 611
612 writeb(xmit->buf[xmit->tail], &channel->data); 612 writeb(xmit->buf[xmit->tail], &channel->data);
613 ZSDELAY(); 613 ZSDELAY();
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 9dadaa11d266..b4b124e4828f 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -989,7 +989,7 @@ static void neo_param(struct jsm_channel *ch)
989 { 50, B50 }, 989 { 50, B50 },
990 }; 990 };
991 991
992 cflag = C_BAUD(ch->uart_port.info->port.tty); 992 cflag = C_BAUD(ch->uart_port.state->port.tty);
993 baud = 9600; 993 baud = 9600;
994 for (i = 0; i < ARRAY_SIZE(baud_rates); i++) { 994 for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
995 if (baud_rates[i].cflag == cflag) { 995 if (baud_rates[i].cflag == cflag) {
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 00f4577d2f7f..7439c0373620 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -147,7 +147,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
147 struct ktermios *termios; 147 struct ktermios *termios;
148 148
149 spin_lock_irqsave(&port->lock, lock_flags); 149 spin_lock_irqsave(&port->lock, lock_flags);
150 termios = port->info->port.tty->termios; 150 termios = port->state->port.tty->termios;
151 if (ch == termios->c_cc[VSTART]) 151 if (ch == termios->c_cc[VSTART])
152 channel->ch_bd->bd_ops->send_start_character(channel); 152 channel->ch_bd->bd_ops->send_start_character(channel);
153 153
@@ -245,7 +245,7 @@ static int jsm_tty_open(struct uart_port *port)
245 channel->ch_cached_lsr = 0; 245 channel->ch_cached_lsr = 0;
246 channel->ch_stops_sent = 0; 246 channel->ch_stops_sent = 0;
247 247
248 termios = port->info->port.tty->termios; 248 termios = port->state->port.tty->termios;
249 channel->ch_c_cflag = termios->c_cflag; 249 channel->ch_c_cflag = termios->c_cflag;
250 channel->ch_c_iflag = termios->c_iflag; 250 channel->ch_c_iflag = termios->c_iflag;
251 channel->ch_c_oflag = termios->c_oflag; 251 channel->ch_c_oflag = termios->c_oflag;
@@ -278,7 +278,7 @@ static void jsm_tty_close(struct uart_port *port)
278 jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); 278 jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
279 279
280 bd = channel->ch_bd; 280 bd = channel->ch_bd;
281 ts = port->info->port.tty->termios; 281 ts = port->state->port.tty->termios;
282 282
283 channel->ch_flags &= ~(CH_STOPI); 283 channel->ch_flags &= ~(CH_STOPI);
284 284
@@ -530,7 +530,7 @@ void jsm_input(struct jsm_channel *ch)
530 if (!ch) 530 if (!ch)
531 return; 531 return;
532 532
533 tp = ch->uart_port.info->port.tty; 533 tp = ch->uart_port.state->port.tty;
534 534
535 bd = ch->ch_bd; 535 bd = ch->ch_bd;
536 if(!bd) 536 if(!bd)
@@ -849,7 +849,7 @@ int jsm_tty_write(struct uart_port *port)
849 u16 tail; 849 u16 tail;
850 u16 tmask; 850 u16 tmask;
851 u32 remain; 851 u32 remain;
852 int temp_tail = port->info->xmit.tail; 852 int temp_tail = port->state->xmit.tail;
853 struct jsm_channel *channel = (struct jsm_channel *)port; 853 struct jsm_channel *channel = (struct jsm_channel *)port;
854 854
855 tmask = WQUEUEMASK; 855 tmask = WQUEUEMASK;
@@ -865,10 +865,10 @@ int jsm_tty_write(struct uart_port *port)
865 data_count = 0; 865 data_count = 0;
866 if (bufcount >= remain) { 866 if (bufcount >= remain) {
867 bufcount -= remain; 867 bufcount -= remain;
868 while ((port->info->xmit.head != temp_tail) && 868 while ((port->state->xmit.head != temp_tail) &&
869 (data_count < remain)) { 869 (data_count < remain)) {
870 channel->ch_wqueue[head++] = 870 channel->ch_wqueue[head++] =
871 port->info->xmit.buf[temp_tail]; 871 port->state->xmit.buf[temp_tail];
872 872
873 temp_tail++; 873 temp_tail++;
874 temp_tail &= (UART_XMIT_SIZE - 1); 874 temp_tail &= (UART_XMIT_SIZE - 1);
@@ -880,10 +880,10 @@ int jsm_tty_write(struct uart_port *port)
880 data_count1 = 0; 880 data_count1 = 0;
881 if (bufcount > 0) { 881 if (bufcount > 0) {
882 remain = bufcount; 882 remain = bufcount;
883 while ((port->info->xmit.head != temp_tail) && 883 while ((port->state->xmit.head != temp_tail) &&
884 (data_count1 < remain)) { 884 (data_count1 < remain)) {
885 channel->ch_wqueue[head++] = 885 channel->ch_wqueue[head++] =
886 port->info->xmit.buf[temp_tail]; 886 port->state->xmit.buf[temp_tail];
887 887
888 temp_tail++; 888 temp_tail++;
889 temp_tail &= (UART_XMIT_SIZE - 1); 889 temp_tail &= (UART_XMIT_SIZE - 1);
@@ -892,7 +892,7 @@ int jsm_tty_write(struct uart_port *port)
892 } 892 }
893 } 893 }
894 894
895 port->info->xmit.tail = temp_tail; 895 port->state->xmit.tail = temp_tail;
896 896
897 data_count += data_count1; 897 data_count += data_count1;
898 if (data_count) { 898 if (data_count) {
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 611c97a15654..bea5c215460c 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -286,7 +286,7 @@ static void m32r_sio_start_tx(struct uart_port *port)
286{ 286{
287#ifdef CONFIG_SERIAL_M32R_PLDSIO 287#ifdef CONFIG_SERIAL_M32R_PLDSIO
288 struct uart_sio_port *up = (struct uart_sio_port *)port; 288 struct uart_sio_port *up = (struct uart_sio_port *)port;
289 struct circ_buf *xmit = &up->port.info->xmit; 289 struct circ_buf *xmit = &up->port.state->xmit;
290 290
291 if (!(up->ier & UART_IER_THRI)) { 291 if (!(up->ier & UART_IER_THRI)) {
292 up->ier |= UART_IER_THRI; 292 up->ier |= UART_IER_THRI;
@@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
325 325
326static void receive_chars(struct uart_sio_port *up, int *status) 326static void receive_chars(struct uart_sio_port *up, int *status)
327{ 327{
328 struct tty_struct *tty = up->port.info->port.tty; 328 struct tty_struct *tty = up->port.state->port.tty;
329 unsigned char ch; 329 unsigned char ch;
330 unsigned char flag; 330 unsigned char flag;
331 int max_count = 256; 331 int max_count = 256;
@@ -398,7 +398,7 @@ static void receive_chars(struct uart_sio_port *up, int *status)
398 398
399static void transmit_chars(struct uart_sio_port *up) 399static void transmit_chars(struct uart_sio_port *up)
400{ 400{
401 struct circ_buf *xmit = &up->port.info->xmit; 401 struct circ_buf *xmit = &up->port.state->xmit;
402 int count; 402 int count;
403 403
404 if (up->port.x_char) { 404 if (up->port.x_char) {
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
index 9fd33e5622bd..75ab00631c41 100644
--- a/drivers/serial/max3100.c
+++ b/drivers/serial/max3100.c
@@ -184,7 +184,7 @@ static void max3100_timeout(unsigned long data)
184{ 184{
185 struct max3100_port *s = (struct max3100_port *)data; 185 struct max3100_port *s = (struct max3100_port *)data;
186 186
187 if (s->port.info) { 187 if (s->port.state) {
188 max3100_dowork(s); 188 max3100_dowork(s);
189 mod_timer(&s->timer, jiffies + s->poll_time); 189 mod_timer(&s->timer, jiffies + s->poll_time);
190 } 190 }
@@ -261,7 +261,7 @@ static void max3100_work(struct work_struct *w)
261 int rxchars; 261 int rxchars;
262 u16 tx, rx; 262 u16 tx, rx;
263 int conf, cconf, rts, crts; 263 int conf, cconf, rts, crts;
264 struct circ_buf *xmit = &s->port.info->xmit; 264 struct circ_buf *xmit = &s->port.state->xmit;
265 265
266 dev_dbg(&s->spi->dev, "%s\n", __func__); 266 dev_dbg(&s->spi->dev, "%s\n", __func__);
267 267
@@ -307,8 +307,8 @@ static void max3100_work(struct work_struct *w)
307 } 307 }
308 } 308 }
309 309
310 if (rxchars > 16 && s->port.info->port.tty != NULL) { 310 if (rxchars > 16 && s->port.state->port.tty != NULL) {
311 tty_flip_buffer_push(s->port.info->port.tty); 311 tty_flip_buffer_push(s->port.state->port.tty);
312 rxchars = 0; 312 rxchars = 0;
313 } 313 }
314 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 314 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -320,8 +320,8 @@ static void max3100_work(struct work_struct *w)
320 (!uart_circ_empty(xmit) && 320 (!uart_circ_empty(xmit) &&
321 !uart_tx_stopped(&s->port)))); 321 !uart_tx_stopped(&s->port))));
322 322
323 if (rxchars > 0 && s->port.info->port.tty != NULL) 323 if (rxchars > 0 && s->port.state->port.tty != NULL)
324 tty_flip_buffer_push(s->port.info->port.tty); 324 tty_flip_buffer_push(s->port.state->port.tty);
325} 325}
326 326
327static irqreturn_t max3100_irq(int irqno, void *dev_id) 327static irqreturn_t max3100_irq(int irqno, void *dev_id)
@@ -429,7 +429,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
429 int baud = 0; 429 int baud = 0;
430 unsigned cflag; 430 unsigned cflag;
431 u32 param_new, param_mask, parity = 0; 431 u32 param_new, param_mask, parity = 0;
432 struct tty_struct *tty = s->port.info->port.tty; 432 struct tty_struct *tty = s->port.state->port.tty;
433 433
434 dev_dbg(&s->spi->dev, "%s\n", __func__); 434 dev_dbg(&s->spi->dev, "%s\n", __func__);
435 if (!tty) 435 if (!tty)
@@ -529,7 +529,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
529 MAX3100_STATUS_OE; 529 MAX3100_STATUS_OE;
530 530
531 /* we are sending char from a workqueue so enable */ 531 /* we are sending char from a workqueue so enable */
532 s->port.info->port.tty->low_latency = 1; 532 s->port.state->port.tty->low_latency = 1;
533 533
534 if (s->poll_time > 0) 534 if (s->poll_time > 0)
535 del_timer_sync(&s->timer); 535 del_timer_sync(&s->timer);
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 0eefb07bebaf..b44382442bf1 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -323,7 +323,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
323 uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); 323 uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
324 } 324 }
325 325
326 tty_flip_buffer_push(port->info->port.tty); 326 tty_flip_buffer_push(port->state->port.tty);
327} 327}
328 328
329/****************************************************************************/ 329/****************************************************************************/
@@ -331,7 +331,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
331static void mcf_tx_chars(struct mcf_uart *pp) 331static void mcf_tx_chars(struct mcf_uart *pp)
332{ 332{
333 struct uart_port *port = &pp->port; 333 struct uart_port *port = &pp->port;
334 struct circ_buf *xmit = &port->info->xmit; 334 struct circ_buf *xmit = &port->state->xmit;
335 335
336 if (port->x_char) { 336 if (port->x_char) {
337 /* Send special char - probably flow control */ 337 /* Send special char - probably flow control */
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index abbd146c50d9..d7bcd074d383 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -745,7 +745,7 @@ static struct uart_ops mpc52xx_uart_ops = {
745static inline int 745static inline int
746mpc52xx_uart_int_rx_chars(struct uart_port *port) 746mpc52xx_uart_int_rx_chars(struct uart_port *port)
747{ 747{
748 struct tty_struct *tty = port->info->port.tty; 748 struct tty_struct *tty = port->state->port.tty;
749 unsigned char ch, flag; 749 unsigned char ch, flag;
750 unsigned short status; 750 unsigned short status;
751 751
@@ -812,7 +812,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
812static inline int 812static inline int
813mpc52xx_uart_int_tx_chars(struct uart_port *port) 813mpc52xx_uart_int_tx_chars(struct uart_port *port)
814{ 814{
815 struct circ_buf *xmit = &port->info->xmit; 815 struct circ_buf *xmit = &port->state->xmit;
816 816
817 /* Process out of band chars */ 817 /* Process out of band chars */
818 if (port->x_char) { 818 if (port->x_char) {
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 61d3ade5286c..b5496c28e60b 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -936,7 +936,7 @@ static int serial_polled;
936static int mpsc_rx_intr(struct mpsc_port_info *pi) 936static int mpsc_rx_intr(struct mpsc_port_info *pi)
937{ 937{
938 struct mpsc_rx_desc *rxre; 938 struct mpsc_rx_desc *rxre;
939 struct tty_struct *tty = pi->port.info->port.tty; 939 struct tty_struct *tty = pi->port.state->port.tty;
940 u32 cmdstat, bytes_in, i; 940 u32 cmdstat, bytes_in, i;
941 int rc = 0; 941 int rc = 0;
942 u8 *bp; 942 u8 *bp;
@@ -1109,7 +1109,7 @@ static void mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
1109 1109
1110static void mpsc_copy_tx_data(struct mpsc_port_info *pi) 1110static void mpsc_copy_tx_data(struct mpsc_port_info *pi)
1111{ 1111{
1112 struct circ_buf *xmit = &pi->port.info->xmit; 1112 struct circ_buf *xmit = &pi->port.state->xmit;
1113 u8 *bp; 1113 u8 *bp;
1114 u32 i; 1114 u32 i;
1115 1115
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c
index f7c24baa1416..b05c5aa02cb4 100644
--- a/drivers/serial/msm_serial.c
+++ b/drivers/serial/msm_serial.c
@@ -88,7 +88,7 @@ static void msm_enable_ms(struct uart_port *port)
88 88
89static void handle_rx(struct uart_port *port) 89static void handle_rx(struct uart_port *port)
90{ 90{
91 struct tty_struct *tty = port->info->port.tty; 91 struct tty_struct *tty = port->state->port.tty;
92 unsigned int sr; 92 unsigned int sr;
93 93
94 /* 94 /*
@@ -136,7 +136,7 @@ static void handle_rx(struct uart_port *port)
136 136
137static void handle_tx(struct uart_port *port) 137static void handle_tx(struct uart_port *port)
138{ 138{
139 struct circ_buf *xmit = &port->info->xmit; 139 struct circ_buf *xmit = &port->state->xmit;
140 struct msm_port *msm_port = UART_TO_MSM(port); 140 struct msm_port *msm_port = UART_TO_MSM(port);
141 int sent_tx; 141 int sent_tx;
142 142
@@ -169,7 +169,7 @@ static void handle_delta_cts(struct uart_port *port)
169{ 169{
170 msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR); 170 msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
171 port->icount.cts++; 171 port->icount.cts++;
172 wake_up_interruptible(&port->info->delta_msr_wait); 172 wake_up_interruptible(&port->state->port.delta_msr_wait);
173} 173}
174 174
175static irqreturn_t msm_irq(int irq, void *dev_id) 175static irqreturn_t msm_irq(int irq, void *dev_id)
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 953a5ffa9b44..7571aaa138b0 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -199,7 +199,7 @@ static void mux_break_ctl(struct uart_port *port, int break_state)
199static void mux_write(struct uart_port *port) 199static void mux_write(struct uart_port *port)
200{ 200{
201 int count; 201 int count;
202 struct circ_buf *xmit = &port->info->xmit; 202 struct circ_buf *xmit = &port->state->xmit;
203 203
204 if(port->x_char) { 204 if(port->x_char) {
205 UART_PUT_CHAR(port, port->x_char); 205 UART_PUT_CHAR(port, port->x_char);
@@ -243,7 +243,7 @@ static void mux_write(struct uart_port *port)
243static void mux_read(struct uart_port *port) 243static void mux_read(struct uart_port *port)
244{ 244{
245 int data; 245 int data;
246 struct tty_struct *tty = port->info->port.tty; 246 struct tty_struct *tty = port->state->port.tty;
247 __u32 start_count = port->icount.rx; 247 __u32 start_count = port->icount.rx;
248 248
249 while(1) { 249 while(1) {
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 3e5dda8518b7..7735c9f35fa0 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -140,7 +140,7 @@ static void netx_enable_ms(struct uart_port *port)
140 140
141static inline void netx_transmit_buffer(struct uart_port *port) 141static inline void netx_transmit_buffer(struct uart_port *port)
142{ 142{
143 struct circ_buf *xmit = &port->info->xmit; 143 struct circ_buf *xmit = &port->state->xmit;
144 144
145 if (port->x_char) { 145 if (port->x_char) {
146 writel(port->x_char, port->membase + UART_DR); 146 writel(port->x_char, port->membase + UART_DR);
@@ -185,7 +185,7 @@ static unsigned int netx_tx_empty(struct uart_port *port)
185 185
186static void netx_txint(struct uart_port *port) 186static void netx_txint(struct uart_port *port)
187{ 187{
188 struct circ_buf *xmit = &port->info->xmit; 188 struct circ_buf *xmit = &port->state->xmit;
189 189
190 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 190 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
191 netx_stop_tx(port); 191 netx_stop_tx(port);
@@ -201,7 +201,7 @@ static void netx_txint(struct uart_port *port)
201static void netx_rxint(struct uart_port *port) 201static void netx_rxint(struct uart_port *port)
202{ 202{
203 unsigned char rx, flg, status; 203 unsigned char rx, flg, status;
204 struct tty_struct *tty = port->info->port.tty; 204 struct tty_struct *tty = port->state->port.tty;
205 205
206 while (!(readl(port->membase + UART_FR) & FR_RXFE)) { 206 while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
207 rx = readl(port->membase + UART_DR); 207 rx = readl(port->membase + UART_DR);
diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c
index 9e150b19d726..e1ab8ec0a4a6 100644
--- a/drivers/serial/nwpserial.c
+++ b/drivers/serial/nwpserial.c
@@ -126,7 +126,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags)
126static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) 126static irqreturn_t nwpserial_interrupt(int irq, void *dev_id)
127{ 127{
128 struct nwpserial_port *up = dev_id; 128 struct nwpserial_port *up = dev_id;
129 struct tty_struct *tty = up->port.info->port.tty; 129 struct tty_struct *tty = up->port.state->port.tty;
130 irqreturn_t ret; 130 irqreturn_t ret;
131 unsigned int iir; 131 unsigned int iir;
132 unsigned char ch; 132 unsigned char ch;
@@ -261,7 +261,7 @@ static void nwpserial_start_tx(struct uart_port *port)
261 struct nwpserial_port *up; 261 struct nwpserial_port *up;
262 struct circ_buf *xmit; 262 struct circ_buf *xmit;
263 up = container_of(port, struct nwpserial_port, port); 263 up = container_of(port, struct nwpserial_port, port);
264 xmit = &up->port.info->xmit; 264 xmit = &up->port.state->xmit;
265 265
266 if (port->x_char) { 266 if (port->x_char) {
267 nwpserial_putchar(up, up->port.x_char); 267 nwpserial_putchar(up, up->port.x_char);
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 9c1243fbd512..0700cd10b97c 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -242,12 +242,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
242 } 242 }
243 243
244 /* Sanity check, make sure the old bug is no longer happening */ 244 /* Sanity check, make sure the old bug is no longer happening */
245 if (uap->port.info == NULL || uap->port.info->port.tty == NULL) { 245 if (uap->port.state == NULL || uap->port.state->port.tty == NULL) {
246 WARN_ON(1); 246 WARN_ON(1);
247 (void)read_zsdata(uap); 247 (void)read_zsdata(uap);
248 return NULL; 248 return NULL;
249 } 249 }
250 tty = uap->port.info->port.tty; 250 tty = uap->port.state->port.tty;
251 251
252 while (1) { 252 while (1) {
253 error = 0; 253 error = 0;
@@ -369,7 +369,7 @@ static void pmz_status_handle(struct uart_pmac_port *uap)
369 uart_handle_cts_change(&uap->port, 369 uart_handle_cts_change(&uap->port,
370 !(status & CTS)); 370 !(status & CTS));
371 371
372 wake_up_interruptible(&uap->port.info->delta_msr_wait); 372 wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
373 } 373 }
374 374
375 if (status & BRK_ABRT) 375 if (status & BRK_ABRT)
@@ -420,9 +420,9 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
420 return; 420 return;
421 } 421 }
422 422
423 if (uap->port.info == NULL) 423 if (uap->port.state == NULL)
424 goto ack_tx_int; 424 goto ack_tx_int;
425 xmit = &uap->port.info->xmit; 425 xmit = &uap->port.state->xmit;
426 if (uart_circ_empty(xmit)) { 426 if (uart_circ_empty(xmit)) {
427 uart_write_wakeup(&uap->port); 427 uart_write_wakeup(&uap->port);
428 goto ack_tx_int; 428 goto ack_tx_int;
@@ -655,7 +655,7 @@ static void pmz_start_tx(struct uart_port *port)
655 port->icount.tx++; 655 port->icount.tx++;
656 port->x_char = 0; 656 port->x_char = 0;
657 } else { 657 } else {
658 struct circ_buf *xmit = &port->info->xmit; 658 struct circ_buf *xmit = &port->state->xmit;
659 659
660 write_zsdata(uap, xmit->buf[xmit->tail]); 660 write_zsdata(uap, xmit->buf[xmit->tail]);
661 zssync(uap); 661 zssync(uap);
@@ -1645,7 +1645,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
1645 state = pmz_uart_reg.state + uap->port.line; 1645 state = pmz_uart_reg.state + uap->port.line;
1646 1646
1647 mutex_lock(&pmz_irq_mutex); 1647 mutex_lock(&pmz_irq_mutex);
1648 mutex_lock(&state->mutex); 1648 mutex_lock(&state->port.mutex);
1649 1649
1650 spin_lock_irqsave(&uap->port.lock, flags); 1650 spin_lock_irqsave(&uap->port.lock, flags);
1651 1651
@@ -1676,7 +1676,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
1676 /* Shut the chip down */ 1676 /* Shut the chip down */
1677 pmz_set_scc_power(uap, 0); 1677 pmz_set_scc_power(uap, 0);
1678 1678
1679 mutex_unlock(&state->mutex); 1679 mutex_unlock(&state->port.mutex);
1680 mutex_unlock(&pmz_irq_mutex); 1680 mutex_unlock(&pmz_irq_mutex);
1681 1681
1682 pmz_debug("suspend, switching complete\n"); 1682 pmz_debug("suspend, switching complete\n");
@@ -1705,7 +1705,7 @@ static int pmz_resume(struct macio_dev *mdev)
1705 state = pmz_uart_reg.state + uap->port.line; 1705 state = pmz_uart_reg.state + uap->port.line;
1706 1706
1707 mutex_lock(&pmz_irq_mutex); 1707 mutex_lock(&pmz_irq_mutex);
1708 mutex_lock(&state->mutex); 1708 mutex_lock(&state->port.mutex);
1709 1709
1710 spin_lock_irqsave(&uap->port.lock, flags); 1710 spin_lock_irqsave(&uap->port.lock, flags);
1711 if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) { 1711 if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
@@ -1737,7 +1737,7 @@ static int pmz_resume(struct macio_dev *mdev)
1737 } 1737 }
1738 1738
1739 bail: 1739 bail:
1740 mutex_unlock(&state->mutex); 1740 mutex_unlock(&state->port.mutex);
1741 mutex_unlock(&pmz_irq_mutex); 1741 mutex_unlock(&pmz_irq_mutex);
1742 1742
1743 /* Right now, we deal with delay by blocking here, I'll be 1743 /* Right now, we deal with delay by blocking here, I'll be
diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c
index 1bb8f1b45767..0aa75a97531c 100644
--- a/drivers/serial/pnx8xxx_uart.c
+++ b/drivers/serial/pnx8xxx_uart.c
@@ -100,7 +100,7 @@ static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport)
100 if (changed & TIOCM_CTS) 100 if (changed & TIOCM_CTS)
101 uart_handle_cts_change(&sport->port, status & TIOCM_CTS); 101 uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
102 102
103 wake_up_interruptible(&sport->port.info->delta_msr_wait); 103 wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
104} 104}
105 105
106/* 106/*
@@ -112,7 +112,7 @@ static void pnx8xxx_timeout(unsigned long data)
112 struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data; 112 struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data;
113 unsigned long flags; 113 unsigned long flags;
114 114
115 if (sport->port.info) { 115 if (sport->port.state) {
116 spin_lock_irqsave(&sport->port.lock, flags); 116 spin_lock_irqsave(&sport->port.lock, flags);
117 pnx8xxx_mctrl_check(sport); 117 pnx8xxx_mctrl_check(sport);
118 spin_unlock_irqrestore(&sport->port.lock, flags); 118 spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port)
181 181
182static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) 182static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
183{ 183{
184 struct tty_struct *tty = sport->port.info->port.tty; 184 struct tty_struct *tty = sport->port.state->port.tty;
185 unsigned int status, ch, flg; 185 unsigned int status, ch, flg;
186 186
187 status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | 187 status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
@@ -243,7 +243,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
243 243
244static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) 244static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
245{ 245{
246 struct circ_buf *xmit = &sport->port.info->xmit; 246 struct circ_buf *xmit = &sport->port.state->xmit;
247 247
248 if (sport->port.x_char) { 248 if (sport->port.x_char) {
249 serial_out(sport, PNX8XXX_FIFO, sport->port.x_char); 249 serial_out(sport, PNX8XXX_FIFO, sport->port.x_char);
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index a48a8a13d87b..6443b7ff274a 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -96,7 +96,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
96 96
97static inline void receive_chars(struct uart_pxa_port *up, int *status) 97static inline void receive_chars(struct uart_pxa_port *up, int *status)
98{ 98{
99 struct tty_struct *tty = up->port.info->port.tty; 99 struct tty_struct *tty = up->port.state->port.tty;
100 unsigned int ch, flag; 100 unsigned int ch, flag;
101 int max_count = 256; 101 int max_count = 256;
102 102
@@ -161,7 +161,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
161 161
162static void transmit_chars(struct uart_pxa_port *up) 162static void transmit_chars(struct uart_pxa_port *up)
163{ 163{
164 struct circ_buf *xmit = &up->port.info->xmit; 164 struct circ_buf *xmit = &up->port.state->xmit;
165 int count; 165 int count;
166 166
167 if (up->port.x_char) { 167 if (up->port.x_char) {
@@ -220,7 +220,7 @@ static inline void check_modem_status(struct uart_pxa_port *up)
220 if (status & UART_MSR_DCTS) 220 if (status & UART_MSR_DCTS)
221 uart_handle_cts_change(&up->port, status & UART_MSR_CTS); 221 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
222 222
223 wake_up_interruptible(&up->port.info->delta_msr_wait); 223 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
224} 224}
225 225
226/* 226/*
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 94530f01521e..7f5e26873220 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -117,7 +117,7 @@ static void sa1100_mctrl_check(struct sa1100_port *sport)
117 if (changed & TIOCM_CTS) 117 if (changed & TIOCM_CTS)
118 uart_handle_cts_change(&sport->port, status & TIOCM_CTS); 118 uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
119 119
120 wake_up_interruptible(&sport->port.info->delta_msr_wait); 120 wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
121} 121}
122 122
123/* 123/*
@@ -129,7 +129,7 @@ static void sa1100_timeout(unsigned long data)
129 struct sa1100_port *sport = (struct sa1100_port *)data; 129 struct sa1100_port *sport = (struct sa1100_port *)data;
130 unsigned long flags; 130 unsigned long flags;
131 131
132 if (sport->port.info) { 132 if (sport->port.state) {
133 spin_lock_irqsave(&sport->port.lock, flags); 133 spin_lock_irqsave(&sport->port.lock, flags);
134 sa1100_mctrl_check(sport); 134 sa1100_mctrl_check(sport);
135 spin_unlock_irqrestore(&sport->port.lock, flags); 135 spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -189,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port)
189static void 189static void
190sa1100_rx_chars(struct sa1100_port *sport) 190sa1100_rx_chars(struct sa1100_port *sport)
191{ 191{
192 struct tty_struct *tty = sport->port.info->port.tty; 192 struct tty_struct *tty = sport->port.state->port.tty;
193 unsigned int status, ch, flg; 193 unsigned int status, ch, flg;
194 194
195 status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | 195 status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
@@ -239,7 +239,7 @@ sa1100_rx_chars(struct sa1100_port *sport)
239 239
240static void sa1100_tx_chars(struct sa1100_port *sport) 240static void sa1100_tx_chars(struct sa1100_port *sport)
241{ 241{
242 struct circ_buf *xmit = &sport->port.info->xmit; 242 struct circ_buf *xmit = &sport->port.state->xmit;
243 243
244 if (sport->port.x_char) { 244 if (sport->port.x_char) {
245 UART_PUT_CHAR(sport, sport->port.x_char); 245 UART_PUT_CHAR(sport, sport->port.x_char);
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index c8851a0db63a..1523e8d9ae77 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -196,7 +196,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
196{ 196{
197 struct s3c24xx_uart_port *ourport = dev_id; 197 struct s3c24xx_uart_port *ourport = dev_id;
198 struct uart_port *port = &ourport->port; 198 struct uart_port *port = &ourport->port;
199 struct tty_struct *tty = port->info->port.tty; 199 struct tty_struct *tty = port->state->port.tty;
200 unsigned int ufcon, ch, flag, ufstat, uerstat; 200 unsigned int ufcon, ch, flag, ufstat, uerstat;
201 int max_count = 64; 201 int max_count = 64;
202 202
@@ -281,7 +281,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
281{ 281{
282 struct s3c24xx_uart_port *ourport = id; 282 struct s3c24xx_uart_port *ourport = id;
283 struct uart_port *port = &ourport->port; 283 struct uart_port *port = &ourport->port;
284 struct circ_buf *xmit = &port->info->xmit; 284 struct circ_buf *xmit = &port->state->xmit;
285 int count = 256; 285 int count = 256;
286 286
287 if (port->x_char) { 287 if (port->x_char) {
@@ -992,10 +992,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
992 struct ktermios *termios; 992 struct ktermios *termios;
993 struct tty_struct *tty; 993 struct tty_struct *tty;
994 994
995 if (uport->info == NULL) 995 if (uport->state == NULL)
996 goto exit; 996 goto exit;
997 997
998 tty = uport->info->port.tty; 998 tty = uport->state->port.tty;
999 999
1000 if (tty == NULL) 1000 if (tty == NULL)
1001 goto exit; 1001 goto exit;
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index 319e8b83f6be..a2f2b3254499 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -384,13 +384,13 @@ static void sbd_receive_chars(struct sbd_port *sport)
384 uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); 384 uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
385 } 385 }
386 386
387 tty_flip_buffer_push(uport->info->port.tty); 387 tty_flip_buffer_push(uport->state->port.tty);
388} 388}
389 389
390static void sbd_transmit_chars(struct sbd_port *sport) 390static void sbd_transmit_chars(struct sbd_port *sport)
391{ 391{
392 struct uart_port *uport = &sport->port; 392 struct uart_port *uport = &sport->port;
393 struct circ_buf *xmit = &sport->port.info->xmit; 393 struct circ_buf *xmit = &sport->port.state->xmit;
394 unsigned int mask; 394 unsigned int mask;
395 int stop_tx; 395 int stop_tx;
396 396
@@ -440,7 +440,7 @@ static void sbd_status_handle(struct sbd_port *sport)
440 440
441 if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) << 441 if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) <<
442 S_DUART_IN_PIN_CHNG)) 442 S_DUART_IN_PIN_CHNG))
443 wake_up_interruptible(&uport->info->delta_msr_wait); 443 wake_up_interruptible(&uport->state->port.delta_msr_wait);
444} 444}
445 445
446static irqreturn_t sbd_interrupt(int irq, void *dev_id) 446static irqreturn_t sbd_interrupt(int irq, void *dev_id)
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
index e0be11ceaa25..75038ad2b242 100644
--- a/drivers/serial/sc26xx.c
+++ b/drivers/serial/sc26xx.c
@@ -140,8 +140,8 @@ static struct tty_struct *receive_chars(struct uart_port *port)
140 char flag; 140 char flag;
141 u8 status; 141 u8 status;
142 142
143 if (port->info != NULL) /* Unopened serial console */ 143 if (port->state != NULL) /* Unopened serial console */
144 tty = port->info->port.tty; 144 tty = port->state->port.tty;
145 145
146 while (limit-- > 0) { 146 while (limit-- > 0) {
147 status = READ_SC_PORT(port, SR); 147 status = READ_SC_PORT(port, SR);
@@ -190,10 +190,10 @@ static void transmit_chars(struct uart_port *port)
190{ 190{
191 struct circ_buf *xmit; 191 struct circ_buf *xmit;
192 192
193 if (!port->info) 193 if (!port->state)
194 return; 194 return;
195 195
196 xmit = &port->info->xmit; 196 xmit = &port->state->xmit;
197 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 197 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
198 sc26xx_disable_irq(port, IMR_TXRDY); 198 sc26xx_disable_irq(port, IMR_TXRDY);
199 return; 199 return;
@@ -316,7 +316,7 @@ static void sc26xx_stop_tx(struct uart_port *port)
316/* port->lock held by caller. */ 316/* port->lock held by caller. */
317static void sc26xx_start_tx(struct uart_port *port) 317static void sc26xx_start_tx(struct uart_port *port)
318{ 318{
319 struct circ_buf *xmit = &port->info->xmit; 319 struct circ_buf *xmit = &port->state->xmit;
320 320
321 while (!uart_circ_empty(xmit)) { 321 while (!uart_circ_empty(xmit)) {
322 if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) { 322 if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) {
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index b0bb29d804ae..2514d00c0f6f 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -29,10 +29,10 @@
29#include <linux/console.h> 29#include <linux/console.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/serial_core.h>
33#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
34#include <linux/device.h> 33#include <linux/device.h>
35#include <linux/serial.h> /* for serial_state and serial_icounter_struct */ 34#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
35#include <linux/serial_core.h>
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38 38
@@ -52,8 +52,6 @@ static struct lock_class_key port_lock_key;
52 52
53#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 53#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
54 54
55#define uart_users(state) ((state)->count + (state)->info.port.blocked_open)
56
57#ifdef CONFIG_SERIAL_CORE_CONSOLE 55#ifdef CONFIG_SERIAL_CORE_CONSOLE
58#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) 56#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
59#else 57#else
@@ -71,19 +69,19 @@ static void uart_change_pm(struct uart_state *state, int pm_state);
71 */ 69 */
72void uart_write_wakeup(struct uart_port *port) 70void uart_write_wakeup(struct uart_port *port)
73{ 71{
74 struct uart_info *info = port->info; 72 struct uart_state *state = port->state;
75 /* 73 /*
76 * This means you called this function _after_ the port was 74 * This means you called this function _after_ the port was
77 * closed. No cookie for you. 75 * closed. No cookie for you.
78 */ 76 */
79 BUG_ON(!info); 77 BUG_ON(!state);
80 tasklet_schedule(&info->tlet); 78 tasklet_schedule(&state->tlet);
81} 79}
82 80
83static void uart_stop(struct tty_struct *tty) 81static void uart_stop(struct tty_struct *tty)
84{ 82{
85 struct uart_state *state = tty->driver_data; 83 struct uart_state *state = tty->driver_data;
86 struct uart_port *port = state->port; 84 struct uart_port *port = state->uart_port;
87 unsigned long flags; 85 unsigned long flags;
88 86
89 spin_lock_irqsave(&port->lock, flags); 87 spin_lock_irqsave(&port->lock, flags);
@@ -94,9 +92,9 @@ static void uart_stop(struct tty_struct *tty)
94static void __uart_start(struct tty_struct *tty) 92static void __uart_start(struct tty_struct *tty)
95{ 93{
96 struct uart_state *state = tty->driver_data; 94 struct uart_state *state = tty->driver_data;
97 struct uart_port *port = state->port; 95 struct uart_port *port = state->uart_port;
98 96
99 if (!uart_circ_empty(&state->info.xmit) && state->info.xmit.buf && 97 if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
100 !tty->stopped && !tty->hw_stopped) 98 !tty->stopped && !tty->hw_stopped)
101 port->ops->start_tx(port); 99 port->ops->start_tx(port);
102} 100}
@@ -104,7 +102,7 @@ static void __uart_start(struct tty_struct *tty)
104static void uart_start(struct tty_struct *tty) 102static void uart_start(struct tty_struct *tty)
105{ 103{
106 struct uart_state *state = tty->driver_data; 104 struct uart_state *state = tty->driver_data;
107 struct uart_port *port = state->port; 105 struct uart_port *port = state->uart_port;
108 unsigned long flags; 106 unsigned long flags;
109 107
110 spin_lock_irqsave(&port->lock, flags); 108 spin_lock_irqsave(&port->lock, flags);
@@ -115,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
115static void uart_tasklet_action(unsigned long data) 113static void uart_tasklet_action(unsigned long data)
116{ 114{
117 struct uart_state *state = (struct uart_state *)data; 115 struct uart_state *state = (struct uart_state *)data;
118 tty_wakeup(state->info.port.tty); 116 tty_wakeup(state->port.tty);
119} 117}
120 118
121static inline void 119static inline void
@@ -141,12 +139,12 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
141 */ 139 */
142static int uart_startup(struct uart_state *state, int init_hw) 140static int uart_startup(struct uart_state *state, int init_hw)
143{ 141{
144 struct uart_info *info = &state->info; 142 struct uart_port *uport = state->uart_port;
145 struct uart_port *port = state->port; 143 struct tty_port *port = &state->port;
146 unsigned long page; 144 unsigned long page;
147 int retval = 0; 145 int retval = 0;
148 146
149 if (info->flags & UIF_INITIALIZED) 147 if (port->flags & ASYNC_INITIALIZED)
150 return 0; 148 return 0;
151 149
152 /* 150 /*
@@ -154,26 +152,26 @@ static int uart_startup(struct uart_state *state, int init_hw)
154 * once we have successfully opened the port. Also set 152 * once we have successfully opened the port. Also set
155 * up the tty->alt_speed kludge 153 * up the tty->alt_speed kludge
156 */ 154 */
157 set_bit(TTY_IO_ERROR, &info->port.tty->flags); 155 set_bit(TTY_IO_ERROR, &port->tty->flags);
158 156
159 if (port->type == PORT_UNKNOWN) 157 if (uport->type == PORT_UNKNOWN)
160 return 0; 158 return 0;
161 159
162 /* 160 /*
163 * Initialise and allocate the transmit and temporary 161 * Initialise and allocate the transmit and temporary
164 * buffer. 162 * buffer.
165 */ 163 */
166 if (!info->xmit.buf) { 164 if (!state->xmit.buf) {
167 /* This is protected by the per port mutex */ 165 /* This is protected by the per port mutex */
168 page = get_zeroed_page(GFP_KERNEL); 166 page = get_zeroed_page(GFP_KERNEL);
169 if (!page) 167 if (!page)
170 return -ENOMEM; 168 return -ENOMEM;
171 169
172 info->xmit.buf = (unsigned char *) page; 170 state->xmit.buf = (unsigned char *) page;
173 uart_circ_clear(&info->xmit); 171 uart_circ_clear(&state->xmit);
174 } 172 }
175 173
176 retval = port->ops->startup(port); 174 retval = uport->ops->startup(uport);
177 if (retval == 0) { 175 if (retval == 0) {
178 if (init_hw) { 176 if (init_hw) {
179 /* 177 /*
@@ -185,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
185 * Setup the RTS and DTR signals once the 183 * Setup the RTS and DTR signals once the
186 * port is open and ready to respond. 184 * port is open and ready to respond.
187 */ 185 */
188 if (info->port.tty->termios->c_cflag & CBAUD) 186 if (port->tty->termios->c_cflag & CBAUD)
189 uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); 187 uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
190 } 188 }
191 189
192 if (info->flags & UIF_CTS_FLOW) { 190 if (port->flags & ASYNC_CTS_FLOW) {
193 spin_lock_irq(&port->lock); 191 spin_lock_irq(&uport->lock);
194 if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) 192 if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
195 info->port.tty->hw_stopped = 1; 193 port->tty->hw_stopped = 1;
196 spin_unlock_irq(&port->lock); 194 spin_unlock_irq(&uport->lock);
197 } 195 }
198 196
199 info->flags |= UIF_INITIALIZED; 197 set_bit(ASYNCB_INITIALIZED, &port->flags);
200 198
201 clear_bit(TTY_IO_ERROR, &info->port.tty->flags); 199 clear_bit(TTY_IO_ERROR, &port->tty->flags);
202 } 200 }
203 201
204 if (retval && capable(CAP_SYS_ADMIN)) 202 if (retval && capable(CAP_SYS_ADMIN))
@@ -214,9 +212,9 @@ static int uart_startup(struct uart_state *state, int init_hw)
214 */ 212 */
215static void uart_shutdown(struct uart_state *state) 213static void uart_shutdown(struct uart_state *state)
216{ 214{
217 struct uart_info *info = &state->info; 215 struct uart_port *uport = state->uart_port;
218 struct uart_port *port = state->port; 216 struct tty_port *port = &state->port;
219 struct tty_struct *tty = info->port.tty; 217 struct tty_struct *tty = port->tty;
220 218
221 /* 219 /*
222 * Set the TTY IO error marker 220 * Set the TTY IO error marker
@@ -224,14 +222,12 @@ static void uart_shutdown(struct uart_state *state)
224 if (tty) 222 if (tty)
225 set_bit(TTY_IO_ERROR, &tty->flags); 223 set_bit(TTY_IO_ERROR, &tty->flags);
226 224
227 if (info->flags & UIF_INITIALIZED) { 225 if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
228 info->flags &= ~UIF_INITIALIZED;
229
230 /* 226 /*
231 * Turn off DTR and RTS early. 227 * Turn off DTR and RTS early.
232 */ 228 */
233 if (!tty || (tty->termios->c_cflag & HUPCL)) 229 if (!tty || (tty->termios->c_cflag & HUPCL))
234 uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); 230 uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
235 231
236 /* 232 /*
237 * clear delta_msr_wait queue to avoid mem leaks: we may free 233 * clear delta_msr_wait queue to avoid mem leaks: we may free
@@ -240,30 +236,30 @@ static void uart_shutdown(struct uart_state *state)
240 * any outstanding file descriptors should be pointing at 236 * any outstanding file descriptors should be pointing at
241 * hung_up_tty_fops now. 237 * hung_up_tty_fops now.
242 */ 238 */
243 wake_up_interruptible(&info->delta_msr_wait); 239 wake_up_interruptible(&port->delta_msr_wait);
244 240
245 /* 241 /*
246 * Free the IRQ and disable the port. 242 * Free the IRQ and disable the port.
247 */ 243 */
248 port->ops->shutdown(port); 244 uport->ops->shutdown(uport);
249 245
250 /* 246 /*
251 * Ensure that the IRQ handler isn't running on another CPU. 247 * Ensure that the IRQ handler isn't running on another CPU.
252 */ 248 */
253 synchronize_irq(port->irq); 249 synchronize_irq(uport->irq);
254 } 250 }
255 251
256 /* 252 /*
257 * kill off our tasklet 253 * kill off our tasklet
258 */ 254 */
259 tasklet_kill(&info->tlet); 255 tasklet_kill(&state->tlet);
260 256
261 /* 257 /*
262 * Free the transmit buffer page. 258 * Free the transmit buffer page.
263 */ 259 */
264 if (info->xmit.buf) { 260 if (state->xmit.buf) {
265 free_page((unsigned long)info->xmit.buf); 261 free_page((unsigned long)state->xmit.buf);
266 info->xmit.buf = NULL; 262 state->xmit.buf = NULL;
267 } 263 }
268} 264}
269 265
@@ -430,15 +426,16 @@ EXPORT_SYMBOL(uart_get_divisor);
430static void 426static void
431uart_change_speed(struct uart_state *state, struct ktermios *old_termios) 427uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
432{ 428{
433 struct tty_struct *tty = state->info.port.tty; 429 struct tty_port *port = &state->port;
434 struct uart_port *port = state->port; 430 struct tty_struct *tty = port->tty;
431 struct uart_port *uport = state->uart_port;
435 struct ktermios *termios; 432 struct ktermios *termios;
436 433
437 /* 434 /*
438 * If we have no tty, termios, or the port does not exist, 435 * If we have no tty, termios, or the port does not exist,
439 * then we can't set the parameters for this port. 436 * then we can't set the parameters for this port.
440 */ 437 */
441 if (!tty || !tty->termios || port->type == PORT_UNKNOWN) 438 if (!tty || !tty->termios || uport->type == PORT_UNKNOWN)
442 return; 439 return;
443 440
444 termios = tty->termios; 441 termios = tty->termios;
@@ -447,16 +444,16 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
447 * Set flags based on termios cflag 444 * Set flags based on termios cflag
448 */ 445 */
449 if (termios->c_cflag & CRTSCTS) 446 if (termios->c_cflag & CRTSCTS)
450 state->info.flags |= UIF_CTS_FLOW; 447 set_bit(ASYNCB_CTS_FLOW, &port->flags);
451 else 448 else
452 state->info.flags &= ~UIF_CTS_FLOW; 449 clear_bit(ASYNCB_CTS_FLOW, &port->flags);
453 450
454 if (termios->c_cflag & CLOCAL) 451 if (termios->c_cflag & CLOCAL)
455 state->info.flags &= ~UIF_CHECK_CD; 452 clear_bit(ASYNCB_CHECK_CD, &port->flags);
456 else 453 else
457 state->info.flags |= UIF_CHECK_CD; 454 set_bit(ASYNCB_CHECK_CD, &port->flags);
458 455
459 port->ops->set_termios(port, termios, old_termios); 456 uport->ops->set_termios(uport, termios, old_termios);
460} 457}
461 458
462static inline int 459static inline int
@@ -482,7 +479,7 @@ static int uart_put_char(struct tty_struct *tty, unsigned char ch)
482{ 479{
483 struct uart_state *state = tty->driver_data; 480 struct uart_state *state = tty->driver_data;
484 481
485 return __uart_put_char(state->port, &state->info.xmit, ch); 482 return __uart_put_char(state->uart_port, &state->xmit, ch);
486} 483}
487 484
488static void uart_flush_chars(struct tty_struct *tty) 485static void uart_flush_chars(struct tty_struct *tty)
@@ -508,8 +505,8 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
508 return -EL3HLT; 505 return -EL3HLT;
509 } 506 }
510 507
511 port = state->port; 508 port = state->uart_port;
512 circ = &state->info.xmit; 509 circ = &state->xmit;
513 510
514 if (!circ->buf) 511 if (!circ->buf)
515 return 0; 512 return 0;
@@ -539,9 +536,9 @@ static int uart_write_room(struct tty_struct *tty)
539 unsigned long flags; 536 unsigned long flags;
540 int ret; 537 int ret;
541 538
542 spin_lock_irqsave(&state->port->lock, flags); 539 spin_lock_irqsave(&state->uart_port->lock, flags);
543 ret = uart_circ_chars_free(&state->info.xmit); 540 ret = uart_circ_chars_free(&state->xmit);
544 spin_unlock_irqrestore(&state->port->lock, flags); 541 spin_unlock_irqrestore(&state->uart_port->lock, flags);
545 return ret; 542 return ret;
546} 543}
547 544
@@ -551,9 +548,9 @@ static int uart_chars_in_buffer(struct tty_struct *tty)
551 unsigned long flags; 548 unsigned long flags;
552 int ret; 549 int ret;
553 550
554 spin_lock_irqsave(&state->port->lock, flags); 551 spin_lock_irqsave(&state->uart_port->lock, flags);
555 ret = uart_circ_chars_pending(&state->info.xmit); 552 ret = uart_circ_chars_pending(&state->xmit);
556 spin_unlock_irqrestore(&state->port->lock, flags); 553 spin_unlock_irqrestore(&state->uart_port->lock, flags);
557 return ret; 554 return ret;
558} 555}
559 556
@@ -572,11 +569,11 @@ static void uart_flush_buffer(struct tty_struct *tty)
572 return; 569 return;
573 } 570 }
574 571
575 port = state->port; 572 port = state->uart_port;
576 pr_debug("uart_flush_buffer(%d) called\n", tty->index); 573 pr_debug("uart_flush_buffer(%d) called\n", tty->index);
577 574
578 spin_lock_irqsave(&port->lock, flags); 575 spin_lock_irqsave(&port->lock, flags);
579 uart_circ_clear(&state->info.xmit); 576 uart_circ_clear(&state->xmit);
580 if (port->ops->flush_buffer) 577 if (port->ops->flush_buffer)
581 port->ops->flush_buffer(port); 578 port->ops->flush_buffer(port);
582 spin_unlock_irqrestore(&port->lock, flags); 579 spin_unlock_irqrestore(&port->lock, flags);
@@ -590,7 +587,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
590static void uart_send_xchar(struct tty_struct *tty, char ch) 587static void uart_send_xchar(struct tty_struct *tty, char ch)
591{ 588{
592 struct uart_state *state = tty->driver_data; 589 struct uart_state *state = tty->driver_data;
593 struct uart_port *port = state->port; 590 struct uart_port *port = state->uart_port;
594 unsigned long flags; 591 unsigned long flags;
595 592
596 if (port->ops->send_xchar) 593 if (port->ops->send_xchar)
@@ -613,13 +610,13 @@ static void uart_throttle(struct tty_struct *tty)
613 uart_send_xchar(tty, STOP_CHAR(tty)); 610 uart_send_xchar(tty, STOP_CHAR(tty));
614 611
615 if (tty->termios->c_cflag & CRTSCTS) 612 if (tty->termios->c_cflag & CRTSCTS)
616 uart_clear_mctrl(state->port, TIOCM_RTS); 613 uart_clear_mctrl(state->uart_port, TIOCM_RTS);
617} 614}
618 615
619static void uart_unthrottle(struct tty_struct *tty) 616static void uart_unthrottle(struct tty_struct *tty)
620{ 617{
621 struct uart_state *state = tty->driver_data; 618 struct uart_state *state = tty->driver_data;
622 struct uart_port *port = state->port; 619 struct uart_port *port = state->uart_port;
623 620
624 if (I_IXOFF(tty)) { 621 if (I_IXOFF(tty)) {
625 if (port->x_char) 622 if (port->x_char)
@@ -635,35 +632,36 @@ static void uart_unthrottle(struct tty_struct *tty)
635static int uart_get_info(struct uart_state *state, 632static int uart_get_info(struct uart_state *state,
636 struct serial_struct __user *retinfo) 633 struct serial_struct __user *retinfo)
637{ 634{
638 struct uart_port *port = state->port; 635 struct uart_port *uport = state->uart_port;
636 struct tty_port *port = &state->port;
639 struct serial_struct tmp; 637 struct serial_struct tmp;
640 638
641 memset(&tmp, 0, sizeof(tmp)); 639 memset(&tmp, 0, sizeof(tmp));
642 640
643 /* Ensure the state we copy is consistent and no hardware changes 641 /* Ensure the state we copy is consistent and no hardware changes
644 occur as we go */ 642 occur as we go */
645 mutex_lock(&state->mutex); 643 mutex_lock(&port->mutex);
646 644
647 tmp.type = port->type; 645 tmp.type = uport->type;
648 tmp.line = port->line; 646 tmp.line = uport->line;
649 tmp.port = port->iobase; 647 tmp.port = uport->iobase;
650 if (HIGH_BITS_OFFSET) 648 if (HIGH_BITS_OFFSET)
651 tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET; 649 tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET;
652 tmp.irq = port->irq; 650 tmp.irq = uport->irq;
653 tmp.flags = port->flags; 651 tmp.flags = uport->flags;
654 tmp.xmit_fifo_size = port->fifosize; 652 tmp.xmit_fifo_size = uport->fifosize;
655 tmp.baud_base = port->uartclk / 16; 653 tmp.baud_base = uport->uartclk / 16;
656 tmp.close_delay = state->close_delay / 10; 654 tmp.close_delay = port->close_delay / 10;
657 tmp.closing_wait = state->closing_wait == USF_CLOSING_WAIT_NONE ? 655 tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
658 ASYNC_CLOSING_WAIT_NONE : 656 ASYNC_CLOSING_WAIT_NONE :
659 state->closing_wait / 10; 657 port->closing_wait / 10;
660 tmp.custom_divisor = port->custom_divisor; 658 tmp.custom_divisor = uport->custom_divisor;
661 tmp.hub6 = port->hub6; 659 tmp.hub6 = uport->hub6;
662 tmp.io_type = port->iotype; 660 tmp.io_type = uport->iotype;
663 tmp.iomem_reg_shift = port->regshift; 661 tmp.iomem_reg_shift = uport->regshift;
664 tmp.iomem_base = (void *)(unsigned long)port->mapbase; 662 tmp.iomem_base = (void *)(unsigned long)uport->mapbase;
665 663
666 mutex_unlock(&state->mutex); 664 mutex_unlock(&port->mutex);
667 665
668 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 666 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
669 return -EFAULT; 667 return -EFAULT;
@@ -674,7 +672,8 @@ static int uart_set_info(struct uart_state *state,
674 struct serial_struct __user *newinfo) 672 struct serial_struct __user *newinfo)
675{ 673{
676 struct serial_struct new_serial; 674 struct serial_struct new_serial;
677 struct uart_port *port = state->port; 675 struct uart_port *uport = state->uart_port;
676 struct tty_port *port = &state->port;
678 unsigned long new_port; 677 unsigned long new_port;
679 unsigned int change_irq, change_port, closing_wait; 678 unsigned int change_irq, change_port, closing_wait;
680 unsigned int old_custom_divisor, close_delay; 679 unsigned int old_custom_divisor, close_delay;
@@ -691,58 +690,58 @@ static int uart_set_info(struct uart_state *state,
691 new_serial.irq = irq_canonicalize(new_serial.irq); 690 new_serial.irq = irq_canonicalize(new_serial.irq);
692 close_delay = new_serial.close_delay * 10; 691 close_delay = new_serial.close_delay * 10;
693 closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? 692 closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
694 USF_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; 693 ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
695 694
696 /* 695 /*
697 * This semaphore protects state->count. It is also 696 * This semaphore protects port->count. It is also
698 * very useful to prevent opens. Also, take the 697 * very useful to prevent opens. Also, take the
699 * port configuration semaphore to make sure that a 698 * port configuration semaphore to make sure that a
700 * module insertion/removal doesn't change anything 699 * module insertion/removal doesn't change anything
701 * under us. 700 * under us.
702 */ 701 */
703 mutex_lock(&state->mutex); 702 mutex_lock(&port->mutex);
704 703
705 change_irq = !(port->flags & UPF_FIXED_PORT) 704 change_irq = !(uport->flags & UPF_FIXED_PORT)
706 && new_serial.irq != port->irq; 705 && new_serial.irq != uport->irq;
707 706
708 /* 707 /*
709 * Since changing the 'type' of the port changes its resource 708 * Since changing the 'type' of the port changes its resource
710 * allocations, we should treat type changes the same as 709 * allocations, we should treat type changes the same as
711 * IO port changes. 710 * IO port changes.
712 */ 711 */
713 change_port = !(port->flags & UPF_FIXED_PORT) 712 change_port = !(uport->flags & UPF_FIXED_PORT)
714 && (new_port != port->iobase || 713 && (new_port != uport->iobase ||
715 (unsigned long)new_serial.iomem_base != port->mapbase || 714 (unsigned long)new_serial.iomem_base != uport->mapbase ||
716 new_serial.hub6 != port->hub6 || 715 new_serial.hub6 != uport->hub6 ||
717 new_serial.io_type != port->iotype || 716 new_serial.io_type != uport->iotype ||
718 new_serial.iomem_reg_shift != port->regshift || 717 new_serial.iomem_reg_shift != uport->regshift ||
719 new_serial.type != port->type); 718 new_serial.type != uport->type);
720 719
721 old_flags = port->flags; 720 old_flags = uport->flags;
722 new_flags = new_serial.flags; 721 new_flags = new_serial.flags;
723 old_custom_divisor = port->custom_divisor; 722 old_custom_divisor = uport->custom_divisor;
724 723
725 if (!capable(CAP_SYS_ADMIN)) { 724 if (!capable(CAP_SYS_ADMIN)) {
726 retval = -EPERM; 725 retval = -EPERM;
727 if (change_irq || change_port || 726 if (change_irq || change_port ||
728 (new_serial.baud_base != port->uartclk / 16) || 727 (new_serial.baud_base != uport->uartclk / 16) ||
729 (close_delay != state->close_delay) || 728 (close_delay != port->close_delay) ||
730 (closing_wait != state->closing_wait) || 729 (closing_wait != port->closing_wait) ||
731 (new_serial.xmit_fifo_size && 730 (new_serial.xmit_fifo_size &&
732 new_serial.xmit_fifo_size != port->fifosize) || 731 new_serial.xmit_fifo_size != uport->fifosize) ||
733 (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) 732 (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
734 goto exit; 733 goto exit;
735 port->flags = ((port->flags & ~UPF_USR_MASK) | 734 uport->flags = ((uport->flags & ~UPF_USR_MASK) |
736 (new_flags & UPF_USR_MASK)); 735 (new_flags & UPF_USR_MASK));
737 port->custom_divisor = new_serial.custom_divisor; 736 uport->custom_divisor = new_serial.custom_divisor;
738 goto check_and_exit; 737 goto check_and_exit;
739 } 738 }
740 739
741 /* 740 /*
742 * Ask the low level driver to verify the settings. 741 * Ask the low level driver to verify the settings.
743 */ 742 */
744 if (port->ops->verify_port) 743 if (uport->ops->verify_port)
745 retval = port->ops->verify_port(port, &new_serial); 744 retval = uport->ops->verify_port(uport, &new_serial);
746 745
747 if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || 746 if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
748 (new_serial.baud_base < 9600)) 747 (new_serial.baud_base < 9600))
@@ -757,7 +756,7 @@ static int uart_set_info(struct uart_state *state,
757 /* 756 /*
758 * Make sure that we are the sole user of this port. 757 * Make sure that we are the sole user of this port.
759 */ 758 */
760 if (uart_users(state) > 1) 759 if (tty_port_users(port) > 1)
761 goto exit; 760 goto exit;
762 761
763 /* 762 /*
@@ -771,31 +770,31 @@ static int uart_set_info(struct uart_state *state,
771 unsigned long old_iobase, old_mapbase; 770 unsigned long old_iobase, old_mapbase;
772 unsigned int old_type, old_iotype, old_hub6, old_shift; 771 unsigned int old_type, old_iotype, old_hub6, old_shift;
773 772
774 old_iobase = port->iobase; 773 old_iobase = uport->iobase;
775 old_mapbase = port->mapbase; 774 old_mapbase = uport->mapbase;
776 old_type = port->type; 775 old_type = uport->type;
777 old_hub6 = port->hub6; 776 old_hub6 = uport->hub6;
778 old_iotype = port->iotype; 777 old_iotype = uport->iotype;
779 old_shift = port->regshift; 778 old_shift = uport->regshift;
780 779
781 /* 780 /*
782 * Free and release old regions 781 * Free and release old regions
783 */ 782 */
784 if (old_type != PORT_UNKNOWN) 783 if (old_type != PORT_UNKNOWN)
785 port->ops->release_port(port); 784 uport->ops->release_port(uport);
786 785
787 port->iobase = new_port; 786 uport->iobase = new_port;
788 port->type = new_serial.type; 787 uport->type = new_serial.type;
789 port->hub6 = new_serial.hub6; 788 uport->hub6 = new_serial.hub6;
790 port->iotype = new_serial.io_type; 789 uport->iotype = new_serial.io_type;
791 port->regshift = new_serial.iomem_reg_shift; 790 uport->regshift = new_serial.iomem_reg_shift;
792 port->mapbase = (unsigned long)new_serial.iomem_base; 791 uport->mapbase = (unsigned long)new_serial.iomem_base;
793 792
794 /* 793 /*
795 * Claim and map the new regions 794 * Claim and map the new regions
796 */ 795 */
797 if (port->type != PORT_UNKNOWN) { 796 if (uport->type != PORT_UNKNOWN) {
798 retval = port->ops->request_port(port); 797 retval = uport->ops->request_port(uport);
799 } else { 798 } else {
800 /* Always success - Jean II */ 799 /* Always success - Jean II */
801 retval = 0; 800 retval = 0;
@@ -806,19 +805,19 @@ static int uart_set_info(struct uart_state *state,
806 * new port, try to restore the old settings. 805 * new port, try to restore the old settings.
807 */ 806 */
808 if (retval && old_type != PORT_UNKNOWN) { 807 if (retval && old_type != PORT_UNKNOWN) {
809 port->iobase = old_iobase; 808 uport->iobase = old_iobase;
810 port->type = old_type; 809 uport->type = old_type;
811 port->hub6 = old_hub6; 810 uport->hub6 = old_hub6;
812 port->iotype = old_iotype; 811 uport->iotype = old_iotype;
813 port->regshift = old_shift; 812 uport->regshift = old_shift;
814 port->mapbase = old_mapbase; 813 uport->mapbase = old_mapbase;
815 retval = port->ops->request_port(port); 814 retval = uport->ops->request_port(uport);
816 /* 815 /*
817 * If we failed to restore the old settings, 816 * If we failed to restore the old settings,
818 * we fail like this. 817 * we fail like this.
819 */ 818 */
820 if (retval) 819 if (retval)
821 port->type = PORT_UNKNOWN; 820 uport->type = PORT_UNKNOWN;
822 821
823 /* 822 /*
824 * We failed anyway. 823 * We failed anyway.
@@ -830,45 +829,45 @@ static int uart_set_info(struct uart_state *state,
830 } 829 }
831 830
832 if (change_irq) 831 if (change_irq)
833 port->irq = new_serial.irq; 832 uport->irq = new_serial.irq;
834 if (!(port->flags & UPF_FIXED_PORT)) 833 if (!(uport->flags & UPF_FIXED_PORT))
835 port->uartclk = new_serial.baud_base * 16; 834 uport->uartclk = new_serial.baud_base * 16;
836 port->flags = (port->flags & ~UPF_CHANGE_MASK) | 835 uport->flags = (uport->flags & ~UPF_CHANGE_MASK) |
837 (new_flags & UPF_CHANGE_MASK); 836 (new_flags & UPF_CHANGE_MASK);
838 port->custom_divisor = new_serial.custom_divisor; 837 uport->custom_divisor = new_serial.custom_divisor;
839 state->close_delay = close_delay; 838 port->close_delay = close_delay;
840 state->closing_wait = closing_wait; 839 port->closing_wait = closing_wait;
841 if (new_serial.xmit_fifo_size) 840 if (new_serial.xmit_fifo_size)
842 port->fifosize = new_serial.xmit_fifo_size; 841 uport->fifosize = new_serial.xmit_fifo_size;
843 if (state->info.port.tty) 842 if (port->tty)
844 state->info.port.tty->low_latency = 843 port->tty->low_latency =
845 (port->flags & UPF_LOW_LATENCY) ? 1 : 0; 844 (uport->flags & UPF_LOW_LATENCY) ? 1 : 0;
846 845
847 check_and_exit: 846 check_and_exit:
848 retval = 0; 847 retval = 0;
849 if (port->type == PORT_UNKNOWN) 848 if (uport->type == PORT_UNKNOWN)
850 goto exit; 849 goto exit;
851 if (state->info.flags & UIF_INITIALIZED) { 850 if (port->flags & ASYNC_INITIALIZED) {
852 if (((old_flags ^ port->flags) & UPF_SPD_MASK) || 851 if (((old_flags ^ uport->flags) & UPF_SPD_MASK) ||
853 old_custom_divisor != port->custom_divisor) { 852 old_custom_divisor != uport->custom_divisor) {
854 /* 853 /*
855 * If they're setting up a custom divisor or speed, 854 * If they're setting up a custom divisor or speed,
856 * instead of clearing it, then bitch about it. No 855 * instead of clearing it, then bitch about it. No
857 * need to rate-limit; it's CAP_SYS_ADMIN only. 856 * need to rate-limit; it's CAP_SYS_ADMIN only.
858 */ 857 */
859 if (port->flags & UPF_SPD_MASK) { 858 if (uport->flags & UPF_SPD_MASK) {
860 char buf[64]; 859 char buf[64];
861 printk(KERN_NOTICE 860 printk(KERN_NOTICE
862 "%s sets custom speed on %s. This " 861 "%s sets custom speed on %s. This "
863 "is deprecated.\n", current->comm, 862 "is deprecated.\n", current->comm,
864 tty_name(state->info.port.tty, buf)); 863 tty_name(port->tty, buf));
865 } 864 }
866 uart_change_speed(state, NULL); 865 uart_change_speed(state, NULL);
867 } 866 }
868 } else 867 } else
869 retval = uart_startup(state, 1); 868 retval = uart_startup(state, 1);
870 exit: 869 exit:
871 mutex_unlock(&state->mutex); 870 mutex_unlock(&port->mutex);
872 return retval; 871 return retval;
873} 872}
874 873
@@ -880,10 +879,11 @@ static int uart_set_info(struct uart_state *state,
880static int uart_get_lsr_info(struct uart_state *state, 879static int uart_get_lsr_info(struct uart_state *state,
881 unsigned int __user *value) 880 unsigned int __user *value)
882{ 881{
883 struct uart_port *port = state->port; 882 struct uart_port *uport = state->uart_port;
883 struct tty_port *port = &state->port;
884 unsigned int result; 884 unsigned int result;
885 885
886 result = port->ops->tx_empty(port); 886 result = uport->ops->tx_empty(uport);
887 887
888 /* 888 /*
889 * If we're about to load something into the transmit 889 * If we're about to load something into the transmit
@@ -891,9 +891,9 @@ static int uart_get_lsr_info(struct uart_state *state,
891 * avoid a race condition (depending on when the transmit 891 * avoid a race condition (depending on when the transmit
892 * interrupt happens). 892 * interrupt happens).
893 */ 893 */
894 if (port->x_char || 894 if (uport->x_char ||
895 ((uart_circ_chars_pending(&state->info.xmit) > 0) && 895 ((uart_circ_chars_pending(&state->xmit) > 0) &&
896 !state->info.port.tty->stopped && !state->info.port.tty->hw_stopped)) 896 !port->tty->stopped && !port->tty->hw_stopped))
897 result &= ~TIOCSER_TEMT; 897 result &= ~TIOCSER_TEMT;
898 898
899 return put_user(result, value); 899 return put_user(result, value);
@@ -902,19 +902,20 @@ static int uart_get_lsr_info(struct uart_state *state,
902static int uart_tiocmget(struct tty_struct *tty, struct file *file) 902static int uart_tiocmget(struct tty_struct *tty, struct file *file)
903{ 903{
904 struct uart_state *state = tty->driver_data; 904 struct uart_state *state = tty->driver_data;
905 struct uart_port *port = state->port; 905 struct tty_port *port = &state->port;
906 struct uart_port *uport = state->uart_port;
906 int result = -EIO; 907 int result = -EIO;
907 908
908 mutex_lock(&state->mutex); 909 mutex_lock(&port->mutex);
909 if ((!file || !tty_hung_up_p(file)) && 910 if ((!file || !tty_hung_up_p(file)) &&
910 !(tty->flags & (1 << TTY_IO_ERROR))) { 911 !(tty->flags & (1 << TTY_IO_ERROR))) {
911 result = port->mctrl; 912 result = uport->mctrl;
912 913
913 spin_lock_irq(&port->lock); 914 spin_lock_irq(&uport->lock);
914 result |= port->ops->get_mctrl(port); 915 result |= uport->ops->get_mctrl(uport);
915 spin_unlock_irq(&port->lock); 916 spin_unlock_irq(&uport->lock);
916 } 917 }
917 mutex_unlock(&state->mutex); 918 mutex_unlock(&port->mutex);
918 919
919 return result; 920 return result;
920} 921}
@@ -924,36 +925,39 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
924 unsigned int set, unsigned int clear) 925 unsigned int set, unsigned int clear)
925{ 926{
926 struct uart_state *state = tty->driver_data; 927 struct uart_state *state = tty->driver_data;
927 struct uart_port *port = state->port; 928 struct uart_port *uport = state->uart_port;
929 struct tty_port *port = &state->port;
928 int ret = -EIO; 930 int ret = -EIO;
929 931
930 mutex_lock(&state->mutex); 932 mutex_lock(&port->mutex);
931 if ((!file || !tty_hung_up_p(file)) && 933 if ((!file || !tty_hung_up_p(file)) &&
932 !(tty->flags & (1 << TTY_IO_ERROR))) { 934 !(tty->flags & (1 << TTY_IO_ERROR))) {
933 uart_update_mctrl(port, set, clear); 935 uart_update_mctrl(uport, set, clear);
934 ret = 0; 936 ret = 0;
935 } 937 }
936 mutex_unlock(&state->mutex); 938 mutex_unlock(&port->mutex);
937 return ret; 939 return ret;
938} 940}
939 941
940static int uart_break_ctl(struct tty_struct *tty, int break_state) 942static int uart_break_ctl(struct tty_struct *tty, int break_state)
941{ 943{
942 struct uart_state *state = tty->driver_data; 944 struct uart_state *state = tty->driver_data;
943 struct uart_port *port = state->port; 945 struct tty_port *port = &state->port;
946 struct uart_port *uport = state->uart_port;
944 947
945 mutex_lock(&state->mutex); 948 mutex_lock(&port->mutex);
946 949
947 if (port->type != PORT_UNKNOWN) 950 if (uport->type != PORT_UNKNOWN)
948 port->ops->break_ctl(port, break_state); 951 uport->ops->break_ctl(uport, break_state);
949 952
950 mutex_unlock(&state->mutex); 953 mutex_unlock(&port->mutex);
951 return 0; 954 return 0;
952} 955}
953 956
954static int uart_do_autoconfig(struct uart_state *state) 957static int uart_do_autoconfig(struct uart_state *state)
955{ 958{
956 struct uart_port *port = state->port; 959 struct uart_port *uport = state->uart_port;
960 struct tty_port *port = &state->port;
957 int flags, ret; 961 int flags, ret;
958 962
959 if (!capable(CAP_SYS_ADMIN)) 963 if (!capable(CAP_SYS_ADMIN))
@@ -964,33 +968,33 @@ static int uart_do_autoconfig(struct uart_state *state)
964 * changing, and hence any extra opens of the port while 968 * changing, and hence any extra opens of the port while
965 * we're auto-configuring. 969 * we're auto-configuring.
966 */ 970 */
967 if (mutex_lock_interruptible(&state->mutex)) 971 if (mutex_lock_interruptible(&port->mutex))
968 return -ERESTARTSYS; 972 return -ERESTARTSYS;
969 973
970 ret = -EBUSY; 974 ret = -EBUSY;
971 if (uart_users(state) == 1) { 975 if (tty_port_users(port) == 1) {
972 uart_shutdown(state); 976 uart_shutdown(state);
973 977
974 /* 978 /*
975 * If we already have a port type configured, 979 * If we already have a port type configured,
976 * we must release its resources. 980 * we must release its resources.
977 */ 981 */
978 if (port->type != PORT_UNKNOWN) 982 if (uport->type != PORT_UNKNOWN)
979 port->ops->release_port(port); 983 uport->ops->release_port(uport);
980 984
981 flags = UART_CONFIG_TYPE; 985 flags = UART_CONFIG_TYPE;
982 if (port->flags & UPF_AUTO_IRQ) 986 if (uport->flags & UPF_AUTO_IRQ)
983 flags |= UART_CONFIG_IRQ; 987 flags |= UART_CONFIG_IRQ;
984 988
985 /* 989 /*
986 * This will claim the ports resources if 990 * This will claim the ports resources if
987 * a port is found. 991 * a port is found.
988 */ 992 */
989 port->ops->config_port(port, flags); 993 uport->ops->config_port(uport, flags);
990 994
991 ret = uart_startup(state, 1); 995 ret = uart_startup(state, 1);
992 } 996 }
993 mutex_unlock(&state->mutex); 997 mutex_unlock(&port->mutex);
994 return ret; 998 return ret;
995} 999}
996 1000
@@ -999,11 +1003,15 @@ static int uart_do_autoconfig(struct uart_state *state)
999 * - mask passed in arg for lines of interest 1003 * - mask passed in arg for lines of interest
1000 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 1004 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1001 * Caller should use TIOCGICOUNT to see which one it was 1005 * Caller should use TIOCGICOUNT to see which one it was
1006 *
1007 * FIXME: This wants extracting into a common all driver implementation
1008 * of TIOCMWAIT using tty_port.
1002 */ 1009 */
1003static int 1010static int
1004uart_wait_modem_status(struct uart_state *state, unsigned long arg) 1011uart_wait_modem_status(struct uart_state *state, unsigned long arg)
1005{ 1012{
1006 struct uart_port *port = state->port; 1013 struct uart_port *uport = state->uart_port;
1014 struct tty_port *port = &state->port;
1007 DECLARE_WAITQUEUE(wait, current); 1015 DECLARE_WAITQUEUE(wait, current);
1008 struct uart_icount cprev, cnow; 1016 struct uart_icount cprev, cnow;
1009 int ret; 1017 int ret;
@@ -1011,20 +1019,20 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
1011 /* 1019 /*
1012 * note the counters on entry 1020 * note the counters on entry
1013 */ 1021 */
1014 spin_lock_irq(&port->lock); 1022 spin_lock_irq(&uport->lock);
1015 memcpy(&cprev, &port->icount, sizeof(struct uart_icount)); 1023 memcpy(&cprev, &uport->icount, sizeof(struct uart_icount));
1016 1024
1017 /* 1025 /*
1018 * Force modem status interrupts on 1026 * Force modem status interrupts on
1019 */ 1027 */
1020 port->ops->enable_ms(port); 1028 uport->ops->enable_ms(uport);
1021 spin_unlock_irq(&port->lock); 1029 spin_unlock_irq(&uport->lock);
1022 1030
1023 add_wait_queue(&state->info.delta_msr_wait, &wait); 1031 add_wait_queue(&port->delta_msr_wait, &wait);
1024 for (;;) { 1032 for (;;) {
1025 spin_lock_irq(&port->lock); 1033 spin_lock_irq(&uport->lock);
1026 memcpy(&cnow, &port->icount, sizeof(struct uart_icount)); 1034 memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
1027 spin_unlock_irq(&port->lock); 1035 spin_unlock_irq(&uport->lock);
1028 1036
1029 set_current_state(TASK_INTERRUPTIBLE); 1037 set_current_state(TASK_INTERRUPTIBLE);
1030 1038
@@ -1048,7 +1056,7 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
1048 } 1056 }
1049 1057
1050 current->state = TASK_RUNNING; 1058 current->state = TASK_RUNNING;
1051 remove_wait_queue(&state->info.delta_msr_wait, &wait); 1059 remove_wait_queue(&port->delta_msr_wait, &wait);
1052 1060
1053 return ret; 1061 return ret;
1054} 1062}
@@ -1064,11 +1072,11 @@ static int uart_get_count(struct uart_state *state,
1064{ 1072{
1065 struct serial_icounter_struct icount; 1073 struct serial_icounter_struct icount;
1066 struct uart_icount cnow; 1074 struct uart_icount cnow;
1067 struct uart_port *port = state->port; 1075 struct uart_port *uport = state->uart_port;
1068 1076
1069 spin_lock_irq(&port->lock); 1077 spin_lock_irq(&uport->lock);
1070 memcpy(&cnow, &port->icount, sizeof(struct uart_icount)); 1078 memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
1071 spin_unlock_irq(&port->lock); 1079 spin_unlock_irq(&uport->lock);
1072 1080
1073 icount.cts = cnow.cts; 1081 icount.cts = cnow.cts;
1074 icount.dsr = cnow.dsr; 1082 icount.dsr = cnow.dsr;
@@ -1093,6 +1101,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
1093 unsigned long arg) 1101 unsigned long arg)
1094{ 1102{
1095 struct uart_state *state = tty->driver_data; 1103 struct uart_state *state = tty->driver_data;
1104 struct tty_port *port = &state->port;
1096 void __user *uarg = (void __user *)arg; 1105 void __user *uarg = (void __user *)arg;
1097 int ret = -ENOIOCTLCMD; 1106 int ret = -ENOIOCTLCMD;
1098 1107
@@ -1143,7 +1152,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
1143 if (ret != -ENOIOCTLCMD) 1152 if (ret != -ENOIOCTLCMD)
1144 goto out; 1153 goto out;
1145 1154
1146 mutex_lock(&state->mutex); 1155 mutex_lock(&port->mutex);
1147 1156
1148 if (tty_hung_up_p(filp)) { 1157 if (tty_hung_up_p(filp)) {
1149 ret = -EIO; 1158 ret = -EIO;
@@ -1160,14 +1169,14 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
1160 break; 1169 break;
1161 1170
1162 default: { 1171 default: {
1163 struct uart_port *port = state->port; 1172 struct uart_port *uport = state->uart_port;
1164 if (port->ops->ioctl) 1173 if (uport->ops->ioctl)
1165 ret = port->ops->ioctl(port, cmd, arg); 1174 ret = uport->ops->ioctl(uport, cmd, arg);
1166 break; 1175 break;
1167 } 1176 }
1168 } 1177 }
1169out_up: 1178out_up:
1170 mutex_unlock(&state->mutex); 1179 mutex_unlock(&port->mutex);
1171out: 1180out:
1172 return ret; 1181 return ret;
1173} 1182}
@@ -1175,10 +1184,10 @@ out:
1175static void uart_set_ldisc(struct tty_struct *tty) 1184static void uart_set_ldisc(struct tty_struct *tty)
1176{ 1185{
1177 struct uart_state *state = tty->driver_data; 1186 struct uart_state *state = tty->driver_data;
1178 struct uart_port *port = state->port; 1187 struct uart_port *uport = state->uart_port;
1179 1188
1180 if (port->ops->set_ldisc) 1189 if (uport->ops->set_ldisc)
1181 port->ops->set_ldisc(port); 1190 uport->ops->set_ldisc(uport);
1182} 1191}
1183 1192
1184static void uart_set_termios(struct tty_struct *tty, 1193static void uart_set_termios(struct tty_struct *tty,
@@ -1207,7 +1216,7 @@ static void uart_set_termios(struct tty_struct *tty,
1207 1216
1208 /* Handle transition to B0 status */ 1217 /* Handle transition to B0 status */
1209 if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) 1218 if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
1210 uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR); 1219 uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR);
1211 1220
1212 /* Handle transition away from B0 status */ 1221 /* Handle transition away from B0 status */
1213 if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { 1222 if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
@@ -1215,25 +1224,25 @@ static void uart_set_termios(struct tty_struct *tty,
1215 if (!(cflag & CRTSCTS) || 1224 if (!(cflag & CRTSCTS) ||
1216 !test_bit(TTY_THROTTLED, &tty->flags)) 1225 !test_bit(TTY_THROTTLED, &tty->flags))
1217 mask |= TIOCM_RTS; 1226 mask |= TIOCM_RTS;
1218 uart_set_mctrl(state->port, mask); 1227 uart_set_mctrl(state->uart_port, mask);
1219 } 1228 }
1220 1229
1221 /* Handle turning off CRTSCTS */ 1230 /* Handle turning off CRTSCTS */
1222 if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { 1231 if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
1223 spin_lock_irqsave(&state->port->lock, flags); 1232 spin_lock_irqsave(&state->uart_port->lock, flags);
1224 tty->hw_stopped = 0; 1233 tty->hw_stopped = 0;
1225 __uart_start(tty); 1234 __uart_start(tty);
1226 spin_unlock_irqrestore(&state->port->lock, flags); 1235 spin_unlock_irqrestore(&state->uart_port->lock, flags);
1227 } 1236 }
1228 1237
1229 /* Handle turning on CRTSCTS */ 1238 /* Handle turning on CRTSCTS */
1230 if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { 1239 if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
1231 spin_lock_irqsave(&state->port->lock, flags); 1240 spin_lock_irqsave(&state->uart_port->lock, flags);
1232 if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { 1241 if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) {
1233 tty->hw_stopped = 1; 1242 tty->hw_stopped = 1;
1234 state->port->ops->stop_tx(state->port); 1243 state->uart_port->ops->stop_tx(state->uart_port);
1235 } 1244 }
1236 spin_unlock_irqrestore(&state->port->lock, flags); 1245 spin_unlock_irqrestore(&state->uart_port->lock, flags);
1237 } 1246 }
1238#if 0 1247#if 0
1239 /* 1248 /*
@@ -1244,7 +1253,7 @@ static void uart_set_termios(struct tty_struct *tty,
1244 */ 1253 */
1245 if (!(old_termios->c_cflag & CLOCAL) && 1254 if (!(old_termios->c_cflag & CLOCAL) &&
1246 (tty->termios->c_cflag & CLOCAL)) 1255 (tty->termios->c_cflag & CLOCAL))
1247 wake_up_interruptible(&info->port.open_wait); 1256 wake_up_interruptible(&state->uart_port.open_wait);
1248#endif 1257#endif
1249} 1258}
1250 1259
@@ -1256,40 +1265,39 @@ static void uart_set_termios(struct tty_struct *tty,
1256static void uart_close(struct tty_struct *tty, struct file *filp) 1265static void uart_close(struct tty_struct *tty, struct file *filp)
1257{ 1266{
1258 struct uart_state *state = tty->driver_data; 1267 struct uart_state *state = tty->driver_data;
1259 struct uart_port *port; 1268 struct tty_port *port;
1269 struct uart_port *uport;
1260 1270
1261 BUG_ON(!kernel_locked()); 1271 BUG_ON(!kernel_locked());
1262 1272
1263 if (!state || !state->port) 1273 uport = state->uart_port;
1264 return; 1274 port = &state->port;
1265 1275
1266 port = state->port; 1276 pr_debug("uart_close(%d) called\n", uport->line);
1267 1277
1268 pr_debug("uart_close(%d) called\n", port->line); 1278 mutex_lock(&port->mutex);
1269
1270 mutex_lock(&state->mutex);
1271 1279
1272 if (tty_hung_up_p(filp)) 1280 if (tty_hung_up_p(filp))
1273 goto done; 1281 goto done;
1274 1282
1275 if ((tty->count == 1) && (state->count != 1)) { 1283 if ((tty->count == 1) && (port->count != 1)) {
1276 /* 1284 /*
1277 * Uh, oh. tty->count is 1, which means that the tty 1285 * Uh, oh. tty->count is 1, which means that the tty
1278 * structure will be freed. state->count should always 1286 * structure will be freed. port->count should always
1279 * be one in these conditions. If it's greater than 1287 * be one in these conditions. If it's greater than
1280 * one, we've got real problems, since it means the 1288 * one, we've got real problems, since it means the
1281 * serial port won't be shutdown. 1289 * serial port won't be shutdown.
1282 */ 1290 */
1283 printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " 1291 printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, "
1284 "state->count is %d\n", state->count); 1292 "port->count is %d\n", port->count);
1285 state->count = 1; 1293 port->count = 1;
1286 } 1294 }
1287 if (--state->count < 0) { 1295 if (--port->count < 0) {
1288 printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", 1296 printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n",
1289 tty->name, state->count); 1297 tty->name, port->count);
1290 state->count = 0; 1298 port->count = 0;
1291 } 1299 }
1292 if (state->count) 1300 if (port->count)
1293 goto done; 1301 goto done;
1294 1302
1295 /* 1303 /*
@@ -1299,24 +1307,24 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1299 */ 1307 */
1300 tty->closing = 1; 1308 tty->closing = 1;
1301 1309
1302 if (state->closing_wait != USF_CLOSING_WAIT_NONE) 1310 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1303 tty_wait_until_sent(tty, msecs_to_jiffies(state->closing_wait)); 1311 tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
1304 1312
1305 /* 1313 /*
1306 * At this point, we stop accepting input. To do this, we 1314 * At this point, we stop accepting input. To do this, we
1307 * disable the receive line status interrupts. 1315 * disable the receive line status interrupts.
1308 */ 1316 */
1309 if (state->info.flags & UIF_INITIALIZED) { 1317 if (port->flags & ASYNC_INITIALIZED) {
1310 unsigned long flags; 1318 unsigned long flags;
1311 spin_lock_irqsave(&port->lock, flags); 1319 spin_lock_irqsave(&port->lock, flags);
1312 port->ops->stop_rx(port); 1320 uport->ops->stop_rx(uport);
1313 spin_unlock_irqrestore(&port->lock, flags); 1321 spin_unlock_irqrestore(&port->lock, flags);
1314 /* 1322 /*
1315 * Before we drop DTR, make sure the UART transmitter 1323 * Before we drop DTR, make sure the UART transmitter
1316 * has completely drained; this is especially 1324 * has completely drained; this is especially
1317 * important if there is a transmit FIFO! 1325 * important if there is a transmit FIFO!
1318 */ 1326 */
1319 uart_wait_until_sent(tty, port->timeout); 1327 uart_wait_until_sent(tty, uport->timeout);
1320 } 1328 }
1321 1329
1322 uart_shutdown(state); 1330 uart_shutdown(state);
@@ -1325,29 +1333,29 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1325 tty_ldisc_flush(tty); 1333 tty_ldisc_flush(tty);
1326 1334
1327 tty->closing = 0; 1335 tty->closing = 0;
1328 state->info.port.tty = NULL; 1336 tty_port_tty_set(port, NULL);
1329 1337
1330 if (state->info.port.blocked_open) { 1338 if (port->blocked_open) {
1331 if (state->close_delay) 1339 if (port->close_delay)
1332 msleep_interruptible(state->close_delay); 1340 msleep_interruptible(port->close_delay);
1333 } else if (!uart_console(port)) { 1341 } else if (!uart_console(uport)) {
1334 uart_change_pm(state, 3); 1342 uart_change_pm(state, 3);
1335 } 1343 }
1336 1344
1337 /* 1345 /*
1338 * Wake up anyone trying to open this port. 1346 * Wake up anyone trying to open this port.
1339 */ 1347 */
1340 state->info.flags &= ~UIF_NORMAL_ACTIVE; 1348 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1341 wake_up_interruptible(&state->info.port.open_wait); 1349 wake_up_interruptible(&port->open_wait);
1342 1350
1343 done: 1351done:
1344 mutex_unlock(&state->mutex); 1352 mutex_unlock(&port->mutex);
1345} 1353}
1346 1354
1347static void uart_wait_until_sent(struct tty_struct *tty, int timeout) 1355static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1348{ 1356{
1349 struct uart_state *state = tty->driver_data; 1357 struct uart_state *state = tty->driver_data;
1350 struct uart_port *port = state->port; 1358 struct uart_port *port = state->uart_port;
1351 unsigned long char_time, expire; 1359 unsigned long char_time, expire;
1352 1360
1353 if (port->type == PORT_UNKNOWN || port->fifosize == 0) 1361 if (port->type == PORT_UNKNOWN || port->fifosize == 0)
@@ -1412,22 +1420,22 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
1412static void uart_hangup(struct tty_struct *tty) 1420static void uart_hangup(struct tty_struct *tty)
1413{ 1421{
1414 struct uart_state *state = tty->driver_data; 1422 struct uart_state *state = tty->driver_data;
1415 struct uart_info *info = &state->info; 1423 struct tty_port *port = &state->port;
1416 1424
1417 BUG_ON(!kernel_locked()); 1425 BUG_ON(!kernel_locked());
1418 pr_debug("uart_hangup(%d)\n", state->port->line); 1426 pr_debug("uart_hangup(%d)\n", state->uart_port->line);
1419 1427
1420 mutex_lock(&state->mutex); 1428 mutex_lock(&port->mutex);
1421 if (info->flags & UIF_NORMAL_ACTIVE) { 1429 if (port->flags & ASYNC_NORMAL_ACTIVE) {
1422 uart_flush_buffer(tty); 1430 uart_flush_buffer(tty);
1423 uart_shutdown(state); 1431 uart_shutdown(state);
1424 state->count = 0; 1432 port->count = 0;
1425 info->flags &= ~UIF_NORMAL_ACTIVE; 1433 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1426 info->port.tty = NULL; 1434 tty_port_tty_set(port, NULL);
1427 wake_up_interruptible(&info->port.open_wait); 1435 wake_up_interruptible(&port->open_wait);
1428 wake_up_interruptible(&info->delta_msr_wait); 1436 wake_up_interruptible(&port->delta_msr_wait);
1429 } 1437 }
1430 mutex_unlock(&state->mutex); 1438 mutex_unlock(&port->mutex);
1431} 1439}
1432 1440
1433/* 1441/*
@@ -1438,8 +1446,8 @@ static void uart_hangup(struct tty_struct *tty)
1438 */ 1446 */
1439static void uart_update_termios(struct uart_state *state) 1447static void uart_update_termios(struct uart_state *state)
1440{ 1448{
1441 struct tty_struct *tty = state->info.port.tty; 1449 struct tty_struct *tty = state->port.tty;
1442 struct uart_port *port = state->port; 1450 struct uart_port *port = state->uart_port;
1443 1451
1444 if (uart_console(port) && port->cons->cflag) { 1452 if (uart_console(port) && port->cons->cflag) {
1445 tty->termios->c_cflag = port->cons->cflag; 1453 tty->termios->c_cflag = port->cons->cflag;
@@ -1473,27 +1481,27 @@ static int
1473uart_block_til_ready(struct file *filp, struct uart_state *state) 1481uart_block_til_ready(struct file *filp, struct uart_state *state)
1474{ 1482{
1475 DECLARE_WAITQUEUE(wait, current); 1483 DECLARE_WAITQUEUE(wait, current);
1476 struct uart_info *info = &state->info; 1484 struct uart_port *uport = state->uart_port;
1477 struct uart_port *port = state->port; 1485 struct tty_port *port = &state->port;
1478 unsigned int mctrl; 1486 unsigned int mctrl;
1479 1487
1480 info->port.blocked_open++; 1488 port->blocked_open++;
1481 state->count--; 1489 port->count--;
1482 1490
1483 add_wait_queue(&info->port.open_wait, &wait); 1491 add_wait_queue(&port->open_wait, &wait);
1484 while (1) { 1492 while (1) {
1485 set_current_state(TASK_INTERRUPTIBLE); 1493 set_current_state(TASK_INTERRUPTIBLE);
1486 1494
1487 /* 1495 /*
1488 * If we have been hung up, tell userspace/restart open. 1496 * If we have been hung up, tell userspace/restart open.
1489 */ 1497 */
1490 if (tty_hung_up_p(filp) || info->port.tty == NULL) 1498 if (tty_hung_up_p(filp) || port->tty == NULL)
1491 break; 1499 break;
1492 1500
1493 /* 1501 /*
1494 * If the port has been closed, tell userspace/restart open. 1502 * If the port has been closed, tell userspace/restart open.
1495 */ 1503 */
1496 if (!(info->flags & UIF_INITIALIZED)) 1504 if (!(port->flags & ASYNC_INITIALIZED))
1497 break; 1505 break;
1498 1506
1499 /* 1507 /*
@@ -1506,8 +1514,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1506 * have set TTY_IO_ERROR for a non-existant port. 1514 * have set TTY_IO_ERROR for a non-existant port.
1507 */ 1515 */
1508 if ((filp->f_flags & O_NONBLOCK) || 1516 if ((filp->f_flags & O_NONBLOCK) ||
1509 (info->port.tty->termios->c_cflag & CLOCAL) || 1517 (port->tty->termios->c_cflag & CLOCAL) ||
1510 (info->port.tty->flags & (1 << TTY_IO_ERROR))) 1518 (port->tty->flags & (1 << TTY_IO_ERROR)))
1511 break; 1519 break;
1512 1520
1513 /* 1521 /*
@@ -1515,37 +1523,37 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1515 * not set RTS here - we want to make sure we catch 1523 * not set RTS here - we want to make sure we catch
1516 * the data from the modem. 1524 * the data from the modem.
1517 */ 1525 */
1518 if (info->port.tty->termios->c_cflag & CBAUD) 1526 if (port->tty->termios->c_cflag & CBAUD)
1519 uart_set_mctrl(port, TIOCM_DTR); 1527 uart_set_mctrl(uport, TIOCM_DTR);
1520 1528
1521 /* 1529 /*
1522 * and wait for the carrier to indicate that the 1530 * and wait for the carrier to indicate that the
1523 * modem is ready for us. 1531 * modem is ready for us.
1524 */ 1532 */
1525 spin_lock_irq(&port->lock); 1533 spin_lock_irq(&uport->lock);
1526 port->ops->enable_ms(port); 1534 uport->ops->enable_ms(uport);
1527 mctrl = port->ops->get_mctrl(port); 1535 mctrl = uport->ops->get_mctrl(uport);
1528 spin_unlock_irq(&port->lock); 1536 spin_unlock_irq(&uport->lock);
1529 if (mctrl & TIOCM_CAR) 1537 if (mctrl & TIOCM_CAR)
1530 break; 1538 break;
1531 1539
1532 mutex_unlock(&state->mutex); 1540 mutex_unlock(&port->mutex);
1533 schedule(); 1541 schedule();
1534 mutex_lock(&state->mutex); 1542 mutex_lock(&port->mutex);
1535 1543
1536 if (signal_pending(current)) 1544 if (signal_pending(current))
1537 break; 1545 break;
1538 } 1546 }
1539 set_current_state(TASK_RUNNING); 1547 set_current_state(TASK_RUNNING);
1540 remove_wait_queue(&info->port.open_wait, &wait); 1548 remove_wait_queue(&port->open_wait, &wait);
1541 1549
1542 state->count++; 1550 port->count++;
1543 info->port.blocked_open--; 1551 port->blocked_open--;
1544 1552
1545 if (signal_pending(current)) 1553 if (signal_pending(current))
1546 return -ERESTARTSYS; 1554 return -ERESTARTSYS;
1547 1555
1548 if (!info->port.tty || tty_hung_up_p(filp)) 1556 if (!port->tty || tty_hung_up_p(filp))
1549 return -EAGAIN; 1557 return -EAGAIN;
1550 1558
1551 return 0; 1559 return 0;
@@ -1554,24 +1562,26 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1554static struct uart_state *uart_get(struct uart_driver *drv, int line) 1562static struct uart_state *uart_get(struct uart_driver *drv, int line)
1555{ 1563{
1556 struct uart_state *state; 1564 struct uart_state *state;
1565 struct tty_port *port;
1557 int ret = 0; 1566 int ret = 0;
1558 1567
1559 state = drv->state + line; 1568 state = drv->state + line;
1560 if (mutex_lock_interruptible(&state->mutex)) { 1569 port = &state->port;
1570 if (mutex_lock_interruptible(&port->mutex)) {
1561 ret = -ERESTARTSYS; 1571 ret = -ERESTARTSYS;
1562 goto err; 1572 goto err;
1563 } 1573 }
1564 1574
1565 state->count++; 1575 port->count++;
1566 if (!state->port || state->port->flags & UPF_DEAD) { 1576 if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
1567 ret = -ENXIO; 1577 ret = -ENXIO;
1568 goto err_unlock; 1578 goto err_unlock;
1569 } 1579 }
1570 return state; 1580 return state;
1571 1581
1572 err_unlock: 1582 err_unlock:
1573 state->count--; 1583 port->count--;
1574 mutex_unlock(&state->mutex); 1584 mutex_unlock(&port->mutex);
1575 err: 1585 err:
1576 return ERR_PTR(ret); 1586 return ERR_PTR(ret);
1577} 1587}
@@ -1590,6 +1600,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1590{ 1600{
1591 struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; 1601 struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state;
1592 struct uart_state *state; 1602 struct uart_state *state;
1603 struct tty_port *port;
1593 int retval, line = tty->index; 1604 int retval, line = tty->index;
1594 1605
1595 BUG_ON(!kernel_locked()); 1606 BUG_ON(!kernel_locked());
@@ -1606,16 +1617,18 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1606 1617
1607 /* 1618 /*
1608 * We take the semaphore inside uart_get to guarantee that we won't 1619 * We take the semaphore inside uart_get to guarantee that we won't
1609 * be re-entered while allocating the info structure, or while we 1620 * be re-entered while allocating the state structure, or while we
1610 * request any IRQs that the driver may need. This also has the nice 1621 * request any IRQs that the driver may need. This also has the nice
1611 * side-effect that it delays the action of uart_hangup, so we can 1622 * side-effect that it delays the action of uart_hangup, so we can
1612 * guarantee that info->port.tty will always contain something reasonable. 1623 * guarantee that state->port.tty will always contain something
1624 * reasonable.
1613 */ 1625 */
1614 state = uart_get(drv, line); 1626 state = uart_get(drv, line);
1615 if (IS_ERR(state)) { 1627 if (IS_ERR(state)) {
1616 retval = PTR_ERR(state); 1628 retval = PTR_ERR(state);
1617 goto fail; 1629 goto fail;
1618 } 1630 }
1631 port = &state->port;
1619 1632
1620 /* 1633 /*
1621 * Once we set tty->driver_data here, we are guaranteed that 1634 * Once we set tty->driver_data here, we are guaranteed that
@@ -1623,25 +1636,25 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1623 * Any failures from here onwards should not touch the count. 1636 * Any failures from here onwards should not touch the count.
1624 */ 1637 */
1625 tty->driver_data = state; 1638 tty->driver_data = state;
1626 state->port->info = &state->info; 1639 state->uart_port->state = state;
1627 tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; 1640 tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0;
1628 tty->alt_speed = 0; 1641 tty->alt_speed = 0;
1629 state->info.port.tty = tty; 1642 tty_port_tty_set(port, tty);
1630 1643
1631 /* 1644 /*
1632 * If the port is in the middle of closing, bail out now. 1645 * If the port is in the middle of closing, bail out now.
1633 */ 1646 */
1634 if (tty_hung_up_p(filp)) { 1647 if (tty_hung_up_p(filp)) {
1635 retval = -EAGAIN; 1648 retval = -EAGAIN;
1636 state->count--; 1649 port->count--;
1637 mutex_unlock(&state->mutex); 1650 mutex_unlock(&port->mutex);
1638 goto fail; 1651 goto fail;
1639 } 1652 }
1640 1653
1641 /* 1654 /*
1642 * Make sure the device is in D0 state. 1655 * Make sure the device is in D0 state.
1643 */ 1656 */
1644 if (state->count == 1) 1657 if (port->count == 1)
1645 uart_change_pm(state, 0); 1658 uart_change_pm(state, 0);
1646 1659
1647 /* 1660 /*
@@ -1654,18 +1667,18 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1654 */ 1667 */
1655 if (retval == 0) 1668 if (retval == 0)
1656 retval = uart_block_til_ready(filp, state); 1669 retval = uart_block_til_ready(filp, state);
1657 mutex_unlock(&state->mutex); 1670 mutex_unlock(&port->mutex);
1658 1671
1659 /* 1672 /*
1660 * If this is the first open to succeed, adjust things to suit. 1673 * If this is the first open to succeed, adjust things to suit.
1661 */ 1674 */
1662 if (retval == 0 && !(state->info.flags & UIF_NORMAL_ACTIVE)) { 1675 if (retval == 0 && !(port->flags & ASYNC_NORMAL_ACTIVE)) {
1663 state->info.flags |= UIF_NORMAL_ACTIVE; 1676 set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
1664 1677
1665 uart_update_termios(state); 1678 uart_update_termios(state);
1666 } 1679 }
1667 1680
1668 fail: 1681fail:
1669 return retval; 1682 return retval;
1670} 1683}
1671 1684
@@ -1687,57 +1700,58 @@ static const char *uart_type(struct uart_port *port)
1687static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) 1700static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
1688{ 1701{
1689 struct uart_state *state = drv->state + i; 1702 struct uart_state *state = drv->state + i;
1703 struct tty_port *port = &state->port;
1690 int pm_state; 1704 int pm_state;
1691 struct uart_port *port = state->port; 1705 struct uart_port *uport = state->uart_port;
1692 char stat_buf[32]; 1706 char stat_buf[32];
1693 unsigned int status; 1707 unsigned int status;
1694 int mmio; 1708 int mmio;
1695 1709
1696 if (!port) 1710 if (!uport)
1697 return; 1711 return;
1698 1712
1699 mmio = port->iotype >= UPIO_MEM; 1713 mmio = uport->iotype >= UPIO_MEM;
1700 seq_printf(m, "%d: uart:%s %s%08llX irq:%d", 1714 seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
1701 port->line, uart_type(port), 1715 uport->line, uart_type(uport),
1702 mmio ? "mmio:0x" : "port:", 1716 mmio ? "mmio:0x" : "port:",
1703 mmio ? (unsigned long long)port->mapbase 1717 mmio ? (unsigned long long)uport->mapbase
1704 : (unsigned long long) port->iobase, 1718 : (unsigned long long)uport->iobase,
1705 port->irq); 1719 uport->irq);
1706 1720
1707 if (port->type == PORT_UNKNOWN) { 1721 if (uport->type == PORT_UNKNOWN) {
1708 seq_putc(m, '\n'); 1722 seq_putc(m, '\n');
1709 return; 1723 return;
1710 } 1724 }
1711 1725
1712 if (capable(CAP_SYS_ADMIN)) { 1726 if (capable(CAP_SYS_ADMIN)) {
1713 mutex_lock(&state->mutex); 1727 mutex_lock(&port->mutex);
1714 pm_state = state->pm_state; 1728 pm_state = state->pm_state;
1715 if (pm_state) 1729 if (pm_state)
1716 uart_change_pm(state, 0); 1730 uart_change_pm(state, 0);
1717 spin_lock_irq(&port->lock); 1731 spin_lock_irq(&uport->lock);
1718 status = port->ops->get_mctrl(port); 1732 status = uport->ops->get_mctrl(uport);
1719 spin_unlock_irq(&port->lock); 1733 spin_unlock_irq(&uport->lock);
1720 if (pm_state) 1734 if (pm_state)
1721 uart_change_pm(state, pm_state); 1735 uart_change_pm(state, pm_state);
1722 mutex_unlock(&state->mutex); 1736 mutex_unlock(&port->mutex);
1723 1737
1724 seq_printf(m, " tx:%d rx:%d", 1738 seq_printf(m, " tx:%d rx:%d",
1725 port->icount.tx, port->icount.rx); 1739 uport->icount.tx, uport->icount.rx);
1726 if (port->icount.frame) 1740 if (uport->icount.frame)
1727 seq_printf(m, " fe:%d", 1741 seq_printf(m, " fe:%d",
1728 port->icount.frame); 1742 uport->icount.frame);
1729 if (port->icount.parity) 1743 if (uport->icount.parity)
1730 seq_printf(m, " pe:%d", 1744 seq_printf(m, " pe:%d",
1731 port->icount.parity); 1745 uport->icount.parity);
1732 if (port->icount.brk) 1746 if (uport->icount.brk)
1733 seq_printf(m, " brk:%d", 1747 seq_printf(m, " brk:%d",
1734 port->icount.brk); 1748 uport->icount.brk);
1735 if (port->icount.overrun) 1749 if (uport->icount.overrun)
1736 seq_printf(m, " oe:%d", 1750 seq_printf(m, " oe:%d",
1737 port->icount.overrun); 1751 uport->icount.overrun);
1738 1752
1739#define INFOBIT(bit, str) \ 1753#define INFOBIT(bit, str) \
1740 if (port->mctrl & (bit)) \ 1754 if (uport->mctrl & (bit)) \
1741 strncat(stat_buf, (str), sizeof(stat_buf) - \ 1755 strncat(stat_buf, (str), sizeof(stat_buf) - \
1742 strlen(stat_buf) - 2) 1756 strlen(stat_buf) - 2)
1743#define STATBIT(bit, str) \ 1757#define STATBIT(bit, str) \
@@ -1958,7 +1972,7 @@ EXPORT_SYMBOL_GPL(uart_set_options);
1958 1972
1959static void uart_change_pm(struct uart_state *state, int pm_state) 1973static void uart_change_pm(struct uart_state *state, int pm_state)
1960{ 1974{
1961 struct uart_port *port = state->port; 1975 struct uart_port *port = state->uart_port;
1962 1976
1963 if (state->pm_state != pm_state) { 1977 if (state->pm_state != pm_state) {
1964 if (port->ops->pm) 1978 if (port->ops->pm)
@@ -1982,132 +1996,138 @@ static int serial_match_port(struct device *dev, void *data)
1982 return dev->devt == devt; /* Actually, only one tty per port */ 1996 return dev->devt == devt; /* Actually, only one tty per port */
1983} 1997}
1984 1998
1985int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) 1999int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
1986{ 2000{
1987 struct uart_state *state = drv->state + port->line; 2001 struct uart_state *state = drv->state + uport->line;
2002 struct tty_port *port = &state->port;
1988 struct device *tty_dev; 2003 struct device *tty_dev;
1989 struct uart_match match = {port, drv}; 2004 struct uart_match match = {uport, drv};
1990 2005
1991 mutex_lock(&state->mutex); 2006 mutex_lock(&port->mutex);
1992 2007
1993 if (!console_suspend_enabled && uart_console(port)) { 2008 if (!console_suspend_enabled && uart_console(uport)) {
1994 /* we're going to avoid suspending serial console */ 2009 /* we're going to avoid suspending serial console */
1995 mutex_unlock(&state->mutex); 2010 mutex_unlock(&port->mutex);
1996 return 0; 2011 return 0;
1997 } 2012 }
1998 2013
1999 tty_dev = device_find_child(port->dev, &match, serial_match_port); 2014 tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2000 if (device_may_wakeup(tty_dev)) { 2015 if (device_may_wakeup(tty_dev)) {
2001 enable_irq_wake(port->irq); 2016 enable_irq_wake(uport->irq);
2002 put_device(tty_dev); 2017 put_device(tty_dev);
2003 mutex_unlock(&state->mutex); 2018 mutex_unlock(&port->mutex);
2004 return 0; 2019 return 0;
2005 } 2020 }
2006 port->suspended = 1; 2021 uport->suspended = 1;
2007 2022
2008 if (state->info.flags & UIF_INITIALIZED) { 2023 if (port->flags & ASYNC_INITIALIZED) {
2009 const struct uart_ops *ops = port->ops; 2024 const struct uart_ops *ops = uport->ops;
2010 int tries; 2025 int tries;
2011 2026
2012 state->info.flags = (state->info.flags & ~UIF_INITIALIZED) 2027 set_bit(ASYNCB_SUSPENDED, &port->flags);
2013 | UIF_SUSPENDED; 2028 clear_bit(ASYNCB_INITIALIZED, &port->flags);
2014 2029
2015 spin_lock_irq(&port->lock); 2030 spin_lock_irq(&uport->lock);
2016 ops->stop_tx(port); 2031 ops->stop_tx(uport);
2017 ops->set_mctrl(port, 0); 2032 ops->set_mctrl(uport, 0);
2018 ops->stop_rx(port); 2033 ops->stop_rx(uport);
2019 spin_unlock_irq(&port->lock); 2034 spin_unlock_irq(&uport->lock);
2020 2035
2021 /* 2036 /*
2022 * Wait for the transmitter to empty. 2037 * Wait for the transmitter to empty.
2023 */ 2038 */
2024 for (tries = 3; !ops->tx_empty(port) && tries; tries--) 2039 for (tries = 3; !ops->tx_empty(uport) && tries; tries--)
2025 msleep(10); 2040 msleep(10);
2026 if (!tries) 2041 if (!tries)
2027 printk(KERN_ERR "%s%s%s%d: Unable to drain " 2042 printk(KERN_ERR "%s%s%s%d: Unable to drain "
2028 "transmitter\n", 2043 "transmitter\n",
2029 port->dev ? dev_name(port->dev) : "", 2044 uport->dev ? dev_name(uport->dev) : "",
2030 port->dev ? ": " : "", 2045 uport->dev ? ": " : "",
2031 drv->dev_name, 2046 drv->dev_name,
2032 drv->tty_driver->name_base + port->line); 2047 drv->tty_driver->name_base + uport->line);
2033 2048
2034 ops->shutdown(port); 2049 ops->shutdown(uport);
2035 } 2050 }
2036 2051
2037 /* 2052 /*
2038 * Disable the console device before suspending. 2053 * Disable the console device before suspending.
2039 */ 2054 */
2040 if (uart_console(port)) 2055 if (uart_console(uport))
2041 console_stop(port->cons); 2056 console_stop(uport->cons);
2042 2057
2043 uart_change_pm(state, 3); 2058 uart_change_pm(state, 3);
2044 2059
2045 mutex_unlock(&state->mutex); 2060 mutex_unlock(&port->mutex);
2046 2061
2047 return 0; 2062 return 0;
2048} 2063}
2049 2064
2050int uart_resume_port(struct uart_driver *drv, struct uart_port *port) 2065int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
2051{ 2066{
2052 struct uart_state *state = drv->state + port->line; 2067 struct uart_state *state = drv->state + uport->line;
2068 struct tty_port *port = &state->port;
2053 struct device *tty_dev; 2069 struct device *tty_dev;
2054 struct uart_match match = {port, drv}; 2070 struct uart_match match = {uport, drv};
2071 struct ktermios termios;
2055 2072
2056 mutex_lock(&state->mutex); 2073 mutex_lock(&port->mutex);
2057 2074
2058 if (!console_suspend_enabled && uart_console(port)) { 2075 if (!console_suspend_enabled && uart_console(uport)) {
2059 /* no need to resume serial console, it wasn't suspended */ 2076 /* no need to resume serial console, it wasn't suspended */
2060 mutex_unlock(&state->mutex); 2077 /*
2078 * First try to use the console cflag setting.
2079 */
2080 memset(&termios, 0, sizeof(struct ktermios));
2081 termios.c_cflag = uport->cons->cflag;
2082 /*
2083 * If that's unset, use the tty termios setting.
2084 */
2085 if (termios.c_cflag == 0)
2086 termios = *state->port.tty->termios;
2087 else {
2088 termios.c_ispeed = termios.c_ospeed =
2089 tty_termios_input_baud_rate(&termios);
2090 termios.c_ispeed = termios.c_ospeed =
2091 tty_termios_baud_rate(&termios);
2092 }
2093 uport->ops->set_termios(uport, &termios, NULL);
2094 mutex_unlock(&port->mutex);
2061 return 0; 2095 return 0;
2062 } 2096 }
2063 2097
2064 tty_dev = device_find_child(port->dev, &match, serial_match_port); 2098 tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2065 if (!port->suspended && device_may_wakeup(tty_dev)) { 2099 if (!uport->suspended && device_may_wakeup(tty_dev)) {
2066 disable_irq_wake(port->irq); 2100 disable_irq_wake(uport->irq);
2067 mutex_unlock(&state->mutex); 2101 mutex_unlock(&port->mutex);
2068 return 0; 2102 return 0;
2069 } 2103 }
2070 port->suspended = 0; 2104 uport->suspended = 0;
2071 2105
2072 /* 2106 /*
2073 * Re-enable the console device after suspending. 2107 * Re-enable the console device after suspending.
2074 */ 2108 */
2075 if (uart_console(port)) { 2109 if (uart_console(uport)) {
2076 struct ktermios termios;
2077
2078 /*
2079 * First try to use the console cflag setting.
2080 */
2081 memset(&termios, 0, sizeof(struct ktermios));
2082 termios.c_cflag = port->cons->cflag;
2083
2084 /*
2085 * If that's unset, use the tty termios setting.
2086 */
2087 if (state->info.port.tty && termios.c_cflag == 0)
2088 termios = *state->info.port.tty->termios;
2089
2090 uart_change_pm(state, 0); 2110 uart_change_pm(state, 0);
2091 port->ops->set_termios(port, &termios, NULL); 2111 uport->ops->set_termios(uport, &termios, NULL);
2092 console_start(port->cons); 2112 console_start(uport->cons);
2093 } 2113 }
2094 2114
2095 if (state->info.flags & UIF_SUSPENDED) { 2115 if (port->flags & ASYNC_SUSPENDED) {
2096 const struct uart_ops *ops = port->ops; 2116 const struct uart_ops *ops = uport->ops;
2097 int ret; 2117 int ret;
2098 2118
2099 uart_change_pm(state, 0); 2119 uart_change_pm(state, 0);
2100 spin_lock_irq(&port->lock); 2120 spin_lock_irq(&uport->lock);
2101 ops->set_mctrl(port, 0); 2121 ops->set_mctrl(uport, 0);
2102 spin_unlock_irq(&port->lock); 2122 spin_unlock_irq(&uport->lock);
2103 ret = ops->startup(port); 2123 ret = ops->startup(uport);
2104 if (ret == 0) { 2124 if (ret == 0) {
2105 uart_change_speed(state, NULL); 2125 uart_change_speed(state, NULL);
2106 spin_lock_irq(&port->lock); 2126 spin_lock_irq(&uport->lock);
2107 ops->set_mctrl(port, port->mctrl); 2127 ops->set_mctrl(uport, uport->mctrl);
2108 ops->start_tx(port); 2128 ops->start_tx(uport);
2109 spin_unlock_irq(&port->lock); 2129 spin_unlock_irq(&uport->lock);
2110 state->info.flags |= UIF_INITIALIZED; 2130 set_bit(ASYNCB_INITIALIZED, &port->flags);
2111 } else { 2131 } else {
2112 /* 2132 /*
2113 * Failed to resume - maybe hardware went away? 2133 * Failed to resume - maybe hardware went away?
@@ -2117,10 +2137,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
2117 uart_shutdown(state); 2137 uart_shutdown(state);
2118 } 2138 }
2119 2139
2120 state->info.flags &= ~UIF_SUSPENDED; 2140 clear_bit(ASYNCB_SUSPENDED, &port->flags);
2121 } 2141 }
2122 2142
2123 mutex_unlock(&state->mutex); 2143 mutex_unlock(&port->mutex);
2124 2144
2125 return 0; 2145 return 0;
2126} 2146}
@@ -2232,10 +2252,10 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
2232 int parity = 'n'; 2252 int parity = 'n';
2233 int flow = 'n'; 2253 int flow = 'n';
2234 2254
2235 if (!state || !state->port) 2255 if (!state || !state->uart_port)
2236 return -1; 2256 return -1;
2237 2257
2238 port = state->port; 2258 port = state->uart_port;
2239 if (!(port->ops->poll_get_char && port->ops->poll_put_char)) 2259 if (!(port->ops->poll_get_char && port->ops->poll_put_char))
2240 return -1; 2260 return -1;
2241 2261
@@ -2253,10 +2273,10 @@ static int uart_poll_get_char(struct tty_driver *driver, int line)
2253 struct uart_state *state = drv->state + line; 2273 struct uart_state *state = drv->state + line;
2254 struct uart_port *port; 2274 struct uart_port *port;
2255 2275
2256 if (!state || !state->port) 2276 if (!state || !state->uart_port)
2257 return -1; 2277 return -1;
2258 2278
2259 port = state->port; 2279 port = state->uart_port;
2260 return port->ops->poll_get_char(port); 2280 return port->ops->poll_get_char(port);
2261} 2281}
2262 2282
@@ -2266,10 +2286,10 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch)
2266 struct uart_state *state = drv->state + line; 2286 struct uart_state *state = drv->state + line;
2267 struct uart_port *port; 2287 struct uart_port *port;
2268 2288
2269 if (!state || !state->port) 2289 if (!state || !state->uart_port)
2270 return; 2290 return;
2271 2291
2272 port = state->port; 2292 port = state->uart_port;
2273 port->ops->poll_put_char(port, ch); 2293 port->ops->poll_put_char(port, ch);
2274} 2294}
2275#endif 2295#endif
@@ -2360,14 +2380,12 @@ int uart_register_driver(struct uart_driver *drv)
2360 */ 2380 */
2361 for (i = 0; i < drv->nr; i++) { 2381 for (i = 0; i < drv->nr; i++) {
2362 struct uart_state *state = drv->state + i; 2382 struct uart_state *state = drv->state + i;
2383 struct tty_port *port = &state->port;
2363 2384
2364 state->close_delay = 500; /* .5 seconds */ 2385 tty_port_init(port);
2365 state->closing_wait = 30000; /* 30 seconds */ 2386 port->close_delay = 500; /* .5 seconds */
2366 mutex_init(&state->mutex); 2387 port->closing_wait = 30000; /* 30 seconds */
2367 2388 tasklet_init(&state->tlet, uart_tasklet_action,
2368 tty_port_init(&state->info.port);
2369 init_waitqueue_head(&state->info.delta_msr_wait);
2370 tasklet_init(&state->info.tlet, uart_tasklet_action,
2371 (unsigned long)state); 2389 (unsigned long)state);
2372 } 2390 }
2373 2391
@@ -2415,62 +2433,64 @@ struct tty_driver *uart_console_device(struct console *co, int *index)
2415 * level uart drivers to expand uart_port, rather than having yet 2433 * level uart drivers to expand uart_port, rather than having yet
2416 * more levels of structures. 2434 * more levels of structures.
2417 */ 2435 */
2418int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) 2436int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
2419{ 2437{
2420 struct uart_state *state; 2438 struct uart_state *state;
2439 struct tty_port *port;
2421 int ret = 0; 2440 int ret = 0;
2422 struct device *tty_dev; 2441 struct device *tty_dev;
2423 2442
2424 BUG_ON(in_interrupt()); 2443 BUG_ON(in_interrupt());
2425 2444
2426 if (port->line >= drv->nr) 2445 if (uport->line >= drv->nr)
2427 return -EINVAL; 2446 return -EINVAL;
2428 2447
2429 state = drv->state + port->line; 2448 state = drv->state + uport->line;
2449 port = &state->port;
2430 2450
2431 mutex_lock(&port_mutex); 2451 mutex_lock(&port_mutex);
2432 mutex_lock(&state->mutex); 2452 mutex_lock(&port->mutex);
2433 if (state->port) { 2453 if (state->uart_port) {
2434 ret = -EINVAL; 2454 ret = -EINVAL;
2435 goto out; 2455 goto out;
2436 } 2456 }
2437 2457
2438 state->port = port; 2458 state->uart_port = uport;
2439 state->pm_state = -1; 2459 state->pm_state = -1;
2440 2460
2441 port->cons = drv->cons; 2461 uport->cons = drv->cons;
2442 port->info = &state->info; 2462 uport->state = state;
2443 2463
2444 /* 2464 /*
2445 * If this port is a console, then the spinlock is already 2465 * If this port is a console, then the spinlock is already
2446 * initialised. 2466 * initialised.
2447 */ 2467 */
2448 if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) { 2468 if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) {
2449 spin_lock_init(&port->lock); 2469 spin_lock_init(&uport->lock);
2450 lockdep_set_class(&port->lock, &port_lock_key); 2470 lockdep_set_class(&uport->lock, &port_lock_key);
2451 } 2471 }
2452 2472
2453 uart_configure_port(drv, state, port); 2473 uart_configure_port(drv, state, uport);
2454 2474
2455 /* 2475 /*
2456 * Register the port whether it's detected or not. This allows 2476 * Register the port whether it's detected or not. This allows
2457 * setserial to be used to alter this ports parameters. 2477 * setserial to be used to alter this ports parameters.
2458 */ 2478 */
2459 tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev); 2479 tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
2460 if (likely(!IS_ERR(tty_dev))) { 2480 if (likely(!IS_ERR(tty_dev))) {
2461 device_init_wakeup(tty_dev, 1); 2481 device_init_wakeup(tty_dev, 1);
2462 device_set_wakeup_enable(tty_dev, 0); 2482 device_set_wakeup_enable(tty_dev, 0);
2463 } else 2483 } else
2464 printk(KERN_ERR "Cannot register tty device on line %d\n", 2484 printk(KERN_ERR "Cannot register tty device on line %d\n",
2465 port->line); 2485 uport->line);
2466 2486
2467 /* 2487 /*
2468 * Ensure UPF_DEAD is not set. 2488 * Ensure UPF_DEAD is not set.
2469 */ 2489 */
2470 port->flags &= ~UPF_DEAD; 2490 uport->flags &= ~UPF_DEAD;
2471 2491
2472 out: 2492 out:
2473 mutex_unlock(&state->mutex); 2493 mutex_unlock(&port->mutex);
2474 mutex_unlock(&port_mutex); 2494 mutex_unlock(&port_mutex);
2475 2495
2476 return ret; 2496 return ret;
@@ -2485,16 +2505,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2485 * core driver. No further calls will be made to the low-level code 2505 * core driver. No further calls will be made to the low-level code
2486 * for this port. 2506 * for this port.
2487 */ 2507 */
2488int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port) 2508int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
2489{ 2509{
2490 struct uart_state *state = drv->state + port->line; 2510 struct uart_state *state = drv->state + uport->line;
2491 struct uart_info *info; 2511 struct tty_port *port = &state->port;
2492 2512
2493 BUG_ON(in_interrupt()); 2513 BUG_ON(in_interrupt());
2494 2514
2495 if (state->port != port) 2515 if (state->uart_port != uport)
2496 printk(KERN_ALERT "Removing wrong port: %p != %p\n", 2516 printk(KERN_ALERT "Removing wrong port: %p != %p\n",
2497 state->port, port); 2517 state->uart_port, uport);
2498 2518
2499 mutex_lock(&port_mutex); 2519 mutex_lock(&port_mutex);
2500 2520
@@ -2502,37 +2522,35 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
2502 * Mark the port "dead" - this prevents any opens from 2522 * Mark the port "dead" - this prevents any opens from
2503 * succeeding while we shut down the port. 2523 * succeeding while we shut down the port.
2504 */ 2524 */
2505 mutex_lock(&state->mutex); 2525 mutex_lock(&port->mutex);
2506 port->flags |= UPF_DEAD; 2526 uport->flags |= UPF_DEAD;
2507 mutex_unlock(&state->mutex); 2527 mutex_unlock(&port->mutex);
2508 2528
2509 /* 2529 /*
2510 * Remove the devices from the tty layer 2530 * Remove the devices from the tty layer
2511 */ 2531 */
2512 tty_unregister_device(drv->tty_driver, port->line); 2532 tty_unregister_device(drv->tty_driver, uport->line);
2513 2533
2514 info = &state->info; 2534 if (port->tty)
2515 if (info && info->port.tty) 2535 tty_vhangup(port->tty);
2516 tty_vhangup(info->port.tty);
2517 2536
2518 /* 2537 /*
2519 * Free the port IO and memory resources, if any. 2538 * Free the port IO and memory resources, if any.
2520 */ 2539 */
2521 if (port->type != PORT_UNKNOWN) 2540 if (uport->type != PORT_UNKNOWN)
2522 port->ops->release_port(port); 2541 uport->ops->release_port(uport);
2523 2542
2524 /* 2543 /*
2525 * Indicate that there isn't a port here anymore. 2544 * Indicate that there isn't a port here anymore.
2526 */ 2545 */
2527 port->type = PORT_UNKNOWN; 2546 uport->type = PORT_UNKNOWN;
2528 2547
2529 /* 2548 /*
2530 * Kill the tasklet, and free resources. 2549 * Kill the tasklet, and free resources.
2531 */ 2550 */
2532 if (info) 2551 tasklet_kill(&state->tlet);
2533 tasklet_kill(&info->tlet);
2534 2552
2535 state->port = NULL; 2553 state->uart_port = NULL;
2536 mutex_unlock(&port_mutex); 2554 mutex_unlock(&port_mutex);
2537 2555
2538 return 0; 2556 return 0;
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index ed4648b556c7..a3bb49031a7f 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -884,6 +884,7 @@ static struct pcmcia_device_id serial_ids[] = {
884 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 884 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
885 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 885 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
886 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), 886 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
887 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "COMpad2.cis"),
887 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), 888 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
888 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), 889 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
889 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), 890 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 52db5cc3f900..2e71bbc04dac 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -154,7 +154,7 @@ static void ks8695uart_disable_ms(struct uart_port *port)
154static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) 154static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
155{ 155{
156 struct uart_port *port = dev_id; 156 struct uart_port *port = dev_id;
157 struct tty_struct *tty = port->info->port.tty; 157 struct tty_struct *tty = port->state->port.tty;
158 unsigned int status, ch, lsr, flg, max_count = 256; 158 unsigned int status, ch, lsr, flg, max_count = 256;
159 159
160 status = UART_GET_LSR(port); /* clears pending LSR interrupts */ 160 status = UART_GET_LSR(port); /* clears pending LSR interrupts */
@@ -210,7 +210,7 @@ ignore_char:
210static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id) 210static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id)
211{ 211{
212 struct uart_port *port = dev_id; 212 struct uart_port *port = dev_id;
213 struct circ_buf *xmit = &port->info->xmit; 213 struct circ_buf *xmit = &port->state->xmit;
214 unsigned int count; 214 unsigned int count;
215 215
216 if (port->x_char) { 216 if (port->x_char) {
@@ -266,7 +266,7 @@ static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id)
266 if (status & URMS_URTERI) 266 if (status & URMS_URTERI)
267 port->icount.rng++; 267 port->icount.rng++;
268 268
269 wake_up_interruptible(&port->info->delta_msr_wait); 269 wake_up_interruptible(&port->state->port.delta_msr_wait);
270 270
271 return IRQ_HANDLED; 271 return IRQ_HANDLED;
272} 272}
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index a7bf024a8286..ea744707c4d6 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -138,7 +138,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
138 138
139static void lh7a40xuart_rx_chars (struct uart_port* port) 139static void lh7a40xuart_rx_chars (struct uart_port* port)
140{ 140{
141 struct tty_struct* tty = port->info->port.tty; 141 struct tty_struct* tty = port->state->port.tty;
142 int cbRxMax = 256; /* (Gross) limit on receive */ 142 int cbRxMax = 256; /* (Gross) limit on receive */
143 unsigned int data; /* Received data and status */ 143 unsigned int data; /* Received data and status */
144 unsigned int flag; 144 unsigned int flag;
@@ -184,7 +184,7 @@ static void lh7a40xuart_rx_chars (struct uart_port* port)
184 184
185static void lh7a40xuart_tx_chars (struct uart_port* port) 185static void lh7a40xuart_tx_chars (struct uart_port* port)
186{ 186{
187 struct circ_buf* xmit = &port->info->xmit; 187 struct circ_buf* xmit = &port->state->xmit;
188 int cbTxMax = port->fifosize; 188 int cbTxMax = port->fifosize;
189 189
190 if (port->x_char) { 190 if (port->x_char) {
@@ -241,7 +241,7 @@ static void lh7a40xuart_modem_status (struct uart_port* port)
241 if (delta & CTS) 241 if (delta & CTS)
242 uart_handle_cts_change (port, status & CTS); 242 uart_handle_cts_change (port, status & CTS);
243 243
244 wake_up_interruptible (&port->info->delta_msr_wait); 244 wake_up_interruptible (&port->state->port.delta_msr_wait);
245} 245}
246 246
247static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) 247static irqreturn_t lh7a40xuart_int (int irq, void* dev_id)
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 54dd16d66a4b..0f7cf4c453e6 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -272,7 +272,7 @@ static void serial_txx9_initialize(struct uart_port *port)
272static inline void 272static inline void
273receive_chars(struct uart_txx9_port *up, unsigned int *status) 273receive_chars(struct uart_txx9_port *up, unsigned int *status)
274{ 274{
275 struct tty_struct *tty = up->port.info->port.tty; 275 struct tty_struct *tty = up->port.state->port.tty;
276 unsigned char ch; 276 unsigned char ch;
277 unsigned int disr = *status; 277 unsigned int disr = *status;
278 int max_count = 256; 278 int max_count = 256;
@@ -348,7 +348,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status)
348 348
349static inline void transmit_chars(struct uart_txx9_port *up) 349static inline void transmit_chars(struct uart_txx9_port *up)
350{ 350{
351 struct circ_buf *xmit = &up->port.info->xmit; 351 struct circ_buf *xmit = &up->port.state->xmit;
352 int count; 352 int count;
353 353
354 if (up->port.x_char) { 354 if (up->port.x_char) {
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 32dc2fc50e6b..85119fb7cb50 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -361,7 +361,7 @@ static inline int sci_rxroom(struct uart_port *port)
361 361
362static void sci_transmit_chars(struct uart_port *port) 362static void sci_transmit_chars(struct uart_port *port)
363{ 363{
364 struct circ_buf *xmit = &port->info->xmit; 364 struct circ_buf *xmit = &port->state->xmit;
365 unsigned int stopped = uart_tx_stopped(port); 365 unsigned int stopped = uart_tx_stopped(port);
366 unsigned short status; 366 unsigned short status;
367 unsigned short ctrl; 367 unsigned short ctrl;
@@ -426,7 +426,7 @@ static void sci_transmit_chars(struct uart_port *port)
426static inline void sci_receive_chars(struct uart_port *port) 426static inline void sci_receive_chars(struct uart_port *port)
427{ 427{
428 struct sci_port *sci_port = to_sci_port(port); 428 struct sci_port *sci_port = to_sci_port(port);
429 struct tty_struct *tty = port->info->port.tty; 429 struct tty_struct *tty = port->state->port.tty;
430 int i, count, copied = 0; 430 int i, count, copied = 0;
431 unsigned short status; 431 unsigned short status;
432 unsigned char flag; 432 unsigned char flag;
@@ -546,7 +546,7 @@ static inline int sci_handle_errors(struct uart_port *port)
546{ 546{
547 int copied = 0; 547 int copied = 0;
548 unsigned short status = sci_in(port, SCxSR); 548 unsigned short status = sci_in(port, SCxSR);
549 struct tty_struct *tty = port->info->port.tty; 549 struct tty_struct *tty = port->state->port.tty;
550 550
551 if (status & SCxSR_ORER(port)) { 551 if (status & SCxSR_ORER(port)) {
552 /* overrun error */ 552 /* overrun error */
@@ -600,7 +600,7 @@ static inline int sci_handle_errors(struct uart_port *port)
600 600
601static inline int sci_handle_fifo_overrun(struct uart_port *port) 601static inline int sci_handle_fifo_overrun(struct uart_port *port)
602{ 602{
603 struct tty_struct *tty = port->info->port.tty; 603 struct tty_struct *tty = port->state->port.tty;
604 int copied = 0; 604 int copied = 0;
605 605
606 if (port->type != PORT_SCIF) 606 if (port->type != PORT_SCIF)
@@ -623,7 +623,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
623{ 623{
624 int copied = 0; 624 int copied = 0;
625 unsigned short status = sci_in(port, SCxSR); 625 unsigned short status = sci_in(port, SCxSR);
626 struct tty_struct *tty = port->info->port.tty; 626 struct tty_struct *tty = port->state->port.tty;
627 struct sci_port *s = to_sci_port(port); 627 struct sci_port *s = to_sci_port(port);
628 628
629 if (uart_handle_break(port)) 629 if (uart_handle_break(port))
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index d5276c012f78..9794e0cd3dcc 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -469,9 +469,9 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
469 return; 469 return;
470 } 470 }
471 471
472 if (port->sc_port.info) { 472 if (port->sc_port.state) {
473 /* The serial_core stuffs are initilized, use them */ 473 /* The serial_core stuffs are initilized, use them */
474 tty = port->sc_port.info->port.tty; 474 tty = port->sc_port.state->port.tty;
475 } 475 }
476 else { 476 else {
477 /* Not registered yet - can't pass to tty layer. */ 477 /* Not registered yet - can't pass to tty layer. */
@@ -550,9 +550,9 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
550 550
551 BUG_ON(!port->sc_is_asynch); 551 BUG_ON(!port->sc_is_asynch);
552 552
553 if (port->sc_port.info) { 553 if (port->sc_port.state) {
554 /* We're initilized, using serial core infrastructure */ 554 /* We're initilized, using serial core infrastructure */
555 xmit = &port->sc_port.info->xmit; 555 xmit = &port->sc_port.state->xmit;
556 } else { 556 } else {
557 /* Probably sn_sal_switch_to_asynch has been run but serial core isn't 557 /* Probably sn_sal_switch_to_asynch has been run but serial core isn't
558 * initilized yet. Just return. Writes are going through 558 * initilized yet. Just return. Writes are going through
@@ -927,7 +927,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
927 /* We can't look at the xmit buffer if we're not registered with serial core 927 /* We can't look at the xmit buffer if we're not registered with serial core
928 * yet. So only do the fancy recovery after registering 928 * yet. So only do the fancy recovery after registering
929 */ 929 */
930 if (!port->sc_port.info) { 930 if (!port->sc_port.state) {
931 /* Not yet registered with serial core - simple case */ 931 /* Not yet registered with serial core - simple case */
932 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count); 932 puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
933 return; 933 return;
@@ -936,8 +936,8 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
936 /* somebody really wants this output, might be an 936 /* somebody really wants this output, might be an
937 * oops, kdb, panic, etc. make sure they get it. */ 937 * oops, kdb, panic, etc. make sure they get it. */
938 if (spin_is_locked(&port->sc_port.lock)) { 938 if (spin_is_locked(&port->sc_port.lock)) {
939 int lhead = port->sc_port.info->xmit.head; 939 int lhead = port->sc_port.state->xmit.head;
940 int ltail = port->sc_port.info->xmit.tail; 940 int ltail = port->sc_port.state->xmit.tail;
941 int counter, got_lock = 0; 941 int counter, got_lock = 0;
942 942
943 /* 943 /*
@@ -962,13 +962,13 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
962 break; 962 break;
963 } else { 963 } else {
964 /* still locked */ 964 /* still locked */
965 if ((lhead != port->sc_port.info->xmit.head) 965 if ((lhead != port->sc_port.state->xmit.head)
966 || (ltail != 966 || (ltail !=
967 port->sc_port.info->xmit.tail)) { 967 port->sc_port.state->xmit.tail)) {
968 lhead = 968 lhead =
969 port->sc_port.info->xmit.head; 969 port->sc_port.state->xmit.head;
970 ltail = 970 ltail =
971 port->sc_port.info->xmit.tail; 971 port->sc_port.state->xmit.tail;
972 counter = 0; 972 counter = 0;
973 } 973 }
974 } 974 }
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 1df5325faab2..d548652dee50 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -184,8 +184,8 @@ static struct tty_struct *receive_chars(struct uart_port *port)
184{ 184{
185 struct tty_struct *tty = NULL; 185 struct tty_struct *tty = NULL;
186 186
187 if (port->info != NULL) /* Unopened serial console */ 187 if (port->state != NULL) /* Unopened serial console */
188 tty = port->info->port.tty; 188 tty = port->state->port.tty;
189 189
190 if (sunhv_ops->receive_chars(port, tty)) 190 if (sunhv_ops->receive_chars(port, tty))
191 sun_do_break(); 191 sun_do_break();
@@ -197,10 +197,10 @@ static void transmit_chars(struct uart_port *port)
197{ 197{
198 struct circ_buf *xmit; 198 struct circ_buf *xmit;
199 199
200 if (!port->info) 200 if (!port->state)
201 return; 201 return;
202 202
203 xmit = &port->info->xmit; 203 xmit = &port->state->xmit;
204 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) 204 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
205 return; 205 return;
206 206
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 0355efe115d9..d1ad34128635 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -117,8 +117,8 @@ receive_chars(struct uart_sunsab_port *up,
117 int count = 0; 117 int count = 0;
118 int i; 118 int i;
119 119
120 if (up->port.info != NULL) /* Unopened serial console */ 120 if (up->port.state != NULL) /* Unopened serial console */
121 tty = up->port.info->port.tty; 121 tty = up->port.state->port.tty;
122 122
123 /* Read number of BYTES (Character + Status) available. */ 123 /* Read number of BYTES (Character + Status) available. */
124 if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { 124 if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
@@ -229,7 +229,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *);
229static void transmit_chars(struct uart_sunsab_port *up, 229static void transmit_chars(struct uart_sunsab_port *up,
230 union sab82532_irq_status *stat) 230 union sab82532_irq_status *stat)
231{ 231{
232 struct circ_buf *xmit = &up->port.info->xmit; 232 struct circ_buf *xmit = &up->port.state->xmit;
233 int i; 233 int i;
234 234
235 if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) { 235 if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
@@ -297,7 +297,7 @@ static void check_status(struct uart_sunsab_port *up,
297 up->port.icount.dsr++; 297 up->port.icount.dsr++;
298 } 298 }
299 299
300 wake_up_interruptible(&up->port.info->delta_msr_wait); 300 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
301} 301}
302 302
303static irqreturn_t sunsab_interrupt(int irq, void *dev_id) 303static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
@@ -429,7 +429,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *up)
429static void sunsab_start_tx(struct uart_port *port) 429static void sunsab_start_tx(struct uart_port *port)
430{ 430{
431 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 431 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
432 struct circ_buf *xmit = &up->port.info->xmit; 432 struct circ_buf *xmit = &up->port.state->xmit;
433 int i; 433 int i;
434 434
435 up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); 435 up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 47c6837850b1..68d262b15749 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
311static struct tty_struct * 311static struct tty_struct *
312receive_chars(struct uart_sunsu_port *up, unsigned char *status) 312receive_chars(struct uart_sunsu_port *up, unsigned char *status)
313{ 313{
314 struct tty_struct *tty = up->port.info->port.tty; 314 struct tty_struct *tty = up->port.state->port.tty;
315 unsigned char ch, flag; 315 unsigned char ch, flag;
316 int max_count = 256; 316 int max_count = 256;
317 int saw_console_brk = 0; 317 int saw_console_brk = 0;
@@ -389,7 +389,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
389 389
390static void transmit_chars(struct uart_sunsu_port *up) 390static void transmit_chars(struct uart_sunsu_port *up)
391{ 391{
392 struct circ_buf *xmit = &up->port.info->xmit; 392 struct circ_buf *xmit = &up->port.state->xmit;
393 int count; 393 int count;
394 394
395 if (up->port.x_char) { 395 if (up->port.x_char) {
@@ -441,7 +441,7 @@ static void check_modem_status(struct uart_sunsu_port *up)
441 if (status & UART_MSR_DCTS) 441 if (status & UART_MSR_DCTS)
442 uart_handle_cts_change(&up->port, status & UART_MSR_CTS); 442 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
443 443
444 wake_up_interruptible(&up->port.info->delta_msr_wait); 444 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
445} 445}
446 446
447static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) 447static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index e09d3cebb4fb..ef693ae22e7f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -328,9 +328,9 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
328 unsigned char ch, r1, flag; 328 unsigned char ch, r1, flag;
329 329
330 tty = NULL; 330 tty = NULL;
331 if (up->port.info != NULL && /* Unopened serial console */ 331 if (up->port.state != NULL && /* Unopened serial console */
332 up->port.info->port.tty != NULL) /* Keyboard || mouse */ 332 up->port.state->port.tty != NULL) /* Keyboard || mouse */
333 tty = up->port.info->port.tty; 333 tty = up->port.state->port.tty;
334 334
335 for (;;) { 335 for (;;) {
336 336
@@ -451,7 +451,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
451 uart_handle_cts_change(&up->port, 451 uart_handle_cts_change(&up->port,
452 (status & CTS)); 452 (status & CTS));
453 453
454 wake_up_interruptible(&up->port.info->delta_msr_wait); 454 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
455 } 455 }
456 456
457 up->prev_status = status; 457 up->prev_status = status;
@@ -501,9 +501,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
501 return; 501 return;
502 } 502 }
503 503
504 if (up->port.info == NULL) 504 if (up->port.state == NULL)
505 goto ack_tx_int; 505 goto ack_tx_int;
506 xmit = &up->port.info->xmit; 506 xmit = &up->port.state->xmit;
507 if (uart_circ_empty(xmit)) 507 if (uart_circ_empty(xmit))
508 goto ack_tx_int; 508 goto ack_tx_int;
509 509
@@ -705,7 +705,7 @@ static void sunzilog_start_tx(struct uart_port *port)
705 port->icount.tx++; 705 port->icount.tx++;
706 port->x_char = 0; 706 port->x_char = 0;
707 } else { 707 } else {
708 struct circ_buf *xmit = &port->info->xmit; 708 struct circ_buf *xmit = &port->state->xmit;
709 709
710 writeb(xmit->buf[xmit->tail], &channel->data); 710 writeb(xmit->buf[xmit->tail], &channel->data);
711 ZSDELAY(); 711 ZSDELAY();
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c
index 063a313b755c..34b31da01d09 100644
--- a/drivers/serial/timbuart.c
+++ b/drivers/serial/timbuart.c
@@ -77,7 +77,7 @@ static void timbuart_flush_buffer(struct uart_port *port)
77 77
78static void timbuart_rx_chars(struct uart_port *port) 78static void timbuart_rx_chars(struct uart_port *port)
79{ 79{
80 struct tty_struct *tty = port->info->port.tty; 80 struct tty_struct *tty = port->state->port.tty;
81 81
82 while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { 82 while (ioread32(port->membase + TIMBUART_ISR) & RXDP) {
83 u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); 83 u8 ch = ioread8(port->membase + TIMBUART_RXFIFO);
@@ -86,7 +86,7 @@ static void timbuart_rx_chars(struct uart_port *port)
86 } 86 }
87 87
88 spin_unlock(&port->lock); 88 spin_unlock(&port->lock);
89 tty_flip_buffer_push(port->info->port.tty); 89 tty_flip_buffer_push(port->state->port.tty);
90 spin_lock(&port->lock); 90 spin_lock(&port->lock);
91 91
92 dev_dbg(port->dev, "%s - total read %d bytes\n", 92 dev_dbg(port->dev, "%s - total read %d bytes\n",
@@ -95,7 +95,7 @@ static void timbuart_rx_chars(struct uart_port *port)
95 95
96static void timbuart_tx_chars(struct uart_port *port) 96static void timbuart_tx_chars(struct uart_port *port)
97{ 97{
98 struct circ_buf *xmit = &port->info->xmit; 98 struct circ_buf *xmit = &port->state->xmit;
99 99
100 while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) && 100 while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
101 !uart_circ_empty(xmit)) { 101 !uart_circ_empty(xmit)) {
@@ -118,7 +118,7 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
118{ 118{
119 struct timbuart_port *uart = 119 struct timbuart_port *uart =
120 container_of(port, struct timbuart_port, port); 120 container_of(port, struct timbuart_port, port);
121 struct circ_buf *xmit = &port->info->xmit; 121 struct circ_buf *xmit = &port->state->xmit;
122 122
123 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) 123 if (uart_circ_empty(xmit) || uart_tx_stopped(port))
124 return; 124 return;
@@ -231,7 +231,7 @@ static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier)
231 iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR); 231 iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR);
232 cts = timbuart_get_mctrl(port); 232 cts = timbuart_get_mctrl(port);
233 uart_handle_cts_change(port, cts & TIOCM_CTS); 233 uart_handle_cts_change(port, cts & TIOCM_CTS);
234 wake_up_interruptible(&port->info->delta_msr_wait); 234 wake_up_interruptible(&port->state->port.delta_msr_wait);
235 } 235 }
236 236
237 *ier |= CTS_DELTA; 237 *ier |= CTS_DELTA;
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 3317148a4b93..377f2712289e 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -75,7 +75,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS];
75 75
76static int ulite_receive(struct uart_port *port, int stat) 76static int ulite_receive(struct uart_port *port, int stat)
77{ 77{
78 struct tty_struct *tty = port->info->port.tty; 78 struct tty_struct *tty = port->state->port.tty;
79 unsigned char ch = 0; 79 unsigned char ch = 0;
80 char flag = TTY_NORMAL; 80 char flag = TTY_NORMAL;
81 81
@@ -125,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat)
125 125
126static int ulite_transmit(struct uart_port *port, int stat) 126static int ulite_transmit(struct uart_port *port, int stat)
127{ 127{
128 struct circ_buf *xmit = &port->info->xmit; 128 struct circ_buf *xmit = &port->state->xmit;
129 129
130 if (stat & ULITE_STATUS_TXFULL) 130 if (stat & ULITE_STATUS_TXFULL)
131 return 0; 131 return 0;
@@ -154,17 +154,22 @@ static int ulite_transmit(struct uart_port *port, int stat)
154static irqreturn_t ulite_isr(int irq, void *dev_id) 154static irqreturn_t ulite_isr(int irq, void *dev_id)
155{ 155{
156 struct uart_port *port = dev_id; 156 struct uart_port *port = dev_id;
157 int busy; 157 int busy, n = 0;
158 158
159 do { 159 do {
160 int stat = readb(port->membase + ULITE_STATUS); 160 int stat = readb(port->membase + ULITE_STATUS);
161 busy = ulite_receive(port, stat); 161 busy = ulite_receive(port, stat);
162 busy |= ulite_transmit(port, stat); 162 busy |= ulite_transmit(port, stat);
163 n++;
163 } while (busy); 164 } while (busy);
164 165
165 tty_flip_buffer_push(port->info->port.tty); 166 /* work done? */
166 167 if (n > 1) {
167 return IRQ_HANDLED; 168 tty_flip_buffer_push(port->state->port.tty);
169 return IRQ_HANDLED;
170 } else {
171 return IRQ_NONE;
172 }
168} 173}
169 174
170static unsigned int ulite_tx_empty(struct uart_port *port) 175static unsigned int ulite_tx_empty(struct uart_port *port)
@@ -221,7 +226,7 @@ static int ulite_startup(struct uart_port *port)
221 int ret; 226 int ret;
222 227
223 ret = request_irq(port->irq, ulite_isr, 228 ret = request_irq(port->irq, ulite_isr,
224 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port); 229 IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port);
225 if (ret) 230 if (ret)
226 return ret; 231 return ret;
227 232
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index e945e780b5c9..0c08f286a2ef 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -327,7 +327,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
327 unsigned char *p; 327 unsigned char *p;
328 unsigned int count; 328 unsigned int count;
329 struct uart_port *port = &qe_port->port; 329 struct uart_port *port = &qe_port->port;
330 struct circ_buf *xmit = &port->info->xmit; 330 struct circ_buf *xmit = &port->state->xmit;
331 331
332 bdp = qe_port->rx_cur; 332 bdp = qe_port->rx_cur;
333 333
@@ -466,7 +466,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
466 int i; 466 int i;
467 unsigned char ch, *cp; 467 unsigned char ch, *cp;
468 struct uart_port *port = &qe_port->port; 468 struct uart_port *port = &qe_port->port;
469 struct tty_struct *tty = port->info->port.tty; 469 struct tty_struct *tty = port->state->port.tty;
470 struct qe_bd *bdp; 470 struct qe_bd *bdp;
471 u16 status; 471 u16 status;
472 unsigned int flg; 472 unsigned int flg;
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index dac550e57c29..3beb6ab4fa68 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status)
318 char flag; 318 char flag;
319 int max_count = RX_MAX_COUNT; 319 int max_count = RX_MAX_COUNT;
320 320
321 tty = port->info->port.tty; 321 tty = port->state->port.tty;
322 lsr = *status; 322 lsr = *status;
323 323
324 do { 324 do {
@@ -386,7 +386,7 @@ static inline void check_modem_status(struct uart_port *port)
386 if (msr & UART_MSR_DCTS) 386 if (msr & UART_MSR_DCTS)
387 uart_handle_cts_change(port, msr & UART_MSR_CTS); 387 uart_handle_cts_change(port, msr & UART_MSR_CTS);
388 388
389 wake_up_interruptible(&port->info->delta_msr_wait); 389 wake_up_interruptible(&port->state->port.delta_msr_wait);
390} 390}
391 391
392static inline void transmit_chars(struct uart_port *port) 392static inline void transmit_chars(struct uart_port *port)
@@ -394,7 +394,7 @@ static inline void transmit_chars(struct uart_port *port)
394 struct circ_buf *xmit; 394 struct circ_buf *xmit;
395 int max_count = TX_MAX_COUNT; 395 int max_count = TX_MAX_COUNT;
396 396
397 xmit = &port->info->xmit; 397 xmit = &port->state->xmit;
398 398
399 if (port->x_char) { 399 if (port->x_char) {
400 siu_write(port, UART_TX, port->x_char); 400 siu_write(port, UART_TX, port->x_char);
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c
index d8c2809b1ab6..1a7fd3e70315 100644
--- a/drivers/serial/zs.c
+++ b/drivers/serial/zs.c
@@ -602,12 +602,12 @@ static void zs_receive_chars(struct zs_port *zport)
602 uart_insert_char(uport, status, Rx_OVR, ch, flag); 602 uart_insert_char(uport, status, Rx_OVR, ch, flag);
603 } 603 }
604 604
605 tty_flip_buffer_push(uport->info->port.tty); 605 tty_flip_buffer_push(uport->state->port.tty);
606} 606}
607 607
608static void zs_raw_transmit_chars(struct zs_port *zport) 608static void zs_raw_transmit_chars(struct zs_port *zport)
609{ 609{
610 struct circ_buf *xmit = &zport->port.info->xmit; 610 struct circ_buf *xmit = &zport->port.state->xmit;
611 611
612 /* XON/XOFF chars. */ 612 /* XON/XOFF chars. */
613 if (zport->port.x_char) { 613 if (zport->port.x_char) {
@@ -686,7 +686,7 @@ static void zs_status_handle(struct zs_port *zport, struct zs_port *zport_a)
686 uport->icount.rng++; 686 uport->icount.rng++;
687 687
688 if (delta) 688 if (delta)
689 wake_up_interruptible(&uport->info->delta_msr_wait); 689 wake_up_interruptible(&uport->state->port.delta_msr_wait);
690 690
691 spin_lock(&scc->zlock); 691 spin_lock(&scc->zlock);
692 } 692 }
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 10d3fcffe91c..82b34893e5b5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -47,6 +47,8 @@ source "drivers/staging/slicoss/Kconfig"
47 47
48source "drivers/staging/go7007/Kconfig" 48source "drivers/staging/go7007/Kconfig"
49 49
50source "drivers/staging/cx25821/Kconfig"
51
50source "drivers/staging/usbip/Kconfig" 52source "drivers/staging/usbip/Kconfig"
51 53
52source "drivers/staging/winbond/Kconfig" 54source "drivers/staging/winbond/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index c30093bae621..b1cad0d9ba72 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_STAGING) += staging.o
6obj-$(CONFIG_ET131X) += et131x/ 6obj-$(CONFIG_ET131X) += et131x/
7obj-$(CONFIG_SLICOSS) += slicoss/ 7obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_VIDEO_GO7007) += go7007/ 8obj-$(CONFIG_VIDEO_GO7007) += go7007/
9obj-$(CONFIG_VIDEO_CX25821) += cx25821/
9obj-$(CONFIG_USB_IP_COMMON) += usbip/ 10obj-$(CONFIG_USB_IP_COMMON) += usbip/
10obj-$(CONFIG_W35UND) += winbond/ 11obj-$(CONFIG_W35UND) += winbond/
11obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
new file mode 100644
index 000000000000..df7756a95fad
--- /dev/null
+++ b/drivers/staging/cx25821/Kconfig
@@ -0,0 +1,34 @@
1config VIDEO_CX25821
2 tristate "Conexant cx25821 support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
4 select I2C_ALGOBIT
5 select VIDEO_BTCX
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 select VIDEOBUF_DVB
9 select VIDEOBUF_DMA_SG
10 select VIDEO_CX25840
11 select VIDEO_CX2341X
12 ---help---
13 This is a video4linux driver for Conexant 25821 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called cx25821
18
19config VIDEO_CX25821_ALSA
20 tristate "Conexant 25821 DMA audio support"
21 depends on VIDEO_CX25821 && SND && EXPERIMENTAL
22 select SND_PCM
23 ---help---
24 This is a video4linux driver for direct (DMA) audio on
25 Conexant 25821 based capture cards using ALSA.
26
27 It only works with boards with function 01 enabled.
28 To check if your board supports, use lspci -n.
29 If supported, you should see 14f1:8801 or 14f1:8811
30 PCI device.
31
32 To compile this driver as a module, choose M here: the
33 module will be called cx25821-alsa.
34
diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile
new file mode 100644
index 000000000000..10f87f05d8e8
--- /dev/null
+++ b/drivers/staging/cx25821/Makefile
@@ -0,0 +1,14 @@
1cx25821-objs := cx25821-core.o cx25821-cards.o cx25821-i2c.o cx25821-gpio.o \
2 cx25821-medusa-video.o cx25821-video.o cx25821-video0.o cx25821-video1.o \
3 cx25821-video2.o cx25821-video3.o cx25821-video4.o cx25821-video5.o \
4 cx25821-video6.o cx25821-video7.o cx25821-vidups9.o cx25821-vidups10.o \
5 cx25821-audups11.o cx25821-video-upstream.o cx25821-video-upstream-ch2.o \
6 cx25821-audio-upstream.o cx25821-videoioctl.o
7
8obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
9obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
10
11EXTRA_CFLAGS += -Idrivers/media/video
12EXTRA_CFLAGS += -Idrivers/media/common/tuners
13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
14EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
new file mode 100644
index 000000000000..a9ba50b9888b
--- /dev/null
+++ b/drivers/staging/cx25821/README
@@ -0,0 +1,6 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4
5Please send patches to linux-media@vger.kernel.org
6
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
new file mode 100644
index 000000000000..e0eef12759e4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -0,0 +1,789 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on SAA713x ALSA driver and CX88 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/interrupt.h>
27#include <linux/vmalloc.h>
28#include <linux/dma-mapping.h>
29#include <linux/pci.h>
30
31#include <asm/delay.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37#include <sound/tlv.h>
38
39#include "cx25821.h"
40#include "cx25821-reg.h"
41
42#define AUDIO_SRAM_CHANNEL SRAM_CH08
43
44#define dprintk(level,fmt, arg...) if (debug >= level) \
45 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
46
47#define dprintk_core(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
49
50/****************************************************************************
51 Data type declarations - Can be moded to a header file later
52 ****************************************************************************/
53
54static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
55static int devno;
56
57struct cx25821_audio_dev {
58 struct cx25821_dev *dev;
59 struct cx25821_dmaqueue q;
60
61 /* pci i/o */
62 struct pci_dev *pci;
63
64 /* audio controls */
65 int irq;
66
67 struct snd_card *card;
68
69 unsigned long iobase;
70 spinlock_t reg_lock;
71 atomic_t count;
72
73 unsigned int dma_size;
74 unsigned int period_size;
75 unsigned int num_periods;
76
77 struct videobuf_dmabuf *dma_risc;
78
79 struct cx25821_buffer *buf;
80
81 struct snd_pcm_substream *substream;
82};
83typedef struct cx25821_audio_dev snd_cx25821_card_t;
84
85
86/****************************************************************************
87 Module global static vars
88 ****************************************************************************/
89
90static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
91static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
92static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 1 };
93
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
96
97module_param_array(index, int, NULL, 0444);
98MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
99
100/****************************************************************************
101 Module macros
102 ****************************************************************************/
103
104MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
105MODULE_AUTHOR("Hiep Huynh");
106MODULE_LICENSE("GPL");
107MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); //"{{Conexant,23881},"
108
109static unsigned int debug;
110module_param(debug, int, 0644);
111MODULE_PARM_DESC(debug, "enable debug messages");
112
113/****************************************************************************
114 Module specific funtions
115 ****************************************************************************/
116/* Constants taken from cx88-reg.h */
117#define AUD_INT_DN_RISCI1 (1 << 0)
118#define AUD_INT_UP_RISCI1 (1 << 1)
119#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
120#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
121#define AUD_INT_UP_RISCI2 (1 << 5)
122#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
123#define AUD_INT_DN_SYNC (1 << 12)
124#define AUD_INT_UP_SYNC (1 << 13)
125#define AUD_INT_RDS_DN_SYNC (1 << 14)
126#define AUD_INT_OPC_ERR (1 << 16)
127#define AUD_INT_BER_IRQ (1 << 20)
128#define AUD_INT_MCHG_IRQ (1 << 21)
129#define GP_COUNT_CONTROL_RESET 0x3
130
131#define PCI_MSK_AUD_EXT (1 << 4)
132#define PCI_MSK_AUD_INT (1 << 3)
133/*
134 * BOARD Specific: Sets audio DMA
135 */
136
137static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
138{
139 struct cx25821_buffer *buf = chip->buf;
140 struct cx25821_dev *dev = chip->dev;
141 struct sram_channel *audio_ch =
142 &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
143 u32 tmp = 0;
144
145 // enable output on the GPIO 0 for the MCLK ADC (Audio)
146 cx25821_set_gpiopin_direction(chip->dev, 0, 0);
147
148 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
149 cx_clear(AUD_INT_DMA_CTL,
150 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
151
152 /* setup fifo + format - out channel */
153 cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl,
154 buf->risc.dma);
155
156 /* sets bpl size */
157 cx_write(AUD_A_LNGTH, buf->bpl);
158
159 /* reset counter */
160 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3
161 atomic_set(&chip->count, 0);
162
163 //Set the input mode to 16-bit
164 tmp = cx_read(AUD_A_CFG);
165 cx_write(AUD_A_CFG,
166 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
167 FLD_AUD_CLK_ENABLE);
168
169 //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d "
170 // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1,
171 // chip->num_periods, buf->bpl * chip->num_periods);
172
173 /* Enables corresponding bits at AUD_INT_STAT */
174 cx_write(AUD_A_INT_MSK,
175 FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC |
176 FLD_AUD_DST_OPC_ERR);
177
178 /* Clean any pending interrupt bits already set */
179 cx_write(AUD_A_INT_STAT, ~0);
180
181 /* enable audio irqs */
182 cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
183
184 // Turn on audio downstream fifo and risc enable 0x101
185 tmp = cx_read(AUD_INT_DMA_CTL);
186 cx_set(AUD_INT_DMA_CTL,
187 tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
188
189 mdelay(100);
190 return 0;
191}
192
193/*
194 * BOARD Specific: Resets audio DMA
195 */
196static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip)
197{
198 struct cx25821_dev *dev = chip->dev;
199
200 /* stop dma */
201 cx_clear(AUD_INT_DMA_CTL,
202 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
203
204 /* disable irqs */
205 cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
206 cx_clear(AUD_A_INT_MSK,
207 AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 |
208 AUD_INT_DN_RISCI1);
209
210 return 0;
211}
212
213#define MAX_IRQ_LOOP 50
214
215/*
216 * BOARD Specific: IRQ dma bits
217 */
218static char *cx25821_aud_irqs[32] = {
219 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
220 NULL, /* reserved */
221 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
222 NULL, /* reserved */
223 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
224 NULL, /* reserved */
225 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
226 NULL, /* reserved */
227 "opc_err", "par_err", "rip_err", /* 16-18 */
228 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
229};
230
231/*
232 * BOARD Specific: Threats IRQ audio specific calls
233 */
234static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask)
235{
236 struct cx25821_dev *dev = chip->dev;
237
238 if (0 == (status & mask)) {
239 return;
240 }
241
242 cx_write(AUD_A_INT_STAT, status);
243 if (debug > 1 || (status & mask & ~0xff))
244 cx25821_print_irqbits(dev->name, "irq aud",
245 cx25821_aud_irqs,
246 ARRAY_SIZE(cx25821_aud_irqs), status,
247 mask);
248
249 /* risc op code error */
250 if (status & AUD_INT_OPC_ERR) {
251 printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
252 dev->name);
253
254 cx_clear(AUD_INT_DMA_CTL,
255 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
256 cx25821_sram_channel_dump_audio(dev,
257 &cx25821_sram_channels
258 [AUDIO_SRAM_CHANNEL]);
259 }
260 if (status & AUD_INT_DN_SYNC) {
261 printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
262 dev->name);
263 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
264 return;
265 }
266
267 /* risc1 downstream */
268 if (status & AUD_INT_DN_RISCI1) {
269 atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
270 snd_pcm_period_elapsed(chip->substream);
271 }
272}
273
274/*
275 * BOARD Specific: Handles IRQ calls
276 */
277static irqreturn_t cx25821_irq(int irq, void *dev_id)
278{
279 snd_cx25821_card_t *chip = dev_id;
280 struct cx25821_dev *dev = chip->dev;
281 u32 status, pci_status;
282 u32 audint_status, audint_mask;
283 int loop, handled = 0;
284 int audint_count = 0;
285
286 audint_status = cx_read(AUD_A_INT_STAT);
287 audint_mask = cx_read(AUD_A_INT_MSK);
288 audint_count = cx_read(AUD_A_GPCNT);
289 status = cx_read(PCI_INT_STAT);
290
291 for (loop = 0; loop < 1; loop++) {
292 status = cx_read(PCI_INT_STAT);
293 if (0 == status) {
294 status = cx_read(PCI_INT_STAT);
295 audint_status = cx_read(AUD_A_INT_STAT);
296 audint_mask = cx_read(AUD_A_INT_MSK);
297
298 if (status) {
299 handled = 1;
300 cx_write(PCI_INT_STAT, status);
301
302 cx25821_aud_irq(chip, audint_status,
303 audint_mask);
304 break;
305 } else
306 goto out;
307 }
308
309 handled = 1;
310 cx_write(PCI_INT_STAT, status);
311
312 cx25821_aud_irq(chip, audint_status, audint_mask);
313 }
314
315 pci_status = cx_read(PCI_INT_STAT);
316
317 if (handled)
318 cx_write(PCI_INT_STAT, pci_status);
319
320 out:
321 return IRQ_RETVAL(handled);
322}
323
324static int dsp_buffer_free(snd_cx25821_card_t * chip)
325{
326 BUG_ON(!chip->dma_size);
327
328 dprintk(2, "Freeing buffer\n");
329 videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
330 videobuf_dma_free(chip->dma_risc);
331 btcx_riscmem_free(chip->pci, &chip->buf->risc);
332 kfree(chip->buf);
333
334 chip->dma_risc = NULL;
335 chip->dma_size = 0;
336
337 return 0;
338}
339
340/****************************************************************************
341 ALSA PCM Interface
342 ****************************************************************************/
343
344/*
345 * Digital hardware definition
346 */
347#define DEFAULT_FIFO_SIZE 384
348static struct snd_pcm_hardware snd_cx25821_digital_hw = {
349 .info = SNDRV_PCM_INFO_MMAP |
350 SNDRV_PCM_INFO_INTERLEAVED |
351 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
352 .formats = SNDRV_PCM_FMTBIT_S16_LE,
353
354 .rates = SNDRV_PCM_RATE_48000,
355 .rate_min = 48000,
356 .rate_max = 48000,
357 .channels_min = 2,
358 .channels_max = 2,
359 /* Analog audio output will be full of clicks and pops if there
360 are not exactly four lines in the SRAM FIFO buffer. */
361 .period_bytes_min = DEFAULT_FIFO_SIZE / 3,
362 .period_bytes_max = DEFAULT_FIFO_SIZE / 3,
363 .periods_min = 1,
364 .periods_max = AUDIO_LINE_SIZE,
365 .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16
366};
367
368/*
369 * audio pcm capture open callback
370 */
371static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
372{
373 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
374 struct snd_pcm_runtime *runtime = substream->runtime;
375 int err;
376 unsigned int bpl = 0;
377
378 if (!chip) {
379 printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
380 " Can't proceed with open\n");
381 return -ENODEV;
382 }
383
384 err =
385 snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
386 if (err < 0)
387 goto _error;
388
389 chip->substream = substream;
390
391 runtime->hw = snd_cx25821_digital_hw;
392
393 if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
394 DEFAULT_FIFO_SIZE) {
395 bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; //since there are 3 audio Clusters
396 bpl &= ~7; /* must be multiple of 8 */
397
398 if (bpl > AUDIO_LINE_SIZE) {
399 bpl = AUDIO_LINE_SIZE;
400 }
401 runtime->hw.period_bytes_min = bpl;
402 runtime->hw.period_bytes_max = bpl;
403 }
404
405 return 0;
406 _error:
407 dprintk(1, "Error opening PCM!\n");
408 return err;
409}
410
411/*
412 * audio close callback
413 */
414static int snd_cx25821_close(struct snd_pcm_substream *substream)
415{
416 return 0;
417}
418
419/*
420 * hw_params callback
421 */
422static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
423 struct snd_pcm_hw_params *hw_params)
424{
425 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
426 struct videobuf_dmabuf *dma;
427
428 struct cx25821_buffer *buf;
429 int ret;
430
431 if (substream->runtime->dma_area) {
432 dsp_buffer_free(chip);
433 substream->runtime->dma_area = NULL;
434 }
435
436 chip->period_size = params_period_bytes(hw_params);
437 chip->num_periods = params_periods(hw_params);
438 chip->dma_size = chip->period_size * params_periods(hw_params);
439
440 BUG_ON(!chip->dma_size);
441 BUG_ON(chip->num_periods & (chip->num_periods - 1));
442
443 buf = videobuf_sg_alloc(sizeof(*buf));
444 if (NULL == buf)
445 return -ENOMEM;
446
447 if (chip->period_size > AUDIO_LINE_SIZE) {
448 chip->period_size = AUDIO_LINE_SIZE;
449 }
450
451 buf->vb.memory = V4L2_MEMORY_MMAP;
452 buf->vb.field = V4L2_FIELD_NONE;
453 buf->vb.width = chip->period_size;
454 buf->bpl = chip->period_size;
455 buf->vb.height = chip->num_periods;
456 buf->vb.size = chip->dma_size;
457
458 dma = videobuf_to_dma(&buf->vb);
459 videobuf_dma_init(dma);
460
461 ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
462 (PAGE_ALIGN(buf->vb.size) >>
463 PAGE_SHIFT));
464 if (ret < 0)
465 goto error;
466
467 ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
468 if (ret < 0)
469 goto error;
470
471 ret =
472 cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
473 buf->vb.width, buf->vb.height, 1);
474 if (ret < 0) {
475 printk(KERN_INFO
476 "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n");
477 goto error;
478 }
479
480 /* Loop back to start of program */
481 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
482 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
483 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
484
485 buf->vb.state = VIDEOBUF_PREPARED;
486
487 chip->buf = buf;
488 chip->dma_risc = dma;
489
490 substream->runtime->dma_area = chip->dma_risc->vmalloc;
491 substream->runtime->dma_bytes = chip->dma_size;
492 substream->runtime->dma_addr = 0;
493
494 return 0;
495
496 error:
497 kfree(buf);
498 return ret;
499}
500
501/*
502 * hw free callback
503 */
504static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
505{
506 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
507
508 if (substream->runtime->dma_area) {
509 dsp_buffer_free(chip);
510 substream->runtime->dma_area = NULL;
511 }
512
513 return 0;
514}
515
516/*
517 * prepare callback
518 */
519static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
520{
521 return 0;
522}
523
524/*
525 * trigger callback
526 */
527static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
528 int cmd)
529{
530 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
531 int err = 0;
532
533 /* Local interrupts are already disabled by ALSA */
534 spin_lock(&chip->reg_lock);
535
536 switch (cmd) {
537 case SNDRV_PCM_TRIGGER_START:
538 err = _cx25821_start_audio_dma(chip);
539 break;
540 case SNDRV_PCM_TRIGGER_STOP:
541 err = _cx25821_stop_audio_dma(chip);
542 break;
543 default:
544 err = -EINVAL;
545 break;
546 }
547
548 spin_unlock(&chip->reg_lock);
549
550 return err;
551}
552
553/*
554 * pointer callback
555 */
556static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
557 *substream)
558{
559 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
560 struct snd_pcm_runtime *runtime = substream->runtime;
561 u16 count;
562
563 count = atomic_read(&chip->count);
564
565 return runtime->period_size * (count & (runtime->periods - 1));
566}
567
568/*
569 * page callback (needed for mmap)
570 */
571static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
572 unsigned long offset)
573{
574 void *pageptr = substream->runtime->dma_area + offset;
575
576 return vmalloc_to_page(pageptr);
577}
578
579/*
580 * operators
581 */
582static struct snd_pcm_ops snd_cx25821_pcm_ops = {
583 .open = snd_cx25821_pcm_open,
584 .close = snd_cx25821_close,
585 .ioctl = snd_pcm_lib_ioctl,
586 .hw_params = snd_cx25821_hw_params,
587 .hw_free = snd_cx25821_hw_free,
588 .prepare = snd_cx25821_prepare,
589 .trigger = snd_cx25821_card_trigger,
590 .pointer = snd_cx25821_pointer,
591 .page = snd_cx25821_page,
592};
593
594/*
595 * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up
596 * the callbacks
597 */
598static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name)
599{
600 struct snd_pcm *pcm;
601 int err;
602
603 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
604 if (err < 0) {
605 printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
606 __func__);
607 return err;
608 }
609 pcm->private_data = chip;
610 pcm->info_flags = 0;
611 strcpy(pcm->name, name);
612 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
613
614 return 0;
615}
616
617/****************************************************************************
618 Basic Flow for Sound Devices
619 ****************************************************************************/
620
621/*
622 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
623 * Only boards with eeprom and byte 1 at eeprom=1 have it
624 */
625
626static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
627 {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
628 {0,}
629};
630
631MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
632
633/*
634 * Not used in the function snd_cx25821_dev_free so removing
635 * from the file.
636 */
637/*
638static int snd_cx25821_free(snd_cx25821_card_t *chip)
639{
640 if (chip->irq >= 0)
641 free_irq(chip->irq, chip);
642
643 cx25821_dev_unregister(chip->dev);
644 pci_disable_device(chip->pci);
645
646 return 0;
647}
648*/
649
650/*
651 * Component Destructor
652 */
653static void snd_cx25821_dev_free(struct snd_card *card)
654{
655 snd_cx25821_card_t *chip = card->private_data;
656
657 //snd_cx25821_free(chip);
658 snd_card_free(chip->card);
659}
660
661/*
662 * Alsa Constructor - Component probe
663 */
664static int cx25821_audio_initdev(struct cx25821_dev *dev)
665{
666 struct snd_card *card;
667 snd_cx25821_card_t *chip;
668 int err;
669
670 if (devno >= SNDRV_CARDS) {
671 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
672 __func__);
673 return (-ENODEV);
674 }
675
676 if (!enable[devno]) {
677 ++devno;
678 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
679 return (-ENOENT);
680 }
681
682 err = snd_card_create(index[devno], id[devno], THIS_MODULE,
683 sizeof(snd_cx25821_card_t), &card);
684 if (err < 0) {
685 printk(KERN_INFO
686 "DEBUG ERROR: cannot create snd_card_new in %s\n",
687 __func__);
688 return err;
689 }
690
691 strcpy(card->driver, "cx25821");
692
693 /* Card "creation" */
694 card->private_free = snd_cx25821_dev_free;
695 chip = (snd_cx25821_card_t *) card->private_data;
696 spin_lock_init(&chip->reg_lock);
697
698 chip->dev = dev;
699 chip->card = card;
700 chip->pci = dev->pci;
701 chip->iobase = pci_resource_start(dev->pci, 0);
702
703 chip->irq = dev->pci->irq;
704
705 err = request_irq(dev->pci->irq, cx25821_irq,
706 IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
707
708 if (err < 0) {
709 printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
710 chip->dev->name, dev->pci->irq);
711 goto error;
712 }
713
714 if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0) {
715 printk(KERN_INFO
716 "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
717 __func__);
718 goto error;
719 }
720
721 snd_card_set_dev(card, &chip->pci->dev);
722
723 strcpy(card->shortname, "cx25821");
724 sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
725 chip->iobase, chip->irq);
726 strcpy(card->mixername, "CX25821");
727
728 printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
729 card->driver, devno);
730
731 err = snd_card_register(card);
732 if (err < 0) {
733 printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
734 __func__);
735 goto error;
736 }
737
738 snd_cx25821_cards[devno] = card;
739
740 devno++;
741 return 0;
742
743 error:
744 snd_card_free(card);
745 return err;
746}
747
748/****************************************************************************
749 LINUX MODULE INIT
750 ****************************************************************************/
751static void cx25821_audio_fini(void)
752{
753 snd_card_free(snd_cx25821_cards[0]);
754}
755
756/*
757 * Module initializer
758 *
759 * Loops through present saa7134 cards, and assigns an ALSA device
760 * to each one
761 *
762 */
763static int cx25821_alsa_init(void)
764{
765 struct cx25821_dev *dev = NULL;
766 struct list_head *list;
767
768 list_for_each(list, &cx25821_devlist) {
769 dev = list_entry(list, struct cx25821_dev, devlist);
770 cx25821_audio_initdev(dev);
771 }
772
773 if (dev == NULL)
774 printk(KERN_INFO
775 "cx25821 ERROR ALSA: no cx25821 cards found\n");
776
777 return 0;
778
779}
780
781late_initcall(cx25821_alsa_init);
782module_exit(cx25821_audio_fini);
783
784/* ----------------------------------------------------------- */
785/*
786 * Local variables:
787 * c-basic-offset: 8
788 * End:
789 */
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
new file mode 100644
index 000000000000..ddddf651266b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -0,0 +1,804 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-audio-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <linux/delay.h>
35#include <asm/uaccess.h>
36
37MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
38MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
39MODULE_LICENSE("GPL");
40
41static int _intr_msk =
42 FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC |
43 FLD_AUD_SRC_OPC_ERR;
44
45int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
46 struct sram_channel *ch,
47 unsigned int bpl, u32 risc)
48{
49 unsigned int i, lines;
50 u32 cdt;
51
52 if (ch->cmds_start == 0) {
53 cx_write(ch->ptr1_reg, 0);
54 cx_write(ch->ptr2_reg, 0);
55 cx_write(ch->cnt2_reg, 0);
56 cx_write(ch->cnt1_reg, 0);
57 return 0;
58 }
59
60 bpl = (bpl + 7) & ~7; /* alignment */
61 cdt = ch->cdt;
62 lines = ch->fifo_size / bpl;
63
64 if (lines > 3) {
65 lines = 3;
66 }
67
68 BUG_ON(lines < 2);
69
70 /* write CDT */
71 for (i = 0; i < lines; i++) {
72 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
73 cx_write(cdt + 16 * i + 4, 0);
74 cx_write(cdt + 16 * i + 8, 0);
75 cx_write(cdt + 16 * i + 12, 0);
76 }
77
78 /* write CMDS */
79 cx_write(ch->cmds_start + 0, risc);
80
81 cx_write(ch->cmds_start + 4, 0);
82 cx_write(ch->cmds_start + 8, cdt);
83 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
84 cx_write(ch->cmds_start + 16, ch->ctrl_start);
85
86 //IQ size
87 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
88
89 for (i = 24; i < 80; i += 4)
90 cx_write(ch->cmds_start + i, 0);
91
92 /* fill registers */
93 cx_write(ch->ptr1_reg, ch->fifo_start);
94 cx_write(ch->ptr2_reg, cdt);
95 cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
96 cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
97
98 return 0;
99}
100
101static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
102 __le32 * rp,
103 dma_addr_t databuf_phys_addr,
104 unsigned int bpl,
105 int fifo_enable)
106{
107 unsigned int line;
108 struct sram_channel *sram_ch =
109 &dev->sram_channels[dev->_audio_upstream_channel_select];
110 int offset = 0;
111
112 /* scan lines */
113 for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) {
114 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
115 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
116 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
117
118 // Check if we need to enable the FIFO after the first 3 lines
119 // For the upstream audio channel, the risc engine will enable the FIFO.
120 if (fifo_enable && line == 2) {
121 *(rp++) = RISC_WRITECR;
122 *(rp++) = sram_ch->dma_ctl;
123 *(rp++) = sram_ch->fld_aud_fifo_en;
124 *(rp++) = 0x00000020;
125 }
126
127 offset += AUDIO_LINE_SIZE;
128 }
129
130 return rp;
131}
132
133int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
134 struct pci_dev *pci,
135 unsigned int bpl, unsigned int lines)
136{
137 __le32 *rp;
138 int fifo_enable = 0;
139 int frame = 0, i = 0;
140 int frame_size = AUDIO_DATA_BUF_SZ;
141 int databuf_offset = 0;
142 int risc_flag = RISC_CNT_INC;
143 dma_addr_t risc_phys_jump_addr;
144
145 /* Virtual address of Risc buffer program */
146 rp = dev->_risc_virt_addr;
147
148 /* sync instruction */
149 *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
150
151 for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) {
152 databuf_offset = frame_size * frame;
153
154 if (frame == 0) {
155 fifo_enable = 1;
156 risc_flag = RISC_CNT_RESET;
157 } else {
158 fifo_enable = 0;
159 risc_flag = RISC_CNT_INC;
160 }
161
162 //Calculate physical jump address
163 if ((frame + 1) == NUM_AUDIO_FRAMES) {
164 risc_phys_jump_addr =
165 dev->_risc_phys_start_addr +
166 RISC_SYNC_INSTRUCTION_SIZE;
167 } else {
168 risc_phys_jump_addr =
169 dev->_risc_phys_start_addr +
170 RISC_SYNC_INSTRUCTION_SIZE +
171 AUDIO_RISC_DMA_BUF_SIZE * (frame + 1);
172 }
173
174 rp = cx25821_risc_field_upstream_audio(dev, rp,
175 dev->
176 _audiodata_buf_phys_addr
177 + databuf_offset, bpl,
178 fifo_enable);
179
180 if (USE_RISC_NOOP_AUDIO) {
181 for (i = 0; i < NUM_NO_OPS; i++) {
182 *(rp++) = cpu_to_le32(RISC_NOOP);
183 }
184 }
185
186 // Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ
187 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
188 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
189 *(rp++) = cpu_to_le32(0);
190
191 //Recalculate virtual address based on frame index
192 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
193 (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
194 }
195
196 return 0;
197}
198
199void cx25821_free_memory_audio(struct cx25821_dev *dev)
200{
201 if (dev->_risc_virt_addr) {
202 pci_free_consistent(dev->pci, dev->_audiorisc_size,
203 dev->_risc_virt_addr, dev->_risc_phys_addr);
204 dev->_risc_virt_addr = NULL;
205 }
206
207 if (dev->_audiodata_buf_virt_addr) {
208 pci_free_consistent(dev->pci, dev->_audiodata_buf_size,
209 dev->_audiodata_buf_virt_addr,
210 dev->_audiodata_buf_phys_addr);
211 dev->_audiodata_buf_virt_addr = NULL;
212 }
213}
214
215void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
216{
217 struct sram_channel *sram_ch =
218 &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
219 u32 tmp = 0;
220
221 if (!dev->_audio_is_running) {
222 printk
223 ("cx25821: No audio file is currently running so return!\n");
224 return;
225 }
226 //Disable RISC interrupts
227 cx_write(sram_ch->int_msk, 0);
228
229 //Turn OFF risc and fifo enable in AUD_DMA_CNTRL
230 tmp = cx_read(sram_ch->dma_ctl);
231 cx_write(sram_ch->dma_ctl,
232 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
233
234 //Clear data buffer memory
235 if (dev->_audiodata_buf_virt_addr)
236 memset(dev->_audiodata_buf_virt_addr, 0,
237 dev->_audiodata_buf_size);
238
239 dev->_audio_is_running = 0;
240 dev->_is_first_audio_frame = 0;
241 dev->_audioframe_count = 0;
242 dev->_audiofile_status = END_OF_FILE;
243
244 if (dev->_irq_audio_queues) {
245 kfree(dev->_irq_audio_queues);
246 dev->_irq_audio_queues = NULL;
247 }
248
249 if (dev->_audiofilename != NULL)
250 kfree(dev->_audiofilename);
251}
252
253void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
254{
255 if (dev->_audio_is_running) {
256 cx25821_stop_upstream_audio(dev);
257 }
258
259 cx25821_free_memory_audio(dev);
260}
261
262int cx25821_get_audio_data(struct cx25821_dev *dev,
263 struct sram_channel *sram_ch)
264{
265 struct file *myfile;
266 int frame_index_temp = dev->_audioframe_index;
267 int i = 0;
268 int line_size = AUDIO_LINE_SIZE;
269 int frame_size = AUDIO_DATA_BUF_SZ;
270 int frame_offset = frame_size * frame_index_temp;
271 ssize_t vfs_read_retval = 0;
272 char mybuf[line_size];
273 loff_t file_offset = dev->_audioframe_count * frame_size;
274 loff_t pos;
275 mm_segment_t old_fs;
276
277 if (dev->_audiofile_status == END_OF_FILE)
278 return 0;
279
280 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
281
282 if (IS_ERR(myfile)) {
283 const int open_errno = -PTR_ERR(myfile);
284 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
285 __func__, dev->_audiofilename, open_errno);
286 return PTR_ERR(myfile);
287 } else {
288 if (!(myfile->f_op)) {
289 printk("%s: File has no file operations registered!\n",
290 __func__);
291 filp_close(myfile, NULL);
292 return -EIO;
293 }
294
295 if (!myfile->f_op->read) {
296 printk("%s: File has no READ operations registered! \n",
297 __func__);
298 filp_close(myfile, NULL);
299 return -EIO;
300 }
301
302 pos = myfile->f_pos;
303 old_fs = get_fs();
304 set_fs(KERNEL_DS);
305
306 for (i = 0; i < dev->_audio_lines_count; i++) {
307 pos = file_offset;
308
309 vfs_read_retval =
310 vfs_read(myfile, mybuf, line_size, &pos);
311
312 if (vfs_read_retval > 0 && vfs_read_retval == line_size
313 && dev->_audiodata_buf_virt_addr != NULL) {
314 memcpy((void *)(dev->_audiodata_buf_virt_addr +
315 frame_offset / 4), mybuf,
316 vfs_read_retval);
317 }
318
319 file_offset += vfs_read_retval;
320 frame_offset += vfs_read_retval;
321
322 if (vfs_read_retval < line_size) {
323 printk(KERN_INFO
324 "Done: exit %s() since no more bytes to read from Audio file.\n",
325 __func__);
326 break;
327 }
328 }
329
330 if (i > 0)
331 dev->_audioframe_count++;
332
333 dev->_audiofile_status =
334 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
335
336 set_fs(old_fs);
337 filp_close(myfile, NULL);
338 }
339
340 return 0;
341}
342
343static void cx25821_audioups_handler(struct work_struct *work)
344{
345 struct cx25821_dev *dev =
346 container_of(work, struct cx25821_dev, _audio_work_entry);
347
348 if (!dev) {
349 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
350 __func__);
351 return;
352 }
353
354 cx25821_get_audio_data(dev,
355 &dev->sram_channels[dev->
356 _audio_upstream_channel_select]);
357}
358
359int cx25821_openfile_audio(struct cx25821_dev *dev,
360 struct sram_channel *sram_ch)
361{
362 struct file *myfile;
363 int i = 0, j = 0;
364 int line_size = AUDIO_LINE_SIZE;
365 ssize_t vfs_read_retval = 0;
366 char mybuf[line_size];
367 loff_t pos;
368 loff_t offset = (unsigned long)0;
369 mm_segment_t old_fs;
370
371 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
372
373 if (IS_ERR(myfile)) {
374 const int open_errno = -PTR_ERR(myfile);
375 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
376 __func__, dev->_audiofilename, open_errno);
377 return PTR_ERR(myfile);
378 } else {
379 if (!(myfile->f_op)) {
380 printk("%s: File has no file operations registered! \n",
381 __func__);
382 filp_close(myfile, NULL);
383 return -EIO;
384 }
385
386 if (!myfile->f_op->read) {
387 printk("%s: File has no READ operations registered! \n",
388 __func__);
389 filp_close(myfile, NULL);
390 return -EIO;
391 }
392
393 pos = myfile->f_pos;
394 old_fs = get_fs();
395 set_fs(KERNEL_DS);
396
397 for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
398 for (i = 0; i < dev->_audio_lines_count; i++) {
399 pos = offset;
400
401 vfs_read_retval =
402 vfs_read(myfile, mybuf, line_size, &pos);
403
404 if (vfs_read_retval > 0
405 && vfs_read_retval == line_size
406 && dev->_audiodata_buf_virt_addr != NULL) {
407 memcpy((void *)(dev->
408 _audiodata_buf_virt_addr
409 + offset / 4), mybuf,
410 vfs_read_retval);
411 }
412
413 offset += vfs_read_retval;
414
415 if (vfs_read_retval < line_size) {
416 printk(KERN_INFO
417 "Done: exit %s() since no more bytes to read from Audio file.\n",
418 __func__);
419 break;
420 }
421 }
422
423 if (i > 0) {
424 dev->_audioframe_count++;
425 }
426
427 if (vfs_read_retval < line_size) {
428 break;
429 }
430 }
431
432 dev->_audiofile_status =
433 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
434
435 set_fs(old_fs);
436 myfile->f_pos = 0;
437 filp_close(myfile, NULL);
438 }
439
440 return 0;
441}
442
443static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
444 struct sram_channel *sram_ch,
445 int bpl)
446{
447 int ret = 0;
448 dma_addr_t dma_addr;
449 dma_addr_t data_dma_addr;
450
451 cx25821_free_memory_audio(dev);
452
453 dev->_risc_virt_addr =
454 pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size,
455 &dma_addr);
456 dev->_risc_virt_start_addr = dev->_risc_virt_addr;
457 dev->_risc_phys_start_addr = dma_addr;
458 dev->_risc_phys_addr = dma_addr;
459 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
460
461 if (!dev->_risc_virt_addr) {
462 printk
463 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
464 return -ENOMEM;
465 }
466 //Clear out memory at address
467 memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
468
469 //For Audio Data buffer allocation
470 dev->_audiodata_buf_virt_addr =
471 pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
472 &data_dma_addr);
473 dev->_audiodata_buf_phys_addr = data_dma_addr;
474 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
475
476 if (!dev->_audiodata_buf_virt_addr) {
477 printk
478 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n");
479 return -ENOMEM;
480 }
481 //Clear out memory at address
482 memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
483
484 ret = cx25821_openfile_audio(dev, sram_ch);
485 if (ret < 0)
486 return ret;
487
488 //Creating RISC programs
489 ret =
490 cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
491 dev->_audio_lines_count);
492 if (ret < 0) {
493 printk(KERN_DEBUG
494 "cx25821 ERROR creating audio upstream RISC programs! \n");
495 goto error;
496 }
497
498 return 0;
499
500 error:
501 return ret;
502}
503
504int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
505 u32 status)
506{
507 int i = 0;
508 u32 int_msk_tmp;
509 struct sram_channel *channel = &dev->sram_channels[chan_num];
510 dma_addr_t risc_phys_jump_addr;
511 __le32 *rp;
512
513 if (status & FLD_AUD_SRC_RISCI1) {
514 //Get interrupt_index of the program that interrupted
515 u32 prog_cnt = cx_read(channel->gpcnt);
516
517 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
518 cx_write(channel->int_msk, 0);
519 cx_write(channel->int_stat, cx_read(channel->int_stat));
520
521 spin_lock(&dev->slock);
522
523 while (prog_cnt != dev->_last_index_irq) {
524 //Update _last_index_irq
525 if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) {
526 dev->_last_index_irq++;
527 } else {
528 dev->_last_index_irq = 0;
529 }
530
531 dev->_audioframe_index = dev->_last_index_irq;
532
533 queue_work(dev->_irq_audio_queues,
534 &dev->_audio_work_entry);
535 }
536
537 if (dev->_is_first_audio_frame) {
538 dev->_is_first_audio_frame = 0;
539
540 if (dev->_risc_virt_start_addr != NULL) {
541 risc_phys_jump_addr =
542 dev->_risc_phys_start_addr +
543 RISC_SYNC_INSTRUCTION_SIZE +
544 AUDIO_RISC_DMA_BUF_SIZE;
545
546 rp = cx25821_risc_field_upstream_audio(dev,
547 dev->
548 _risc_virt_start_addr
549 + 1,
550 dev->
551 _audiodata_buf_phys_addr,
552 AUDIO_LINE_SIZE,
553 FIFO_DISABLE);
554
555 if (USE_RISC_NOOP_AUDIO) {
556 for (i = 0; i < NUM_NO_OPS; i++) {
557 *(rp++) =
558 cpu_to_le32(RISC_NOOP);
559 }
560 }
561 // Jump to 2nd Audio Frame
562 *(rp++) =
563 cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
564 RISC_CNT_RESET);
565 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
566 *(rp++) = cpu_to_le32(0);
567 }
568 }
569
570 spin_unlock(&dev->slock);
571 } else {
572 if (status & FLD_AUD_SRC_OF)
573 printk("%s: Audio Received Overflow Error Interrupt!\n",
574 __func__);
575
576 if (status & FLD_AUD_SRC_SYNC)
577 printk("%s: Audio Received Sync Error Interrupt!\n",
578 __func__);
579
580 if (status & FLD_AUD_SRC_OPC_ERR)
581 printk("%s: Audio Received OpCode Error Interrupt!\n",
582 __func__);
583
584 // Read and write back the interrupt status register to clear our bits
585 cx_write(channel->int_stat, cx_read(channel->int_stat));
586 }
587
588 if (dev->_audiofile_status == END_OF_FILE) {
589 printk("cx25821: EOF Channel Audio Framecount = %d\n",
590 dev->_audioframe_count);
591 return -1;
592 }
593 //ElSE, set the interrupt mask register, re-enable irq.
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
596
597 return 0;
598}
599
600static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
601{
602 struct cx25821_dev *dev = dev_id;
603 u32 msk_stat, audio_status;
604 int handled = 0;
605 struct sram_channel *sram_ch;
606
607 if (!dev)
608 return -1;
609
610 sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
611
612 msk_stat = cx_read(sram_ch->int_mstat);
613 audio_status = cx_read(sram_ch->int_stat);
614
615 // Only deal with our interrupt
616 if (audio_status) {
617 handled =
618 cx25821_audio_upstream_irq(dev,
619 dev->
620 _audio_upstream_channel_select,
621 audio_status);
622 }
623
624 if (handled < 0) {
625 cx25821_stop_upstream_audio(dev);
626 } else {
627 handled += handled;
628 }
629
630 return IRQ_RETVAL(handled);
631}
632
633static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
634 struct sram_channel *sram_ch)
635{
636 int count = 0;
637 u32 tmp;
638
639 do {
640 //Wait 10 microsecond before checking to see if the FIFO is turned ON.
641 udelay(10);
642
643 tmp = cx_read(sram_ch->dma_ctl);
644
645 if (count++ > 1000) //10 millisecond timeout
646 {
647 printk
648 ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
649 __func__);
650 return;
651 }
652
653 } while (!(tmp & sram_ch->fld_aud_fifo_en));
654
655}
656
657int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
658 struct sram_channel *sram_ch)
659{
660 u32 tmp = 0;
661 int err = 0;
662
663 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS.
664 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
665 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
666
667 /* reset counter */
668 cx_write(sram_ch->gpcnt_ctl, 3);
669
670 //Set the line length (It looks like we do not need to set the line length)
671 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
672
673 //Set the input mode to 16-bit
674 tmp = cx_read(sram_ch->aud_cfg);
675 tmp |=
676 FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
677 FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
678 cx_write(sram_ch->aud_cfg, tmp);
679
680 // Read and write back the interrupt status register to clear it
681 tmp = cx_read(sram_ch->int_stat);
682 cx_write(sram_ch->int_stat, tmp);
683
684 // Clear our bits from the interrupt status register.
685 cx_write(sram_ch->int_stat, _intr_msk);
686
687 //Set the interrupt mask register, enable irq.
688 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
689 tmp = cx_read(sram_ch->int_msk);
690 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
691
692 err =
693 request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
694 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
695 if (err < 0) {
696 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
697 dev->pci->irq);
698 goto fail_irq;
699 }
700
701 // Start the DMA engine
702 tmp = cx_read(sram_ch->dma_ctl);
703 cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
704
705 dev->_audio_is_running = 1;
706 dev->_is_first_audio_frame = 1;
707
708 // The fifo_en bit turns on by the first Risc program
709 cx25821_wait_fifo_enable(dev, sram_ch);
710
711 return 0;
712
713 fail_irq:
714 cx25821_dev_unregister(dev);
715 return err;
716}
717
718int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
719{
720 struct sram_channel *sram_ch;
721 int retval = 0;
722 int err = 0;
723 int str_length = 0;
724
725 if (dev->_audio_is_running) {
726 printk("Audio Channel is still running so return!\n");
727 return 0;
728 }
729
730 dev->_audio_upstream_channel_select = channel_select;
731 sram_ch = &dev->sram_channels[channel_select];
732
733 //Work queue
734 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
735 dev->_irq_audio_queues =
736 create_singlethread_workqueue("cx25821_audioworkqueue");
737
738 if (!dev->_irq_audio_queues) {
739 printk
740 ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
741 return -ENOMEM;
742 }
743
744 dev->_last_index_irq = 0;
745 dev->_audio_is_running = 0;
746 dev->_audioframe_count = 0;
747 dev->_audiofile_status = RESET_STATUS;
748 dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
749 _line_size = AUDIO_LINE_SIZE;
750
751 if (dev->input_audiofilename) {
752 str_length = strlen(dev->input_audiofilename);
753 dev->_audiofilename =
754 (char *)kmalloc(str_length + 1, GFP_KERNEL);
755
756 if (!dev->_audiofilename)
757 goto error;
758
759 memcpy(dev->_audiofilename, dev->input_audiofilename,
760 str_length + 1);
761
762 //Default if filename is empty string
763 if (strcmp(dev->input_audiofilename, "") == 0) {
764 dev->_audiofilename = "/root/audioGOOD.wav";
765 }
766 } else {
767 str_length = strlen(_defaultAudioName);
768 dev->_audiofilename =
769 (char *)kmalloc(str_length + 1, GFP_KERNEL);
770
771 if (!dev->_audiofilename)
772 goto error;
773
774 memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
775 }
776
777 retval =
778 cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size,
779 0);
780
781 dev->audio_upstream_riscbuf_size =
782 AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
783 RISC_SYNC_INSTRUCTION_SIZE;
784 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
785
786 //Allocating buffers and prepare RISC program
787 retval =
788 cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
789 if (retval < 0) {
790 printk(KERN_ERR
791 "%s: Failed to set up Audio upstream buffers!\n",
792 dev->name);
793 goto error;
794 }
795 //Start RISC engine
796 cx25821_start_audio_dma_upstream(dev, sram_ch);
797
798 return 0;
799
800 error:
801 cx25821_dev_unregister(dev);
802
803 return err;
804}
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h
new file mode 100644
index 000000000000..ca987addf815
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.h
@@ -0,0 +1,57 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define NUM_AUDIO_PROGS 8
27#define NUM_AUDIO_FRAMES 8
28#define END_OF_FILE 0
29#define IN_PROGRESS 1
30#define RESET_STATUS -1
31#define FIFO_DISABLE 0
32#define FIFO_ENABLE 1
33#define NUM_NO_OPS 4
34
35#define RISC_READ_INSTRUCTION_SIZE 12
36#define RISC_JUMP_INSTRUCTION_SIZE 12
37#define RISC_WRITECR_INSTRUCTION_SIZE 16
38#define RISC_SYNC_INSTRUCTION_SIZE 4
39#define DWORD_SIZE 4
40#define AUDIO_SYNC_LINE 4
41
42#define LINES_PER_AUDIO_BUFFER 15
43#define AUDIO_LINE_SIZE 128
44#define AUDIO_DATA_BUF_SZ (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
45
46#define USE_RISC_NOOP_AUDIO 1
47
48#ifdef USE_RISC_NOOP_AUDIO
49#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
50#endif
51
52#ifndef USE_RISC_NOOP_AUDIO
53#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
54#endif
55
56static int _line_size;
57char *_defaultAudioName = "/root/audioGOOD.wav";
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
new file mode 100644
index 000000000000..503f42f036a8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -0,0 +1,57 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_AUDIO_H__
24#define __CX25821_AUDIO_H__
25
26#define USE_RISC_NOOP 1
27#define LINES_PER_BUFFER 15
28#define AUDIO_LINE_SIZE 128
29
30//Number of buffer programs to use at once.
31#define NUMBER_OF_PROGRAMS 8
32
33//Max size of the RISC program for a buffer. - worst case is 2 writes per line
34// Space is also added for the 4 no-op instructions added on the end.
35
36#ifndef USE_RISC_NOOP
37#define MAX_BUFFER_PROGRAM_SIZE \
38 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
39#endif
40
41// MAE 12 July 2005 Try to use NOOP RISC instruction instead
42#ifdef USE_RISC_NOOP
43#define MAX_BUFFER_PROGRAM_SIZE \
44 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
45#endif
46
47//Sizes of various instructions in bytes. Used when adding instructions.
48#define RISC_WRITE_INSTRUCTION_SIZE 12
49#define RISC_JUMP_INSTRUCTION_SIZE 12
50#define RISC_SKIP_INSTRUCTION_SIZE 4
51#define RISC_SYNC_INSTRUCTION_SIZE 4
52#define RISC_WRITECR_INSTRUCTION_SIZE 16
53#define RISC_NOOP_INSTRUCTION_SIZE 4
54
55#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
56
57#endif
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
new file mode 100644
index 000000000000..f78b8912d905
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -0,0 +1,434 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH11];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH11]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH11]
108 && h->video_dev[SRAM_CH11]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 10;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO11))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO11)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel11->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO11)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO11);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO11);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
268 struct v4l2_format *f)
269{
270 struct cx25821_fh *fh = priv;
271 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
272 int err;
273
274 if (fh) {
275 err = v4l2_prio_check(&dev->prio, &fh->prio);
276 if (0 != err)
277 return err;
278 }
279
280 dprintk(2, "%s()\n", __func__);
281 err = vidioc_try_fmt_vid_cap(file, priv, f);
282
283 if (0 != err)
284 return err;
285 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
286 fh->width = f->fmt.pix.width;
287 fh->height = f->fmt.pix.height;
288 fh->vidq.field = f->fmt.pix.field;
289 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
290 fh->height, fh->vidq.field);
291 cx25821_call_all(dev, video, s_fmt, f);
292 return 0;
293}
294
295static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
296 unsigned long arg)
297{
298 struct cx25821_fh *fh = file->private_data;
299 struct cx25821_dev *dev = fh->dev;
300 int command = 0;
301 struct upstream_user_struct *data_from_user;
302
303 data_from_user = (struct upstream_user_struct *)arg;
304
305 if (!data_from_user) {
306 printk
307 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
308 __func__);
309 return 0;
310 }
311
312 command = data_from_user->command;
313
314 if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) {
315 return 0;
316 }
317
318 dev->input_filename = data_from_user->input_filename;
319 dev->input_audiofilename = data_from_user->input_filename;
320 dev->vid_stdname = data_from_user->vid_stdname;
321 dev->pixel_format = data_from_user->pixel_format;
322 dev->channel_select = data_from_user->channel_select;
323 dev->command = data_from_user->command;
324
325 switch (command) {
326 case UPSTREAM_START_AUDIO:
327 cx25821_start_upstream_audio(dev, data_from_user);
328 break;
329
330 case UPSTREAM_STOP_AUDIO:
331 cx25821_stop_upstream_audio(dev);
332 break;
333 }
334
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = fh->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370 return 0;
371}
372
373// exported stuff
374static const struct v4l2_file_operations video_fops = {
375 .owner = THIS_MODULE,
376 .open = video_open,
377 .release = video_release,
378 .read = video_read,
379 .poll = video_poll,
380 .mmap = video_mmap,
381 .ioctl = video_ioctl_upstream11,
382};
383
384static const struct v4l2_ioctl_ops video_ioctl_ops = {
385 .vidioc_querycap = vidioc_querycap,
386 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
387 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
388 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
389 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
390 .vidioc_reqbufs = vidioc_reqbufs,
391 .vidioc_querybuf = vidioc_querybuf,
392 .vidioc_qbuf = vidioc_qbuf,
393 .vidioc_dqbuf = vidioc_dqbuf,
394#ifdef TUNER_FLAG
395 .vidioc_s_std = vidioc_s_std,
396 .vidioc_querystd = vidioc_querystd,
397#endif
398 .vidioc_cropcap = vidioc_cropcap,
399 .vidioc_s_crop = vidioc_s_crop,
400 .vidioc_g_crop = vidioc_g_crop,
401 .vidioc_enum_input = vidioc_enum_input,
402 .vidioc_g_input = vidioc_g_input,
403 .vidioc_s_input = vidioc_s_input,
404 .vidioc_g_ctrl = vidioc_g_ctrl,
405 .vidioc_s_ctrl = vidioc_s_ctrl,
406 .vidioc_queryctrl = vidioc_queryctrl,
407 .vidioc_streamon = vidioc_streamon,
408 .vidioc_streamoff = vidioc_streamoff,
409 .vidioc_log_status = vidioc_log_status,
410 .vidioc_g_priority = vidioc_g_priority,
411 .vidioc_s_priority = vidioc_s_priority,
412#ifdef CONFIG_VIDEO_V4L1_COMPAT
413 .vidiocgmbuf = vidiocgmbuf,
414#endif
415#ifdef TUNER_FLAG
416 .vidioc_g_tuner = vidioc_g_tuner,
417 .vidioc_s_tuner = vidioc_s_tuner,
418 .vidioc_g_frequency = vidioc_g_frequency,
419 .vidioc_s_frequency = vidioc_s_frequency,
420#endif
421#ifdef CONFIG_VIDEO_ADV_DEBUG
422 .vidioc_g_register = vidioc_g_register,
423 .vidioc_s_register = vidioc_s_register,
424#endif
425};
426
427struct video_device cx25821_video_template11 = {
428 .name = "cx25821-audioupstream",
429 .fops = &video_fops,
430 .minor = -1,
431 .ioctl_ops = &video_ioctl_ops,
432 .tvnorms = CX25821_NORMS,
433 .current_norm = V4L2_STD_NTSC_M,
434};
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/staging/cx25821/cx25821-biffuncs.h
new file mode 100644
index 000000000000..9326a7c729ec
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-biffuncs.h
@@ -0,0 +1,45 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _BITFUNCS_H
24#define _BITFUNCS_H
25
26#define SetBit(Bit) (1 << Bit)
27
28inline u8 getBit(u32 sample, u8 index)
29{
30 return (u8) ((sample >> index) & 1);
31}
32
33inline u32 clearBitAtPos(u32 value, u8 bit)
34{
35 return value & ~(1 << bit);
36}
37
38inline u32 setBitAtPos(u32 sample, u8 bit)
39{
40 sample |= (1 << bit);
41 return sample;
42
43}
44
45#endif
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
new file mode 100644
index 000000000000..4d0b9eac3e49
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -0,0 +1,70 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <media/cx25840.h>
29
30#include "cx25821.h"
31#include "tuner-xc2028.h"
32
33// board config info
34
35struct cx25821_board cx25821_boards[] = {
36 [UNKNOWN_BOARD] = {
37 .name = "UNKNOWN/GENERIC",
38 // Ensure safe default for unknown boards
39 .clk_freq = 0,
40 },
41
42 [CX25821_BOARD] = {
43 .name = "CX25821",
44 .portb = CX25821_RAW,
45 .portc = CX25821_264,
46 .input[0].type = CX25821_VMUX_COMPOSITE,
47 },
48
49};
50
51const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);
52
53struct cx25821_subid cx25821_subids[] = {
54 {
55 .subvendor = 0x14f1,
56 .subdevice = 0x0920,
57 .card = CX25821_BOARD,
58 },
59};
60
61void cx25821_card_setup(struct cx25821_dev *dev)
62{
63 static u8 eeprom[256];
64
65 if (dev->i2c_bus[0].i2c_rc == 0) {
66 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
67 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
68 sizeof(eeprom));
69 }
70}
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
new file mode 100644
index 000000000000..8aceae5a072e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -0,0 +1,1551 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/i2c.h>
25#include "cx25821.h"
26#include "cx25821-sram.h"
27#include "cx25821-video.h"
28
29MODULE_DESCRIPTION("Driver for Athena cards");
30MODULE_AUTHOR("Shu Lin - Hiep Huynh");
31MODULE_LICENSE("GPL");
32
33struct list_head cx25821_devlist;
34
35static unsigned int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debug messages");
38
39static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
40module_param_array(card, int, NULL, 0444);
41MODULE_PARM_DESC(card, "card type");
42
43static unsigned int cx25821_devcount = 0;
44
45static DEFINE_MUTEX(devlist);
46LIST_HEAD(cx25821_devlist);
47
48struct sram_channel cx25821_sram_channels[] = {
49 [SRAM_CH00] = {
50 .i = SRAM_CH00,
51 .name = "VID A",
52 .cmds_start = VID_A_DOWN_CMDS,
53 .ctrl_start = VID_A_IQ,
54 .cdt = VID_A_CDT,
55 .fifo_start = VID_A_DOWN_CLUSTER_1,
56 .fifo_size = (VID_CLUSTER_SIZE << 2),
57 .ptr1_reg = DMA1_PTR1,
58 .ptr2_reg = DMA1_PTR2,
59 .cnt1_reg = DMA1_CNT1,
60 .cnt2_reg = DMA1_CNT2,
61 .int_msk = VID_A_INT_MSK,
62 .int_stat = VID_A_INT_STAT,
63 .int_mstat = VID_A_INT_MSTAT,
64 .dma_ctl = VID_DST_A_DMA_CTL,
65 .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
66 .gpcnt = VID_DST_A_GPCNT,
67 .vip_ctl = VID_DST_A_VIP_CTL,
68 .pix_frmt = VID_DST_A_PIX_FRMT,
69 },
70
71 [SRAM_CH01] = {
72 .i = SRAM_CH01,
73 .name = "VID B",
74 .cmds_start = VID_B_DOWN_CMDS,
75 .ctrl_start = VID_B_IQ,
76 .cdt = VID_B_CDT,
77 .fifo_start = VID_B_DOWN_CLUSTER_1,
78 .fifo_size = (VID_CLUSTER_SIZE << 2),
79 .ptr1_reg = DMA2_PTR1,
80 .ptr2_reg = DMA2_PTR2,
81 .cnt1_reg = DMA2_CNT1,
82 .cnt2_reg = DMA2_CNT2,
83 .int_msk = VID_B_INT_MSK,
84 .int_stat = VID_B_INT_STAT,
85 .int_mstat = VID_B_INT_MSTAT,
86 .dma_ctl = VID_DST_B_DMA_CTL,
87 .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
88 .gpcnt = VID_DST_B_GPCNT,
89 .vip_ctl = VID_DST_B_VIP_CTL,
90 .pix_frmt = VID_DST_B_PIX_FRMT,
91 },
92
93 [SRAM_CH02] = {
94 .i = SRAM_CH02,
95 .name = "VID C",
96 .cmds_start = VID_C_DOWN_CMDS,
97 .ctrl_start = VID_C_IQ,
98 .cdt = VID_C_CDT,
99 .fifo_start = VID_C_DOWN_CLUSTER_1,
100 .fifo_size = (VID_CLUSTER_SIZE << 2),
101 .ptr1_reg = DMA3_PTR1,
102 .ptr2_reg = DMA3_PTR2,
103 .cnt1_reg = DMA3_CNT1,
104 .cnt2_reg = DMA3_CNT2,
105 .int_msk = VID_C_INT_MSK,
106 .int_stat = VID_C_INT_STAT,
107 .int_mstat = VID_C_INT_MSTAT,
108 .dma_ctl = VID_DST_C_DMA_CTL,
109 .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
110 .gpcnt = VID_DST_C_GPCNT,
111 .vip_ctl = VID_DST_C_VIP_CTL,
112 .pix_frmt = VID_DST_C_PIX_FRMT,
113 },
114
115 [SRAM_CH03] = {
116 .i = SRAM_CH03,
117 .name = "VID D",
118 .cmds_start = VID_D_DOWN_CMDS,
119 .ctrl_start = VID_D_IQ,
120 .cdt = VID_D_CDT,
121 .fifo_start = VID_D_DOWN_CLUSTER_1,
122 .fifo_size = (VID_CLUSTER_SIZE << 2),
123 .ptr1_reg = DMA4_PTR1,
124 .ptr2_reg = DMA4_PTR2,
125 .cnt1_reg = DMA4_CNT1,
126 .cnt2_reg = DMA4_CNT2,
127 .int_msk = VID_D_INT_MSK,
128 .int_stat = VID_D_INT_STAT,
129 .int_mstat = VID_D_INT_MSTAT,
130 .dma_ctl = VID_DST_D_DMA_CTL,
131 .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
132 .gpcnt = VID_DST_D_GPCNT,
133 .vip_ctl = VID_DST_D_VIP_CTL,
134 .pix_frmt = VID_DST_D_PIX_FRMT,
135 },
136
137 [SRAM_CH04] = {
138 .i = SRAM_CH04,
139 .name = "VID E",
140 .cmds_start = VID_E_DOWN_CMDS,
141 .ctrl_start = VID_E_IQ,
142 .cdt = VID_E_CDT,
143 .fifo_start = VID_E_DOWN_CLUSTER_1,
144 .fifo_size = (VID_CLUSTER_SIZE << 2),
145 .ptr1_reg = DMA5_PTR1,
146 .ptr2_reg = DMA5_PTR2,
147 .cnt1_reg = DMA5_CNT1,
148 .cnt2_reg = DMA5_CNT2,
149 .int_msk = VID_E_INT_MSK,
150 .int_stat = VID_E_INT_STAT,
151 .int_mstat = VID_E_INT_MSTAT,
152 .dma_ctl = VID_DST_E_DMA_CTL,
153 .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
154 .gpcnt = VID_DST_E_GPCNT,
155 .vip_ctl = VID_DST_E_VIP_CTL,
156 .pix_frmt = VID_DST_E_PIX_FRMT,
157 },
158
159 [SRAM_CH05] = {
160 .i = SRAM_CH05,
161 .name = "VID F",
162 .cmds_start = VID_F_DOWN_CMDS,
163 .ctrl_start = VID_F_IQ,
164 .cdt = VID_F_CDT,
165 .fifo_start = VID_F_DOWN_CLUSTER_1,
166 .fifo_size = (VID_CLUSTER_SIZE << 2),
167 .ptr1_reg = DMA6_PTR1,
168 .ptr2_reg = DMA6_PTR2,
169 .cnt1_reg = DMA6_CNT1,
170 .cnt2_reg = DMA6_CNT2,
171 .int_msk = VID_F_INT_MSK,
172 .int_stat = VID_F_INT_STAT,
173 .int_mstat = VID_F_INT_MSTAT,
174 .dma_ctl = VID_DST_F_DMA_CTL,
175 .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
176 .gpcnt = VID_DST_F_GPCNT,
177 .vip_ctl = VID_DST_F_VIP_CTL,
178 .pix_frmt = VID_DST_F_PIX_FRMT,
179 },
180
181 [SRAM_CH06] = {
182 .i = SRAM_CH06,
183 .name = "VID G",
184 .cmds_start = VID_G_DOWN_CMDS,
185 .ctrl_start = VID_G_IQ,
186 .cdt = VID_G_CDT,
187 .fifo_start = VID_G_DOWN_CLUSTER_1,
188 .fifo_size = (VID_CLUSTER_SIZE << 2),
189 .ptr1_reg = DMA7_PTR1,
190 .ptr2_reg = DMA7_PTR2,
191 .cnt1_reg = DMA7_CNT1,
192 .cnt2_reg = DMA7_CNT2,
193 .int_msk = VID_G_INT_MSK,
194 .int_stat = VID_G_INT_STAT,
195 .int_mstat = VID_G_INT_MSTAT,
196 .dma_ctl = VID_DST_G_DMA_CTL,
197 .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
198 .gpcnt = VID_DST_G_GPCNT,
199 .vip_ctl = VID_DST_G_VIP_CTL,
200 .pix_frmt = VID_DST_G_PIX_FRMT,
201 },
202
203 [SRAM_CH07] = {
204 .i = SRAM_CH07,
205 .name = "VID H",
206 .cmds_start = VID_H_DOWN_CMDS,
207 .ctrl_start = VID_H_IQ,
208 .cdt = VID_H_CDT,
209 .fifo_start = VID_H_DOWN_CLUSTER_1,
210 .fifo_size = (VID_CLUSTER_SIZE << 2),
211 .ptr1_reg = DMA8_PTR1,
212 .ptr2_reg = DMA8_PTR2,
213 .cnt1_reg = DMA8_CNT1,
214 .cnt2_reg = DMA8_CNT2,
215 .int_msk = VID_H_INT_MSK,
216 .int_stat = VID_H_INT_STAT,
217 .int_mstat = VID_H_INT_MSTAT,
218 .dma_ctl = VID_DST_H_DMA_CTL,
219 .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
220 .gpcnt = VID_DST_H_GPCNT,
221 .vip_ctl = VID_DST_H_VIP_CTL,
222 .pix_frmt = VID_DST_H_PIX_FRMT,
223 },
224
225 [SRAM_CH08] = {
226 .name = "audio from",
227 .cmds_start = AUD_A_DOWN_CMDS,
228 .ctrl_start = AUD_A_IQ,
229 .cdt = AUD_A_CDT,
230 .fifo_start = AUD_A_DOWN_CLUSTER_1,
231 .fifo_size = AUDIO_CLUSTER_SIZE * 3,
232 .ptr1_reg = DMA17_PTR1,
233 .ptr2_reg = DMA17_PTR2,
234 .cnt1_reg = DMA17_CNT1,
235 .cnt2_reg = DMA17_CNT2,
236 },
237
238 [SRAM_CH09] = {
239 .i = SRAM_CH09,
240 .name = "VID Upstream I",
241 .cmds_start = VID_I_UP_CMDS,
242 .ctrl_start = VID_I_IQ,
243 .cdt = VID_I_CDT,
244 .fifo_start = VID_I_UP_CLUSTER_1,
245 .fifo_size = (VID_CLUSTER_SIZE << 2),
246 .ptr1_reg = DMA15_PTR1,
247 .ptr2_reg = DMA15_PTR2,
248 .cnt1_reg = DMA15_CNT1,
249 .cnt2_reg = DMA15_CNT2,
250 .int_msk = VID_I_INT_MSK,
251 .int_stat = VID_I_INT_STAT,
252 .int_mstat = VID_I_INT_MSTAT,
253 .dma_ctl = VID_SRC_I_DMA_CTL,
254 .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
255 .gpcnt = VID_SRC_I_GPCNT,
256
257 .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
258 .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
259 .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
260 .vid_cdt_size = VID_SRC_I_CDT_SZ,
261 .irq_bit = 8,
262 },
263
264 [SRAM_CH10] = {
265 .i = SRAM_CH10,
266 .name = "VID Upstream J",
267 .cmds_start = VID_J_UP_CMDS,
268 .ctrl_start = VID_J_IQ,
269 .cdt = VID_J_CDT,
270 .fifo_start = VID_J_UP_CLUSTER_1,
271 .fifo_size = (VID_CLUSTER_SIZE << 2),
272 .ptr1_reg = DMA16_PTR1,
273 .ptr2_reg = DMA16_PTR2,
274 .cnt1_reg = DMA16_CNT1,
275 .cnt2_reg = DMA16_CNT2,
276 .int_msk = VID_J_INT_MSK,
277 .int_stat = VID_J_INT_STAT,
278 .int_mstat = VID_J_INT_MSTAT,
279 .dma_ctl = VID_SRC_J_DMA_CTL,
280 .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
281 .gpcnt = VID_SRC_J_GPCNT,
282
283 .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
284 .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
285 .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
286 .vid_cdt_size = VID_SRC_J_CDT_SZ,
287 .irq_bit = 9,
288 },
289
290 [SRAM_CH11] = {
291 .i = SRAM_CH11,
292 .name = "Audio Upstream Channel B",
293 .cmds_start = AUD_B_UP_CMDS,
294 .ctrl_start = AUD_B_IQ,
295 .cdt = AUD_B_CDT,
296 .fifo_start = AUD_B_UP_CLUSTER_1,
297 .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
298 .ptr1_reg = DMA22_PTR1,
299 .ptr2_reg = DMA22_PTR2,
300 .cnt1_reg = DMA22_CNT1,
301 .cnt2_reg = DMA22_CNT2,
302 .int_msk = AUD_B_INT_MSK,
303 .int_stat = AUD_B_INT_STAT,
304 .int_mstat = AUD_B_INT_MSTAT,
305 .dma_ctl = AUD_INT_DMA_CTL,
306 .gpcnt_ctl = AUD_B_GPCNT_CTL,
307 .gpcnt = AUD_B_GPCNT,
308 .aud_length = AUD_B_LNGTH,
309 .aud_cfg = AUD_B_CFG,
310 .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
311 .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
312 .irq_bit = 11,
313 },
314};
315
316struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
317struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
318struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
319struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
320struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
321struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
322struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
323struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
324struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
325struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
326struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
327
328struct cx25821_dmaqueue mpegq;
329
330static int cx25821_risc_decode(u32 risc)
331{
332 static char *instr[16] = {
333 [RISC_SYNC >> 28] = "sync",
334 [RISC_WRITE >> 28] = "write",
335 [RISC_WRITEC >> 28] = "writec",
336 [RISC_READ >> 28] = "read",
337 [RISC_READC >> 28] = "readc",
338 [RISC_JUMP >> 28] = "jump",
339 [RISC_SKIP >> 28] = "skip",
340 [RISC_WRITERM >> 28] = "writerm",
341 [RISC_WRITECM >> 28] = "writecm",
342 [RISC_WRITECR >> 28] = "writecr",
343 };
344 static int incr[16] = {
345 [RISC_WRITE >> 28] = 3,
346 [RISC_JUMP >> 28] = 3,
347 [RISC_SKIP >> 28] = 1,
348 [RISC_SYNC >> 28] = 1,
349 [RISC_WRITERM >> 28] = 3,
350 [RISC_WRITECM >> 28] = 3,
351 [RISC_WRITECR >> 28] = 4,
352 };
353 static char *bits[] = {
354 "12", "13", "14", "resync",
355 "cnt0", "cnt1", "18", "19",
356 "20", "21", "22", "23",
357 "irq1", "irq2", "eol", "sol",
358 };
359 int i;
360
361 printk("0x%08x [ %s", risc,
362 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
363 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
364 if (risc & (1 << (i + 12)))
365 printk(" %s", bits[i]);
366 }
367 printk(" count=%d ]\n", risc & 0xfff);
368 return incr[risc >> 28] ? incr[risc >> 28] : 1;
369}
370
371static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
372{
373 struct cx25821_i2c *bus = i2c_adap->algo_data;
374 struct cx25821_dev *dev = bus->dev;
375 return cx_read(bus->reg_stat) & 0x01;
376}
377
378void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char *reg_string)
379{
380 int tmp = 0;
381 u32 value = 0;
382
383 value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
384}
385
386static void cx25821_registers_init(struct cx25821_dev *dev)
387{
388 u32 tmp;
389
390 // enable RUN_RISC in Pecos
391 cx_write(DEV_CNTRL2, 0x20);
392
393 // Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts
394 // I2C interrupt masking is handled by the I2C objects themselves.
395 cx_write(PCI_INT_MSK, 0x2001FFFF);
396
397 tmp = cx_read(RDR_TLCTL0);
398 tmp &= ~FLD_CFG_RCB_CK_EN; // Clear the RCB_CK_EN bit
399 cx_write(RDR_TLCTL0, tmp);
400
401 // PLL-A setting for the Audio Master Clock
402 cx_write(PLL_A_INT_FRAC, 0x9807A58B);
403
404 // PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1
405 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
406
407 // clear reset bit [31]
408 tmp = cx_read(PLL_A_INT_FRAC);
409 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
410
411 // PLL-B setting for Mobilygen Host Bus Interface
412 cx_write(PLL_B_INT_FRAC, 0x9883A86F);
413
414 // PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0
415 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
416
417 // clear reset bit [31]
418 tmp = cx_read(PLL_B_INT_FRAC);
419 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
420
421 // PLL-C setting for video upstream channel
422 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
423
424 // PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0
425 cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
426
427 // clear reset bit [31]
428 tmp = cx_read(PLL_C_INT_FRAC);
429 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
430
431 // PLL-D setting for audio upstream channel
432 cx_write(PLL_D_INT_FRAC, 0x98757F5B);
433
434 // PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0
435 cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
436
437 // clear reset bit [31]
438 tmp = cx_read(PLL_D_INT_FRAC);
439 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
440
441 // This selects the PLL C clock source for the video upstream channel I and J
442 tmp = cx_read(VID_CH_CLK_SEL);
443 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
444
445 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
446 //select 656/VIP DST for downstream Channel A - C
447 tmp = cx_read(VID_CH_MODE_SEL);
448 //cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
449 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
450
451 // enables 656 port I and J as output
452 tmp = cx_read(CLK_RST);
453 tmp |= FLD_USE_ALT_PLL_REF; // use external ALT_PLL_REF pin as its reference clock instead
454 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
455
456 mdelay(100);
457}
458
459int cx25821_sram_channel_setup(struct cx25821_dev *dev,
460 struct sram_channel *ch,
461 unsigned int bpl, u32 risc)
462{
463 unsigned int i, lines;
464 u32 cdt;
465
466 if (ch->cmds_start == 0) {
467 cx_write(ch->ptr1_reg, 0);
468 cx_write(ch->ptr2_reg, 0);
469 cx_write(ch->cnt2_reg, 0);
470 cx_write(ch->cnt1_reg, 0);
471 return 0;
472 }
473
474 bpl = (bpl + 7) & ~7; /* alignment */
475 cdt = ch->cdt;
476 lines = ch->fifo_size / bpl;
477
478 if (lines > 4) {
479 lines = 4;
480 }
481
482 BUG_ON(lines < 2);
483
484 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
485 cx_write(8 + 4, 8);
486 cx_write(8 + 8, 0);
487
488 /* write CDT */
489 for (i = 0; i < lines; i++) {
490 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
491 cx_write(cdt + 16 * i + 4, 0);
492 cx_write(cdt + 16 * i + 8, 0);
493 cx_write(cdt + 16 * i + 12, 0);
494 }
495
496 //init the first cdt buffer
497 for (i = 0; i < 128; i++)
498 cx_write(ch->fifo_start + 4 * i, i);
499
500 /* write CMDS */
501 if (ch->jumponly) {
502 cx_write(ch->cmds_start + 0, 8);
503 } else {
504 cx_write(ch->cmds_start + 0, risc);
505 }
506
507 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
508 cx_write(ch->cmds_start + 8, cdt);
509 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
510 cx_write(ch->cmds_start + 16, ch->ctrl_start);
511
512 if (ch->jumponly)
513 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
514 else
515 cx_write(ch->cmds_start + 20, 64 >> 2);
516
517 for (i = 24; i < 80; i += 4)
518 cx_write(ch->cmds_start + i, 0);
519
520 /* fill registers */
521 cx_write(ch->ptr1_reg, ch->fifo_start);
522 cx_write(ch->ptr2_reg, cdt);
523 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
524 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
525
526 return 0;
527}
528
529int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
530 struct sram_channel *ch,
531 unsigned int bpl, u32 risc)
532{
533 unsigned int i, lines;
534 u32 cdt;
535
536 if (ch->cmds_start == 0) {
537 cx_write(ch->ptr1_reg, 0);
538 cx_write(ch->ptr2_reg, 0);
539 cx_write(ch->cnt2_reg, 0);
540 cx_write(ch->cnt1_reg, 0);
541 return 0;
542 }
543
544 bpl = (bpl + 7) & ~7; /* alignment */
545 cdt = ch->cdt;
546 lines = ch->fifo_size / bpl;
547
548 if (lines > 3) {
549 lines = 3; //for AUDIO
550 }
551
552 BUG_ON(lines < 2);
553
554 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
555 cx_write(8 + 4, 8);
556 cx_write(8 + 8, 0);
557
558 /* write CDT */
559 for (i = 0; i < lines; i++) {
560 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
561 cx_write(cdt + 16 * i + 4, 0);
562 cx_write(cdt + 16 * i + 8, 0);
563 cx_write(cdt + 16 * i + 12, 0);
564 }
565
566 /* write CMDS */
567 if (ch->jumponly) {
568 cx_write(ch->cmds_start + 0, 8);
569 } else {
570 cx_write(ch->cmds_start + 0, risc);
571 }
572
573 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
574 cx_write(ch->cmds_start + 8, cdt);
575 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
576 cx_write(ch->cmds_start + 16, ch->ctrl_start);
577
578 //IQ size
579 if (ch->jumponly) {
580 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
581 } else {
582 cx_write(ch->cmds_start + 20, 64 >> 2);
583 }
584
585 //zero out
586 for (i = 24; i < 80; i += 4)
587 cx_write(ch->cmds_start + i, 0);
588
589 /* fill registers */
590 cx_write(ch->ptr1_reg, ch->fifo_start);
591 cx_write(ch->ptr2_reg, cdt);
592 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
593 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
594
595 return 0;
596}
597
598void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
599{
600 static char *name[] = {
601 "init risc lo",
602 "init risc hi",
603 "cdt base",
604 "cdt size",
605 "iq base",
606 "iq size",
607 "risc pc lo",
608 "risc pc hi",
609 "iq wr ptr",
610 "iq rd ptr",
611 "cdt current",
612 "pci target lo",
613 "pci target hi",
614 "line / byte",
615 };
616 u32 risc;
617 unsigned int i, j, n;
618
619 printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
620 ch->name);
621 for (i = 0; i < ARRAY_SIZE(name); i++)
622 printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i * 4,
623 name[i], cx_read(ch->cmds_start + 4 * i));
624
625 j = i * 4;
626 for (i = 0; i < 4;) {
627 risc = cx_read(ch->cmds_start + 4 * (i + 14));
628 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
629 i += cx25821_risc_decode(risc);
630 }
631
632 for (i = 0; i < (64 >> 2); i += n) {
633 risc = cx_read(ch->ctrl_start + 4 * i);
634 /* No consideration for bits 63-32 */
635
636 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
637 ch->ctrl_start + 4 * i, i);
638 n = cx25821_risc_decode(risc);
639 for (j = 1; j < n; j++) {
640 risc = cx_read(ch->ctrl_start + 4 * (i + j));
641 printk(KERN_WARNING
642 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
643 4 * (i + j), i + j, risc, j);
644 }
645 }
646
647 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
648 ch->fifo_start, ch->fifo_start + ch->fifo_size);
649 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
650 ch->ctrl_start, ch->ctrl_start + 6 * 16);
651 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
652 cx_read(ch->ptr1_reg));
653 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
654 cx_read(ch->ptr2_reg));
655 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
656 cx_read(ch->cnt1_reg));
657 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
658 cx_read(ch->cnt2_reg));
659}
660
661void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
662 struct sram_channel *ch)
663{
664 static char *name[] = {
665 "init risc lo",
666 "init risc hi",
667 "cdt base",
668 "cdt size",
669 "iq base",
670 "iq size",
671 "risc pc lo",
672 "risc pc hi",
673 "iq wr ptr",
674 "iq rd ptr",
675 "cdt current",
676 "pci target lo",
677 "pci target hi",
678 "line / byte",
679 };
680
681 u32 risc, value, tmp;
682 unsigned int i, j, n;
683
684 printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
685 dev->name, ch->name);
686
687 for (i = 0; i < ARRAY_SIZE(name); i++)
688 printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n",
689 dev->name, i * 4, name[i],
690 cx_read(ch->cmds_start + 4 * i));
691
692 j = i * 4;
693 for (i = 0; i < 4;) {
694 risc = cx_read(ch->cmds_start + 4 * (i + 14));
695 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
696 i += cx25821_risc_decode(risc);
697 }
698
699 for (i = 0; i < (64 >> 2); i += n) {
700 risc = cx_read(ch->ctrl_start + 4 * i);
701 /* No consideration for bits 63-32 */
702
703 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
704 ch->ctrl_start + 4 * i, i);
705 n = cx25821_risc_decode(risc);
706
707 for (j = 1; j < n; j++) {
708 risc = cx_read(ch->ctrl_start + 4 * (i + j));
709 printk(KERN_WARNING
710 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
711 4 * (i + j), i + j, risc, j);
712 }
713 }
714
715 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
716 ch->fifo_start, ch->fifo_start + ch->fifo_size);
717 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
718 ch->ctrl_start, ch->ctrl_start + 6 * 16);
719 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
720 cx_read(ch->ptr1_reg));
721 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
722 cx_read(ch->ptr2_reg));
723 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
724 cx_read(ch->cnt1_reg));
725 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
726 cx_read(ch->cnt2_reg));
727
728 for (i = 0; i < 4; i++) {
729 risc = cx_read(ch->cmds_start + 56 + (i * 4));
730 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
731 }
732
733 //read data from the first cdt buffer
734 risc = cx_read(AUD_A_CDT);
735 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
736 for (i = 0; i < 8; i++) {
737 n = cx_read(risc + i * 4);
738 printk(KERN_WARNING "0x%x ", n);
739 }
740 printk(KERN_WARNING "\n\n");
741
742 value = cx_read(CLK_RST);
743 CX25821_INFO(" CLK_RST = 0x%x \n\n", value);
744
745 value = cx_read(PLL_A_POST_STAT_BIST);
746 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value);
747 value = cx_read(PLL_A_INT_FRAC);
748 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value);
749
750 value = cx_read(PLL_B_POST_STAT_BIST);
751 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value);
752 value = cx_read(PLL_B_INT_FRAC);
753 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value);
754
755 value = cx_read(PLL_C_POST_STAT_BIST);
756 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value);
757 value = cx_read(PLL_C_INT_FRAC);
758 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value);
759
760 value = cx_read(PLL_D_POST_STAT_BIST);
761 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value);
762 value = cx_read(PLL_D_INT_FRAC);
763 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value);
764
765 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
766 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value);
767}
768
769static void cx25821_shutdown(struct cx25821_dev *dev)
770{
771 int i;
772
773 /* disable RISC controller */
774 cx_write(DEV_CNTRL2, 0);
775
776 /* Disable Video A/B activity */
777 for (i = 0; i < VID_CHANNEL_NUM; i++) {
778 cx_write(dev->sram_channels[i].dma_ctl, 0);
779 cx_write(dev->sram_channels[i].int_msk, 0);
780 }
781
782 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
783 i++) {
784 cx_write(dev->sram_channels[i].dma_ctl, 0);
785 cx_write(dev->sram_channels[i].int_msk, 0);
786 }
787
788 /* Disable Audio activity */
789 cx_write(AUD_INT_DMA_CTL, 0);
790
791 /* Disable Serial port */
792 cx_write(UART_CTL, 0);
793
794 /* Disable Interrupts */
795 cx_write(PCI_INT_MSK, 0);
796 cx_write(AUD_A_INT_MSK, 0);
797}
798
799void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
800 u32 format)
801{
802 struct sram_channel *ch;
803
804 if (channel_select <= 7 && channel_select >= 0) {
805 ch = &cx25821_sram_channels[channel_select];
806 cx_write(ch->pix_frmt, format);
807 dev->pixel_formats[channel_select] = format;
808 }
809}
810
811static void cx25821_set_vip_mode(struct cx25821_dev *dev,
812 struct sram_channel *ch)
813{
814 cx_write(ch->pix_frmt, PIXEL_FRMT_422);
815 cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
816}
817
818static void cx25821_initialize(struct cx25821_dev *dev)
819{
820 int i;
821
822 dprintk(1, "%s()\n", __func__);
823
824 cx25821_shutdown(dev);
825 cx_write(PCI_INT_STAT, 0xffffffff);
826
827 for (i = 0; i < VID_CHANNEL_NUM; i++)
828 cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
829
830 cx_write(AUD_A_INT_STAT, 0xffffffff);
831 cx_write(AUD_B_INT_STAT, 0xffffffff);
832 cx_write(AUD_C_INT_STAT, 0xffffffff);
833 cx_write(AUD_D_INT_STAT, 0xffffffff);
834 cx_write(AUD_E_INT_STAT, 0xffffffff);
835
836 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
837 cx_write(PAD_CTRL, 0x12); //for I2C
838 cx25821_registers_init(dev); //init Pecos registers
839 mdelay(100);
840
841 for (i = 0; i < VID_CHANNEL_NUM; i++) {
842 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
843 cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440,
844 0);
845 dev->pixel_formats[i] = PIXEL_FRMT_422;
846 dev->use_cif_resolution[i] = FALSE;
847 }
848
849 //Probably only affect Downstream
850 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
851 i++) {
852 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
853 }
854
855 cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08],
856 128, 0);
857
858 cx25821_gpio_init(dev);
859}
860
861static int get_resources(struct cx25821_dev *dev)
862{
863 if (request_mem_region
864 (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
865 dev->name))
866 return 0;
867
868 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
869 dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
870
871 return -EBUSY;
872}
873
874static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
875{
876 dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
877
878 printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
879 dev->hwrevision);
880}
881
882static void cx25821_iounmap(struct cx25821_dev *dev)
883{
884 if (dev == NULL)
885 return;
886
887 /* Releasing IO memory */
888 if (dev->lmmio != NULL) {
889 CX25821_INFO("Releasing lmmio.\n");
890 iounmap(dev->lmmio);
891 dev->lmmio = NULL;
892 }
893}
894
895static int cx25821_dev_setup(struct cx25821_dev *dev)
896{
897 int io_size = 0, i;
898
899 struct video_device *video_template[] = {
900 &cx25821_video_template0,
901 &cx25821_video_template1,
902 &cx25821_video_template2,
903 &cx25821_video_template3,
904 &cx25821_video_template4,
905 &cx25821_video_template5,
906 &cx25821_video_template6,
907 &cx25821_video_template7,
908 &cx25821_video_template9,
909 &cx25821_video_template10,
910 &cx25821_video_template11,
911 &cx25821_videoioctl_template,
912 };
913
914 printk(KERN_INFO "\n***********************************\n");
915 printk(KERN_INFO "cx25821 set up\n");
916 printk(KERN_INFO "***********************************\n\n");
917
918 mutex_init(&dev->lock);
919
920 atomic_inc(&dev->refcount);
921
922 dev->nr = ++cx25821_devcount;
923 sprintf(dev->name, "cx25821[%d]", dev->nr);
924
925 mutex_lock(&devlist);
926 list_add_tail(&dev->devlist, &cx25821_devlist);
927 mutex_unlock(&devlist);
928
929 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
930 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
931
932 if (dev->pci->device != 0x8210) {
933 printk(KERN_INFO
934 "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
935 __func__, dev->pci->device);
936 return -1;
937 } else {
938 printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
939 dev->pci->device);
940 }
941
942 /* Apply a sensible clock frequency for the PCIe bridge */
943 dev->clk_freq = 28000000;
944 dev->sram_channels = cx25821_sram_channels;
945
946 if (dev->nr > 1) {
947 CX25821_INFO("dev->nr > 1!");
948 }
949
950 /* board config */
951 dev->board = 1; //card[dev->nr];
952 dev->_max_num_decoders = MAX_DECODERS;
953
954 dev->pci_bus = dev->pci->bus->number;
955 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
956 dev->pci_irqmask = 0x001f00;
957
958 /* External Master 1 Bus */
959 dev->i2c_bus[0].nr = 0;
960 dev->i2c_bus[0].dev = dev;
961 dev->i2c_bus[0].reg_stat = I2C1_STAT;
962 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
963 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
964 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
965 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
966 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
967
968
969 if (get_resources(dev) < 0) {
970 printk(KERN_ERR "%s No more PCIe resources for "
971 "subsystem: %04x:%04x\n",
972 dev->name, dev->pci->subsystem_vendor,
973 dev->pci->subsystem_device);
974
975 cx25821_devcount--;
976 return -ENODEV;
977 }
978
979 /* PCIe stuff */
980 dev->base_io_addr = pci_resource_start(dev->pci, 0);
981 io_size = pci_resource_len(dev->pci, 0);
982
983 if (!dev->base_io_addr) {
984 CX25821_ERR("No PCI Memory resources, exiting!\n");
985 return -ENODEV;
986 }
987
988 dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
989
990 if (!dev->lmmio) {
991 CX25821_ERR
992 ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
993 cx25821_iounmap(dev);
994 return -ENOMEM;
995 }
996
997 dev->bmmio = (u8 __iomem *) dev->lmmio;
998
999 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1000 dev->name, dev->pci->subsystem_vendor,
1001 dev->pci->subsystem_device, cx25821_boards[dev->board].name,
1002 dev->board, card[dev->nr] == dev->board ?
1003 "insmod option" : "autodetected");
1004
1005 /* init hardware */
1006 cx25821_initialize(dev);
1007
1008 cx25821_i2c_register(&dev->i2c_bus[0]);
1009// cx25821_i2c_register(&dev->i2c_bus[1]);
1010// cx25821_i2c_register(&dev->i2c_bus[2]);
1011
1012 CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
1013 dev->i2c_bus[0].i2c_rc);
1014
1015 cx25821_card_setup(dev);
1016 medusa_video_init(dev);
1017
1018 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1019 if (cx25821_video_register(dev, i, video_template[i]) < 0) {
1020 printk(KERN_ERR
1021 "%s() Failed to register analog video adapters on VID channel %d\n",
1022 __func__, i);
1023 }
1024 }
1025
1026 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1027 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1028 //Since we don't have template8 for Audio Downstream
1029 if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
1030 printk(KERN_ERR
1031 "%s() Failed to register analog video adapters for Upstream channel %d.\n",
1032 __func__, i);
1033 }
1034 }
1035
1036 // register IOCTL device
1037 dev->ioctl_dev =
1038 cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
1039 "video");
1040
1041 if (video_register_device
1042 (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
1043 cx25821_videoioctl_unregister(dev);
1044 printk(KERN_ERR
1045 "%s() Failed to register video adapter for IOCTL so releasing.\n",
1046 __func__);
1047 }
1048
1049 cx25821_dev_checkrevision(dev);
1050 CX25821_INFO("cx25821 setup done!\n");
1051
1052 return 0;
1053}
1054
1055void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
1056 struct upstream_user_struct *up_data)
1057{
1058 dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0;
1059
1060 dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1061 medusa_set_videostandard(dev);
1062
1063 cx25821_vidupstream_init_ch1(dev, dev->channel_select,
1064 dev->pixel_format);
1065}
1066
1067void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
1068 struct upstream_user_struct *up_data)
1069{
1070 dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0;
1071
1072 dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1073 medusa_set_videostandard(dev);
1074
1075 cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2,
1076 dev->pixel_format_ch2);
1077}
1078
1079void cx25821_start_upstream_audio(struct cx25821_dev *dev,
1080 struct upstream_user_struct *up_data)
1081{
1082 cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
1083}
1084
1085void cx25821_dev_unregister(struct cx25821_dev *dev)
1086{
1087 int i;
1088
1089 if (!dev->base_io_addr)
1090 return;
1091
1092 cx25821_free_mem_upstream_ch1(dev);
1093 cx25821_free_mem_upstream_ch2(dev);
1094 cx25821_free_mem_upstream_audio(dev);
1095
1096 release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
1097
1098 if (!atomic_dec_and_test(&dev->refcount))
1099 return;
1100
1101 for (i = 0; i < VID_CHANNEL_NUM; i++)
1102 cx25821_video_unregister(dev, i);
1103
1104 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1105 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1106 cx25821_video_unregister(dev, i);
1107 }
1108
1109 cx25821_videoioctl_unregister(dev);
1110
1111 cx25821_i2c_unregister(&dev->i2c_bus[0]);
1112 cx25821_iounmap(dev);
1113}
1114
1115static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
1116 unsigned int offset, u32 sync_line,
1117 unsigned int bpl, unsigned int padding,
1118 unsigned int lines)
1119{
1120 struct scatterlist *sg;
1121 unsigned int line, todo;
1122
1123 /* sync instruction */
1124 if (sync_line != NO_SYNC_LINE) {
1125 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1126 }
1127
1128 /* scan lines */
1129 sg = sglist;
1130 for (line = 0; line < lines; line++) {
1131 while (offset && offset >= sg_dma_len(sg)) {
1132 offset -= sg_dma_len(sg);
1133 sg++;
1134 }
1135 if (bpl <= sg_dma_len(sg) - offset) {
1136 /* fits into current chunk */
1137 *(rp++) =
1138 cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl);
1139 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1140 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1141 offset += bpl;
1142 } else {
1143 /* scanline needs to be split */
1144 todo = bpl;
1145 *(rp++) =
1146 cpu_to_le32(RISC_WRITE | RISC_SOL |
1147 (sg_dma_len(sg) - offset));
1148 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1149 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1150 todo -= (sg_dma_len(sg) - offset);
1151 offset = 0;
1152 sg++;
1153 while (todo > sg_dma_len(sg)) {
1154 *(rp++) =
1155 cpu_to_le32(RISC_WRITE | sg_dma_len(sg));
1156 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1157 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1158 todo -= sg_dma_len(sg);
1159 sg++;
1160 }
1161 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1162 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1163 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1164 offset += todo;
1165 }
1166
1167 offset += padding;
1168 }
1169
1170 return rp;
1171}
1172
1173int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
1174 struct scatterlist *sglist, unsigned int top_offset,
1175 unsigned int bottom_offset, unsigned int bpl,
1176 unsigned int padding, unsigned int lines)
1177{
1178 u32 instructions;
1179 u32 fields;
1180 __le32 *rp;
1181 int rc;
1182
1183 fields = 0;
1184 if (UNSET != top_offset)
1185 fields++;
1186 if (UNSET != bottom_offset)
1187 fields++;
1188
1189 /* estimate risc mem: worst case is one write per page border +
1190 one write per scan line + syncs + jump (all 2 dwords). Padding
1191 can cause next bpl to start close to a page border. First DMA
1192 region may be smaller than PAGE_SIZE */
1193 /* write and jump need and extra dword */
1194 instructions =
1195 fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
1196 instructions += 2;
1197 rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
1198
1199 if (rc < 0)
1200 return rc;
1201
1202 /* write risc instructions */
1203 rp = risc->cpu;
1204
1205 if (UNSET != top_offset) {
1206 rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
1207 lines);
1208 }
1209
1210 if (UNSET != bottom_offset) {
1211 rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
1212 padding, lines);
1213 }
1214
1215 /* save pointer to jmp instruction address */
1216 risc->jmp = rp;
1217 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1218
1219 return 0;
1220}
1221
1222static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
1223 unsigned int offset, u32 sync_line,
1224 unsigned int bpl, unsigned int padding,
1225 unsigned int lines, unsigned int lpi)
1226{
1227 struct scatterlist *sg;
1228 unsigned int line, todo, sol;
1229
1230 /* sync instruction */
1231 if (sync_line != NO_SYNC_LINE)
1232 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1233
1234 /* scan lines */
1235 sg = sglist;
1236 for (line = 0; line < lines; line++) {
1237 while (offset && offset >= sg_dma_len(sg)) {
1238 offset -= sg_dma_len(sg);
1239 sg++;
1240 }
1241
1242 if (lpi && line > 0 && !(line % lpi))
1243 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
1244 else
1245 sol = RISC_SOL;
1246
1247 if (bpl <= sg_dma_len(sg) - offset) {
1248 /* fits into current chunk */
1249 *(rp++) =
1250 cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl);
1251 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1252 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1253 offset += bpl;
1254 } else {
1255 /* scanline needs to be split */
1256 todo = bpl;
1257 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
1258 (sg_dma_len(sg) - offset));
1259 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1260 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1261 todo -= (sg_dma_len(sg) - offset);
1262 offset = 0;
1263 sg++;
1264 while (todo > sg_dma_len(sg)) {
1265 *(rp++) = cpu_to_le32(RISC_WRITE |
1266 sg_dma_len(sg));
1267 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1268 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1269 todo -= sg_dma_len(sg);
1270 sg++;
1271 }
1272 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1273 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1274 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1275 offset += todo;
1276 }
1277 offset += padding;
1278 }
1279
1280 return rp;
1281}
1282
1283int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1284 struct btcx_riscmem *risc,
1285 struct scatterlist *sglist,
1286 unsigned int bpl,
1287 unsigned int lines, unsigned int lpi)
1288{
1289 u32 instructions;
1290 __le32 *rp;
1291 int rc;
1292
1293 /* estimate risc mem: worst case is one write per page border +
1294 one write per scan line + syncs + jump (all 2 dwords). Here
1295 there is no padding and no sync. First DMA region may be smaller
1296 than PAGE_SIZE */
1297 /* Jump and write need an extra dword */
1298 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1299 instructions += 1;
1300
1301 if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0)
1302 return rc;
1303
1304 /* write risc instructions */
1305 rp = risc->cpu;
1306 rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
1307 lines, lpi);
1308
1309 /* save pointer to jmp instruction address */
1310 risc->jmp = rp;
1311 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1312 return 0;
1313}
1314
1315int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
1316 u32 reg, u32 mask, u32 value)
1317{
1318 __le32 *rp;
1319 int rc;
1320
1321 rc = btcx_riscmem_alloc(pci, risc, 4 * 16);
1322
1323 if (rc < 0)
1324 return rc;
1325
1326 /* write risc instructions */
1327 rp = risc->cpu;
1328
1329 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
1330 *(rp++) = cpu_to_le32(reg);
1331 *(rp++) = cpu_to_le32(value);
1332 *(rp++) = cpu_to_le32(mask);
1333 *(rp++) = cpu_to_le32(RISC_JUMP);
1334 *(rp++) = cpu_to_le32(risc->dma);
1335 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1336 return 0;
1337}
1338
1339void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
1340{
1341 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
1342
1343 BUG_ON(in_interrupt());
1344 videobuf_waiton(&buf->vb, 0, 0);
1345 videobuf_dma_unmap(q, dma);
1346 videobuf_dma_free(dma);
1347 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
1348 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1349}
1350
1351static irqreturn_t cx25821_irq(int irq, void *dev_id)
1352{
1353 struct cx25821_dev *dev = dev_id;
1354 u32 pci_status, pci_mask;
1355 u32 vid_status;
1356 int i, handled = 0;
1357 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
1358
1359 pci_status = cx_read(PCI_INT_STAT);
1360 pci_mask = cx_read(PCI_INT_MSK);
1361
1362 if (pci_status == 0)
1363 goto out;
1364
1365 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1366 if (pci_status & mask[i]) {
1367 vid_status = cx_read(dev->sram_channels[i].int_stat);
1368
1369 if (vid_status)
1370 handled +=
1371 cx25821_video_irq(dev, i, vid_status);
1372
1373 cx_write(PCI_INT_STAT, mask[i]);
1374 }
1375 }
1376
1377 out:
1378 return IRQ_RETVAL(handled);
1379}
1380
1381void cx25821_print_irqbits(char *name, char *tag, char **strings,
1382 int len, u32 bits, u32 mask)
1383{
1384 unsigned int i;
1385
1386 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
1387
1388 for (i = 0; i < len; i++) {
1389 if (!(bits & (1 << i)))
1390 continue;
1391 if (strings[i])
1392 printk(" %s", strings[i]);
1393 else
1394 printk(" %d", i);
1395 if (!(mask & (1 << i)))
1396 continue;
1397 printk("*");
1398 }
1399 printk("\n");
1400}
1401
1402struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
1403{
1404 struct cx25821_dev *dev = pci_get_drvdata(pci);
1405 return dev;
1406}
1407
1408static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1409 const struct pci_device_id *pci_id)
1410{
1411 struct cx25821_dev *dev;
1412 int err = 0;
1413
1414 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1415 if (NULL == dev)
1416 return -ENOMEM;
1417
1418 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
1419 if (err < 0)
1420 goto fail_free;
1421
1422 /* pci init */
1423 dev->pci = pci_dev;
1424 if (pci_enable_device(pci_dev)) {
1425 err = -EIO;
1426
1427 printk(KERN_INFO "pci enable failed! ");
1428
1429 goto fail_unregister_device;
1430 }
1431
1432 printk(KERN_INFO "cx25821 Athena pci enable ! \n");
1433
1434 if (cx25821_dev_setup(dev) < 0) {
1435 err = -EINVAL;
1436 goto fail_unregister_device;
1437 }
1438
1439 /* print pci info */
1440 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1441 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1442 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1443 "latency: %d, mmio: 0x%llx\n", dev->name,
1444 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1445 dev->pci_lat, (unsigned long long)dev->base_io_addr);
1446
1447 pci_set_master(pci_dev);
1448 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
1449 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1450 err = -EIO;
1451 goto fail_irq;
1452 }
1453
1454 err =
1455 request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED | IRQF_DISABLED,
1456 dev->name, dev);
1457
1458 if (err < 0) {
1459 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
1460 pci_dev->irq);
1461 goto fail_irq;
1462 }
1463
1464 return 0;
1465
1466 fail_irq:
1467 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n");
1468 cx25821_dev_unregister(dev);
1469
1470 fail_unregister_device:
1471 v4l2_device_unregister(&dev->v4l2_dev);
1472
1473 fail_free:
1474 kfree(dev);
1475 return err;
1476}
1477
1478static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1479{
1480 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1481 struct cx25821_dev *dev = get_cx25821(v4l2_dev);
1482
1483 cx25821_shutdown(dev);
1484 pci_disable_device(pci_dev);
1485
1486 /* unregister stuff */
1487 if (pci_dev->irq)
1488 free_irq(pci_dev->irq, dev);
1489
1490 mutex_lock(&devlist);
1491 list_del(&dev->devlist);
1492 mutex_unlock(&devlist);
1493
1494 cx25821_dev_unregister(dev);
1495 v4l2_device_unregister(v4l2_dev);
1496 kfree(dev);
1497}
1498
1499static struct pci_device_id cx25821_pci_tbl[] = {
1500 {
1501 /* CX25821 Athena */
1502 .vendor = 0x14f1,
1503 .device = 0x8210,
1504 .subvendor = 0x14f1,
1505 .subdevice = 0x0920,
1506 },
1507 {
1508 /* --- end of list --- */
1509 }
1510};
1511
1512MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
1513
1514static struct pci_driver cx25821_pci_driver = {
1515 .name = "cx25821",
1516 .id_table = cx25821_pci_tbl,
1517 .probe = cx25821_initdev,
1518 .remove = __devexit_p(cx25821_finidev),
1519 /* TODO */
1520 .suspend = NULL,
1521 .resume = NULL,
1522};
1523
1524static int cx25821_init(void)
1525{
1526 INIT_LIST_HEAD(&cx25821_devlist);
1527 printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
1528 (CX25821_VERSION_CODE >> 16) & 0xff,
1529 (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
1530 return pci_register_driver(&cx25821_pci_driver);
1531}
1532
1533static void cx25821_fini(void)
1534{
1535 pci_unregister_driver(&cx25821_pci_driver);
1536}
1537
1538EXPORT_SYMBOL(cx25821_devlist);
1539EXPORT_SYMBOL(cx25821_sram_channels);
1540EXPORT_SYMBOL(cx25821_print_irqbits);
1541EXPORT_SYMBOL(cx25821_dev_get);
1542EXPORT_SYMBOL(cx25821_dev_unregister);
1543EXPORT_SYMBOL(cx25821_sram_channel_setup);
1544EXPORT_SYMBOL(cx25821_sram_channel_dump);
1545EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
1546EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
1547EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1548EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
1549
1550module_init(cx25821_init);
1551module_exit(cx25821_fini);
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
new file mode 100644
index 000000000000..e8a37b47e437
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -0,0 +1,98 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24
25/********************* GPIO stuffs *********************/
26void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
27 int pin_number, int pin_logic_value)
28{
29 int bit = pin_number;
30 u32 gpio_oe_reg = GPIO_LO_OE;
31 u32 gpio_register = 0;
32 u32 value = 0;
33
34 // Check for valid pinNumber
35 if (pin_number >= 47)
36 return;
37
38 if (pin_number > 31) {
39 bit = pin_number - 31;
40 gpio_oe_reg = GPIO_HI_OE;
41 }
42 // Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is
43 gpio_register = cx_read(gpio_oe_reg);
44
45 if (pin_logic_value == 1) {
46 value = gpio_register | Set_GPIO_Bit(bit);
47 } else {
48 value = gpio_register & Clear_GPIO_Bit(bit);
49 }
50
51 cx_write(gpio_oe_reg, value);
52}
53
54static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
55 int pin_number, int pin_logic_value)
56{
57 int bit = pin_number;
58 u32 gpio_reg = GPIO_LO;
59 u32 value = 0;
60
61 // Check for valid pinNumber
62 if (pin_number >= 47)
63 return;
64
65 cx25821_set_gpiopin_direction(dev, pin_number, 0); // change to output direction
66
67 if (pin_number > 31) {
68 bit = pin_number - 31;
69 gpio_reg = GPIO_HI;
70 }
71
72 value = cx_read(gpio_reg);
73
74 if (pin_logic_value == 0) {
75 value &= Clear_GPIO_Bit(bit);
76 } else {
77 value |= Set_GPIO_Bit(bit);
78 }
79
80 cx_write(gpio_reg, value);
81}
82
83void cx25821_gpio_init(struct cx25821_dev *dev)
84{
85 if (dev == NULL) {
86 return;
87 }
88
89 switch (dev->board) {
90 case CX25821_BOARD_CONEXANT_ATHENA10:
91 default:
92 //set GPIO 5 to select the path for Medusa/Athena
93 cx25821_set_gpiopin_logicvalue(dev, 5, 1);
94 mdelay(20);
95 break;
96 }
97
98}
diff --git a/drivers/staging/cx25821/cx25821-gpio.h b/drivers/staging/cx25821/cx25821-gpio.h
new file mode 100644
index 000000000000..ca07644154af
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.h
@@ -0,0 +1,2 @@
1
2void cx25821_gpio_init(struct athena_dev *dev);
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
new file mode 100644
index 000000000000..f4f2681d8f1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -0,0 +1,419 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821.h"
25#include <linux/i2c.h>
26
27static unsigned int i2c_debug;
28module_param(i2c_debug, int, 0644);
29MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
30
31static unsigned int i2c_scan = 0;
32module_param(i2c_scan, int, 0444);
33MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
34
35#define dprintk(level, fmt, arg...)\
36 do { if (i2c_debug >= level)\
37 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
38 } while (0)
39
40#define I2C_WAIT_DELAY 32
41#define I2C_WAIT_RETRY 64
42
43#define I2C_EXTEND (1 << 3)
44#define I2C_NOSTOP (1 << 4)
45
46static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
47{
48 struct cx25821_i2c *bus = i2c_adap->algo_data;
49 struct cx25821_dev *dev = bus->dev;
50 return cx_read(bus->reg_stat) & 0x01;
51}
52
53static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
54{
55 struct cx25821_i2c *bus = i2c_adap->algo_data;
56 struct cx25821_dev *dev = bus->dev;
57 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
58}
59
60static int i2c_wait_done(struct i2c_adapter *i2c_adap)
61{
62 int count;
63
64 for (count = 0; count < I2C_WAIT_RETRY; count++) {
65 if (!i2c_is_busy(i2c_adap))
66 break;
67 udelay(I2C_WAIT_DELAY);
68 }
69
70 if (I2C_WAIT_RETRY == count)
71 return 0;
72
73 return 1;
74}
75
76static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
77 const struct i2c_msg *msg, int joined_rlen)
78{
79 struct cx25821_i2c *bus = i2c_adap->algo_data;
80 struct cx25821_dev *dev = bus->dev;
81 u32 wdata, addr, ctrl;
82 int retval, cnt;
83
84 if (joined_rlen)
85 dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
86 msg->len, joined_rlen);
87 else
88 dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
89
90 /* Deal with i2c probe functions with zero payload */
91 if (msg->len == 0) {
92 cx_write(bus->reg_addr, msg->addr << 25);
93 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
94
95 if (!i2c_wait_done(i2c_adap))
96 return -EIO;
97
98 if (!i2c_slave_did_ack(i2c_adap))
99 return -EIO;
100
101 dprintk(1, "%s() returns 0\n", __func__);
102 return 0;
103 }
104
105 /* dev, reg + first byte */
106 addr = (msg->addr << 25) | msg->buf[0];
107 wdata = msg->buf[0];
108
109 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
110
111 if (msg->len > 1)
112 ctrl |= I2C_NOSTOP | I2C_EXTEND;
113 else if (joined_rlen)
114 ctrl |= I2C_NOSTOP;
115
116 cx_write(bus->reg_addr, addr);
117 cx_write(bus->reg_wdata, wdata);
118 cx_write(bus->reg_ctrl, ctrl);
119
120 retval = i2c_wait_done(i2c_adap);
121 if (retval < 0)
122 goto err;
123
124 if (retval == 0)
125 goto eio;
126
127 if (i2c_debug) {
128 if (!(ctrl & I2C_NOSTOP))
129 printk(" >\n");
130 }
131
132 for (cnt = 1; cnt < msg->len; cnt++) {
133 /* following bytes */
134 wdata = msg->buf[cnt];
135 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
136
137 if (cnt < msg->len - 1)
138 ctrl |= I2C_NOSTOP | I2C_EXTEND;
139 else if (joined_rlen)
140 ctrl |= I2C_NOSTOP;
141
142 cx_write(bus->reg_addr, addr);
143 cx_write(bus->reg_wdata, wdata);
144 cx_write(bus->reg_ctrl, ctrl);
145
146 retval = i2c_wait_done(i2c_adap);
147 if (retval < 0)
148 goto err;
149
150 if (retval == 0)
151 goto eio;
152
153 if (i2c_debug) {
154 dprintk(1, " %02x", msg->buf[cnt]);
155 if (!(ctrl & I2C_NOSTOP))
156 dprintk(1, " >\n");
157 }
158 }
159
160 return msg->len;
161
162 eio:
163 retval = -EIO;
164 err:
165 if (i2c_debug)
166 printk(KERN_ERR " ERR: %d\n", retval);
167 return retval;
168}
169
170static int i2c_readbytes(struct i2c_adapter *i2c_adap,
171 const struct i2c_msg *msg, int joined)
172{
173 struct cx25821_i2c *bus = i2c_adap->algo_data;
174 struct cx25821_dev *dev = bus->dev;
175 u32 ctrl, cnt;
176 int retval;
177
178 if (i2c_debug && !joined)
179 dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
180
181 /* Deal with i2c probe functions with zero payload */
182 if (msg->len == 0) {
183 cx_write(bus->reg_addr, msg->addr << 25);
184 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
185 if (!i2c_wait_done(i2c_adap))
186 return -EIO;
187 if (!i2c_slave_did_ack(i2c_adap))
188 return -EIO;
189
190 dprintk(1, "%s() returns 0\n", __func__);
191 return 0;
192 }
193
194 if (i2c_debug) {
195 if (joined)
196 dprintk(1, " R");
197 else
198 dprintk(1, " <R %02x", (msg->addr << 1) + 1);
199 }
200
201 for (cnt = 0; cnt < msg->len; cnt++) {
202
203 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
204
205 if (cnt < msg->len - 1)
206 ctrl |= I2C_NOSTOP | I2C_EXTEND;
207
208 cx_write(bus->reg_addr, msg->addr << 25);
209 cx_write(bus->reg_ctrl, ctrl);
210
211 retval = i2c_wait_done(i2c_adap);
212 if (retval < 0)
213 goto err;
214 if (retval == 0)
215 goto eio;
216 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
217
218 if (i2c_debug) {
219 dprintk(1, " %02x", msg->buf[cnt]);
220 if (!(ctrl & I2C_NOSTOP))
221 dprintk(1, " >\n");
222 }
223 }
224
225 return msg->len;
226 eio:
227 retval = -EIO;
228 err:
229 if (i2c_debug)
230 printk(KERN_ERR " ERR: %d\n", retval);
231 return retval;
232}
233
234static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
235{
236 struct cx25821_i2c *bus = i2c_adap->algo_data;
237 struct cx25821_dev *dev = bus->dev;
238 int i, retval = 0;
239
240 dprintk(1, "%s(num = %d)\n", __func__, num);
241
242 for (i = 0; i < num; i++) {
243 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
244 __func__, num, msgs[i].addr, msgs[i].len);
245
246 if (msgs[i].flags & I2C_M_RD) {
247 /* read */
248 retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
249 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
250 msgs[i].addr == msgs[i + 1].addr) {
251 /* write then read from same address */
252 retval =
253 i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
254
255 if (retval < 0)
256 goto err;
257 i++;
258 retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
259 } else {
260 /* write */
261 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
262 }
263
264 if (retval < 0)
265 goto err;
266 }
267 return num;
268
269 err:
270 return retval;
271}
272
273
274static u32 cx25821_functionality(struct i2c_adapter *adap)
275{
276 return I2C_FUNC_SMBUS_EMUL |
277 I2C_FUNC_I2C |
278 I2C_FUNC_SMBUS_WORD_DATA |
279 I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
280}
281
282static struct i2c_algorithm cx25821_i2c_algo_template = {
283 .master_xfer = i2c_xfer,
284 .functionality = cx25821_functionality,
285};
286
287static struct i2c_adapter cx25821_i2c_adap_template = {
288 .name = "cx25821",
289 .owner = THIS_MODULE,
290 .algo = &cx25821_i2c_algo_template,
291};
292
293static struct i2c_client cx25821_i2c_client_template = {
294 .name = "cx25821 internal",
295};
296
297/* init + register i2c algo-bit adapter */
298int cx25821_i2c_register(struct cx25821_i2c *bus)
299{
300 struct cx25821_dev *dev = bus->dev;
301
302 dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
303
304 memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
305 sizeof(bus->i2c_adap));
306 memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
307 sizeof(bus->i2c_algo));
308 memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
309 sizeof(bus->i2c_client));
310
311 bus->i2c_adap.dev.parent = &dev->pci->dev;
312
313 strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
314
315 bus->i2c_algo.data = bus;
316 bus->i2c_adap.algo_data = bus;
317 i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
318 i2c_add_adapter(&bus->i2c_adap);
319
320 bus->i2c_client.adapter = &bus->i2c_adap;
321
322 //set up the I2c
323 bus->i2c_client.addr = (0x88 >> 1);
324
325 return bus->i2c_rc;
326}
327
328int cx25821_i2c_unregister(struct cx25821_i2c *bus)
329{
330 i2c_del_adapter(&bus->i2c_adap);
331 return 0;
332}
333
334void cx25821_av_clk(struct cx25821_dev *dev, int enable)
335{
336 /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
337 char buffer[3];
338 struct i2c_msg msg;
339 dprintk(1, "%s(enabled = %d)\n", __func__, enable);
340
341 /* Register 0x144 */
342 buffer[0] = 0x01;
343 buffer[1] = 0x44;
344 if (enable == 1)
345 buffer[2] = 0x05;
346 else
347 buffer[2] = 0x00;
348
349 msg.addr = 0x44;
350 msg.flags = I2C_M_TEN;
351 msg.len = 3;
352 msg.buf = buffer;
353
354 i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
355}
356
357int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
358{
359 struct i2c_client *client = &bus->i2c_client;
360 int retval = 0;
361 int v = 0;
362 u8 addr[2] = { 0, 0 };
363 u8 buf[4] = { 0, 0, 0, 0 };
364
365 struct i2c_msg msgs[2] = {
366 {
367 .addr = client->addr,
368 .flags = 0,
369 .len = 2,
370 .buf = addr,
371 }, {
372 .addr = client->addr,
373 .flags = I2C_M_RD,
374 .len = 4,
375 .buf = buf,
376 }
377 };
378
379 addr[0] = (reg_addr >> 8);
380 addr[1] = (reg_addr & 0xff);
381 msgs[0].addr = 0x44;
382 msgs[1].addr = 0x44;
383
384 retval = i2c_xfer(client->adapter, msgs, 2);
385
386 v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
387 *value = v;
388
389 return v;
390}
391
392int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
393{
394 struct i2c_client *client = &bus->i2c_client;
395 int retval = 0;
396 u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
397
398 struct i2c_msg msgs[1] = {
399 {
400 .addr = client->addr,
401 .flags = 0,
402 .len = 6,
403 .buf = buf,
404 }
405 };
406
407 buf[0] = reg_addr >> 8;
408 buf[1] = reg_addr & 0xff;
409 buf[5] = (value >> 24) & 0xff;
410 buf[4] = (value >> 16) & 0xff;
411 buf[3] = (value >> 8) & 0xff;
412 buf[2] = value & 0xff;
413 client->flags = 0;
414 msgs[0].addr = 0x44;
415
416 retval = i2c_xfer(client->adapter, msgs, 1);
417
418 return retval;
419}
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
new file mode 100644
index 000000000000..b0d216ba7f81
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-defines.h
@@ -0,0 +1,51 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_DEF_H_
24#define _MEDUSA_DEF_H_
25
26// Video deocder that we supported
27#define VDEC_A 0
28#define VDEC_B 1
29#define VDEC_C 2
30#define VDEC_D 3
31#define VDEC_E 4
32#define VDEC_F 5
33#define VDEC_G 6
34#define VDEC_H 7
35
36//#define AUTO_SWITCH_BIT[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
37
38// The following bit position enables automatic source switching for decoder A-H.
39// Display index per camera.
40//#define VDEC_INDEX[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
41
42// Select input bit to video decoder A-H.
43//#define CH_SRC_SEL_BIT[] = {24, 25, 26, 27, 28, 29, 30, 31};
44
45// end of display sequence
46#define END_OF_SEQ 0xF;
47
48// registry string size
49#define MAX_REGISTRY_SZ 40;
50
51#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h
new file mode 100644
index 000000000000..12c90f831b22
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -0,0 +1,455 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __MEDUSA_REGISTERS__
24#define __MEDUSA_REGISTERS__
25
26// Serial Slave Registers
27#define HOST_REGISTER1 0x0000
28#define HOST_REGISTER2 0x0001
29
30// Chip Configuration Registers
31#define CHIP_CTRL 0x0100
32#define AFE_AB_CTRL 0x0104
33#define AFE_CD_CTRL 0x0108
34#define AFE_EF_CTRL 0x010C
35#define AFE_GH_CTRL 0x0110
36#define DENC_AB_CTRL 0x0114
37#define BYP_AB_CTRL 0x0118
38#define MON_A_CTRL 0x011C
39#define DISP_SEQ_A 0x0120
40#define DISP_SEQ_B 0x0124
41#define DISP_AB_CNT 0x0128
42#define DISP_CD_CNT 0x012C
43#define DISP_EF_CNT 0x0130
44#define DISP_GH_CNT 0x0134
45#define DISP_IJ_CNT 0x0138
46#define PIN_OE_CTRL 0x013C
47#define PIN_SPD_CTRL 0x0140
48#define PIN_SPD_CTRL2 0x0144
49#define IRQ_STAT_CTRL 0x0148
50#define POWER_CTRL_AB 0x014C
51#define POWER_CTRL_CD 0x0150
52#define POWER_CTRL_EF 0x0154
53#define POWER_CTRL_GH 0x0158
54#define TUNE_CTRL 0x015C
55#define BIAS_CTRL 0x0160
56#define AFE_AB_DIAG_CTRL 0x0164
57#define AFE_CD_DIAG_CTRL 0x0168
58#define AFE_EF_DIAG_CTRL 0x016C
59#define AFE_GH_DIAG_CTRL 0x0170
60#define PLL_AB_DIAG_CTRL 0x0174
61#define PLL_CD_DIAG_CTRL 0x0178
62#define PLL_EF_DIAG_CTRL 0x017C
63#define PLL_GH_DIAG_CTRL 0x0180
64#define TEST_CTRL 0x0184
65#define BIST_STAT 0x0188
66#define BIST_STAT2 0x018C
67#define BIST_VID_PLL_AB_STAT 0x0190
68#define BIST_VID_PLL_CD_STAT 0x0194
69#define BIST_VID_PLL_EF_STAT 0x0198
70#define BIST_VID_PLL_GH_STAT 0x019C
71#define DLL_DIAG_CTRL 0x01A0
72#define DEV_CH_ID_CTRL 0x01A4
73#define ABIST_CTRL_STATUS 0x01A8
74#define ABIST_FREQ 0x01AC
75#define ABIST_GOERT_SHIFT 0x01B0
76#define ABIST_COEF12 0x01B4
77#define ABIST_COEF34 0x01B8
78#define ABIST_COEF56 0x01BC
79#define ABIST_COEF7_SNR 0x01C0
80#define ABIST_ADC_CAL 0x01C4
81#define ABIST_BIN1_VGA0 0x01C8
82#define ABIST_BIN2_VGA1 0x01CC
83#define ABIST_BIN3_VGA2 0x01D0
84#define ABIST_BIN4_VGA3 0x01D4
85#define ABIST_BIN5_VGA4 0x01D8
86#define ABIST_BIN6_VGA5 0x01DC
87#define ABIST_BIN7_VGA6 0x0x1E0
88#define ABIST_CLAMP_A 0x0x1E4
89#define ABIST_CLAMP_B 0x0x1E8
90#define ABIST_CLAMP_C 0x01EC
91#define ABIST_CLAMP_D 0x01F0
92#define ABIST_CLAMP_E 0x01F4
93#define ABIST_CLAMP_F 0x01F8
94
95// Digital Video Encoder A Registers
96#define DENC_A_REG_1 0x0200
97#define DENC_A_REG_2 0x0204
98#define DENC_A_REG_3 0x0208
99#define DENC_A_REG_4 0x020C
100#define DENC_A_REG_5 0x0210
101#define DENC_A_REG_6 0x0214
102#define DENC_A_REG_7 0x0218
103#define DENC_A_REG_8 0x021C
104
105// Digital Video Encoder B Registers
106#define DENC_B_REG_1 0x0300
107#define DENC_B_REG_2 0x0304
108#define DENC_B_REG_3 0x0308
109#define DENC_B_REG_4 0x030C
110#define DENC_B_REG_5 0x0310
111#define DENC_B_REG_6 0x0314
112#define DENC_B_REG_7 0x0318
113#define DENC_B_REG_8 0x031C
114
115// Video Decoder A Registers
116#define MODE_CTRL 0x1000
117#define OUT_CTRL1 0x1004
118#define OUT_CTRL_NS 0x1008
119#define GEN_STAT 0x100C
120#define INT_STAT_MASK 0x1010
121#define LUMA_CTRL 0x1014
122#define CHROMA_CTRL 0x1018
123#define CRUSH_CTRL 0x101C
124#define HORIZ_TIM_CTRL 0x1020
125#define VERT_TIM_CTRL 0x1024
126#define MISC_TIM_CTRL 0x1028
127#define FIELD_COUNT 0x102C
128#define HSCALE_CTRL 0x1030
129#define VSCALE_CTRL 0x1034
130#define MAN_VGA_CTRL 0x1038
131#define MAN_AGC_CTRL 0x103C
132#define DFE_CTRL1 0x1040
133#define DFE_CTRL2 0x1044
134#define DFE_CTRL3 0x1048
135#define PLL_CTRL 0x104C
136#define PLL_CTRL_FAST 0x1050
137#define HTL_CTRL 0x1054
138#define SRC_CFG 0x1058
139#define SC_STEP_SIZE 0x105C
140#define SC_CONVERGE_CTRL 0x1060
141#define SC_LOOP_CTRL 0x1064
142#define COMB_2D_HFS_CFG 0x1068
143#define COMB_2D_HFD_CFG 0x106C
144#define COMB_2D_LF_CFG 0x1070
145#define COMB_2D_BLEND 0x1074
146#define COMB_MISC_CTRL 0x1078
147#define COMB_FLAT_THRESH_CTRL 0x107C
148#define COMB_TEST 0x1080
149#define BP_MISC_CTRL 0x1084
150#define VCR_DET_CTRL 0x1088
151#define NOISE_DET_CTRL 0x108C
152#define COMB_FLAT_NOISE_CTRL 0x1090
153#define VERSION 0x11F8
154#define SOFT_RST_CTRL 0x11FC
155
156// Video Decoder B Registers
157#define VDEC_B_MODE_CTRL 0x1200
158#define VDEC_B_OUT_CTRL1 0x1204
159#define VDEC_B_OUT_CTRL_NS 0x1208
160#define VDEC_B_GEN_STAT 0x120C
161#define VDEC_B_INT_STAT_MASK 0x1210
162#define VDEC_B_LUMA_CTRL 0x1214
163#define VDEC_B_CHROMA_CTRL 0x1218
164#define VDEC_B_CRUSH_CTRL 0x121C
165#define VDEC_B_HORIZ_TIM_CTRL 0x1220
166#define VDEC_B_VERT_TIM_CTRL 0x1224
167#define VDEC_B_MISC_TIM_CTRL 0x1228
168#define VDEC_B_FIELD_COUNT 0x122C
169#define VDEC_B_HSCALE_CTRL 0x1230
170#define VDEC_B_VSCALE_CTRL 0x1234
171#define VDEC_B_MAN_VGA_CTRL 0x1238
172#define VDEC_B_MAN_AGC_CTRL 0x123C
173#define VDEC_B_DFE_CTRL1 0x1240
174#define VDEC_B_DFE_CTRL2 0x1244
175#define VDEC_B_DFE_CTRL3 0x1248
176#define VDEC_B_PLL_CTRL 0x124C
177#define VDEC_B_PLL_CTRL_FAST 0x1250
178#define VDEC_B_HTL_CTRL 0x1254
179#define VDEC_B_SRC_CFG 0x1258
180#define VDEC_B_SC_STEP_SIZE 0x125C
181#define VDEC_B_SC_CONVERGE_CTRL 0x1260
182#define VDEC_B_SC_LOOP_CTRL 0x1264
183#define VDEC_B_COMB_2D_HFS_CFG 0x1268
184#define VDEC_B_COMB_2D_HFD_CFG 0x126C
185#define VDEC_B_COMB_2D_LF_CFG 0x1270
186#define VDEC_B_COMB_2D_BLEND 0x1274
187#define VDEC_B_COMB_MISC_CTRL 0x1278
188#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C
189#define VDEC_B_COMB_TEST 0x1280
190#define VDEC_B_BP_MISC_CTRL 0x1284
191#define VDEC_B_VCR_DET_CTRL 0x1288
192#define VDEC_B_NOISE_DET_CTRL 0x128C
193#define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290
194#define VDEC_B_VERSION 0x13F8
195#define VDEC_B_SOFT_RST_CTRL 0x13FC
196
197// Video Decoder C Registers
198#define VDEC_C_MODE_CTRL 0x1400
199#define VDEC_C_OUT_CTRL1 0x1404
200#define VDEC_C_OUT_CTRL_NS 0x1408
201#define VDEC_C_GEN_STAT 0x140C
202#define VDEC_C_INT_STAT_MASK 0x1410
203#define VDEC_C_LUMA_CTRL 0x1414
204#define VDEC_C_CHROMA_CTRL 0x1418
205#define VDEC_C_CRUSH_CTRL 0x141C
206#define VDEC_C_HORIZ_TIM_CTRL 0x1420
207#define VDEC_C_VERT_TIM_CTRL 0x1424
208#define VDEC_C_MISC_TIM_CTRL 0x1428
209#define VDEC_C_FIELD_COUNT 0x142C
210#define VDEC_C_HSCALE_CTRL 0x1430
211#define VDEC_C_VSCALE_CTRL 0x1434
212#define VDEC_C_MAN_VGA_CTRL 0x1438
213#define VDEC_C_MAN_AGC_CTRL 0x143C
214#define VDEC_C_DFE_CTRL1 0x1440
215#define VDEC_C_DFE_CTRL2 0x1444
216#define VDEC_C_DFE_CTRL3 0x1448
217#define VDEC_C_PLL_CTRL 0x144C
218#define VDEC_C_PLL_CTRL_FAST 0x1450
219#define VDEC_C_HTL_CTRL 0x1454
220#define VDEC_C_SRC_CFG 0x1458
221#define VDEC_C_SC_STEP_SIZE 0x145C
222#define VDEC_C_SC_CONVERGE_CTRL 0x1460
223#define VDEC_C_SC_LOOP_CTRL 0x1464
224#define VDEC_C_COMB_2D_HFS_CFG 0x1468
225#define VDEC_C_COMB_2D_HFD_CFG 0x146C
226#define VDEC_C_COMB_2D_LF_CFG 0x1470
227#define VDEC_C_COMB_2D_BLEND 0x1474
228#define VDEC_C_COMB_MISC_CTRL 0x1478
229#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C
230#define VDEC_C_COMB_TEST 0x1480
231#define VDEC_C_BP_MISC_CTRL 0x1484
232#define VDEC_C_VCR_DET_CTRL 0x1488
233#define VDEC_C_NOISE_DET_CTRL 0x148C
234#define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490
235#define VDEC_C_VERSION 0x15F8
236#define VDEC_C_SOFT_RST_CTRL 0x15FC
237
238// Video Decoder D Registers
239#define VDEC_D_MODE_CTRL 0x1600
240#define VDEC_D_OUT_CTRL1 0x1604
241#define VDEC_D_OUT_CTRL_NS 0x1608
242#define VDEC_D_GEN_STAT 0x160C
243#define VDEC_D_INT_STAT_MASK 0x1610
244#define VDEC_D_LUMA_CTRL 0x1614
245#define VDEC_D_CHROMA_CTRL 0x1618
246#define VDEC_D_CRUSH_CTRL 0x161C
247#define VDEC_D_HORIZ_TIM_CTRL 0x1620
248#define VDEC_D_VERT_TIM_CTRL 0x1624
249#define VDEC_D_MISC_TIM_CTRL 0x1628
250#define VDEC_D_FIELD_COUNT 0x162C
251#define VDEC_D_HSCALE_CTRL 0x1630
252#define VDEC_D_VSCALE_CTRL 0x1634
253#define VDEC_D_MAN_VGA_CTRL 0x1638
254#define VDEC_D_MAN_AGC_CTRL 0x163C
255#define VDEC_D_DFE_CTRL1 0x1640
256#define VDEC_D_DFE_CTRL2 0x1644
257#define VDEC_D_DFE_CTRL3 0x1648
258#define VDEC_D_PLL_CTRL 0x164C
259#define VDEC_D_PLL_CTRL_FAST 0x1650
260#define VDEC_D_HTL_CTRL 0x1654
261#define VDEC_D_SRC_CFG 0x1658
262#define VDEC_D_SC_STEP_SIZE 0x165C
263#define VDEC_D_SC_CONVERGE_CTRL 0x1660
264#define VDEC_D_SC_LOOP_CTRL 0x1664
265#define VDEC_D_COMB_2D_HFS_CFG 0x1668
266#define VDEC_D_COMB_2D_HFD_CFG 0x166C
267#define VDEC_D_COMB_2D_LF_CFG 0x1670
268#define VDEC_D_COMB_2D_BLEND 0x1674
269#define VDEC_D_COMB_MISC_CTRL 0x1678
270#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C
271#define VDEC_D_COMB_TEST 0x1680
272#define VDEC_D_BP_MISC_CTRL 0x1684
273#define VDEC_D_VCR_DET_CTRL 0x1688
274#define VDEC_D_NOISE_DET_CTRL 0x168C
275#define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690
276#define VDEC_D_VERSION 0x17F8
277#define VDEC_D_SOFT_RST_CTRL 0x17FC
278
279// Video Decoder E Registers
280#define VDEC_E_MODE_CTRL 0x1800
281#define VDEC_E_OUT_CTRL1 0x1804
282#define VDEC_E_OUT_CTRL_NS 0x1808
283#define VDEC_E_GEN_STAT 0x180C
284#define VDEC_E_INT_STAT_MASK 0x1810
285#define VDEC_E_LUMA_CTRL 0x1814
286#define VDEC_E_CHROMA_CTRL 0x1818
287#define VDEC_E_CRUSH_CTRL 0x181C
288#define VDEC_E_HORIZ_TIM_CTRL 0x1820
289#define VDEC_E_VERT_TIM_CTRL 0x1824
290#define VDEC_E_MISC_TIM_CTRL 0x1828
291#define VDEC_E_FIELD_COUNT 0x182C
292#define VDEC_E_HSCALE_CTRL 0x1830
293#define VDEC_E_VSCALE_CTRL 0x1834
294#define VDEC_E_MAN_VGA_CTRL 0x1838
295#define VDEC_E_MAN_AGC_CTRL 0x183C
296#define VDEC_E_DFE_CTRL1 0x1840
297#define VDEC_E_DFE_CTRL2 0x1844
298#define VDEC_E_DFE_CTRL3 0x1848
299#define VDEC_E_PLL_CTRL 0x184C
300#define VDEC_E_PLL_CTRL_FAST 0x1850
301#define VDEC_E_HTL_CTRL 0x1854
302#define VDEC_E_SRC_CFG 0x1858
303#define VDEC_E_SC_STEP_SIZE 0x185C
304#define VDEC_E_SC_CONVERGE_CTRL 0x1860
305#define VDEC_E_SC_LOOP_CTRL 0x1864
306#define VDEC_E_COMB_2D_HFS_CFG 0x1868
307#define VDEC_E_COMB_2D_HFD_CFG 0x186C
308#define VDEC_E_COMB_2D_LF_CFG 0x1870
309#define VDEC_E_COMB_2D_BLEND 0x1874
310#define VDEC_E_COMB_MISC_CTRL 0x1878
311#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C
312#define VDEC_E_COMB_TEST 0x1880
313#define VDEC_E_BP_MISC_CTRL 0x1884
314#define VDEC_E_VCR_DET_CTRL 0x1888
315#define VDEC_E_NOISE_DET_CTRL 0x188C
316#define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890
317#define VDEC_E_VERSION 0x19F8
318#define VDEC_E_SOFT_RST_CTRL 0x19FC
319
320// Video Decoder F Registers
321#define VDEC_F_MODE_CTRL 0x1A00
322#define VDEC_F_OUT_CTRL1 0x1A04
323#define VDEC_F_OUT_CTRL_NS 0x1A08
324#define VDEC_F_GEN_STAT 0x1A0C
325#define VDEC_F_INT_STAT_MASK 0x1A10
326#define VDEC_F_LUMA_CTRL 0x1A14
327#define VDEC_F_CHROMA_CTRL 0x1A18
328#define VDEC_F_CRUSH_CTRL 0x1A1C
329#define VDEC_F_HORIZ_TIM_CTRL 0x1A20
330#define VDEC_F_VERT_TIM_CTRL 0x1A24
331#define VDEC_F_MISC_TIM_CTRL 0x1A28
332#define VDEC_F_FIELD_COUNT 0x1A2C
333#define VDEC_F_HSCALE_CTRL 0x1A30
334#define VDEC_F_VSCALE_CTRL 0x1A34
335#define VDEC_F_MAN_VGA_CTRL 0x1A38
336#define VDEC_F_MAN_AGC_CTRL 0x1A3C
337#define VDEC_F_DFE_CTRL1 0x1A40
338#define VDEC_F_DFE_CTRL2 0x1A44
339#define VDEC_F_DFE_CTRL3 0x1A48
340#define VDEC_F_PLL_CTRL 0x1A4C
341#define VDEC_F_PLL_CTRL_FAST 0x1A50
342#define VDEC_F_HTL_CTRL 0x1A54
343#define VDEC_F_SRC_CFG 0x1A58
344#define VDEC_F_SC_STEP_SIZE 0x1A5C
345#define VDEC_F_SC_CONVERGE_CTRL 0x1A60
346#define VDEC_F_SC_LOOP_CTRL 0x1A64
347#define VDEC_F_COMB_2D_HFS_CFG 0x1A68
348#define VDEC_F_COMB_2D_HFD_CFG 0x1A6C
349#define VDEC_F_COMB_2D_LF_CFG 0x1A70
350#define VDEC_F_COMB_2D_BLEND 0x1A74
351#define VDEC_F_COMB_MISC_CTRL 0x1A78
352#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C
353#define VDEC_F_COMB_TEST 0x1A80
354#define VDEC_F_BP_MISC_CTRL 0x1A84
355#define VDEC_F_VCR_DET_CTRL 0x1A88
356#define VDEC_F_NOISE_DET_CTRL 0x1A8C
357#define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90
358#define VDEC_F_VERSION 0x1BF8
359#define VDEC_F_SOFT_RST_CTRL 0x1BFC
360
361// Video Decoder G Registers
362#define VDEC_G_MODE_CTRL 0x1C00
363#define VDEC_G_OUT_CTRL1 0x1C04
364#define VDEC_G_OUT_CTRL_NS 0x1C08
365#define VDEC_G_GEN_STAT 0x1C0C
366#define VDEC_G_INT_STAT_MASK 0x1C10
367#define VDEC_G_LUMA_CTRL 0x1C14
368#define VDEC_G_CHROMA_CTRL 0x1C18
369#define VDEC_G_CRUSH_CTRL 0x1C1C
370#define VDEC_G_HORIZ_TIM_CTRL 0x1C20
371#define VDEC_G_VERT_TIM_CTRL 0x1C24
372#define VDEC_G_MISC_TIM_CTRL 0x1C28
373#define VDEC_G_FIELD_COUNT 0x1C2C
374#define VDEC_G_HSCALE_CTRL 0x1C30
375#define VDEC_G_VSCALE_CTRL 0x1C34
376#define VDEC_G_MAN_VGA_CTRL 0x1C38
377#define VDEC_G_MAN_AGC_CTRL 0x1C3C
378#define VDEC_G_DFE_CTRL1 0x1C40
379#define VDEC_G_DFE_CTRL2 0x1C44
380#define VDEC_G_DFE_CTRL3 0x1C48
381#define VDEC_G_PLL_CTRL 0x1C4C
382#define VDEC_G_PLL_CTRL_FAST 0x1C50
383#define VDEC_G_HTL_CTRL 0x1C54
384#define VDEC_G_SRC_CFG 0x1C58
385#define VDEC_G_SC_STEP_SIZE 0x1C5C
386#define VDEC_G_SC_CONVERGE_CTRL 0x1C60
387#define VDEC_G_SC_LOOP_CTRL 0x1C64
388#define VDEC_G_COMB_2D_HFS_CFG 0x1C68
389#define VDEC_G_COMB_2D_HFD_CFG 0x1C6C
390#define VDEC_G_COMB_2D_LF_CFG 0x1C70
391#define VDEC_G_COMB_2D_BLEND 0x1C74
392#define VDEC_G_COMB_MISC_CTRL 0x1C78
393#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C
394#define VDEC_G_COMB_TEST 0x1C80
395#define VDEC_G_BP_MISC_CTRL 0x1C84
396#define VDEC_G_VCR_DET_CTRL 0x1C88
397#define VDEC_G_NOISE_DET_CTRL 0x1C8C
398#define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90
399#define VDEC_G_VERSION 0x1DF8
400#define VDEC_G_SOFT_RST_CTRL 0x1DFC
401
402// Video Decoder H Registers
403#define VDEC_H_MODE_CTRL 0x1E00
404#define VDEC_H_OUT_CTRL1 0x1E04
405#define VDEC_H_OUT_CTRL_NS 0x1E08
406#define VDEC_H_GEN_STAT 0x1E0C
407#define VDEC_H_INT_STAT_MASK 0x1E1E
408#define VDEC_H_LUMA_CTRL 0x1E14
409#define VDEC_H_CHROMA_CTRL 0x1E18
410#define VDEC_H_CRUSH_CTRL 0x1E1C
411#define VDEC_H_HORIZ_TIM_CTRL 0x1E20
412#define VDEC_H_VERT_TIM_CTRL 0x1E24
413#define VDEC_H_MISC_TIM_CTRL 0x1E28
414#define VDEC_H_FIELD_COUNT 0x1E2C
415#define VDEC_H_HSCALE_CTRL 0x1E30
416#define VDEC_H_VSCALE_CTRL 0x1E34
417#define VDEC_H_MAN_VGA_CTRL 0x1E38
418#define VDEC_H_MAN_AGC_CTRL 0x1E3C
419#define VDEC_H_DFE_CTRL1 0x1E40
420#define VDEC_H_DFE_CTRL2 0x1E44
421#define VDEC_H_DFE_CTRL3 0x1E48
422#define VDEC_H_PLL_CTRL 0x1E4C
423#define VDEC_H_PLL_CTRL_FAST 0x1E50
424#define VDEC_H_HTL_CTRL 0x1E54
425#define VDEC_H_SRC_CFG 0x1E58
426#define VDEC_H_SC_STEP_SIZE 0x1E5C
427#define VDEC_H_SC_CONVERGE_CTRL 0x1E60
428#define VDEC_H_SC_LOOP_CTRL 0x1E64
429#define VDEC_H_COMB_2D_HFS_CFG 0x1E68
430#define VDEC_H_COMB_2D_HFD_CFG 0x1E6C
431#define VDEC_H_COMB_2D_LF_CFG 0x1E70
432#define VDEC_H_COMB_2D_BLEND 0x1E74
433#define VDEC_H_COMB_MISC_CTRL 0x1E78
434#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C
435#define VDEC_H_COMB_TEST 0x1E80
436#define VDEC_H_BP_MISC_CTRL 0x1E84
437#define VDEC_H_VCR_DET_CTRL 0x1E88
438#define VDEC_H_NOISE_DET_CTRL 0x1E8C
439#define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90
440#define VDEC_H_VERSION 0x1FF8
441#define VDEC_H_SOFT_RST_CTRL 0x1FFC
442
443//*****************************************************************************
444// LUMA_CTRL register fields
445#define VDEC_A_BRITE_CTRL 0x1014
446#define VDEC_A_CNTRST_CTRL 0x1015
447#define VDEC_A_PEAK_SEL 0x1016
448
449//*****************************************************************************
450// CHROMA_CTRL register fields
451#define VDEC_A_USAT_CTRL 0x1018
452#define VDEC_A_VSAT_CTRL 0x1019
453#define VDEC_A_HUE_CTRL 0x101A
454
455#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
new file mode 100644
index 000000000000..e4df8134f059
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -0,0 +1,869 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24#include "cx25821-medusa-video.h"
25#include "cx25821-biffuncs.h"
26
27/////////////////////////////////////////////////////////////////////////////////////////
28//medusa_enable_bluefield_output()
29//
30// Enable the generation of blue filed output if no video
31//
32static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
33 int enable)
34{
35 int ret_val = 1;
36 u32 value = 0;
37 u32 tmp = 0;
38 int out_ctrl = OUT_CTRL1;
39 int out_ctrl_ns = OUT_CTRL_NS;
40
41 switch (channel) {
42 default:
43 case VDEC_A:
44 break;
45 case VDEC_B:
46 out_ctrl = VDEC_B_OUT_CTRL1;
47 out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
48 break;
49 case VDEC_C:
50 out_ctrl = VDEC_C_OUT_CTRL1;
51 out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
52 break;
53 case VDEC_D:
54 out_ctrl = VDEC_D_OUT_CTRL1;
55 out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
56 break;
57 case VDEC_E:
58 out_ctrl = VDEC_E_OUT_CTRL1;
59 out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
60 return;
61 case VDEC_F:
62 out_ctrl = VDEC_F_OUT_CTRL1;
63 out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
64 return;
65 case VDEC_G:
66 out_ctrl = VDEC_G_OUT_CTRL1;
67 out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
68 return;
69 case VDEC_H:
70 out_ctrl = VDEC_H_OUT_CTRL1;
71 out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
72 return;
73 }
74
75 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
76 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN
77 if (enable)
78 value |= 0x00000080; // set BLUE_FIELD_EN
79 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
80
81 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
82 value &= 0xFFFFFF7F;
83 if (enable)
84 value |= 0x00000080; // set BLUE_FIELD_EN
85 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
86}
87
88static int medusa_initialize_ntsc(struct cx25821_dev *dev)
89{
90 int ret_val = 0;
91 int i = 0;
92 u32 value = 0;
93 u32 tmp = 0;
94
95 mutex_lock(&dev->lock);
96
97 for (i = 0; i < MAX_DECODERS; i++) {
98 // set video format NTSC-M
99 value =
100 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
101 &tmp);
102 value &= 0xFFFFFFF0;
103 value |= 0x10001; // enable the fast locking mode bit[16]
104 ret_val =
105 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
106 value);
107
108 // resolution NTSC 720x480
109 value =
110 cx25821_i2c_read(&dev->i2c_bus[0],
111 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
112 value &= 0x00C00C00;
113 value |= 0x612D0074;
114 ret_val =
115 cx25821_i2c_write(&dev->i2c_bus[0],
116 HORIZ_TIM_CTRL + (0x200 * i), value);
117
118 value =
119 cx25821_i2c_read(&dev->i2c_bus[0],
120 VERT_TIM_CTRL + (0x200 * i), &tmp);
121 value &= 0x00C00C00;
122 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID
123 ret_val =
124 cx25821_i2c_write(&dev->i2c_bus[0],
125 VERT_TIM_CTRL + (0x200 * i), value);
126
127 // chroma subcarrier step size
128 ret_val =
129 cx25821_i2c_write(&dev->i2c_bus[0],
130 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
131
132 // enable VIP optional active
133 value =
134 cx25821_i2c_read(&dev->i2c_bus[0],
135 OUT_CTRL_NS + (0x200 * i), &tmp);
136 value &= 0xFFFBFFFF;
137 value |= 0x00040000;
138 ret_val =
139 cx25821_i2c_write(&dev->i2c_bus[0],
140 OUT_CTRL_NS + (0x200 * i), value);
141
142 // enable VIP optional active (VIP_OPT_AL) for direct output.
143 value =
144 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
145 &tmp);
146 value &= 0xFFFBFFFF;
147 value |= 0x00040000;
148 ret_val =
149 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
150 value);
151
152 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
153 // when the input switching rate < 16 fields
154 //
155 value =
156 cx25821_i2c_read(&dev->i2c_bus[0],
157 MISC_TIM_CTRL + (0x200 * i), &tmp);
158 value = setBitAtPos(value, 14); // disable special play detection
159 value = clearBitAtPos(value, 15);
160 ret_val =
161 cx25821_i2c_write(&dev->i2c_bus[0],
162 MISC_TIM_CTRL + (0x200 * i), value);
163
164 // set vbi_gate_en to 0
165 value =
166 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
167 &tmp);
168 value = clearBitAtPos(value, 29);
169 ret_val =
170 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
171 value);
172
173 // Enable the generation of blue field output if no video
174 medusa_enable_bluefield_output(dev, i, 1);
175 }
176
177 for (i = 0; i < MAX_ENCODERS; i++) {
178 // NTSC hclock
179 value =
180 cx25821_i2c_read(&dev->i2c_bus[0],
181 DENC_A_REG_1 + (0x100 * i), &tmp);
182 value &= 0xF000FC00;
183 value |= 0x06B402D0;
184 ret_val =
185 cx25821_i2c_write(&dev->i2c_bus[0],
186 DENC_A_REG_1 + (0x100 * i), value);
187
188 // burst begin and burst end
189 value =
190 cx25821_i2c_read(&dev->i2c_bus[0],
191 DENC_A_REG_2 + (0x100 * i), &tmp);
192 value &= 0xFF000000;
193 value |= 0x007E9054;
194 ret_val =
195 cx25821_i2c_write(&dev->i2c_bus[0],
196 DENC_A_REG_2 + (0x100 * i), value);
197
198 value =
199 cx25821_i2c_read(&dev->i2c_bus[0],
200 DENC_A_REG_3 + (0x100 * i), &tmp);
201 value &= 0xFC00FE00;
202 value |= 0x00EC00F0;
203 ret_val =
204 cx25821_i2c_write(&dev->i2c_bus[0],
205 DENC_A_REG_3 + (0x100 * i), value);
206
207 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal
208 value =
209 cx25821_i2c_read(&dev->i2c_bus[0],
210 DENC_A_REG_4 + (0x100 * i), &tmp);
211 value &= 0x00FCFFFF;
212 value |= 0x13020000;
213 ret_val =
214 cx25821_i2c_write(&dev->i2c_bus[0],
215 DENC_A_REG_4 + (0x100 * i), value);
216
217 value =
218 cx25821_i2c_read(&dev->i2c_bus[0],
219 DENC_A_REG_5 + (0x100 * i), &tmp);
220 value &= 0xFFFF0000;
221 value |= 0x0000E575;
222 ret_val =
223 cx25821_i2c_write(&dev->i2c_bus[0],
224 DENC_A_REG_5 + (0x100 * i), value);
225
226 ret_val =
227 cx25821_i2c_write(&dev->i2c_bus[0],
228 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
229
230 // Subcarrier Increment
231 ret_val =
232 cx25821_i2c_write(&dev->i2c_bus[0],
233 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
234 }
235
236 //set picture resolutions
237 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
238 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480
239
240 // set Bypass input format to NTSC 525 lines
241 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
242 value |= 0x00080200;
243 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
244
245 mutex_unlock(&dev->lock);
246
247 return ret_val;
248}
249
250static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
251{
252 int ret_val = -1;
253 u32 value = 0, tmp = 0;
254
255 // Setup for 2D threshold
256 ret_val =
257 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
258 0x20002861);
259 ret_val =
260 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
261 0x20002861);
262 ret_val =
263 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
264 0x200A1023);
265
266 // Setup flat chroma and luma thresholds
267 value =
268 cx25821_i2c_read(&dev->i2c_bus[0],
269 COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
270 value &= 0x06230000;
271 ret_val =
272 cx25821_i2c_write(&dev->i2c_bus[0],
273 COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
274
275 // set comb 2D blend
276 ret_val =
277 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
278 0x210F0F0F);
279
280 // COMB MISC CONTROL
281 ret_val =
282 cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
283 0x41120A7F);
284
285 return ret_val;
286}
287
288static int medusa_initialize_pal(struct cx25821_dev *dev)
289{
290 int ret_val = 0;
291 int i = 0;
292 u32 value = 0;
293 u32 tmp = 0;
294
295 mutex_lock(&dev->lock);
296
297 for (i = 0; i < MAX_DECODERS; i++) {
298 // set video format PAL-BDGHI
299 value =
300 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
301 &tmp);
302 value &= 0xFFFFFFF0;
303 value |= 0x10004; // enable the fast locking mode bit[16]
304 ret_val =
305 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
306 value);
307
308 // resolution PAL 720x576
309 value =
310 cx25821_i2c_read(&dev->i2c_bus[0],
311 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
312 value &= 0x00C00C00;
313 value |= 0x632D007D;
314 ret_val =
315 cx25821_i2c_write(&dev->i2c_bus[0],
316 HORIZ_TIM_CTRL + (0x200 * i), value);
317
318 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
319 value =
320 cx25821_i2c_read(&dev->i2c_bus[0],
321 VERT_TIM_CTRL + (0x200 * i), &tmp);
322 value &= 0x00C00C00;
323 value |= 0x28240026; // vblank_cnt + 2 to get camera ID
324 ret_val =
325 cx25821_i2c_write(&dev->i2c_bus[0],
326 VERT_TIM_CTRL + (0x200 * i), value);
327
328 // chroma subcarrier step size
329 ret_val =
330 cx25821_i2c_write(&dev->i2c_bus[0],
331 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
332
333 // enable VIP optional active
334 value =
335 cx25821_i2c_read(&dev->i2c_bus[0],
336 OUT_CTRL_NS + (0x200 * i), &tmp);
337 value &= 0xFFFBFFFF;
338 value |= 0x00040000;
339 ret_val =
340 cx25821_i2c_write(&dev->i2c_bus[0],
341 OUT_CTRL_NS + (0x200 * i), value);
342
343 // enable VIP optional active (VIP_OPT_AL) for direct output.
344 value =
345 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
346 &tmp);
347 value &= 0xFFFBFFFF;
348 value |= 0x00040000;
349 ret_val =
350 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
351 value);
352
353 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
354 // when the input switching rate < 16 fields
355 value =
356 cx25821_i2c_read(&dev->i2c_bus[0],
357 MISC_TIM_CTRL + (0x200 * i), &tmp);
358 value = setBitAtPos(value, 14); // disable special play detection
359 value = clearBitAtPos(value, 15);
360 ret_val =
361 cx25821_i2c_write(&dev->i2c_bus[0],
362 MISC_TIM_CTRL + (0x200 * i), value);
363
364 // set vbi_gate_en to 0
365 value =
366 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
367 &tmp);
368 value = clearBitAtPos(value, 29);
369 ret_val =
370 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
371 value);
372
373 medusa_PALCombInit(dev, i);
374
375 // Enable the generation of blue field output if no video
376 medusa_enable_bluefield_output(dev, i, 1);
377 }
378
379 for (i = 0; i < MAX_ENCODERS; i++) {
380 // PAL hclock
381 value =
382 cx25821_i2c_read(&dev->i2c_bus[0],
383 DENC_A_REG_1 + (0x100 * i), &tmp);
384 value &= 0xF000FC00;
385 value |= 0x06C002D0;
386 ret_val =
387 cx25821_i2c_write(&dev->i2c_bus[0],
388 DENC_A_REG_1 + (0x100 * i), value);
389
390 // burst begin and burst end
391 value =
392 cx25821_i2c_read(&dev->i2c_bus[0],
393 DENC_A_REG_2 + (0x100 * i), &tmp);
394 value &= 0xFF000000;
395 value |= 0x007E9754;
396 ret_val =
397 cx25821_i2c_write(&dev->i2c_bus[0],
398 DENC_A_REG_2 + (0x100 * i), value);
399
400 // hblank and vactive
401 value =
402 cx25821_i2c_read(&dev->i2c_bus[0],
403 DENC_A_REG_3 + (0x100 * i), &tmp);
404 value &= 0xFC00FE00;
405 value |= 0x00FC0120;
406 ret_val =
407 cx25821_i2c_write(&dev->i2c_bus[0],
408 DENC_A_REG_3 + (0x100 * i), value);
409
410 // set PAL vblank, phase alternation, 0 IRE pedestal
411 value =
412 cx25821_i2c_read(&dev->i2c_bus[0],
413 DENC_A_REG_4 + (0x100 * i), &tmp);
414 value &= 0x00FCFFFF;
415 value |= 0x14010000;
416 ret_val =
417 cx25821_i2c_write(&dev->i2c_bus[0],
418 DENC_A_REG_4 + (0x100 * i), value);
419
420 value =
421 cx25821_i2c_read(&dev->i2c_bus[0],
422 DENC_A_REG_5 + (0x100 * i), &tmp);
423 value &= 0xFFFF0000;
424 value |= 0x0000F078;
425 ret_val =
426 cx25821_i2c_write(&dev->i2c_bus[0],
427 DENC_A_REG_5 + (0x100 * i), value);
428
429 ret_val =
430 cx25821_i2c_write(&dev->i2c_bus[0],
431 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
432
433 // Subcarrier Increment
434 ret_val =
435 cx25821_i2c_write(&dev->i2c_bus[0],
436 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
437 }
438
439 //set picture resolutions
440 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
441 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576
442
443 // set Bypass input format to PAL 625 lines
444 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
445 value &= 0xFFF7FDFF;
446 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
447
448 mutex_unlock(&dev->lock);
449
450 return ret_val;
451}
452
453int medusa_set_videostandard(struct cx25821_dev *dev)
454{
455 int status = STATUS_SUCCESS;
456 u32 value = 0, tmp = 0;
457
458 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) {
459 status = medusa_initialize_pal(dev);
460 } else {
461 status = medusa_initialize_ntsc(dev);
462 }
463
464 // Enable DENC_A output
465 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
466 value = setBitAtPos(value, 4);
467 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
468
469 // Enable DENC_B output
470 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
471 value = setBitAtPos(value, 4);
472 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
473
474 return status;
475}
476
477void medusa_set_resolution(struct cx25821_dev *dev, int width,
478 int decoder_select)
479{
480 int decoder = 0;
481 int decoder_count = 0;
482 int ret_val = 0;
483 u32 hscale = 0x0;
484 u32 vscale = 0x0;
485 const int MAX_WIDTH = 720;
486
487 mutex_lock(&dev->lock);
488
489 // validate the width - cannot be negative
490 if (width > MAX_WIDTH) {
491 printk
492 ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n",
493 __func__, width, MAX_WIDTH);
494 width = MAX_WIDTH;
495 }
496
497 if (decoder_select <= 7 && decoder_select >= 0) {
498 decoder = decoder_select;
499 decoder_count = decoder_select + 1;
500 } else {
501 decoder = 0;
502 decoder_count = _num_decoders;
503 }
504
505 switch (width) {
506 case 320:
507 hscale = 0x13E34B;
508 vscale = 0x0;
509 break;
510
511 case 352:
512 hscale = 0x10A273;
513 vscale = 0x0;
514 break;
515
516 case 176:
517 hscale = 0x3115B2;
518 vscale = 0x1E00;
519 break;
520
521 case 160:
522 hscale = 0x378D84;
523 vscale = 0x1E00;
524 break;
525
526 default: //720
527 hscale = 0x0;
528 vscale = 0x0;
529 break;
530 }
531
532 for (; decoder < decoder_count; decoder++) {
533 // write scaling values for each decoder
534 ret_val =
535 cx25821_i2c_write(&dev->i2c_bus[0],
536 HSCALE_CTRL + (0x200 * decoder), hscale);
537 ret_val =
538 cx25821_i2c_write(&dev->i2c_bus[0],
539 VSCALE_CTRL + (0x200 * decoder), vscale);
540 }
541
542 mutex_unlock(&dev->lock);
543}
544
545static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
546 int duration)
547{
548 int ret_val = 0;
549 u32 fld_cnt = 0;
550 u32 tmp = 0;
551 u32 disp_cnt_reg = DISP_AB_CNT;
552
553 mutex_lock(&dev->lock);
554
555 // no support
556 if (decoder < VDEC_A && decoder > VDEC_H) {
557 mutex_unlock(&dev->lock);
558 return;
559 }
560
561 switch (decoder) {
562 default:
563 break;
564 case VDEC_C:
565 case VDEC_D:
566 disp_cnt_reg = DISP_CD_CNT;
567 break;
568 case VDEC_E:
569 case VDEC_F:
570 disp_cnt_reg = DISP_EF_CNT;
571 break;
572 case VDEC_G:
573 case VDEC_H:
574 disp_cnt_reg = DISP_GH_CNT;
575 break;
576 }
577
578 _display_field_cnt[decoder] = duration;
579
580 // update hardware
581 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
582
583 if (!(decoder % 2)) // EVEN decoder
584 {
585 fld_cnt &= 0xFFFF0000;
586 fld_cnt |= duration;
587 } else {
588 fld_cnt &= 0x0000FFFF;
589 fld_cnt |= ((u32) duration) << 16;
590 }
591
592 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
593
594 mutex_unlock(&dev->lock);
595}
596
597/////////////////////////////////////////////////////////////////////////////////////////
598// Map to Medusa register setting
599static int mapM(int srcMin,
600 int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
601{
602 int numerator;
603 int denominator;
604 int quotient;
605
606 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) {
607 return -1;
608 }
609 // This is the overall expression used:
610 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
611 // but we need to account for rounding so below we use the modulus
612 // operator to find the remainder and increment if necessary.
613 numerator = (srcVal - srcMin) * (dstMax - dstMin);
614 denominator = srcMax - srcMin;
615 quotient = numerator / denominator;
616
617 if (2 * (numerator % denominator) >= denominator) {
618 quotient++;
619 }
620
621 *dstVal = quotient + dstMin;
622
623 return 0;
624}
625
626static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
627{
628 unsigned char temp;
629
630 if (numeric >= 0)
631 return numeric;
632 else {
633 temp = ~(abs(numeric) & 0xFF);
634 temp += 1;
635 return temp;
636 }
637}
638
639/////////////////////////////////////////////////////////////////////////////////////////
640int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
641{
642 int ret_val = 0;
643 int value = 0;
644 u32 val = 0, tmp = 0;
645
646 mutex_lock(&dev->lock);
647 if ((brightness > VIDEO_PROCAMP_MAX)
648 || (brightness < VIDEO_PROCAMP_MIN)) {
649 mutex_unlock(&dev->lock);
650 return -1;
651 }
652 ret_val =
653 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
654 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
655 value = convert_to_twos(value, 8);
656 val =
657 cx25821_i2c_read(&dev->i2c_bus[0],
658 VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
659 val &= 0xFFFFFF00;
660 ret_val |=
661 cx25821_i2c_write(&dev->i2c_bus[0],
662 VDEC_A_BRITE_CTRL + (0x200 * decoder),
663 val | value);
664 mutex_unlock(&dev->lock);
665 return ret_val;
666}
667
668/////////////////////////////////////////////////////////////////////////////////////////
669int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
670{
671 int ret_val = 0;
672 int value = 0;
673 u32 val = 0, tmp = 0;
674
675 mutex_lock(&dev->lock);
676
677 if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
678 mutex_unlock(&dev->lock);
679 return -1;
680 }
681
682 ret_val =
683 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
684 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
685 val =
686 cx25821_i2c_read(&dev->i2c_bus[0],
687 VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
688 val &= 0xFFFFFF00;
689 ret_val |=
690 cx25821_i2c_write(&dev->i2c_bus[0],
691 VDEC_A_CNTRST_CTRL + (0x200 * decoder),
692 val | value);
693
694 mutex_unlock(&dev->lock);
695 return ret_val;
696}
697
698/////////////////////////////////////////////////////////////////////////////////////////
699int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
700{
701 int ret_val = 0;
702 int value = 0;
703 u32 val = 0, tmp = 0;
704
705 mutex_lock(&dev->lock);
706
707 if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
708 mutex_unlock(&dev->lock);
709 return -1;
710 }
711
712 ret_val =
713 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
714 SIGNED_BYTE_MAX, &value);
715
716 value = convert_to_twos(value, 8);
717 val =
718 cx25821_i2c_read(&dev->i2c_bus[0],
719 VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
720 val &= 0xFFFFFF00;
721
722 ret_val |=
723 cx25821_i2c_write(&dev->i2c_bus[0],
724 VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
725
726 mutex_unlock(&dev->lock);
727 return ret_val;
728}
729
730/////////////////////////////////////////////////////////////////////////////////////////
731int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
732{
733 int ret_val = 0;
734 int value = 0;
735 u32 val = 0, tmp = 0;
736
737 mutex_lock(&dev->lock);
738
739 if ((saturation > VIDEO_PROCAMP_MAX)
740 || (saturation < VIDEO_PROCAMP_MIN)) {
741 mutex_unlock(&dev->lock);
742 return -1;
743 }
744
745 ret_val =
746 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
747 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
748
749 val =
750 cx25821_i2c_read(&dev->i2c_bus[0],
751 VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
752 val &= 0xFFFFFF00;
753 ret_val |=
754 cx25821_i2c_write(&dev->i2c_bus[0],
755 VDEC_A_USAT_CTRL + (0x200 * decoder),
756 val | value);
757
758 val =
759 cx25821_i2c_read(&dev->i2c_bus[0],
760 VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
761 val &= 0xFFFFFF00;
762 ret_val |=
763 cx25821_i2c_write(&dev->i2c_bus[0],
764 VDEC_A_VSAT_CTRL + (0x200 * decoder),
765 val | value);
766
767 mutex_unlock(&dev->lock);
768 return ret_val;
769}
770
771/////////////////////////////////////////////////////////////////////////////////////////
772// Program the display sequence and monitor output.
773//
774int medusa_video_init(struct cx25821_dev *dev)
775{
776 u32 value = 0, tmp = 0;
777 int ret_val = 0;
778 int i = 0;
779
780 mutex_lock(&dev->lock);
781
782 _num_decoders = dev->_max_num_decoders;
783
784 // disable Auto source selection on all video decoders
785 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
786 value &= 0xFFFFF0FF;
787 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
788
789 if (ret_val < 0) {
790 mutex_unlock(&dev->lock);
791 return -EINVAL;
792 }
793 // Turn off Master source switch enable
794 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
795 value &= 0xFFFFFFDF;
796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
797
798 if (ret_val < 0) {
799 mutex_unlock(&dev->lock);
800 return -EINVAL;
801 }
802
803 mutex_unlock(&dev->lock);
804
805 for (i = 0; i < _num_decoders; i++) {
806 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
807 }
808
809 mutex_lock(&dev->lock);
810
811 // Select monitor as DENC A input, power up the DAC
812 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
813 value &= 0xFF70FF70;
814 value |= 0x00090008; // set en_active
815 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
816
817 if (ret_val < 0) {
818 mutex_unlock(&dev->lock);
819 return -EINVAL;
820 }
821 // enable input is VIP/656
822 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
823 value |= 0x00040100; // enable VIP
824 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
825
826 if (ret_val < 0) {
827 mutex_unlock(&dev->lock);
828 return -EINVAL;
829 }
830 // select AFE clock to output mode
831 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
832 value &= 0x83FFFFFF;
833 ret_val =
834 cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
835 value | 0x10000000);
836
837 if (ret_val < 0) {
838 mutex_unlock(&dev->lock);
839 return -EINVAL;
840 }
841 // Turn on all of the data out and control output pins.
842 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
843 value &= 0xFEF0FE00;
844 if (_num_decoders == MAX_DECODERS) {
845 // Note: The octal board does not support control pins(bit16-19).
846 // These bits are ignored in the octal board.
847 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface
848 } else {
849 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface
850 }
851
852 value |= 7;
853 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
854 if (ret_val < 0) {
855 mutex_unlock(&dev->lock);
856 return -EINVAL;
857 }
858
859 mutex_unlock(&dev->lock);
860
861 ret_val = medusa_set_videostandard(dev);
862
863 if (ret_val < 0) {
864 mutex_unlock(&dev->lock);
865 return -EINVAL;
866 }
867
868 return 1;
869}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
new file mode 100644
index 000000000000..2fab4b2f251c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -0,0 +1,49 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_VIDEO_H
24#define _MEDUSA_VIDEO_H
25
26#include "cx25821-medusa-defines.h"
27
28// Color control constants
29#define VIDEO_PROCAMP_MIN 0
30#define VIDEO_PROCAMP_MAX 10000
31#define UNSIGNED_BYTE_MIN 0
32#define UNSIGNED_BYTE_MAX 0xFF
33#define SIGNED_BYTE_MIN -128
34#define SIGNED_BYTE_MAX 127
35
36// Default video color settings
37#define SHARPNESS_DEFAULT 50
38#define SATURATION_DEFAULT 5000
39#define BRIGHTNESS_DEFAULT 6200
40#define CONTRAST_DEFAULT 5000
41#define HUE_DEFAULT 5000
42
43unsigned short _num_decoders;
44unsigned short _num_cameras;
45
46unsigned int _video_standard;
47int _display_field_cnt[MAX_DECODERS];
48
49#endif
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
new file mode 100644
index 000000000000..7241e7ee3fd3
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -0,0 +1,1592 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_REGISTERS__
24#define __CX25821_REGISTERS__
25
26/* Risc Instructions */
27#define RISC_CNT_INC 0x00010000
28#define RISC_CNT_RESET 0x00030000
29#define RISC_IRQ1 0x01000000
30#define RISC_IRQ2 0x02000000
31#define RISC_EOL 0x04000000
32#define RISC_SOL 0x08000000
33#define RISC_WRITE 0x10000000
34#define RISC_SKIP 0x20000000
35#define RISC_JUMP 0x70000000
36#define RISC_SYNC 0x80000000
37#define RISC_RESYNC 0x80008000
38#define RISC_READ 0x90000000
39#define RISC_WRITERM 0xB0000000
40#define RISC_WRITECM 0xC0000000
41#define RISC_WRITECR 0xD0000000
42#define RISC_WRITEC 0x50000000
43#define RISC_READC 0xA0000000
44
45#define RISC_SYNC_ODD 0x00000000
46#define RISC_SYNC_EVEN 0x00000200
47#define RISC_SYNC_ODD_VBI 0x00000006
48#define RISC_SYNC_EVEN_VBI 0x00000207
49#define RISC_NOOP 0xF0000000
50
51//*****************************************************************************
52// ASB SRAM
53//*****************************************************************************
54#define TX_SRAM 0x000000 // Transmit SRAM
55
56//*****************************************************************************
57#define RX_RAM 0x010000 // Receive SRAM
58
59//*****************************************************************************
60// Application Layer (AL)
61//*****************************************************************************
62#define DEV_CNTRL2 0x040000 // Device control
63#define FLD_RUN_RISC 0x00000020
64
65//*****************************************************************************
66#define PCI_INT_MSK 0x040010 // PCI interrupt mask
67#define PCI_INT_STAT 0x040014 // PCI interrupt status
68#define PCI_INT_MSTAT 0x040018 // PCI interrupt masked status
69#define FLD_HAMMERHEAD_INT (1 << 27)
70#define FLD_UART_INT (1 << 26)
71#define FLD_IRQN_INT (1 << 25)
72#define FLD_TM_INT (1 << 28)
73#define FLD_I2C_3_RACK (1 << 27)
74#define FLD_I2C_3_INT (1 << 26)
75#define FLD_I2C_2_RACK (1 << 25)
76#define FLD_I2C_2_INT (1 << 24)
77#define FLD_I2C_1_RACK (1 << 23)
78#define FLD_I2C_1_INT (1 << 22)
79
80#define FLD_APB_DMA_BERR_INT (1 << 21)
81#define FLD_AL_WR_BERR_INT (1 << 20)
82#define FLD_AL_RD_BERR_INT (1 << 19)
83#define FLD_RISC_WR_BERR_INT (1 << 18)
84#define FLD_RISC_RD_BERR_INT (1 << 17)
85
86#define FLD_VID_I_INT (1 << 8)
87#define FLD_VID_H_INT (1 << 7)
88#define FLD_VID_G_INT (1 << 6)
89#define FLD_VID_F_INT (1 << 5)
90#define FLD_VID_E_INT (1 << 4)
91#define FLD_VID_D_INT (1 << 3)
92#define FLD_VID_C_INT (1 << 2)
93#define FLD_VID_B_INT (1 << 1)
94#define FLD_VID_A_INT (1 << 0)
95
96//*****************************************************************************
97#define VID_A_INT_MSK 0x040020 // Video A interrupt mask
98#define VID_A_INT_STAT 0x040024 // Video A interrupt status
99#define VID_A_INT_MSTAT 0x040028 // Video A interrupt masked status
100#define VID_A_INT_SSTAT 0x04002C // Video A interrupt set status
101
102//*****************************************************************************
103#define VID_B_INT_MSK 0x040030 // Video B interrupt mask
104#define VID_B_INT_STAT 0x040034 // Video B interrupt status
105#define VID_B_INT_MSTAT 0x040038 // Video B interrupt masked status
106#define VID_B_INT_SSTAT 0x04003C // Video B interrupt set status
107
108//*****************************************************************************
109#define VID_C_INT_MSK 0x040040 // Video C interrupt mask
110#define VID_C_INT_STAT 0x040044 // Video C interrupt status
111#define VID_C_INT_MSTAT 0x040048 // Video C interrupt masked status
112#define VID_C_INT_SSTAT 0x04004C // Video C interrupt set status
113
114//*****************************************************************************
115#define VID_D_INT_MSK 0x040050 // Video D interrupt mask
116#define VID_D_INT_STAT 0x040054 // Video D interrupt status
117#define VID_D_INT_MSTAT 0x040058 // Video D interrupt masked status
118#define VID_D_INT_SSTAT 0x04005C // Video D interrupt set status
119
120//*****************************************************************************
121#define VID_E_INT_MSK 0x040060 // Video E interrupt mask
122#define VID_E_INT_STAT 0x040064 // Video E interrupt status
123#define VID_E_INT_MSTAT 0x040068 // Video E interrupt masked status
124#define VID_E_INT_SSTAT 0x04006C // Video E interrupt set status
125
126//*****************************************************************************
127#define VID_F_INT_MSK 0x040070 // Video F interrupt mask
128#define VID_F_INT_STAT 0x040074 // Video F interrupt status
129#define VID_F_INT_MSTAT 0x040078 // Video F interrupt masked status
130#define VID_F_INT_SSTAT 0x04007C // Video F interrupt set status
131
132//*****************************************************************************
133#define VID_G_INT_MSK 0x040080 // Video G interrupt mask
134#define VID_G_INT_STAT 0x040084 // Video G interrupt status
135#define VID_G_INT_MSTAT 0x040088 // Video G interrupt masked status
136#define VID_G_INT_SSTAT 0x04008C // Video G interrupt set status
137
138//*****************************************************************************
139#define VID_H_INT_MSK 0x040090 // Video H interrupt mask
140#define VID_H_INT_STAT 0x040094 // Video H interrupt status
141#define VID_H_INT_MSTAT 0x040098 // Video H interrupt masked status
142#define VID_H_INT_SSTAT 0x04009C // Video H interrupt set status
143
144//*****************************************************************************
145#define VID_I_INT_MSK 0x0400A0 // Video I interrupt mask
146#define VID_I_INT_STAT 0x0400A4 // Video I interrupt status
147#define VID_I_INT_MSTAT 0x0400A8 // Video I interrupt masked status
148#define VID_I_INT_SSTAT 0x0400AC // Video I interrupt set status
149
150//*****************************************************************************
151#define VID_J_INT_MSK 0x0400B0 // Video J interrupt mask
152#define VID_J_INT_STAT 0x0400B4 // Video J interrupt status
153#define VID_J_INT_MSTAT 0x0400B8 // Video J interrupt masked status
154#define VID_J_INT_SSTAT 0x0400BC // Video J interrupt set status
155
156#define FLD_VID_SRC_OPC_ERR 0x00020000
157#define FLD_VID_DST_OPC_ERR 0x00010000
158#define FLD_VID_SRC_SYNC 0x00002000
159#define FLD_VID_DST_SYNC 0x00001000
160#define FLD_VID_SRC_UF 0x00000200
161#define FLD_VID_DST_OF 0x00000100
162#define FLD_VID_SRC_RISC2 0x00000020
163#define FLD_VID_DST_RISC2 0x00000010
164#define FLD_VID_SRC_RISC1 0x00000002
165#define FLD_VID_DST_RISC1 0x00000001
166#define FLD_VID_SRC_ERRORS FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF
167#define FLD_VID_DST_ERRORS FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF
168
169//*****************************************************************************
170#define AUD_A_INT_MSK 0x0400C0 // Audio Int interrupt mask
171#define AUD_A_INT_STAT 0x0400C4 // Audio Int interrupt status
172#define AUD_A_INT_MSTAT 0x0400C8 // Audio Int interrupt masked status
173#define AUD_A_INT_SSTAT 0x0400CC // Audio Int interrupt set status
174
175//*****************************************************************************
176#define AUD_B_INT_MSK 0x0400D0 // Audio Int interrupt mask
177#define AUD_B_INT_STAT 0x0400D4 // Audio Int interrupt status
178#define AUD_B_INT_MSTAT 0x0400D8 // Audio Int interrupt masked status
179#define AUD_B_INT_SSTAT 0x0400DC // Audio Int interrupt set status
180
181//*****************************************************************************
182#define AUD_C_INT_MSK 0x0400E0 // Audio Int interrupt mask
183#define AUD_C_INT_STAT 0x0400E4 // Audio Int interrupt status
184#define AUD_C_INT_MSTAT 0x0400E8 // Audio Int interrupt masked status
185#define AUD_C_INT_SSTAT 0x0400EC // Audio Int interrupt set status
186
187//*****************************************************************************
188#define AUD_D_INT_MSK 0x0400F0 // Audio Int interrupt mask
189#define AUD_D_INT_STAT 0x0400F4 // Audio Int interrupt status
190#define AUD_D_INT_MSTAT 0x0400F8 // Audio Int interrupt masked status
191#define AUD_D_INT_SSTAT 0x0400FC // Audio Int interrupt set status
192
193//*****************************************************************************
194#define AUD_E_INT_MSK 0x040100 // Audio Int interrupt mask
195#define AUD_E_INT_STAT 0x040104 // Audio Int interrupt status
196#define AUD_E_INT_MSTAT 0x040108 // Audio Int interrupt masked status
197#define AUD_E_INT_SSTAT 0x04010C // Audio Int interrupt set status
198
199#define FLD_AUD_SRC_OPC_ERR 0x00020000
200#define FLD_AUD_DST_OPC_ERR 0x00010000
201#define FLD_AUD_SRC_SYNC 0x00002000
202#define FLD_AUD_DST_SYNC 0x00001000
203#define FLD_AUD_SRC_OF 0x00000200
204#define FLD_AUD_DST_OF 0x00000100
205#define FLD_AUD_SRC_RISCI2 0x00000020
206#define FLD_AUD_DST_RISCI2 0x00000010
207#define FLD_AUD_SRC_RISCI1 0x00000002
208#define FLD_AUD_DST_RISCI1 0x00000001
209
210//*****************************************************************************
211#define MBIF_A_INT_MSK 0x040110 // MBIF Int interrupt mask
212#define MBIF_A_INT_STAT 0x040114 // MBIF Int interrupt status
213#define MBIF_A_INT_MSTAT 0x040118 // MBIF Int interrupt masked status
214#define MBIF_A_INT_SSTAT 0x04011C // MBIF Int interrupt set status
215
216//*****************************************************************************
217#define MBIF_B_INT_MSK 0x040120 // MBIF Int interrupt mask
218#define MBIF_B_INT_STAT 0x040124 // MBIF Int interrupt status
219#define MBIF_B_INT_MSTAT 0x040128 // MBIF Int interrupt masked status
220#define MBIF_B_INT_SSTAT 0x04012C // MBIF Int interrupt set status
221
222#define FLD_MBIF_DST_OPC_ERR 0x00010000
223#define FLD_MBIF_DST_SYNC 0x00001000
224#define FLD_MBIF_DST_OF 0x00000100
225#define FLD_MBIF_DST_RISCI2 0x00000010
226#define FLD_MBIF_DST_RISCI1 0x00000001
227
228//*****************************************************************************
229#define AUD_EXT_INT_MSK 0x040060 // Audio Ext interrupt mask
230#define AUD_EXT_INT_STAT 0x040064 // Audio Ext interrupt status
231#define AUD_EXT_INT_MSTAT 0x040068 // Audio Ext interrupt masked status
232#define AUD_EXT_INT_SSTAT 0x04006C // Audio Ext interrupt set status
233#define FLD_AUD_EXT_OPC_ERR 0x00010000
234#define FLD_AUD_EXT_SYNC 0x00001000
235#define FLD_AUD_EXT_OF 0x00000100
236#define FLD_AUD_EXT_RISCI2 0x00000010
237#define FLD_AUD_EXT_RISCI1 0x00000001
238
239//*****************************************************************************
240#define GPIO_LO 0x110010 // Lower of GPIO pins [31:0]
241#define GPIO_HI 0x110014 // Upper WORD of GPIO pins [47:31]
242
243#define GPIO_LO_OE 0x110018 // Lower of GPIO output enable [31:0]
244#define GPIO_HI_OE 0x11001C // Upper word of GPIO output enable [47:32]
245
246#define GPIO_LO_INT_MSK 0x11003C // GPIO interrupt mask
247#define GPIO_LO_INT_STAT 0x110044 // GPIO interrupt status
248#define GPIO_LO_INT_MSTAT 0x11004C // GPIO interrupt masked status
249#define GPIO_LO_ISM_SNS 0x110054 // GPIO interrupt sensitivity
250#define GPIO_LO_ISM_POL 0x11005C // GPIO interrupt polarity
251
252#define GPIO_HI_INT_MSK 0x110040 // GPIO interrupt mask
253#define GPIO_HI_INT_STAT 0x110048 // GPIO interrupt status
254#define GPIO_HI_INT_MSTAT 0x110050 // GPIO interrupt masked status
255#define GPIO_HI_ISM_SNS 0x110058 // GPIO interrupt sensitivity
256#define GPIO_HI_ISM_POL 0x110060 // GPIO interrupt polarity
257
258#define FLD_GPIO43_INT (1 << 11)
259#define FLD_GPIO42_INT (1 << 10)
260#define FLD_GPIO41_INT (1 << 9)
261#define FLD_GPIO40_INT (1 << 8)
262
263#define FLD_GPIO9_INT (1 << 9)
264#define FLD_GPIO8_INT (1 << 8)
265#define FLD_GPIO7_INT (1 << 7)
266#define FLD_GPIO6_INT (1 << 6)
267#define FLD_GPIO5_INT (1 << 5)
268#define FLD_GPIO4_INT (1 << 4)
269#define FLD_GPIO3_INT (1 << 3)
270#define FLD_GPIO2_INT (1 << 2)
271#define FLD_GPIO1_INT (1 << 1)
272#define FLD_GPIO0_INT (1 << 0)
273
274//*****************************************************************************
275#define TC_REQ 0x040090 // Rider PCI Express traFFic class request
276
277//*****************************************************************************
278#define TC_REQ_SET 0x040094 // Rider PCI Express traFFic class request set
279
280//*****************************************************************************
281// Rider
282//*****************************************************************************
283
284// PCI Compatible Header
285//*****************************************************************************
286#define RDR_CFG0 0x050000
287#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
288
289//*****************************************************************************
290#define RDR_CFG1 0x050004
291
292//*****************************************************************************
293#define RDR_CFG2 0x050008
294
295//*****************************************************************************
296#define RDR_CFG3 0x05000C
297
298//*****************************************************************************
299#define RDR_CFG4 0x050010
300
301//*****************************************************************************
302#define RDR_CFG5 0x050014
303
304//*****************************************************************************
305#define RDR_CFG6 0x050018
306
307//*****************************************************************************
308#define RDR_CFG7 0x05001C
309
310//*****************************************************************************
311#define RDR_CFG8 0x050020
312
313//*****************************************************************************
314#define RDR_CFG9 0x050024
315
316//*****************************************************************************
317#define RDR_CFGA 0x050028
318
319//*****************************************************************************
320#define RDR_CFGB 0x05002C
321#define RDR_SUSSYSTEM_ID_CFG 0x05002C
322
323//*****************************************************************************
324#define RDR_CFGC 0x050030
325
326//*****************************************************************************
327#define RDR_CFGD 0x050034
328
329//*****************************************************************************
330#define RDR_CFGE 0x050038
331
332//*****************************************************************************
333#define RDR_CFGF 0x05003C
334
335//*****************************************************************************
336// PCI-Express Capabilities
337//*****************************************************************************
338#define RDR_PECAP 0x050040
339
340//*****************************************************************************
341#define RDR_PEDEVCAP 0x050044
342
343//*****************************************************************************
344#define RDR_PEDEVSC 0x050048
345
346//*****************************************************************************
347#define RDR_PELINKCAP 0x05004C
348
349//*****************************************************************************
350#define RDR_PELINKSC 0x050050
351
352//*****************************************************************************
353#define RDR_PMICAP 0x050080
354
355//*****************************************************************************
356#define RDR_PMCSR 0x050084
357
358//*****************************************************************************
359#define RDR_VPDCAP 0x050090
360
361//*****************************************************************************
362#define RDR_VPDDATA 0x050094
363
364//*****************************************************************************
365#define RDR_MSICAP 0x0500A0
366
367//*****************************************************************************
368#define RDR_MSIARL 0x0500A4
369
370//*****************************************************************************
371#define RDR_MSIARU 0x0500A8
372
373//*****************************************************************************
374#define RDR_MSIDATA 0x0500AC
375
376//*****************************************************************************
377// PCI Express Extended Capabilities
378//*****************************************************************************
379#define RDR_AERXCAP 0x050100
380
381//*****************************************************************************
382#define RDR_AERUESTA 0x050104
383
384//*****************************************************************************
385#define RDR_AERUEMSK 0x050108
386
387//*****************************************************************************
388#define RDR_AERUESEV 0x05010C
389
390//*****************************************************************************
391#define RDR_AERCESTA 0x050110
392
393//*****************************************************************************
394#define RDR_AERCEMSK 0x050114
395
396//*****************************************************************************
397#define RDR_AERCC 0x050118
398
399//*****************************************************************************
400#define RDR_AERHL0 0x05011C
401
402//*****************************************************************************
403#define RDR_AERHL1 0x050120
404
405//*****************************************************************************
406#define RDR_AERHL2 0x050124
407
408//*****************************************************************************
409#define RDR_AERHL3 0x050128
410
411//*****************************************************************************
412#define RDR_VCXCAP 0x050200
413
414//*****************************************************************************
415#define RDR_VCCAP1 0x050204
416
417//*****************************************************************************
418#define RDR_VCCAP2 0x050208
419
420//*****************************************************************************
421#define RDR_VCSC 0x05020C
422
423//*****************************************************************************
424#define RDR_VCR0_CAP 0x050210
425
426//*****************************************************************************
427#define RDR_VCR0_CTRL 0x050214
428
429//*****************************************************************************
430#define RDR_VCR0_STAT 0x050218
431
432//*****************************************************************************
433#define RDR_VCR1_CAP 0x05021C
434
435//*****************************************************************************
436#define RDR_VCR1_CTRL 0x050220
437
438//*****************************************************************************
439#define RDR_VCR1_STAT 0x050224
440
441//*****************************************************************************
442#define RDR_VCR2_CAP 0x050228
443
444//*****************************************************************************
445#define RDR_VCR2_CTRL 0x05022C
446
447//*****************************************************************************
448#define RDR_VCR2_STAT 0x050230
449
450//*****************************************************************************
451#define RDR_VCR3_CAP 0x050234
452
453//*****************************************************************************
454#define RDR_VCR3_CTRL 0x050238
455
456//*****************************************************************************
457#define RDR_VCR3_STAT 0x05023C
458
459//*****************************************************************************
460#define RDR_VCARB0 0x050240
461
462//*****************************************************************************
463#define RDR_VCARB1 0x050244
464
465//*****************************************************************************
466#define RDR_VCARB2 0x050248
467
468//*****************************************************************************
469#define RDR_VCARB3 0x05024C
470
471//*****************************************************************************
472#define RDR_VCARB4 0x050250
473
474//*****************************************************************************
475#define RDR_VCARB5 0x050254
476
477//*****************************************************************************
478#define RDR_VCARB6 0x050258
479
480//*****************************************************************************
481#define RDR_VCARB7 0x05025C
482
483//*****************************************************************************
484#define RDR_RDRSTAT0 0x050300
485
486//*****************************************************************************
487#define RDR_RDRSTAT1 0x050304
488
489//*****************************************************************************
490#define RDR_RDRCTL0 0x050308
491
492//*****************************************************************************
493#define RDR_RDRCTL1 0x05030C
494
495//*****************************************************************************
496// Transaction Layer Registers
497//*****************************************************************************
498#define RDR_TLSTAT0 0x050310
499
500//*****************************************************************************
501#define RDR_TLSTAT1 0x050314
502
503//*****************************************************************************
504#define RDR_TLCTL0 0x050318
505#define FLD_CFG_UR_CPL_MODE 0x00000040
506#define FLD_CFG_CORR_ERR_QUITE 0x00000020
507#define FLD_CFG_RCB_CK_EN 0x00000010
508#define FLD_CFG_BNDRY_CK_EN 0x00000008
509#define FLD_CFG_BYTE_EN_CK_EN 0x00000004
510#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
511#define FLD_CFG_TAG_ORDER_EN 0x00000001
512
513//*****************************************************************************
514#define RDR_TLCTL1 0x05031C
515
516//*****************************************************************************
517#define RDR_REQRCAL 0x050320
518
519//*****************************************************************************
520#define RDR_REQRCAU 0x050324
521
522//*****************************************************************************
523#define RDR_REQEPA 0x050328
524
525//*****************************************************************************
526#define RDR_REQCTRL 0x05032C
527
528//*****************************************************************************
529#define RDR_REQSTAT 0x050330
530
531//*****************************************************************************
532#define RDR_TL_TEST 0x050334
533
534//*****************************************************************************
535#define RDR_VCR01_CTL 0x050348
536
537//*****************************************************************************
538#define RDR_VCR23_CTL 0x05034C
539
540//*****************************************************************************
541#define RDR_RX_VCR0_FC 0x050350
542
543//*****************************************************************************
544#define RDR_RX_VCR1_FC 0x050354
545
546//*****************************************************************************
547#define RDR_RX_VCR2_FC 0x050358
548
549//*****************************************************************************
550#define RDR_RX_VCR3_FC 0x05035C
551
552//*****************************************************************************
553// Data Link Layer Registers
554//*****************************************************************************
555#define RDR_DLLSTAT 0x050360
556
557//*****************************************************************************
558#define RDR_DLLCTRL 0x050364
559
560//*****************************************************************************
561#define RDR_REPLAYTO 0x050368
562
563//*****************************************************************************
564#define RDR_ACKLATTO 0x05036C
565
566//*****************************************************************************
567// MAC Layer Registers
568//*****************************************************************************
569#define RDR_MACSTAT0 0x050380
570
571//*****************************************************************************
572#define RDR_MACSTAT1 0x050384
573
574//*****************************************************************************
575#define RDR_MACCTRL0 0x050388
576
577//*****************************************************************************
578#define RDR_MACCTRL1 0x05038C
579
580//*****************************************************************************
581#define RDR_MACCTRL2 0x050390
582
583//*****************************************************************************
584#define RDR_MAC_LB_DATA 0x050394
585
586//*****************************************************************************
587#define RDR_L0S_EXIT_LAT 0x050398
588
589//*****************************************************************************
590// DMAC
591//*****************************************************************************
592#define DMA1_PTR1 0x100000 // DMA Current Ptr : Ch#1
593
594//*****************************************************************************
595#define DMA2_PTR1 0x100004 // DMA Current Ptr : Ch#2
596
597//*****************************************************************************
598#define DMA3_PTR1 0x100008 // DMA Current Ptr : Ch#3
599
600//*****************************************************************************
601#define DMA4_PTR1 0x10000C // DMA Current Ptr : Ch#4
602
603//*****************************************************************************
604#define DMA5_PTR1 0x100010 // DMA Current Ptr : Ch#5
605
606//*****************************************************************************
607#define DMA6_PTR1 0x100014 // DMA Current Ptr : Ch#6
608
609//*****************************************************************************
610#define DMA7_PTR1 0x100018 // DMA Current Ptr : Ch#7
611
612//*****************************************************************************
613#define DMA8_PTR1 0x10001C // DMA Current Ptr : Ch#8
614
615//*****************************************************************************
616#define DMA9_PTR1 0x100020 // DMA Current Ptr : Ch#9
617
618//*****************************************************************************
619#define DMA10_PTR1 0x100024 // DMA Current Ptr : Ch#10
620
621//*****************************************************************************
622#define DMA11_PTR1 0x100028 // DMA Current Ptr : Ch#11
623
624//*****************************************************************************
625#define DMA12_PTR1 0x10002C // DMA Current Ptr : Ch#12
626
627//*****************************************************************************
628#define DMA13_PTR1 0x100030 // DMA Current Ptr : Ch#13
629
630//*****************************************************************************
631#define DMA14_PTR1 0x100034 // DMA Current Ptr : Ch#14
632
633//*****************************************************************************
634#define DMA15_PTR1 0x100038 // DMA Current Ptr : Ch#15
635
636//*****************************************************************************
637#define DMA16_PTR1 0x10003C // DMA Current Ptr : Ch#16
638
639//*****************************************************************************
640#define DMA17_PTR1 0x100040 // DMA Current Ptr : Ch#17
641
642//*****************************************************************************
643#define DMA18_PTR1 0x100044 // DMA Current Ptr : Ch#18
644
645//*****************************************************************************
646#define DMA19_PTR1 0x100048 // DMA Current Ptr : Ch#19
647
648//*****************************************************************************
649#define DMA20_PTR1 0x10004C // DMA Current Ptr : Ch#20
650
651//*****************************************************************************
652#define DMA21_PTR1 0x100050 // DMA Current Ptr : Ch#21
653
654//*****************************************************************************
655#define DMA22_PTR1 0x100054 // DMA Current Ptr : Ch#22
656
657//*****************************************************************************
658#define DMA23_PTR1 0x100058 // DMA Current Ptr : Ch#23
659
660//*****************************************************************************
661#define DMA24_PTR1 0x10005C // DMA Current Ptr : Ch#24
662
663//*****************************************************************************
664#define DMA25_PTR1 0x100060 // DMA Current Ptr : Ch#25
665
666//*****************************************************************************
667#define DMA26_PTR1 0x100064 // DMA Current Ptr : Ch#26
668
669//*****************************************************************************
670#define DMA1_PTR2 0x100080 // DMA Tab Ptr : Ch#1
671
672//*****************************************************************************
673#define DMA2_PTR2 0x100084 // DMA Tab Ptr : Ch#2
674
675//*****************************************************************************
676#define DMA3_PTR2 0x100088 // DMA Tab Ptr : Ch#3
677
678//*****************************************************************************
679#define DMA4_PTR2 0x10008C // DMA Tab Ptr : Ch#4
680
681//*****************************************************************************
682#define DMA5_PTR2 0x100090 // DMA Tab Ptr : Ch#5
683
684//*****************************************************************************
685#define DMA6_PTR2 0x100094 // DMA Tab Ptr : Ch#6
686
687//*****************************************************************************
688#define DMA7_PTR2 0x100098 // DMA Tab Ptr : Ch#7
689
690//*****************************************************************************
691#define DMA8_PTR2 0x10009C // DMA Tab Ptr : Ch#8
692
693//*****************************************************************************
694#define DMA9_PTR2 0x1000A0 // DMA Tab Ptr : Ch#9
695
696//*****************************************************************************
697#define DMA10_PTR2 0x1000A4 // DMA Tab Ptr : Ch#10
698
699//*****************************************************************************
700#define DMA11_PTR2 0x1000A8 // DMA Tab Ptr : Ch#11
701
702//*****************************************************************************
703#define DMA12_PTR2 0x1000AC // DMA Tab Ptr : Ch#12
704
705//*****************************************************************************
706#define DMA13_PTR2 0x1000B0 // DMA Tab Ptr : Ch#13
707
708//*****************************************************************************
709#define DMA14_PTR2 0x1000B4 // DMA Tab Ptr : Ch#14
710
711//*****************************************************************************
712#define DMA15_PTR2 0x1000B8 // DMA Tab Ptr : Ch#15
713
714//*****************************************************************************
715#define DMA16_PTR2 0x1000BC // DMA Tab Ptr : Ch#16
716
717//*****************************************************************************
718#define DMA17_PTR2 0x1000C0 // DMA Tab Ptr : Ch#17
719
720//*****************************************************************************
721#define DMA18_PTR2 0x1000C4 // DMA Tab Ptr : Ch#18
722
723//*****************************************************************************
724#define DMA19_PTR2 0x1000C8 // DMA Tab Ptr : Ch#19
725
726//*****************************************************************************
727#define DMA20_PTR2 0x1000CC // DMA Tab Ptr : Ch#20
728
729//*****************************************************************************
730#define DMA21_PTR2 0x1000D0 // DMA Tab Ptr : Ch#21
731
732//*****************************************************************************
733#define DMA22_PTR2 0x1000D4 // DMA Tab Ptr : Ch#22
734
735//*****************************************************************************
736#define DMA23_PTR2 0x1000D8 // DMA Tab Ptr : Ch#23
737
738//*****************************************************************************
739#define DMA24_PTR2 0x1000DC // DMA Tab Ptr : Ch#24
740
741//*****************************************************************************
742#define DMA25_PTR2 0x1000E0 // DMA Tab Ptr : Ch#25
743
744//*****************************************************************************
745#define DMA26_PTR2 0x1000E4 // DMA Tab Ptr : Ch#26
746
747//*****************************************************************************
748#define DMA1_CNT1 0x100100 // DMA BuFFer Size : Ch#1
749
750//*****************************************************************************
751#define DMA2_CNT1 0x100104 // DMA BuFFer Size : Ch#2
752
753//*****************************************************************************
754#define DMA3_CNT1 0x100108 // DMA BuFFer Size : Ch#3
755
756//*****************************************************************************
757#define DMA4_CNT1 0x10010C // DMA BuFFer Size : Ch#4
758
759//*****************************************************************************
760#define DMA5_CNT1 0x100110 // DMA BuFFer Size : Ch#5
761
762//*****************************************************************************
763#define DMA6_CNT1 0x100114 // DMA BuFFer Size : Ch#6
764
765//*****************************************************************************
766#define DMA7_CNT1 0x100118 // DMA BuFFer Size : Ch#7
767
768//*****************************************************************************
769#define DMA8_CNT1 0x10011C // DMA BuFFer Size : Ch#8
770
771//*****************************************************************************
772#define DMA9_CNT1 0x100120 // DMA BuFFer Size : Ch#9
773
774//*****************************************************************************
775#define DMA10_CNT1 0x100124 // DMA BuFFer Size : Ch#10
776
777//*****************************************************************************
778#define DMA11_CNT1 0x100128 // DMA BuFFer Size : Ch#11
779
780//*****************************************************************************
781#define DMA12_CNT1 0x10012C // DMA BuFFer Size : Ch#12
782
783//*****************************************************************************
784#define DMA13_CNT1 0x100130 // DMA BuFFer Size : Ch#13
785
786//*****************************************************************************
787#define DMA14_CNT1 0x100134 // DMA BuFFer Size : Ch#14
788
789//*****************************************************************************
790#define DMA15_CNT1 0x100138 // DMA BuFFer Size : Ch#15
791
792//*****************************************************************************
793#define DMA16_CNT1 0x10013C // DMA BuFFer Size : Ch#16
794
795//*****************************************************************************
796#define DMA17_CNT1 0x100140 // DMA BuFFer Size : Ch#17
797
798//*****************************************************************************
799#define DMA18_CNT1 0x100144 // DMA BuFFer Size : Ch#18
800
801//*****************************************************************************
802#define DMA19_CNT1 0x100148 // DMA BuFFer Size : Ch#19
803
804//*****************************************************************************
805#define DMA20_CNT1 0x10014C // DMA BuFFer Size : Ch#20
806
807//*****************************************************************************
808#define DMA21_CNT1 0x100150 // DMA BuFFer Size : Ch#21
809
810//*****************************************************************************
811#define DMA22_CNT1 0x100154 // DMA BuFFer Size : Ch#22
812
813//*****************************************************************************
814#define DMA23_CNT1 0x100158 // DMA BuFFer Size : Ch#23
815
816//*****************************************************************************
817#define DMA24_CNT1 0x10015C // DMA BuFFer Size : Ch#24
818
819//*****************************************************************************
820#define DMA25_CNT1 0x100160 // DMA BuFFer Size : Ch#25
821
822//*****************************************************************************
823#define DMA26_CNT1 0x100164 // DMA BuFFer Size : Ch#26
824
825//*****************************************************************************
826#define DMA1_CNT2 0x100180 // DMA Table Size : Ch#1
827
828//*****************************************************************************
829#define DMA2_CNT2 0x100184 // DMA Table Size : Ch#2
830
831//*****************************************************************************
832#define DMA3_CNT2 0x100188 // DMA Table Size : Ch#3
833
834//*****************************************************************************
835#define DMA4_CNT2 0x10018C // DMA Table Size : Ch#4
836
837//*****************************************************************************
838#define DMA5_CNT2 0x100190 // DMA Table Size : Ch#5
839
840//*****************************************************************************
841#define DMA6_CNT2 0x100194 // DMA Table Size : Ch#6
842
843//*****************************************************************************
844#define DMA7_CNT2 0x100198 // DMA Table Size : Ch#7
845
846//*****************************************************************************
847#define DMA8_CNT2 0x10019C // DMA Table Size : Ch#8
848
849//*****************************************************************************
850#define DMA9_CNT2 0x1001A0 // DMA Table Size : Ch#9
851
852//*****************************************************************************
853#define DMA10_CNT2 0x1001A4 // DMA Table Size : Ch#10
854
855//*****************************************************************************
856#define DMA11_CNT2 0x1001A8 // DMA Table Size : Ch#11
857
858//*****************************************************************************
859#define DMA12_CNT2 0x1001AC // DMA Table Size : Ch#12
860
861//*****************************************************************************
862#define DMA13_CNT2 0x1001B0 // DMA Table Size : Ch#13
863
864//*****************************************************************************
865#define DMA14_CNT2 0x1001B4 // DMA Table Size : Ch#14
866
867//*****************************************************************************
868#define DMA15_CNT2 0x1001B8 // DMA Table Size : Ch#15
869
870//*****************************************************************************
871#define DMA16_CNT2 0x1001BC // DMA Table Size : Ch#16
872
873//*****************************************************************************
874#define DMA17_CNT2 0x1001C0 // DMA Table Size : Ch#17
875
876//*****************************************************************************
877#define DMA18_CNT2 0x1001C4 // DMA Table Size : Ch#18
878
879//*****************************************************************************
880#define DMA19_CNT2 0x1001C8 // DMA Table Size : Ch#19
881
882//*****************************************************************************
883#define DMA20_CNT2 0x1001CC // DMA Table Size : Ch#20
884
885//*****************************************************************************
886#define DMA21_CNT2 0x1001D0 // DMA Table Size : Ch#21
887
888//*****************************************************************************
889#define DMA22_CNT2 0x1001D4 // DMA Table Size : Ch#22
890
891//*****************************************************************************
892#define DMA23_CNT2 0x1001D8 // DMA Table Size : Ch#23
893
894//*****************************************************************************
895#define DMA24_CNT2 0x1001DC // DMA Table Size : Ch#24
896
897//*****************************************************************************
898#define DMA25_CNT2 0x1001E0 // DMA Table Size : Ch#25
899
900//*****************************************************************************
901#define DMA26_CNT2 0x1001E4 // DMA Table Size : Ch#26
902
903//*****************************************************************************
904 // ITG
905//*****************************************************************************
906#define TM_CNT_LDW 0x110000 // Timer : Counter low
907
908//*****************************************************************************
909#define TM_CNT_UW 0x110004 // Timer : Counter high word
910
911//*****************************************************************************
912#define TM_LMT_LDW 0x110008 // Timer : Limit low
913
914//*****************************************************************************
915#define TM_LMT_UW 0x11000C // Timer : Limit high word
916
917//*****************************************************************************
918#define GP0_IO 0x110010 // GPIO output enables data I/O
919#define FLD_GP_OE 0x00FF0000 // GPIO: GP_OE output enable
920#define FLD_GP_IN 0x0000FF00 // GPIO: GP_IN status
921#define FLD_GP_OUT 0x000000FF // GPIO: GP_OUT control
922
923//*****************************************************************************
924#define GPIO_ISM 0x110014 // GPIO interrupt sensitivity mode
925#define FLD_GP_ISM_SNS 0x00000070
926#define FLD_GP_ISM_POL 0x00000007
927
928//*****************************************************************************
929#define SOFT_RESET 0x11001C // Output system reset reg
930#define FLD_PECOS_SOFT_RESET 0x00000001
931
932//*****************************************************************************
933#define MC416_RWD 0x110020 // MC416 GPIO[18:3] pin
934#define MC416_OEN 0x110024 // Output enable of GPIO[18:3]
935#define MC416_CTL 0x110028
936
937//*****************************************************************************
938#define ALT_PIN_OUT_SEL 0x11002C // Alternate GPIO output select
939
940#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
941// 0 Disabled <-- default
942// 1 GPIO[0]
943// 2 GPIO[10]
944// 3 VIP_656_DATA_VAL
945// 4 VIP_656_DATA[0]
946// 5 VIP_656_CLK
947// 6 VIP_656_DATA_EXT[1]
948// 7 VIP_656_DATA_EXT[0]
949// 8 ATT_IF
950
951#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
952// 0 AUX_PLL_CLK<-- default
953// 1 GPIO[2]
954// 2 GPIO[10]
955// 3 VIP_656_DATA_VAL
956// 4 VIP_656_DATA[0]
957// 5 VIP_656_CLK
958// 6 VIP_656_DATA_EXT[1]
959// 7 VIP_656_DATA_EXT[0]
960
961#define FLD_IR_TX_ALT_SEL 0x00F00000
962// 0 IR_TX <-- default
963// 1 GPIO[1]
964// 2 GPIO[10]
965// 3 VIP_656_DATA_VAL
966// 4 VIP_656_DATA[0]
967// 5 VIP_656_CLK
968// 6 VIP_656_DATA_EXT[1]
969// 7 VIP_656_DATA_EXT[0]
970
971#define FLD_IR_RX_ALT_SEL 0x000F0000
972// 0 IR_RX <-- default
973// 1 GPIO[0]
974// 2 GPIO[10]
975// 3 VIP_656_DATA_VAL
976// 4 VIP_656_DATA[0]
977// 5 VIP_656_CLK
978// 6 VIP_656_DATA_EXT[1]
979// 7 VIP_656_DATA_EXT[0]
980
981#define FLD_GPIO10_ALT_SEL 0x0000F000
982// 0 GPIO[10] <-- default
983// 1 GPIO[0]
984// 2 GPIO[10]
985// 3 VIP_656_DATA_VAL
986// 4 VIP_656_DATA[0]
987// 5 VIP_656_CLK
988// 6 VIP_656_DATA_EXT[1]
989// 7 VIP_656_DATA_EXT[0]
990
991#define FLD_GPIO2_ALT_SEL 0x00000F00
992// 0 GPIO[2] <-- default
993// 1 GPIO[1]
994// 2 GPIO[10]
995// 3 VIP_656_DATA_VAL
996// 4 VIP_656_DATA[0]
997// 5 VIP_656_CLK
998// 6 VIP_656_DATA_EXT[1]
999// 7 VIP_656_DATA_EXT[0]
1000
1001#define FLD_GPIO1_ALT_SEL 0x000000F0
1002// 0 GPIO[1] <-- default
1003// 1 GPIO[0]
1004// 2 GPIO[10]
1005// 3 VIP_656_DATA_VAL
1006// 4 VIP_656_DATA[0]
1007// 5 VIP_656_CLK
1008// 6 VIP_656_DATA_EXT[1]
1009// 7 VIP_656_DATA_EXT[0]
1010
1011#define FLD_GPIO0_ALT_SEL 0x0000000F
1012// 0 GPIO[0] <-- default
1013// 1 GPIO[1]
1014// 2 GPIO[10]
1015// 3 VIP_656_DATA_VAL
1016// 4 VIP_656_DATA[0]
1017// 5 VIP_656_CLK
1018// 6 VIP_656_DATA_EXT[1]
1019// 7 VIP_656_DATA_EXT[0]
1020
1021#define ALT_PIN_IN_SEL 0x110030 // Alternate GPIO input select
1022
1023#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
1024// 0 GPIO[10] <-- default
1025// 1 IR_RX
1026// 2 IR_TX
1027// 3 AUX_PLL_CLK
1028// 4 IF_ATT_SEL
1029// 5 GPIO[0]
1030// 6 GPIO[1]
1031// 7 GPIO[2]
1032
1033#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
1034// 0 GPIO[2] <-- default
1035// 1 IR_RX
1036// 2 IR_TX
1037// 3 AUX_PLL_CLK
1038// 4 IF_ATT_SEL
1039
1040#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
1041// 0 GPIO[1] <-- default
1042// 1 IR_RX
1043// 2 IR_TX
1044// 3 AUX_PLL_CLK
1045// 4 IF_ATT_SEL
1046
1047#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
1048// 0 GPIO[0] <-- default
1049// 1 IR_RX
1050// 2 IR_TX
1051// 3 AUX_PLL_CLK
1052// 4 IF_ATT_SEL
1053
1054//*****************************************************************************
1055#define TEST_BUS_CTL1 0x110040 // Test bus control register #1
1056
1057//*****************************************************************************
1058#define TEST_BUS_CTL2 0x110044 // Test bus control register #2
1059
1060//*****************************************************************************
1061#define CLK_DELAY 0x110048 // Clock delay
1062#define FLD_MOE_CLK_DIS 0x80000000 // Disable MoE clock
1063
1064//*****************************************************************************
1065#define PAD_CTRL 0x110068 // Pad drive strength control
1066
1067//*****************************************************************************
1068#define MBIST_CTRL 0x110050 // SRAM memory built-in self test control
1069
1070//*****************************************************************************
1071#define MBIST_STAT 0x110054 // SRAM memory built-in self test status
1072
1073//*****************************************************************************
1074// PLL registers
1075//*****************************************************************************
1076#define PLL_A_INT_FRAC 0x110088
1077#define PLL_A_POST_STAT_BIST 0x11008C
1078#define PLL_B_INT_FRAC 0x110090
1079#define PLL_B_POST_STAT_BIST 0x110094
1080#define PLL_C_INT_FRAC 0x110098
1081#define PLL_C_POST_STAT_BIST 0x11009C
1082#define PLL_D_INT_FRAC 0x1100A0
1083#define PLL_D_POST_STAT_BIST 0x1100A4
1084
1085#define CLK_RST 0x11002C
1086#define FLD_VID_I_CLK_NOE 0x00001000
1087#define FLD_VID_J_CLK_NOE 0x00002000
1088#define FLD_USE_ALT_PLL_REF 0x00004000
1089
1090#define VID_CH_MODE_SEL 0x110078
1091#define VID_CH_CLK_SEL 0x11007C
1092
1093//*****************************************************************************
1094#define VBI_A_DMA 0x130008 // VBI A DMA data port
1095
1096//*****************************************************************************
1097#define VID_A_VIP_CTL 0x130080 // Video A VIP format control
1098#define FLD_VIP_MODE 0x00000001
1099
1100//*****************************************************************************
1101#define VID_A_PIXEL_FRMT 0x130084 // Video A pixel format
1102#define FLD_VID_A_GAMMA_DIS 0x00000008
1103#define FLD_VID_A_FORMAT 0x00000007
1104#define FLD_VID_A_GAMMA_FACTOR 0x00000010
1105
1106//*****************************************************************************
1107#define VID_A_VBI_CTL 0x130088 // Video A VBI miscellaneous control
1108#define FLD_VID_A_VIP_EXT 0x00000003
1109
1110//*****************************************************************************
1111#define VID_B_DMA 0x130100 // Video B DMA data port
1112
1113//*****************************************************************************
1114#define VBI_B_DMA 0x130108 // VBI B DMA data port
1115
1116//*****************************************************************************
1117#define VID_B_SRC_SEL 0x130144 // Video B source select
1118#define FLD_VID_B_SRC_SEL 0x00000000
1119
1120//*****************************************************************************
1121#define VID_B_LNGTH 0x130150 // Video B line length
1122#define FLD_VID_B_LN_LNGTH 0x00000FFF
1123
1124//*****************************************************************************
1125#define VID_B_VIP_CTL 0x130180 // Video B VIP format control
1126
1127//*****************************************************************************
1128#define VID_B_PIXEL_FRMT 0x130184 // Video B pixel format
1129#define FLD_VID_B_GAMMA_DIS 0x00000008
1130#define FLD_VID_B_FORMAT 0x00000007
1131#define FLD_VID_B_GAMMA_FACTOR 0x00000010
1132
1133//*****************************************************************************
1134#define VID_C_DMA 0x130200 // Video C DMA data port
1135
1136//*****************************************************************************
1137#define VID_C_LNGTH 0x130250 // Video C line length
1138#define FLD_VID_C_LN_LNGTH 0x00000FFF
1139
1140//*****************************************************************************
1141// Video Destination Channels
1142//*****************************************************************************
1143
1144#define VID_DST_A_GPCNT 0x130020 // Video A general purpose counter
1145#define VID_DST_B_GPCNT 0x130120 // Video B general purpose counter
1146#define VID_DST_C_GPCNT 0x130220 // Video C general purpose counter
1147#define VID_DST_D_GPCNT 0x130320 // Video D general purpose counter
1148#define VID_DST_E_GPCNT 0x130420 // Video E general purpose counter
1149#define VID_DST_F_GPCNT 0x130520 // Video F general purpose counter
1150#define VID_DST_G_GPCNT 0x130620 // Video G general purpose counter
1151#define VID_DST_H_GPCNT 0x130720 // Video H general purpose counter
1152
1153//*****************************************************************************
1154
1155#define VID_DST_A_GPCNT_CTL 0x130030 // Video A general purpose control
1156#define VID_DST_B_GPCNT_CTL 0x130130 // Video B general purpose control
1157#define VID_DST_C_GPCNT_CTL 0x130230 // Video C general purpose control
1158#define VID_DST_D_GPCNT_CTL 0x130330 // Video D general purpose control
1159#define VID_DST_E_GPCNT_CTL 0x130430 // Video E general purpose control
1160#define VID_DST_F_GPCNT_CTL 0x130530 // Video F general purpose control
1161#define VID_DST_G_GPCNT_CTL 0x130630 // Video G general purpose control
1162#define VID_DST_H_GPCNT_CTL 0x130730 // Video H general purpose control
1163
1164//*****************************************************************************
1165
1166#define VID_DST_A_DMA_CTL 0x130040 // Video A DMA control
1167#define VID_DST_B_DMA_CTL 0x130140 // Video B DMA control
1168#define VID_DST_C_DMA_CTL 0x130240 // Video C DMA control
1169#define VID_DST_D_DMA_CTL 0x130340 // Video D DMA control
1170#define VID_DST_E_DMA_CTL 0x130440 // Video E DMA control
1171#define VID_DST_F_DMA_CTL 0x130540 // Video F DMA control
1172#define VID_DST_G_DMA_CTL 0x130640 // Video G DMA control
1173#define VID_DST_H_DMA_CTL 0x130740 // Video H DMA control
1174
1175#define FLD_VID_RISC_EN 0x00000010
1176#define FLD_VID_FIFO_EN 0x00000001
1177
1178//*****************************************************************************
1179
1180#define VID_DST_A_VIP_CTL 0x130080 // Video A VIP control
1181#define VID_DST_B_VIP_CTL 0x130180 // Video B VIP control
1182#define VID_DST_C_VIP_CTL 0x130280 // Video C VIP control
1183#define VID_DST_D_VIP_CTL 0x130380 // Video D VIP control
1184#define VID_DST_E_VIP_CTL 0x130480 // Video E VIP control
1185#define VID_DST_F_VIP_CTL 0x130580 // Video F VIP control
1186#define VID_DST_G_VIP_CTL 0x130680 // Video G VIP control
1187#define VID_DST_H_VIP_CTL 0x130780 // Video H VIP control
1188
1189//*****************************************************************************
1190
1191#define VID_DST_A_PIX_FRMT 0x130084 // Video A Pixel format
1192#define VID_DST_B_PIX_FRMT 0x130184 // Video B Pixel format
1193#define VID_DST_C_PIX_FRMT 0x130284 // Video C Pixel format
1194#define VID_DST_D_PIX_FRMT 0x130384 // Video D Pixel format
1195#define VID_DST_E_PIX_FRMT 0x130484 // Video E Pixel format
1196#define VID_DST_F_PIX_FRMT 0x130584 // Video F Pixel format
1197#define VID_DST_G_PIX_FRMT 0x130684 // Video G Pixel format
1198#define VID_DST_H_PIX_FRMT 0x130784 // Video H Pixel format
1199
1200//*****************************************************************************
1201// Video Source Channels
1202//*****************************************************************************
1203
1204#define VID_SRC_A_GPCNT_CTL 0x130804 // Video A general purpose control
1205#define VID_SRC_B_GPCNT_CTL 0x130904 // Video B general purpose control
1206#define VID_SRC_C_GPCNT_CTL 0x130A04 // Video C general purpose control
1207#define VID_SRC_D_GPCNT_CTL 0x130B04 // Video D general purpose control
1208#define VID_SRC_E_GPCNT_CTL 0x130C04 // Video E general purpose control
1209#define VID_SRC_F_GPCNT_CTL 0x130D04 // Video F general purpose control
1210#define VID_SRC_I_GPCNT_CTL 0x130E04 // Video I general purpose control
1211#define VID_SRC_J_GPCNT_CTL 0x130F04 // Video J general purpose control
1212
1213//*****************************************************************************
1214
1215#define VID_SRC_A_GPCNT 0x130808 // Video A general purpose counter
1216#define VID_SRC_B_GPCNT 0x130908 // Video B general purpose counter
1217#define VID_SRC_C_GPCNT 0x130A08 // Video C general purpose counter
1218#define VID_SRC_D_GPCNT 0x130B08 // Video D general purpose counter
1219#define VID_SRC_E_GPCNT 0x130C08 // Video E general purpose counter
1220#define VID_SRC_F_GPCNT 0x130D08 // Video F general purpose counter
1221#define VID_SRC_I_GPCNT 0x130E08 // Video I general purpose counter
1222#define VID_SRC_J_GPCNT 0x130F08 // Video J general purpose counter
1223
1224//*****************************************************************************
1225
1226#define VID_SRC_A_DMA_CTL 0x13080C // Video A DMA control
1227#define VID_SRC_B_DMA_CTL 0x13090C // Video B DMA control
1228#define VID_SRC_C_DMA_CTL 0x130A0C // Video C DMA control
1229#define VID_SRC_D_DMA_CTL 0x130B0C // Video D DMA control
1230#define VID_SRC_E_DMA_CTL 0x130C0C // Video E DMA control
1231#define VID_SRC_F_DMA_CTL 0x130D0C // Video F DMA control
1232#define VID_SRC_I_DMA_CTL 0x130E0C // Video I DMA control
1233#define VID_SRC_J_DMA_CTL 0x130F0C // Video J DMA control
1234
1235#define FLD_APB_RISC_EN 0x00000010
1236#define FLD_APB_FIFO_EN 0x00000001
1237
1238//*****************************************************************************
1239
1240#define VID_SRC_A_FMT_CTL 0x130810 // Video A format control
1241#define VID_SRC_B_FMT_CTL 0x130910 // Video B format control
1242#define VID_SRC_C_FMT_CTL 0x130A10 // Video C format control
1243#define VID_SRC_D_FMT_CTL 0x130B10 // Video D format control
1244#define VID_SRC_E_FMT_CTL 0x130C10 // Video E format control
1245#define VID_SRC_F_FMT_CTL 0x130D10 // Video F format control
1246#define VID_SRC_I_FMT_CTL 0x130E10 // Video I format control
1247#define VID_SRC_J_FMT_CTL 0x130F10 // Video J format control
1248
1249//*****************************************************************************
1250
1251#define VID_SRC_A_ACTIVE_CTL1 0x130814 // Video A active control 1
1252#define VID_SRC_B_ACTIVE_CTL1 0x130914 // Video B active control 1
1253#define VID_SRC_C_ACTIVE_CTL1 0x130A14 // Video C active control 1
1254#define VID_SRC_D_ACTIVE_CTL1 0x130B14 // Video D active control 1
1255#define VID_SRC_E_ACTIVE_CTL1 0x130C14 // Video E active control 1
1256#define VID_SRC_F_ACTIVE_CTL1 0x130D14 // Video F active control 1
1257#define VID_SRC_I_ACTIVE_CTL1 0x130E14 // Video I active control 1
1258#define VID_SRC_J_ACTIVE_CTL1 0x130F14 // Video J active control 1
1259
1260//*****************************************************************************
1261
1262#define VID_SRC_A_ACTIVE_CTL2 0x130818 // Video A active control 2
1263#define VID_SRC_B_ACTIVE_CTL2 0x130918 // Video B active control 2
1264#define VID_SRC_C_ACTIVE_CTL2 0x130A18 // Video C active control 2
1265#define VID_SRC_D_ACTIVE_CTL2 0x130B18 // Video D active control 2
1266#define VID_SRC_E_ACTIVE_CTL2 0x130C18 // Video E active control 2
1267#define VID_SRC_F_ACTIVE_CTL2 0x130D18 // Video F active control 2
1268#define VID_SRC_I_ACTIVE_CTL2 0x130E18 // Video I active control 2
1269#define VID_SRC_J_ACTIVE_CTL2 0x130F18 // Video J active control 2
1270
1271//*****************************************************************************
1272
1273#define VID_SRC_A_CDT_SZ 0x13081C // Video A CDT size
1274#define VID_SRC_B_CDT_SZ 0x13091C // Video B CDT size
1275#define VID_SRC_C_CDT_SZ 0x130A1C // Video C CDT size
1276#define VID_SRC_D_CDT_SZ 0x130B1C // Video D CDT size
1277#define VID_SRC_E_CDT_SZ 0x130C1C // Video E CDT size
1278#define VID_SRC_F_CDT_SZ 0x130D1C // Video F CDT size
1279#define VID_SRC_I_CDT_SZ 0x130E1C // Video I CDT size
1280#define VID_SRC_J_CDT_SZ 0x130F1C // Video J CDT size
1281
1282//*****************************************************************************
1283// Audio I/F
1284//*****************************************************************************
1285#define AUD_DST_A_DMA 0x140000 // Audio Int A DMA data port
1286#define AUD_SRC_A_DMA 0x140008 // Audio Int A DMA data port
1287
1288#define AUD_A_GPCNT 0x140010 // Audio Int A gp counter
1289#define FLD_AUD_A_GP_CNT 0x0000FFFF
1290
1291#define AUD_A_GPCNT_CTL 0x140014 // Audio Int A gp control
1292
1293#define AUD_A_LNGTH 0x140018 // Audio Int A line length
1294
1295#define AUD_A_CFG 0x14001C // Audio Int A configuration
1296
1297//*****************************************************************************
1298#define AUD_DST_B_DMA 0x140100 // Audio Int B DMA data port
1299#define AUD_SRC_B_DMA 0x140108 // Audio Int B DMA data port
1300
1301#define AUD_B_GPCNT 0x140110 // Audio Int B gp counter
1302#define FLD_AUD_B_GP_CNT 0x0000FFFF
1303
1304#define AUD_B_GPCNT_CTL 0x140114 // Audio Int B gp control
1305
1306#define AUD_B_LNGTH 0x140118 // Audio Int B line length
1307
1308#define AUD_B_CFG 0x14011C // Audio Int B configuration
1309
1310//*****************************************************************************
1311#define AUD_DST_C_DMA 0x140200 // Audio Int C DMA data port
1312#define AUD_SRC_C_DMA 0x140208 // Audio Int C DMA data port
1313
1314#define AUD_C_GPCNT 0x140210 // Audio Int C gp counter
1315#define FLD_AUD_C_GP_CNT 0x0000FFFF
1316
1317#define AUD_C_GPCNT_CTL 0x140214 // Audio Int C gp control
1318
1319#define AUD_C_LNGTH 0x140218 // Audio Int C line length
1320
1321#define AUD_C_CFG 0x14021C // Audio Int C configuration
1322
1323//*****************************************************************************
1324#define AUD_DST_D_DMA 0x140300 // Audio Int D DMA data port
1325#define AUD_SRC_D_DMA 0x140308 // Audio Int D DMA data port
1326
1327#define AUD_D_GPCNT 0x140310 // Audio Int D gp counter
1328#define FLD_AUD_D_GP_CNT 0x0000FFFF
1329
1330#define AUD_D_GPCNT_CTL 0x140314 // Audio Int D gp control
1331
1332#define AUD_D_LNGTH 0x140318 // Audio Int D line length
1333
1334#define AUD_D_CFG 0x14031C // Audio Int D configuration
1335
1336//*****************************************************************************
1337#define AUD_SRC_E_DMA 0x140400 // Audio Int E DMA data port
1338
1339#define AUD_E_GPCNT 0x140410 // Audio Int E gp counter
1340#define FLD_AUD_E_GP_CNT 0x0000FFFF
1341
1342#define AUD_E_GPCNT_CTL 0x140414 // Audio Int E gp control
1343
1344#define AUD_E_CFG 0x14041C // Audio Int E configuration
1345
1346//*****************************************************************************
1347
1348#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
1349
1350#define FLD_AUD_DST_PK_MODE 0x00004000
1351
1352#define FLD_AUD_CLK_ENABLE 0x00000200
1353
1354#define FLD_AUD_MASTER_MODE 0x00000002
1355
1356#define FLD_AUD_SONY_MODE 0x00000001
1357
1358#define FLD_AUD_CLK_SELECT_PLL_D 0x00001800
1359
1360#define FLD_AUD_DST_ENABLE 0x00020000
1361
1362#define FLD_AUD_SRC_ENABLE 0x00010000
1363
1364//*****************************************************************************
1365#define AUD_INT_DMA_CTL 0x140500 // Audio Int DMA control
1366
1367#define FLD_AUD_SRC_E_RISC_EN 0x00008000
1368#define FLD_AUD_SRC_C_RISC_EN 0x00004000
1369#define FLD_AUD_SRC_B_RISC_EN 0x00002000
1370#define FLD_AUD_SRC_A_RISC_EN 0x00001000
1371
1372#define FLD_AUD_DST_D_RISC_EN 0x00000800
1373#define FLD_AUD_DST_C_RISC_EN 0x00000400
1374#define FLD_AUD_DST_B_RISC_EN 0x00000200
1375#define FLD_AUD_DST_A_RISC_EN 0x00000100
1376
1377#define FLD_AUD_SRC_E_FIFO_EN 0x00000080
1378#define FLD_AUD_SRC_C_FIFO_EN 0x00000040
1379#define FLD_AUD_SRC_B_FIFO_EN 0x00000020
1380#define FLD_AUD_SRC_A_FIFO_EN 0x00000010
1381
1382#define FLD_AUD_DST_D_FIFO_EN 0x00000008
1383#define FLD_AUD_DST_C_FIFO_EN 0x00000004
1384#define FLD_AUD_DST_B_FIFO_EN 0x00000002
1385#define FLD_AUD_DST_A_FIFO_EN 0x00000001
1386
1387//*****************************************************************************
1388//
1389// Mobilygen Interface Registers
1390//
1391//*****************************************************************************
1392// Mobilygen Interface A
1393//*****************************************************************************
1394#define MB_IF_A_DMA 0x150000 // MBIF A DMA data port
1395#define MB_IF_A_GPCN 0x150008 // MBIF A GP counter
1396#define MB_IF_A_GPCN_CTRL 0x15000C
1397#define MB_IF_A_DMA_CTRL 0x150010
1398#define MB_IF_A_LENGTH 0x150014
1399#define MB_IF_A_HDMA_XFER_SZ 0x150018
1400#define MB_IF_A_HCMD 0x15001C
1401#define MB_IF_A_HCONFIG 0x150020
1402#define MB_IF_A_DATA_STRUCT_0 0x150024
1403#define MB_IF_A_DATA_STRUCT_1 0x150028
1404#define MB_IF_A_DATA_STRUCT_2 0x15002C
1405#define MB_IF_A_DATA_STRUCT_3 0x150030
1406#define MB_IF_A_DATA_STRUCT_4 0x150034
1407#define MB_IF_A_DATA_STRUCT_5 0x150038
1408#define MB_IF_A_DATA_STRUCT_6 0x15003C
1409#define MB_IF_A_DATA_STRUCT_7 0x150040
1410#define MB_IF_A_DATA_STRUCT_8 0x150044
1411#define MB_IF_A_DATA_STRUCT_9 0x150048
1412#define MB_IF_A_DATA_STRUCT_A 0x15004C
1413#define MB_IF_A_DATA_STRUCT_B 0x150050
1414#define MB_IF_A_DATA_STRUCT_C 0x150054
1415#define MB_IF_A_DATA_STRUCT_D 0x150058
1416#define MB_IF_A_DATA_STRUCT_E 0x15005C
1417#define MB_IF_A_DATA_STRUCT_F 0x150060
1418//*****************************************************************************
1419// Mobilygen Interface B
1420//*****************************************************************************
1421#define MB_IF_B_DMA 0x160000 // MBIF A DMA data port
1422#define MB_IF_B_GPCN 0x160008 // MBIF A GP counter
1423#define MB_IF_B_GPCN_CTRL 0x16000C
1424#define MB_IF_B_DMA_CTRL 0x160010
1425#define MB_IF_B_LENGTH 0x160014
1426#define MB_IF_B_HDMA_XFER_SZ 0x160018
1427#define MB_IF_B_HCMD 0x16001C
1428#define MB_IF_B_HCONFIG 0x160020
1429#define MB_IF_B_DATA_STRUCT_0 0x160024
1430#define MB_IF_B_DATA_STRUCT_1 0x160028
1431#define MB_IF_B_DATA_STRUCT_2 0x16002C
1432#define MB_IF_B_DATA_STRUCT_3 0x160030
1433#define MB_IF_B_DATA_STRUCT_4 0x160034
1434#define MB_IF_B_DATA_STRUCT_5 0x160038
1435#define MB_IF_B_DATA_STRUCT_6 0x16003C
1436#define MB_IF_B_DATA_STRUCT_7 0x160040
1437#define MB_IF_B_DATA_STRUCT_8 0x160044
1438#define MB_IF_B_DATA_STRUCT_9 0x160048
1439#define MB_IF_B_DATA_STRUCT_A 0x16004C
1440#define MB_IF_B_DATA_STRUCT_B 0x160050
1441#define MB_IF_B_DATA_STRUCT_C 0x160054
1442#define MB_IF_B_DATA_STRUCT_D 0x160058
1443#define MB_IF_B_DATA_STRUCT_E 0x16005C
1444#define MB_IF_B_DATA_STRUCT_F 0x160060
1445
1446// MB_DMA_CTRL
1447#define FLD_MB_IF_RISC_EN 0x00000010
1448#define FLD_MB_IF_FIFO_EN 0x00000001
1449
1450// MB_LENGTH
1451#define FLD_MB_IF_LN_LNGTH 0x00000FFF
1452
1453// MB_HCMD register
1454#define FLD_MB_HCMD_H_GO 0x80000000
1455#define FLD_MB_HCMD_H_BUSY 0x40000000
1456#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
1457#define FLD_MB_HCMD_H_DMA_BUSY 0x08000000
1458#define FLD_MB_HCMD_H_DMA_TYPE 0x04000000
1459#define FLD_MB_HCMD_H_DMA_XACT 0x02000000
1460#define FLD_MB_HCMD_H_RW_N 0x01000000
1461#define FLD_MB_HCMD_H_ADDR 0x00FF0000
1462#define FLD_MB_HCMD_H_DATA 0x0000FFFF
1463
1464//*****************************************************************************
1465// I2C #1
1466//*****************************************************************************
1467#define I2C1_ADDR 0x180000 // I2C #1 address
1468#define FLD_I2C_DADDR 0xfe000000 // RW [31:25] I2C Device Address
1469 // RO [24] reserved
1470//*****************************************************************************
1471#define FLD_I2C_SADDR 0x00FFFFFF // RW [23:0] I2C Sub-address
1472
1473//*****************************************************************************
1474#define I2C1_WDATA 0x180004 // I2C #1 write data
1475#define FLD_I2C_WDATA 0xFFFFFFFF // RW [31:0]
1476
1477//*****************************************************************************
1478#define I2C1_CTRL 0x180008 // I2C #1 control
1479#define FLD_I2C_PERIOD 0xFF000000 // RW [31:24]
1480#define FLD_I2C_SCL_IN 0x00200000 // RW [21]
1481#define FLD_I2C_SDA_IN 0x00100000 // RW [20]
1482 // RO [19:18] reserved
1483#define FLD_I2C_SCL_OUT 0x00020000 // RW [17]
1484#define FLD_I2C_SDA_OUT 0x00010000 // RW [16]
1485 // RO [15] reserved
1486#define FLD_I2C_DATA_LEN 0x00007000 // RW [14:12]
1487#define FLD_I2C_SADDR_INC 0x00000800 // RW [11]
1488 // RO [10:9] reserved
1489#define FLD_I2C_SADDR_LEN 0x00000300 // RW [9:8]
1490 // RO [7:6] reserved
1491#define FLD_I2C_SOFT 0x00000020 // RW [5]
1492#define FLD_I2C_NOSTOP 0x00000010 // RW [4]
1493#define FLD_I2C_EXTEND 0x00000008 // RW [3]
1494#define FLD_I2C_SYNC 0x00000004 // RW [2]
1495#define FLD_I2C_READ_SA 0x00000002 // RW [1]
1496#define FLD_I2C_READ_WRN 0x00000001 // RW [0]
1497
1498//*****************************************************************************
1499#define I2C1_RDATA 0x18000C // I2C #1 read data
1500#define FLD_I2C_RDATA 0xFFFFFFFF // RO [31:0]
1501
1502//*****************************************************************************
1503#define I2C1_STAT 0x180010 // I2C #1 status
1504#define FLD_I2C_XFER_IN_PROG 0x00000002 // RO [1]
1505#define FLD_I2C_RACK 0x00000001 // RO [0]
1506
1507//*****************************************************************************
1508// I2C #2
1509//*****************************************************************************
1510#define I2C2_ADDR 0x190000 // I2C #2 address
1511
1512//*****************************************************************************
1513#define I2C2_WDATA 0x190004 // I2C #2 write data
1514
1515//*****************************************************************************
1516#define I2C2_CTRL 0x190008 // I2C #2 control
1517
1518//*****************************************************************************
1519#define I2C2_RDATA 0x19000C // I2C #2 read data
1520
1521//*****************************************************************************
1522#define I2C2_STAT 0x190010 // I2C #2 status
1523
1524//*****************************************************************************
1525// I2C #3
1526//*****************************************************************************
1527#define I2C3_ADDR 0x1A0000 // I2C #3 address
1528
1529//*****************************************************************************
1530#define I2C3_WDATA 0x1A0004 // I2C #3 write data
1531
1532//*****************************************************************************
1533#define I2C3_CTRL 0x1A0008 // I2C #3 control
1534
1535//*****************************************************************************
1536#define I2C3_RDATA 0x1A000C // I2C #3 read data
1537
1538//*****************************************************************************
1539#define I2C3_STAT 0x1A0010 // I2C #3 status
1540
1541//*****************************************************************************
1542// UART
1543//*****************************************************************************
1544#define UART_CTL 0x1B0000 // UART Control Register
1545#define FLD_LOOP_BACK_EN (1 << 7) // RW field - default 0
1546#define FLD_RX_TRG_SZ (3 << 2) // RW field - default 0
1547#define FLD_RX_EN (1 << 1) // RW field - default 0
1548#define FLD_TX_EN (1 << 0) // RW field - default 0
1549
1550//*****************************************************************************
1551#define UART_BRD 0x1B0004 // UART Baud Rate Divisor
1552#define FLD_BRD 0x0000FFFF // RW field - default 0x197
1553
1554//*****************************************************************************
1555#define UART_DBUF 0x1B0008 // UART Tx/Rx Data BuFFer
1556#define FLD_DB 0xFFFFFFFF // RW field - default 0
1557
1558//*****************************************************************************
1559#define UART_ISR 0x1B000C // UART Interrupt Status
1560#define FLD_RXD_TIMEOUT_EN (1 << 7) // RW field - default 0
1561#define FLD_FRM_ERR_EN (1 << 6) // RW field - default 0
1562#define FLD_RXD_RDY_EN (1 << 5) // RW field - default 0
1563#define FLD_TXD_EMPTY_EN (1 << 4) // RW field - default 0
1564#define FLD_RXD_OVERFLOW (1 << 3) // RW field - default 0
1565#define FLD_FRM_ERR (1 << 2) // RW field - default 0
1566#define FLD_RXD_RDY (1 << 1) // RW field - default 0
1567#define FLD_TXD_EMPTY (1 << 0) // RW field - default 0
1568
1569//*****************************************************************************
1570#define UART_CNT 0x1B0010 // UART Tx/Rx FIFO Byte Count
1571#define FLD_TXD_CNT (0x1F << 8) // RW field - default 0
1572#define FLD_RXD_CNT (0x1F << 0) // RW field - default 0
1573
1574//*****************************************************************************
1575// Motion Detection
1576#define MD_CH0_GRID_BLOCK_YCNT 0x170014
1577#define MD_CH1_GRID_BLOCK_YCNT 0x170094
1578#define MD_CH2_GRID_BLOCK_YCNT 0x170114
1579#define MD_CH3_GRID_BLOCK_YCNT 0x170194
1580#define MD_CH4_GRID_BLOCK_YCNT 0x170214
1581#define MD_CH5_GRID_BLOCK_YCNT 0x170294
1582#define MD_CH6_GRID_BLOCK_YCNT 0x170314
1583#define MD_CH7_GRID_BLOCK_YCNT 0x170394
1584
1585#define PIXEL_FRMT_422 4
1586#define PIXEL_FRMT_411 5
1587#define PIXEL_FRMT_Y8 6
1588
1589#define PIXEL_ENGINE_VIP1 0
1590#define PIXEL_ENGINE_VIP2 1
1591
1592#endif //Athena_REGISTERS
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
new file mode 100644
index 000000000000..bd677ee22996
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -0,0 +1,261 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __ATHENA_SRAM_H__
24#define __ATHENA_SRAM_H__
25
26//#define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM
27#define VID_CMDS_SIZE 80 // Video CMDS size in bytes
28#define AUDIO_CMDS_SIZE 80 // AUDIO CMDS size in bytes
29#define MBIF_CMDS_SIZE 80 // MBIF CMDS size in bytes
30
31//#define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers
32#define VID_IQ_SIZE 64 // VID instruction queue size in bytes
33#define MBIF_IQ_SIZE 64
34#define AUDIO_IQ_SIZE 64 // AUD instruction queue size in bytes
35
36#define VID_CDT_SIZE 64 // VID cluster descriptor table size in bytes
37#define MBIF_CDT_SIZE 64 // MBIF/HBI cluster descriptor table size in bytes
38#define AUDIO_CDT_SIZE 48 // AUD cluster descriptor table size in bytes
39
40//#define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM
41//#define RX_SRAM_END_SIZE = 0; // End of RX SRAM
42
43//#define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM
44//#define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora
45
46#define VID_CLUSTER_SIZE 1440 // VID cluster data line
47#define AUDIO_CLUSTER_SIZE 128 // AUDIO cluster data line
48#define MBIF_CLUSTER_SIZE 1440 // MBIF/HBI cluster data line
49
50//#define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM
51//#define TX_SRAM_END_SIZE = 0; // End of TX SRAM
52
53// Receive SRAM
54#define RX_SRAM_START 0x10000
55#define VID_A_DOWN_CMDS 0x10000
56#define VID_B_DOWN_CMDS 0x10050
57#define VID_C_DOWN_CMDS 0x100A0
58#define VID_D_DOWN_CMDS 0x100F0
59#define VID_E_DOWN_CMDS 0x10140
60#define VID_F_DOWN_CMDS 0x10190
61#define VID_G_DOWN_CMDS 0x101E0
62#define VID_H_DOWN_CMDS 0x10230
63#define VID_A_UP_CMDS 0x10280
64#define VID_B_UP_CMDS 0x102D0
65#define VID_C_UP_CMDS 0x10320
66#define VID_D_UP_CMDS 0x10370
67#define VID_E_UP_CMDS 0x103C0
68#define VID_F_UP_CMDS 0x10410
69#define VID_I_UP_CMDS 0x10460
70#define VID_J_UP_CMDS 0x104B0
71#define AUD_A_DOWN_CMDS 0x10500
72#define AUD_B_DOWN_CMDS 0x10550
73#define AUD_C_DOWN_CMDS 0x105A0
74#define AUD_D_DOWN_CMDS 0x105F0
75#define AUD_A_UP_CMDS 0x10640
76#define AUD_B_UP_CMDS 0x10690
77#define AUD_C_UP_CMDS 0x106E0
78#define AUD_E_UP_CMDS 0x10730
79#define MBIF_A_DOWN_CMDS 0x10780
80#define MBIF_B_DOWN_CMDS 0x107D0
81#define DMA_SCRATCH_PAD 0x10820 // Scratch pad area from 0x10820 to 0x10B40
82
83//#define RX_SRAM_POOL_START = 0x105B0;
84
85#define VID_A_IQ 0x11000
86#define VID_B_IQ 0x11040
87#define VID_C_IQ 0x11080
88#define VID_D_IQ 0x110C0
89#define VID_E_IQ 0x11100
90#define VID_F_IQ 0x11140
91#define VID_G_IQ 0x11180
92#define VID_H_IQ 0x111C0
93#define VID_I_IQ 0x11200
94#define VID_J_IQ 0x11240
95#define AUD_A_IQ 0x11280
96#define AUD_B_IQ 0x112C0
97#define AUD_C_IQ 0x11300
98#define AUD_D_IQ 0x11340
99#define AUD_E_IQ 0x11380
100#define MBIF_A_IQ 0x11000
101#define MBIF_B_IQ 0x110C0
102
103#define VID_A_CDT 0x10C00
104#define VID_B_CDT 0x10C40
105#define VID_C_CDT 0x10C80
106#define VID_D_CDT 0x10CC0
107#define VID_E_CDT 0x10D00
108#define VID_F_CDT 0x10D40
109#define VID_G_CDT 0x10D80
110#define VID_H_CDT 0x10DC0
111#define VID_I_CDT 0x10E00
112#define VID_J_CDT 0x10E40
113#define AUD_A_CDT 0x10E80
114#define AUD_B_CDT 0x10EB0
115#define AUD_C_CDT 0x10EE0
116#define AUD_D_CDT 0x10F10
117#define AUD_E_CDT 0x10F40
118#define MBIF_A_CDT 0x10C00
119#define MBIF_B_CDT 0x10CC0
120
121// Cluster Buffer for RX
122#define VID_A_UP_CLUSTER_1 0x11400
123#define VID_A_UP_CLUSTER_2 0x119A0
124#define VID_A_UP_CLUSTER_3 0x11F40
125#define VID_A_UP_CLUSTER_4 0x124E0
126
127#define VID_B_UP_CLUSTER_1 0x12A80
128#define VID_B_UP_CLUSTER_2 0x13020
129#define VID_B_UP_CLUSTER_3 0x135C0
130#define VID_B_UP_CLUSTER_4 0x13B60
131
132#define VID_C_UP_CLUSTER_1 0x14100
133#define VID_C_UP_CLUSTER_2 0x146A0
134#define VID_C_UP_CLUSTER_3 0x14C40
135#define VID_C_UP_CLUSTER_4 0x151E0
136
137#define VID_D_UP_CLUSTER_1 0x15780
138#define VID_D_UP_CLUSTER_2 0x15D20
139#define VID_D_UP_CLUSTER_3 0x162C0
140#define VID_D_UP_CLUSTER_4 0x16860
141
142#define VID_E_UP_CLUSTER_1 0x16E00
143#define VID_E_UP_CLUSTER_2 0x173A0
144#define VID_E_UP_CLUSTER_3 0x17940
145#define VID_E_UP_CLUSTER_4 0x17EE0
146
147#define VID_F_UP_CLUSTER_1 0x18480
148#define VID_F_UP_CLUSTER_2 0x18A20
149#define VID_F_UP_CLUSTER_3 0x18FC0
150#define VID_F_UP_CLUSTER_4 0x19560
151
152#define VID_I_UP_CLUSTER_1 0x19B00
153#define VID_I_UP_CLUSTER_2 0x1A0A0
154#define VID_I_UP_CLUSTER_3 0x1A640
155#define VID_I_UP_CLUSTER_4 0x1ABE0
156
157#define VID_J_UP_CLUSTER_1 0x1B180
158#define VID_J_UP_CLUSTER_2 0x1B720
159#define VID_J_UP_CLUSTER_3 0x1BCC0
160#define VID_J_UP_CLUSTER_4 0x1C260
161
162#define AUD_A_UP_CLUSTER_1 0x1C800
163#define AUD_A_UP_CLUSTER_2 0x1C880
164#define AUD_A_UP_CLUSTER_3 0x1C900
165
166#define AUD_B_UP_CLUSTER_1 0x1C980
167#define AUD_B_UP_CLUSTER_2 0x1CA00
168#define AUD_B_UP_CLUSTER_3 0x1CA80
169
170#define AUD_C_UP_CLUSTER_1 0x1CB00
171#define AUD_C_UP_CLUSTER_2 0x1CB80
172#define AUD_C_UP_CLUSTER_3 0x1CC00
173
174#define AUD_E_UP_CLUSTER_1 0x1CC80
175#define AUD_E_UP_CLUSTER_2 0x1CD00
176#define AUD_E_UP_CLUSTER_3 0x1CD80
177
178#define RX_SRAM_POOL_FREE 0x1CE00
179#define RX_SRAM_END 0x1D000
180
181// Free Receive SRAM 144 Bytes
182
183// Transmit SRAM
184#define TX_SRAM_POOL_START 0x00000
185
186#define VID_A_DOWN_CLUSTER_1 0x00040
187#define VID_A_DOWN_CLUSTER_2 0x005E0
188#define VID_A_DOWN_CLUSTER_3 0x00B80
189#define VID_A_DOWN_CLUSTER_4 0x01120
190
191#define VID_B_DOWN_CLUSTER_1 0x016C0
192#define VID_B_DOWN_CLUSTER_2 0x01C60
193#define VID_B_DOWN_CLUSTER_3 0x02200
194#define VID_B_DOWN_CLUSTER_4 0x027A0
195
196#define VID_C_DOWN_CLUSTER_1 0x02D40
197#define VID_C_DOWN_CLUSTER_2 0x032E0
198#define VID_C_DOWN_CLUSTER_3 0x03880
199#define VID_C_DOWN_CLUSTER_4 0x03E20
200
201#define VID_D_DOWN_CLUSTER_1 0x043C0
202#define VID_D_DOWN_CLUSTER_2 0x04960
203#define VID_D_DOWN_CLUSTER_3 0x04F00
204#define VID_D_DOWN_CLUSTER_4 0x054A0
205
206#define VID_E_DOWN_CLUSTER_1 0x05a40
207#define VID_E_DOWN_CLUSTER_2 0x05FE0
208#define VID_E_DOWN_CLUSTER_3 0x06580
209#define VID_E_DOWN_CLUSTER_4 0x06B20
210
211#define VID_F_DOWN_CLUSTER_1 0x070C0
212#define VID_F_DOWN_CLUSTER_2 0x07660
213#define VID_F_DOWN_CLUSTER_3 0x07C00
214#define VID_F_DOWN_CLUSTER_4 0x081A0
215
216#define VID_G_DOWN_CLUSTER_1 0x08740
217#define VID_G_DOWN_CLUSTER_2 0x08CE0
218#define VID_G_DOWN_CLUSTER_3 0x09280
219#define VID_G_DOWN_CLUSTER_4 0x09820
220
221#define VID_H_DOWN_CLUSTER_1 0x09DC0
222#define VID_H_DOWN_CLUSTER_2 0x0A360
223#define VID_H_DOWN_CLUSTER_3 0x0A900
224#define VID_H_DOWN_CLUSTER_4 0x0AEA0
225
226#define AUD_A_DOWN_CLUSTER_1 0x0B500
227#define AUD_A_DOWN_CLUSTER_2 0x0B580
228#define AUD_A_DOWN_CLUSTER_3 0x0B600
229
230#define AUD_B_DOWN_CLUSTER_1 0x0B680
231#define AUD_B_DOWN_CLUSTER_2 0x0B700
232#define AUD_B_DOWN_CLUSTER_3 0x0B780
233
234#define AUD_C_DOWN_CLUSTER_1 0x0B800
235#define AUD_C_DOWN_CLUSTER_2 0x0B880
236#define AUD_C_DOWN_CLUSTER_3 0x0B900
237
238#define AUD_D_DOWN_CLUSTER_1 0x0B980
239#define AUD_D_DOWN_CLUSTER_2 0x0BA00
240#define AUD_D_DOWN_CLUSTER_3 0x0BA80
241
242#define TX_SRAM_POOL_FREE 0x0BB00
243#define TX_SRAM_END 0x0C000
244
245#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
246#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
247#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
248
249#define VID_IQ_SIZE_DW BYTES_TO_DWORDS(VID_IQ_SIZE)
250#define VID_CDT_SIZE_QW BYTES_TO_QWORDS(VID_CDT_SIZE)
251#define VID_CLUSTER_SIZE_OW BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
252
253#define AUDIO_IQ_SIZE_DW BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
254#define AUDIO_CDT_SIZE_QW BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
255#define AUDIO_CLUSTER_SIZE_QW BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
256
257#define MBIF_IQ_SIZE_DW BYTES_TO_DWORDS(MBIF_IQ_SIZE)
258#define MBIF_CDT_SIZE_QW BYTES_TO_QWORDS(MBIF_CDT_SIZE)
259#define MBIF_CLUSTER_SIZE_OW BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
260
261#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
new file mode 100644
index 000000000000..c8905e0ac509
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -0,0 +1,835 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-video-upstream-ch2.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev,
44 __le32 * rp, unsigned int offset,
45 unsigned int bpl, u32 sync_line,
46 unsigned int lines,
47 int fifo_enable, int field_type)
48{
49 unsigned int line, i;
50 int dist_betwn_starts = bpl * 2;
51
52 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
53
54 if (USE_RISC_NOOP_VIDEO) {
55 for (i = 0; i < NUM_NO_OPS; i++) {
56 *(rp++) = cpu_to_le32(RISC_NOOP);
57 }
58 }
59
60 /* scan lines */
61 for (line = 0; line < lines; line++) {
62 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
63 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
64 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
65
66 if ((lines <= NTSC_FIELD_HEIGHT)
67 || (line < (NTSC_FIELD_HEIGHT - 1))
68 || !(dev->_isNTSC_ch2)) {
69 offset += dist_betwn_starts;
70 }
71 }
72
73 return rp;
74}
75
76static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
77 __le32 * rp,
78 dma_addr_t databuf_phys_addr,
79 unsigned int offset,
80 u32 sync_line, unsigned int bpl,
81 unsigned int lines,
82 int fifo_enable, int field_type)
83{
84 unsigned int line, i;
85 struct sram_channel *sram_ch =
86 &dev->sram_channels[dev->_channel2_upstream_select];
87 int dist_betwn_starts = bpl * 2;
88
89 /* sync instruction */
90 if (sync_line != NO_SYNC_LINE) {
91 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
92 }
93
94 if (USE_RISC_NOOP_VIDEO) {
95 for (i = 0; i < NUM_NO_OPS; i++) {
96 *(rp++) = cpu_to_le32(RISC_NOOP);
97 }
98 }
99
100 /* scan lines */
101 for (line = 0; line < lines; line++) {
102 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
103 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
104 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
105
106 if ((lines <= NTSC_FIELD_HEIGHT)
107 || (line < (NTSC_FIELD_HEIGHT - 1))
108 || !(dev->_isNTSC_ch2)) {
109 offset += dist_betwn_starts;
110 }
111
112 // check if we need to enable the FIFO after the first 4 lines
113 // For the upstream video channel, the risc engine will enable the FIFO.
114 if (fifo_enable && line == 3) {
115 *(rp++) = RISC_WRITECR;
116 *(rp++) = sram_ch->dma_ctl;
117 *(rp++) = FLD_VID_FIFO_EN;
118 *(rp++) = 0x00000001;
119 }
120 }
121
122 return rp;
123}
124
125int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
126 struct pci_dev *pci,
127 unsigned int top_offset, unsigned int bpl,
128 unsigned int lines)
129{
130 __le32 *rp;
131 int fifo_enable = 0;
132 int singlefield_lines = lines >> 1; //get line count for single field
133 int odd_num_lines = singlefield_lines;
134 int frame = 0;
135 int frame_size = 0;
136 int databuf_offset = 0;
137 int risc_program_size = 0;
138 int risc_flag = RISC_CNT_RESET;
139 unsigned int bottom_offset = bpl;
140 dma_addr_t risc_phys_jump_addr;
141
142 if (dev->_isNTSC_ch2) {
143 odd_num_lines = singlefield_lines + 1;
144 risc_program_size = FRAME1_VID_PROG_SIZE;
145 frame_size =
146 (bpl ==
147 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
148 FRAME_SIZE_NTSC_Y422;
149 } else {
150 risc_program_size = PAL_VID_PROG_SIZE;
151 frame_size =
152 (bpl ==
153 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
154 }
155
156 /* Virtual address of Risc buffer program */
157 rp = dev->_dma_virt_addr_ch2;
158
159 for (frame = 0; frame < NUM_FRAMES; frame++) {
160 databuf_offset = frame_size * frame;
161
162 if (UNSET != top_offset) {
163 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
164 rp = cx25821_risc_field_upstream_ch2(dev, rp,
165 dev->
166 _data_buf_phys_addr_ch2
167 + databuf_offset,
168 top_offset, 0, bpl,
169 odd_num_lines,
170 fifo_enable,
171 ODD_FIELD);
172 }
173
174 fifo_enable = FIFO_DISABLE;
175
176 //Even field
177 rp = cx25821_risc_field_upstream_ch2(dev, rp,
178 dev->
179 _data_buf_phys_addr_ch2 +
180 databuf_offset,
181 bottom_offset, 0x200, bpl,
182 singlefield_lines,
183 fifo_enable, EVEN_FIELD);
184
185 if (frame == 0) {
186 risc_flag = RISC_CNT_RESET;
187 risc_phys_jump_addr =
188 dev->_dma_phys_start_addr_ch2 + risc_program_size;
189 } else {
190 risc_flag = RISC_CNT_INC;
191 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
192 }
193
194 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
195 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
196 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
197 *(rp++) = cpu_to_le32(0);
198 }
199
200 return 0;
201}
202
203void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
204{
205 struct sram_channel *sram_ch =
206 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
207 u32 tmp = 0;
208
209 if (!dev->_is_running_ch2) {
210 printk
211 ("cx25821: No video file is currently running so return!\n");
212 return;
213 }
214 //Disable RISC interrupts
215 tmp = cx_read(sram_ch->int_msk);
216 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
217
218 //Turn OFF risc and fifo
219 tmp = cx_read(sram_ch->dma_ctl);
220 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
221
222 //Clear data buffer memory
223 if (dev->_data_buf_virt_addr_ch2)
224 memset(dev->_data_buf_virt_addr_ch2, 0,
225 dev->_data_buf_size_ch2);
226
227 dev->_is_running_ch2 = 0;
228 dev->_is_first_frame_ch2 = 0;
229 dev->_frame_count_ch2 = 0;
230 dev->_file_status_ch2 = END_OF_FILE;
231
232 if (dev->_irq_queues_ch2) {
233 kfree(dev->_irq_queues_ch2);
234 dev->_irq_queues_ch2 = NULL;
235 }
236
237 if (dev->_filename_ch2 != NULL)
238 kfree(dev->_filename_ch2);
239
240 tmp = cx_read(VID_CH_MODE_SEL);
241 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
242}
243
244void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
245{
246 if (dev->_is_running_ch2) {
247 cx25821_stop_upstream_video_ch2(dev);
248 }
249
250 if (dev->_dma_virt_addr_ch2) {
251 pci_free_consistent(dev->pci, dev->_risc_size_ch2,
252 dev->_dma_virt_addr_ch2,
253 dev->_dma_phys_addr_ch2);
254 dev->_dma_virt_addr_ch2 = NULL;
255 }
256
257 if (dev->_data_buf_virt_addr_ch2) {
258 pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
259 dev->_data_buf_virt_addr_ch2,
260 dev->_data_buf_phys_addr_ch2);
261 dev->_data_buf_virt_addr_ch2 = NULL;
262 }
263}
264
265int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
266{
267 struct file *myfile;
268 int frame_index_temp = dev->_frame_index_ch2;
269 int i = 0;
270 int line_size =
271 (dev->_pixel_format_ch2 ==
272 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
273 int frame_size = 0;
274 int frame_offset = 0;
275 ssize_t vfs_read_retval = 0;
276 char mybuf[line_size];
277 loff_t file_offset;
278 loff_t pos;
279 mm_segment_t old_fs;
280
281 if (dev->_file_status_ch2 == END_OF_FILE)
282 return 0;
283
284 if (dev->_isNTSC_ch2) {
285 frame_size =
286 (line_size ==
287 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
288 FRAME_SIZE_NTSC_Y422;
289 } else {
290 frame_size =
291 (line_size ==
292 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
293 }
294
295 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
296 file_offset = dev->_frame_count_ch2 * frame_size;
297
298 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
299
300 if (IS_ERR(myfile)) {
301 const int open_errno = -PTR_ERR(myfile);
302 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
303 __func__, dev->_filename_ch2, open_errno);
304 return PTR_ERR(myfile);
305 } else {
306 if (!(myfile->f_op)) {
307 printk("%s: File has no file operations registered!",
308 __func__);
309 filp_close(myfile, NULL);
310 return -EIO;
311 }
312
313 if (!myfile->f_op->read) {
314 printk("%s: File has no READ operations registered!",
315 __func__);
316 filp_close(myfile, NULL);
317 return -EIO;
318 }
319
320 pos = myfile->f_pos;
321 old_fs = get_fs();
322 set_fs(KERNEL_DS);
323
324 for (i = 0; i < dev->_lines_count_ch2; i++) {
325 pos = file_offset;
326
327 vfs_read_retval =
328 vfs_read(myfile, mybuf, line_size, &pos);
329
330 if (vfs_read_retval > 0 && vfs_read_retval == line_size
331 && dev->_data_buf_virt_addr_ch2 != NULL) {
332 memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
333 frame_offset / 4), mybuf,
334 vfs_read_retval);
335 }
336
337 file_offset += vfs_read_retval;
338 frame_offset += vfs_read_retval;
339
340 if (vfs_read_retval < line_size) {
341 printk(KERN_INFO
342 "Done: exit %s() since no more bytes to read from Video file.\n",
343 __func__);
344 break;
345 }
346 }
347
348 if (i > 0)
349 dev->_frame_count_ch2++;
350
351 dev->_file_status_ch2 =
352 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
353
354 set_fs(old_fs);
355 filp_close(myfile, NULL);
356 }
357
358 return 0;
359}
360
361static void cx25821_vidups_handler_ch2(struct work_struct *work)
362{
363 struct cx25821_dev *dev =
364 container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
365
366 if (!dev) {
367 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
368 __func__);
369 return;
370 }
371
372 cx25821_get_frame_ch2(dev,
373 &dev->sram_channels[dev->
374 _channel2_upstream_select]);
375}
376
377int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
378{
379 struct file *myfile;
380 int i = 0, j = 0;
381 int line_size =
382 (dev->_pixel_format_ch2 ==
383 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
384 ssize_t vfs_read_retval = 0;
385 char mybuf[line_size];
386 loff_t pos;
387 loff_t offset = (unsigned long)0;
388 mm_segment_t old_fs;
389
390 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
391
392 if (IS_ERR(myfile)) {
393 const int open_errno = -PTR_ERR(myfile);
394 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
395 __func__, dev->_filename_ch2, open_errno);
396 return PTR_ERR(myfile);
397 } else {
398 if (!(myfile->f_op)) {
399 printk("%s: File has no file operations registered!",
400 __func__);
401 filp_close(myfile, NULL);
402 return -EIO;
403 }
404
405 if (!myfile->f_op->read) {
406 printk
407 ("%s: File has no READ operations registered! Returning.",
408 __func__);
409 filp_close(myfile, NULL);
410 return -EIO;
411 }
412
413 pos = myfile->f_pos;
414 old_fs = get_fs();
415 set_fs(KERNEL_DS);
416
417 for (j = 0; j < NUM_FRAMES; j++) {
418 for (i = 0; i < dev->_lines_count_ch2; i++) {
419 pos = offset;
420
421 vfs_read_retval =
422 vfs_read(myfile, mybuf, line_size, &pos);
423
424 if (vfs_read_retval > 0
425 && vfs_read_retval == line_size
426 && dev->_data_buf_virt_addr_ch2 != NULL) {
427 memcpy((void *)(dev->
428 _data_buf_virt_addr_ch2
429 + offset / 4), mybuf,
430 vfs_read_retval);
431 }
432
433 offset += vfs_read_retval;
434
435 if (vfs_read_retval < line_size) {
436 printk(KERN_INFO
437 "Done: exit %s() since no more bytes to read from Video file.\n",
438 __func__);
439 break;
440 }
441 }
442
443 if (i > 0)
444 dev->_frame_count_ch2++;
445
446 if (vfs_read_retval < line_size) {
447 break;
448 }
449 }
450
451 dev->_file_status_ch2 =
452 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
453
454 set_fs(old_fs);
455 myfile->f_pos = 0;
456 filp_close(myfile, NULL);
457 }
458
459 return 0;
460}
461
462static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
463 struct sram_channel *sram_ch,
464 int bpl)
465{
466 int ret = 0;
467 dma_addr_t dma_addr;
468 dma_addr_t data_dma_addr;
469
470 if (dev->_dma_virt_addr_ch2 != NULL) {
471 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
472 dev->_dma_virt_addr_ch2,
473 dev->_dma_phys_addr_ch2);
474 }
475
476 dev->_dma_virt_addr_ch2 =
477 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
478 &dma_addr);
479 dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
480 dev->_dma_phys_start_addr_ch2 = dma_addr;
481 dev->_dma_phys_addr_ch2 = dma_addr;
482 dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
483
484 if (!dev->_dma_virt_addr_ch2) {
485 printk
486 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
487 return -ENOMEM;
488 }
489
490 //Iniitize at this address until n bytes to 0
491 memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
492
493 if (dev->_data_buf_virt_addr_ch2 != NULL) {
494 pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
495 dev->_data_buf_virt_addr_ch2,
496 dev->_data_buf_phys_addr_ch2);
497 }
498 //For Video Data buffer allocation
499 dev->_data_buf_virt_addr_ch2 =
500 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
501 &data_dma_addr);
502 dev->_data_buf_phys_addr_ch2 = data_dma_addr;
503 dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
504
505 if (!dev->_data_buf_virt_addr_ch2) {
506 printk
507 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
508 return -ENOMEM;
509 }
510
511 //Initialize at this address until n bytes to 0
512 memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
513
514 ret = cx25821_openfile_ch2(dev, sram_ch);
515 if (ret < 0)
516 return ret;
517
518 //Creating RISC programs
519 ret =
520 cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
521 dev->_lines_count_ch2);
522 if (ret < 0) {
523 printk(KERN_INFO
524 "cx25821: Failed creating Video Upstream Risc programs! \n");
525 goto error;
526 }
527
528 return 0;
529
530 error:
531 return ret;
532}
533
534int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
535 u32 status)
536{
537 u32 int_msk_tmp;
538 struct sram_channel *channel = &dev->sram_channels[chan_num];
539 int singlefield_lines = NTSC_FIELD_HEIGHT;
540 int line_size_in_bytes = Y422_LINE_SZ;
541 int odd_risc_prog_size = 0;
542 dma_addr_t risc_phys_jump_addr;
543 __le32 *rp;
544
545 if (status & FLD_VID_SRC_RISC1) {
546 // We should only process one program per call
547 u32 prog_cnt = cx_read(channel->gpcnt);
548
549 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
550 int_msk_tmp = cx_read(channel->int_msk);
551 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
552 cx_write(channel->int_stat, _intr_msk);
553
554 spin_lock(&dev->slock);
555
556 dev->_frame_index_ch2 = prog_cnt;
557
558 queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
559
560 if (dev->_is_first_frame_ch2) {
561 dev->_is_first_frame_ch2 = 0;
562
563 if (dev->_isNTSC_ch2) {
564 singlefield_lines += 1;
565 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
566 } else {
567 singlefield_lines = PAL_FIELD_HEIGHT;
568 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
569 }
570
571 if (dev->_dma_virt_start_addr_ch2 != NULL) {
572 line_size_in_bytes =
573 (dev->_pixel_format_ch2 ==
574 PIXEL_FRMT_411) ? Y411_LINE_SZ :
575 Y422_LINE_SZ;
576 risc_phys_jump_addr =
577 dev->_dma_phys_start_addr_ch2 +
578 odd_risc_prog_size;
579
580 rp = cx25821_update_riscprogram_ch2(dev,
581 dev->
582 _dma_virt_start_addr_ch2,
583 TOP_OFFSET,
584 line_size_in_bytes,
585 0x0,
586 singlefield_lines,
587 FIFO_DISABLE,
588 ODD_FIELD);
589
590 // Jump to Even Risc program of 1st Frame
591 *(rp++) = cpu_to_le32(RISC_JUMP);
592 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
593 *(rp++) = cpu_to_le32(0);
594 }
595 }
596
597 spin_unlock(&dev->slock);
598 }
599
600 if (dev->_file_status_ch2 == END_OF_FILE) {
601 printk("cx25821: EOF Channel 2 Framecount = %d\n",
602 dev->_frame_count_ch2);
603 return -1;
604 }
605 //ElSE, set the interrupt mask register, re-enable irq.
606 int_msk_tmp = cx_read(channel->int_msk);
607 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
608
609 return 0;
610}
611
612static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
613{
614 struct cx25821_dev *dev = dev_id;
615 u32 msk_stat, vid_status;
616 int handled = 0;
617 int channel_num = 0;
618 struct sram_channel *sram_ch;
619
620 if (!dev)
621 return -1;
622
623 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
624
625 sram_ch = &dev->sram_channels[channel_num];
626
627 msk_stat = cx_read(sram_ch->int_mstat);
628 vid_status = cx_read(sram_ch->int_stat);
629
630 // Only deal with our interrupt
631 if (vid_status) {
632 handled =
633 cx25821_video_upstream_irq_ch2(dev, channel_num,
634 vid_status);
635 }
636
637 if (handled < 0) {
638 cx25821_stop_upstream_video_ch2(dev);
639 } else {
640 handled += handled;
641 }
642
643 return IRQ_RETVAL(handled);
644}
645
646static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
647 struct sram_channel *ch, int pix_format)
648{
649 int width = WIDTH_D1;
650 int height = dev->_lines_count_ch2;
651 int num_lines, odd_num_lines;
652 u32 value;
653 int vip_mode = PIXEL_ENGINE_VIP1;
654
655 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
656 value &= 0xFFFFFFEF;
657 value |= dev->_isNTSC_ch2 ? 0 : 0x10;
658 cx_write(ch->vid_fmt_ctl, value);
659
660 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
661 cx_write(ch->vid_active_ctl1, width);
662
663 num_lines = (height / 2) & 0x3FF;
664 odd_num_lines = num_lines;
665
666 if (dev->_isNTSC_ch2) {
667 odd_num_lines += 1;
668 }
669
670 value = (num_lines << 16) | odd_num_lines;
671
672 // set number of active lines in field 0 (top) and field 1 (bottom)
673 cx_write(ch->vid_active_ctl2, value);
674
675 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
676}
677
678int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
679 struct sram_channel *sram_ch)
680{
681 u32 tmp = 0;
682 int err = 0;
683
684 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
685 tmp = cx_read(VID_CH_MODE_SEL);
686 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
687
688 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
689 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
690 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
691
692 /* reset counter */
693 cx_write(sram_ch->gpcnt_ctl, 3);
694
695 // Clear our bits from the interrupt status register.
696 cx_write(sram_ch->int_stat, _intr_msk);
697
698 //Set the interrupt mask register, enable irq.
699 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
700 tmp = cx_read(sram_ch->int_msk);
701 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
702
703 err =
704 request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
705 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
706 if (err < 0) {
707 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
708 dev->pci->irq);
709 goto fail_irq;
710 }
711 // Start the DMA engine
712 tmp = cx_read(sram_ch->dma_ctl);
713 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
714
715 dev->_is_running_ch2 = 1;
716 dev->_is_first_frame_ch2 = 1;
717
718 return 0;
719
720 fail_irq:
721 cx25821_dev_unregister(dev);
722 return err;
723}
724
725int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
726 int pixel_format)
727{
728 struct sram_channel *sram_ch;
729 u32 tmp;
730 int retval = 0;
731 int err = 0;
732 int data_frame_size = 0;
733 int risc_buffer_size = 0;
734 int str_length = 0;
735
736 if (dev->_is_running_ch2) {
737 printk("Video Channel is still running so return!\n");
738 return 0;
739 }
740
741 dev->_channel2_upstream_select = channel_select;
742 sram_ch = &dev->sram_channels[channel_select];
743
744 INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
745 dev->_irq_queues_ch2 =
746 create_singlethread_workqueue("cx25821_workqueue2");
747
748 if (!dev->_irq_queues_ch2) {
749 printk
750 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
751 return -ENOMEM;
752 }
753 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
754 tmp = cx_read(VID_CH_MODE_SEL);
755 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
756
757 dev->_is_running_ch2 = 0;
758 dev->_frame_count_ch2 = 0;
759 dev->_file_status_ch2 = RESET_STATUS;
760 dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
761 dev->_pixel_format_ch2 = pixel_format;
762 dev->_line_size_ch2 =
763 (dev->_pixel_format_ch2 ==
764 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
765 data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
766 risc_buffer_size =
767 dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
768
769 if (dev->input_filename_ch2) {
770 str_length = strlen(dev->input_filename_ch2);
771 dev->_filename_ch2 =
772 (char *)kmalloc(str_length + 1, GFP_KERNEL);
773
774 if (!dev->_filename_ch2)
775 goto error;
776
777 memcpy(dev->_filename_ch2, dev->input_filename_ch2,
778 str_length + 1);
779 } else {
780 str_length = strlen(dev->_defaultname_ch2);
781 dev->_filename_ch2 =
782 (char *)kmalloc(str_length + 1, GFP_KERNEL);
783
784 if (!dev->_filename_ch2)
785 goto error;
786
787 memcpy(dev->_filename_ch2, dev->_defaultname_ch2,
788 str_length + 1);
789 }
790
791 //Default if filename is empty string
792 if (strcmp(dev->input_filename_ch2, "") == 0) {
793 if (dev->_isNTSC_ch2) {
794 dev->_filename_ch2 =
795 (dev->_pixel_format_ch2 ==
796 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
797 "/root/vidtest.yuv";
798 } else {
799 dev->_filename_ch2 =
800 (dev->_pixel_format_ch2 ==
801 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
802 "/root/pal422.yuv";
803 }
804 }
805
806 retval =
807 cx25821_sram_channel_setup_upstream(dev, sram_ch,
808 dev->_line_size_ch2, 0);
809
810 /* setup fifo + format */
811 cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
812
813 dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
814 dev->upstream_databuf_size_ch2 = data_frame_size * 2;
815
816 //Allocating buffers and prepare RISC program
817 retval =
818 cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
819 dev->_line_size_ch2);
820 if (retval < 0) {
821 printk(KERN_ERR
822 "%s: Failed to set up Video upstream buffers!\n",
823 dev->name);
824 goto error;
825 }
826
827 cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
828
829 return 0;
830
831 error:
832 cx25821_dev_unregister(dev);
833
834 return err;
835}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
new file mode 100644
index 000000000000..73feea114c1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -0,0 +1,101 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define OPEN_FILE_1 0
27#define NUM_PROGS 8
28#define NUM_FRAMES 2
29#define ODD_FIELD 0
30#define EVEN_FIELD 1
31#define TOP_OFFSET 0
32#define FIFO_DISABLE 0
33#define FIFO_ENABLE 1
34#define TEST_FRAMES 5
35#define END_OF_FILE 0
36#define IN_PROGRESS 1
37#define RESET_STATUS -1
38#define NUM_NO_OPS 5
39
40// PAL and NTSC line sizes and number of lines.
41#define WIDTH_D1 720
42#define NTSC_LINES_PER_FRAME 480
43#define PAL_LINES_PER_FRAME 576
44#define PAL_LINE_SZ 1440
45#define Y422_LINE_SZ 1440
46#define Y411_LINE_SZ 1080
47#define NTSC_FIELD_HEIGHT 240
48#define NTSC_ODD_FLD_LINES 241
49#define PAL_FIELD_HEIGHT 288
50
51#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
52#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
53#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
54#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
55
56#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
57#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
58
59#define RISC_WRITECR_INSTRUCTION_SIZE 16
60#define RISC_SYNC_INSTRUCTION_SIZE 4
61#define JUMP_INSTRUCTION_SIZE 12
62#define MAXSIZE_NO_OPS 36
63#define DWORD_SIZE 4
64
65#define USE_RISC_NOOP_VIDEO 1
66
67#ifdef USE_RISC_NOOP_VIDEO
68#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
69 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
70
71#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
72
73#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
74 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
75
76#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
77 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
78
79#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
80 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
81
82#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
83
84#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
85 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
86#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
87 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
88#endif
89
90#ifndef USE_RISC_NOOP_VIDEO
91#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
92#define PAL_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) )
93#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
94 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
95#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
96#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
97#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
98#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
99#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
new file mode 100644
index 000000000000..3d7dd3f66541
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -0,0 +1,894 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-video-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
44 struct sram_channel *ch,
45 unsigned int bpl, u32 risc)
46{
47 unsigned int i, lines;
48 u32 cdt;
49
50 if (ch->cmds_start == 0) {
51 cx_write(ch->ptr1_reg, 0);
52 cx_write(ch->ptr2_reg, 0);
53 cx_write(ch->cnt2_reg, 0);
54 cx_write(ch->cnt1_reg, 0);
55 return 0;
56 }
57
58 bpl = (bpl + 7) & ~7; /* alignment */
59 cdt = ch->cdt;
60 lines = ch->fifo_size / bpl;
61
62 if (lines > 4) {
63 lines = 4;
64 }
65
66 BUG_ON(lines < 2);
67
68 /* write CDT */
69 for (i = 0; i < lines; i++) {
70 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
71 cx_write(cdt + 16 * i + 4, 0);
72 cx_write(cdt + 16 * i + 8, 0);
73 cx_write(cdt + 16 * i + 12, 0);
74 }
75
76 /* write CMDS */
77 cx_write(ch->cmds_start + 0, risc);
78
79 cx_write(ch->cmds_start + 4, 0);
80 cx_write(ch->cmds_start + 8, cdt);
81 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
82 cx_write(ch->cmds_start + 16, ch->ctrl_start);
83
84 cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
85
86 for (i = 24; i < 80; i += 4)
87 cx_write(ch->cmds_start + i, 0);
88
89 /* fill registers */
90 cx_write(ch->ptr1_reg, ch->fifo_start);
91 cx_write(ch->ptr2_reg, cdt);
92 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
93 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
94
95 return 0;
96}
97
98static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
99 __le32 * rp, unsigned int offset,
100 unsigned int bpl, u32 sync_line,
101 unsigned int lines, int fifo_enable,
102 int field_type)
103{
104 unsigned int line, i;
105 int dist_betwn_starts = bpl * 2;
106
107 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
108
109 if (USE_RISC_NOOP_VIDEO) {
110 for (i = 0; i < NUM_NO_OPS; i++) {
111 *(rp++) = cpu_to_le32(RISC_NOOP);
112 }
113 }
114
115 /* scan lines */
116 for (line = 0; line < lines; line++) {
117 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
118 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
119 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
120
121 if ((lines <= NTSC_FIELD_HEIGHT)
122 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
123 offset += dist_betwn_starts;
124 }
125 }
126
127 return rp;
128}
129
130static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
131 dma_addr_t databuf_phys_addr,
132 unsigned int offset, u32 sync_line,
133 unsigned int bpl, unsigned int lines,
134 int fifo_enable, int field_type)
135{
136 unsigned int line, i;
137 struct sram_channel *sram_ch =
138 &dev->sram_channels[dev->_channel_upstream_select];
139 int dist_betwn_starts = bpl * 2;
140
141 /* sync instruction */
142 if (sync_line != NO_SYNC_LINE) {
143 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
144 }
145
146 if (USE_RISC_NOOP_VIDEO) {
147 for (i = 0; i < NUM_NO_OPS; i++) {
148 *(rp++) = cpu_to_le32(RISC_NOOP);
149 }
150 }
151
152 /* scan lines */
153 for (line = 0; line < lines; line++) {
154 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
155 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
156 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
157
158 if ((lines <= NTSC_FIELD_HEIGHT)
159 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
160 offset += dist_betwn_starts; //to skip the other field line
161 }
162
163 // check if we need to enable the FIFO after the first 4 lines
164 // For the upstream video channel, the risc engine will enable the FIFO.
165 if (fifo_enable && line == 3) {
166 *(rp++) = RISC_WRITECR;
167 *(rp++) = sram_ch->dma_ctl;
168 *(rp++) = FLD_VID_FIFO_EN;
169 *(rp++) = 0x00000001;
170 }
171 }
172
173 return rp;
174}
175
176int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
177 struct pci_dev *pci,
178 unsigned int top_offset,
179 unsigned int bpl, unsigned int lines)
180{
181 __le32 *rp;
182 int fifo_enable = 0;
183 int singlefield_lines = lines >> 1; //get line count for single field
184 int odd_num_lines = singlefield_lines;
185 int frame = 0;
186 int frame_size = 0;
187 int databuf_offset = 0;
188 int risc_program_size = 0;
189 int risc_flag = RISC_CNT_RESET;
190 unsigned int bottom_offset = bpl;
191 dma_addr_t risc_phys_jump_addr;
192
193 if (dev->_isNTSC) {
194 odd_num_lines = singlefield_lines + 1;
195 risc_program_size = FRAME1_VID_PROG_SIZE;
196 frame_size =
197 (bpl ==
198 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
199 FRAME_SIZE_NTSC_Y422;
200 } else {
201 risc_program_size = PAL_VID_PROG_SIZE;
202 frame_size =
203 (bpl ==
204 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
205 }
206
207 /* Virtual address of Risc buffer program */
208 rp = dev->_dma_virt_addr;
209
210 for (frame = 0; frame < NUM_FRAMES; frame++) {
211 databuf_offset = frame_size * frame;
212
213 if (UNSET != top_offset) {
214 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
215 rp = cx25821_risc_field_upstream(dev, rp,
216 dev->
217 _data_buf_phys_addr +
218 databuf_offset,
219 top_offset, 0, bpl,
220 odd_num_lines,
221 fifo_enable,
222 ODD_FIELD);
223 }
224
225 fifo_enable = FIFO_DISABLE;
226
227 //Even Field
228 rp = cx25821_risc_field_upstream(dev, rp,
229 dev->_data_buf_phys_addr +
230 databuf_offset, bottom_offset,
231 0x200, bpl, singlefield_lines,
232 fifo_enable, EVEN_FIELD);
233
234 if (frame == 0) {
235 risc_flag = RISC_CNT_RESET;
236 risc_phys_jump_addr =
237 dev->_dma_phys_start_addr + risc_program_size;
238 } else {
239 risc_phys_jump_addr = dev->_dma_phys_start_addr;
240 risc_flag = RISC_CNT_INC;
241 }
242
243 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
244 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
245 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
246 *(rp++) = cpu_to_le32(0);
247 }
248
249 return 0;
250}
251
252void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
253{
254 struct sram_channel *sram_ch =
255 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
256 u32 tmp = 0;
257
258 if (!dev->_is_running) {
259 printk
260 ("cx25821: No video file is currently running so return!\n");
261 return;
262 }
263 //Disable RISC interrupts
264 tmp = cx_read(sram_ch->int_msk);
265 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
266
267 //Turn OFF risc and fifo enable
268 tmp = cx_read(sram_ch->dma_ctl);
269 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
270
271 //Clear data buffer memory
272 if (dev->_data_buf_virt_addr)
273 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
274
275 dev->_is_running = 0;
276 dev->_is_first_frame = 0;
277 dev->_frame_count = 0;
278 dev->_file_status = END_OF_FILE;
279
280 if (dev->_irq_queues) {
281 kfree(dev->_irq_queues);
282 dev->_irq_queues = NULL;
283 }
284
285 if (dev->_filename != NULL)
286 kfree(dev->_filename);
287
288 tmp = cx_read(VID_CH_MODE_SEL);
289 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
290}
291
292void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
293{
294 if (dev->_is_running) {
295 cx25821_stop_upstream_video_ch1(dev);
296 }
297
298 if (dev->_dma_virt_addr) {
299 pci_free_consistent(dev->pci, dev->_risc_size,
300 dev->_dma_virt_addr, dev->_dma_phys_addr);
301 dev->_dma_virt_addr = NULL;
302 }
303
304 if (dev->_data_buf_virt_addr) {
305 pci_free_consistent(dev->pci, dev->_data_buf_size,
306 dev->_data_buf_virt_addr,
307 dev->_data_buf_phys_addr);
308 dev->_data_buf_virt_addr = NULL;
309 }
310}
311
312int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
313{
314 struct file *myfile;
315 int frame_index_temp = dev->_frame_index;
316 int i = 0;
317 int line_size =
318 (dev->_pixel_format ==
319 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
320 int frame_size = 0;
321 int frame_offset = 0;
322 ssize_t vfs_read_retval = 0;
323 char mybuf[line_size];
324 loff_t file_offset;
325 loff_t pos;
326 mm_segment_t old_fs;
327
328 if (dev->_file_status == END_OF_FILE)
329 return 0;
330
331 if (dev->_isNTSC) {
332 frame_size =
333 (line_size ==
334 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
335 FRAME_SIZE_NTSC_Y422;
336 } else {
337 frame_size =
338 (line_size ==
339 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
340 }
341
342 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
343 file_offset = dev->_frame_count * frame_size;
344
345 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
346
347 if (IS_ERR(myfile)) {
348 const int open_errno = -PTR_ERR(myfile);
349 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
350 __func__, dev->_filename, open_errno);
351 return PTR_ERR(myfile);
352 } else {
353 if (!(myfile->f_op)) {
354 printk("%s: File has no file operations registered!",
355 __func__);
356 filp_close(myfile, NULL);
357 return -EIO;
358 }
359
360 if (!myfile->f_op->read) {
361 printk("%s: File has no READ operations registered!",
362 __func__);
363 filp_close(myfile, NULL);
364 return -EIO;
365 }
366
367 pos = myfile->f_pos;
368 old_fs = get_fs();
369 set_fs(KERNEL_DS);
370
371 for (i = 0; i < dev->_lines_count; i++) {
372 pos = file_offset;
373
374 vfs_read_retval =
375 vfs_read(myfile, mybuf, line_size, &pos);
376
377 if (vfs_read_retval > 0 && vfs_read_retval == line_size
378 && dev->_data_buf_virt_addr != NULL) {
379 memcpy((void *)(dev->_data_buf_virt_addr +
380 frame_offset / 4), mybuf,
381 vfs_read_retval);
382 }
383
384 file_offset += vfs_read_retval;
385 frame_offset += vfs_read_retval;
386
387 if (vfs_read_retval < line_size) {
388 printk(KERN_INFO
389 "Done: exit %s() since no more bytes to read from Video file.\n",
390 __func__);
391 break;
392 }
393 }
394
395 if (i > 0)
396 dev->_frame_count++;
397
398 dev->_file_status =
399 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
400
401 set_fs(old_fs);
402 filp_close(myfile, NULL);
403 }
404
405 return 0;
406}
407
408static void cx25821_vidups_handler(struct work_struct *work)
409{
410 struct cx25821_dev *dev =
411 container_of(work, struct cx25821_dev, _irq_work_entry);
412
413 if (!dev) {
414 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
415 __func__);
416 return;
417 }
418
419 cx25821_get_frame(dev,
420 &dev->sram_channels[dev->_channel_upstream_select]);
421}
422
423int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
424{
425 struct file *myfile;
426 int i = 0, j = 0;
427 int line_size =
428 (dev->_pixel_format ==
429 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
430 ssize_t vfs_read_retval = 0;
431 char mybuf[line_size];
432 loff_t pos;
433 loff_t offset = (unsigned long)0;
434 mm_segment_t old_fs;
435
436 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
437
438 if (IS_ERR(myfile)) {
439 const int open_errno = -PTR_ERR(myfile);
440 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
441 __func__, dev->_filename, open_errno);
442 return PTR_ERR(myfile);
443 } else {
444 if (!(myfile->f_op)) {
445 printk("%s: File has no file operations registered!",
446 __func__);
447 filp_close(myfile, NULL);
448 return -EIO;
449 }
450
451 if (!myfile->f_op->read) {
452 printk
453 ("%s: File has no READ operations registered! Returning.",
454 __func__);
455 filp_close(myfile, NULL);
456 return -EIO;
457 }
458
459 pos = myfile->f_pos;
460 old_fs = get_fs();
461 set_fs(KERNEL_DS);
462
463 for (j = 0; j < NUM_FRAMES; j++) {
464 for (i = 0; i < dev->_lines_count; i++) {
465 pos = offset;
466
467 vfs_read_retval =
468 vfs_read(myfile, mybuf, line_size, &pos);
469
470 if (vfs_read_retval > 0
471 && vfs_read_retval == line_size
472 && dev->_data_buf_virt_addr != NULL) {
473 memcpy((void *)(dev->
474 _data_buf_virt_addr +
475 offset / 4), mybuf,
476 vfs_read_retval);
477 }
478
479 offset += vfs_read_retval;
480
481 if (vfs_read_retval < line_size) {
482 printk(KERN_INFO
483 "Done: exit %s() since no more bytes to read from Video file.\n",
484 __func__);
485 break;
486 }
487 }
488
489 if (i > 0)
490 dev->_frame_count++;
491
492 if (vfs_read_retval < line_size) {
493 break;
494 }
495 }
496
497 dev->_file_status =
498 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
499
500 set_fs(old_fs);
501 myfile->f_pos = 0;
502 filp_close(myfile, NULL);
503 }
504
505 return 0;
506}
507
508int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
509 struct sram_channel *sram_ch, int bpl)
510{
511 int ret = 0;
512 dma_addr_t dma_addr;
513 dma_addr_t data_dma_addr;
514
515 if (dev->_dma_virt_addr != NULL) {
516 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
517 dev->_dma_virt_addr, dev->_dma_phys_addr);
518 }
519
520 dev->_dma_virt_addr =
521 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
522 &dma_addr);
523 dev->_dma_virt_start_addr = dev->_dma_virt_addr;
524 dev->_dma_phys_start_addr = dma_addr;
525 dev->_dma_phys_addr = dma_addr;
526 dev->_risc_size = dev->upstream_riscbuf_size;
527
528 if (!dev->_dma_virt_addr) {
529 printk
530 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
531 return -ENOMEM;
532 }
533
534 //Clear memory at address
535 memset(dev->_dma_virt_addr, 0, dev->_risc_size);
536
537 if (dev->_data_buf_virt_addr != NULL) {
538 pci_free_consistent(dev->pci, dev->upstream_databuf_size,
539 dev->_data_buf_virt_addr,
540 dev->_data_buf_phys_addr);
541 }
542 //For Video Data buffer allocation
543 dev->_data_buf_virt_addr =
544 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
545 &data_dma_addr);
546 dev->_data_buf_phys_addr = data_dma_addr;
547 dev->_data_buf_size = dev->upstream_databuf_size;
548
549 if (!dev->_data_buf_virt_addr) {
550 printk
551 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
552 return -ENOMEM;
553 }
554
555 //Clear memory at address
556 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
557
558 ret = cx25821_openfile(dev, sram_ch);
559 if (ret < 0)
560 return ret;
561
562 //Create RISC programs
563 ret =
564 cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
565 dev->_lines_count);
566 if (ret < 0) {
567 printk(KERN_INFO
568 "cx25821: Failed creating Video Upstream Risc programs! \n");
569 goto error;
570 }
571
572 return 0;
573
574 error:
575 return ret;
576}
577
578int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
579 u32 status)
580{
581 u32 int_msk_tmp;
582 struct sram_channel *channel = &dev->sram_channels[chan_num];
583 int singlefield_lines = NTSC_FIELD_HEIGHT;
584 int line_size_in_bytes = Y422_LINE_SZ;
585 int odd_risc_prog_size = 0;
586 dma_addr_t risc_phys_jump_addr;
587 __le32 *rp;
588
589 if (status & FLD_VID_SRC_RISC1) {
590 // We should only process one program per call
591 u32 prog_cnt = cx_read(channel->gpcnt);
592
593 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
596 cx_write(channel->int_stat, _intr_msk);
597
598 spin_lock(&dev->slock);
599
600 dev->_frame_index = prog_cnt;
601
602 queue_work(dev->_irq_queues, &dev->_irq_work_entry);
603
604 if (dev->_is_first_frame) {
605 dev->_is_first_frame = 0;
606
607 if (dev->_isNTSC) {
608 singlefield_lines += 1;
609 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
610 } else {
611 singlefield_lines = PAL_FIELD_HEIGHT;
612 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
613 }
614
615 if (dev->_dma_virt_start_addr != NULL) {
616 line_size_in_bytes =
617 (dev->_pixel_format ==
618 PIXEL_FRMT_411) ? Y411_LINE_SZ :
619 Y422_LINE_SZ;
620 risc_phys_jump_addr =
621 dev->_dma_phys_start_addr +
622 odd_risc_prog_size;
623
624 rp = cx25821_update_riscprogram(dev,
625 dev->
626 _dma_virt_start_addr,
627 TOP_OFFSET,
628 line_size_in_bytes,
629 0x0,
630 singlefield_lines,
631 FIFO_DISABLE,
632 ODD_FIELD);
633
634 // Jump to Even Risc program of 1st Frame
635 *(rp++) = cpu_to_le32(RISC_JUMP);
636 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
637 *(rp++) = cpu_to_le32(0);
638 }
639 }
640
641 spin_unlock(&dev->slock);
642 } else {
643 if (status & FLD_VID_SRC_UF)
644 printk
645 ("%s: Video Received Underflow Error Interrupt!\n",
646 __func__);
647
648 if (status & FLD_VID_SRC_SYNC)
649 printk("%s: Video Received Sync Error Interrupt!\n",
650 __func__);
651
652 if (status & FLD_VID_SRC_OPC_ERR)
653 printk("%s: Video Received OpCode Error Interrupt!\n",
654 __func__);
655 }
656
657 if (dev->_file_status == END_OF_FILE) {
658 printk("cx25821: EOF Channel 1 Framecount = %d\n",
659 dev->_frame_count);
660 return -1;
661 }
662 //ElSE, set the interrupt mask register, re-enable irq.
663 int_msk_tmp = cx_read(channel->int_msk);
664 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
665
666 return 0;
667}
668
669static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
670{
671 struct cx25821_dev *dev = dev_id;
672 u32 msk_stat, vid_status;
673 int handled = 0;
674 int channel_num = 0;
675 struct sram_channel *sram_ch;
676
677 if (!dev)
678 return -1;
679
680 channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
681
682 sram_ch = &dev->sram_channels[channel_num];
683
684 msk_stat = cx_read(sram_ch->int_mstat);
685 vid_status = cx_read(sram_ch->int_stat);
686
687 // Only deal with our interrupt
688 if (vid_status) {
689 handled =
690 cx25821_video_upstream_irq(dev, channel_num, vid_status);
691 }
692
693 if (handled < 0) {
694 cx25821_stop_upstream_video_ch1(dev);
695 } else {
696 handled += handled;
697 }
698
699 return IRQ_RETVAL(handled);
700}
701
702void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
703 int pix_format)
704{
705 int width = WIDTH_D1;
706 int height = dev->_lines_count;
707 int num_lines, odd_num_lines;
708 u32 value;
709 int vip_mode = OUTPUT_FRMT_656;
710
711 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
712 value &= 0xFFFFFFEF;
713 value |= dev->_isNTSC ? 0 : 0x10;
714 cx_write(ch->vid_fmt_ctl, value);
715
716 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
717 cx_write(ch->vid_active_ctl1, width);
718
719 num_lines = (height / 2) & 0x3FF;
720 odd_num_lines = num_lines;
721
722 if (dev->_isNTSC) {
723 odd_num_lines += 1;
724 }
725
726 value = (num_lines << 16) | odd_num_lines;
727
728 // set number of active lines in field 0 (top) and field 1 (bottom)
729 cx_write(ch->vid_active_ctl2, value);
730
731 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
732}
733
734int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
735 struct sram_channel *sram_ch)
736{
737 u32 tmp = 0;
738 int err = 0;
739
740 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
741 tmp = cx_read(VID_CH_MODE_SEL);
742 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
743
744 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
745 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
746 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
747
748 /* reset counter */
749 cx_write(sram_ch->gpcnt_ctl, 3);
750
751 // Clear our bits from the interrupt status register.
752 cx_write(sram_ch->int_stat, _intr_msk);
753
754 //Set the interrupt mask register, enable irq.
755 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
756 tmp = cx_read(sram_ch->int_msk);
757 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
758
759 err =
760 request_irq(dev->pci->irq, cx25821_upstream_irq,
761 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
762 if (err < 0) {
763 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
764 dev->pci->irq);
765 goto fail_irq;
766 }
767
768 // Start the DMA engine
769 tmp = cx_read(sram_ch->dma_ctl);
770 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
771
772 dev->_is_running = 1;
773 dev->_is_first_frame = 1;
774
775 return 0;
776
777 fail_irq:
778 cx25821_dev_unregister(dev);
779 return err;
780}
781
782int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
783 int pixel_format)
784{
785 struct sram_channel *sram_ch;
786 u32 tmp;
787 int retval = 0;
788 int err = 0;
789 int data_frame_size = 0;
790 int risc_buffer_size = 0;
791 int str_length = 0;
792
793 if (dev->_is_running) {
794 printk("Video Channel is still running so return!\n");
795 return 0;
796 }
797
798 dev->_channel_upstream_select = channel_select;
799 sram_ch = &dev->sram_channels[channel_select];
800
801 INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
802 dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
803
804 if (!dev->_irq_queues) {
805 printk
806 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
807 return -ENOMEM;
808 }
809 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
810 tmp = cx_read(VID_CH_MODE_SEL);
811 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
812
813 dev->_is_running = 0;
814 dev->_frame_count = 0;
815 dev->_file_status = RESET_STATUS;
816 dev->_lines_count = dev->_isNTSC ? 480 : 576;
817 dev->_pixel_format = pixel_format;
818 dev->_line_size =
819 (dev->_pixel_format ==
820 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
821 data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
822 risc_buffer_size =
823 dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
824
825 if (dev->input_filename) {
826 str_length = strlen(dev->input_filename);
827 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
828
829 if (!dev->_filename)
830 goto error;
831
832 memcpy(dev->_filename, dev->input_filename, str_length + 1);
833 } else {
834 str_length = strlen(dev->_defaultname);
835 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
836
837 if (!dev->_filename)
838 goto error;
839
840 memcpy(dev->_filename, dev->_defaultname, str_length + 1);
841 }
842
843 //Default if filename is empty string
844 if (strcmp(dev->input_filename, "") == 0) {
845 if (dev->_isNTSC) {
846 dev->_filename =
847 (dev->_pixel_format ==
848 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
849 "/root/vidtest.yuv";
850 } else {
851 dev->_filename =
852 (dev->_pixel_format ==
853 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
854 "/root/pal422.yuv";
855 }
856 }
857
858 dev->_is_running = 0;
859 dev->_frame_count = 0;
860 dev->_file_status = RESET_STATUS;
861 dev->_lines_count = dev->_isNTSC ? 480 : 576;
862 dev->_pixel_format = pixel_format;
863 dev->_line_size =
864 (dev->_pixel_format ==
865 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
866
867 retval =
868 cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
869 0);
870
871 /* setup fifo + format */
872 cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
873
874 dev->upstream_riscbuf_size = risc_buffer_size * 2;
875 dev->upstream_databuf_size = data_frame_size * 2;
876
877 //Allocating buffers and prepare RISC program
878 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
879 if (retval < 0) {
880 printk(KERN_ERR
881 "%s: Failed to set up Video upstream buffers!\n",
882 dev->name);
883 goto error;
884 }
885
886 cx25821_start_video_dma_upstream(dev, sram_ch);
887
888 return 0;
889
890 error:
891 cx25821_dev_unregister(dev);
892
893 return err;
894}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
new file mode 100644
index 000000000000..cc9f93842514
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -0,0 +1,109 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define OUTPUT_FRMT_656 0
27#define OPEN_FILE_1 0
28#define NUM_PROGS 8
29#define NUM_FRAMES 2
30#define ODD_FIELD 0
31#define EVEN_FIELD 1
32#define TOP_OFFSET 0
33#define FIFO_DISABLE 0
34#define FIFO_ENABLE 1
35#define TEST_FRAMES 5
36#define END_OF_FILE 0
37#define IN_PROGRESS 1
38#define RESET_STATUS -1
39#define NUM_NO_OPS 5
40
41// PAL and NTSC line sizes and number of lines.
42#define WIDTH_D1 720
43#define NTSC_LINES_PER_FRAME 480
44#define PAL_LINES_PER_FRAME 576
45#define PAL_LINE_SZ 1440
46#define Y422_LINE_SZ 1440
47#define Y411_LINE_SZ 1080
48#define NTSC_FIELD_HEIGHT 240
49#define NTSC_ODD_FLD_LINES 241
50#define PAL_FIELD_HEIGHT 288
51
52#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
53#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
54#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
55#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
56
57#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
58#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
59
60#define RISC_WRITECR_INSTRUCTION_SIZE 16
61#define RISC_SYNC_INSTRUCTION_SIZE 4
62#define JUMP_INSTRUCTION_SIZE 12
63#define MAXSIZE_NO_OPS 36
64#define DWORD_SIZE 4
65
66#define USE_RISC_NOOP_VIDEO 1
67
68#ifdef USE_RISC_NOOP_VIDEO
69#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
70 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
71
72#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
73
74#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
75 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
76
77#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
78 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
79
80#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
81 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
82
83#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
84 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
85
86#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
87
88#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
89 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
90
91#endif
92
93#ifndef USE_RISC_NOOP_VIDEO
94#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
95 RISC_SYNC_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
96
97#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
98
99#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101
102#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
103#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
104
105#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
106#define NTSC_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
107#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
108 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
109#endif
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
new file mode 100644
index 000000000000..8834bc80a5ab
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -0,0 +1,1299 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
27MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
28MODULE_LICENSE("GPL");
29
30static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
31static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
32
33module_param_array(video_nr, int, NULL, 0444);
34module_param_array(radio_nr, int, NULL, 0444);
35
36MODULE_PARM_DESC(video_nr, "video device numbers");
37MODULE_PARM_DESC(radio_nr, "radio device numbers");
38
39static unsigned int video_debug = VIDEO_DEBUG;
40module_param(video_debug, int, 0644);
41MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
42
43static unsigned int irq_debug;
44module_param(irq_debug, int, 0644);
45MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
46
47unsigned int vid_limit = 16;
48module_param(vid_limit, int, 0644);
49MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
50
51static void init_controls(struct cx25821_dev *dev, int chan_num);
52
53#define FORMAT_FLAGS_PACKED 0x01
54
55struct cx25821_fmt formats[] = {
56 {
57 .name = "8 bpp, gray",
58 .fourcc = V4L2_PIX_FMT_GREY,
59 .depth = 8,
60 .flags = FORMAT_FLAGS_PACKED,
61 }, {
62 .name = "4:1:1, packed, Y41P",
63 .fourcc = V4L2_PIX_FMT_Y41P,
64 .depth = 12,
65 .flags = FORMAT_FLAGS_PACKED,
66 }, {
67 .name = "4:2:2, packed, YUYV",
68 .fourcc = V4L2_PIX_FMT_YUYV,
69 .depth = 16,
70 .flags = FORMAT_FLAGS_PACKED,
71 }, {
72 .name = "4:2:2, packed, UYVY",
73 .fourcc = V4L2_PIX_FMT_UYVY,
74 .depth = 16,
75 .flags = FORMAT_FLAGS_PACKED,
76 }, {
77 .name = "4:2:0, YUV",
78 .fourcc = V4L2_PIX_FMT_YUV420,
79 .depth = 12,
80 .flags = FORMAT_FLAGS_PACKED,
81 },
82};
83
84int get_format_size(void)
85{
86 return ARRAY_SIZE(formats);
87}
88
89struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
90{
91 unsigned int i;
92
93 if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
94 return formats + 1;
95 }
96
97 for (i = 0; i < ARRAY_SIZE(formats); i++)
98 if (formats[i].fourcc == fourcc)
99 return formats + i;
100
101 printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
102 return NULL;
103}
104
105void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
106{
107 struct cx25821_buffer *buf;
108 struct list_head *item;
109 dprintk(1, "%s()\n", __func__);
110
111 if (!list_empty(&q->active)) {
112 list_for_each(item, &q->active)
113 buf = list_entry(item, struct cx25821_buffer, vb.queue);
114 }
115
116 if (!list_empty(&q->queued)) {
117 list_for_each(item, &q->queued)
118 buf = list_entry(item, struct cx25821_buffer, vb.queue);
119 }
120
121}
122
123void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
124 u32 count)
125{
126 struct cx25821_buffer *buf;
127 int bc;
128
129 for (bc = 0;; bc++) {
130 if (list_empty(&q->active)) {
131 dprintk(1, "bc=%d (=0: active empty)\n", bc);
132 break;
133 }
134
135 buf =
136 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
137
138 /* count comes from the hw and it is 16bit wide --
139 * this trick handles wrap-arounds correctly for
140 * up to 32767 buffers in flight... */
141 if ((s16) (count - buf->count) < 0) {
142 break;
143 }
144
145 do_gettimeofday(&buf->vb.ts);
146 buf->vb.state = VIDEOBUF_DONE;
147 list_del(&buf->vb.queue);
148 wake_up(&buf->vb.done);
149 }
150
151 if (list_empty(&q->active))
152 del_timer(&q->timeout);
153 else
154 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
155 if (bc != 1)
156 printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
157 __func__, bc);
158}
159
160#ifdef TUNER_FLAG
161int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
162{
163 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
164 (unsigned int)norm, v4l2_norm_to_name(norm));
165
166 dev->tvnorm = norm;
167
168 /* Tell the internal A/V decoder */
169 cx25821_call_all(dev, core, s_std, norm);
170
171 return 0;
172}
173#endif
174
175struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
176 struct pci_dev *pci,
177 struct video_device *template,
178 char *type)
179{
180 struct video_device *vfd;
181 dprintk(1, "%s()\n", __func__);
182
183 vfd = video_device_alloc();
184 if (NULL == vfd)
185 return NULL;
186 *vfd = *template;
187 vfd->minor = -1;
188 vfd->v4l2_dev = &dev->v4l2_dev;
189 vfd->release = video_device_release;
190 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
191 cx25821_boards[dev->board].name);
192 return vfd;
193}
194
195/*
196static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
197{
198 int i;
199
200 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
201 return -EINVAL;
202 for (i = 0; i < CX25821_CTLS; i++)
203 if (cx25821_ctls[i].v.id == qctrl->id)
204 break;
205 if (i == CX25821_CTLS) {
206 *qctrl = no_ctl;
207 return 0;
208 }
209 *qctrl = cx25821_ctls[i].v;
210 return 0;
211}
212*/
213
214// resource management
215int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
216{
217 dprintk(1, "%s()\n", __func__);
218 if (fh->resources & bit)
219 /* have it already allocated */
220 return 1;
221
222 /* is it free? */
223 mutex_lock(&dev->lock);
224 if (dev->resources & bit) {
225 /* no, someone else uses it */
226 mutex_unlock(&dev->lock);
227 return 0;
228 }
229 /* it's free, grab it */
230 fh->resources |= bit;
231 dev->resources |= bit;
232 dprintk(1, "res: get %d\n", bit);
233 mutex_unlock(&dev->lock);
234 return 1;
235}
236
237int res_check(struct cx25821_fh *fh, unsigned int bit)
238{
239 return fh->resources & bit;
240}
241
242int res_locked(struct cx25821_dev *dev, unsigned int bit)
243{
244 return dev->resources & bit;
245}
246
247void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
248{
249 BUG_ON((fh->resources & bits) != bits);
250 dprintk(1, "%s()\n", __func__);
251
252 mutex_lock(&dev->lock);
253 fh->resources &= ~bits;
254 dev->resources &= ~bits;
255 dprintk(1, "res: put %d\n", bits);
256 mutex_unlock(&dev->lock);
257}
258
259int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
260{
261 struct v4l2_routing route;
262 memset(&route, 0, sizeof(route));
263
264 dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
265 __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
266 INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
267 dev->input = input;
268
269 route.input = INPUT(input)->vmux;
270
271 /* Tell the internal A/V decoder */
272 cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
273
274 return 0;
275}
276
277int cx25821_start_video_dma(struct cx25821_dev *dev,
278 struct cx25821_dmaqueue *q,
279 struct cx25821_buffer *buf,
280 struct sram_channel *channel)
281{
282 int tmp = 0;
283
284 /* setup fifo + format */
285 cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
286
287 /* reset counter */
288 cx_write(channel->gpcnt_ctl, 3);
289 q->count = 1;
290
291 /* enable irq */
292 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
293 cx_set(channel->int_msk, 0x11);
294
295 /* start dma */
296 cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */
297
298 /* make sure upstream setting if any is reversed */
299 tmp = cx_read(VID_CH_MODE_SEL);
300 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
301
302 return 0;
303}
304
305int cx25821_restart_video_queue(struct cx25821_dev *dev,
306 struct cx25821_dmaqueue *q,
307 struct sram_channel *channel)
308{
309 struct cx25821_buffer *buf, *prev;
310 struct list_head *item;
311
312 if (!list_empty(&q->active)) {
313 buf =
314 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
315
316 cx25821_start_video_dma(dev, q, buf, channel);
317
318 list_for_each(item, &q->active) {
319 buf = list_entry(item, struct cx25821_buffer, vb.queue);
320 buf->count = q->count++;
321 }
322
323 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
324 return 0;
325 }
326
327 prev = NULL;
328 for (;;) {
329 if (list_empty(&q->queued))
330 return 0;
331
332 buf =
333 list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
334
335 if (NULL == prev) {
336 list_move_tail(&buf->vb.queue, &q->active);
337 cx25821_start_video_dma(dev, q, buf, channel);
338 buf->vb.state = VIDEOBUF_ACTIVE;
339 buf->count = q->count++;
340 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
341 } else if (prev->vb.width == buf->vb.width &&
342 prev->vb.height == buf->vb.height &&
343 prev->fmt == buf->fmt) {
344 list_move_tail(&buf->vb.queue, &q->active);
345 buf->vb.state = VIDEOBUF_ACTIVE;
346 buf->count = q->count++;
347 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
348 prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
349 } else {
350 return 0;
351 }
352 prev = buf;
353 }
354}
355
356void cx25821_vid_timeout(unsigned long data)
357{
358 struct cx25821_data *timeout_data = (struct cx25821_data *)data;
359 struct cx25821_dev *dev = timeout_data->dev;
360 struct sram_channel *channel = timeout_data->channel;
361 struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
362 struct cx25821_buffer *buf;
363 unsigned long flags;
364
365 //cx25821_sram_channel_dump(dev, channel);
366 cx_clear(channel->dma_ctl, 0x11);
367
368 spin_lock_irqsave(&dev->slock, flags);
369 while (!list_empty(&q->active)) {
370 buf =
371 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
372 list_del(&buf->vb.queue);
373
374 buf->vb.state = VIDEOBUF_ERROR;
375 wake_up(&buf->vb.done);
376 }
377
378 cx25821_restart_video_queue(dev, q, channel);
379 spin_unlock_irqrestore(&dev->slock, flags);
380}
381
382int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
383{
384 u32 count = 0;
385 int handled = 0;
386 u32 mask;
387 struct sram_channel *channel = &dev->sram_channels[chan_num];
388
389 mask = cx_read(channel->int_msk);
390 if (0 == (status & mask))
391 return handled;
392
393 cx_write(channel->int_stat, status);
394
395 /* risc op code error */
396 if (status & (1 << 16)) {
397 printk(KERN_WARNING "%s, %s: video risc op code error\n",
398 dev->name, channel->name);
399 cx_clear(channel->dma_ctl, 0x11);
400 cx25821_sram_channel_dump(dev, channel);
401 }
402
403 /* risc1 y */
404 if (status & FLD_VID_DST_RISC1) {
405 spin_lock(&dev->slock);
406 count = cx_read(channel->gpcnt);
407 cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
408 spin_unlock(&dev->slock);
409 handled++;
410 }
411
412 /* risc2 y */
413 if (status & 0x10) {
414 dprintk(2, "stopper video\n");
415 spin_lock(&dev->slock);
416 cx25821_restart_video_queue(dev, &dev->vidq[channel->i],
417 channel);
418 spin_unlock(&dev->slock);
419 handled++;
420 }
421 return handled;
422}
423
424void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
425{
426 if (dev->ioctl_dev) {
427 if (dev->ioctl_dev->minor != -1)
428 video_unregister_device(dev->ioctl_dev);
429 else
430 video_device_release(dev->ioctl_dev);
431
432 dev->ioctl_dev = NULL;
433 }
434}
435
436void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
437{
438 cx_clear(PCI_INT_MSK, 1);
439
440 if (dev->video_dev[chan_num]) {
441 if (-1 != dev->video_dev[chan_num]->minor)
442 video_unregister_device(dev->video_dev[chan_num]);
443 else
444 video_device_release(dev->video_dev[chan_num]);
445
446 dev->video_dev[chan_num] = NULL;
447
448 btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
449
450 printk(KERN_WARNING "device %d released!\n", chan_num);
451 }
452
453}
454
455int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
456 struct video_device *video_template)
457{
458 int err;
459
460 spin_lock_init(&dev->slock);
461
462 //printk(KERN_WARNING "Channel %d\n", chan_num);
463
464#ifdef TUNER_FLAG
465 dev->tvnorm = video_template->current_norm;
466#endif
467
468 /* init video dma queues */
469 dev->timeout_data[chan_num].dev = dev;
470 dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
471 INIT_LIST_HEAD(&dev->vidq[chan_num].active);
472 INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
473 dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
474 dev->vidq[chan_num].timeout.data =
475 (unsigned long)&dev->timeout_data[chan_num];
476 init_timer(&dev->vidq[chan_num].timeout);
477 cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
478 dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
479
480 /* register v4l devices */
481 dev->video_dev[chan_num] =
482 cx25821_vdev_init(dev, dev->pci, video_template, "video");
483 err =
484 video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
485 video_nr[dev->nr]);
486
487 if (err < 0) {
488 goto fail_unreg;
489 }
490 //set PCI interrupt
491 cx_set(PCI_INT_MSK, 0xff);
492
493 /* initial device configuration */
494 mutex_lock(&dev->lock);
495#ifdef TUNER_FLAG
496 cx25821_set_tvnorm(dev, dev->tvnorm);
497#endif
498 mutex_unlock(&dev->lock);
499
500 init_controls(dev, chan_num);
501
502 return 0;
503
504 fail_unreg:
505 cx25821_video_unregister(dev, chan_num);
506 return err;
507}
508
509int buffer_setup(struct videobuf_queue *q, unsigned int *count,
510 unsigned int *size)
511{
512 struct cx25821_fh *fh = q->priv_data;
513
514 *size = fh->fmt->depth * fh->width * fh->height >> 3;
515
516 if (0 == *count)
517 *count = 32;
518
519 while (*size * *count > vid_limit * 1024 * 1024)
520 (*count)--;
521
522 return 0;
523}
524
525int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
526 enum v4l2_field field)
527{
528 struct cx25821_fh *fh = q->priv_data;
529 struct cx25821_dev *dev = fh->dev;
530 struct cx25821_buffer *buf =
531 container_of(vb, struct cx25821_buffer, vb);
532 int rc, init_buffer = 0;
533 u32 line0_offset, line1_offset;
534 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
535 int bpl_local = LINE_SIZE_D1;
536 int channel_opened = 0;
537
538 BUG_ON(NULL == fh->fmt);
539 if (fh->width < 48 || fh->width > 720 ||
540 fh->height < 32 || fh->height > 576)
541 return -EINVAL;
542
543 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
544
545 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
546 return -EINVAL;
547
548 if (buf->fmt != fh->fmt ||
549 buf->vb.width != fh->width ||
550 buf->vb.height != fh->height || buf->vb.field != field) {
551 buf->fmt = fh->fmt;
552 buf->vb.width = fh->width;
553 buf->vb.height = fh->height;
554 buf->vb.field = field;
555 init_buffer = 1;
556 }
557
558 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
559 init_buffer = 1;
560 rc = videobuf_iolock(q, &buf->vb, NULL);
561 if (0 != rc) {
562 printk(KERN_DEBUG "videobuf_iolock failed!\n");
563 goto fail;
564 }
565 }
566
567 dprintk(1, "init_buffer=%d\n", init_buffer);
568
569 if (init_buffer) {
570
571 channel_opened = dev->channel_opened;
572 channel_opened = (channel_opened < 0
573 || channel_opened > 7) ? 7 : channel_opened;
574
575 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
576 buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
577 else
578 buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
579
580 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
581 bpl_local = buf->bpl;
582 } else {
583 bpl_local = buf->bpl; //Default
584
585 if (channel_opened >= 0 && channel_opened <= 7) {
586 if (dev->use_cif_resolution[channel_opened]) {
587 if (dev->tvnorm & V4L2_STD_PAL_BG
588 || dev->tvnorm & V4L2_STD_PAL_DK)
589 bpl_local = 352 << 1;
590 else
591 bpl_local =
592 dev->
593 cif_width[channel_opened] <<
594 1;
595 }
596 }
597 }
598
599 switch (buf->vb.field) {
600 case V4L2_FIELD_TOP:
601 cx25821_risc_buffer(dev->pci, &buf->risc,
602 dma->sglist, 0, UNSET,
603 buf->bpl, 0, buf->vb.height);
604 break;
605 case V4L2_FIELD_BOTTOM:
606 cx25821_risc_buffer(dev->pci, &buf->risc,
607 dma->sglist, UNSET, 0,
608 buf->bpl, 0, buf->vb.height);
609 break;
610 case V4L2_FIELD_INTERLACED:
611 /* All other formats are top field first */
612 line0_offset = 0;
613 line1_offset = buf->bpl;
614 dprintk(1, "top field first\n");
615
616 cx25821_risc_buffer(dev->pci, &buf->risc,
617 dma->sglist, line0_offset,
618 bpl_local, bpl_local, bpl_local,
619 buf->vb.height >> 1);
620 break;
621 case V4L2_FIELD_SEQ_TB:
622 cx25821_risc_buffer(dev->pci, &buf->risc,
623 dma->sglist,
624 0, buf->bpl * (buf->vb.height >> 1),
625 buf->bpl, 0, buf->vb.height >> 1);
626 break;
627 case V4L2_FIELD_SEQ_BT:
628 cx25821_risc_buffer(dev->pci, &buf->risc,
629 dma->sglist,
630 buf->bpl * (buf->vb.height >> 1), 0,
631 buf->bpl, 0, buf->vb.height >> 1);
632 break;
633 default:
634 BUG();
635 }
636 }
637
638 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
639 buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
640 fh->fmt->name, (unsigned long)buf->risc.dma);
641
642 buf->vb.state = VIDEOBUF_PREPARED;
643
644 return 0;
645
646 fail:
647 cx25821_free_buffer(q, buf);
648 return rc;
649}
650
651void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
652{
653 struct cx25821_buffer *buf =
654 container_of(vb, struct cx25821_buffer, vb);
655
656 cx25821_free_buffer(q, buf);
657}
658
659struct videobuf_queue *get_queue(struct cx25821_fh *fh)
660{
661 switch (fh->type) {
662 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
663 return &fh->vidq;
664 default:
665 BUG();
666 return NULL;
667 }
668}
669
670int get_resource(struct cx25821_fh *fh, int resource)
671{
672 switch (fh->type) {
673 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
674 return resource;
675 default:
676 BUG();
677 return 0;
678 }
679}
680
681int video_mmap(struct file *file, struct vm_area_struct *vma)
682{
683 struct cx25821_fh *fh = file->private_data;
684
685 return videobuf_mmap_mapper(get_queue(fh), vma);
686}
687
688/* VIDEO IOCTLS */
689int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
690{
691 struct cx25821_fh *fh = priv;
692
693 f->fmt.pix.width = fh->width;
694 f->fmt.pix.height = fh->height;
695 f->fmt.pix.field = fh->vidq.field;
696 f->fmt.pix.pixelformat = fh->fmt->fourcc;
697 f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
698 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
699
700 return 0;
701}
702
703int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
704{
705 struct cx25821_fmt *fmt;
706 enum v4l2_field field;
707 unsigned int maxw, maxh;
708
709 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
710 if (NULL == fmt)
711 return -EINVAL;
712
713 field = f->fmt.pix.field;
714 maxw = 720;
715 maxh = 576;
716
717 if (V4L2_FIELD_ANY == field) {
718 field = (f->fmt.pix.height > maxh / 2)
719 ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
720 }
721
722 switch (field) {
723 case V4L2_FIELD_TOP:
724 case V4L2_FIELD_BOTTOM:
725 maxh = maxh / 2;
726 break;
727 case V4L2_FIELD_INTERLACED:
728 break;
729 default:
730 return -EINVAL;
731 }
732
733 f->fmt.pix.field = field;
734 if (f->fmt.pix.height < 32)
735 f->fmt.pix.height = 32;
736 if (f->fmt.pix.height > maxh)
737 f->fmt.pix.height = maxh;
738 if (f->fmt.pix.width < 48)
739 f->fmt.pix.width = 48;
740 if (f->fmt.pix.width > maxw)
741 f->fmt.pix.width = maxw;
742 f->fmt.pix.width &= ~0x03;
743 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
744 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
745
746 return 0;
747}
748
749int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
750{
751 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
752
753 strcpy(cap->driver, "cx25821");
754 strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
755 sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
756 cap->version = CX25821_VERSION_CODE;
757 cap->capabilities =
758 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
759 if (UNSET != dev->tuner_type)
760 cap->capabilities |= V4L2_CAP_TUNER;
761 return 0;
762}
763
764int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
765 struct v4l2_fmtdesc *f)
766{
767 if (unlikely(f->index >= ARRAY_SIZE(formats)))
768 return -EINVAL;
769
770 strlcpy(f->description, formats[f->index].name, sizeof(f->description));
771 f->pixelformat = formats[f->index].fourcc;
772
773 return 0;
774}
775
776#ifdef CONFIG_VIDEO_V4L1_COMPAT
777int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
778{
779 struct cx25821_fh *fh = priv;
780 struct videobuf_queue *q;
781 struct v4l2_requestbuffers req;
782 unsigned int i;
783 int err;
784
785 q = get_queue(fh);
786 memset(&req, 0, sizeof(req));
787 req.type = q->type;
788 req.count = 8;
789 req.memory = V4L2_MEMORY_MMAP;
790 err = videobuf_reqbufs(q, &req);
791 if (err < 0)
792 return err;
793
794 mbuf->frames = req.count;
795 mbuf->size = 0;
796 for (i = 0; i < mbuf->frames; i++) {
797 mbuf->offsets[i] = q->bufs[i]->boff;
798 mbuf->size += q->bufs[i]->bsize;
799 }
800 return 0;
801}
802#endif
803
804int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
805{
806 struct cx25821_fh *fh = priv;
807 return videobuf_reqbufs(get_queue(fh), p);
808}
809
810int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
811{
812 struct cx25821_fh *fh = priv;
813 return videobuf_querybuf(get_queue(fh), p);
814}
815
816int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
817{
818 struct cx25821_fh *fh = priv;
819 return videobuf_qbuf(get_queue(fh), p);
820}
821
822int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
823{
824 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
825
826 *p = v4l2_prio_max(&dev->prio);
827
828 return 0;
829}
830
831int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
832{
833 struct cx25821_fh *fh = f;
834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
835
836 return v4l2_prio_change(&dev->prio, &fh->prio, prio);
837}
838
839#ifdef TUNER_FLAG
840int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
841{
842 struct cx25821_fh *fh = priv;
843 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
844 int err;
845
846 dprintk(1, "%s()\n", __func__);
847
848 if (fh) {
849 err = v4l2_prio_check(&dev->prio, &fh->prio);
850 if (0 != err)
851 return err;
852 }
853
854 if (dev->tvnorm == *tvnorms) {
855 return 0;
856 }
857
858 mutex_lock(&dev->lock);
859 cx25821_set_tvnorm(dev, *tvnorms);
860 mutex_unlock(&dev->lock);
861
862 medusa_set_videostandard(dev);
863
864 return 0;
865}
866#endif
867
868int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
869{
870 static const char *iname[] = {
871 [CX25821_VMUX_COMPOSITE] = "Composite",
872 [CX25821_VMUX_SVIDEO] = "S-Video",
873 [CX25821_VMUX_DEBUG] = "for debug only",
874 };
875 unsigned int n;
876 dprintk(1, "%s()\n", __func__);
877
878 n = i->index;
879 if (n > 2)
880 return -EINVAL;
881
882 if (0 == INPUT(n)->type)
883 return -EINVAL;
884
885 memset(i, 0, sizeof(*i));
886 i->index = n;
887 i->type = V4L2_INPUT_TYPE_CAMERA;
888 strcpy(i->name, iname[INPUT(n)->type]);
889
890 i->std = CX25821_NORMS;
891 return 0;
892}
893
894int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
895{
896 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
897 dprintk(1, "%s()\n", __func__);
898 return cx25821_enum_input(dev, i);
899}
900
901int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
902{
903 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
904
905 *i = dev->input;
906 dprintk(1, "%s() returns %d\n", __func__, *i);
907 return 0;
908}
909
910int vidioc_s_input(struct file *file, void *priv, unsigned int i)
911{
912 struct cx25821_fh *fh = priv;
913 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
914 int err;
915
916 dprintk(1, "%s(%d)\n", __func__, i);
917
918 if (fh) {
919 err = v4l2_prio_check(&dev->prio, &fh->prio);
920 if (0 != err)
921 return err;
922 }
923
924 if (i > 2) {
925 dprintk(1, "%s() -EINVAL\n", __func__);
926 return -EINVAL;
927 }
928
929 mutex_lock(&dev->lock);
930 cx25821_video_mux(dev, i);
931 mutex_unlock(&dev->lock);
932 return 0;
933}
934
935#ifdef TUNER_FLAG
936int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
937{
938 struct cx25821_fh *fh = priv;
939 struct cx25821_dev *dev = fh->dev;
940
941 f->frequency = dev->freq;
942
943 cx25821_call_all(dev, tuner, g_frequency, f);
944
945 return 0;
946}
947
948int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
949{
950 mutex_lock(&dev->lock);
951 dev->freq = f->frequency;
952
953 cx25821_call_all(dev, tuner, s_frequency, f);
954
955 /* When changing channels it is required to reset TVAUDIO */
956 msleep(10);
957
958 mutex_unlock(&dev->lock);
959
960 return 0;
961}
962
963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
964{
965 struct cx25821_fh *fh = priv;
966 struct cx25821_dev *dev = fh->dev;
967 int err;
968
969 if (fh) {
970 err = v4l2_prio_check(&dev->prio, &fh->prio);
971 if (0 != err)
972 return err;
973 }
974
975 return cx25821_set_freq(dev, f);
976}
977#endif
978
979#ifdef CONFIG_VIDEO_ADV_DEBUG
980int vidioc_g_register(struct file *file, void *fh,
981 struct v4l2_dbg_register *reg)
982{
983 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
984
985 if (!v4l2_chip_match_host(&reg->match))
986 return -EINVAL;
987
988 cx25821_call_all(dev, core, g_register, reg);
989
990 return 0;
991}
992
993int vidioc_s_register(struct file *file, void *fh,
994 struct v4l2_dbg_register *reg)
995{
996 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
997
998 if (!v4l2_chip_match_host(&reg->match))
999 return -EINVAL;
1000
1001 cx25821_call_all(dev, core, s_register, reg);
1002
1003 return 0;
1004}
1005
1006#endif
1007
1008#ifdef TUNER_FLAG
1009int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1010{
1011 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1012
1013 if (unlikely(UNSET == dev->tuner_type))
1014 return -EINVAL;
1015 if (0 != t->index)
1016 return -EINVAL;
1017
1018 strcpy(t->name, "Television");
1019 t->type = V4L2_TUNER_ANALOG_TV;
1020 t->capability = V4L2_TUNER_CAP_NORM;
1021 t->rangehigh = 0xffffffffUL;
1022
1023 t->signal = 0xffff; /* LOCKED */
1024 return 0;
1025}
1026
1027int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1028{
1029 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1030 struct cx25821_fh *fh = priv;
1031 int err;
1032
1033 if (fh) {
1034 err = v4l2_prio_check(&dev->prio, &fh->prio);
1035 if (0 != err)
1036 return err;
1037 }
1038
1039 dprintk(1, "%s()\n", __func__);
1040 if (UNSET == dev->tuner_type)
1041 return -EINVAL;
1042 if (0 != t->index)
1043 return -EINVAL;
1044
1045 return 0;
1046}
1047
1048#endif
1049// ******************************************************************************************
1050static const struct v4l2_queryctrl no_ctl = {
1051 .name = "42",
1052 .flags = V4L2_CTRL_FLAG_DISABLED,
1053};
1054
1055static struct v4l2_queryctrl cx25821_ctls[] = {
1056 /* --- video --- */
1057 {
1058 .id = V4L2_CID_BRIGHTNESS,
1059 .name = "Brightness",
1060 .minimum = 0,
1061 .maximum = 10000,
1062 .step = 1,
1063 .default_value = 6200,
1064 .type = V4L2_CTRL_TYPE_INTEGER,
1065 }, {
1066 .id = V4L2_CID_CONTRAST,
1067 .name = "Contrast",
1068 .minimum = 0,
1069 .maximum = 10000,
1070 .step = 1,
1071 .default_value = 5000,
1072 .type = V4L2_CTRL_TYPE_INTEGER,
1073 }, {
1074 .id = V4L2_CID_SATURATION,
1075 .name = "Saturation",
1076 .minimum = 0,
1077 .maximum = 10000,
1078 .step = 1,
1079 .default_value = 5000,
1080 .type = V4L2_CTRL_TYPE_INTEGER,
1081 }, {
1082 .id = V4L2_CID_HUE,
1083 .name = "Hue",
1084 .minimum = 0,
1085 .maximum = 10000,
1086 .step = 1,
1087 .default_value = 5000,
1088 .type = V4L2_CTRL_TYPE_INTEGER,
1089 }
1090};
1091static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1092
1093static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1094{
1095 int i;
1096
1097 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1098 return -EINVAL;
1099 for (i = 0; i < CX25821_CTLS; i++)
1100 if (cx25821_ctls[i].id == qctrl->id)
1101 break;
1102 if (i == CX25821_CTLS) {
1103 *qctrl = no_ctl;
1104 return 0;
1105 }
1106 *qctrl = cx25821_ctls[i];
1107 return 0;
1108}
1109
1110int vidioc_queryctrl(struct file *file, void *priv,
1111 struct v4l2_queryctrl *qctrl)
1112{
1113 return cx25821_ctrl_query(qctrl);
1114}
1115
1116/* ------------------------------------------------------------------ */
1117/* VIDEO CTRL IOCTLS */
1118
1119static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1120{
1121 unsigned int i;
1122
1123 for (i = 0; i < CX25821_CTLS; i++)
1124 if (cx25821_ctls[i].id == id)
1125 return cx25821_ctls + i;
1126 return NULL;
1127}
1128
1129int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1130{
1131 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1132
1133 const struct v4l2_queryctrl *ctrl;
1134
1135 ctrl = ctrl_by_id(ctl->id);
1136
1137 if (NULL == ctrl)
1138 return -EINVAL;
1139 switch (ctl->id) {
1140 case V4L2_CID_BRIGHTNESS:
1141 ctl->value = dev->ctl_bright;
1142 break;
1143 case V4L2_CID_HUE:
1144 ctl->value = dev->ctl_hue;
1145 break;
1146 case V4L2_CID_CONTRAST:
1147 ctl->value = dev->ctl_contrast;
1148 break;
1149 case V4L2_CID_SATURATION:
1150 ctl->value = dev->ctl_saturation;
1151 break;
1152 }
1153 return 0;
1154}
1155
1156int cx25821_set_control(struct cx25821_dev *dev,
1157 struct v4l2_control *ctl, int chan_num)
1158{
1159 int err;
1160 const struct v4l2_queryctrl *ctrl;
1161
1162 err = -EINVAL;
1163
1164 ctrl = ctrl_by_id(ctl->id);
1165
1166 if (NULL == ctrl)
1167 return err;
1168
1169 switch (ctrl->type) {
1170 case V4L2_CTRL_TYPE_BOOLEAN:
1171 case V4L2_CTRL_TYPE_MENU:
1172 case V4L2_CTRL_TYPE_INTEGER:
1173 if (ctl->value < ctrl->minimum)
1174 ctl->value = ctrl->minimum;
1175 if (ctl->value > ctrl->maximum)
1176 ctl->value = ctrl->maximum;
1177 break;
1178 default:
1179 /* nothing */ ;
1180 };
1181
1182 switch (ctl->id) {
1183 case V4L2_CID_BRIGHTNESS:
1184 dev->ctl_bright = ctl->value;
1185 medusa_set_brightness(dev, ctl->value, chan_num);
1186 break;
1187 case V4L2_CID_HUE:
1188 dev->ctl_hue = ctl->value;
1189 medusa_set_hue(dev, ctl->value, chan_num);
1190 break;
1191 case V4L2_CID_CONTRAST:
1192 dev->ctl_contrast = ctl->value;
1193 medusa_set_contrast(dev, ctl->value, chan_num);
1194 break;
1195 case V4L2_CID_SATURATION:
1196 dev->ctl_saturation = ctl->value;
1197 medusa_set_saturation(dev, ctl->value, chan_num);
1198 break;
1199 }
1200
1201 err = 0;
1202
1203 return err;
1204}
1205
1206static void init_controls(struct cx25821_dev *dev, int chan_num)
1207{
1208 struct v4l2_control ctrl;
1209 int i;
1210 for (i = 0; i < CX25821_CTLS; i++) {
1211 ctrl.id = cx25821_ctls[i].id;
1212 ctrl.value = cx25821_ctls[i].default_value;
1213
1214 cx25821_set_control(dev, &ctrl, chan_num);
1215 }
1216}
1217
1218int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1219{
1220 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1221
1222 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1223 return -EINVAL;
1224 cropcap->bounds.top = cropcap->bounds.left = 0;
1225 cropcap->bounds.width = 720;
1226 cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1227 cropcap->pixelaspect.numerator =
1228 dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1229 cropcap->pixelaspect.denominator =
1230 dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1231 cropcap->defrect = cropcap->bounds;
1232 return 0;
1233}
1234
1235int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1236{
1237 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1238 struct cx25821_fh *fh = priv;
1239 int err;
1240
1241 if (fh) {
1242 err = v4l2_prio_check(&dev->prio, &fh->prio);
1243 if (0 != err)
1244 return err;
1245 }
1246 // vidioc_s_crop not supported
1247 return -EINVAL;
1248}
1249
1250int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1251{
1252 // vidioc_g_crop not supported
1253 return -EINVAL;
1254}
1255
1256int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1257{
1258 // medusa does not support video standard sensing of current input
1259 *norm = CX25821_NORMS;
1260
1261 return 0;
1262}
1263
1264int is_valid_width(u32 width, v4l2_std_id tvnorm)
1265{
1266 if (tvnorm == V4L2_STD_PAL_BG) {
1267 if (width == 352 || width == 720)
1268 return 1;
1269 else
1270 return 0;
1271 }
1272
1273 if (tvnorm == V4L2_STD_NTSC_M) {
1274 if (width == 320 || width == 352 || width == 720)
1275 return 1;
1276 else
1277 return 0;
1278 }
1279 return 0;
1280}
1281
1282int is_valid_height(u32 height, v4l2_std_id tvnorm)
1283{
1284 if (tvnorm == V4L2_STD_PAL_BG) {
1285 if (height == 576 || height == 288)
1286 return 1;
1287 else
1288 return 0;
1289 }
1290
1291 if (tvnorm == V4L2_STD_NTSC_M) {
1292 if (height == 480 || height == 240)
1293 return 1;
1294 else
1295 return 0;
1296 }
1297
1298 return 0;
1299}
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
new file mode 100644
index 000000000000..4417ff5d90d4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -0,0 +1,194 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef CX25821_VIDEO_H_
25#define CX25821_VIDEO_H_
26
27#include <linux/init.h>
28#include <linux/list.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/kmod.h>
32#include <linux/kernel.h>
33#include <linux/slab.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/kthread.h>
37#include <asm/div64.h>
38
39#include "cx25821.h"
40#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h>
42
43#ifdef CONFIG_VIDEO_V4L1_COMPAT
44/* Include V4L1 specific functions. Should be removed soon */
45#include <linux/videodev.h>
46#endif
47
48#define TUNER_FLAG
49
50#define VIDEO_DEBUG 0
51
52#define dprintk(level, fmt, arg...)\
53 do { if (VIDEO_DEBUG >= level)\
54 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
55 } while (0)
56
57//For IOCTL to identify running upstream
58#define UPSTREAM_START_VIDEO 700
59#define UPSTREAM_STOP_VIDEO 701
60#define UPSTREAM_START_AUDIO 702
61#define UPSTREAM_STOP_AUDIO 703
62#define UPSTREAM_DUMP_REGISTERS 702
63#define SET_VIDEO_STD 800
64#define SET_PIXEL_FORMAT 1000
65#define ENABLE_CIF_RESOLUTION 1001
66
67#define REG_READ 900
68#define REG_WRITE 901
69#define MEDUSA_READ 910
70#define MEDUSA_WRITE 911
71
72extern struct sram_channel *channel0;
73extern struct sram_channel *channel1;
74extern struct sram_channel *channel2;
75extern struct sram_channel *channel3;
76extern struct sram_channel *channel4;
77extern struct sram_channel *channel5;
78extern struct sram_channel *channel6;
79extern struct sram_channel *channel7;
80extern struct sram_channel *channel9;
81extern struct sram_channel *channel10;
82extern struct sram_channel *channel11;
83extern struct video_device cx25821_video_template0;
84extern struct video_device cx25821_video_template1;
85extern struct video_device cx25821_video_template2;
86extern struct video_device cx25821_video_template3;
87extern struct video_device cx25821_video_template4;
88extern struct video_device cx25821_video_template5;
89extern struct video_device cx25821_video_template6;
90extern struct video_device cx25821_video_template7;
91extern struct video_device cx25821_video_template9;
92extern struct video_device cx25821_video_template10;
93extern struct video_device cx25821_video_template11;
94extern struct video_device cx25821_videoioctl_template;
95//extern const u32 *ctrl_classes[];
96
97extern unsigned int vid_limit;
98
99#define FORMAT_FLAGS_PACKED 0x01
100extern struct cx25821_fmt formats[];
101extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
102extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
103
104extern void dump_video_queue(struct cx25821_dev *dev,
105 struct cx25821_dmaqueue *q);
106extern void cx25821_video_wakeup(struct cx25821_dev *dev,
107 struct cx25821_dmaqueue *q, u32 count);
108
109#ifdef TUNER_FLAG
110extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
111#endif
112
113extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
114 unsigned int bit);
115extern int res_check(struct cx25821_fh *fh, unsigned int bit);
116extern int res_locked(struct cx25821_dev *dev, unsigned int bit);
117extern void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
118 unsigned int bits);
119extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
120extern int cx25821_start_video_dma(struct cx25821_dev *dev,
121 struct cx25821_dmaqueue *q,
122 struct cx25821_buffer *buf,
123 struct sram_channel *channel);
124
125extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
126 unsigned int height, enum v4l2_field field);
127extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
128extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
129extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
130 struct video_device *video_template);
131extern int get_format_size(void);
132
133extern int buffer_setup(struct videobuf_queue *q, unsigned int *count,
134 unsigned int *size);
135extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
136 enum v4l2_field field);
137extern void buffer_release(struct videobuf_queue *q,
138 struct videobuf_buffer *vb);
139extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
140extern int get_resource(struct cx25821_fh *fh, int resource);
141extern int video_mmap(struct file *file, struct vm_area_struct *vma);
142extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
143 struct v4l2_format *f);
144extern int vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *cap);
146extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
147 struct v4l2_fmtdesc *f);
148extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
149extern int vidioc_reqbufs(struct file *file, void *priv,
150 struct v4l2_requestbuffers *p);
151extern int vidioc_querybuf(struct file *file, void *priv,
152 struct v4l2_buffer *p);
153extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
154extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms);
155extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
156extern int vidioc_enum_input(struct file *file, void *priv,
157 struct v4l2_input *i);
158extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i);
159extern int vidioc_s_input(struct file *file, void *priv, unsigned int i);
160extern int vidioc_g_ctrl(struct file *file, void *priv,
161 struct v4l2_control *ctl);
162extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
163 struct v4l2_format *f);
164extern int vidioc_g_frequency(struct file *file, void *priv,
165 struct v4l2_frequency *f);
166extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
167extern int vidioc_s_frequency(struct file *file, void *priv,
168 struct v4l2_frequency *f);
169extern int vidioc_g_register(struct file *file, void *fh,
170 struct v4l2_dbg_register *reg);
171extern int vidioc_s_register(struct file *file, void *fh,
172 struct v4l2_dbg_register *reg);
173extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
174extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
175
176extern int is_valid_width(u32 width, v4l2_std_id tvnorm);
177extern int is_valid_height(u32 height, v4l2_std_id tvnorm);
178
179extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
180extern int vidioc_s_priority(struct file *file, void *f,
181 enum v4l2_priority prio);
182
183extern int vidioc_queryctrl(struct file *file, void *priv,
184 struct v4l2_queryctrl *qctrl);
185extern int cx25821_set_control(struct cx25821_dev *dev,
186 struct v4l2_control *ctrl, int chan_num);
187
188extern int vidioc_cropcap(struct file *file, void *fh,
189 struct v4l2_cropcap *cropcap);
190extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
191extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
192
193extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm);
194#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
new file mode 100644
index 000000000000..950fac1d7003
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH00];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH00]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH00]
109 && h->video_dev[SRAM_CH00]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH00;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO0))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO0)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH00]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO0)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO0);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0)))) {
259 return -EBUSY;
260 }
261
262 return videobuf_streamon(get_queue(fh));
263}
264
265static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
266{
267 struct cx25821_fh *fh = priv;
268 struct cx25821_dev *dev = fh->dev;
269 int err, res;
270
271 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
272 return -EINVAL;
273 if (i != fh->type)
274 return -EINVAL;
275
276 res = get_resource(fh, RESOURCE_VIDEO0);
277 err = videobuf_streamoff(get_queue(fh));
278 if (err < 0)
279 return err;
280 res_free(dev, fh, res);
281 return 0;
282}
283
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = PIXEL_FRMT_422;
291
292 if (fh) {
293 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH00] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH00] = 0;
330 }
331 dev->cif_width[SRAM_CH00] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH00);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH00].count;
350
351 return ret_val;
352}
353
354static int vidioc_log_status(struct file *file, void *priv)
355{
356 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
357 char name[32 + 2];
358
359 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH00];
360 u32 tmp = 0;
361
362 snprintf(name, sizeof(name), "%s/2", dev->name);
363 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
364 dev->name);
365 cx25821_call_all(dev, core, log_status);
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 0 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH00);
388}
389
390// exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template0 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
new file mode 100644
index 000000000000..a4dddc684adf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH01];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH01]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH01]
109 && h->video_dev[SRAM_CH01]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH01;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO1))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO1)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH01]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO1)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO1);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1)))) {
259 return -EBUSY;
260 }
261
262 return videobuf_streamon(get_queue(fh));
263}
264
265static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
266{
267 struct cx25821_fh *fh = priv;
268 struct cx25821_dev *dev = fh->dev;
269 int err, res;
270
271 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
272 return -EINVAL;
273 if (i != fh->type)
274 return -EINVAL;
275
276 res = get_resource(fh, RESOURCE_VIDEO1);
277 err = videobuf_streamoff(get_queue(fh));
278 if (err < 0)
279 return err;
280 res_free(dev, fh, res);
281 return 0;
282}
283
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = 0;
291
292 if (fh) {
293 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format(dev, SRAM_CH01, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH01] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH01] = 0;
330 }
331 dev->cif_width[SRAM_CH01] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH01);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH01].count;
350
351 return ret_val;
352}
353
354static int vidioc_log_status(struct file *file, void *priv)
355{
356 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
357 char name[32 + 2];
358
359 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH01];
360 u32 tmp = 0;
361
362 snprintf(name, sizeof(name), "%s/2", dev->name);
363 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
364 dev->name);
365 cx25821_call_all(dev, core, log_status);
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 1 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH01);
388}
389
390//exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template1 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
new file mode 100644
index 000000000000..8e04e253f5d9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -0,0 +1,452 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH02];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH02]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH02]
109 && h->video_dev[SRAM_CH02]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH02;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO2))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO2)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH02]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO2)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO2);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO2);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH02, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH02] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH02] = 0;
329 }
330 dev->cif_width[SRAM_CH02] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH02);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH02].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364
365 cx25821_call_all(dev, core, log_status);
366
367 tmp = cx_read(sram_ch->dma_ctl);
368 printk(KERN_INFO "Video input 2 is %s\n",
369 (tmp & 0x11) ? "streaming" : "stopped");
370 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
371 dev->name);
372 return 0;
373}
374
375static int vidioc_s_ctrl(struct file *file, void *priv,
376 struct v4l2_control *ctl)
377{
378 struct cx25821_fh *fh = priv;
379 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
380 int err;
381
382 if (fh) {
383 err = v4l2_prio_check(&dev->prio, &fh->prio);
384 if (0 != err)
385 return err;
386 }
387
388 return cx25821_set_control(dev, ctl, SRAM_CH02);
389}
390
391// exported stuff
392static const struct v4l2_file_operations video_fops = {
393 .owner = THIS_MODULE,
394 .open = video_open,
395 .release = video_release,
396 .read = video_read,
397 .poll = video_poll,
398 .mmap = video_mmap,
399 .ioctl = video_ioctl2,
400};
401
402static const struct v4l2_ioctl_ops video_ioctl_ops = {
403 .vidioc_querycap = vidioc_querycap,
404 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
405 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
406 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
407 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
408 .vidioc_reqbufs = vidioc_reqbufs,
409 .vidioc_querybuf = vidioc_querybuf,
410 .vidioc_qbuf = vidioc_qbuf,
411 .vidioc_dqbuf = vidioc_dqbuf,
412#ifdef TUNER_FLAG
413 .vidioc_s_std = vidioc_s_std,
414 .vidioc_querystd = vidioc_querystd,
415#endif
416 .vidioc_cropcap = vidioc_cropcap,
417 .vidioc_s_crop = vidioc_s_crop,
418 .vidioc_g_crop = vidioc_g_crop,
419 .vidioc_enum_input = vidioc_enum_input,
420 .vidioc_g_input = vidioc_g_input,
421 .vidioc_s_input = vidioc_s_input,
422 .vidioc_g_ctrl = vidioc_g_ctrl,
423 .vidioc_s_ctrl = vidioc_s_ctrl,
424 .vidioc_queryctrl = vidioc_queryctrl,
425 .vidioc_streamon = vidioc_streamon,
426 .vidioc_streamoff = vidioc_streamoff,
427 .vidioc_log_status = vidioc_log_status,
428 .vidioc_g_priority = vidioc_g_priority,
429 .vidioc_s_priority = vidioc_s_priority,
430#ifdef CONFIG_VIDEO_V4L1_COMPAT
431 .vidiocgmbuf = vidiocgmbuf,
432#endif
433#ifdef TUNER_FLAG
434 .vidioc_g_tuner = vidioc_g_tuner,
435 .vidioc_s_tuner = vidioc_s_tuner,
436 .vidioc_g_frequency = vidioc_g_frequency,
437 .vidioc_s_frequency = vidioc_s_frequency,
438#endif
439#ifdef CONFIG_VIDEO_ADV_DEBUG
440 .vidioc_g_register = vidioc_g_register,
441 .vidioc_s_register = vidioc_s_register,
442#endif
443};
444
445struct video_device cx25821_video_template2 = {
446 .name = "cx25821-video",
447 .fops = &video_fops,
448 .minor = -1,
449 .ioctl_ops = &video_ioctl_ops,
450 .tvnorms = CX25821_NORMS,
451 .current_norm = V4L2_STD_NTSC_M,
452};
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
new file mode 100644
index 000000000000..8801a8ead904
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH03];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH03]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH03]
109 && h->video_dev[SRAM_CH03]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH03;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO3))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO3)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH03]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO3)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO3);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO3);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH03, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH03] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH03] = 0;
329 }
330 dev->cif_width[SRAM_CH03] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH03);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH03].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364 cx25821_call_all(dev, core, log_status);
365
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 3 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH03);
388}
389
390// exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template3 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
new file mode 100644
index 000000000000..ab0d747138ad
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH04];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH04]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH04]
109 && h->video_dev[SRAM_CH04]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH04;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO4))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO4)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH04]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO4)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO4);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO4);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 // check priority
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH04, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH04] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH04] = 0;
328 }
329 dev->cif_width[SRAM_CH04] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH04);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH04].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 4 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH04);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template4 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
new file mode 100644
index 000000000000..7ef0b971f5cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH05];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH05]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH05]
109 && h->video_dev[SRAM_CH05]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH05;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO5))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO5)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH05]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO5)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO5);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO5);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH05, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH05] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH05] = 0;
329 }
330 dev->cif_width[SRAM_CH05] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH05);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH05].count;
349
350 return ret_val;
351}
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 5 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH05);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template5 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
new file mode 100644
index 000000000000..3c41b49e2ea9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH06];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH06]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH06]
109 && h->video_dev[SRAM_CH06]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH06;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO6))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO6)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH06]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO6)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO6);
228 }
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO6);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 if (fh) {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH06, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH06] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH06] = 0;
328 }
329 dev->cif_width[SRAM_CH06] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH06);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH06].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 6 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH06);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template6 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
new file mode 100644
index 000000000000..625c9b78a9cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -0,0 +1,449 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH07];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41 if (!list_empty(&q->queued)) {
42 list_add_tail(&buf->vb.queue, &q->queued);
43 buf->vb.state = VIDEOBUF_QUEUED;
44 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
45 buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf,
50 &dev->sram_channels[SRAM_CH07]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
54 dprintk(2,
55 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
56 buf, buf->vb.i, buf->count, q->count);
57 } else {
58 prev =
59 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
60 if (prev->vb.width == buf->vb.width
61 && prev->vb.height == buf->vb.height
62 && prev->fmt == buf->fmt) {
63 list_add_tail(&buf->vb.queue, &q->active);
64 buf->vb.state = VIDEOBUF_ACTIVE;
65 buf->count = q->count++;
66 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
67
68 /* 64 bit bits 63-32 */
69 prev->risc.jmp[2] = cpu_to_le32(0);
70 dprintk(2,
71 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
72 buf, buf->vb.i, buf->count);
73
74 } else {
75 list_add_tail(&buf->vb.queue, &q->queued);
76 buf->vb.state = VIDEOBUF_QUEUED;
77 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
78 buf->vb.i);
79 }
80 }
81
82 if (list_empty(&q->active)) {
83 dprintk(2, "active queue empty!\n");
84 }
85}
86
87static struct videobuf_queue_ops cx25821_video_qops = {
88 .buf_setup = buffer_setup,
89 .buf_prepare = buffer_prepare,
90 .buf_queue = buffer_queue,
91 .buf_release = buffer_release,
92};
93
94static int video_open(struct file *file)
95{
96 int minor = video_devdata(file)->minor;
97 struct cx25821_dev *h, *dev = NULL;
98 struct cx25821_fh *fh;
99 struct list_head *list;
100 enum v4l2_buf_type type = 0;
101 u32 pix_format;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH07]
108 && h->video_dev[SRAM_CH07]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127 file->private_data = fh;
128 fh->dev = dev;
129 fh->type = type;
130 fh->width = 720;
131
132 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
133 fh->height = 576;
134 else
135 fh->height = 480;
136
137 dev->channel_opened = SRAM_CH07;
138 pix_format =
139 (dev->pixel_formats[dev->channel_opened] ==
140 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
141 fh->fmt = format_by_fourcc(pix_format);
142
143 v4l2_prio_open(&dev->prio, &fh->prio);
144
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO7))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO7)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH07]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO7)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO7);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO7);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 if (fh) {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH07, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH07] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH07] = 0;
328 }
329 dev->cif_width[SRAM_CH07] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH07);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH07].count;
348
349 return ret_val;
350}
351static int vidioc_log_status(struct file *file, void *priv)
352{
353 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
354 char name[32 + 2];
355
356 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
357 u32 tmp = 0;
358
359 snprintf(name, sizeof(name), "%s/2", dev->name);
360 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
361 dev->name);
362 cx25821_call_all(dev, core, log_status);
363
364 tmp = cx_read(sram_ch->dma_ctl);
365 printk(KERN_INFO "Video input 7 is %s\n",
366 (tmp & 0x11) ? "streaming" : "stopped");
367 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
368 dev->name);
369 return 0;
370}
371
372static int vidioc_s_ctrl(struct file *file, void *priv,
373 struct v4l2_control *ctl)
374{
375 struct cx25821_fh *fh = priv;
376 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
377 int err;
378
379 if (fh) {
380 err = v4l2_prio_check(&dev->prio, &fh->prio);
381 if (0 != err)
382 return err;
383 }
384
385 return cx25821_set_control(dev, ctl, SRAM_CH07);
386}
387
388// exported stuff
389static const struct v4l2_file_operations video_fops = {
390 .owner = THIS_MODULE,
391 .open = video_open,
392 .release = video_release,
393 .read = video_read,
394 .poll = video_poll,
395 .mmap = video_mmap,
396 .ioctl = video_ioctl2,
397};
398
399static const struct v4l2_ioctl_ops video_ioctl_ops = {
400 .vidioc_querycap = vidioc_querycap,
401 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
402 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
403 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
404 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
405 .vidioc_reqbufs = vidioc_reqbufs,
406 .vidioc_querybuf = vidioc_querybuf,
407 .vidioc_qbuf = vidioc_qbuf,
408 .vidioc_dqbuf = vidioc_dqbuf,
409#ifdef TUNER_FLAG
410 .vidioc_s_std = vidioc_s_std,
411 .vidioc_querystd = vidioc_querystd,
412#endif
413 .vidioc_cropcap = vidioc_cropcap,
414 .vidioc_s_crop = vidioc_s_crop,
415 .vidioc_g_crop = vidioc_g_crop,
416 .vidioc_enum_input = vidioc_enum_input,
417 .vidioc_g_input = vidioc_g_input,
418 .vidioc_s_input = vidioc_s_input,
419 .vidioc_g_ctrl = vidioc_g_ctrl,
420 .vidioc_s_ctrl = vidioc_s_ctrl,
421 .vidioc_queryctrl = vidioc_queryctrl,
422 .vidioc_streamon = vidioc_streamon,
423 .vidioc_streamoff = vidioc_streamoff,
424 .vidioc_log_status = vidioc_log_status,
425 .vidioc_g_priority = vidioc_g_priority,
426 .vidioc_s_priority = vidioc_s_priority,
427#ifdef CONFIG_VIDEO_V4L1_COMPAT
428 .vidiocgmbuf = vidiocgmbuf,
429#endif
430#ifdef TUNER_FLAG
431 .vidioc_g_tuner = vidioc_g_tuner,
432 .vidioc_s_tuner = vidioc_s_tuner,
433 .vidioc_g_frequency = vidioc_g_frequency,
434 .vidioc_s_frequency = vidioc_s_frequency,
435#endif
436#ifdef CONFIG_VIDEO_ADV_DEBUG
437 .vidioc_g_register = vidioc_g_register,
438 .vidioc_s_register = vidioc_s_register,
439#endif
440};
441
442struct video_device cx25821_video_template7 = {
443 .name = "cx25821-video",
444 .fops = &video_fops,
445 .minor = -1,
446 .ioctl_ops = &video_ioctl_ops,
447 .tvnorms = CX25821_NORMS,
448 .current_norm = V4L2_STD_NTSC_M,
449};
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
new file mode 100644
index 000000000000..2a312ce78c63
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -0,0 +1,496 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[VIDEO_IOCTL_CH];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[VIDEO_IOCTL_CH]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->ioctl_dev && h->ioctl_dev->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = VIDEO_IOCTL_CH;
139 pix_format = V4L2_PIX_FMT_YUYV;
140 fh->fmt = format_by_fourcc(pix_format);
141
142 v4l2_prio_open(&dev->prio, &fh->prio);
143
144 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
145 &dev->pci->dev, &dev->slock,
146 V4L2_BUF_TYPE_VIDEO_CAPTURE,
147 V4L2_FIELD_INTERLACED,
148 sizeof(struct cx25821_buffer), fh);
149
150 dprintk(1, "post videobuf_queue_init()\n");
151 unlock_kernel();
152
153 return 0;
154}
155
156static ssize_t video_read(struct file *file, char __user * data, size_t count,
157 loff_t * ppos)
158{
159 struct cx25821_fh *fh = file->private_data;
160
161 switch (fh->type) {
162 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
163 if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
164 return -EBUSY;
165
166 return videobuf_read_one(&fh->vidq, data, count, ppos,
167 file->f_flags & O_NONBLOCK);
168
169 default:
170 BUG();
171 return 0;
172 }
173}
174
175static unsigned int video_poll(struct file *file,
176 struct poll_table_struct *wait)
177{
178 struct cx25821_fh *fh = file->private_data;
179 struct cx25821_buffer *buf;
180
181 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
182 /* streaming capture */
183 if (list_empty(&fh->vidq.stream))
184 return POLLERR;
185 buf = list_entry(fh->vidq.stream.next,
186 struct cx25821_buffer, vb.stream);
187 } else {
188 /* read() capture */
189 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
190 if (NULL == buf)
191 return POLLERR;
192 }
193
194 poll_wait(file, &buf->vb.done, wait);
195 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
196 return POLLIN | POLLRDNORM;
197
198 return 0;
199}
200
201static int video_release(struct file *file)
202{
203 struct cx25821_fh *fh = file->private_data;
204 struct cx25821_dev *dev = fh->dev;
205
206 /* stop video capture */
207 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
208 videobuf_queue_cancel(&fh->vidq);
209 res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
210 }
211
212 if (fh->vidq.read_buf) {
213 buffer_release(&fh->vidq, fh->vidq.read_buf);
214 kfree(fh->vidq.read_buf);
215 }
216
217 videobuf_mmap_free(&fh->vidq);
218
219 v4l2_prio_close(&dev->prio, &fh->prio);
220
221 file->private_data = NULL;
222 kfree(fh);
223
224 return 0;
225}
226
227static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
228{
229 struct cx25821_fh *fh = priv;
230 struct cx25821_dev *dev = fh->dev;
231
232 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type)) {
237 return -EINVAL;
238 }
239
240 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
241 return -EBUSY;
242 }
243
244 return videobuf_streamon(get_queue(fh));
245}
246
247static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
248{
249 struct cx25821_fh *fh = priv;
250 struct cx25821_dev *dev = fh->dev;
251 int err, res;
252
253 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
254 return -EINVAL;
255 if (i != fh->type)
256 return -EINVAL;
257
258 res = get_resource(fh, RESOURCE_VIDEO_IOCTL);
259 err = videobuf_streamoff(get_queue(fh));
260 if (err < 0)
261 return err;
262 res_free(dev, fh, res);
263 return 0;
264}
265
266static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
267 struct v4l2_format *f)
268{
269 struct cx25821_fh *fh = priv;
270 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
271 int err;
272
273 if (fh) {
274 err = v4l2_prio_check(&dev->prio, &fh->prio);
275 if (0 != err)
276 return err;
277 }
278
279 dprintk(2, "%s()\n", __func__);
280 err = vidioc_try_fmt_vid_cap(file, priv, f);
281
282 if (0 != err)
283 return err;
284 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
285 fh->width = f->fmt.pix.width;
286 fh->height = f->fmt.pix.height;
287 fh->vidq.field = f->fmt.pix.field;
288 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
289 fh->height, fh->vidq.field);
290 cx25821_call_all(dev, video, s_fmt, f);
291 return 0;
292}
293
294static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
295{
296 struct cx25821_fh *fh = priv;
297 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
298}
299
300static long video_ioctl_set(struct file *file, unsigned int cmd,
301 unsigned long arg)
302{
303 struct cx25821_fh *fh = file->private_data;
304 struct cx25821_dev *dev = fh->dev;
305 struct downstream_user_struct *data_from_user;
306 int command;
307 int width = 720;
308 int selected_channel = 0, pix_format = 0, i = 0;
309 int cif_enable = 0, cif_width = 0;
310 u32 value = 0;
311
312 data_from_user = (struct downstream_user_struct *)arg;
313
314 if (!data_from_user) {
315 printk("cx25821 in %s(): User data is INVALID. Returning.\n",
316 __func__);
317 return 0;
318 }
319
320 command = data_from_user->command;
321
322 if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
323 && command != ENABLE_CIF_RESOLUTION && command != REG_READ
324 && command != REG_WRITE && command != MEDUSA_READ
325 && command != MEDUSA_WRITE) {
326 return 0;
327 }
328
329 switch (command) {
330 case SET_VIDEO_STD:
331 dev->tvnorm =
332 !strcmp(data_from_user->vid_stdname,
333 "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
334 medusa_set_videostandard(dev);
335 break;
336
337 case SET_PIXEL_FORMAT:
338 selected_channel = data_from_user->decoder_select;
339 pix_format = data_from_user->pixel_format;
340
341 if (!(selected_channel <= 7 && selected_channel >= 0)) {
342 selected_channel -= 4;
343 selected_channel = selected_channel % 8;
344 }
345
346 if (selected_channel >= 0)
347 cx25821_set_pixel_format(dev, selected_channel,
348 pix_format);
349
350 break;
351
352 case ENABLE_CIF_RESOLUTION:
353 selected_channel = data_from_user->decoder_select;
354 cif_enable = data_from_user->cif_resolution_enable;
355 cif_width = data_from_user->cif_width;
356
357 if (cif_enable) {
358 if (dev->tvnorm & V4L2_STD_PAL_BG
359 || dev->tvnorm & V4L2_STD_PAL_DK)
360 width = 352;
361 else
362 width = (cif_width == 320
363 || cif_width == 352) ? cif_width : 320;
364 }
365
366 if (!(selected_channel <= 7 && selected_channel >= 0)) {
367 selected_channel -= 4;
368 selected_channel = selected_channel % 8;
369 }
370
371 if (selected_channel <= 7 && selected_channel >= 0) {
372 dev->use_cif_resolution[selected_channel] = cif_enable;
373 dev->cif_width[selected_channel] = width;
374 } else {
375 for (i = 0; i < VID_CHANNEL_NUM; i++) {
376 dev->use_cif_resolution[i] = cif_enable;
377 dev->cif_width[i] = width;
378 }
379 }
380
381 medusa_set_resolution(dev, width, selected_channel);
382 break;
383 case REG_READ:
384 data_from_user->reg_data = cx_read(data_from_user->reg_address);
385 break;
386 case REG_WRITE:
387 cx_write(data_from_user->reg_address, data_from_user->reg_data);
388 break;
389 case MEDUSA_READ:
390 value =
391 cx25821_i2c_read(&dev->i2c_bus[0],
392 (u16) data_from_user->reg_address,
393 &data_from_user->reg_data);
394 break;
395 case MEDUSA_WRITE:
396 cx25821_i2c_write(&dev->i2c_bus[0],
397 (u16) data_from_user->reg_address,
398 data_from_user->reg_data);
399 break;
400 }
401
402 return 0;
403}
404
405static int vidioc_log_status(struct file *file, void *priv)
406{
407 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
408 char name[32 + 2];
409
410 snprintf(name, sizeof(name), "%s/2", dev->name);
411 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
412 dev->name);
413 cx25821_call_all(dev, core, log_status);
414 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
415 dev->name);
416 return 0;
417}
418
419static int vidioc_s_ctrl(struct file *file, void *priv,
420 struct v4l2_control *ctl)
421{
422 struct cx25821_fh *fh = priv;
423 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
424 int err;
425
426 if (fh) {
427 err = v4l2_prio_check(&dev->prio, &fh->prio);
428 if (0 != err)
429 return err;
430 }
431
432 return 0;
433}
434
435// exported stuff
436static const struct v4l2_file_operations video_fops = {
437 .owner = THIS_MODULE,
438 .open = video_open,
439 .release = video_release,
440 .read = video_read,
441 .poll = video_poll,
442 .mmap = video_mmap,
443 .ioctl = video_ioctl_set,
444};
445
446static const struct v4l2_ioctl_ops video_ioctl_ops = {
447 .vidioc_querycap = vidioc_querycap,
448 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
449 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
450 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
451 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
452 .vidioc_reqbufs = vidioc_reqbufs,
453 .vidioc_querybuf = vidioc_querybuf,
454 .vidioc_qbuf = vidioc_qbuf,
455 .vidioc_dqbuf = vidioc_dqbuf,
456#ifdef TUNER_FLAG
457 .vidioc_s_std = vidioc_s_std,
458 .vidioc_querystd = vidioc_querystd,
459#endif
460 .vidioc_cropcap = vidioc_cropcap,
461 .vidioc_s_crop = vidioc_s_crop,
462 .vidioc_g_crop = vidioc_g_crop,
463 .vidioc_enum_input = vidioc_enum_input,
464 .vidioc_g_input = vidioc_g_input,
465 .vidioc_s_input = vidioc_s_input,
466 .vidioc_g_ctrl = vidioc_g_ctrl,
467 .vidioc_s_ctrl = vidioc_s_ctrl,
468 .vidioc_queryctrl = vidioc_queryctrl,
469 .vidioc_streamon = vidioc_streamon,
470 .vidioc_streamoff = vidioc_streamoff,
471 .vidioc_log_status = vidioc_log_status,
472 .vidioc_g_priority = vidioc_g_priority,
473 .vidioc_s_priority = vidioc_s_priority,
474#ifdef CONFIG_VIDEO_V4L1_COMPAT
475 .vidiocgmbuf = vidiocgmbuf,
476#endif
477#ifdef TUNER_FLAG
478 .vidioc_g_tuner = vidioc_g_tuner,
479 .vidioc_s_tuner = vidioc_s_tuner,
480 .vidioc_g_frequency = vidioc_g_frequency,
481 .vidioc_s_frequency = vidioc_s_frequency,
482#endif
483#ifdef CONFIG_VIDEO_ADV_DEBUG
484 .vidioc_g_register = vidioc_g_register,
485 .vidioc_s_register = vidioc_s_register,
486#endif
487};
488
489struct video_device cx25821_videoioctl_template = {
490 .name = "cx25821-videoioctl",
491 .fops = &video_fops,
492 .minor = -1,
493 .ioctl_ops = &video_ioctl_ops,
494 .tvnorms = CX25821_NORMS,
495 .current_norm = V4L2_STD_NTSC_M,
496};
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
new file mode 100644
index 000000000000..77b63b060405
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -0,0 +1,435 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH10];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH10]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH10]
108 && h->video_dev[SRAM_CH10]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 9;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO10))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO10)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel10->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO10)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO10);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO10);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename_ch2 = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname_ch2 = data_from_user->vid_stdname;
293 dev->pixel_format_ch2 = data_from_user->pixel_format;
294 dev->channel_select_ch2 = data_from_user->channel_select;
295 dev->command_ch2 = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch2(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch2(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370
371 return 0;
372}
373
374//exported stuff
375static const struct v4l2_file_operations video_fops = {
376 .owner = THIS_MODULE,
377 .open = video_open,
378 .release = video_release,
379 .read = video_read,
380 .poll = video_poll,
381 .mmap = video_mmap,
382 .ioctl = video_ioctl_upstream10,
383};
384
385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd,
398#endif
399 .vidioc_cropcap = vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf,
415#endif
416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency,
421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register,
425#endif
426};
427
428struct video_device cx25821_video_template10 = {
429 .name = "cx25821-upstream10",
430 .fops = &video_fops,
431 .minor = -1,
432 .ioctl_ops = &video_ioctl_ops,
433 .tvnorms = CX25821_NORMS,
434 .current_norm = V4L2_STD_NTSC_M,
435};
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
new file mode 100644
index 000000000000..75c8c1eed2da
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -0,0 +1,433 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH09];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH09]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH09]
108 && h->video_dev[SRAM_CH09]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 8;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO9))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO9)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel9->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO9)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO9);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO9);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname = data_from_user->vid_stdname;
293 dev->pixel_format = data_from_user->pixel_format;
294 dev->channel_select = data_from_user->channel_select;
295 dev->command = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch1(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch1(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343static int vidioc_log_status(struct file *file, void *priv)
344{
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346 char name[32 + 2];
347
348 snprintf(name, sizeof(name), "%s/2", dev->name);
349 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
350 dev->name);
351 cx25821_call_all(dev, core, log_status);
352 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
353 dev->name);
354 return 0;
355}
356
357static int vidioc_s_ctrl(struct file *file, void *priv,
358 struct v4l2_control *ctl)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 struct cx25821_fh *fh = priv;
362 int err;
363 if (fh) {
364 err = v4l2_prio_check(&dev->prio, &fh->prio);
365 if (0 != err)
366 return err;
367 }
368
369 return 0;
370}
371
372// exported stuff
373static const struct v4l2_file_operations video_fops = {
374 .owner = THIS_MODULE,
375 .open = video_open,
376 .release = video_release,
377 .read = video_read,
378 .poll = video_poll,
379 .mmap = video_mmap,
380 .ioctl = video_ioctl_upstream9,
381};
382
383static const struct v4l2_ioctl_ops video_ioctl_ops = {
384 .vidioc_querycap = vidioc_querycap,
385 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
386 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
387 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
388 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
389 .vidioc_reqbufs = vidioc_reqbufs,
390 .vidioc_querybuf = vidioc_querybuf,
391 .vidioc_qbuf = vidioc_qbuf,
392 .vidioc_dqbuf = vidioc_dqbuf,
393#ifdef TUNER_FLAG
394 .vidioc_s_std = vidioc_s_std,
395 .vidioc_querystd = vidioc_querystd,
396#endif
397 .vidioc_cropcap = vidioc_cropcap,
398 .vidioc_s_crop = vidioc_s_crop,
399 .vidioc_g_crop = vidioc_g_crop,
400 .vidioc_enum_input = vidioc_enum_input,
401 .vidioc_g_input = vidioc_g_input,
402 .vidioc_s_input = vidioc_s_input,
403 .vidioc_g_ctrl = vidioc_g_ctrl,
404 .vidioc_s_ctrl = vidioc_s_ctrl,
405 .vidioc_queryctrl = vidioc_queryctrl,
406 .vidioc_streamon = vidioc_streamon,
407 .vidioc_streamoff = vidioc_streamoff,
408 .vidioc_log_status = vidioc_log_status,
409 .vidioc_g_priority = vidioc_g_priority,
410 .vidioc_s_priority = vidioc_s_priority,
411#ifdef CONFIG_VIDEO_V4L1_COMPAT
412 .vidiocgmbuf = vidiocgmbuf,
413#endif
414#ifdef TUNER_FLAG
415 .vidioc_g_tuner = vidioc_g_tuner,
416 .vidioc_s_tuner = vidioc_s_tuner,
417 .vidioc_g_frequency = vidioc_g_frequency,
418 .vidioc_s_frequency = vidioc_s_frequency,
419#endif
420#ifdef CONFIG_VIDEO_ADV_DEBUG
421 .vidioc_g_register = vidioc_g_register,
422 .vidioc_s_register = vidioc_s_register,
423#endif
424};
425
426struct video_device cx25821_video_template9 = {
427 .name = "cx25821-upstream9",
428 .fops = &video_fops,
429 .minor = -1,
430 .ioctl_ops = &video_ioctl_ops,
431 .tvnorms = CX25821_NORMS,
432 .current_norm = V4L2_STD_NTSC_M,
433};
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
new file mode 100644
index 000000000000..cf2286d83b6a
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821.h
@@ -0,0 +1,602 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef CX25821_H_
25#define CX25821_H_
26
27#include <linux/pci.h>
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30#include <linux/interrupt.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/kdev_t.h>
34#include <linux/smp_lock.h>
35
36#include <media/v4l2-common.h>
37#include <media/v4l2-device.h>
38#include <media/tuner.h>
39#include <media/tveeprom.h>
40#include <media/videobuf-dma-sg.h>
41#include <media/videobuf-dvb.h>
42
43#include "btcx-risc.h"
44#include "cx25821-reg.h"
45#include "cx25821-medusa-reg.h"
46#include "cx25821-sram.h"
47#include "cx25821-audio.h"
48#include "media/cx2341x.h"
49
50#include <linux/version.h>
51#include <linux/mutex.h>
52
53#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106)
54
55#define UNSET (-1U)
56#define NO_SYNC_LINE (-1U)
57
58#define CX25821_MAXBOARDS 2
59
60#define TRUE 1
61#define FALSE 0
62#define LINE_SIZE_D1 1440
63
64// Number of decoders and encoders
65#define MAX_DECODERS 8
66#define MAX_ENCODERS 2
67#define QUAD_DECODERS 4
68#define MAX_CAMERAS 16
69
70/* Max number of inputs by card */
71#define MAX_CX25821_INPUT 8
72#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
73#define RESOURCE_VIDEO0 1
74#define RESOURCE_VIDEO1 2
75#define RESOURCE_VIDEO2 4
76#define RESOURCE_VIDEO3 8
77#define RESOURCE_VIDEO4 16
78#define RESOURCE_VIDEO5 32
79#define RESOURCE_VIDEO6 64
80#define RESOURCE_VIDEO7 128
81#define RESOURCE_VIDEO8 256
82#define RESOURCE_VIDEO9 512
83#define RESOURCE_VIDEO10 1024
84#define RESOURCE_VIDEO11 2048
85#define RESOURCE_VIDEO_IOCTL 4096
86
87#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
88
89#define UNKNOWN_BOARD 0
90#define CX25821_BOARD 1
91
92/* Currently supported by the driver */
93#define CX25821_NORMS (\
94 V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
95 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
96 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \
97 V4L2_STD_PAL_Nc )
98
99#define CX25821_BOARD_CONEXANT_ATHENA10 1
100#define MAX_VID_CHANNEL_NUM 12
101#define VID_CHANNEL_NUM 8
102
103struct cx25821_fmt {
104 char *name;
105 u32 fourcc; /* v4l2 format id */
106 int depth;
107 int flags;
108 u32 cxformat;
109};
110
111struct cx25821_ctrl {
112 struct v4l2_queryctrl v;
113 u32 off;
114 u32 reg;
115 u32 mask;
116 u32 shift;
117};
118
119struct cx25821_tvnorm {
120 char *name;
121 v4l2_std_id id;
122 u32 cxiformat;
123 u32 cxoformat;
124};
125
126struct cx25821_fh {
127 struct cx25821_dev *dev;
128 enum v4l2_buf_type type;
129 int radio;
130 u32 resources;
131
132 enum v4l2_priority prio;
133
134 /* video overlay */
135 struct v4l2_window win;
136 struct v4l2_clip *clips;
137 unsigned int nclips;
138
139 /* video capture */
140 struct cx25821_fmt *fmt;
141 unsigned int width, height;
142
143 /* vbi capture */
144 struct videobuf_queue vidq;
145 struct videobuf_queue vbiq;
146
147 /* H264 Encoder specifics ONLY */
148 struct videobuf_queue mpegq;
149 atomic_t v4l_reading;
150};
151
152enum cx25821_itype {
153 CX25821_VMUX_COMPOSITE = 1,
154 CX25821_VMUX_SVIDEO,
155 CX25821_VMUX_DEBUG,
156 CX25821_RADIO,
157};
158
159enum cx25821_src_sel_type {
160 CX25821_SRC_SEL_EXT_656_VIDEO = 0,
161 CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
162};
163
164/* buffer for one video frame */
165struct cx25821_buffer {
166 /* common v4l buffer stuff -- must be first */
167 struct videobuf_buffer vb;
168
169 /* cx25821 specific */
170 unsigned int bpl;
171 struct btcx_riscmem risc;
172 struct cx25821_fmt *fmt;
173 u32 count;
174};
175
176struct cx25821_input {
177 enum cx25821_itype type;
178 unsigned int vmux;
179 u32 gpio0, gpio1, gpio2, gpio3;
180};
181
182typedef enum {
183 CX25821_UNDEFINED = 0,
184 CX25821_RAW,
185 CX25821_264
186} port_t;
187
188struct cx25821_board {
189 char *name;
190 port_t porta, portb, portc;
191 unsigned int tuner_type;
192 unsigned int radio_type;
193 unsigned char tuner_addr;
194 unsigned char radio_addr;
195
196 u32 clk_freq;
197 struct cx25821_input input[2];
198};
199
200struct cx25821_subid {
201 u16 subvendor;
202 u16 subdevice;
203 u32 card;
204};
205
206struct cx25821_i2c {
207 struct cx25821_dev *dev;
208
209 int nr;
210
211 /* i2c i/o */
212 struct i2c_adapter i2c_adap;
213 struct i2c_algo_bit_data i2c_algo;
214 struct i2c_client i2c_client;
215 u32 i2c_rc;
216
217 /* cx25821 registers used for raw addess */
218 u32 i2c_period;
219 u32 reg_ctrl;
220 u32 reg_stat;
221 u32 reg_addr;
222 u32 reg_rdata;
223 u32 reg_wdata;
224};
225
226struct cx25821_dmaqueue {
227 struct list_head active;
228 struct list_head queued;
229 struct timer_list timeout;
230 struct btcx_riscmem stopper;
231 u32 count;
232};
233
234struct cx25821_data {
235 struct cx25821_dev *dev;
236 struct sram_channel *channel;
237};
238
239struct cx25821_dev {
240 struct list_head devlist;
241 atomic_t refcount;
242 struct v4l2_device v4l2_dev;
243
244 struct v4l2_prio_state prio;
245
246 /* pci stuff */
247 struct pci_dev *pci;
248 unsigned char pci_rev, pci_lat;
249 int pci_bus, pci_slot;
250 u32 base_io_addr;
251 u32 __iomem *lmmio;
252 u8 __iomem *bmmio;
253 int pci_irqmask;
254 int hwrevision;
255
256 u32 clk_freq;
257
258 /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
259 struct cx25821_i2c i2c_bus[3];
260
261 int nr;
262 struct mutex lock;
263
264 /* board details */
265 unsigned int board;
266 char name[32];
267
268 /* sram configuration */
269 struct sram_channel *sram_channels;
270
271 /* Analog video */
272 u32 resources;
273 unsigned int input;
274 u32 tvaudio;
275 v4l2_std_id tvnorm;
276 unsigned int tuner_type;
277 unsigned char tuner_addr;
278 unsigned int radio_type;
279 unsigned char radio_addr;
280 unsigned int has_radio;
281 unsigned int videc_type;
282 unsigned char videc_addr;
283 unsigned short _max_num_decoders;
284
285 int ctl_bright;
286 int ctl_contrast;
287 int ctl_hue;
288 int ctl_saturation;
289
290 struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
291
292 /* Analog Audio Upstream */
293 int _audio_is_running;
294 int _audiopixel_format;
295 int _is_first_audio_frame;
296 int _audiofile_status;
297 int _audio_lines_count;
298 int _audioframe_count;
299 int _audio_upstream_channel_select;
300 int _last_index_irq; //The last interrupt index processed.
301
302 __le32 *_risc_audio_jmp_addr;
303 __le32 *_risc_virt_start_addr;
304 __le32 *_risc_virt_addr;
305 dma_addr_t _risc_phys_addr;
306 dma_addr_t _risc_phys_start_addr;
307
308 unsigned int _audiorisc_size;
309 unsigned int _audiodata_buf_size;
310 __le32 *_audiodata_buf_virt_addr;
311 dma_addr_t _audiodata_buf_phys_addr;
312 char *_audiofilename;
313
314 /* V4l */
315 u32 freq;
316 struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
317 struct video_device *vbi_dev;
318 struct video_device *radio_dev;
319 struct video_device *ioctl_dev;
320
321 struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
322 spinlock_t slock;
323
324 /* Video Upstream */
325 int _line_size;
326 int _prog_cnt;
327 int _pixel_format;
328 int _is_first_frame;
329 int _is_running;
330 int _file_status;
331 int _lines_count;
332 int _frame_count;
333 int _channel_upstream_select;
334 unsigned int _risc_size;
335
336 __le32 *_dma_virt_start_addr;
337 __le32 *_dma_virt_addr;
338 dma_addr_t _dma_phys_addr;
339 dma_addr_t _dma_phys_start_addr;
340
341 unsigned int _data_buf_size;
342 __le32 *_data_buf_virt_addr;
343 dma_addr_t _data_buf_phys_addr;
344 char *_filename;
345 char *_defaultname;
346
347 int _line_size_ch2;
348 int _prog_cnt_ch2;
349 int _pixel_format_ch2;
350 int _is_first_frame_ch2;
351 int _is_running_ch2;
352 int _file_status_ch2;
353 int _lines_count_ch2;
354 int _frame_count_ch2;
355 int _channel2_upstream_select;
356 unsigned int _risc_size_ch2;
357
358 __le32 *_dma_virt_start_addr_ch2;
359 __le32 *_dma_virt_addr_ch2;
360 dma_addr_t _dma_phys_addr_ch2;
361 dma_addr_t _dma_phys_start_addr_ch2;
362
363 unsigned int _data_buf_size_ch2;
364 __le32 *_data_buf_virt_addr_ch2;
365 dma_addr_t _data_buf_phys_addr_ch2;
366 char *_filename_ch2;
367 char *_defaultname_ch2;
368
369 /* MPEG Encoder ONLY settings */
370 u32 cx23417_mailbox;
371 struct cx2341x_mpeg_params mpeg_params;
372 struct video_device *v4l_device;
373 atomic_t v4l_reader_count;
374 struct cx25821_tvnorm encodernorm;
375
376 u32 upstream_riscbuf_size;
377 u32 upstream_databuf_size;
378 u32 upstream_riscbuf_size_ch2;
379 u32 upstream_databuf_size_ch2;
380 u32 audio_upstream_riscbuf_size;
381 u32 audio_upstream_databuf_size;
382 int _isNTSC;
383 int _frame_index;
384 int _audioframe_index;
385 struct workqueue_struct *_irq_queues;
386 struct work_struct _irq_work_entry;
387 struct workqueue_struct *_irq_queues_ch2;
388 struct work_struct _irq_work_entry_ch2;
389 struct workqueue_struct *_irq_audio_queues;
390 struct work_struct _audio_work_entry;
391 char *input_filename;
392 char *input_filename_ch2;
393 int _frame_index_ch2;
394 int _isNTSC_ch2;
395 char *vid_stdname_ch2;
396 int pixel_format_ch2;
397 int channel_select_ch2;
398 int command_ch2;
399 char *input_audiofilename;
400 char *vid_stdname;
401 int pixel_format;
402 int channel_select;
403 int command;
404 int pixel_formats[VID_CHANNEL_NUM];
405 int use_cif_resolution[VID_CHANNEL_NUM];
406 int cif_width[VID_CHANNEL_NUM];
407 int channel_opened;
408};
409
410struct upstream_user_struct {
411 char *input_filename;
412 char *vid_stdname;
413 int pixel_format;
414 int channel_select;
415 int command;
416};
417
418struct downstream_user_struct {
419 char *vid_stdname;
420 int pixel_format;
421 int cif_resolution_enable;
422 int cif_width;
423 int decoder_select;
424 int command;
425 int reg_address;
426 int reg_data;
427};
428
429extern struct upstream_user_struct *up_data;
430
431static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
432{
433 return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
434}
435
436#define cx25821_call_all(dev, o, f, args...) \
437 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
438
439extern struct list_head cx25821_devlist;
440extern struct cx25821_board cx25821_boards[];
441extern struct cx25821_subid cx25821_subids[];
442
443#define SRAM_CH00 0 /* Video A */
444#define SRAM_CH01 1 /* Video B */
445#define SRAM_CH02 2 /* Video C */
446#define SRAM_CH03 3 /* Video D */
447#define SRAM_CH04 4 /* Video E */
448#define SRAM_CH05 5 /* Video F */
449#define SRAM_CH06 6 /* Video G */
450#define SRAM_CH07 7 /* Video H */
451
452#define SRAM_CH08 8 /* Audio A */
453#define SRAM_CH09 9 /* Video Upstream I */
454#define SRAM_CH10 10 /* Video Upstream J */
455#define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */
456
457#define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09
458#define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10
459#define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11
460#define VIDEO_IOCTL_CH 11
461
462struct sram_channel {
463 char *name;
464 u32 i;
465 u32 cmds_start;
466 u32 ctrl_start;
467 u32 cdt;
468 u32 fifo_start;
469 u32 fifo_size;
470 u32 ptr1_reg;
471 u32 ptr2_reg;
472 u32 cnt1_reg;
473 u32 cnt2_reg;
474 u32 int_msk;
475 u32 int_stat;
476 u32 int_mstat;
477 u32 dma_ctl;
478 u32 gpcnt_ctl;
479 u32 gpcnt;
480 u32 aud_length;
481 u32 aud_cfg;
482 u32 fld_aud_fifo_en;
483 u32 fld_aud_risc_en;
484
485 //For Upstream Video
486 u32 vid_fmt_ctl;
487 u32 vid_active_ctl1;
488 u32 vid_active_ctl2;
489 u32 vid_cdt_size;
490
491 u32 vip_ctl;
492 u32 pix_frmt;
493 u32 jumponly;
494 u32 irq_bit;
495};
496extern struct sram_channel cx25821_sram_channels[];
497
498#define STATUS_SUCCESS 0
499#define STATUS_UNSUCCESSFUL -1
500
501#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
502#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
503
504#define cx_andor(reg, mask, value) \
505 writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
506 ((value) & (mask)), dev->lmmio+((reg)>>2))
507
508#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
509#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
510
511#define Set_GPIO_Bit(Bit) (1 << Bit)
512#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
513
514#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
515#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
516#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
517
518extern int cx25821_i2c_register(struct cx25821_i2c *bus);
519extern void cx25821_card_setup(struct cx25821_dev *dev);
520extern int cx25821_ir_init(struct cx25821_dev *dev);
521extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
522extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
523extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
524extern void cx25821_gpio_init(struct cx25821_dev *dev);
525extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
526 int pin_number, int pin_logic_value);
527
528extern int medusa_video_init(struct cx25821_dev *dev);
529extern int medusa_set_videostandard(struct cx25821_dev *dev);
530extern void medusa_set_resolution(struct cx25821_dev *dev, int width,
531 int decoder_select);
532extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness,
533 int decoder);
534extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast,
535 int decoder);
536extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
537extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,
538 int decoder);
539
540extern int cx25821_sram_channel_setup(struct cx25821_dev *dev,
541 struct sram_channel *ch, unsigned int bpl,
542 u32 risc);
543
544extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
545 struct scatterlist *sglist,
546 unsigned int top_offset,
547 unsigned int bottom_offset,
548 unsigned int bpl,
549 unsigned int padding, unsigned int lines);
550extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
551 struct btcx_riscmem *risc,
552 struct scatterlist *sglist,
553 unsigned int bpl,
554 unsigned int lines, unsigned int lpi);
555extern void cx25821_free_buffer(struct videobuf_queue *q,
556 struct cx25821_buffer *buf);
557extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
558 u32 reg, u32 mask, u32 value);
559extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
560 struct sram_channel *ch);
561extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
562 struct sram_channel *ch);
563
564extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);
565extern void cx25821_print_irqbits(char *name, char *tag, char **strings,
566 int len, u32 bits, u32 mask);
567extern void cx25821_dev_unregister(struct cx25821_dev *dev);
568extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
569 struct sram_channel *ch,
570 unsigned int bpl, u32 risc);
571
572extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev,
573 int channel_select, int pixel_format);
574extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev,
575 int channel_select, int pixel_format);
576extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
577 int channel_select);
578extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
579extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
580extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
581extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
582 struct upstream_user_struct
583 *up_data);
584extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
585 struct upstream_user_struct
586 *up_data);
587extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
588 struct upstream_user_struct *up_data);
589extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
590extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
591extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
592extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
593 struct sram_channel *ch,
594 unsigned int bpl, u32 risc);
595extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,
596 u32 format);
597extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
598extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
599 struct pci_dev *pci,
600 struct video_device *template,
601 char *type);
602#endif
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index ca6ade6c4b47..e47f683a323e 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,5 +1,5 @@
1config VIDEO_GO7007 1config VIDEO_GO7007
2 tristate "Go 7007 support" 2 tristate "WIS GO7007 MPEG encoder support"
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 depends on SND 4 depends on SND
5 select VIDEOBUF_DMA_SG 5 select VIDEOBUF_DMA_SG
@@ -10,17 +10,19 @@ config VIDEO_GO7007
10 select CRC32 10 select CRC32
11 default N 11 default N
12 ---help--- 12 ---help---
13 This is a video4linux driver for some weird device... 13 This is a video4linux driver for the WIS GO7007 MPEG
14 encoder chip.
14 15
15 To compile this driver as a module, choose M here: the 16 To compile this driver as a module, choose M here: the
16 module will be called go7007 17 module will be called go7007
17 18
18config VIDEO_GO7007_USB 19config VIDEO_GO7007_USB
19 tristate "Go 7007 USB support" 20 tristate "WIS GO7007 USB support"
20 depends on VIDEO_GO7007 && USB 21 depends on VIDEO_GO7007 && USB
21 default N 22 default N
22 ---help--- 23 ---help---
23 This is a video4linux driver for some weird device... 24 This is a video4linux driver for the WIS GO7007 MPEG
25 encoder chip over USB.
24 26
25 To compile this driver as a module, choose M here: the 27 To compile this driver as a module, choose M here: the
26 module will be called go7007-usb 28 module will be called go7007-usb
@@ -30,8 +32,78 @@ config VIDEO_GO7007_USB_S2250_BOARD
30 depends on VIDEO_GO7007_USB && DVB_USB 32 depends on VIDEO_GO7007_USB && DVB_USB
31 default N 33 default N
32 ---help--- 34 ---help---
33 This is a video4linux driver for the Sensoray 2250/2251 device 35 This is a video4linux driver for the Sensoray 2250/2251 device.
34 36
35 To compile this driver as a module, choose M here: the 37 To compile this driver as a module, choose M here: the
36 module will be called s2250-board 38 module will be called s2250
39
40config VIDEO_GO7007_OV7640
41 tristate "OV7640 subdev support"
42 depends on VIDEO_GO7007
43 default N
44 ---help---
45 This is a video4linux driver for the OV7640 sub-device.
46
47 To compile this driver as a module, choose M here: the
48 module will be called wis-ov7640
49
50config VIDEO_GO7007_SAA7113
51 tristate "SAA7113 subdev support"
52 depends on VIDEO_GO7007
53 default N
54 ---help---
55 This is a video4linux driver for the SAA7113 sub-device.
56
57 To compile this driver as a module, choose M here: the
58 module will be called wis-saa7113
59
60config VIDEO_GO7007_SAA7115
61 tristate "SAA7115 subdev support"
62 depends on VIDEO_GO7007
63 default N
64 ---help---
65 This is a video4linux driver for the SAA7115 sub-device.
66
67 To compile this driver as a module, choose M here: the
68 module will be called wis-saa7115
69
70config VIDEO_GO7007_TW9903
71 tristate "TW9903 subdev support"
72 depends on VIDEO_GO7007
73 default N
74 ---help---
75 This is a video4linux driver for the TW9903 sub-device.
76
77 To compile this driver as a module, choose M here: the
78 module will be called wis-tw9903
79
80config VIDEO_GO7007_UDA1342
81 tristate "UDA1342 subdev support"
82 depends on VIDEO_GO7007
83 default N
84 ---help---
85 This is a video4linux driver for the UDA1342 sub-device.
86
87 To compile this driver as a module, choose M here: the
88 module will be called wis-uda1342
89
90config VIDEO_GO7007_SONY_TUNER
91 tristate "Sony tuner subdev support"
92 depends on VIDEO_GO7007
93 default N
94 ---help---
95 This is a video4linux driver for the Sony Tuner sub-device.
96
97 To compile this driver as a module, choose M here: the
98 module will be called wis-sony-tuner
99
100config VIDEO_GO7007_TW2804
101 tristate "TW2804 subdev support"
102 depends on VIDEO_GO7007
103 default N
104 ---help---
105 This is a video4linux driver for the TW2804 sub-device.
106
107 To compile this driver as a module, choose M here: the
108 module will be called wis-tw2804
37 109
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index e514b4af6d06..d14ea84a01f6 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -6,22 +6,34 @@
6obj-$(CONFIG_VIDEO_GO7007) += go7007.o 6obj-$(CONFIG_VIDEO_GO7007) += go7007.o
7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o 7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o 8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
12obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
13obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
14obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
15obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
9 16
10go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ 17go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
11 snd-go7007.o wis-saa7113.o 18 snd-go7007.o
12 19
13s2250-objs += s2250-board.o s2250-loader.o 20s2250-objs += s2250-board.o s2250-loader.o
14 21
15# Uncompile when the saa7134 patches get into upstream 22# Uncomment when the saa7134 patches get into upstream
16#ifneq ($(CONFIG_VIDEO_SAA7134),) 23#ifneq ($(CONFIG_VIDEO_SAA7134),)
17#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o 24#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
18#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 25#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
19#endif 26#endif
20 27
28# S2250 needs cypress ezusb loader from dvb-usb
21ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),) 29ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),)
22EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb 30EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
23endif 31endif
24 32
25EXTRA_CFLAGS += -Idrivers/staging/saa7134
26EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 33EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 34EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
35
36# Ubuntu 8.04 has CONFIG_SND undefined, so include lum sound/config.h too
37ifeq ($(CONFIG_SND),)
38EXTRA_CFLAGS += -include sound/config.h
39endif
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 77b1e769ac92..472f4bb08fdc 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -27,7 +27,7 @@
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/firmware.h> 29#include <linux/firmware.h>
30#include <linux/semaphore.h> 30#include <linux/mutex.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <asm/system.h> 32#include <asm/system.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
@@ -49,7 +49,7 @@ int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
49 go->hpi_ops->read_interrupt(go); 49 go->hpi_ops->read_interrupt(go);
50 if (wait_event_timeout(go->interrupt_waitq, 50 if (wait_event_timeout(go->interrupt_waitq,
51 go->interrupt_available, 5*HZ) < 0) { 51 go->interrupt_available, 5*HZ) < 0) {
52 printk(KERN_ERR "go7007: timeout waiting for read interrupt\n"); 52 v4l2_err(go->video_dev, "timeout waiting for read interrupt\n");
53 return -1; 53 return -1;
54 } 54 }
55 if (!go->interrupt_available) 55 if (!go->interrupt_available)
@@ -97,13 +97,12 @@ static int go7007_load_encoder(struct go7007 *go)
97 u16 intr_val, intr_data; 97 u16 intr_val, intr_data;
98 98
99 if (request_firmware(&fw_entry, fw_name, go->dev)) { 99 if (request_firmware(&fw_entry, fw_name, go->dev)) {
100 printk(KERN_ERR 100 v4l2_err(go, "unable to load firmware from file "
101 "go7007: unable to load firmware from file \"%s\"\n", 101 "\"%s\"\n", fw_name);
102 fw_name);
103 return -1; 102 return -1;
104 } 103 }
105 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { 104 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
106 printk(KERN_ERR "go7007: file \"%s\" does not appear to be " 105 v4l2_err(go, "file \"%s\" does not appear to be "
107 "go7007 firmware\n", fw_name); 106 "go7007 firmware\n", fw_name);
108 release_firmware(fw_entry); 107 release_firmware(fw_entry);
109 return -1; 108 return -1;
@@ -111,7 +110,7 @@ static int go7007_load_encoder(struct go7007 *go)
111 fw_len = fw_entry->size - 16; 110 fw_len = fw_entry->size - 16;
112 bounce = kmalloc(fw_len, GFP_KERNEL); 111 bounce = kmalloc(fw_len, GFP_KERNEL);
113 if (bounce == NULL) { 112 if (bounce == NULL) {
114 printk(KERN_ERR "go7007: unable to allocate %d bytes for " 113 v4l2_err(go, "unable to allocate %d bytes for "
115 "firmware transfer\n", fw_len); 114 "firmware transfer\n", fw_len);
116 release_firmware(fw_entry); 115 release_firmware(fw_entry);
117 return -1; 116 return -1;
@@ -122,7 +121,7 @@ static int go7007_load_encoder(struct go7007 *go)
122 go7007_send_firmware(go, bounce, fw_len) < 0 || 121 go7007_send_firmware(go, bounce, fw_len) < 0 ||
123 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || 122 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
124 (intr_val & ~0x1) != 0x5a5a) { 123 (intr_val & ~0x1) != 0x5a5a) {
125 printk(KERN_ERR "go7007: error transferring firmware\n"); 124 v4l2_err(go, "error transferring firmware\n");
126 rv = -1; 125 rv = -1;
127 } 126 }
128 kfree(bounce); 127 kfree(bounce);
@@ -140,9 +139,9 @@ int go7007_boot_encoder(struct go7007 *go, int init_i2c)
140{ 139{
141 int ret; 140 int ret;
142 141
143 down(&go->hw_lock); 142 mutex_lock(&go->hw_lock);
144 ret = go7007_load_encoder(go); 143 ret = go7007_load_encoder(go);
145 up(&go->hw_lock); 144 mutex_unlock(&go->hw_lock);
146 if (ret < 0) 145 if (ret < 0)
147 return -1; 146 return -1;
148 if (!init_i2c) 147 if (!init_i2c)
@@ -257,9 +256,9 @@ int go7007_register_encoder(struct go7007 *go)
257 256
258 printk(KERN_INFO "go7007: registering new %s\n", go->name); 257 printk(KERN_INFO "go7007: registering new %s\n", go->name);
259 258
260 down(&go->hw_lock); 259 mutex_lock(&go->hw_lock);
261 ret = go7007_init_encoder(go); 260 ret = go7007_init_encoder(go);
262 up(&go->hw_lock); 261 mutex_unlock(&go->hw_lock);
263 if (ret < 0) 262 if (ret < 0)
264 return -1; 263 return -1;
265 264
@@ -316,7 +315,7 @@ int go7007_start_encoder(struct go7007 *go)
316 315
317 if (go7007_send_firmware(go, fw, fw_len) < 0 || 316 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
318 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) { 317 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
319 printk(KERN_ERR "go7007: error transferring firmware\n"); 318 v4l2_err(go->video_dev, "error transferring firmware\n");
320 rv = -1; 319 rv = -1;
321 goto start_error; 320 goto start_error;
322 } 321 }
@@ -325,7 +324,7 @@ int go7007_start_encoder(struct go7007 *go)
325 go->parse_length = 0; 324 go->parse_length = 0;
326 go->seen_frame = 0; 325 go->seen_frame = 0;
327 if (go7007_stream_start(go) < 0) { 326 if (go7007_stream_start(go) < 0) {
328 printk(KERN_ERR "go7007: error starting stream transfer\n"); 327 v4l2_err(go->video_dev, "error starting stream transfer\n");
329 rv = -1; 328 rv = -1;
330 goto start_error; 329 goto start_error;
331 } 330 }
@@ -421,7 +420,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
421 for (i = 0; i < length; ++i) { 420 for (i = 0; i < length; ++i) {
422 if (go->active_buf != NULL && 421 if (go->active_buf != NULL &&
423 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) { 422 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
424 printk(KERN_DEBUG "go7007: dropping oversized frame\n"); 423 v4l2_info(go->video_dev, "dropping oversized frame\n");
425 go->active_buf->offset -= go->active_buf->bytesused; 424 go->active_buf->offset -= go->active_buf->bytesused;
426 go->active_buf->bytesused = 0; 425 go->active_buf->bytesused = 0;
427 go->active_buf->modet_active = 0; 426 go->active_buf->modet_active = 0;
@@ -604,7 +603,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
604 go->tuner_type = -1; 603 go->tuner_type = -1;
605 go->channel_number = 0; 604 go->channel_number = 0;
606 go->name[0] = 0; 605 go->name[0] = 0;
607 init_MUTEX(&go->hw_lock); 606 mutex_init(&go->hw_lock);
608 init_waitqueue_head(&go->frame_waitq); 607 init_waitqueue_head(&go->frame_waitq);
609 spin_lock_init(&go->spinlock); 608 spin_lock_init(&go->spinlock);
610 go->video_dev = NULL; 609 go->video_dev = NULL;
@@ -669,8 +668,8 @@ void go7007_remove(struct go7007 *go)
669 if (i2c_del_adapter(&go->i2c_adapter) == 0) 668 if (i2c_del_adapter(&go->i2c_adapter) == 0)
670 go->i2c_adapter_online = 0; 669 go->i2c_adapter_online = 0;
671 else 670 else
672 printk(KERN_ERR 671 v4l2_err(go->video_dev,
673 "go7007: error removing I2C adapter!\n"); 672 "error removing I2C adapter!\n");
674 } 673 }
675 674
676 if (go->audio_enabled) 675 if (go->audio_enabled)
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
index 871ed43e4e05..a8bb264e0074 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -1034,7 +1034,8 @@ static int brctrl_to_package(struct go7007 *go,
1034 0xBF1B, framelen[7], 1034 0xBF1B, framelen[7],
1035 0, 0, 1035 0, 0,
1036 1036
1037#if 0 /* Remove once we don't care about matching */ 1037#if 0
1038 /* Remove once we don't care about matching */
1038 0x200e, 0x0000, 1039 0x200e, 0x0000,
1039 0xBF56, 4, 1040 0xBF56, 4,
1040 0xBF57, 0, 1041 0xBF57, 0,
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
index c82867fdd28d..b8cfa1a6eaeb 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -24,7 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/semaphore.h> 27#include <linux/mutex.h>
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <asm/system.h> 29#include <asm/system.h>
30 30
@@ -48,7 +48,7 @@
48 48
49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs 49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
50 * on the Adlink PCI-MPG24, so access is shared between all of them. */ 50 * on the Adlink PCI-MPG24, so access is shared between all of them. */
51static DECLARE_MUTEX(adlink_mpg24_i2c_lock); 51static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
52 52
53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read, 53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
54 u16 command, int flags, u8 *data) 54 u16 command, int flags, u8 *data)
@@ -69,11 +69,11 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
69 *data, command, addr); 69 *data, command, addr);
70#endif 70#endif
71 71
72 down(&go->hw_lock); 72 mutex_lock(&go->hw_lock);
73 73
74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
75 /* Bridge the I2C port on this GO7007 to the shared bus */ 75 /* Bridge the I2C port on this GO7007 to the shared bus */
76 down(&adlink_mpg24_i2c_lock); 76 mutex_lock(&adlink_mpg24_i2c_lock);
77 go7007_write_addr(go, 0x3c82, 0x0020); 77 go7007_write_addr(go, 0x3c82, 0x0020);
78 } 78 }
79 79
@@ -134,9 +134,9 @@ i2c_done:
134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
135 /* Isolate the I2C port on this GO7007 from the shared bus */ 135 /* Isolate the I2C port on this GO7007 from the shared bus */
136 go7007_write_addr(go, 0x3c82, 0x0000); 136 go7007_write_addr(go, 0x3c82, 0x0000);
137 up(&adlink_mpg24_i2c_lock); 137 mutex_unlock(&adlink_mpg24_i2c_lock);
138 } 138 }
139 up(&go->hw_lock); 139 mutex_unlock(&go->hw_lock);
140 return ret; 140 return ret;
141} 141}
142 142
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index 178d18119faa..ce9307e3e186 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -132,7 +132,7 @@ struct go7007_buffer {
132 132
133struct go7007_file { 133struct go7007_file {
134 struct go7007 *go; 134 struct go7007 *go;
135 struct semaphore lock; 135 struct mutex lock;
136 int buf_count; 136 int buf_count;
137 struct go7007_buffer *bufs; 137 struct go7007_buffer *bufs;
138}; 138};
@@ -170,7 +170,7 @@ struct go7007 {
170 int ref_count; 170 int ref_count;
171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; 171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
172 spinlock_t spinlock; 172 spinlock_t spinlock;
173 struct semaphore hw_lock; 173 struct mutex hw_lock;
174 int streaming; 174 int streaming;
175 int in_use; 175 int in_use;
176 int audio_enabled; 176 int audio_enabled;
@@ -240,7 +240,7 @@ struct go7007 {
240 unsigned short interrupt_data; 240 unsigned short interrupt_data;
241}; 241};
242 242
243/* All of these must be called with the hpi_lock semaphore held! */ 243/* All of these must be called with the hpi_lock mutex held! */
244#define go7007_interface_reset(go) \ 244#define go7007_interface_reset(go) \
245 ((go)->hpi_ops->interface_reset(go)) 245 ((go)->hpi_ops->interface_reset(go))
246#define go7007_write_interrupt(go, x, y) \ 246#define go7007_write_interrupt(go, x, y) \
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index aa4a9e0b9954..ecaa3c989cf4 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -33,7 +33,8 @@
33 33
34static unsigned int assume_endura; 34static unsigned int assume_endura;
35module_param(assume_endura, int, 0644); 35module_param(assume_endura, int, 0644);
36MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"); 36MODULE_PARM_DESC(assume_endura, "when probing fails, "
37 "hardware is a Pelco Endura");
37 38
38/* #define GO7007_USB_DEBUG */ 39/* #define GO7007_USB_DEBUG */
39/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */ 40/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
@@ -44,12 +45,12 @@ MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"
44 45
45/* 46/*
46 * Pipes on EZ-USB interface: 47 * Pipes on EZ-USB interface:
47 * 0 snd - Control 48 * 0 snd - Control
48 * 0 rcv - Control 49 * 0 rcv - Control
49 * 2 snd - Download firmware (control) 50 * 2 snd - Download firmware (control)
50 * 4 rcv - Read Interrupt (interrupt) 51 * 4 rcv - Read Interrupt (interrupt)
51 * 6 rcv - Read Video (bulk) 52 * 6 rcv - Read Video (bulk)
52 * 8 rcv - Read Audio (bulk) 53 * 8 rcv - Read Audio (bulk)
53 */ 54 */
54 55
55#define GO7007_USB_EZUSB (1<<0) 56#define GO7007_USB_EZUSB (1<<0)
@@ -62,7 +63,7 @@ struct go7007_usb_board {
62 63
63struct go7007_usb { 64struct go7007_usb {
64 struct go7007_usb_board *board; 65 struct go7007_usb_board *board;
65 struct semaphore i2c_lock; 66 struct mutex i2c_lock;
66 struct usb_device *usbdev; 67 struct usb_device *usbdev;
67 struct urb *video_urbs[8]; 68 struct urb *video_urbs[8];
68 struct urb *audio_urbs[8]; 69 struct urb *audio_urbs[8];
@@ -97,7 +98,7 @@ static struct go7007_usb_board board_matrix_ii = {
97 }, 98 },
98 }, 99 },
99 .num_inputs = 2, 100 .num_inputs = 2,
100 .inputs = { 101 .inputs = {
101 { 102 {
102 .video_input = 0, 103 .video_input = 0,
103 .name = "Composite", 104 .name = "Composite",
@@ -134,7 +135,7 @@ static struct go7007_usb_board board_matrix_reload = {
134 }, 135 },
135 }, 136 },
136 .num_inputs = 2, 137 .num_inputs = 2,
137 .inputs = { 138 .inputs = {
138 { 139 {
139 .video_input = 0, 140 .video_input = 0,
140 .name = "Composite", 141 .name = "Composite",
@@ -172,7 +173,7 @@ static struct go7007_usb_board board_star_trek = {
172 }, 173 },
173 }, 174 },
174 .num_inputs = 2, 175 .num_inputs = 2,
175 .inputs = { 176 .inputs = {
176 { 177 {
177 .video_input = 1, 178 .video_input = 1,
178 /* .audio_input = AUDIO_EXTERN, */ 179 /* .audio_input = AUDIO_EXTERN, */
@@ -228,7 +229,7 @@ static struct go7007_usb_board board_px_tv402u = {
228 }, 229 },
229 }, 230 },
230 .num_inputs = 3, 231 .num_inputs = 3,
231 .inputs = { 232 .inputs = {
232 { 233 {
233 .video_input = 1, 234 .video_input = 1,
234 .audio_input = TVAUDIO_INPUT_EXTERN, 235 .audio_input = TVAUDIO_INPUT_EXTERN,
@@ -276,7 +277,7 @@ static struct go7007_usb_board board_xmen = {
276 }, 277 },
277 }, 278 },
278 .num_inputs = 1, 279 .num_inputs = 1,
279 .inputs = { 280 .inputs = {
280 { 281 {
281 .name = "Camera", 282 .name = "Camera",
282 }, 283 },
@@ -309,7 +310,7 @@ static struct go7007_usb_board board_matrix_revolution = {
309 }, 310 },
310 }, 311 },
311 .num_inputs = 2, 312 .num_inputs = 2,
312 .inputs = { 313 .inputs = {
313 { 314 {
314 .video_input = 2, 315 .video_input = 2,
315 .name = "Composite", 316 .name = "Composite",
@@ -341,7 +342,7 @@ static struct go7007_usb_board board_lifeview_lr192 = {
341 GO7007_SENSOR_SCALING, 342 GO7007_SENSOR_SCALING,
342 .num_i2c_devs = 0, 343 .num_i2c_devs = 0,
343 .num_inputs = 1, 344 .num_inputs = 1,
344 .inputs = { 345 .inputs = {
345 { 346 {
346 .video_input = 0, 347 .video_input = 0,
347 .name = "Composite", 348 .name = "Composite",
@@ -367,7 +368,7 @@ static struct go7007_usb_board board_endura = {
367 .sensor_h_offset = 8, 368 .sensor_h_offset = 8,
368 .num_i2c_devs = 0, 369 .num_i2c_devs = 0,
369 .num_inputs = 1, 370 .num_inputs = 1,
370 .inputs = { 371 .inputs = {
371 { 372 {
372 .name = "Camera", 373 .name = "Camera",
373 }, 374 },
@@ -399,7 +400,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
399 }, 400 },
400 }, 401 },
401 .num_inputs = 1, 402 .num_inputs = 1,
402 .inputs = { 403 .inputs = {
403 { 404 {
404 .name = "Composite", 405 .name = "Composite",
405 }, 406 },
@@ -430,7 +431,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
430 }, 431 },
431 }, 432 },
432 .num_inputs = 2, 433 .num_inputs = 2,
433 .inputs = { 434 .inputs = {
434 { 435 {
435 .video_input = 0, 436 .video_input = 0,
436 .name = "Composite", 437 .name = "Composite",
@@ -734,14 +735,15 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
734static void go7007_usb_read_video_pipe_complete(struct urb *urb) 735static void go7007_usb_read_video_pipe_complete(struct urb *urb)
735{ 736{
736 struct go7007 *go = (struct go7007 *)urb->context; 737 struct go7007 *go = (struct go7007 *)urb->context;
737 int r, status = urb-> status; 738 int r, status = urb->status;
738 739
739 if (!go->streaming) { 740 if (!go->streaming) {
740 wake_up_interruptible(&go->frame_waitq); 741 wake_up_interruptible(&go->frame_waitq);
741 return; 742 return;
742 } 743 }
743 if (status) { 744 if (status) {
744 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", status); 745 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
746 status);
745 return; 747 return;
746 } 748 }
747 if (urb->actual_length != urb->transfer_buffer_length) { 749 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -762,7 +764,8 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
762 if (!go->streaming) 764 if (!go->streaming)
763 return; 765 return;
764 if (status) { 766 if (status) {
765 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", status); 767 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
768 status);
766 return; 769 return;
767 } 770 }
768 if (urb->actual_length != urb->transfer_buffer_length) { 771 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -877,7 +880,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
877 if (go->status == STATUS_SHUTDOWN) 880 if (go->status == STATUS_SHUTDOWN)
878 return -1; 881 return -1;
879 882
880 down(&usb->i2c_lock); 883 mutex_lock(&usb->i2c_lock);
881 884
882 for (i = 0; i < num; ++i) { 885 for (i = 0; i < num; ++i) {
883 /* The hardware command is "write some bytes then read some 886 /* The hardware command is "write some bytes then read some
@@ -935,7 +938,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
935 ret = 0; 938 ret = 0;
936 939
937i2c_done: 940i2c_done:
938 up(&usb->i2c_lock); 941 mutex_unlock(&usb->i2c_lock);
939 return ret; 942 return ret;
940} 943}
941 944
@@ -1017,7 +1020,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1017 break; 1020 break;
1018 case GO7007_BOARDID_SENSORAY_2250: 1021 case GO7007_BOARDID_SENSORAY_2250:
1019 printk(KERN_INFO "Sensoray 2250 found\n"); 1022 printk(KERN_INFO "Sensoray 2250 found\n");
1020 name = "Sensoray 2250/2251\n"; 1023 name = "Sensoray 2250/2251";
1021 board = &board_sensoray_2250; 1024 board = &board_sensoray_2250;
1022 break; 1025 break;
1023 default: 1026 default:
@@ -1065,7 +1068,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1065 if (board->flags & GO7007_USB_EZUSB_I2C) { 1068 if (board->flags & GO7007_USB_EZUSB_I2C) {
1066 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ, 1069 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1067 sizeof(go7007_usb_adap_templ)); 1070 sizeof(go7007_usb_adap_templ));
1068 init_MUTEX(&usb->i2c_lock); 1071 mutex_init(&usb->i2c_lock);
1069 go->i2c_adapter.dev.parent = go->dev; 1072 go->i2c_adapter.dev.parent = go->dev;
1070 i2c_set_adapdata(&go->i2c_adapter, go); 1073 i2c_set_adapdata(&go->i2c_adapter, go);
1071 if (i2c_add_adapter(&go->i2c_adapter) < 0) { 1074 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
@@ -1096,7 +1099,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1096 usb->board = board = &board_endura; 1099 usb->board = board = &board_endura;
1097 go->board_info = &board->main_info; 1100 go->board_info = &board->main_info;
1098 strncpy(go->name, "Pelco Endura", 1101 strncpy(go->name, "Pelco Endura",
1099 sizeof(go->name)); 1102 sizeof(go->name));
1100 } else { 1103 } else {
1101 u16 channel; 1104 u16 channel;
1102 1105
@@ -1154,8 +1157,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1154 * to the EZ-USB GPIO output pins */ 1157 * to the EZ-USB GPIO output pins */
1155 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0, 1158 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1156 NULL, 0, 0) < 0) { 1159 NULL, 0, 0) < 0) {
1157 printk(KERN_ERR 1160 printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
1158 "go7007-usb: GPIO write failed!\n");
1159 goto initfail; 1161 goto initfail;
1160 } 1162 }
1161 } 1163 }
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 06cacd37bbd8..4bd353afa596 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -30,7 +30,7 @@
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/semaphore.h> 33#include <linux/mutex.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <asm/system.h> 35#include <asm/system.h>
36 36
@@ -75,7 +75,7 @@ static int go7007_streamoff(struct go7007 *go)
75 int retval = -EINVAL; 75 int retval = -EINVAL;
76 unsigned long flags; 76 unsigned long flags;
77 77
78 down(&go->hw_lock); 78 mutex_lock(&go->hw_lock);
79 if (go->streaming) { 79 if (go->streaming) {
80 go->streaming = 0; 80 go->streaming = 0;
81 go7007_stream_stop(go); 81 go7007_stream_stop(go);
@@ -85,7 +85,7 @@ static int go7007_streamoff(struct go7007 *go)
85 go7007_reset_encoder(go); 85 go7007_reset_encoder(go);
86 retval = 0; 86 retval = 0;
87 } 87 }
88 up(&go->hw_lock); 88 mutex_unlock(&go->hw_lock);
89 return 0; 89 return 0;
90} 90}
91 91
@@ -101,7 +101,7 @@ static int go7007_open(struct file *file)
101 return -ENOMEM; 101 return -ENOMEM;
102 ++go->ref_count; 102 ++go->ref_count;
103 gofh->go = go; 103 gofh->go = go;
104 init_MUTEX(&gofh->lock); 104 mutex_init(&gofh->lock);
105 gofh->buf_count = 0; 105 gofh->buf_count = 0;
106 file->private_data = gofh; 106 file->private_data = gofh;
107 return 0; 107 return 0;
@@ -383,13 +383,10 @@ static int clip_to_modet_map(struct go7007 *go, int region,
383 } 383 }
384 return 0; 384 return 0;
385} 385}
386#endif
386 387
387static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl) 388static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
388{ 389{
389 static const u32 user_ctrls[] = {
390 V4L2_CID_USER_CLASS,
391 0
392 };
393 static const u32 mpeg_ctrls[] = { 390 static const u32 mpeg_ctrls[] = {
394 V4L2_CID_MPEG_CLASS, 391 V4L2_CID_MPEG_CLASS,
395 V4L2_CID_MPEG_STREAM_TYPE, 392 V4L2_CID_MPEG_STREAM_TYPE,
@@ -401,26 +398,15 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
401 0 398 0
402 }; 399 };
403 static const u32 *ctrl_classes[] = { 400 static const u32 *ctrl_classes[] = {
404 user_ctrls,
405 mpeg_ctrls, 401 mpeg_ctrls,
406 NULL 402 NULL
407 }; 403 };
408 404
409 /* The ctrl may already contain the queried i2c controls, 405 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
410 * query the mpeg controls if the existing ctrl id is
411 * greater than the next mpeg ctrl id.
412 */
413 id = v4l2_ctrl_next(ctrl_classes, id);
414 if (id >= ctrl->id && ctrl->name[0])
415 return 0;
416
417 memset(ctrl, 0, sizeof(*ctrl));
418 ctrl->id = id;
419 406
420 switch (ctrl->id) { 407 switch (ctrl->id) {
421 case V4L2_CID_USER_CLASS:
422 case V4L2_CID_MPEG_CLASS: 408 case V4L2_CID_MPEG_CLASS:
423 return v4l2_ctrl_query_fill_std(ctrl); 409 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
424 case V4L2_CID_MPEG_STREAM_TYPE: 410 case V4L2_CID_MPEG_STREAM_TYPE:
425 return v4l2_ctrl_query_fill(ctrl, 411 return v4l2_ctrl_query_fill(ctrl,
426 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, 412 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
@@ -437,20 +423,21 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
437 V4L2_MPEG_VIDEO_ASPECT_16x9, 1, 423 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
438 V4L2_MPEG_VIDEO_ASPECT_1x1); 424 V4L2_MPEG_VIDEO_ASPECT_1x1);
439 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 425 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
426 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
440 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 427 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
441 return v4l2_ctrl_query_fill_std(ctrl); 428 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
442 case V4L2_CID_MPEG_VIDEO_BITRATE: 429 case V4L2_CID_MPEG_VIDEO_BITRATE:
443 return v4l2_ctrl_query_fill(ctrl, 430 return v4l2_ctrl_query_fill(ctrl,
444 64000, 431 64000,
445 10000000, 1, 432 10000000, 1,
446 9800000); 433 1500000);
447 default: 434 default:
448 break; 435 return -EINVAL;
449 } 436 }
450 return -EINVAL; 437 return 0;
451} 438}
452 439
453static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go) 440static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
454{ 441{
455 /* pretty sure we can't change any of these while streaming */ 442 /* pretty sure we can't change any of these while streaming */
456 if (go->streaming) 443 if (go->streaming)
@@ -528,6 +515,8 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
528 } 515 }
529 break; 516 break;
530 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 517 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
518 if (ctrl->value < 0 || ctrl->value > 34)
519 return -EINVAL;
531 go->gop_size = ctrl->value; 520 go->gop_size = ctrl->value;
532 break; 521 break;
533 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 522 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
@@ -547,7 +536,7 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
547 return 0; 536 return 0;
548} 537}
549 538
550static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go) 539static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
551{ 540{
552 switch (ctrl->id) { 541 switch (ctrl->id) {
553 case V4L2_CID_MPEG_STREAM_TYPE: 542 case V4L2_CID_MPEG_STREAM_TYPE:
@@ -600,13 +589,11 @@ static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
600 } 589 }
601 return 0; 590 return 0;
602} 591}
603#endif
604 592
605static int vidioc_querycap(struct file *file, void *priv, 593static int vidioc_querycap(struct file *file, void *priv,
606 struct v4l2_capability *cap) 594 struct v4l2_capability *cap)
607{ 595{
608 struct go7007_file *gofh = priv; 596 struct go7007 *go = ((struct go7007_file *) priv)->go;
609 struct go7007 *go = gofh->go;
610 597
611 strlcpy(cap->driver, "go7007", sizeof(cap->driver)); 598 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
612 strlcpy(cap->card, go->name, sizeof(cap->card)); 599 strlcpy(cap->card, go->name, sizeof(cap->card));
@@ -653,8 +640,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
653static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 640static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
654 struct v4l2_format *fmt) 641 struct v4l2_format *fmt)
655{ 642{
656 struct go7007_file *gofh = priv; 643 struct go7007 *go = ((struct go7007_file *) priv)->go;
657 struct go7007 *go = gofh->go;
658 644
659 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 645 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
660 fmt->fmt.pix.width = go->width; 646 fmt->fmt.pix.width = go->width;
@@ -672,8 +658,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
672static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 658static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
673 struct v4l2_format *fmt) 659 struct v4l2_format *fmt)
674{ 660{
675 struct go7007_file *gofh = priv; 661 struct go7007 *go = ((struct go7007_file *) priv)->go;
676 struct go7007 *go = gofh->go;
677 662
678 return set_capture_size(go, fmt, 1); 663 return set_capture_size(go, fmt, 1);
679} 664}
@@ -681,8 +666,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
681static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 666static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
682 struct v4l2_format *fmt) 667 struct v4l2_format *fmt)
683{ 668{
684 struct go7007_file *gofh = priv; 669 struct go7007 *go = ((struct go7007_file *) priv)->go;
685 struct go7007 *go = gofh->go;
686 670
687 if (go->streaming) 671 if (go->streaming)
688 return -EBUSY; 672 return -EBUSY;
@@ -705,14 +689,14 @@ static int vidioc_reqbufs(struct file *file, void *priv,
705 req->memory != V4L2_MEMORY_MMAP) 689 req->memory != V4L2_MEMORY_MMAP)
706 return -EINVAL; 690 return -EINVAL;
707 691
708 down(&gofh->lock); 692 mutex_lock(&gofh->lock);
709 for (i = 0; i < gofh->buf_count; ++i) 693 for (i = 0; i < gofh->buf_count; ++i)
710 if (gofh->bufs[i].mapped > 0) 694 if (gofh->bufs[i].mapped > 0)
711 goto unlock_and_return; 695 goto unlock_and_return;
712 696
713 down(&go->hw_lock); 697 mutex_lock(&go->hw_lock);
714 if (go->in_use > 0 && gofh->buf_count == 0) { 698 if (go->in_use > 0 && gofh->buf_count == 0) {
715 up(&go->hw_lock); 699 mutex_unlock(&go->hw_lock);
716 goto unlock_and_return; 700 goto unlock_and_return;
717 } 701 }
718 702
@@ -731,7 +715,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
731 GFP_KERNEL); 715 GFP_KERNEL);
732 716
733 if (!gofh->bufs) { 717 if (!gofh->bufs) {
734 up(&go->hw_lock); 718 mutex_unlock(&go->hw_lock);
735 goto unlock_and_return; 719 goto unlock_and_return;
736 } 720 }
737 721
@@ -750,8 +734,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
750 } 734 }
751 735
752 gofh->buf_count = count; 736 gofh->buf_count = count;
753 up(&go->hw_lock); 737 mutex_unlock(&go->hw_lock);
754 up(&gofh->lock); 738 mutex_unlock(&gofh->lock);
755 739
756 memset(req, 0, sizeof(*req)); 740 memset(req, 0, sizeof(*req));
757 741
@@ -762,7 +746,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
762 return 0; 746 return 0;
763 747
764unlock_and_return: 748unlock_and_return:
765 up(&gofh->lock); 749 mutex_unlock(&gofh->lock);
766 return retval; 750 return retval;
767} 751}
768 752
@@ -778,7 +762,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
778 762
779 index = buf->index; 763 index = buf->index;
780 764
781 down(&gofh->lock); 765 mutex_lock(&gofh->lock);
782 if (index >= gofh->buf_count) 766 if (index >= gofh->buf_count)
783 goto unlock_and_return; 767 goto unlock_and_return;
784 768
@@ -802,12 +786,12 @@ static int vidioc_querybuf(struct file *file, void *priv,
802 buf->memory = V4L2_MEMORY_MMAP; 786 buf->memory = V4L2_MEMORY_MMAP;
803 buf->m.offset = index * GO7007_BUF_SIZE; 787 buf->m.offset = index * GO7007_BUF_SIZE;
804 buf->length = GO7007_BUF_SIZE; 788 buf->length = GO7007_BUF_SIZE;
805 up(&gofh->lock); 789 mutex_unlock(&gofh->lock);
806 790
807 return 0; 791 return 0;
808 792
809unlock_and_return: 793unlock_and_return:
810 up(&gofh->lock); 794 mutex_unlock(&gofh->lock);
811 return retval; 795 return retval;
812} 796}
813 797
@@ -824,7 +808,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
824 buf->memory != V4L2_MEMORY_MMAP) 808 buf->memory != V4L2_MEMORY_MMAP)
825 return retval; 809 return retval;
826 810
827 down(&gofh->lock); 811 mutex_lock(&gofh->lock);
828 if (buf->index < 0 || buf->index >= gofh->buf_count) 812 if (buf->index < 0 || buf->index >= gofh->buf_count)
829 goto unlock_and_return; 813 goto unlock_and_return;
830 814
@@ -865,12 +849,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
865 spin_lock_irqsave(&go->spinlock, flags); 849 spin_lock_irqsave(&go->spinlock, flags);
866 list_add_tail(&gobuf->stream, &go->stream); 850 list_add_tail(&gobuf->stream, &go->stream);
867 spin_unlock_irqrestore(&go->spinlock, flags); 851 spin_unlock_irqrestore(&go->spinlock, flags);
868 up(&gofh->lock); 852 mutex_unlock(&gofh->lock);
869 853
870 return 0; 854 return 0;
871 855
872unlock_and_return: 856unlock_and_return:
873 up(&gofh->lock); 857 mutex_unlock(&gofh->lock);
874 return retval; 858 return retval;
875} 859}
876 860
@@ -890,7 +874,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
890 if (buf->memory != V4L2_MEMORY_MMAP) 874 if (buf->memory != V4L2_MEMORY_MMAP)
891 return retval; 875 return retval;
892 876
893 down(&gofh->lock); 877 mutex_lock(&gofh->lock);
894 if (list_empty(&go->stream)) 878 if (list_empty(&go->stream))
895 goto unlock_and_return; 879 goto unlock_and_return;
896 gobuf = list_entry(go->stream.next, 880 gobuf = list_entry(go->stream.next,
@@ -934,11 +918,11 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
934 buf->length = GO7007_BUF_SIZE; 918 buf->length = GO7007_BUF_SIZE;
935 buf->reserved = gobuf->modet_active; 919 buf->reserved = gobuf->modet_active;
936 920
937 up(&gofh->lock); 921 mutex_unlock(&gofh->lock);
938 return 0; 922 return 0;
939 923
940unlock_and_return: 924unlock_and_return:
941 up(&gofh->lock); 925 mutex_unlock(&gofh->lock);
942 return retval; 926 return retval;
943} 927}
944 928
@@ -952,8 +936,8 @@ static int vidioc_streamon(struct file *file, void *priv,
952 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 936 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
953 return -EINVAL; 937 return -EINVAL;
954 938
955 down(&gofh->lock); 939 mutex_lock(&gofh->lock);
956 down(&go->hw_lock); 940 mutex_lock(&go->hw_lock);
957 941
958 if (!go->streaming) { 942 if (!go->streaming) {
959 go->streaming = 1; 943 go->streaming = 1;
@@ -964,8 +948,8 @@ static int vidioc_streamon(struct file *file, void *priv,
964 else 948 else
965 retval = 0; 949 retval = 0;
966 } 950 }
967 up(&go->hw_lock); 951 mutex_unlock(&go->hw_lock);
968 up(&gofh->lock); 952 mutex_unlock(&gofh->lock);
969 953
970 return retval; 954 return retval;
971} 955}
@@ -978,9 +962,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
978 962
979 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 963 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
980 return -EINVAL; 964 return -EINVAL;
981 down(&gofh->lock); 965 mutex_lock(&gofh->lock);
982 go7007_streamoff(go); 966 go7007_streamoff(go);
983 up(&gofh->lock); 967 mutex_unlock(&gofh->lock);
984 968
985 return 0; 969 return 0;
986} 970}
@@ -988,22 +972,20 @@ static int vidioc_streamoff(struct file *file, void *priv,
988static int vidioc_queryctrl(struct file *file, void *priv, 972static int vidioc_queryctrl(struct file *file, void *priv,
989 struct v4l2_queryctrl *query) 973 struct v4l2_queryctrl *query)
990{ 974{
991 struct go7007_file *gofh = priv; 975 struct go7007 *go = ((struct go7007_file *) priv)->go;
992 struct go7007 *go = gofh->go;
993 976
994 if (!go->i2c_adapter_online) 977 if (!go->i2c_adapter_online)
995 return -EIO; 978 return -EIO;
996 979
997 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query); 980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
998 981
999 return (!query->name[0]) ? -EINVAL : 0; 982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
1000} 983}
1001 984
1002static int vidioc_g_ctrl(struct file *file, void *priv, 985static int vidioc_g_ctrl(struct file *file, void *priv,
1003 struct v4l2_control *ctrl) 986 struct v4l2_control *ctrl)
1004{ 987{
1005 struct go7007_file *gofh = priv; 988 struct go7007 *go = ((struct go7007_file *) priv)->go;
1006 struct go7007 *go = gofh->go;
1007 struct v4l2_queryctrl query; 989 struct v4l2_queryctrl query;
1008 990
1009 if (!go->i2c_adapter_online) 991 if (!go->i2c_adapter_online)
@@ -1013,7 +995,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1013 query.id = ctrl->id; 995 query.id = ctrl->id;
1014 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 996 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1015 if (query.name[0] == 0) 997 if (query.name[0] == 0)
1016 return -EINVAL; 998 return mpeg_g_ctrl(ctrl, go);
1017 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl); 999 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1018 1000
1019 return 0; 1001 return 0;
@@ -1022,8 +1004,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1022static int vidioc_s_ctrl(struct file *file, void *priv, 1004static int vidioc_s_ctrl(struct file *file, void *priv,
1023 struct v4l2_control *ctrl) 1005 struct v4l2_control *ctrl)
1024{ 1006{
1025 struct go7007_file *gofh = priv; 1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1026 struct go7007 *go = gofh->go;
1027 struct v4l2_queryctrl query; 1008 struct v4l2_queryctrl query;
1028 1009
1029 if (!go->i2c_adapter_online) 1010 if (!go->i2c_adapter_online)
@@ -1033,7 +1014,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1033 query.id = ctrl->id; 1014 query.id = ctrl->id;
1034 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 1015 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1035 if (query.name[0] == 0) 1016 if (query.name[0] == 0)
1036 return -EINVAL; 1017 return mpeg_s_ctrl(ctrl, go);
1037 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl); 1018 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1038 1019
1039 return 0; 1020 return 0;
@@ -1042,8 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1042static int vidioc_g_parm(struct file *filp, void *priv, 1023static int vidioc_g_parm(struct file *filp, void *priv,
1043 struct v4l2_streamparm *parm) 1024 struct v4l2_streamparm *parm)
1044{ 1025{
1045 struct go7007_file *gofh = priv; 1026 struct go7007 *go = ((struct go7007_file *) priv)->go;
1046 struct go7007 *go = gofh->go;
1047 struct v4l2_fract timeperframe = { 1027 struct v4l2_fract timeperframe = {
1048 .numerator = 1001 * go->fps_scale, 1028 .numerator = 1001 * go->fps_scale,
1049 .denominator = go->sensor_framerate, 1029 .denominator = go->sensor_framerate,
@@ -1061,8 +1041,7 @@ static int vidioc_g_parm(struct file *filp, void *priv,
1061static int vidioc_s_parm(struct file *filp, void *priv, 1041static int vidioc_s_parm(struct file *filp, void *priv,
1062 struct v4l2_streamparm *parm) 1042 struct v4l2_streamparm *parm)
1063{ 1043{
1064 struct go7007_file *gofh = priv; 1044 struct go7007 *go = ((struct go7007_file *) priv)->go;
1065 struct go7007 *go = gofh->go;
1066 unsigned int n, d; 1045 unsigned int n, d;
1067 1046
1068 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1047 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1094,8 +1073,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1094static int vidioc_enum_framesizes(struct file *filp, void *priv, 1073static int vidioc_enum_framesizes(struct file *filp, void *priv,
1095 struct v4l2_frmsizeenum *fsize) 1074 struct v4l2_frmsizeenum *fsize)
1096{ 1075{
1097 struct go7007_file *gofh = priv; 1076 struct go7007 *go = ((struct go7007_file *) priv)->go;
1098 struct go7007 *go = gofh->go;
1099 1077
1100 /* Return -EINVAL, if it is a TV board */ 1078 /* Return -EINVAL, if it is a TV board */
1101 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1079 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1115,8 +1093,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
1115static int vidioc_enum_frameintervals(struct file *filp, void *priv, 1093static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1116 struct v4l2_frmivalenum *fival) 1094 struct v4l2_frmivalenum *fival)
1117{ 1095{
1118 struct go7007_file *gofh = priv; 1096 struct go7007 *go = ((struct go7007_file *) priv)->go;
1119 struct go7007 *go = gofh->go;
1120 1097
1121 /* Return -EINVAL, if it is a TV board */ 1098 /* Return -EINVAL, if it is a TV board */
1122 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1099 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1133,10 +1110,27 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1133 return 0; 1110 return 0;
1134} 1111}
1135 1112
1113static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1114{
1115 struct go7007 *go = ((struct go7007_file *) priv)->go;
1116
1117 switch (go->standard) {
1118 case GO7007_STD_NTSC:
1119 *std = V4L2_STD_NTSC;
1120 break;
1121 case GO7007_STD_PAL:
1122 *std = V4L2_STD_PAL;
1123 break;
1124 default:
1125 return -EINVAL;
1126 }
1127
1128 return 0;
1129}
1130
1136static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) 1131static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1137{ 1132{
1138 struct go7007_file *gofh = priv; 1133 struct go7007 *go = ((struct go7007_file *) priv)->go;
1139 struct go7007 *go = gofh->go;
1140 1134
1141 if (go->streaming) 1135 if (go->streaming)
1142 return -EBUSY; 1136 return -EBUSY;
@@ -1178,30 +1172,27 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1178 return 0; 1172 return 0;
1179} 1173}
1180 1174
1181#if 0 1175static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1182 case VIDIOC_QUERYSTD: 1176{
1183 { 1177 struct go7007 *go = ((struct go7007_file *) priv)->go;
1184 v4l2_std_id *std = arg;
1185 1178
1186 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1179 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1187 go->input == go->board_info->num_inputs - 1) { 1180 go->input == go->board_info->num_inputs - 1) {
1188 if (!go->i2c_adapter_online) 1181 if (!go->i2c_adapter_online)
1189 return -EIO; 1182 return -EIO;
1190 i2c_clients_command(&go->i2c_adapter, 1183 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
1191 VIDIOC_QUERYSTD, arg); 1184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1192 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1185 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1193 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 1186 else
1194 else 1187 *std = 0;
1195 *std = 0; 1188
1196 return 0; 1189 return 0;
1197 } 1190}
1198#endif
1199 1191
1200static int vidioc_enum_input(struct file *file, void *priv, 1192static int vidioc_enum_input(struct file *file, void *priv,
1201 struct v4l2_input *inp) 1193 struct v4l2_input *inp)
1202{ 1194{
1203 struct go7007_file *gofh = priv; 1195 struct go7007 *go = ((struct go7007_file *) priv)->go;
1204 struct go7007 *go = gofh->go;
1205 1196
1206 if (inp->index >= go->board_info->num_inputs) 1197 if (inp->index >= go->board_info->num_inputs)
1207 return -EINVAL; 1198 return -EINVAL;
@@ -1230,8 +1221,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
1230 1221
1231static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) 1222static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1232{ 1223{
1233 struct go7007_file *gofh = priv; 1224 struct go7007 *go = ((struct go7007_file *) priv)->go;
1234 struct go7007 *go = gofh->go;
1235 1225
1236 *input = go->input; 1226 *input = go->input;
1237 1227
@@ -1240,8 +1230,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1240 1230
1241static int vidioc_s_input(struct file *file, void *priv, unsigned int input) 1231static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1242{ 1232{
1243 struct go7007_file *gofh = priv; 1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1244 struct go7007 *go = gofh->go;
1245 1234
1246 if (input >= go->board_info->num_inputs) 1235 if (input >= go->board_info->num_inputs)
1247 return -EINVAL; 1236 return -EINVAL;
@@ -1262,8 +1251,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1262static int vidioc_g_tuner(struct file *file, void *priv, 1251static int vidioc_g_tuner(struct file *file, void *priv,
1263 struct v4l2_tuner *t) 1252 struct v4l2_tuner *t)
1264{ 1253{
1265 struct go7007_file *gofh = priv; 1254 struct go7007 *go = ((struct go7007_file *) priv)->go;
1266 struct go7007 *go = gofh->go;
1267 1255
1268 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1256 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1269 return -EINVAL; 1257 return -EINVAL;
@@ -1281,8 +1269,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1281static int vidioc_s_tuner(struct file *file, void *priv, 1269static int vidioc_s_tuner(struct file *file, void *priv,
1282 struct v4l2_tuner *t) 1270 struct v4l2_tuner *t)
1283{ 1271{
1284 struct go7007_file *gofh = priv; 1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1285 struct go7007 *go = gofh->go;
1286 1273
1287 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1288 return -EINVAL; 1275 return -EINVAL;
@@ -1308,8 +1295,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
1308static int vidioc_g_frequency(struct file *file, void *priv, 1295static int vidioc_g_frequency(struct file *file, void *priv,
1309 struct v4l2_frequency *f) 1296 struct v4l2_frequency *f)
1310{ 1297{
1311 struct go7007_file *gofh = priv; 1298 struct go7007 *go = ((struct go7007_file *) priv)->go;
1312 struct go7007 *go = gofh->go;
1313 1299
1314 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1300 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1315 return -EINVAL; 1301 return -EINVAL;
@@ -1324,8 +1310,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1324static int vidioc_s_frequency(struct file *file, void *priv, 1310static int vidioc_s_frequency(struct file *file, void *priv,
1325 struct v4l2_frequency *f) 1311 struct v4l2_frequency *f)
1326{ 1312{
1327 struct go7007_file *gofh = priv; 1313 struct go7007 *go = ((struct go7007_file *) priv)->go;
1328 struct go7007 *go = gofh->go;
1329 1314
1330 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1315 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1331 return -EINVAL; 1316 return -EINVAL;
@@ -1340,8 +1325,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1340static int vidioc_cropcap(struct file *file, void *priv, 1325static int vidioc_cropcap(struct file *file, void *priv,
1341 struct v4l2_cropcap *cropcap) 1326 struct v4l2_cropcap *cropcap)
1342{ 1327{
1343 struct go7007_file *gofh = priv; 1328 struct go7007 *go = ((struct go7007_file *) priv)->go;
1344 struct go7007 *go = gofh->go;
1345 1329
1346 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1330 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL; 1331 return -EINVAL;
@@ -1385,8 +1369,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
1385 1369
1386static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1370static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1387{ 1371{
1388 struct go7007_file *gofh = priv; 1372 struct go7007 *go = ((struct go7007_file *) priv)->go;
1389 struct go7007 *go = gofh->go;
1390 1373
1391 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1374 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL; 1375 return -EINVAL;
@@ -1734,18 +1717,18 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1734 return -EINVAL; /* only support VM_SHARED mapping */ 1717 return -EINVAL; /* only support VM_SHARED mapping */
1735 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE) 1718 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1736 return -EINVAL; /* must map exactly one full buffer */ 1719 return -EINVAL; /* must map exactly one full buffer */
1737 down(&gofh->lock); 1720 mutex_lock(&gofh->lock);
1738 index = vma->vm_pgoff / GO7007_BUF_PAGES; 1721 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1739 if (index >= gofh->buf_count) { 1722 if (index >= gofh->buf_count) {
1740 up(&gofh->lock); 1723 mutex_unlock(&gofh->lock);
1741 return -EINVAL; /* trying to map beyond requested buffers */ 1724 return -EINVAL; /* trying to map beyond requested buffers */
1742 } 1725 }
1743 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) { 1726 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1744 up(&gofh->lock); 1727 mutex_unlock(&gofh->lock);
1745 return -EINVAL; /* offset is not aligned on buffer boundary */ 1728 return -EINVAL; /* offset is not aligned on buffer boundary */
1746 } 1729 }
1747 if (gofh->bufs[index].mapped > 0) { 1730 if (gofh->bufs[index].mapped > 0) {
1748 up(&gofh->lock); 1731 mutex_unlock(&gofh->lock);
1749 return -EBUSY; 1732 return -EBUSY;
1750 } 1733 }
1751 gofh->bufs[index].mapped = 1; 1734 gofh->bufs[index].mapped = 1;
@@ -1754,7 +1737,7 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1754 vma->vm_flags |= VM_DONTEXPAND; 1737 vma->vm_flags |= VM_DONTEXPAND;
1755 vma->vm_flags &= ~VM_IO; 1738 vma->vm_flags &= ~VM_IO;
1756 vma->vm_private_data = &gofh->bufs[index]; 1739 vma->vm_private_data = &gofh->bufs[index];
1757 up(&gofh->lock); 1740 mutex_unlock(&gofh->lock);
1758 return 0; 1741 return 0;
1759} 1742}
1760 1743
@@ -1801,7 +1784,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1801 .vidioc_querybuf = vidioc_querybuf, 1784 .vidioc_querybuf = vidioc_querybuf,
1802 .vidioc_qbuf = vidioc_qbuf, 1785 .vidioc_qbuf = vidioc_qbuf,
1803 .vidioc_dqbuf = vidioc_dqbuf, 1786 .vidioc_dqbuf = vidioc_dqbuf,
1787 .vidioc_g_std = vidioc_g_std,
1804 .vidioc_s_std = vidioc_s_std, 1788 .vidioc_s_std = vidioc_s_std,
1789 .vidioc_querystd = vidioc_querystd,
1805 .vidioc_enum_input = vidioc_enum_input, 1790 .vidioc_enum_input = vidioc_enum_input,
1806 .vidioc_g_input = vidioc_g_input, 1791 .vidioc_g_input = vidioc_g_input,
1807 .vidioc_s_input = vidioc_s_input, 1792 .vidioc_s_input = vidioc_s_input,
@@ -1862,7 +1847,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1862{ 1847{
1863 unsigned long flags; 1848 unsigned long flags;
1864 1849
1865 down(&go->hw_lock); 1850 mutex_lock(&go->hw_lock);
1866 if (go->streaming) { 1851 if (go->streaming) {
1867 go->streaming = 0; 1852 go->streaming = 0;
1868 go7007_stream_stop(go); 1853 go7007_stream_stop(go);
@@ -1870,7 +1855,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1870 abort_queued(go); 1855 abort_queued(go);
1871 spin_unlock_irqrestore(&go->spinlock, flags); 1856 spin_unlock_irqrestore(&go->spinlock, flags);
1872 } 1857 }
1873 up(&go->hw_lock); 1858 mutex_unlock(&go->hw_lock);
1874 if (go->video_dev) 1859 if (go->video_dev)
1875 video_unregister_device(go->video_dev); 1860 video_unregister_device(go->video_dev);
1876} 1861}
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt
index 1c2907c1dc81..06a76da32128 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/go7007/go7007.txt
@@ -2,7 +2,7 @@ This is a driver for the WIS GO7007SB multi-format video encoder.
2 2
3Pete Eberlein <pete@sensoray.com> 3Pete Eberlein <pete@sensoray.com>
4 4
5The driver was originally released under the GPL and is currently hosted at: 5The driver was orignally released under the GPL and is currently hosted at:
6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver 6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
7The go7007 firmware can be acquired from the package on the site above. 7The go7007 firmware can be acquired from the package on the site above.
8 8
@@ -24,10 +24,10 @@ These should be used instead of the non-standard GO7007 ioctls described
24below. 24below.
25 25
26 26
27The README files from the original package appears below: 27The README files from the orignal package appear below:
28 28
29--------------------------------------------------------------------------- 29---------------------------------------------------------------------------
30 WIS GO7007SB Public Linux Driver 30 WIS GO7007SB Public Linux Driver
31--------------------------------------------------------------------------- 31---------------------------------------------------------------------------
32 32
33 33
@@ -78,23 +78,23 @@ All vendor-built kernels should already be configured properly. However,
78for custom-built kernels, the following options need to be enabled in the 78for custom-built kernels, the following options need to be enabled in the
79kernel as built-in or modules: 79kernel as built-in or modules:
80 80
81 CONFIG_HOTPLUG - Support for hot-pluggable devices 81 CONFIG_HOTPLUG - Support for hot-pluggable devices
82 CONFIG_MODULES - Enable loadable module support 82 CONFIG_MODULES - Enable loadable module support
83 CONFIG_KMOD - Automatic kernel module loading 83 CONFIG_KMOD - Automatic kernel module loading
84 CONFIG_FW_LOADER - Hotplug firmware loading support 84 CONFIG_FW_LOADER - Hotplug firmware loading support
85 CONFIG_I2C - I2C support 85 CONFIG_I2C - I2C support
86 CONFIG_VIDEO_DEV - Video For Linux 86 CONFIG_VIDEO_DEV - Video For Linux
87 CONFIG_SOUND - Sound card support 87 CONFIG_SOUND - Sound card support
88 CONFIG_SND - Advanced Linux Sound Architecture 88 CONFIG_SND - Advanced Linux Sound Architecture
89 CONFIG_USB - Support for Host-side USB 89 CONFIG_USB - Support for Host-side USB
90 CONFIG_USB_DEVICEFS - USB device filesystem 90 CONFIG_USB_DEVICEFS - USB device filesystem
91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support 91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
92 92
93Additionally, to use the example application, the following options need to 93Additionally, to use the example application, the following options need to
94be enabled in the ALSA section: 94be enabled in the ALSA section:
95 95
96 CONFIG_SND_MIXER_OSS - OSS Mixer API 96 CONFIG_SND_MIXER_OSS - OSS Mixer API
97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API 97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
98 98
99The hotplug scripts, along with the fxload utility, must also be installed. 99The hotplug scripts, along with the fxload utility, must also be installed.
100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>. 100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
@@ -107,7 +107,7 @@ fxload and for loading firmware into the driver using the firmware agent.
107 107
108Most users should be able to compile the driver by simply running: 108Most users should be able to compile the driver by simply running:
109 109
110 $ make 110 $ make
111 111
112in the top-level directory of the driver kit. First the kernel modules 112in the top-level directory of the driver kit. First the kernel modules
113will be built, followed by the example applications. 113will be built, followed by the example applications.
@@ -117,12 +117,12 @@ currently-running kernel, or if the module should be built for a kernel
117other than the currently-running kernel, an additional parameter will need 117other than the currently-running kernel, an additional parameter will need
118to be passed to make to specify the appropriate kernel source directory: 118to be passed to make to specify the appropriate kernel source directory:
119 119
120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3 120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
121 121
122Once the compile completes, the driver and firmware files should be 122Once the compile completes, the driver and firmware files should be
123installed by running: 123installed by running:
124 124
125 $ make install 125 $ make install
126 126
127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra" 127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
128and the firmware files will be placed in the appropriate hotplug firmware 128and the firmware files will be placed in the appropriate hotplug firmware
@@ -200,7 +200,7 @@ stereo audio broadcasts on the A2 carrier.
200To verify that the configuration has been placed in the correct location, 200To verify that the configuration has been placed in the correct location,
201execute: 201execute:
202 202
203 $ modprobe -c | grep wis-sony-tuner 203 $ modprobe -c | grep wis-sony-tuner
204 204
205If the configuration line appears, then modprobe will pass the parameters 205If the configuration line appears, then modprobe will pass the parameters
206correctly the next time the wis-sony-tuner module is loaded into the 206correctly the next time the wis-sony-tuner module is loaded into the
@@ -223,7 +223,7 @@ This application will auto-detect the V4L2 and ALSA/OSS device names of the
223hardware and will record video and audio to an AVI file for a specified 223hardware and will record video and audio to an AVI file for a specified
224number of seconds. For example: 224number of seconds. For example:
225 225
226 $ apps/gorecord -duration 60 capture.avi 226 $ apps/gorecord -duration 60 capture.avi
227 227
228If this application does not successfully record an AVI file, the error 228If this application does not successfully record an AVI file, the error
229messages produced by gorecord and recorded in the system log (usually in 229messages produced by gorecord and recorded in the system log (usually in
@@ -286,35 +286,35 @@ features of the GO7007SB encoder, which are described below:
286 286
287 Fields in struct go7007_comp_params: 287 Fields in struct go7007_comp_params:
288 288
289 __u32 The maximum number of frames in each 289 __u32 The maximum number of frames in each
290 gop_size Group Of Pictures; i.e. the maximum 290 gop_size Group Of Pictures; i.e. the maximum
291 number of frames minus one between 291 number of frames minus one between
292 each key frame. 292 each key frame.
293 293
294 __u32 The maximum number of sequential 294 __u32 The maximum number of sequential
295 max_b_frames bidirectionally-predicted frames. 295 max_b_frames bidirectionally-predicted frames.
296 (B-frames are not yet supported.) 296 (B-frames are not yet supported.)
297 297
298 enum go7007_aspect_ratio The aspect ratio to be encoded in the 298 enum go7007_aspect_ratio The aspect ratio to be encoded in the
299 aspect_ratio meta-data of the compressed format. 299 aspect_ratio meta-data of the compressed format.
300 300
301 Choices are: 301 Choices are:
302 GO7007_ASPECT_RATIO_1_1 302 GO7007_ASPECT_RATIO_1_1
303 GO7007_ASPECT_RATIO_4_3_NTSC 303 GO7007_ASPECT_RATIO_4_3_NTSC
304 GO7007_ASPECT_RATIO_4_3_PAL 304 GO7007_ASPECT_RATIO_4_3_PAL
305 GO7007_ASPECT_RATIO_16_9_NTSC 305 GO7007_ASPECT_RATIO_16_9_NTSC
306 GO7007_ASPECT_RATIO_16_9_PAL 306 GO7007_ASPECT_RATIO_16_9_PAL
307 307
308 __u32 Bit-wise OR of control flags (below) 308 __u32 Bit-wise OR of control flags (below)
309 flags 309 flags
310 310
311 Flags in struct go7007_comp_params: 311 Flags in struct go7007_comp_params:
312 312
313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used 313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
314 to produce streams appropriate for 314 to produce streams appropriate for
315 random seeking. 315 random seeking.
316 316
317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header. 317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
318 318
319 319
320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS 320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
@@ -337,56 +337,56 @@ features of the GO7007SB encoder, which are described below:
337 337
338 Fields in struct go7007_mpeg_params: 338 Fields in struct go7007_mpeg_params:
339 339
340 enum go7007_mpeg_video_standard 340 enum go7007_mpeg_video_standard
341 mpeg_video_standard The MPEG video standard in which to 341 mpeg_video_standard The MPEG video standard in which to
342 compress the video. 342 compress the video.
343 343
344 Choices are: 344 Choices are:
345 GO7007_MPEG_VIDEO_MPEG1 345 GO7007_MPEG_VIDEO_MPEG1
346 GO7007_MPEG_VIDEO_MPEG2 346 GO7007_MPEG_VIDEO_MPEG2
347 GO7007_MPEG_VIDEO_MPEG4 347 GO7007_MPEG_VIDEO_MPEG4
348 348
349 __u32 Bit-wise OR of control flags (below) 349 __u32 Bit-wise OR of control flags (below)
350 flags 350 flags
351 351
352 __u32 The profile and level indication to be 352 __u32 The profile and level indication to be
353 pali stored in the sequence header. This 353 pali stored in the sequence header. This
354 is only used as an indicator to the 354 is only used as an indicator to the
355 decoder, and does not affect the MPEG 355 decoder, and does not affect the MPEG
356 features used in the video stream. 356 features used in the video stream.
357 Not valid for MPEG1. 357 Not valid for MPEG1.
358 358
359 Choices for MPEG2 are: 359 Choices for MPEG2 are:
360 GO7007_MPEG2_PROFILE_MAIN_MAIN 360 GO7007_MPEG2_PROFILE_MAIN_MAIN
361 361
362 Choices for MPEG4 are: 362 Choices for MPEG4 are:
363 GO7007_MPEG4_PROFILE_S_L0 363 GO7007_MPEG4_PROFILE_S_L0
364 GO7007_MPEG4_PROFILE_S_L1 364 GO7007_MPEG4_PROFILE_S_L1
365 GO7007_MPEG4_PROFILE_S_L2 365 GO7007_MPEG4_PROFILE_S_L2
366 GO7007_MPEG4_PROFILE_S_L3 366 GO7007_MPEG4_PROFILE_S_L3
367 GO7007_MPEG4_PROFILE_ARTS_L1 367 GO7007_MPEG4_PROFILE_ARTS_L1
368 GO7007_MPEG4_PROFILE_ARTS_L2 368 GO7007_MPEG4_PROFILE_ARTS_L2
369 GO7007_MPEG4_PROFILE_ARTS_L3 369 GO7007_MPEG4_PROFILE_ARTS_L3
370 GO7007_MPEG4_PROFILE_ARTS_L4 370 GO7007_MPEG4_PROFILE_ARTS_L4
371 GO7007_MPEG4_PROFILE_AS_L0 371 GO7007_MPEG4_PROFILE_AS_L0
372 GO7007_MPEG4_PROFILE_AS_L1 372 GO7007_MPEG4_PROFILE_AS_L1
373 GO7007_MPEG4_PROFILE_AS_L2 373 GO7007_MPEG4_PROFILE_AS_L2
374 GO7007_MPEG4_PROFILE_AS_L3 374 GO7007_MPEG4_PROFILE_AS_L3
375 GO7007_MPEG4_PROFILE_AS_L4 375 GO7007_MPEG4_PROFILE_AS_L4
376 GO7007_MPEG4_PROFILE_AS_L5 376 GO7007_MPEG4_PROFILE_AS_L5
377 377
378 Flags in struct go7007_mpeg_params: 378 Flags in struct go7007_mpeg_params:
379 379
380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and 380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
381 bitrate control settings to comply 381 bitrate control settings to comply
382 with DVD MPEG2 stream requirements. 382 with DVD MPEG2 stream requirements.
383 This overrides most compression and 383 This overrides most compression and
384 bitrate settings! 384 bitrate settings!
385 385
386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header. 386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
387 387
388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at 388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
389 the start of each GOP. 389 the start of each GOP.
390 390
391 391
392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE 392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
@@ -404,7 +404,7 @@ features of the GO7007SB encoder, which are described below:
404 404
405 405
406---------------------------------------------------------------------------- 406----------------------------------------------------------------------------
407 Installing the WIS PCI Voyager Driver 407 Installing the WIS PCI Voyager Driver
408--------------------------------------------------------------------------- 408---------------------------------------------------------------------------
409 409
410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x 410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 1706fbf06847..8c85a9c3665a 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -21,12 +21,10 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23#include <media/v4l2-common.h> 23#include <media/v4l2-common.h>
24#include "s2250-loader.h"
24#include "go7007-priv.h" 25#include "go7007-priv.h"
25#include "wis-i2c.h" 26#include "wis-i2c.h"
26 27
27extern int s2250loader_init(void);
28extern void s2250loader_cleanup(void);
29
30#define TLV320_ADDRESS 0x34 28#define TLV320_ADDRESS 0x34
31#define VPX322_ADDR_ANALOGCONTROL1 0x02 29#define VPX322_ADDR_ANALOGCONTROL1 0x02
32#define VPX322_ADDR_BRIGHTNESS0 0x0127 30#define VPX322_ADDR_BRIGHTNESS0 0x0127
@@ -34,7 +32,7 @@ extern void s2250loader_cleanup(void);
34#define VPX322_ADDR_CONTRAST0 0x0128 32#define VPX322_ADDR_CONTRAST0 0x0128
35#define VPX322_ADDR_CONTRAST1 0x0132 33#define VPX322_ADDR_CONTRAST1 0x0132
36#define VPX322_ADDR_HUE 0x00dc 34#define VPX322_ADDR_HUE 0x00dc
37#define VPX322_ADDR_SAT 0x0030 35#define VPX322_ADDR_SAT 0x0030
38 36
39struct go7007_usb_board { 37struct go7007_usb_board {
40 unsigned int flags; 38 unsigned int flags;
@@ -43,7 +41,7 @@ struct go7007_usb_board {
43 41
44struct go7007_usb { 42struct go7007_usb {
45 struct go7007_usb_board *board; 43 struct go7007_usb_board *board;
46 struct semaphore i2c_lock; 44 struct mutex i2c_lock;
47 struct usb_device *usbdev; 45 struct usb_device *usbdev;
48 struct urb *video_urbs[8]; 46 struct urb *video_urbs[8];
49 struct urb *audio_urbs[8]; 47 struct urb *audio_urbs[8];
@@ -114,7 +112,7 @@ static u16 vid_regs_fp_pal[] =
114}; 112};
115 113
116struct s2250 { 114struct s2250 {
117 int std; 115 v4l2_std_id std;
118 int input; 116 int input;
119 int brightness; 117 int brightness;
120 int contrast; 118 int contrast;
@@ -165,7 +163,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
165 return -ENOMEM; 163 return -ENOMEM;
166 164
167 usb = go->hpi_context; 165 usb = go->hpi_context;
168 if (down_interruptible(&usb->i2c_lock) != 0) { 166 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
169 printk(KERN_INFO "i2c lock failed\n"); 167 printk(KERN_INFO "i2c lock failed\n");
170 kfree(buf); 168 kfree(buf);
171 return -EINTR; 169 return -EINTR;
@@ -175,7 +173,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
175 buf, 173 buf,
176 16, 1); 174 16, 1);
177 175
178 up(&usb->i2c_lock); 176 mutex_unlock(&usb->i2c_lock);
179 kfree(buf); 177 kfree(buf);
180 return rc; 178 return rc;
181} 179}
@@ -203,19 +201,23 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
203 memset(buf, 0xcd, 6); 201 memset(buf, 0xcd, 6);
204 202
205 usb = go->hpi_context; 203 usb = go->hpi_context;
206 if (down_interruptible(&usb->i2c_lock) != 0) { 204 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
207 printk(KERN_INFO "i2c lock failed\n"); 205 printk(KERN_INFO "i2c lock failed\n");
206 kfree(buf);
208 return -EINTR; 207 return -EINTR;
209 } 208 }
210 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) 209 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
210 kfree(buf);
211 return -EFAULT; 211 return -EFAULT;
212 }
212 213
213 up(&usb->i2c_lock); 214 mutex_unlock(&usb->i2c_lock);
214 if (buf[0] == 0) { 215 if (buf[0] == 0) {
215 unsigned int subaddr, val_read; 216 unsigned int subaddr, val_read;
216 217
217 subaddr = (buf[4] << 8) + buf[5]; 218 subaddr = (buf[4] << 8) + buf[5];
218 val_read = (buf[2] << 8) + buf[3]; 219 val_read = (buf[2] << 8) + buf[3];
220 kfree(buf);
219 if (val_read != val) { 221 if (val_read != val) {
220 printk(KERN_INFO "invalid fp write %x %x\n", 222 printk(KERN_INFO "invalid fp write %x %x\n",
221 val_read, val); 223 val_read, val);
@@ -226,8 +228,10 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
226 subaddr, addr); 228 subaddr, addr);
227 return -EFAULT; 229 return -EFAULT;
228 } 230 }
229 } else 231 } else {
232 kfree(buf);
230 return -EFAULT; 233 return -EFAULT;
234 }
231 235
232 /* save last 12b value */ 236 /* save last 12b value */
233 if (addr == 0x12b) 237 if (addr == 0x12b)
@@ -236,6 +240,45 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
236 return 0; 240 return 0;
237} 241}
238 242
243static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
244{
245 struct go7007 *go = i2c_get_adapdata(client->adapter);
246 struct go7007_usb *usb;
247 u8 *buf;
248
249 if (go == NULL)
250 return -ENODEV;
251
252 if (go->status == STATUS_SHUTDOWN)
253 return -EBUSY;
254
255 buf = kzalloc(16, GFP_KERNEL);
256
257 if (buf == NULL)
258 return -ENOMEM;
259
260
261
262 memset(buf, 0xcd, 6);
263 usb = go->hpi_context;
264 if (down_interruptible(&usb->i2c_lock) != 0) {
265 printk(KERN_INFO "i2c lock failed\n");
266 kfree(buf);
267 return -EINTR;
268 }
269 if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
270 kfree(buf);
271 return -EFAULT;
272 }
273 up(&usb->i2c_lock);
274
275 *val = (buf[0] << 8) | buf[1];
276 kfree(buf);
277
278 return 0;
279}
280
281
239static int write_regs(struct i2c_client *client, u8 *regs) 282static int write_regs(struct i2c_client *client, u8 *regs)
240{ 283{
241 int i; 284 int i;
@@ -350,14 +393,42 @@ static int s2250_command(struct i2c_client *client,
350 { 393 {
351 struct v4l2_control *ctrl = arg; 394 struct v4l2_control *ctrl = arg;
352 int value1; 395 int value1;
396 u16 oldvalue;
353 397
354 switch (ctrl->id) { 398 switch (ctrl->id) {
355 case V4L2_CID_BRIGHTNESS: 399 case V4L2_CID_BRIGHTNESS:
356 printk(KERN_INFO "s2250: future setting\n"); 400 if (ctrl->value > 100)
357 return -EINVAL; 401 dec->brightness = 100;
402 else if (ctrl->value < 0)
403 dec->brightness = 0;
404 else
405 dec->brightness = ctrl->value;
406 value1 = (dec->brightness - 50) * 255 / 100;
407 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
408 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
409 value1 | (oldvalue & ~0xff));
410 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
411 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
412 value1 | (oldvalue & ~0xff));
413 write_reg_fp(client, 0x140, 0x60);
414 break;
358 case V4L2_CID_CONTRAST: 415 case V4L2_CID_CONTRAST:
359 printk(KERN_INFO "s2250: future setting\n"); 416 if (ctrl->value > 100)
360 return -EINVAL; 417 dec->contrast = 100;
418 else if (ctrl->value < 0)
419 dec->contrast = 0;
420 else
421 dec->contrast = ctrl->value;
422 value1 = dec->contrast * 0x40 / 100;
423 if (value1 > 0x3f)
424 value1 = 0x3f; /* max */
425 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
426 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
427 value1 | (oldvalue & ~0x3f));
428 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
429 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
430 value1 | (oldvalue & ~0x3f));
431 write_reg_fp(client, 0x140, 0x60);
361 break; 432 break;
362 case V4L2_CID_SATURATION: 433 case V4L2_CID_SATURATION:
363 if (ctrl->value > 127) 434 if (ctrl->value > 127)
@@ -541,7 +612,7 @@ static int s2250_probe(struct i2c_client *client,
541 dec->audio_input = 0; 612 dec->audio_input = 0;
542 write_reg(client, 0x08, 0x02); /* Line In */ 613 write_reg(client, 0x08, 0x02); /* Line In */
543 614
544 if (down_interruptible(&usb->i2c_lock) == 0) { 615 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
545 data = kzalloc(16, GFP_KERNEL); 616 data = kzalloc(16, GFP_KERNEL);
546 if (data != NULL) { 617 if (data != NULL) {
547 int rc; 618 int rc;
@@ -560,7 +631,7 @@ static int s2250_probe(struct i2c_client *client,
560 } 631 }
561 kfree(data); 632 kfree(data);
562 } 633 }
563 up(&usb->i2c_lock); 634 mutex_unlock(&usb->i2c_lock);
564 } 635 }
565 636
566 printk("s2250: initialized successfully\n"); 637 printk("s2250: initialized successfully\n");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index bb22347af60e..d7bf82983274 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -35,7 +35,7 @@ typedef struct device_extension_s {
35#define MAX_DEVICES 256 35#define MAX_DEVICES 256
36 36
37static pdevice_extension_t s2250_dev_table[MAX_DEVICES]; 37static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
38static DECLARE_MUTEX(s2250_dev_table_mutex); 38static DEFINE_MUTEX(s2250_dev_table_mutex);
39 39
40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref) 40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
41static void s2250loader_delete(struct kref *kref) 41static void s2250loader_delete(struct kref *kref)
@@ -67,7 +67,7 @@ static int s2250loader_probe(struct usb_interface *interface,
67 printk(KERN_ERR "can't handle multiple config\n"); 67 printk(KERN_ERR "can't handle multiple config\n");
68 return -1; 68 return -1;
69 } 69 }
70 down(&s2250_dev_table_mutex); 70 mutex_lock(&s2250_dev_table_mutex);
71 71
72 for (minor = 0; minor < MAX_DEVICES; minor++) { 72 for (minor = 0; minor < MAX_DEVICES; minor++) {
73 if (s2250_dev_table[minor] == NULL) 73 if (s2250_dev_table[minor] == NULL)
@@ -96,7 +96,7 @@ static int s2250loader_probe(struct usb_interface *interface,
96 96
97 kref_init(&(s->kref)); 97 kref_init(&(s->kref));
98 98
99 up(&s2250_dev_table_mutex); 99 mutex_unlock(&s2250_dev_table_mutex);
100 100
101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) { 101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
102 printk(KERN_ERR 102 printk(KERN_ERR
@@ -128,7 +128,7 @@ static int s2250loader_probe(struct usb_interface *interface,
128 return 0; 128 return 0;
129 129
130failed: 130failed:
131 up(&s2250_dev_table_mutex); 131 mutex_unlock(&s2250_dev_table_mutex);
132failed2: 132failed2:
133 if (s) 133 if (s)
134 kref_put(&(s->kref), s2250loader_delete); 134 kref_put(&(s->kref), s2250loader_delete);
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index cd19be6c00e0..03c4dfc138a1 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -26,7 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/semaphore.h> 29#include <linux/mutex.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <asm/system.h> 31#include <asm/system.h>
32#include <sound/core.h> 32#include <sound/core.h>
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 6c3427bb6f4c..506dca6e942e 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -111,7 +111,8 @@ static int wis_tw9903_command(struct i2c_client *client,
111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1)); 111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
112 break; 112 break;
113 } 113 }
114#if 0 /* The scaler on this thing seems to be horribly broken */ 114#if 0
115 /* The scaler on this thing seems to be horribly broken */
115 case DECODER_SET_RESOLUTION: 116 case DECODER_SET_RESOLUTION:
116 { 117 {
117 struct video_decoder_resolution *res = arg; 118 struct video_decoder_resolution *res = arg;
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 660a9c1a1f3f..1fa18f255814 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -39,14 +39,14 @@ dev_t iio_devt;
39EXPORT_SYMBOL(iio_devt); 39EXPORT_SYMBOL(iio_devt);
40 40
41#define IIO_DEV_MAX 256 41#define IIO_DEV_MAX 256
42static char *iio_nodename(struct device *dev) 42static char *iio_devnode(struct device *dev, mode_t *mode)
43{ 43{
44 return kasprintf(GFP_KERNEL, "iio/%s", dev_name(dev)); 44 return kasprintf(GFP_KERNEL, "iio/%s", dev_name(dev));
45} 45}
46 46
47struct class iio_class = { 47struct class iio_class = {
48 .name = "iio", 48 .name = "iio",
49 .nodename = iio_nodename, 49 .devnode = iio_devnode,
50}; 50};
51EXPORT_SYMBOL(iio_class); 51EXPORT_SYMBOL(iio_class);
52 52
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 2bfc41ece0e1..85a1a55815cf 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -858,10 +858,7 @@ static void acm_tty_set_termios(struct tty_struct *tty,
858 if (!ACM_READY(acm)) 858 if (!ACM_READY(acm))
859 return; 859 return;
860 860
861 /* FIXME: Needs to support the tty_baud interface */ 861 newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
862 /* FIXME: Broken on sparc */
863 newline.dwDTERate = cpu_to_le32p(acm_tty_speed +
864 (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
865 newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0; 862 newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
866 newline.bParityType = termios->c_cflag & PARENB ? 863 newline.bParityType = termios->c_cflag & PARENB ?
867 (termios->c_cflag & PARODD ? 1 : 2) + 864 (termios->c_cflag & PARODD ? 1 : 2) +
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 26c09f0257db..9bc112ee7803 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = {
1057 .release = usblp_release, 1057 .release = usblp_release,
1058}; 1058};
1059 1059
1060static char *usblp_nodename(struct device *dev) 1060static char *usblp_devnode(struct device *dev, mode_t *mode)
1061{ 1061{
1062 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); 1062 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
1063} 1063}
1064 1064
1065static struct usb_class_driver usblp_class = { 1065static struct usb_class_driver usblp_class = {
1066 .name = "lp%d", 1066 .name = "lp%d",
1067 .nodename = usblp_nodename, 1067 .devnode = usblp_devnode,
1068 .fops = &usblp_fops, 1068 .fops = &usblp_fops,
1069 .minor_base = USBLP_MINOR_BASE, 1069 .minor_base = USBLP_MINOR_BASE,
1070}; 1070};
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 5cef88929b3e..222ee07ea680 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -67,14 +67,14 @@ static struct usb_class {
67 struct class *class; 67 struct class *class;
68} *usb_class; 68} *usb_class;
69 69
70static char *usb_nodename(struct device *dev) 70static char *usb_devnode(struct device *dev, mode_t *mode)
71{ 71{
72 struct usb_class_driver *drv; 72 struct usb_class_driver *drv;
73 73
74 drv = dev_get_drvdata(dev); 74 drv = dev_get_drvdata(dev);
75 if (!drv || !drv->nodename) 75 if (!drv || !drv->devnode)
76 return NULL; 76 return NULL;
77 return drv->nodename(dev); 77 return drv->devnode(dev, mode);
78} 78}
79 79
80static int init_usb_class(void) 80static int init_usb_class(void)
@@ -100,7 +100,7 @@ static int init_usb_class(void)
100 kfree(usb_class); 100 kfree(usb_class);
101 usb_class = NULL; 101 usb_class = NULL;
102 } 102 }
103 usb_class->class->nodename = usb_nodename; 103 usb_class->class->devnode = usb_devnode;
104 104
105exit: 105exit:
106 return result; 106 return result;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index a26f73880c32..43ee943d757a 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -311,7 +311,7 @@ static struct dev_pm_ops usb_device_pm_ops = {
311#endif /* CONFIG_PM */ 311#endif /* CONFIG_PM */
312 312
313 313
314static char *usb_nodename(struct device *dev) 314static char *usb_devnode(struct device *dev, mode_t *mode)
315{ 315{
316 struct usb_device *usb_dev; 316 struct usb_device *usb_dev;
317 317
@@ -324,7 +324,7 @@ struct device_type usb_device_type = {
324 .name = "usb_device", 324 .name = "usb_device",
325 .release = usb_release_dev, 325 .release = usb_release_dev,
326 .uevent = usb_dev_uevent, 326 .uevent = usb_dev_uevent,
327 .nodename = usb_nodename, 327 .devnode = usb_devnode,
328 .pm = &usb_device_pm_ops, 328 .pm = &usb_device_pm_ops,
329}; 329};
330 330
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 90e1a8dedfa9..e75bb87ee92b 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -727,7 +727,7 @@ static const struct file_operations iowarrior_fops = {
727 .poll = iowarrior_poll, 727 .poll = iowarrior_poll,
728}; 728};
729 729
730static char *iowarrior_nodename(struct device *dev) 730static char *iowarrior_devnode(struct device *dev, mode_t *mode)
731{ 731{
732 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); 732 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
733} 733}
@@ -738,7 +738,7 @@ static char *iowarrior_nodename(struct device *dev)
738 */ 738 */
739static struct usb_class_driver iowarrior_class = { 739static struct usb_class_driver iowarrior_class = {
740 .name = "iowarrior%d", 740 .name = "iowarrior%d",
741 .nodename = iowarrior_nodename, 741 .devnode = iowarrior_devnode,
742 .fops = &iowarrior_fops, 742 .fops = &iowarrior_fops,
743 .minor_base = IOWARRIOR_MINOR_BASE, 743 .minor_base = IOWARRIOR_MINOR_BASE,
744}; 744};
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index c1e2433f640d..97efeaec4d52 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -266,7 +266,7 @@ static const struct file_operations tower_fops = {
266 .llseek = tower_llseek, 266 .llseek = tower_llseek,
267}; 267};
268 268
269static char *legousbtower_nodename(struct device *dev) 269static char *legousbtower_devnode(struct device *dev, mode_t *mode)
270{ 270{
271 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); 271 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
272} 272}
@@ -277,7 +277,7 @@ static char *legousbtower_nodename(struct device *dev)
277 */ 277 */
278static struct usb_class_driver tower_class = { 278static struct usb_class_driver tower_class = {
279 .name = "legousbtower%d", 279 .name = "legousbtower%d",
280 .nodename = legousbtower_nodename, 280 .devnode = legousbtower_devnode,
281 .fops = &tower_fops, 281 .fops = &tower_fops,
282 .minor_base = LEGO_USB_TOWER_MINOR_BASE, 282 .minor_base = LEGO_USB_TOWER_MINOR_BASE,
283}; 283};
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index aec61880f36c..5d25d3e52bf6 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -35,11 +35,6 @@ static struct usb_device_id id_table [] = {
35}; 35};
36MODULE_DEVICE_TABLE(usb, id_table); 36MODULE_DEVICE_TABLE(usb, id_table);
37 37
38struct ark3116_private {
39 spinlock_t lock;
40 u8 termios_initialized;
41};
42
43static inline void ARK3116_SND(struct usb_serial *serial, int seq, 38static inline void ARK3116_SND(struct usb_serial *serial, int seq,
44 __u8 request, __u8 requesttype, 39 __u8 request, __u8 requesttype,
45 __u16 value, __u16 index) 40 __u16 value, __u16 index)
@@ -82,22 +77,11 @@ static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
82static int ark3116_attach(struct usb_serial *serial) 77static int ark3116_attach(struct usb_serial *serial)
83{ 78{
84 char *buf; 79 char *buf;
85 struct ark3116_private *priv;
86 int i;
87
88 for (i = 0; i < serial->num_ports; ++i) {
89 priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL);
90 if (!priv)
91 goto cleanup;
92 spin_lock_init(&priv->lock);
93
94 usb_set_serial_port_data(serial->port[i], priv);
95 }
96 80
97 buf = kmalloc(1, GFP_KERNEL); 81 buf = kmalloc(1, GFP_KERNEL);
98 if (!buf) { 82 if (!buf) {
99 dbg("error kmalloc -> out of mem?"); 83 dbg("error kmalloc -> out of mem?");
100 goto cleanup; 84 return -ENOMEM;
101 } 85 }
102 86
103 /* 3 */ 87 /* 3 */
@@ -149,13 +133,16 @@ static int ark3116_attach(struct usb_serial *serial)
149 133
150 kfree(buf); 134 kfree(buf);
151 return 0; 135 return 0;
136}
152 137
153cleanup: 138static void ark3116_init_termios(struct tty_struct *tty)
154 for (--i; i >= 0; --i) { 139{
155 kfree(usb_get_serial_port_data(serial->port[i])); 140 struct ktermios *termios = tty->termios;
156 usb_set_serial_port_data(serial->port[i], NULL); 141 *termios = tty_std_termios;
157 } 142 termios->c_cflag = B9600 | CS8
158 return -ENOMEM; 143 | CREAD | HUPCL | CLOCAL;
144 termios->c_ispeed = 9600;
145 termios->c_ospeed = 9600;
159} 146}
160 147
161static void ark3116_set_termios(struct tty_struct *tty, 148static void ark3116_set_termios(struct tty_struct *tty,
@@ -163,10 +150,8 @@ static void ark3116_set_termios(struct tty_struct *tty,
163 struct ktermios *old_termios) 150 struct ktermios *old_termios)
164{ 151{
165 struct usb_serial *serial = port->serial; 152 struct usb_serial *serial = port->serial;
166 struct ark3116_private *priv = usb_get_serial_port_data(port);
167 struct ktermios *termios = tty->termios; 153 struct ktermios *termios = tty->termios;
168 unsigned int cflag = termios->c_cflag; 154 unsigned int cflag = termios->c_cflag;
169 unsigned long flags;
170 int baud; 155 int baud;
171 int ark3116_baud; 156 int ark3116_baud;
172 char *buf; 157 char *buf;
@@ -176,16 +161,6 @@ static void ark3116_set_termios(struct tty_struct *tty,
176 161
177 dbg("%s - port %d", __func__, port->number); 162 dbg("%s - port %d", __func__, port->number);
178 163
179 spin_lock_irqsave(&priv->lock, flags);
180 if (!priv->termios_initialized) {
181 *termios = tty_std_termios;
182 termios->c_cflag = B9600 | CS8
183 | CREAD | HUPCL | CLOCAL;
184 termios->c_ispeed = 9600;
185 termios->c_ospeed = 9600;
186 priv->termios_initialized = 1;
187 }
188 spin_unlock_irqrestore(&priv->lock, flags);
189 164
190 cflag = termios->c_cflag; 165 cflag = termios->c_cflag;
191 termios->c_cflag &= ~(CMSPAR|CRTSCTS); 166 termios->c_cflag &= ~(CMSPAR|CRTSCTS);
@@ -318,8 +293,7 @@ static void ark3116_set_termios(struct tty_struct *tty,
318 return; 293 return;
319} 294}
320 295
321static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port, 296static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
322 struct file *filp)
323{ 297{
324 struct ktermios tmp_termios; 298 struct ktermios tmp_termios;
325 struct usb_serial *serial = port->serial; 299 struct usb_serial *serial = port->serial;
@@ -334,7 +308,7 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
334 return -ENOMEM; 308 return -ENOMEM;
335 } 309 }
336 310
337 result = usb_serial_generic_open(tty, port, filp); 311 result = usb_serial_generic_open(tty, port);
338 if (result) 312 if (result)
339 goto err_out; 313 goto err_out;
340 314
@@ -455,6 +429,7 @@ static struct usb_serial_driver ark3116_device = {
455 .num_ports = 1, 429 .num_ports = 1,
456 .attach = ark3116_attach, 430 .attach = ark3116_attach,
457 .set_termios = ark3116_set_termios, 431 .set_termios = ark3116_set_termios,
432 .init_termios = ark3116_init_termios,
458 .ioctl = ark3116_ioctl, 433 .ioctl = ark3116_ioctl,
459 .tiocmget = ark3116_tiocmget, 434 .tiocmget = ark3116_tiocmget,
460 .open = ark3116_open, 435 .open = ark3116_open,
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 7033b031b443..a0467bc61627 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -92,7 +92,7 @@ static int debug;
92static int belkin_sa_startup(struct usb_serial *serial); 92static int belkin_sa_startup(struct usb_serial *serial);
93static void belkin_sa_release(struct usb_serial *serial); 93static void belkin_sa_release(struct usb_serial *serial);
94static int belkin_sa_open(struct tty_struct *tty, 94static int belkin_sa_open(struct tty_struct *tty,
95 struct usb_serial_port *port, struct file *filp); 95 struct usb_serial_port *port);
96static void belkin_sa_close(struct usb_serial_port *port); 96static void belkin_sa_close(struct usb_serial_port *port);
97static void belkin_sa_read_int_callback(struct urb *urb); 97static void belkin_sa_read_int_callback(struct urb *urb);
98static void belkin_sa_set_termios(struct tty_struct *tty, 98static void belkin_sa_set_termios(struct tty_struct *tty,
@@ -213,7 +213,7 @@ static void belkin_sa_release(struct usb_serial *serial)
213 213
214 214
215static int belkin_sa_open(struct tty_struct *tty, 215static int belkin_sa_open(struct tty_struct *tty,
216 struct usb_serial_port *port, struct file *filp) 216 struct usb_serial_port *port)
217{ 217{
218 int retval = 0; 218 int retval = 0;
219 219
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 2830766f5b39..8c894a7d5dcf 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -300,8 +300,7 @@ static void ch341_close(struct usb_serial_port *port)
300 300
301 301
302/* open this device, set default parameters */ 302/* open this device, set default parameters */
303static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, 303static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
304 struct file *filp)
305{ 304{
306 struct usb_serial *serial = port->serial; 305 struct usb_serial *serial = port->serial;
307 struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); 306 struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
@@ -333,7 +332,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
333 return -EPROTO; 332 return -EPROTO;
334 } 333 }
335 334
336 r = usb_serial_generic_open(tty, port, filp); 335 r = usb_serial_generic_open(tty, port);
337 336
338out: return r; 337out: return r;
339} 338}
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 0e4f2e41ace5..b22ac3258523 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/tty.h> 17#include <linux/tty.h>
18#include <linux/console.h> 18#include <linux/console.h>
19#include <linux/serial.h>
19#include <linux/usb.h> 20#include <linux/usb.h>
20#include <linux/usb/serial.h> 21#include <linux/usb/serial.h>
21 22
@@ -63,7 +64,7 @@ static int usb_console_setup(struct console *co, char *options)
63 char *s; 64 char *s;
64 struct usb_serial *serial; 65 struct usb_serial *serial;
65 struct usb_serial_port *port; 66 struct usb_serial_port *port;
66 int retval = 0; 67 int retval;
67 struct tty_struct *tty = NULL; 68 struct tty_struct *tty = NULL;
68 struct ktermios *termios = NULL, dummy; 69 struct ktermios *termios = NULL, dummy;
69 70
@@ -116,13 +117,17 @@ static int usb_console_setup(struct console *co, char *options)
116 return -ENODEV; 117 return -ENODEV;
117 } 118 }
118 119
119 port = serial->port[0]; 120 retval = usb_autopm_get_interface(serial->interface);
121 if (retval)
122 goto error_get_interface;
123
124 port = serial->port[co->index - serial->minor];
120 tty_port_tty_set(&port->port, NULL); 125 tty_port_tty_set(&port->port, NULL);
121 126
122 info->port = port; 127 info->port = port;
123 128
124 ++port->port.count; 129 ++port->port.count;
125 if (port->port.count == 1) { 130 if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
126 if (serial->type->set_termios) { 131 if (serial->type->set_termios) {
127 /* 132 /*
128 * allocate a fake tty so the driver can initialize 133 * allocate a fake tty so the driver can initialize
@@ -150,9 +155,9 @@ static int usb_console_setup(struct console *co, char *options)
150 /* only call the device specific open if this 155 /* only call the device specific open if this
151 * is the first time the port is opened */ 156 * is the first time the port is opened */
152 if (serial->type->open) 157 if (serial->type->open)
153 retval = serial->type->open(NULL, port, NULL); 158 retval = serial->type->open(NULL, port);
154 else 159 else
155 retval = usb_serial_generic_open(NULL, port, NULL); 160 retval = usb_serial_generic_open(NULL, port);
156 161
157 if (retval) { 162 if (retval) {
158 err("could not open USB console port"); 163 err("could not open USB console port");
@@ -168,6 +173,7 @@ static int usb_console_setup(struct console *co, char *options)
168 kfree(termios); 173 kfree(termios);
169 kfree(tty); 174 kfree(tty);
170 } 175 }
176 set_bit(ASYNCB_INITIALIZED, &port->port.flags);
171 } 177 }
172 /* Now that any required fake tty operations are completed restore 178 /* Now that any required fake tty operations are completed restore
173 * the tty port count */ 179 * the tty port count */
@@ -175,18 +181,22 @@ static int usb_console_setup(struct console *co, char *options)
175 /* The console is special in terms of closing the device so 181 /* The console is special in terms of closing the device so
176 * indicate this port is now acting as a system console. */ 182 * indicate this port is now acting as a system console. */
177 port->console = 1; 183 port->console = 1;
178 retval = 0;
179 184
180out: 185 mutex_unlock(&serial->disc_mutex);
181 return retval; 186 return retval;
182free_termios: 187
188 free_termios:
183 kfree(termios); 189 kfree(termios);
184 tty_port_tty_set(&port->port, NULL); 190 tty_port_tty_set(&port->port, NULL);
185free_tty: 191 free_tty:
186 kfree(tty); 192 kfree(tty);
187reset_open_count: 193 reset_open_count:
188 port->port.count = 0; 194 port->port.count = 0;
189 goto out; 195 usb_autopm_put_interface(serial->interface);
196 error_get_interface:
197 usb_serial_put(serial);
198 mutex_unlock(&serial->disc_mutex);
199 return retval;
190} 200}
191 201
192static void usb_console_write(struct console *co, 202static void usb_console_write(struct console *co,
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 985cbcf48bda..4a208fe85bc9 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -33,8 +33,7 @@
33/* 33/*
34 * Function Prototypes 34 * Function Prototypes
35 */ 35 */
36static int cp210x_open(struct tty_struct *, struct usb_serial_port *, 36static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
37 struct file *);
38static void cp210x_cleanup(struct usb_serial_port *); 37static void cp210x_cleanup(struct usb_serial_port *);
39static void cp210x_close(struct usb_serial_port *); 38static void cp210x_close(struct usb_serial_port *);
40static void cp210x_get_termios(struct tty_struct *, 39static void cp210x_get_termios(struct tty_struct *,
@@ -368,8 +367,7 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
368 return baud; 367 return baud;
369} 368}
370 369
371static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port, 370static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
372 struct file *filp)
373{ 371{
374 struct usb_serial *serial = port->serial; 372 struct usb_serial *serial = port->serial;
375 int result; 373 int result;
@@ -399,12 +397,6 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port,
399 397
400 /* Configure the termios structure */ 398 /* Configure the termios structure */
401 cp210x_get_termios(tty, port); 399 cp210x_get_termios(tty, port);
402
403 /* Set the DTR and RTS pins low */
404 cp210x_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data
405 : port,
406 NULL, TIOCM_DTR | TIOCM_RTS, 0);
407
408 return 0; 400 return 0;
409} 401}
410 402
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 336523fd7366..b0f6402a91ca 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -61,7 +61,7 @@ static int cyberjack_startup(struct usb_serial *serial);
61static void cyberjack_disconnect(struct usb_serial *serial); 61static void cyberjack_disconnect(struct usb_serial *serial);
62static void cyberjack_release(struct usb_serial *serial); 62static void cyberjack_release(struct usb_serial *serial);
63static int cyberjack_open(struct tty_struct *tty, 63static int cyberjack_open(struct tty_struct *tty,
64 struct usb_serial_port *port, struct file *filp); 64 struct usb_serial_port *port);
65static void cyberjack_close(struct usb_serial_port *port); 65static void cyberjack_close(struct usb_serial_port *port);
66static int cyberjack_write(struct tty_struct *tty, 66static int cyberjack_write(struct tty_struct *tty,
67 struct usb_serial_port *port, const unsigned char *buf, int count); 67 struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -173,7 +173,7 @@ static void cyberjack_release(struct usb_serial *serial)
173} 173}
174 174
175static int cyberjack_open(struct tty_struct *tty, 175static int cyberjack_open(struct tty_struct *tty,
176 struct usb_serial_port *port, struct file *filp) 176 struct usb_serial_port *port)
177{ 177{
178 struct cyberjack_private *priv; 178 struct cyberjack_private *priv;
179 unsigned long flags; 179 unsigned long flags;
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 59adfe123110..e0a8b715f2f2 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -172,8 +172,7 @@ static int cypress_earthmate_startup(struct usb_serial *serial);
172static int cypress_hidcom_startup(struct usb_serial *serial); 172static int cypress_hidcom_startup(struct usb_serial *serial);
173static int cypress_ca42v2_startup(struct usb_serial *serial); 173static int cypress_ca42v2_startup(struct usb_serial *serial);
174static void cypress_release(struct usb_serial *serial); 174static void cypress_release(struct usb_serial *serial);
175static int cypress_open(struct tty_struct *tty, 175static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
176 struct usb_serial_port *port, struct file *filp);
177static void cypress_close(struct usb_serial_port *port); 176static void cypress_close(struct usb_serial_port *port);
178static void cypress_dtr_rts(struct usb_serial_port *port, int on); 177static void cypress_dtr_rts(struct usb_serial_port *port, int on);
179static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 178static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -633,8 +632,7 @@ static void cypress_release(struct usb_serial *serial)
633} 632}
634 633
635 634
636static int cypress_open(struct tty_struct *tty, 635static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
637 struct usb_serial_port *port, struct file *filp)
638{ 636{
639 struct cypress_private *priv = usb_get_serial_port_data(port); 637 struct cypress_private *priv = usb_get_serial_port_data(port);
640 struct usb_serial *serial = port->serial; 638 struct usb_serial *serial = port->serial;
@@ -659,15 +657,7 @@ static int cypress_open(struct tty_struct *tty,
659 spin_unlock_irqrestore(&priv->lock, flags); 657 spin_unlock_irqrestore(&priv->lock, flags);
660 658
661 /* Set termios */ 659 /* Set termios */
662 result = cypress_write(tty, port, NULL, 0); 660 cypress_send(port);
663
664 if (result) {
665 dev_err(&port->dev,
666 "%s - failed setting the control lines - error %d\n",
667 __func__, result);
668 return result;
669 } else
670 dbg("%s - success setting the control lines", __func__);
671 661
672 if (tty) 662 if (tty)
673 cypress_set_termios(tty, port, &priv->tmp_termios); 663 cypress_set_termios(tty, port, &priv->tmp_termios);
@@ -1005,6 +995,8 @@ static void cypress_set_termios(struct tty_struct *tty,
1005 dbg("%s - port %d", __func__, port->number); 995 dbg("%s - port %d", __func__, port->number);
1006 996
1007 spin_lock_irqsave(&priv->lock, flags); 997 spin_lock_irqsave(&priv->lock, flags);
998 /* We can't clean this one up as we don't know the device type
999 early enough */
1008 if (!priv->termios_initialized) { 1000 if (!priv->termios_initialized) {
1009 if (priv->chiptype == CT_EARTHMATE) { 1001 if (priv->chiptype == CT_EARTHMATE) {
1010 *(tty->termios) = tty_std_termios; 1002 *(tty->termios) = tty_std_termios;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index f4808091c47c..ab3dd991586b 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -453,8 +453,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
453static void digi_write_bulk_callback(struct urb *urb); 453static void digi_write_bulk_callback(struct urb *urb);
454static int digi_write_room(struct tty_struct *tty); 454static int digi_write_room(struct tty_struct *tty);
455static int digi_chars_in_buffer(struct tty_struct *tty); 455static int digi_chars_in_buffer(struct tty_struct *tty);
456static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, 456static int digi_open(struct tty_struct *tty, struct usb_serial_port *port);
457 struct file *filp);
458static void digi_close(struct usb_serial_port *port); 457static void digi_close(struct usb_serial_port *port);
459static int digi_carrier_raised(struct usb_serial_port *port); 458static int digi_carrier_raised(struct usb_serial_port *port);
460static void digi_dtr_rts(struct usb_serial_port *port, int on); 459static void digi_dtr_rts(struct usb_serial_port *port, int on);
@@ -1347,8 +1346,7 @@ static int digi_carrier_raised(struct usb_serial_port *port)
1347 return 0; 1346 return 0;
1348} 1347}
1349 1348
1350static int digi_open(struct tty_struct *tty, struct usb_serial_port *port, 1349static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
1351 struct file *filp)
1352{ 1350{
1353 int ret; 1351 int ret;
1354 unsigned char buf[32]; 1352 unsigned char buf[32];
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 80cb3471adbe..33c9e9cf9eb2 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -79,8 +79,7 @@ static int debug;
79#define EMPEG_PRODUCT_ID 0x0001 79#define EMPEG_PRODUCT_ID 0x0001
80 80
81/* function prototypes for an empeg-car player */ 81/* function prototypes for an empeg-car player */
82static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port, 82static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port);
83 struct file *filp);
84static void empeg_close(struct usb_serial_port *port); 83static void empeg_close(struct usb_serial_port *port);
85static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port, 84static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
86 const unsigned char *buf, 85 const unsigned char *buf,
@@ -90,8 +89,7 @@ static int empeg_chars_in_buffer(struct tty_struct *tty);
90static void empeg_throttle(struct tty_struct *tty); 89static void empeg_throttle(struct tty_struct *tty);
91static void empeg_unthrottle(struct tty_struct *tty); 90static void empeg_unthrottle(struct tty_struct *tty);
92static int empeg_startup(struct usb_serial *serial); 91static int empeg_startup(struct usb_serial *serial);
93static void empeg_set_termios(struct tty_struct *tty, 92static void empeg_init_termios(struct tty_struct *tty);
94 struct usb_serial_port *port, struct ktermios *old_termios);
95static void empeg_write_bulk_callback(struct urb *urb); 93static void empeg_write_bulk_callback(struct urb *urb);
96static void empeg_read_bulk_callback(struct urb *urb); 94static void empeg_read_bulk_callback(struct urb *urb);
97 95
@@ -123,7 +121,7 @@ static struct usb_serial_driver empeg_device = {
123 .throttle = empeg_throttle, 121 .throttle = empeg_throttle,
124 .unthrottle = empeg_unthrottle, 122 .unthrottle = empeg_unthrottle,
125 .attach = empeg_startup, 123 .attach = empeg_startup,
126 .set_termios = empeg_set_termios, 124 .init_termios = empeg_init_termios,
127 .write = empeg_write, 125 .write = empeg_write,
128 .write_room = empeg_write_room, 126 .write_room = empeg_write_room,
129 .chars_in_buffer = empeg_chars_in_buffer, 127 .chars_in_buffer = empeg_chars_in_buffer,
@@ -142,17 +140,13 @@ static int bytes_out;
142/****************************************************************************** 140/******************************************************************************
143 * Empeg specific driver functions 141 * Empeg specific driver functions
144 ******************************************************************************/ 142 ******************************************************************************/
145static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port, 143static int empeg_open(struct tty_struct *tty,struct usb_serial_port *port)
146 struct file *filp)
147{ 144{
148 struct usb_serial *serial = port->serial; 145 struct usb_serial *serial = port->serial;
149 int result = 0; 146 int result = 0;
150 147
151 dbg("%s - port %d", __func__, port->number); 148 dbg("%s - port %d", __func__, port->number);
152 149
153 /* Force default termio settings */
154 empeg_set_termios(tty, port, NULL) ;
155
156 bytes_in = 0; 150 bytes_in = 0;
157 bytes_out = 0; 151 bytes_out = 0;
158 152
@@ -425,11 +419,9 @@ static int empeg_startup(struct usb_serial *serial)
425} 419}
426 420
427 421
428static void empeg_set_termios(struct tty_struct *tty, 422static void empeg_init_termios(struct tty_struct *tty)
429 struct usb_serial_port *port, struct ktermios *old_termios)
430{ 423{
431 struct ktermios *termios = tty->termios; 424 struct ktermios *termios = tty->termios;
432 dbg("%s - port %d", __func__, port->number);
433 425
434 /* 426 /*
435 * The empeg-car player wants these particular tty settings. 427 * The empeg-car player wants these particular tty settings.
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8fec5d4455c9..76a17f915eef 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -747,8 +747,7 @@ static int ftdi_sio_probe(struct usb_serial *serial,
747 const struct usb_device_id *id); 747 const struct usb_device_id *id);
748static int ftdi_sio_port_probe(struct usb_serial_port *port); 748static int ftdi_sio_port_probe(struct usb_serial_port *port);
749static int ftdi_sio_port_remove(struct usb_serial_port *port); 749static int ftdi_sio_port_remove(struct usb_serial_port *port);
750static int ftdi_open(struct tty_struct *tty, 750static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port);
751 struct usb_serial_port *port, struct file *filp);
752static void ftdi_close(struct usb_serial_port *port); 751static void ftdi_close(struct usb_serial_port *port);
753static void ftdi_dtr_rts(struct usb_serial_port *port, int on); 752static void ftdi_dtr_rts(struct usb_serial_port *port, int on);
754static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, 753static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -1680,8 +1679,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
1680 return 0; 1679 return 0;
1681} 1680}
1682 1681
1683static int ftdi_open(struct tty_struct *tty, 1682static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1684 struct usb_serial_port *port, struct file *filp)
1685{ /* ftdi_open */ 1683{ /* ftdi_open */
1686 struct usb_device *dev = port->serial->dev; 1684 struct usb_device *dev = port->serial->dev;
1687 struct ftdi_private *priv = usb_get_serial_port_data(port); 1685 struct ftdi_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 8839f1c70b7f..20432d345529 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -933,8 +933,7 @@ static int garmin_init_session(struct usb_serial_port *port)
933 933
934 934
935 935
936static int garmin_open(struct tty_struct *tty, 936static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port)
937 struct usb_serial_port *port, struct file *filp)
938{ 937{
939 unsigned long flags; 938 unsigned long flags;
940 int status = 0; 939 int status = 0;
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index ce57f6a32bdf..d9398e9f30ce 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -114,8 +114,7 @@ void usb_serial_generic_deregister(void)
114#endif 114#endif
115} 115}
116 116
117int usb_serial_generic_open(struct tty_struct *tty, 117int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
118 struct usb_serial_port *port, struct file *filp)
119{ 118{
120 struct usb_serial *serial = port->serial; 119 struct usb_serial *serial = port->serial;
121 int result = 0; 120 int result = 0;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 0191693625d6..dc0f832657e6 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -205,8 +205,7 @@ static void edge_bulk_out_data_callback(struct urb *urb);
205static void edge_bulk_out_cmd_callback(struct urb *urb); 205static void edge_bulk_out_cmd_callback(struct urb *urb);
206 206
207/* function prototypes for the usbserial callbacks */ 207/* function prototypes for the usbserial callbacks */
208static int edge_open(struct tty_struct *tty, struct usb_serial_port *port, 208static int edge_open(struct tty_struct *tty, struct usb_serial_port *port);
209 struct file *filp);
210static void edge_close(struct usb_serial_port *port); 209static void edge_close(struct usb_serial_port *port);
211static int edge_write(struct tty_struct *tty, struct usb_serial_port *port, 210static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
212 const unsigned char *buf, int count); 211 const unsigned char *buf, int count);
@@ -852,8 +851,7 @@ static void edge_bulk_out_cmd_callback(struct urb *urb)
852 * If successful, we return 0 851 * If successful, we return 0
853 * Otherwise we return a negative error number. 852 * Otherwise we return a negative error number.
854 *****************************************************************************/ 853 *****************************************************************************/
855static int edge_open(struct tty_struct *tty, 854static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
856 struct usb_serial_port *port, struct file *filp)
857{ 855{
858 struct edgeport_port *edge_port = usb_get_serial_port_data(port); 856 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
859 struct usb_serial *serial; 857 struct usb_serial *serial;
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index e8bc42f92e79..d4cc0f7af400 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1831,8 +1831,7 @@ static void edge_bulk_out_callback(struct urb *urb)
1831 tty_kref_put(tty); 1831 tty_kref_put(tty);
1832} 1832}
1833 1833
1834static int edge_open(struct tty_struct *tty, 1834static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
1835 struct usb_serial_port *port, struct file *filp)
1836{ 1835{
1837 struct edgeport_port *edge_port = usb_get_serial_port_data(port); 1836 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
1838 struct edgeport_serial *edge_serial; 1837 struct edgeport_serial *edge_serial;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 2545d45ce16f..24fcc64b837d 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -75,7 +75,7 @@ static int initial_wait;
75 75
76/* Function prototypes for an ipaq */ 76/* Function prototypes for an ipaq */
77static int ipaq_open(struct tty_struct *tty, 77static int ipaq_open(struct tty_struct *tty,
78 struct usb_serial_port *port, struct file *filp); 78 struct usb_serial_port *port);
79static void ipaq_close(struct usb_serial_port *port); 79static void ipaq_close(struct usb_serial_port *port);
80static int ipaq_calc_num_ports(struct usb_serial *serial); 80static int ipaq_calc_num_ports(struct usb_serial *serial);
81static int ipaq_startup(struct usb_serial *serial); 81static int ipaq_startup(struct usb_serial *serial);
@@ -587,7 +587,7 @@ static int bytes_in;
587static int bytes_out; 587static int bytes_out;
588 588
589static int ipaq_open(struct tty_struct *tty, 589static int ipaq_open(struct tty_struct *tty,
590 struct usb_serial_port *port, struct file *filp) 590 struct usb_serial_port *port)
591{ 591{
592 struct usb_serial *serial = port->serial; 592 struct usb_serial *serial = port->serial;
593 struct ipaq_private *priv; 593 struct ipaq_private *priv;
@@ -628,11 +628,6 @@ static int ipaq_open(struct tty_struct *tty,
628 priv->free_len += PACKET_SIZE; 628 priv->free_len += PACKET_SIZE;
629 } 629 }
630 630
631 if (tty) {
632 /* FIXME: These two are bogus */
633 tty->raw = 1;
634 tty->real_raw = 1;
635 }
636 /* 631 /*
637 * Lose the small buffers usbserial provides. Make larger ones. 632 * Lose the small buffers usbserial provides. Make larger ones.
638 */ 633 */
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 29ad038b9c8d..727d323f092a 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -193,8 +193,7 @@ static void ipw_read_bulk_callback(struct urb *urb)
193 return; 193 return;
194} 194}
195 195
196static int ipw_open(struct tty_struct *tty, 196static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port)
197 struct usb_serial_port *port, struct file *filp)
198{ 197{
199 struct usb_device *dev = port->serial->dev; 198 struct usb_device *dev = port->serial->dev;
200 u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT; 199 u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT;
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 66009b6b763a..95d8d26b9a44 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -86,8 +86,7 @@ static int buffer_size;
86static int xbof = -1; 86static int xbof = -1;
87 87
88static int ir_startup (struct usb_serial *serial); 88static int ir_startup (struct usb_serial *serial);
89static int ir_open(struct tty_struct *tty, struct usb_serial_port *port, 89static int ir_open(struct tty_struct *tty, struct usb_serial_port *port);
90 struct file *filep);
91static void ir_close(struct usb_serial_port *port); 90static void ir_close(struct usb_serial_port *port);
92static int ir_write(struct tty_struct *tty, struct usb_serial_port *port, 91static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
93 const unsigned char *buf, int count); 92 const unsigned char *buf, int count);
@@ -296,8 +295,7 @@ static int ir_startup(struct usb_serial *serial)
296 return 0; 295 return 0;
297} 296}
298 297
299static int ir_open(struct tty_struct *tty, 298static int ir_open(struct tty_struct *tty, struct usb_serial_port *port)
300 struct usb_serial_port *port, struct file *filp)
301{ 299{
302 char *buffer; 300 char *buffer;
303 int result = 0; 301 int result = 0;
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 96873a7a32b0..6138c1cda35f 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -71,7 +71,6 @@ struct iuu_private {
71 spinlock_t lock; /* store irq state */ 71 spinlock_t lock; /* store irq state */
72 wait_queue_head_t delta_msr_wait; 72 wait_queue_head_t delta_msr_wait;
73 u8 line_status; 73 u8 line_status;
74 u8 termios_initialized;
75 int tiostatus; /* store IUART SIGNAL for tiocmget call */ 74 int tiostatus; /* store IUART SIGNAL for tiocmget call */
76 u8 reset; /* if 1 reset is needed */ 75 u8 reset; /* if 1 reset is needed */
77 int poll; /* number of poll */ 76 int poll; /* number of poll */
@@ -1018,14 +1017,24 @@ static void iuu_close(struct usb_serial_port *port)
1018 } 1017 }
1019} 1018}
1020 1019
1021static int iuu_open(struct tty_struct *tty, 1020static void iuu_init_termios(struct tty_struct *tty)
1022 struct usb_serial_port *port, struct file *filp) 1021{
1022 *(tty->termios) = tty_std_termios;
1023 tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
1024 | TIOCM_CTS | CSTOPB | PARENB;
1025 tty->termios->c_ispeed = 9600;
1026 tty->termios->c_ospeed = 9600;
1027 tty->termios->c_lflag = 0;
1028 tty->termios->c_oflag = 0;
1029 tty->termios->c_iflag = 0;
1030}
1031
1032static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
1023{ 1033{
1024 struct usb_serial *serial = port->serial; 1034 struct usb_serial *serial = port->serial;
1025 u8 *buf; 1035 u8 *buf;
1026 int result; 1036 int result;
1027 u32 actual; 1037 u32 actual;
1028 unsigned long flags;
1029 struct iuu_private *priv = usb_get_serial_port_data(port); 1038 struct iuu_private *priv = usb_get_serial_port_data(port);
1030 1039
1031 dbg("%s - port %d", __func__, port->number); 1040 dbg("%s - port %d", __func__, port->number);
@@ -1064,21 +1073,7 @@ static int iuu_open(struct tty_struct *tty,
1064 port->bulk_in_buffer, 512, 1073 port->bulk_in_buffer, 512,
1065 NULL, NULL); 1074 NULL, NULL);
1066 1075
1067 /* set the termios structure */ 1076 priv->poll = 0;
1068 spin_lock_irqsave(&priv->lock, flags);
1069 if (tty && !priv->termios_initialized) {
1070 *(tty->termios) = tty_std_termios;
1071 tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
1072 | TIOCM_CTS | CSTOPB | PARENB;
1073 tty->termios->c_ispeed = 9600;
1074 tty->termios->c_ospeed = 9600;
1075 tty->termios->c_lflag = 0;
1076 tty->termios->c_oflag = 0;
1077 tty->termios->c_iflag = 0;
1078 priv->termios_initialized = 1;
1079 priv->poll = 0;
1080 }
1081 spin_unlock_irqrestore(&priv->lock, flags);
1082 1077
1083 /* initialize writebuf */ 1078 /* initialize writebuf */
1084#define FISH(a, b, c, d) do { \ 1079#define FISH(a, b, c, d) do { \
@@ -1201,6 +1196,7 @@ static struct usb_serial_driver iuu_device = {
1201 .tiocmget = iuu_tiocmget, 1196 .tiocmget = iuu_tiocmget,
1202 .tiocmset = iuu_tiocmset, 1197 .tiocmset = iuu_tiocmset,
1203 .set_termios = iuu_set_termios, 1198 .set_termios = iuu_set_termios,
1199 .init_termios = iuu_init_termios,
1204 .attach = iuu_startup, 1200 .attach = iuu_startup,
1205 .release = iuu_release, 1201 .release = iuu_release,
1206}; 1202};
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 2594b8743d3f..f8c4b07033ff 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1209,8 +1209,7 @@ static int keyspan_write_room(struct tty_struct *tty)
1209} 1209}
1210 1210
1211 1211
1212static int keyspan_open(struct tty_struct *tty, 1212static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
1213 struct usb_serial_port *port, struct file *filp)
1214{ 1213{
1215 struct keyspan_port_private *p_priv; 1214 struct keyspan_port_private *p_priv;
1216 struct keyspan_serial_private *s_priv; 1215 struct keyspan_serial_private *s_priv;
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 3107ed15af64..30771e5b3973 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -36,8 +36,7 @@
36 36
37/* Function prototypes for Keyspan serial converter */ 37/* Function prototypes for Keyspan serial converter */
38static int keyspan_open (struct tty_struct *tty, 38static int keyspan_open (struct tty_struct *tty,
39 struct usb_serial_port *port, 39 struct usb_serial_port *port);
40 struct file *filp);
41static void keyspan_close (struct usb_serial_port *port); 40static void keyspan_close (struct usb_serial_port *port);
42static void keyspan_dtr_rts (struct usb_serial_port *port, int on); 41static void keyspan_dtr_rts (struct usb_serial_port *port, int on);
43static int keyspan_startup (struct usb_serial *serial); 42static int keyspan_startup (struct usb_serial *serial);
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index d0b12e40c2b1..257c16cc6b2a 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -681,7 +681,7 @@ static int keyspan_pda_carrier_raised(struct usb_serial_port *port)
681 681
682 682
683static int keyspan_pda_open(struct tty_struct *tty, 683static int keyspan_pda_open(struct tty_struct *tty,
684 struct usb_serial_port *port, struct file *filp) 684 struct usb_serial_port *port)
685{ 685{
686 struct usb_serial *serial = port->serial; 686 struct usb_serial *serial = port->serial;
687 unsigned char room; 687 unsigned char room;
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 0f44bb8e8d4f..a61673133d7d 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -75,8 +75,7 @@ static int debug;
75static int klsi_105_startup(struct usb_serial *serial); 75static int klsi_105_startup(struct usb_serial *serial);
76static void klsi_105_disconnect(struct usb_serial *serial); 76static void klsi_105_disconnect(struct usb_serial *serial);
77static void klsi_105_release(struct usb_serial *serial); 77static void klsi_105_release(struct usb_serial *serial);
78static int klsi_105_open(struct tty_struct *tty, 78static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
79 struct usb_serial_port *port, struct file *filp);
80static void klsi_105_close(struct usb_serial_port *port); 79static void klsi_105_close(struct usb_serial_port *port);
81static int klsi_105_write(struct tty_struct *tty, 80static int klsi_105_write(struct tty_struct *tty,
82 struct usb_serial_port *port, const unsigned char *buf, int count); 81 struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -358,8 +357,7 @@ static void klsi_105_release(struct usb_serial *serial)
358 } 357 }
359} /* klsi_105_release */ 358} /* klsi_105_release */
360 359
361static int klsi_105_open(struct tty_struct *tty, 360static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
362 struct usb_serial_port *port, struct file *filp)
363{ 361{
364 struct klsi_105_private *priv = usb_get_serial_port_data(port); 362 struct klsi_105_private *priv = usb_get_serial_port_data(port);
365 int retval = 0; 363 int retval = 0;
@@ -371,10 +369,6 @@ static int klsi_105_open(struct tty_struct *tty,
371 369
372 dbg("%s port %d", __func__, port->number); 370 dbg("%s port %d", __func__, port->number);
373 371
374 /* force low_latency on so that our tty_push actually forces
375 * the data through
376 * tty->low_latency = 1; */
377
378 /* Do a defined restart: 372 /* Do a defined restart:
379 * Set up sane default baud rate and send the 'READ_ON' 373 * Set up sane default baud rate and send the 'READ_ON'
380 * vendor command. 374 * vendor command.
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 6db0e561f680..45ea694b3ae6 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -70,8 +70,7 @@ static int debug;
70/* Function prototypes */ 70/* Function prototypes */
71static int kobil_startup(struct usb_serial *serial); 71static int kobil_startup(struct usb_serial *serial);
72static void kobil_release(struct usb_serial *serial); 72static void kobil_release(struct usb_serial *serial);
73static int kobil_open(struct tty_struct *tty, 73static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
74 struct usb_serial_port *port, struct file *filp);
75static void kobil_close(struct usb_serial_port *port); 74static void kobil_close(struct usb_serial_port *port);
76static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, 75static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
77 const unsigned char *buf, int count); 76 const unsigned char *buf, int count);
@@ -85,7 +84,7 @@ static void kobil_read_int_callback(struct urb *urb);
85static void kobil_write_callback(struct urb *purb); 84static void kobil_write_callback(struct urb *purb);
86static void kobil_set_termios(struct tty_struct *tty, 85static void kobil_set_termios(struct tty_struct *tty,
87 struct usb_serial_port *port, struct ktermios *old); 86 struct usb_serial_port *port, struct ktermios *old);
88 87static void kobil_init_termios(struct tty_struct *tty);
89 88
90static struct usb_device_id id_table [] = { 89static struct usb_device_id id_table [] = {
91 { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) }, 90 { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
@@ -120,6 +119,7 @@ static struct usb_serial_driver kobil_device = {
120 .release = kobil_release, 119 .release = kobil_release,
121 .ioctl = kobil_ioctl, 120 .ioctl = kobil_ioctl,
122 .set_termios = kobil_set_termios, 121 .set_termios = kobil_set_termios,
122 .init_termios = kobil_init_termios,
123 .tiocmget = kobil_tiocmget, 123 .tiocmget = kobil_tiocmget,
124 .tiocmset = kobil_tiocmset, 124 .tiocmset = kobil_tiocmset,
125 .open = kobil_open, 125 .open = kobil_open,
@@ -210,9 +210,17 @@ static void kobil_release(struct usb_serial *serial)
210 kfree(usb_get_serial_port_data(serial->port[i])); 210 kfree(usb_get_serial_port_data(serial->port[i]));
211} 211}
212 212
213static void kobil_init_termios(struct tty_struct *tty)
214{
215 /* Default to echo off and other sane device settings */
216 tty->termios->c_lflag = 0;
217 tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
218 tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
219 /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
220 tty->termios->c_oflag &= ~ONLCR;
221}
213 222
214static int kobil_open(struct tty_struct *tty, 223static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
215 struct usb_serial_port *port, struct file *filp)
216{ 224{
217 int result = 0; 225 int result = 0;
218 struct kobil_private *priv; 226 struct kobil_private *priv;
@@ -226,16 +234,6 @@ static int kobil_open(struct tty_struct *tty,
226 /* someone sets the dev to 0 if the close method has been called */ 234 /* someone sets the dev to 0 if the close method has been called */
227 port->interrupt_in_urb->dev = port->serial->dev; 235 port->interrupt_in_urb->dev = port->serial->dev;
228 236
229 if (tty) {
230
231 /* Default to echo off and other sane device settings */
232 tty->termios->c_lflag = 0;
233 tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
234 XCASE);
235 tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
236 /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
237 tty->termios->c_oflag &= ~ONLCR;
238 }
239 /* allocate memory for transfer buffer */ 237 /* allocate memory for transfer buffer */
240 transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); 238 transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
241 if (!transfer_buffer) 239 if (!transfer_buffer)
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index d8825e159aa5..ad4998bbf16f 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -93,8 +93,7 @@ static int debug;
93 */ 93 */
94static int mct_u232_startup(struct usb_serial *serial); 94static int mct_u232_startup(struct usb_serial *serial);
95static void mct_u232_release(struct usb_serial *serial); 95static void mct_u232_release(struct usb_serial *serial);
96static int mct_u232_open(struct tty_struct *tty, 96static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
97 struct usb_serial_port *port, struct file *filp);
98static void mct_u232_close(struct usb_serial_port *port); 97static void mct_u232_close(struct usb_serial_port *port);
99static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); 98static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
100static void mct_u232_read_int_callback(struct urb *urb); 99static void mct_u232_read_int_callback(struct urb *urb);
@@ -421,8 +420,7 @@ static void mct_u232_release(struct usb_serial *serial)
421 } 420 }
422} /* mct_u232_release */ 421} /* mct_u232_release */
423 422
424static int mct_u232_open(struct tty_struct *tty, 423static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
425 struct usb_serial_port *port, struct file *filp)
426{ 424{
427 struct usb_serial *serial = port->serial; 425 struct usb_serial *serial = port->serial;
428 struct mct_u232_private *priv = usb_get_serial_port_data(port); 426 struct mct_u232_private *priv = usb_get_serial_port_data(port);
@@ -568,10 +566,13 @@ static void mct_u232_read_int_callback(struct urb *urb)
568 * Work-a-round: handle the 'usual' bulk-in pipe here 566 * Work-a-round: handle the 'usual' bulk-in pipe here
569 */ 567 */
570 if (urb->transfer_buffer_length > 2) { 568 if (urb->transfer_buffer_length > 2) {
571 tty = tty_port_tty_get(&port->port);
572 if (urb->actual_length) { 569 if (urb->actual_length) {
573 tty_insert_flip_string(tty, data, urb->actual_length); 570 tty = tty_port_tty_get(&port->port);
574 tty_flip_buffer_push(tty); 571 if (tty) {
572 tty_insert_flip_string(tty, data,
573 urb->actual_length);
574 tty_flip_buffer_push(tty);
575 }
575 tty_kref_put(tty); 576 tty_kref_put(tty);
576 } 577 }
577 goto exit; 578 goto exit;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index ccd4dd340d2c..763e32a44be0 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -85,7 +85,7 @@ static int debug;
85#define MOSCHIP_DEVICE_ID_7720 0x7720 85#define MOSCHIP_DEVICE_ID_7720 0x7720
86#define MOSCHIP_DEVICE_ID_7715 0x7715 86#define MOSCHIP_DEVICE_ID_7715 0x7715
87 87
88static struct usb_device_id moschip_port_id_table [] = { 88static struct usb_device_id moschip_port_id_table[] = {
89 { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) }, 89 { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
90 { } /* terminating entry */ 90 { } /* terminating entry */
91}; 91};
@@ -319,8 +319,7 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
319 return status; 319 return status;
320} 320}
321 321
322static int mos7720_open(struct tty_struct *tty, 322static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
323 struct usb_serial_port *port, struct file *filp)
324{ 323{
325 struct usb_serial *serial; 324 struct usb_serial *serial;
326 struct usb_serial_port *port0; 325 struct usb_serial_port *port0;
@@ -378,10 +377,14 @@ static int mos7720_open(struct tty_struct *tty,
378 /* Initialize MCS7720 -- Write Init values to corresponding Registers 377 /* Initialize MCS7720 -- Write Init values to corresponding Registers
379 * 378 *
380 * Register Index 379 * Register Index
380 * 0 : THR/RHR
381 * 1 : IER 381 * 1 : IER
382 * 2 : FCR 382 * 2 : FCR
383 * 3 : LCR 383 * 3 : LCR
384 * 4 : MCR 384 * 4 : MCR
385 * 5 : LSR
386 * 6 : MSR
387 * 7 : SPR
385 * 388 *
386 * 0x08 : SP1/2 Control Reg 389 * 0x08 : SP1/2 Control Reg
387 */ 390 */
@@ -1250,20 +1253,88 @@ static void mos7720_set_termios(struct tty_struct *tty,
1250static int get_lsr_info(struct tty_struct *tty, 1253static int get_lsr_info(struct tty_struct *tty,
1251 struct moschip_port *mos7720_port, unsigned int __user *value) 1254 struct moschip_port *mos7720_port, unsigned int __user *value)
1252{ 1255{
1253 int count; 1256 struct usb_serial_port *port = tty->driver_data;
1254 unsigned int result = 0; 1257 unsigned int result = 0;
1258 unsigned char data = 0;
1259 int port_number = port->number - port->serial->minor;
1260 int count;
1255 1261
1256 count = mos7720_chars_in_buffer(tty); 1262 count = mos7720_chars_in_buffer(tty);
1257 if (count == 0) { 1263 if (count == 0) {
1258 dbg("%s -- Empty", __func__); 1264 send_mos_cmd(port->serial, MOS_READ, port_number,
1259 result = TIOCSER_TEMT; 1265 UART_LSR, &data);
1266 if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
1267 == (UART_LSR_TEMT | UART_LSR_THRE)) {
1268 dbg("%s -- Empty", __func__);
1269 result = TIOCSER_TEMT;
1270 }
1260 } 1271 }
1261
1262 if (copy_to_user(value, &result, sizeof(int))) 1272 if (copy_to_user(value, &result, sizeof(int)))
1263 return -EFAULT; 1273 return -EFAULT;
1264 return 0; 1274 return 0;
1265} 1275}
1266 1276
1277static int mos7720_tiocmget(struct tty_struct *tty, struct file *file)
1278{
1279 struct usb_serial_port *port = tty->driver_data;
1280 struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
1281 unsigned int result = 0;
1282 unsigned int mcr ;
1283 unsigned int msr ;
1284
1285 dbg("%s - port %d", __func__, port->number);
1286
1287 mcr = mos7720_port->shadowMCR;
1288 msr = mos7720_port->shadowMSR;
1289
1290 result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */
1291 | ((mcr & UART_MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */
1292 | ((msr & UART_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */
1293 | ((msr & UART_MSR_DCD) ? TIOCM_CAR : 0) /* 0x040 */
1294 | ((msr & UART_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */
1295 | ((msr & UART_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */
1296
1297 dbg("%s -- %x", __func__, result);
1298
1299 return result;
1300}
1301
1302static int mos7720_tiocmset(struct tty_struct *tty, struct file *file,
1303 unsigned int set, unsigned int clear)
1304{
1305 struct usb_serial_port *port = tty->driver_data;
1306 struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
1307 unsigned int mcr ;
1308 unsigned char lmcr;
1309
1310 dbg("%s - port %d", __func__, port->number);
1311 dbg("he was at tiocmget");
1312
1313 mcr = mos7720_port->shadowMCR;
1314
1315 if (set & TIOCM_RTS)
1316 mcr |= UART_MCR_RTS;
1317 if (set & TIOCM_DTR)
1318 mcr |= UART_MCR_DTR;
1319 if (set & TIOCM_LOOP)
1320 mcr |= UART_MCR_LOOP;
1321
1322 if (clear & TIOCM_RTS)
1323 mcr &= ~UART_MCR_RTS;
1324 if (clear & TIOCM_DTR)
1325 mcr &= ~UART_MCR_DTR;
1326 if (clear & TIOCM_LOOP)
1327 mcr &= ~UART_MCR_LOOP;
1328
1329 mos7720_port->shadowMCR = mcr;
1330 lmcr = mos7720_port->shadowMCR;
1331
1332 send_mos_cmd(port->serial, MOS_WRITE,
1333 port->number - port->serial->minor, UART_MCR, &lmcr);
1334
1335 return 0;
1336}
1337
1267static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, 1338static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
1268 unsigned int __user *value) 1339 unsigned int __user *value)
1269{ 1340{
@@ -1301,14 +1372,6 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
1301 mcr &= ~UART_MCR_LOOP; 1372 mcr &= ~UART_MCR_LOOP;
1302 break; 1373 break;
1303 1374
1304 case TIOCMSET:
1305 /* turn off the RTS and DTR and LOOPBACK
1306 * and then only turn on what was asked to */
1307 mcr &= ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP);
1308 mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0);
1309 mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
1310 mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0);
1311 break;
1312 } 1375 }
1313 1376
1314 mos7720_port->shadowMCR = mcr; 1377 mos7720_port->shadowMCR = mcr;
@@ -1320,28 +1383,6 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
1320 return 0; 1383 return 0;
1321} 1384}
1322 1385
1323static int get_modem_info(struct moschip_port *mos7720_port,
1324 unsigned int __user *value)
1325{
1326 unsigned int result = 0;
1327 unsigned int msr = mos7720_port->shadowMSR;
1328 unsigned int mcr = mos7720_port->shadowMCR;
1329
1330 result = ((mcr & UART_MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */
1331 | ((mcr & UART_MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */
1332 | ((msr & UART_MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */
1333 | ((msr & UART_MSR_DCD) ? TIOCM_CAR: 0) /* 0x040 */
1334 | ((msr & UART_MSR_RI) ? TIOCM_RI: 0) /* 0x080 */
1335 | ((msr & UART_MSR_DSR) ? TIOCM_DSR: 0); /* 0x100 */
1336
1337
1338 dbg("%s -- %x", __func__, result);
1339
1340 if (copy_to_user(value, &result, sizeof(int)))
1341 return -EFAULT;
1342 return 0;
1343}
1344
1345static int get_serial_info(struct moschip_port *mos7720_port, 1386static int get_serial_info(struct moschip_port *mos7720_port,
1346 struct serial_struct __user *retinfo) 1387 struct serial_struct __user *retinfo)
1347{ 1388{
@@ -1392,17 +1433,11 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
1392 /* FIXME: These should be using the mode methods */ 1433 /* FIXME: These should be using the mode methods */
1393 case TIOCMBIS: 1434 case TIOCMBIS:
1394 case TIOCMBIC: 1435 case TIOCMBIC:
1395 case TIOCMSET:
1396 dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", 1436 dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET",
1397 __func__, port->number); 1437 __func__, port->number);
1398 return set_modem_info(mos7720_port, cmd, 1438 return set_modem_info(mos7720_port, cmd,
1399 (unsigned int __user *)arg); 1439 (unsigned int __user *)arg);
1400 1440
1401 case TIOCMGET:
1402 dbg("%s (%d) TIOCMGET", __func__, port->number);
1403 return get_modem_info(mos7720_port,
1404 (unsigned int __user *)arg);
1405
1406 case TIOCGSERIAL: 1441 case TIOCGSERIAL:
1407 dbg("%s (%d) TIOCGSERIAL", __func__, port->number); 1442 dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
1408 return get_serial_info(mos7720_port, 1443 return get_serial_info(mos7720_port,
@@ -1557,6 +1592,8 @@ static struct usb_serial_driver moschip7720_2port_driver = {
1557 .attach = mos7720_startup, 1592 .attach = mos7720_startup,
1558 .release = mos7720_release, 1593 .release = mos7720_release,
1559 .ioctl = mos7720_ioctl, 1594 .ioctl = mos7720_ioctl,
1595 .tiocmget = mos7720_tiocmget,
1596 .tiocmset = mos7720_tiocmset,
1560 .set_termios = mos7720_set_termios, 1597 .set_termios = mos7720_set_termios,
1561 .write = mos7720_write, 1598 .write = mos7720_write,
1562 .write_room = mos7720_write_room, 1599 .write_room = mos7720_write_room,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 270009afdf77..f11abf52be7d 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -824,8 +824,7 @@ static int mos7840_serial_probe(struct usb_serial *serial,
824 * Otherwise we return a negative error number. 824 * Otherwise we return a negative error number.
825 *****************************************************************************/ 825 *****************************************************************************/
826 826
827static int mos7840_open(struct tty_struct *tty, 827static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
828 struct usb_serial_port *port, struct file *filp)
829{ 828{
830 int response; 829 int response;
831 int j; 830 int j;
@@ -2134,106 +2133,6 @@ static int mos7840_get_lsr_info(struct tty_struct *tty,
2134} 2133}
2135 2134
2136/***************************************************************************** 2135/*****************************************************************************
2137 * mos7840_set_modem_info
2138 * function to set modem info
2139 *****************************************************************************/
2140
2141/* FIXME: Should be using the model control hooks */
2142
2143static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
2144 unsigned int cmd, unsigned int __user *value)
2145{
2146 unsigned int mcr;
2147 unsigned int arg;
2148 __u16 Data;
2149 int status;
2150 struct usb_serial_port *port;
2151
2152 if (mos7840_port == NULL)
2153 return -1;
2154
2155 port = (struct usb_serial_port *)mos7840_port->port;
2156 if (mos7840_port_paranoia_check(port, __func__)) {
2157 dbg("%s", "Invalid port");
2158 return -1;
2159 }
2160
2161 mcr = mos7840_port->shadowMCR;
2162
2163 if (copy_from_user(&arg, value, sizeof(int)))
2164 return -EFAULT;
2165
2166 switch (cmd) {
2167 case TIOCMBIS:
2168 if (arg & TIOCM_RTS)
2169 mcr |= MCR_RTS;
2170 if (arg & TIOCM_DTR)
2171 mcr |= MCR_RTS;
2172 if (arg & TIOCM_LOOP)
2173 mcr |= MCR_LOOPBACK;
2174 break;
2175
2176 case TIOCMBIC:
2177 if (arg & TIOCM_RTS)
2178 mcr &= ~MCR_RTS;
2179 if (arg & TIOCM_DTR)
2180 mcr &= ~MCR_RTS;
2181 if (arg & TIOCM_LOOP)
2182 mcr &= ~MCR_LOOPBACK;
2183 break;
2184
2185 case TIOCMSET:
2186 /* turn off the RTS and DTR and LOOPBACK
2187 * and then only turn on what was asked to */
2188 mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK);
2189 mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0);
2190 mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0);
2191 mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0);
2192 break;
2193 }
2194
2195 lock_kernel();
2196 mos7840_port->shadowMCR = mcr;
2197
2198 Data = mos7840_port->shadowMCR;
2199 status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2200 unlock_kernel();
2201 if (status < 0) {
2202 dbg("setting MODEM_CONTROL_REGISTER Failed");
2203 return -1;
2204 }
2205
2206 return 0;
2207}
2208
2209/*****************************************************************************
2210 * mos7840_get_modem_info
2211 * function to get modem info
2212 *****************************************************************************/
2213
2214static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
2215 unsigned int __user *value)
2216{
2217 unsigned int result = 0;
2218 __u16 msr;
2219 unsigned int mcr = mos7840_port->shadowMCR;
2220 mos7840_get_uart_reg(mos7840_port->port,
2221 MODEM_STATUS_REGISTER, &msr);
2222 result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */
2223 |((mcr & MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */
2224 |((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */
2225 |((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0) /* 0x040 */
2226 |((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */
2227 |((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */
2228
2229 dbg("%s -- %x", __func__, result);
2230
2231 if (copy_to_user(value, &result, sizeof(int)))
2232 return -EFAULT;
2233 return 0;
2234}
2235
2236/*****************************************************************************
2237 * mos7840_get_serial_info 2136 * mos7840_get_serial_info
2238 * function to get information about serial port 2137 * function to get information about serial port
2239 *****************************************************************************/ 2138 *****************************************************************************/
@@ -2281,7 +2180,6 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
2281 struct async_icount cnow; 2180 struct async_icount cnow;
2282 struct async_icount cprev; 2181 struct async_icount cprev;
2283 struct serial_icounter_struct icount; 2182 struct serial_icounter_struct icount;
2284 int mosret = 0;
2285 2183
2286 if (mos7840_port_paranoia_check(port, __func__)) { 2184 if (mos7840_port_paranoia_check(port, __func__)) {
2287 dbg("%s", "Invalid port"); 2185 dbg("%s", "Invalid port");
@@ -2303,20 +2201,6 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
2303 return mos7840_get_lsr_info(tty, argp); 2201 return mos7840_get_lsr_info(tty, argp);
2304 return 0; 2202 return 0;
2305 2203
2306 /* FIXME: use the modem hooks and remove this */
2307 case TIOCMBIS:
2308 case TIOCMBIC:
2309 case TIOCMSET:
2310 dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
2311 port->number);
2312 mosret =
2313 mos7840_set_modem_info(mos7840_port, cmd, argp);
2314 return mosret;
2315
2316 case TIOCMGET:
2317 dbg("%s (%d) TIOCMGET", __func__, port->number);
2318 return mos7840_get_modem_info(mos7840_port, argp);
2319
2320 case TIOCGSERIAL: 2204 case TIOCGSERIAL:
2321 dbg("%s (%d) TIOCGSERIAL", __func__, port->number); 2205 dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
2322 return mos7840_get_serial_info(mos7840_port, argp); 2206 return mos7840_get_serial_info(mos7840_port, argp);
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index f5f3751a888c..5ceaa4c6be09 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -80,8 +80,7 @@ exit:
80 __func__, result); 80 __func__, result);
81} 81}
82 82
83static int navman_open(struct tty_struct *tty, 83static int navman_open(struct tty_struct *tty, struct usb_serial_port *port)
84 struct usb_serial_port *port, struct file *filp)
85{ 84{
86 int result = 0; 85 int result = 0;
87 86
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 56857ddbd70b..062265038bf0 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -64,8 +64,7 @@ static int debug;
64#define BT_IGNITIONPRO_ID 0x2000 64#define BT_IGNITIONPRO_ID 0x2000
65 65
66/* function prototypes */ 66/* function prototypes */
67static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port, 67static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port);
68 struct file *filp);
69static void omninet_close(struct usb_serial_port *port); 68static void omninet_close(struct usb_serial_port *port);
70static void omninet_read_bulk_callback(struct urb *urb); 69static void omninet_read_bulk_callback(struct urb *urb);
71static void omninet_write_bulk_callback(struct urb *urb); 70static void omninet_write_bulk_callback(struct urb *urb);
@@ -163,8 +162,7 @@ static int omninet_attach(struct usb_serial *serial)
163 return 0; 162 return 0;
164} 163}
165 164
166static int omninet_open(struct tty_struct *tty, 165static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
167 struct usb_serial_port *port, struct file *filp)
168{ 166{
169 struct usb_serial *serial = port->serial; 167 struct usb_serial *serial = port->serial;
170 struct usb_serial_port *wport; 168 struct usb_serial_port *wport;
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 336bba79ad32..1085a577c5c1 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -144,8 +144,7 @@ exit:
144 spin_unlock(&priv->lock); 144 spin_unlock(&priv->lock);
145} 145}
146 146
147static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port, 147static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
148 struct file *filp)
149{ 148{
150 struct opticon_private *priv = usb_get_serial_data(port->serial); 149 struct opticon_private *priv = usb_get_serial_data(port->serial);
151 unsigned long flags; 150 unsigned long flags;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index c784ddbe7b61..fe47051dbef2 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -45,8 +45,7 @@
45/* Function prototypes */ 45/* Function prototypes */
46static int option_probe(struct usb_serial *serial, 46static int option_probe(struct usb_serial *serial,
47 const struct usb_device_id *id); 47 const struct usb_device_id *id);
48static int option_open(struct tty_struct *tty, struct usb_serial_port *port, 48static int option_open(struct tty_struct *tty, struct usb_serial_port *port);
49 struct file *filp);
50static void option_close(struct usb_serial_port *port); 49static void option_close(struct usb_serial_port *port);
51static void option_dtr_rts(struct usb_serial_port *port, int on); 50static void option_dtr_rts(struct usb_serial_port *port, int on);
52 51
@@ -961,8 +960,7 @@ static int option_chars_in_buffer(struct tty_struct *tty)
961 return data_len; 960 return data_len;
962} 961}
963 962
964static int option_open(struct tty_struct *tty, 963static int option_open(struct tty_struct *tty, struct usb_serial_port *port)
965 struct usb_serial_port *port, struct file *filp)
966{ 964{
967 struct option_port_private *portdata; 965 struct option_port_private *portdata;
968 int i, err; 966 int i, err;
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 3cece27325e7..0f4a70ce3823 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -141,11 +141,11 @@ struct oti6858_control_pkt {
141 && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt)) 141 && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
142 142
143/* function prototypes */ 143/* function prototypes */
144static int oti6858_open(struct tty_struct *tty, 144static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port);
145 struct usb_serial_port *port, struct file *filp);
146static void oti6858_close(struct usb_serial_port *port); 145static void oti6858_close(struct usb_serial_port *port);
147static void oti6858_set_termios(struct tty_struct *tty, 146static void oti6858_set_termios(struct tty_struct *tty,
148 struct usb_serial_port *port, struct ktermios *old); 147 struct usb_serial_port *port, struct ktermios *old);
148static void oti6858_init_termios(struct tty_struct *tty);
149static int oti6858_ioctl(struct tty_struct *tty, struct file *file, 149static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
150 unsigned int cmd, unsigned long arg); 150 unsigned int cmd, unsigned long arg);
151static void oti6858_read_int_callback(struct urb *urb); 151static void oti6858_read_int_callback(struct urb *urb);
@@ -186,6 +186,7 @@ static struct usb_serial_driver oti6858_device = {
186 .write = oti6858_write, 186 .write = oti6858_write,
187 .ioctl = oti6858_ioctl, 187 .ioctl = oti6858_ioctl,
188 .set_termios = oti6858_set_termios, 188 .set_termios = oti6858_set_termios,
189 .init_termios = oti6858_init_termios,
189 .tiocmget = oti6858_tiocmget, 190 .tiocmget = oti6858_tiocmget,
190 .tiocmset = oti6858_tiocmset, 191 .tiocmset = oti6858_tiocmset,
191 .read_bulk_callback = oti6858_read_bulk_callback, 192 .read_bulk_callback = oti6858_read_bulk_callback,
@@ -206,7 +207,6 @@ struct oti6858_private {
206 struct { 207 struct {
207 u8 read_urb_in_use; 208 u8 read_urb_in_use;
208 u8 write_urb_in_use; 209 u8 write_urb_in_use;
209 u8 termios_initialized;
210 } flags; 210 } flags;
211 struct delayed_work delayed_write_work; 211 struct delayed_work delayed_write_work;
212 212
@@ -447,6 +447,14 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
447 return chars; 447 return chars;
448} 448}
449 449
450static void oti6858_init_termios(struct tty_struct *tty)
451{
452 *(tty->termios) = tty_std_termios;
453 tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
454 tty->termios->c_ispeed = 38400;
455 tty->termios->c_ospeed = 38400;
456}
457
450static void oti6858_set_termios(struct tty_struct *tty, 458static void oti6858_set_termios(struct tty_struct *tty,
451 struct usb_serial_port *port, struct ktermios *old_termios) 459 struct usb_serial_port *port, struct ktermios *old_termios)
452{ 460{
@@ -464,16 +472,6 @@ static void oti6858_set_termios(struct tty_struct *tty,
464 return; 472 return;
465 } 473 }
466 474
467 spin_lock_irqsave(&priv->lock, flags);
468 if (!priv->flags.termios_initialized) {
469 *(tty->termios) = tty_std_termios;
470 tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
471 tty->termios->c_ispeed = 38400;
472 tty->termios->c_ospeed = 38400;
473 priv->flags.termios_initialized = 1;
474 }
475 spin_unlock_irqrestore(&priv->lock, flags);
476
477 cflag = tty->termios->c_cflag; 475 cflag = tty->termios->c_cflag;
478 476
479 spin_lock_irqsave(&priv->lock, flags); 477 spin_lock_irqsave(&priv->lock, flags);
@@ -566,8 +564,7 @@ static void oti6858_set_termios(struct tty_struct *tty,
566 spin_unlock_irqrestore(&priv->lock, flags); 564 spin_unlock_irqrestore(&priv->lock, flags);
567} 565}
568 566
569static int oti6858_open(struct tty_struct *tty, 567static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port)
570 struct usb_serial_port *port, struct file *filp)
571{ 568{
572 struct oti6858_private *priv = usb_get_serial_port_data(port); 569 struct oti6858_private *priv = usb_get_serial_port_data(port);
573 struct ktermios tmp_termios; 570 struct ktermios tmp_termios;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 3e86815b2705..a63ea99936f7 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -691,8 +691,7 @@ static void pl2303_close(struct usb_serial_port *port)
691 691
692} 692}
693 693
694static int pl2303_open(struct tty_struct *tty, 694static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
695 struct usb_serial_port *port, struct file *filp)
696{ 695{
697 struct ktermios tmp_termios; 696 struct ktermios tmp_termios;
698 struct usb_serial *serial = port->serial; 697 struct usb_serial *serial = port->serial;
@@ -714,8 +713,6 @@ static int pl2303_open(struct tty_struct *tty,
714 if (tty) 713 if (tty)
715 pl2303_set_termios(tty, port, &tmp_termios); 714 pl2303_set_termios(tty, port, &tmp_termios);
716 715
717 /* FIXME: need to assert RTS and DTR if CRTSCTS off */
718
719 dbg("%s - submitting read urb", __func__); 716 dbg("%s - submitting read urb", __func__);
720 port->read_urb->dev = serial->dev; 717 port->read_urb->dev = serial->dev;
721 result = usb_submit_urb(port->read_urb, GFP_KERNEL); 718 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f48d05e0acc1..55391bbe1230 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -734,8 +734,7 @@ static void sierra_close(struct usb_serial_port *port)
734 } 734 }
735} 735}
736 736
737static int sierra_open(struct tty_struct *tty, 737static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
738 struct usb_serial_port *port, struct file *filp)
739{ 738{
740 struct sierra_port_private *portdata; 739 struct sierra_port_private *portdata;
741 struct usb_serial *serial = port->serial; 740 struct usb_serial *serial = port->serial;
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 3c249d8e8b8e..61e7c40b94fb 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -299,7 +299,6 @@ struct spcp8x5_private {
299 wait_queue_head_t delta_msr_wait; 299 wait_queue_head_t delta_msr_wait;
300 u8 line_control; 300 u8 line_control;
301 u8 line_status; 301 u8 line_status;
302 u8 termios_initialized;
303}; 302};
304 303
305/* desc : when device plug in,this function would be called. 304/* desc : when device plug in,this function would be called.
@@ -498,6 +497,15 @@ static void spcp8x5_close(struct usb_serial_port *port)
498 dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result); 497 dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result);
499} 498}
500 499
500static void spcp8x5_init_termios(struct tty_struct *tty)
501{
502 /* for the 1st time call this function */
503 *(tty->termios) = tty_std_termios;
504 tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
505 tty->termios->c_ispeed = 115200;
506 tty->termios->c_ospeed = 115200;
507}
508
501/* set the serial param for transfer. we should check if we really need to 509/* set the serial param for transfer. we should check if we really need to
502 * transfer. if we set flow control we should do this too. */ 510 * transfer. if we set flow control we should do this too. */
503static void spcp8x5_set_termios(struct tty_struct *tty, 511static void spcp8x5_set_termios(struct tty_struct *tty,
@@ -514,16 +522,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
514 int i; 522 int i;
515 u8 control; 523 u8 control;
516 524
517 /* for the 1st time call this function */
518 spin_lock_irqsave(&priv->lock, flags);
519 if (!priv->termios_initialized) {
520 *(tty->termios) = tty_std_termios;
521 tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
522 tty->termios->c_ispeed = 115200;
523 tty->termios->c_ospeed = 115200;
524 priv->termios_initialized = 1;
525 }
526 spin_unlock_irqrestore(&priv->lock, flags);
527 525
528 /* check that they really want us to change something */ 526 /* check that they really want us to change something */
529 if (!tty_termios_hw_change(tty->termios, old_termios)) 527 if (!tty_termios_hw_change(tty->termios, old_termios))
@@ -623,8 +621,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
623 621
624/* open the serial port. do some usb system call. set termios and get the line 622/* open the serial port. do some usb system call. set termios and get the line
625 * status of the device. then submit the read urb */ 623 * status of the device. then submit the read urb */
626static int spcp8x5_open(struct tty_struct *tty, 624static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
627 struct usb_serial_port *port, struct file *filp)
628{ 625{
629 struct ktermios tmp_termios; 626 struct ktermios tmp_termios;
630 struct usb_serial *serial = port->serial; 627 struct usb_serial *serial = port->serial;
@@ -658,8 +655,6 @@ static int spcp8x5_open(struct tty_struct *tty,
658 priv->line_status = status & 0xf0 ; 655 priv->line_status = status & 0xf0 ;
659 spin_unlock_irqrestore(&priv->lock, flags); 656 spin_unlock_irqrestore(&priv->lock, flags);
660 657
661 /* FIXME: need to assert RTS and DTR if CRTSCTS off */
662
663 dbg("%s - submitting read urb", __func__); 658 dbg("%s - submitting read urb", __func__);
664 port->read_urb->dev = serial->dev; 659 port->read_urb->dev = serial->dev;
665 ret = usb_submit_urb(port->read_urb, GFP_KERNEL); 660 ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
@@ -1011,6 +1006,7 @@ static struct usb_serial_driver spcp8x5_device = {
1011 .carrier_raised = spcp8x5_carrier_raised, 1006 .carrier_raised = spcp8x5_carrier_raised,
1012 .write = spcp8x5_write, 1007 .write = spcp8x5_write,
1013 .set_termios = spcp8x5_set_termios, 1008 .set_termios = spcp8x5_set_termios,
1009 .init_termios = spcp8x5_init_termios,
1014 .ioctl = spcp8x5_ioctl, 1010 .ioctl = spcp8x5_ioctl,
1015 .tiocmget = spcp8x5_tiocmget, 1011 .tiocmget = spcp8x5_tiocmget,
1016 .tiocmset = spcp8x5_tiocmset, 1012 .tiocmset = spcp8x5_tiocmset,
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 6157fac9366b..cb7e95f9fcbf 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -124,8 +124,7 @@ exit:
124 spin_unlock(&priv->lock); 124 spin_unlock(&priv->lock);
125} 125}
126 126
127static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port, 127static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port)
128 struct file *filp)
129{ 128{
130 struct symbol_private *priv = usb_get_serial_data(port->serial); 129 struct symbol_private *priv = usb_get_serial_data(port->serial);
131 unsigned long flags; 130 unsigned long flags;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 3bc609fe2242..1e9dc8821698 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -98,8 +98,7 @@ struct ti_device {
98 98
99static int ti_startup(struct usb_serial *serial); 99static int ti_startup(struct usb_serial *serial);
100static void ti_release(struct usb_serial *serial); 100static void ti_release(struct usb_serial *serial);
101static int ti_open(struct tty_struct *tty, struct usb_serial_port *port, 101static int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
102 struct file *file);
103static void ti_close(struct usb_serial_port *port); 102static void ti_close(struct usb_serial_port *port);
104static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, 103static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
105 const unsigned char *data, int count); 104 const unsigned char *data, int count);
@@ -492,8 +491,7 @@ static void ti_release(struct usb_serial *serial)
492} 491}
493 492
494 493
495static int ti_open(struct tty_struct *tty, 494static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
496 struct usb_serial_port *port, struct file *file)
497{ 495{
498 struct ti_port *tport = usb_get_serial_port_data(port); 496 struct ti_port *tport = usb_get_serial_port_data(port);
499 struct ti_device *tdev; 497 struct ti_device *tdev;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 99188c92068b..9d7ca4868d37 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -43,8 +43,6 @@
43#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" 43#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
44#define DRIVER_DESC "USB Serial Driver core" 44#define DRIVER_DESC "USB Serial Driver core"
45 45
46static void port_free(struct usb_serial_port *port);
47
48/* Driver structure we register with the USB core */ 46/* Driver structure we register with the USB core */
49static struct usb_driver usb_serial_driver = { 47static struct usb_driver usb_serial_driver = {
50 .name = "usbserial", 48 .name = "usbserial",
@@ -68,6 +66,11 @@ static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
68static DEFINE_MUTEX(table_lock); 66static DEFINE_MUTEX(table_lock);
69static LIST_HEAD(usb_serial_driver_list); 67static LIST_HEAD(usb_serial_driver_list);
70 68
69/*
70 * Look up the serial structure. If it is found and it hasn't been
71 * disconnected, return with its disc_mutex held and its refcount
72 * incremented. Otherwise return NULL.
73 */
71struct usb_serial *usb_serial_get_by_index(unsigned index) 74struct usb_serial *usb_serial_get_by_index(unsigned index)
72{ 75{
73 struct usb_serial *serial; 76 struct usb_serial *serial;
@@ -75,8 +78,15 @@ struct usb_serial *usb_serial_get_by_index(unsigned index)
75 mutex_lock(&table_lock); 78 mutex_lock(&table_lock);
76 serial = serial_table[index]; 79 serial = serial_table[index];
77 80
78 if (serial) 81 if (serial) {
79 kref_get(&serial->kref); 82 mutex_lock(&serial->disc_mutex);
83 if (serial->disconnected) {
84 mutex_unlock(&serial->disc_mutex);
85 serial = NULL;
86 } else {
87 kref_get(&serial->kref);
88 }
89 }
80 mutex_unlock(&table_lock); 90 mutex_unlock(&table_lock);
81 return serial; 91 return serial;
82} 92}
@@ -125,8 +135,10 @@ static void return_serial(struct usb_serial *serial)
125 135
126 dbg("%s", __func__); 136 dbg("%s", __func__);
127 137
138 mutex_lock(&table_lock);
128 for (i = 0; i < serial->num_ports; ++i) 139 for (i = 0; i < serial->num_ports; ++i)
129 serial_table[serial->minor + i] = NULL; 140 serial_table[serial->minor + i] = NULL;
141 mutex_unlock(&table_lock);
130} 142}
131 143
132static void destroy_serial(struct kref *kref) 144static void destroy_serial(struct kref *kref)
@@ -145,161 +157,157 @@ static void destroy_serial(struct kref *kref)
145 157
146 serial->type->release(serial); 158 serial->type->release(serial);
147 159
148 for (i = 0; i < serial->num_ports; ++i) { 160 /* Now that nothing is using the ports, they can be freed */
161 for (i = 0; i < serial->num_port_pointers; ++i) {
149 port = serial->port[i]; 162 port = serial->port[i];
150 if (port) 163 if (port) {
164 port->serial = NULL;
151 put_device(&port->dev); 165 put_device(&port->dev);
152 }
153
154 /* If this is a "fake" port, we have to clean it up here, as it will
155 * not get cleaned up in port_release() as it was never registered with
156 * the driver core */
157 if (serial->num_ports < serial->num_port_pointers) {
158 for (i = serial->num_ports;
159 i < serial->num_port_pointers; ++i) {
160 port = serial->port[i];
161 if (port)
162 port_free(port);
163 } 166 }
164 } 167 }
165 168
166 usb_put_dev(serial->dev); 169 usb_put_dev(serial->dev);
167
168 /* free up any memory that we allocated */
169 kfree(serial); 170 kfree(serial);
170} 171}
171 172
172void usb_serial_put(struct usb_serial *serial) 173void usb_serial_put(struct usb_serial *serial)
173{ 174{
174 mutex_lock(&table_lock);
175 kref_put(&serial->kref, destroy_serial); 175 kref_put(&serial->kref, destroy_serial);
176 mutex_unlock(&table_lock);
177} 176}
178 177
179/***************************************************************************** 178/*****************************************************************************
180 * Driver tty interface functions 179 * Driver tty interface functions
181 *****************************************************************************/ 180 *****************************************************************************/
182static int serial_open (struct tty_struct *tty, struct file *filp) 181
182/**
183 * serial_install - install tty
184 * @driver: the driver (USB in our case)
185 * @tty: the tty being created
186 *
187 * Create the termios objects for this tty. We use the default
188 * USB serial settings but permit them to be overridden by
189 * serial->type->init_termios.
190 *
191 * This is the first place a new tty gets used. Hence this is where we
192 * acquire references to the usb_serial structure and the driver module,
193 * where we store a pointer to the port, and where we do an autoresume.
194 * All these actions are reversed in serial_release().
195 */
196static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
183{ 197{
198 int idx = tty->index;
184 struct usb_serial *serial; 199 struct usb_serial *serial;
185 struct usb_serial_port *port; 200 struct usb_serial_port *port;
186 unsigned int portNumber; 201 int retval = -ENODEV;
187 int retval = 0;
188 int first = 0;
189 202
190 dbg("%s", __func__); 203 dbg("%s", __func__);
191 204
192 /* get the serial object associated with this tty pointer */ 205 serial = usb_serial_get_by_index(idx);
193 serial = usb_serial_get_by_index(tty->index); 206 if (!serial)
194 if (!serial) { 207 return retval;
195 tty->driver_data = NULL;
196 return -ENODEV;
197 }
198 208
199 mutex_lock(&serial->disc_mutex); 209 port = serial->port[idx - serial->minor];
200 portNumber = tty->index - serial->minor; 210 if (!port)
201 port = serial->port[portNumber]; 211 goto error_no_port;
202 if (!port || serial->disconnected) 212 if (!try_module_get(serial->type->driver.owner))
203 retval = -ENODEV; 213 goto error_module_get;
204 else 214
205 get_device(&port->dev); 215 /* perform the standard setup */
206 /* 216 retval = tty_init_termios(tty);
207 * Note: Our locking order requirement does not allow port->mutex
208 * to be acquired while serial->disc_mutex is held.
209 */
210 mutex_unlock(&serial->disc_mutex);
211 if (retval) 217 if (retval)
212 goto bailout_serial_put; 218 goto error_init_termios;
213 219
214 if (mutex_lock_interruptible(&port->mutex)) { 220 retval = usb_autopm_get_interface(serial->interface);
215 retval = -ERESTARTSYS; 221 if (retval)
216 goto bailout_port_put; 222 goto error_get_interface;
217 } 223
224 mutex_unlock(&serial->disc_mutex);
218 225
219 ++port->port.count; 226 /* allow the driver to update the settings */
227 if (serial->type->init_termios)
228 serial->type->init_termios(tty);
220 229
221 /* set up our port structure making the tty driver
222 * remember our port object, and us it */
223 tty->driver_data = port; 230 tty->driver_data = port;
224 tty_port_tty_set(&port->port, tty);
225 231
226 /* If the console is attached, the device is already open */ 232 /* Final install (we use the default method) */
227 if (port->port.count == 1 && !port->console) { 233 tty_driver_kref_get(driver);
228 first = 1; 234 tty->count++;
229 /* lock this module before we call it 235 driver->ttys[idx] = tty;
230 * this may fail, which means we must bail out, 236 return retval;
231 * safe because we are called with BKL held */
232 if (!try_module_get(serial->type->driver.owner)) {
233 retval = -ENODEV;
234 goto bailout_mutex_unlock;
235 }
236 237
238 error_get_interface:
239 error_init_termios:
240 module_put(serial->type->driver.owner);
241 error_module_get:
242 error_no_port:
243 usb_serial_put(serial);
244 mutex_unlock(&serial->disc_mutex);
245 return retval;
246}
247
248static int serial_open(struct tty_struct *tty, struct file *filp)
249{
250 struct usb_serial_port *port = tty->driver_data;
251 struct usb_serial *serial = port->serial;
252 int retval;
253
254 dbg("%s - port %d", __func__, port->number);
255
256 spin_lock_irq(&port->port.lock);
257 if (!tty_hung_up_p(filp))
258 ++port->port.count;
259 spin_unlock_irq(&port->port.lock);
260 tty_port_tty_set(&port->port, tty);
261
262 /* Do the device-specific open only if the hardware isn't
263 * already initialized.
264 */
265 if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
266 if (mutex_lock_interruptible(&port->mutex))
267 return -ERESTARTSYS;
237 mutex_lock(&serial->disc_mutex); 268 mutex_lock(&serial->disc_mutex);
238 if (serial->disconnected) 269 if (serial->disconnected)
239 retval = -ENODEV; 270 retval = -ENODEV;
240 else 271 else
241 retval = usb_autopm_get_interface(serial->interface); 272 retval = port->serial->type->open(tty, port);
242 if (retval)
243 goto bailout_module_put;
244
245 /* only call the device specific open if this
246 * is the first time the port is opened */
247 retval = serial->type->open(tty, port, filp);
248 if (retval)
249 goto bailout_interface_put;
250 mutex_unlock(&serial->disc_mutex); 273 mutex_unlock(&serial->disc_mutex);
274 mutex_unlock(&port->mutex);
275 if (retval)
276 return retval;
251 set_bit(ASYNCB_INITIALIZED, &port->port.flags); 277 set_bit(ASYNCB_INITIALIZED, &port->port.flags);
252 } 278 }
253 mutex_unlock(&port->mutex); 279
254 /* Now do the correct tty layer semantics */ 280 /* Now do the correct tty layer semantics */
255 retval = tty_port_block_til_ready(&port->port, tty, filp); 281 retval = tty_port_block_til_ready(&port->port, tty, filp);
256 if (retval == 0) {
257 if (!first)
258 usb_serial_put(serial);
259 return 0;
260 }
261 mutex_lock(&port->mutex);
262 if (first == 0)
263 goto bailout_mutex_unlock;
264 /* Undo the initial port actions */
265 mutex_lock(&serial->disc_mutex);
266bailout_interface_put:
267 usb_autopm_put_interface(serial->interface);
268bailout_module_put:
269 mutex_unlock(&serial->disc_mutex);
270 module_put(serial->type->driver.owner);
271bailout_mutex_unlock:
272 port->port.count = 0;
273 tty->driver_data = NULL;
274 tty_port_tty_set(&port->port, NULL);
275 mutex_unlock(&port->mutex);
276bailout_port_put:
277 put_device(&port->dev);
278bailout_serial_put:
279 usb_serial_put(serial);
280 return retval; 282 return retval;
281} 283}
282 284
283/** 285/**
284 * serial_do_down - shut down hardware 286 * serial_down - shut down hardware
285 * @port: port to shut down 287 * @port: port to shut down
286 *
287 * Shut down a USB port unless it is the console. We never shut down the
288 * console hardware as it will always be in use.
289 * 288 *
290 * Don't free any resources at this point 289 * Shut down a USB serial port unless it is the console. We never
290 * shut down the console hardware as it will always be in use.
291 */ 291 */
292static void serial_do_down(struct usb_serial_port *port) 292static void serial_down(struct usb_serial_port *port)
293{ 293{
294 struct usb_serial_driver *drv = port->serial->type; 294 struct usb_serial_driver *drv = port->serial->type;
295 struct usb_serial *serial; 295 struct usb_serial *serial;
296 struct module *owner; 296 struct module *owner;
297 297
298 /* The console is magical, do not hang up the console hardware 298 /*
299 or there will be tears */ 299 * The console is magical. Do not hang up the console hardware
300 * or there will be tears.
301 */
300 if (port->console) 302 if (port->console)
301 return; 303 return;
302 304
305 /* Don't call the close method if the hardware hasn't been
306 * initialized.
307 */
308 if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags))
309 return;
310
303 mutex_lock(&port->mutex); 311 mutex_lock(&port->mutex);
304 serial = port->serial; 312 serial = port->serial;
305 owner = serial->type->driver.owner; 313 owner = serial->type->driver.owner;
@@ -310,79 +318,69 @@ static void serial_do_down(struct usb_serial_port *port)
310 mutex_unlock(&port->mutex); 318 mutex_unlock(&port->mutex);
311} 319}
312 320
313/** 321static void serial_hangup(struct tty_struct *tty)
314 * serial_do_free - free resources post close/hangup
315 * @port: port to free up
316 *
317 * Do the resource freeing and refcount dropping for the port. We must
318 * be careful about ordering and we must avoid freeing up the console.
319 */
320
321static void serial_do_free(struct usb_serial_port *port)
322{ 322{
323 struct usb_serial *serial; 323 struct usb_serial_port *port = tty->driver_data;
324 struct module *owner;
325 324
326 /* The console is magical, do not hang up the console hardware 325 dbg("%s - port %d", __func__, port->number);
327 or there will be tears */
328 if (port->console)
329 return;
330 326
331 serial = port->serial; 327 serial_down(port);
332 owner = serial->type->driver.owner; 328 tty_port_hangup(&port->port);
333 put_device(&port->dev);
334 /* Mustn't dereference port any more */
335 mutex_lock(&serial->disc_mutex);
336 if (!serial->disconnected)
337 usb_autopm_put_interface(serial->interface);
338 mutex_unlock(&serial->disc_mutex);
339 usb_serial_put(serial);
340 /* Mustn't dereference serial any more */
341 module_put(owner);
342} 329}
343 330
344static void serial_close(struct tty_struct *tty, struct file *filp) 331static void serial_close(struct tty_struct *tty, struct file *filp)
345{ 332{
346 struct usb_serial_port *port = tty->driver_data; 333 struct usb_serial_port *port = tty->driver_data;
347 334
348 if (!port)
349 return;
350
351 dbg("%s - port %d", __func__, port->number); 335 dbg("%s - port %d", __func__, port->number);
352 336
353 /* FIXME: 337 if (tty_hung_up_p(filp))
354 This leaves a very narrow race. Really we should do the
355 serial_do_free() on tty->shutdown(), but tty->shutdown can
356 be called from IRQ context and serial_do_free can sleep.
357
358 The right fix is probably to make the tty free (which is rare)
359 and thus tty->shutdown() occur via a work queue and simplify all
360 the drivers that use it.
361 */
362 if (tty_hung_up_p(filp)) {
363 /* serial_hangup already called serial_down at this point.
364 Another user may have already reopened the port but
365 serial_do_free is refcounted */
366 serial_do_free(port);
367 return; 338 return;
368 }
369
370 if (tty_port_close_start(&port->port, tty, filp) == 0) 339 if (tty_port_close_start(&port->port, tty, filp) == 0)
371 return; 340 return;
372 341 serial_down(port);
373 serial_do_down(port);
374 tty_port_close_end(&port->port, tty); 342 tty_port_close_end(&port->port, tty);
375 tty_port_tty_set(&port->port, NULL); 343 tty_port_tty_set(&port->port, NULL);
376 serial_do_free(port);
377} 344}
378 345
379static void serial_hangup(struct tty_struct *tty) 346/**
347 * serial_release - free resources post close/hangup
348 * @port: port to free up
349 *
350 * Do the resource freeing and refcount dropping for the port.
351 * Avoid freeing the console.
352 *
353 * Called when the last tty kref is dropped.
354 */
355static void serial_release(struct tty_struct *tty)
380{ 356{
381 struct usb_serial_port *port = tty->driver_data; 357 struct usb_serial_port *port = tty->driver_data;
382 serial_do_down(port); 358 struct usb_serial *serial;
383 tty_port_hangup(&port->port); 359 struct module *owner;
384 /* We must not free port yet - the USB serial layer depends on it's 360
385 continued existence */ 361 /* The console is magical. Do not hang up the console hardware
362 * or there will be tears.
363 */
364 if (port->console)
365 return;
366
367 dbg("%s - port %d", __func__, port->number);
368
369 /* Standard shutdown processing */
370 tty_shutdown(tty);
371
372 tty->driver_data = NULL;
373
374 serial = port->serial;
375 owner = serial->type->driver.owner;
376
377 mutex_lock(&serial->disc_mutex);
378 if (!serial->disconnected)
379 usb_autopm_put_interface(serial->interface);
380 mutex_unlock(&serial->disc_mutex);
381
382 usb_serial_put(serial);
383 module_put(owner);
386} 384}
387 385
388static int serial_write(struct tty_struct *tty, const unsigned char *buf, 386static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -527,6 +525,7 @@ static int serial_proc_show(struct seq_file *m, void *v)
527 525
528 seq_putc(m, '\n'); 526 seq_putc(m, '\n');
529 usb_serial_put(serial); 527 usb_serial_put(serial);
528 mutex_unlock(&serial->disc_mutex);
530 } 529 }
531 return 0; 530 return 0;
532} 531}
@@ -596,14 +595,6 @@ static void usb_serial_port_work(struct work_struct *work)
596 tty_kref_put(tty); 595 tty_kref_put(tty);
597} 596}
598 597
599static void port_release(struct device *dev)
600{
601 struct usb_serial_port *port = to_usb_serial_port(dev);
602
603 dbg ("%s - %s", __func__, dev_name(dev));
604 port_free(port);
605}
606
607static void kill_traffic(struct usb_serial_port *port) 598static void kill_traffic(struct usb_serial_port *port)
608{ 599{
609 usb_kill_urb(port->read_urb); 600 usb_kill_urb(port->read_urb);
@@ -623,8 +614,12 @@ static void kill_traffic(struct usb_serial_port *port)
623 usb_kill_urb(port->interrupt_out_urb); 614 usb_kill_urb(port->interrupt_out_urb);
624} 615}
625 616
626static void port_free(struct usb_serial_port *port) 617static void port_release(struct device *dev)
627{ 618{
619 struct usb_serial_port *port = to_usb_serial_port(dev);
620
621 dbg ("%s - %s", __func__, dev_name(dev));
622
628 /* 623 /*
629 * Stop all the traffic before cancelling the work, so that 624 * Stop all the traffic before cancelling the work, so that
630 * nobody will restart it by calling usb_serial_port_softint. 625 * nobody will restart it by calling usb_serial_port_softint.
@@ -935,6 +930,11 @@ int usb_serial_probe(struct usb_interface *interface,
935 mutex_init(&port->mutex); 930 mutex_init(&port->mutex);
936 INIT_WORK(&port->work, usb_serial_port_work); 931 INIT_WORK(&port->work, usb_serial_port_work);
937 serial->port[i] = port; 932 serial->port[i] = port;
933 port->dev.parent = &interface->dev;
934 port->dev.driver = NULL;
935 port->dev.bus = &usb_serial_bus_type;
936 port->dev.release = &port_release;
937 device_initialize(&port->dev);
938 } 938 }
939 939
940 /* set up the endpoint information */ 940 /* set up the endpoint information */
@@ -1077,15 +1077,10 @@ int usb_serial_probe(struct usb_interface *interface,
1077 /* register all of the individual ports with the driver core */ 1077 /* register all of the individual ports with the driver core */
1078 for (i = 0; i < num_ports; ++i) { 1078 for (i = 0; i < num_ports; ++i) {
1079 port = serial->port[i]; 1079 port = serial->port[i];
1080 port->dev.parent = &interface->dev;
1081 port->dev.driver = NULL;
1082 port->dev.bus = &usb_serial_bus_type;
1083 port->dev.release = &port_release;
1084
1085 dev_set_name(&port->dev, "ttyUSB%d", port->number); 1080 dev_set_name(&port->dev, "ttyUSB%d", port->number);
1086 dbg ("%s - registering %s", __func__, dev_name(&port->dev)); 1081 dbg ("%s - registering %s", __func__, dev_name(&port->dev));
1087 port->dev_state = PORT_REGISTERING; 1082 port->dev_state = PORT_REGISTERING;
1088 retval = device_register(&port->dev); 1083 retval = device_add(&port->dev);
1089 if (retval) { 1084 if (retval) {
1090 dev_err(&port->dev, "Error registering port device, " 1085 dev_err(&port->dev, "Error registering port device, "
1091 "continuing\n"); 1086 "continuing\n");
@@ -1103,39 +1098,7 @@ exit:
1103 return 0; 1098 return 0;
1104 1099
1105probe_error: 1100probe_error:
1106 for (i = 0; i < num_bulk_in; ++i) { 1101 usb_serial_put(serial);
1107 port = serial->port[i];
1108 if (!port)
1109 continue;
1110 usb_free_urb(port->read_urb);
1111 kfree(port->bulk_in_buffer);
1112 }
1113 for (i = 0; i < num_bulk_out; ++i) {
1114 port = serial->port[i];
1115 if (!port)
1116 continue;
1117 usb_free_urb(port->write_urb);
1118 kfree(port->bulk_out_buffer);
1119 }
1120 for (i = 0; i < num_interrupt_in; ++i) {
1121 port = serial->port[i];
1122 if (!port)
1123 continue;
1124 usb_free_urb(port->interrupt_in_urb);
1125 kfree(port->interrupt_in_buffer);
1126 }
1127 for (i = 0; i < num_interrupt_out; ++i) {
1128 port = serial->port[i];
1129 if (!port)
1130 continue;
1131 usb_free_urb(port->interrupt_out_urb);
1132 kfree(port->interrupt_out_buffer);
1133 }
1134
1135 /* free up any memory that we allocated */
1136 for (i = 0; i < serial->num_port_pointers; ++i)
1137 kfree(serial->port[i]);
1138 kfree(serial);
1139 return -EIO; 1102 return -EIO;
1140} 1103}
1141EXPORT_SYMBOL_GPL(usb_serial_probe); 1104EXPORT_SYMBOL_GPL(usb_serial_probe);
@@ -1161,10 +1124,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
1161 if (port) { 1124 if (port) {
1162 struct tty_struct *tty = tty_port_tty_get(&port->port); 1125 struct tty_struct *tty = tty_port_tty_get(&port->port);
1163 if (tty) { 1126 if (tty) {
1164 /* The hangup will occur asynchronously but 1127 tty_vhangup(tty);
1165 the object refcounts will sort out all the
1166 cleanup */
1167 tty_hangup(tty);
1168 tty_kref_put(tty); 1128 tty_kref_put(tty);
1169 } 1129 }
1170 kill_traffic(port); 1130 kill_traffic(port);
@@ -1189,8 +1149,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
1189 } 1149 }
1190 serial->type->disconnect(serial); 1150 serial->type->disconnect(serial);
1191 1151
1192 /* let the last holder of this object 1152 /* let the last holder of this object cause it to be cleaned up */
1193 * cause it to be cleaned up */
1194 usb_serial_put(serial); 1153 usb_serial_put(serial);
1195 dev_info(dev, "device disconnected\n"); 1154 dev_info(dev, "device disconnected\n");
1196} 1155}
@@ -1246,6 +1205,8 @@ static const struct tty_operations serial_ops = {
1246 .chars_in_buffer = serial_chars_in_buffer, 1205 .chars_in_buffer = serial_chars_in_buffer,
1247 .tiocmget = serial_tiocmget, 1206 .tiocmget = serial_tiocmget,
1248 .tiocmset = serial_tiocmset, 1207 .tiocmset = serial_tiocmset,
1208 .shutdown = serial_release,
1209 .install = serial_install,
1249 .proc_fops = &serial_proc_fops, 1210 .proc_fops = &serial_proc_fops,
1250}; 1211};
1251 1212
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 614800972dc3..7b5bfc4edd3d 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -43,11 +43,10 @@ static struct usb_driver debug_driver = {
43 .no_dynamic_id = 1, 43 .no_dynamic_id = 1,
44}; 44};
45 45
46static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port, 46static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port)
47 struct file *filp)
48{ 47{
49 port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE; 48 port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE;
50 return usb_serial_generic_open(tty, port, filp); 49 return usb_serial_generic_open(tty, port);
51} 50}
52 51
53/* This HW really does not support a serial break, so one will be 52/* This HW really does not support a serial break, so one will be
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index f5d0f64dcc52..1aa5d20a5d99 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -36,8 +36,7 @@
36#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" 36#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
37 37
38/* function prototypes for a handspring visor */ 38/* function prototypes for a handspring visor */
39static int visor_open(struct tty_struct *tty, struct usb_serial_port *port, 39static int visor_open(struct tty_struct *tty, struct usb_serial_port *port);
40 struct file *filp);
41static void visor_close(struct usb_serial_port *port); 40static void visor_close(struct usb_serial_port *port);
42static int visor_write(struct tty_struct *tty, struct usb_serial_port *port, 41static int visor_write(struct tty_struct *tty, struct usb_serial_port *port,
43 const unsigned char *buf, int count); 42 const unsigned char *buf, int count);
@@ -273,8 +272,7 @@ static int stats;
273/****************************************************************************** 272/******************************************************************************
274 * Handspring Visor specific driver functions 273 * Handspring Visor specific driver functions
275 ******************************************************************************/ 274 ******************************************************************************/
276static int visor_open(struct tty_struct *tty, struct usb_serial_port *port, 275static int visor_open(struct tty_struct *tty, struct usb_serial_port *port)
277 struct file *filp)
278{ 276{
279 struct usb_serial *serial = port->serial; 277 struct usb_serial *serial = port->serial;
280 struct visor_private *priv = usb_get_serial_port_data(port); 278 struct visor_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 8d126dd7a02e..62424eec33ec 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -146,7 +146,7 @@ static int whiteheat_firmware_attach(struct usb_serial *serial);
146static int whiteheat_attach(struct usb_serial *serial); 146static int whiteheat_attach(struct usb_serial *serial);
147static void whiteheat_release(struct usb_serial *serial); 147static void whiteheat_release(struct usb_serial *serial);
148static int whiteheat_open(struct tty_struct *tty, 148static int whiteheat_open(struct tty_struct *tty,
149 struct usb_serial_port *port, struct file *filp); 149 struct usb_serial_port *port);
150static void whiteheat_close(struct usb_serial_port *port); 150static void whiteheat_close(struct usb_serial_port *port);
151static int whiteheat_write(struct tty_struct *tty, 151static int whiteheat_write(struct tty_struct *tty,
152 struct usb_serial_port *port, 152 struct usb_serial_port *port,
@@ -259,7 +259,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
259 __u8 *data, __u8 datasize); 259 __u8 *data, __u8 datasize);
260static int firm_open(struct usb_serial_port *port); 260static int firm_open(struct usb_serial_port *port);
261static int firm_close(struct usb_serial_port *port); 261static int firm_close(struct usb_serial_port *port);
262static int firm_setup_port(struct tty_struct *tty); 262static void firm_setup_port(struct tty_struct *tty);
263static int firm_set_rts(struct usb_serial_port *port, __u8 onoff); 263static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
264static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff); 264static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
265static int firm_set_break(struct usb_serial_port *port, __u8 onoff); 265static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
@@ -659,8 +659,7 @@ static void whiteheat_release(struct usb_serial *serial)
659 return; 659 return;
660} 660}
661 661
662static int whiteheat_open(struct tty_struct *tty, 662static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
663 struct usb_serial_port *port, struct file *filp)
664{ 663{
665 int retval = 0; 664 int retval = 0;
666 665
@@ -1211,7 +1210,7 @@ static int firm_close(struct usb_serial_port *port)
1211} 1210}
1212 1211
1213 1212
1214static int firm_setup_port(struct tty_struct *tty) 1213static void firm_setup_port(struct tty_struct *tty)
1215{ 1214{
1216 struct usb_serial_port *port = tty->driver_data; 1215 struct usb_serial_port *port = tty->driver_data;
1217 struct whiteheat_port_settings port_settings; 1216 struct whiteheat_port_settings port_settings;
@@ -1286,7 +1285,7 @@ static int firm_setup_port(struct tty_struct *tty)
1286 port_settings.lloop = 0; 1285 port_settings.lloop = 0;
1287 1286
1288 /* now send the message to the device */ 1287 /* now send the message to the device */
1289 return firm_send_command(port, WHITEHEAT_SETUP_PORT, 1288 firm_send_command(port, WHITEHEAT_SETUP_PORT,
1290 (__u8 *)&port_settings, sizeof(port_settings)); 1289 (__u8 *)&port_settings, sizeof(port_settings));
1291} 1290}
1292 1291
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 59d7d5ec17a4..74e96cf83b7e 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -180,7 +180,6 @@ static inline void vga_set_mem_top(struct vc_data *c)
180} 180}
181 181
182#ifdef CONFIG_VGACON_SOFT_SCROLLBACK 182#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
183#include <linux/slab.h>
184/* software scrollback */ 183/* software scrollback */
185static void *vgacon_scrollback; 184static void *vgacon_scrollback;
186static int vgacon_scrollback_tail; 185static int vgacon_scrollback_tail;
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index af031950f9b1..79bedba44fee 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -38,7 +38,6 @@
38#include <linux/string.h> 38#include <linux/string.h>
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/fs.h> 40#include <linux/fs.h>
41#include <linux/errno.h>
42#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
43#include <linux/major.h> 42#include <linux/major.h>
44#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>